commit aacc1a389e145453cf92c18e9d7ffef568cf89e7 Author: Rinjae Date: Fri Sep 5 18:57:45 2025 +0900 init diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0aaaf8c --- /dev/null +++ b/.gitignore @@ -0,0 +1,234 @@ +gradle.properties + +# Package Files # +*.war + +src/main/generated + +# Eclipse # +.metadata +bin/ +tmp/ +*.tmp +*.bak +*.swp +*~.nib +local.properties +.settings/ +.loadpath +.recommenders + +.classpath +.project + +# External tool builders +.externalToolBuilders/ + +# Locally stored "Eclipse launch configurations" +*.launch + +# PyDev specific (Python IDE for Eclipse) +*.pydevproject + +# CDT-specific (C/C++ Development Tooling) +.cproject + +# CDT- autotools +.autotools + +# Java annotation processor (APT) +.factorypath + +# PDT-specific (PHP Development Tools) +.buildpath + +# sbteclipse plugin +.target + +# Tern plugin +.tern-project + +# TeXlipse plugin +.texlipse + +# STS (Spring Tool Suite) +.springBeans + +# Code Recommenders +.recommenders/ + +# Annotation Processing +.apt_generated/ +.apt_generated_test/ + +# Scala IDE specific (Scala & Java development for Eclipse) +.cache-main +.scala_dependencies +.worksheet + +# Uncomment this line if you wish to ignore the project description file. +# Typically, this file would be tracked if it contains build/dependency configurations: +#.project +### Intellij ### +.idea +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### Intellij Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/**/sonarlint/ + +# SonarQube Plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator/ + +### Java ### +# Compiled class file +*.class + +# Log file +*.log + +# BlueJ files +*.ctxt + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# Package Files # +*.war +*.nar +*.ear +*.zip +*.tar.gz +*.rar + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Gradle ### +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache + +# # Work around https://youtrack.jetbrains.com/issue/IDEA-116898 +# gradle/wrapper/gradle-wrapper.properties + +### Gradle Patch ### +**/build/ + +# End of https://www.gitignore.io/api/java,macos,gradle,intellij +/EAISIMWeb/ +/.apt_generated_tests/ diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..ad821c2 --- /dev/null +++ b/build.gradle @@ -0,0 +1,221 @@ +plugins { + id 'java-library' + id 'maven-publish' + id 'eclipse-wtp' + id 'idea' + id 'com.diffplug.eclipse.apt' version '3.41.1' +} +group 'com.eactive' +version '4.5.1-SNAPSHOT' + +def springVersion = "5.3.27" +def quartzVersion = "2.3.2" +def undertowVersion = "1.4.28.Final" +def queryDslVersion = "5.0.0" +def hibernateVersion = "5.6.15.Final" + +def nexusUrl = "https://nexus.eactive.synology.me:8090" +def generatedJavaDir = "$buildDir/generated/java" + +java { + toolchain { + languageVersion = JavaLanguageVersion.of(8) + } +} + +compileJava { + options.encoding = 'UTF-8' + sourceSets.main.java { srcDir generatedJavaDir } + options.generatedSourceOutputDirectory = project.file(generatedJavaDir) + + aptOptions { + processorArgs = [ 'querydsl.generatedAnnotationClass' : 'com.querydsl.core.annotations.Generated' ] + } +} + +jar { + exclude '**/persistence.xml' +} + +tasks.withType(JavaCompile) { + options.encoding = 'UTF-8' +} + +dependencies { + + annotationProcessor "org.projectlombok:lombok:1.18.28", "org.projectlombok:lombok-mapstruct-binding:0.2.0", "org.mapstruct:mapstruct-processor:1.5.5.Final" + annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}:jpa", "jakarta.persistence:jakarta.persistence-api:2.2.3", "jakarta.annotation:jakarta.annotation-api:1.3.5" + + //implementation project(':elink-online-core') + //implementation project(':elink-online-transformer') + api project(':elink-online-transformer') + + compileOnly fileTree(dir: 'libs', include: ['*.jar']) + + api (group: 'org.apache.activemq', name: 'activemq-console', version: '5.14.5'){ + exclude group: 'com.fasterxml.jackson.core' + } + api group: 'org.apache.activemq', name: 'activemq-spring', version: '5.14.5' + + api 'backport-util-concurrent:backport-util-concurrent:3.0' + + api 'com.github.vladimir-bukhtoyarov:bucket4j-jcache:6.0.2' + api 'io.github.resilience4j:resilience4j-core:1.7.1' + api 'io.github.resilience4j:resilience4j-circuitbreaker:1.7.1' + api 'io.github.resilience4j:resilience4j-micrometer:1.7.1' + api 'io.micrometer:micrometer-core:1.5.17' + api 'io.micrometer:micrometer-registry-prometheus:1.5.17' + + //api "com.eactive:mina-core-1.0.10-custom:1.0:custom@jar" + api ("org.apache.mina:mina-filter-ssl:1.0.10") { + exclude module: 'mina-core' + } + + api group: 'commons-fileupload', name: 'commons-fileupload', version: '1.5' + + api 'org.snmp4j:snmp4j:1.9.1f' + api group: 'com.lmax', name: 'disruptor', version: '3.4.4' + api group: 'commons-httpclient', name: 'commons-httpclient', version: '3.1' +// api group: 'log4j', name: 'log4j', version: '1.2.17' + + api 'com.nimbusds:nimbus-jose-jwt:9.24.3' + + api "io.undertow:undertow-servlet:${undertowVersion}" + api 'org.java-websocket:Java-WebSocket:1.3.9' + api 'javax.cache:cache-api:1.1.1' + + api 'org.apache.ignite:ignite-slf4j:2.14.0' + api 'org.apache.ignite:ignite-kubernetes:2.14.0' + + //api 'com.eactive:xc3:1.0' + //api 'com.eactive:xc2:1.0' + //api 'com.eactive:INICrypto:v4.1.22' + //api 'com.eactive:INISAFECore:v2.2.28' + //api 'com.eactive:INISAFENet:v7.2.51_NS' + //api 'com.eactive:INISAFEPKI:v1.1.33' + + //api 'com.eactive:Egloan_aes:1.0' + //api 'com.eactive:ExafeiE2E:1.0' + //api 'com.eactive:tcseed:1.0' + //api "com.eactive:backport-util-concurrent:1.0" + + api "org.quartz-scheduler:quartz:${quartzVersion}" + + api group: 'commons-cli', name: 'commons-cli', version: '1.1' + api "org.springframework:spring-web:${springVersion}" + api "org.springframework:spring-jms:${springVersion}" + api "org.springframework.security.oauth:spring-security-oauth2:2.3.8.RELEASE" + + api 'org.yaml:snakeyaml:1.30' + implementation 'org.codehaus.groovy:groovy:3.0.18' + + api 'org.slf4j:jul-to-slf4j:1.7.35' + api 'org.slf4j:jcl-over-slf4j:1.7.35' + api 'org.slf4j:log4j-over-slf4j:1.7.35' + api 'org.slf4j:slf4j-api:1.7.35' + + //compileOnly "tmax:webt:7.0.2.0-r11661-forJEUS8.0" + //compileOnly "tmax:webtasync:2.0.3.1-r11801-forJEUS8.1" + //compileOnly "tmax:jeus:1.0" + + api 'org.apache.httpcomponents.client5:httpclient5:5.1' + api 'org.apache.httpcomponents.core5:httpcore5:5.1' + + compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '3.1.0' + compileOnly group: 'javax.servlet.jsp', name: 'javax.servlet.jsp-api', version: '2.3.3' + compileOnly 'javax.resource:javax.resource-api:1.7' + compileOnly 'javax.jms:javax.jms-api:2.0.1' + + compileOnly group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.13.1' + + testRuntimeOnly 'com.h2database:h2:2.1.214' + testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' + testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' + testImplementation 'org.springframework.boot:spring-boot-starter-test:2.6.15' + testImplementation 'junit:junit:4.4' +} + +test { + useJUnitPlatform() +} + +publishing { + repositories { + maven { + name = 'eactiveRepository' + def releasesRepoUrl = "${nexusUrl}/repository/maven-releases/" + def snapshotsRepoUrl = "${nexusUrl}/repository/maven-snapshots/" + url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl + credentials(PasswordCredentials) + } + } + + publications { + mavenJava(MavenPublication) { + from components.java + pom { + description = "eLink common module" + licenses { + license { + name = "Commercial License" + url = "http://eactive.co.kr" + } + } + } + } + } +} + +task sourcesJar(type: Jar, dependsOn: classes) { + archiveClassifier = 'sources' + from sourceSets.main.allSource +} + +artifacts { + archives sourcesJar +} + +configurations.all { + exclude group: 'org.apache.geronimo.specs', module: 'geronimo-jta_1.0.1B_spec' +// exclude group: 'javax.transaction', module: 'javax.transaction-api' + resolutionStrategy { + // 동적 버전 탐색을 10분 캐시 + cacheDynamicVersionsFor 10, 'minutes' + // 변하는 모듈(Changing Module)을 캐시하지 않음 + cacheChangingModulesFor 0, 'seconds' + } +} + +task settingEclipseEncoding { + if (project.file('.settings').exists()) { + File f = file('.settings/org.eclipse.core.resources.prefs') + f.write('eclipse.preferences.version=1\n') + f.append('encoding/=utf-8') + } +} + +task initDirs() { + file(generatedJavaDir).mkdirs() +} + +eclipse { + synchronizationTasks settingEclipseEncoding, initDirs + jdt { + apt { + // generated 된 패스 경로를 .setting/org.eclipse.jdt.apt.core.prefs 의 org.eclipse.jdt.apt.genSrcDir에 적용한다. + // project > properties > Java Compiler > Annoation Processing 화면에서 확인 가능하다. + genSrcDir = file(generatedJavaDir) + } + } + project { + natures = ['org.eclipse.buildship.core.gradleprojectnature', + 'org.eclipse.jdt.core.javanature', + 'org.eclipse.wst.common.project.facet.core.nature', + 'org.eclipse.wst.common.modulecore.ModuleCoreNature', + 'org.eclipse.jem.workbench.JavaEMFNature'] + buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder' + buildCommand 'org.eclipse.wst.validation.validationbuilder' + buildCommand 'org.eclipse.wst.common.project.facet.core.builder' + buildCommand 'org.eclipse.jdt.core.javabuilder' + } +} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000..41d9927 Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..54228ea --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +networkTimeout=10000 diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..1b6c787 --- /dev/null +++ b/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" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/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 diff --git a/libs/Egloan_aes-1.0.jar b/libs/Egloan_aes-1.0.jar new file mode 100644 index 0000000..db2be2c Binary files /dev/null and b/libs/Egloan_aes-1.0.jar differ diff --git a/libs/ExafeiE2E-1.0.jar b/libs/ExafeiE2E-1.0.jar new file mode 100644 index 0000000..065331d Binary files /dev/null and b/libs/ExafeiE2E-1.0.jar differ diff --git a/libs/INICrypto-v4.1.22.jar b/libs/INICrypto-v4.1.22.jar new file mode 100644 index 0000000..9208a07 Binary files /dev/null and b/libs/INICrypto-v4.1.22.jar differ diff --git a/libs/INISAFECore-v2.2.28.jar b/libs/INISAFECore-v2.2.28.jar new file mode 100644 index 0000000..92da7c6 Binary files /dev/null and b/libs/INISAFECore-v2.2.28.jar differ diff --git a/libs/INISAFENet-v7.2.51_NS.jar b/libs/INISAFENet-v7.2.51_NS.jar new file mode 100644 index 0000000..92bbc05 Binary files /dev/null and b/libs/INISAFENet-v7.2.51_NS.jar differ diff --git a/libs/INISAFEPKI-v1.1.33.jar b/libs/INISAFEPKI-v1.1.33.jar new file mode 100644 index 0000000..c3daa57 Binary files /dev/null and b/libs/INISAFEPKI-v1.1.33.jar differ diff --git a/libs/asm-9.3.jar b/libs/asm-9.3.jar new file mode 100644 index 0000000..bd8b948 Binary files /dev/null and b/libs/asm-9.3.jar differ diff --git a/libs/jeus-1.0.jar b/libs/jeus-1.0.jar new file mode 100644 index 0000000..5609e28 Binary files /dev/null and b/libs/jeus-1.0.jar differ diff --git a/libs/json-path-2.9.0.jar b/libs/json-path-2.9.0.jar new file mode 100644 index 0000000..f731408 Binary files /dev/null and b/libs/json-path-2.9.0.jar differ diff --git a/libs/json-simple-1.1.1-custom-1.2.jar b/libs/json-simple-1.1.1-custom-1.2.jar new file mode 100644 index 0000000..d7fd255 Binary files /dev/null and b/libs/json-simple-1.1.1-custom-1.2.jar differ diff --git a/libs/json-smart-2.5.0.jar b/libs/json-smart-2.5.0.jar new file mode 100644 index 0000000..2685e03 Binary files /dev/null and b/libs/json-smart-2.5.0.jar differ diff --git a/libs/mina-core-1.0.10-custom-1.0-custom.jar b/libs/mina-core-1.0.10-custom-1.0-custom.jar new file mode 100644 index 0000000..3add5c8 Binary files /dev/null and b/libs/mina-core-1.0.10-custom-1.0-custom.jar differ diff --git a/libs/tcseed-1.0.jar b/libs/tcseed-1.0.jar new file mode 100644 index 0000000..f23ad49 Binary files /dev/null and b/libs/tcseed-1.0.jar differ diff --git a/libs/webt-7.0.2.0-r11661-forJEUS8.0.jar b/libs/webt-7.0.2.0-r11661-forJEUS8.0.jar new file mode 100644 index 0000000..f5b6c66 Binary files /dev/null and b/libs/webt-7.0.2.0-r11661-forJEUS8.0.jar differ diff --git a/libs/webtasync-2.0.3.1-r11801-forJEUS8.1.jar b/libs/webtasync-2.0.3.1-r11801-forJEUS8.1.jar new file mode 100644 index 0000000..a057b7f Binary files /dev/null and b/libs/webtasync-2.0.3.1-r11801-forJEUS8.1.jar differ diff --git a/libs/xc2-1.0.jar b/libs/xc2-1.0.jar new file mode 100644 index 0000000..676cb03 Binary files /dev/null and b/libs/xc2-1.0.jar differ diff --git a/libs/xc3-1.0.jar b/libs/xc3-1.0.jar new file mode 100644 index 0000000..7f53f93 Binary files /dev/null and b/libs/xc3-1.0.jar differ diff --git a/resources/standard-layout-sample.csv b/resources/standard-layout-sample.csv new file mode 100644 index 0000000..7a289f0 --- /dev/null +++ b/resources/standard-layout-sample.csv @@ -0,0 +1,29 @@ +#----------------------------------------------------------------------------- +# comment start with # +# level; // 0 : root ~ n +# type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA +# size // 0 : variable, > 0 fixed +# fieldType; // 0: ELEMENT, 1: ATTRIBUTE, +# length; +# dataType; // 1: String, 2: Number,11: ZZ String, 12: LL Number +#----------------------------------------------------------------------------- +# name ,level ,type ,size ,fieldType ,length ,dataType ,,refPath, refValue,value +#----------------------------------------------------------------------------- +ElinkHeader ,0,0,1,0, 0,0,,, +Header ,1,2,1,1, 0,0,,, +StndCicsTrncd ,2,1,1,1,10,0,,, +StndIntnlStndTelgmLen,2,1,1,1,10,11,,,0 +StndTranBaseYmd ,2,1,1,1,10,0,,, +Common ,1,2,0,0, 0,0,Header.StndCicsTrncd,JI6H,null +TranInfo ,2,2,1,0, 0,0,,, +StndCicsTrncd ,3,1,1,0, 3,0,,, +StndTelgmRecvTranCd ,3,1,1,0,10,0,,, +StndPrcssRtdTranCd ,3,1,1,0,10,0,,, +Array ,1,3,0,0, 3,0,,, +Item1 ,2,1,1,0,10,0,,,JI6H +Group ,2,3,1,0, 1,0,,, +gitem1 ,3,1,1,0,10,1,,,726 +gitem2 ,3,1,1,0,10,0,,,20220905 +FArray ,1,4,0,0,10,0,,, +bizData ,1,9,1,0, 0,0,,, +zzData ,1,1,1,0, 2,10,,,ZZ \ No newline at end of file diff --git a/resources/standard-layout.csv b/resources/standard-layout.csv new file mode 100644 index 0000000..0a22fef --- /dev/null +++ b/resources/standard-layout.csv @@ -0,0 +1,41 @@ +#----------------------------------------------------------------------------- +# comment start with # +# level; // 0 : root ~ n +# type; // 0: Message, 1: Field, 2:Group 3, Grid, 4 : Field Array, 9 : BIZ DATA +# size // 0 : variable, > 0 fixed +# fieldType; // 0: ELEMENT, 1: ATTRIBUTE, +# length; +# dataType; // 1: String, 2: Number,11: ZZ String, 12: LL Number +#----------------------------------------------------------------------------- +# name ,level ,type ,size ,fieldType ,length ,dataType ,,refPath, refValue,value +#----------------------------------------------------------------------------- +# name ,level ,type ,size ,fieldType ,length ,dataType ,refPath, refValue, value +STD_HNCPHEADER_REQ ,0 ,1 ,1 ,1 ,0 ,1 , , ,,표준헤더 +msg_len ,1 ,2 ,1 ,1 ,6 ,12 , , ,199,전문길이 +global_id ,1 ,2 ,1 ,1 ,29 ,1 , , ,GIDNO00000000001111,Global아이디 +service_id ,1 ,2 ,1 ,1 ,10 ,1 , , ,ELINKSVC01,거래코드 +service_cmt ,1 ,2 ,1 ,1 ,100 ,1 , , ,ELINK TEST Service,거래코드설명 +service_tn ,1 ,2 ,1 ,1 ,1 ,1 , , ,1,거래구분 +Session_id ,1 ,2 ,1 ,1 ,100 ,1 , , ,SESSIONID001,Session아이디 +encrypt_yn ,1 ,2 ,1 ,1 ,2 ,1 , , ,NO,전문암호화여부 +http_url ,1 ,2 ,1 ,1 ,100 ,1 , , ,,HTTPURL정보 +screen_id ,1 ,2 ,1 ,1 ,13 ,1 , , ,SCREEN0000001,화면ID +scr_no ,1 ,2 ,1 ,1 ,30 ,1 , , ,000000000100000000020000000003,화면번호 +scr_dsc ,1 ,2 ,1 ,1 ,100 ,1 , , ,,화면명 +usr_id ,1 ,2 ,1 ,1 ,10 ,1 , , ,USER000001,사용자ID +ip_addr ,1 ,2 ,1 ,1 ,47 ,1 , , ,,IPAddress +ip_mac ,1 ,2 ,1 ,1 ,12 ,1 , , ,,ClientMAC Address +com_code ,1 ,2 ,1 ,1 ,4 ,1 , , ,EACT,그룹사코드 +head_code ,1 ,2 ,1 ,1 ,7 ,1 , , ,EACT001,본부코드 +dept_cd ,1 ,2 ,1 ,1 ,7 ,1 , , ,ELINK01,부서코드 +conn_tp ,1 ,2 ,1 ,1 ,2 ,1 , , ,CH,요청채널구분 +Inter_chn ,1 ,2 ,1 ,1 ,2 ,1 , , ,EA,시스템구분 +recv_tm ,1 ,2 ,1 ,1 ,17 ,1 , , ,20220928000000000,전문수신시간 +send_tm ,1 ,2 ,1 ,1 ,17 ,1 , , ,,전문송신시간 +return_gubun ,1 ,2 ,1 ,1 ,1 ,1 , , ,S,전문응답구분 +return_value ,1 ,2 ,1 ,1 ,1 ,1 , , ,,처리결과 +msg_id ,1 ,2 ,1 ,1 ,7 ,1 , , ,,오류코드 +msg_nm ,1 ,2 ,1 ,1 ,250 ,1 , , ,,오류메시지 +filler ,1 ,2 ,1 ,1 ,125 ,1 , , ,,Filler +bizData ,1 ,9 ,0 ,1 ,0 ,1 , , ,,업무데이터 +zzData ,1 ,2 ,0 ,1 ,2 ,11 , , ,,ZZ플래그 \ No newline at end of file diff --git a/resources/standard-message-config-test.properties b/resources/standard-message-config-test.properties new file mode 100644 index 0000000..ec9b993 --- /dev/null +++ b/resources/standard-message-config-test.properties @@ -0,0 +1,11 @@ +layout.file.type=CSV +layout.file.path=./resources/standard-layout-sample.csv +mapper.class=com.eactive.eai.message.test.TestInterfaceMapper +mapper.definition=./resources/standard-message-mapping-config.properties +reader.JSON=com.eactive.eai.message.parser.JsonReader +reader.JSN=com.eactive.eai.message.parser.JsonReader +reader.UJN=com.eactive.eai.message.parser.JsonReader +reader.XML=com.eactive.eai.message.parser.XmlReader +reader.UXL=com.eactive.eai.message.parser.XmlReader +reader.ASC=com.eactive.eai.message.parser.FlatReader +reader.FLAT=com.eactive.eai.message.parser.FlatReader \ No newline at end of file diff --git a/resources/standard-message-config.properties b/resources/standard-message-config.properties new file mode 100644 index 0000000..7a827b7 --- /dev/null +++ b/resources/standard-message-config.properties @@ -0,0 +1,20 @@ +# layout : StandardMessage layout definition +layout.file.type=CSV +layout.file.path=./resources/standard-layout.csv +layout.filter.FLAT=com.eactive.eai.message.filter.FlatMessageFilter +# mapper : StandardMessage's fields getter/setter interface +mapper.class=com.eactive.eai.message.service.DefaultInterfaceMapper +mapper.definition=./resources/standard-message-mapping-config.properties +# reader : parsing input data to StandardMessage +reader.JSON=com.eactive.eai.message.parser.JsonReader +reader.JSN=com.eactive.eai.message.parser.JsonReader +reader.UJN=com.eactive.eai.message.parser.JsonReader +reader.XML=com.eactive.eai.message.parser.XmlReader +reader.UXL=com.eactive.eai.message.parser.XmlReader +reader.ASC=com.eactive.eai.message.parser.FlatReader +reader.FLAT=com.eactive.eai.message.parser.FlatReader +encode.flat=euc-kr +encode.value=euc-kr +encode.xml=utf-8 +# version.layout.name=VERSION_SAMPLE +# version.mapper.definition=./resources/version-message-mapping-config.properties \ No newline at end of file diff --git a/resources/standard-message-mapping-config-sample.properties b/resources/standard-message-mapping-config-sample.properties new file mode 100644 index 0000000..63b7432 --- /dev/null +++ b/resources/standard-message-mapping-config-sample.properties @@ -0,0 +1,28 @@ +REQ_SYS_CODE=systemHeader.DMND_SYS_CD +CHANNEL_TYPE_CD=stdcommon.chnlTycd +CHANNEL_DETAIL_CD=stdcommon.chnlDtlsClcd +SEND_TIME=stdheader.send_tm +GUID=stdheader.global_id +SYSTEM_TYPE=stdheader.Inter_chn +RECV_TIME=stdheader.recv_tm +RETURN_VALUE=stdheader.return_value +GUID_ORG=stdcommon.ortrGuid +GUID_SEQ=stdheader.global_id +#SERVICE_ID=stdheader.service_id +SERVICE_ID=service_id +RETURN_SERVICE_ID=stdcommon.procsRsltRcmsSrvcId +INTERFACE_ID=stdheader.service_id +SESSION_ID=stdheader.Session_id +#SEND_RECV_DIVISION=stdheader.return_gubun +SEND_RECV_DIVISION=service_tn +IN_EX_DIVISION=stdcommon.hmabDvcd +OPERATION_ENV=stdcommon.sysOprtEnvDvcd +FIRST_REQ_IP=stdheader.ip_addr +RECOVER_YN=stdcommon.ortrRestrYn +INST_CODE=stdheader.com_code +TIMEOUT=stdheader.gnrzTmotTktm +ERROR_CODE=stdheader.msg_id +ERROR_MSG=stdheader.msg_nm +USER_ID=stdheader.usr_id +RESPONSE_TYPE=stdcommon.procsRsltDvcd +SYNC_ASYNC_TYPE=stdcommon.txSynzDvcd diff --git a/resources/standard-message-mapping-config.properties b/resources/standard-message-mapping-config.properties new file mode 100644 index 0000000..a24deaf --- /dev/null +++ b/resources/standard-message-mapping-config.properties @@ -0,0 +1,26 @@ +REQ_SYS_CODE=Inter_chn +CHANNEL_TYPE_CD= +CHANNEL_DETAIL_CD=conn_tp +SEND_TIME=send_tm +GUID=global_id +SYSTEM_TYPE=service_tn +RECV_TIME=recv_tm +RETURN_VALUE=return_value +GUID_ORG=stdcommon.ortrGuid +GUID_SEQ=stdheader.global_id +SERVICE_ID=service_id +RETURN_SERVICE_ID=stdcommon.procsRsltRcmsSrvcId +INTERFACE_ID=service_id +SESSION_ID=Session_id +SEND_RECV_DIVISION=service_tn +IN_EX_DIVISION=stdcommon.hmabDvcd +OPERATION_ENV=stdcommon.sysOprtEnvDvcd +FIRST_REQ_IP=ip_addr +RECOVER_YN=stdcommon.ortrRestrYn +INST_CODE=stdheader.com_code +TIMEOUT=stdheader.gnrzTmotTktm +ERROR_CODE=msg_id +ERROR_MSG=msg_nm +USER_ID=usr_id +RESPONSE_TYPE=stdcommon.procsRsltDvcd +SYNC_ASYNC_TYPE=stdcommon.txSynzDvcd diff --git a/resources/version-message-mapping-config.properties b/resources/version-message-mapping-config.properties new file mode 100644 index 0000000..97e97e7 --- /dev/null +++ b/resources/version-message-mapping-config.properties @@ -0,0 +1,4 @@ +service_id=header.if_id +global_id=header.guid +service_tn=header.req_type +bizData=bizData \ No newline at end of file diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..0791851 --- /dev/null +++ b/settings.gradle @@ -0,0 +1,9 @@ +rootProject.name = 'elink-online-common' + +include 'elink-online-core-jpa' +include 'elink-online-core' +include 'elink-online-transformer' + +project (':elink-online-core-jpa').projectDir = new File(settingsDir, "../elink-online-core-jpa") +project (':elink-online-core').projectDir = new File(settingsDir, "../elink-online-core") +project (':elink-online-transformer').projectDir = new File(settingsDir, "../elink-online-transformer") \ No newline at end of file diff --git a/src/main/java/META-INF/persistence.xml b/src/main/java/META-INF/persistence.xml new file mode 100644 index 0000000..549f8be --- /dev/null +++ b/src/main/java/META-INF/persistence.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/AdapterDAO.java b/src/main/java/com/eactive/eai/adapter/AdapterDAO.java new file mode 100644 index 0000000..73ba812 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/AdapterDAO.java @@ -0,0 +1,82 @@ +package com.eactive.eai.adapter; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.adapter.loader.AdapterGroupLoader; +import com.eactive.eai.adapter.loader.AdapterLoader; +import com.eactive.eai.adapter.mapper.AdapterGroupMapper; +import com.eactive.eai.adapter.mapper.AdapterMapper; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.adapter.Adapter; +import com.eactive.eai.data.entity.onl.adapter.AdapterGroup; + +@Service +@Transactional +public class AdapterDAO extends BaseDAO { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private AdapterGroupLoader adapterGroupLoader; + + @Autowired + private AdapterLoader adapterLoader; + + @Autowired + private AdapterGroupMapper adapterGroupMapper; + + @Autowired + private AdapterMapper adapterMapper; + + public List getAllAdapterGroups() throws DAOException { + try { + List adapterGroups = adapterGroupLoader.selectAllGroups(); + return adapterGroups.stream().map(adapterGroupMapper::toVo).collect(Collectors.toList()); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAAC001")); + } + } + + public List getAllAdapters(String adapterGroupName) throws DAOException { + List al = new ArrayList<>(); + + try { + Iterable adapters = adapterLoader.selectAdaptersByGroup( + com.eactive.eai.common.server.Keys.DEFAULT_SERVER, adapterGroupName, + EAIServerManager.getInstance().getLocalServerName()); + + for (Adapter adapter : adapters) { + AdapterVO vo = adapterMapper.toVo(adapter); + al.add(vo); + } + return al; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAAC002")); + } + } + + public AdapterGroupVO getAdapterGroup(String adapterGroupName) throws DAOException { + try { + AdapterGroup adapterGroup = adapterGroupLoader.getById(adapterGroupName); + AdapterGroupVO gvo = adapterGroupMapper.toVo(adapterGroup); + List adapterVos = adapterGroup.getAdapters().stream().map(adapterMapper::toVo) + .collect(Collectors.toList()); + + adapterVos.forEach(gvo::addAdapterVO); + return gvo; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAAC009")); + } + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/AdapterGroupVO.java b/src/main/java/com/eactive/eai/adapter/AdapterGroupVO.java new file mode 100644 index 0000000..b790e16 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/AdapterGroupVO.java @@ -0,0 +1,569 @@ +package com.eactive.eai.adapter; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.Logger; + +public class AdapterGroupVO implements Serializable, Lifecycle { + private static final long serialVersionUID = -8613631838169562236L; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private String name; // 어뎁터업무그룹명[TSEAIAD01.ADPTRBZWKGROUPNAME] + private String adptrMsgPtrnCd; // 어댑터메시지유형코드[TSEAIAD01.ADPTRMSGPTRNCD] //[K, N, S] 값을 가짐 + private String eaiBizCode; // EAI업무구분코드[TSEAIAD01.EAIBZWKDSTCD] + private String type; // 어댑터코드[TSEAIAD01.ADPTRCD] + private String messageType; // 어댑터메시지구분코드[TSEAIAD01.ADPTRMSGDSTCD] + private String messageEncode; // 어댑터메시지구분코드[TSEAIAD01.MSGENCODE] + private String gubun; // 어뎁터입출력구분코드[TSEAIAD01.ADPTRIODSTCD] + private String refClass; // 참고클래스명[TSEAIAD01.REFCLSNAME] + private boolean srLogFlag; // 송수신시각로그여부[TSEAIAD01.SNDRCVHMSLOGYN] + private boolean usedFlag; // 어댑터사용여부[TSEAIAD01.ADPTRUSEYN] + private boolean spcfcLUUseYn; // 특정LU사용여부[TSEAIAD01.SPCFCLUUSEYN] -> 용도변경 : 로그밸런싱 방식으로 사용 RR/LC + private String description; // 어댑터업무그룹설명[TSEAIAD01.ADPTRBZWKGROUPDESC] + private String osidInstiNo; // 대외기관번호[TSEAIAD01.OSIDINSTINO] + // KESA F/W사용여부[TSEAIAD01.KESAUSEYN] + // 0 : KESA 미사용, 1: nKESA 사용, 2: uKESA 사용, 3: zKESA 사용 + private String kesaUseYn; + + // 0 : 기본어댑터, 1: TAS어댑터, 2: TAS참조대표어댑터 + private String testMasterYn; + private String adptrNickName; + private Map adapters; + + private Vector actives; + private Vector disables; + + private List adapterNames; + private String companyCodeData; // 업체코드데이터 (업체코드 추출정보 등록) + private String adptrInstiCode; // 어댑터업체코드 + private String bidInterface; // MCI에서 bid 거래시의 대표 인터페이스 + private AtomicInteger idx = new AtomicInteger(0); + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private int currentTx; + private long successTx; + private long errorTx; + + private String linkedAdapterGroup; + private String sameSessionYn; + private String pairAdapterYn; + private String clientId; + + private boolean weighted = false; + + + public AdapterGroupVO() { + this(""); + } + + public AdapterGroupVO(String name) { + this.name = name; + this.adapters = new ConcurrentHashMap<>(); + this.actives = new Vector<>(); + this.disables = new Vector<>(); + this.adapterNames = new ArrayList<>(); + } + + public boolean isWeighted() { + return weighted; + } + + public void setWeighted(boolean weighted) { + this.weighted = weighted; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void setEaiBizCode(String eaiBizCode) { + this.eaiBizCode = eaiBizCode; + } + + public String getEaiBizCode() { + return this.eaiBizCode; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return this.type; + } + + public void setGubun(String gubun) { + this.gubun = gubun; + } + + public String getGubun() { + return this.gubun; + } + + public void setMessageType(String messageType) { + this.messageType = messageType; + } + + public String getMessageType() { + return this.messageType; + } + + public String getMessageEncode() { + return messageEncode; + } + + public void setMessageEncode(String messageEncode) { + this.messageEncode = messageEncode; + } + + public void setRefClass(String refClass) { + this.refClass = refClass; + } + + public String getRefClass() { + return this.refClass; + } + + public void setSrLogFlag(boolean srLogFlag) { + this.srLogFlag = srLogFlag; + } + + public boolean isSrLogFlag() { + return this.srLogFlag; + } + + public void setUsedFlag(boolean usedFlag) { + this.usedFlag = usedFlag; + } + + public boolean isUsedFlag() { + return this.usedFlag; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + return this.description; + } + + public void setSpcfcLUUseYn(boolean spcfcLUUseYn) { + this.spcfcLUUseYn = spcfcLUUseYn; + } + + public boolean isSpcfcLUUseYn() { + return this.spcfcLUUseYn; + } + + public void setAdptrMsgPtrnCd(String adptrMsgPtrnCd) { + this.adptrMsgPtrnCd = adptrMsgPtrnCd; + } + + public String getAdptrMsgPtrnCd() { + return this.adptrMsgPtrnCd; + } + + public String getOsidInstiNo() { + return osidInstiNo; + } + + public void setOsidInstiNo(String osidInstiNo) { + this.osidInstiNo = osidInstiNo; + } + + public String getKesaUseYn() { + return kesaUseYn; + } + + public void setKesaUseYn(String kesaUseYn) { + this.kesaUseYn = kesaUseYn; + } + + public String getTestMasterYn() { + return testMasterYn; + } + + public void setTestMasterYn(String testMasterYn) { + this.testMasterYn = testMasterYn; + } + + public String getAdptrNickName() { + return adptrNickName; + } + + public void setAdptrNickName(String adptrNickName) { + this.adptrNickName = adptrNickName; + } + + public String getCompanyCodeData() { + return companyCodeData; + } + + public void setCompanyCodeData(String companyCodeData) { + this.companyCodeData = companyCodeData; + } + + public String getAdptrInstiCode() { + return adptrInstiCode; + } + + public void setAdptrInstiCode(String adptrInstiCode) { + this.adptrInstiCode = adptrInstiCode; + } + + public String getBidInterface() { + return bidInterface; + } + + public void setBidInterface(String bidInterface) { + this.bidInterface = bidInterface; + } + + public String getClientId() { return clientId; } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public synchronized void addAdapterVO(AdapterVO avo) { + this.adapters.put(avo.getName(), avo); + this.adapterNames.add(avo.getName()); + } + + public AdapterVO getAdapterVO(String adapterName) { + return adapters.get(adapterName); + } + + public synchronized void increase() { + ++currentTx; + } + + public synchronized void decrease() { + --currentTx; + } + + public int currentTx() { + return this.currentTx; + } + + // GW관련 어댑터 카운터 추가-시작 + public synchronized void increaseSuccess() { + ++successTx; + } + + public synchronized void increaseError() { + ++errorTx; + } + + public long successTx() { + return this.successTx; + } + + public long errorTx() { + return this.errorTx; + } + + public synchronized void resetCount() { + this.successTx = 0; + this.errorTx = 0; + } + // GW관련 어댑터 카운터 추가-종료 + + public String getLinkedAdapterGroup() { + return linkedAdapterGroup; + } + + public void setLinkedAdapterGroup(String linkedAdapterGroup) { + this.linkedAdapterGroup = linkedAdapterGroup; + } + + public String getSameSessionYn() { + return sameSessionYn; + } + + public void setSameSessionYn(String sameSessionYn) { + this.sameSessionYn = sameSessionYn; + } + + public String getPairAdapterYn() { + return pairAdapterYn; + } + + public void setPairAdapterYn(String pairAdapterYn) { + this.pairAdapterYn = pairAdapterYn; + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAIAAC030"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + if (!this.usedFlag) { + String code = "RECEAIAAC040"; + String[] msgArgs = new String[1]; + msgArgs[0] = name; + String errText = ExceptionUtil.make(code, msgArgs); + if (logger.isError()) + logger.error(errText); + throw new LifecycleException(errText); + } + + setWeighted(false); + idx.set(0); + + AdapterVO avo = null; + Iterator it = adapters.values().iterator(); + while (it.hasNext()) { + avo = it.next(); + if (avo instanceof Lifecycle) { + try { + LifecycleListener[] listeners = this.lifecycle.findLifecycleListeners(); + if (listeners != null) { + for (int j = 0; j < listeners.length; j++) { + avo.addLifecycleListener(listeners[j]); + } + } + + // 어댑터 프라퍼티에 active_onstartup = false 일 경우 + // EAI 서버 기동시에 Adapter를 start하지 않는다. + boolean activeOnstartup = true; + AdapterPropManager manager = AdapterPropManager.getInstance(); + String activeOnstartupValue = manager.getProperty(avo.getPropGroupName(), "active_onstartup"); + + if (activeOnstartupValue != null && "false".equals(activeOnstartupValue.trim())) { + activeOnstartup = false; + } + + String lbWeight = manager.getProperty(avo.getPropGroupName(), Keys.LB_WEIGHT); + if(StringUtils.isNoneEmpty(lbWeight)) { + int weight = 1; + try { + weight = Integer.parseInt(lbWeight); + } + catch(NumberFormatException ex) { + weight = 1; + } + + if(weight > 1) setWeighted(true); + avo.setWeight(weight); + } + + avo.setAdapterGroupVO(this); + if (activeOnstartup) { + avo.start(); + } else { + disable(avo); + } + } catch (Exception e) { + disable(avo); + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAIAAC031") + " : " + this.name, e); + } + } + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAIAAC032"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + AdapterVO avo = null; + Iterator it = adapters.values().iterator(); + while (it.hasNext()) { + avo = it.next(); + if (!avo.isStarted()) + continue; + if (avo instanceof Lifecycle) { + try { + avo.stop(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAIAAC033") + " : " + this.name, e); + } + } + } + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public boolean isStarted() { + return this.started; + } + + public void active(AdapterVO vo) { + if (!this.actives.contains(vo) && vo.isStatus()) { + this.actives.add(vo); + this.disables.remove(vo); + } + } + + public void disable(AdapterVO vo) { + if (!this.disables.contains(vo) && !vo.isStatus()) { + this.disables.add(vo); + this.actives.remove(vo); + } + } + + public boolean isAlive() { + return !this.actives.isEmpty(); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public Iterator getAdapters() { + return this.adapters.values().iterator(); + } + + public String[] getAdapterNames() { + String[] names = new String[this.adapterNames.size()]; + for (int i = 0; i < names.length; i++) { + names[i] = this.adapterNames.get(i); + } + return names; + } + + public synchronized AdapterVO nextAdapterVO() { + if (this.actives.isEmpty()) { + return null; + } + + if (this.actives.size() == 1) { + return this.actives.get(0); + } + + if(spcfcLUUseYn) { + if(logger.isDebug()) logger.debug("nextAdapterVO selectWithLeastConnection"); + return selectWithLeastConnection(); + } + else { + if(isWeighted()) { + if(logger.isDebug()) logger.debug("nextAdapterVO selectWithWeightedRoundRobin"); + return selectWithWeightedRoundRobin(); + } + else { + if(logger.isDebug()) logger.debug("nextAdapterVO selectWithRoundRobin"); + return selectWithRoundRobin(); + } + } + } + + private AdapterVO selectWithRoundRobin() { + try { + if (idx.get() >= this.actives.size()) + idx.set(0); + return this.actives.get(idx.getAndIncrement()); + } catch (Exception e) { + if (this.actives.isEmpty()) + return null; + idx.set(0); + return this.actives.get(idx.getAndIncrement()); + } + } + + private AdapterVO selectWithWeightedRoundRobin() { + try { + int totalWeight = actives.stream().mapToInt(AdapterVO::getWeight).sum(); + int currentIndex = idx.getAndIncrement() % totalWeight; + + for (AdapterVO adapter : actives) { + currentIndex -= adapter.getWeight(); + if (currentIndex < 0) { + return adapter; + } + } + return this.actives.get(0); + } catch (Exception e) { + if (this.actives.isEmpty()) + return null; + idx.set(0); + return this.actives.get(idx.getAndIncrement()); + } + } + + private AdapterVO selectWithLeastConnection() { + try { + AdapterVO selected = this.actives.get(0); + for (AdapterVO adapter : this.actives) { + if (adapter.getRequestCount() < selected.getRequestCount()) { + selected = adapter; + } + } + return selected; + } catch (Exception e) { + if (this.actives.isEmpty()) + return null; + return this.actives.get(0); + } + } + + public synchronized void removeAdapterVO(String name) { + adapters.remove(name); + this.adapterNames.remove(name); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("AdapterGroupVO[ name=").append(name); + sb.append(", adptrMsgPtrnCd=").append(adptrMsgPtrnCd); + sb.append(", eaiBizCode=").append(eaiBizCode); + sb.append(", type=").append(type); + sb.append(", messageType=").append(messageType); + sb.append(", messageEncode=").append(messageEncode); + sb.append(", gubun=").append(gubun); + sb.append(", refClass=").append(refClass); + sb.append(", srLogFlag=").append(srLogFlag); + sb.append(", usedFlag=").append(usedFlag); + sb.append(", spcfcLUUseYn=").append(spcfcLUUseYn); + sb.append(", description=").append(description); + sb.append(", osidInstiNo=").append(osidInstiNo); + sb.append(", kesaUseYn=").append(kesaUseYn); + sb.append(", testMasterYn=").append(testMasterYn); + sb.append(", adptrNickName=").append(adptrNickName); + sb.append(", companyCodeData=").append(companyCodeData); + sb.append(", adptrInstiCode=").append(adptrInstiCode); + sb.append(", bidInterface=").append(bidInterface); + sb.append(", actives=").append(this.actives.size()); + sb.append(", disables=").append(this.disables.size()); + sb.append(", AdapterList=").append(adapters); + sb.append(", clientId=").append(clientId); + sb.append(" ]"); + + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/AdapterManager.java b/src/main/java/com/eactive/eai/adapter/AdapterManager.java new file mode 100644 index 0000000..84bec69 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/AdapterManager.java @@ -0,0 +1,217 @@ +package com.eactive.eai.adapter; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class AdapterManager implements Lifecycle { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private boolean started; + + private HashMap adapterGroups = new HashMap<>(); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + @Autowired + private AdapterDAO adapterDAO; + + public static AdapterManager getInstance() { + return ApplicationContextProvider.getContext().getBean(AdapterManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAIAAC015"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + this.adapterGroups.clear(); + + List groups = null; + try { + adapterDAO = ApplicationContextProvider.getContext().getBean(AdapterDAO.class); + groups = adapterDAO.getAllAdapterGroups(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAIAAC016")); + } + + for (AdapterGroupVO gvo : groups) { + List adapterVos = null; + try { + adapterVos = adapterDAO.getAllAdapters(gvo.getName()); + for (AdapterVO vo : adapterVos) { + gvo.addAdapterVO(vo); + } + } catch (DAOException e) { + if (logger.isError()) + logger.error(ExceptionUtil.getErrorCode(e, "RECEAIAAC017")); + continue; + } + + if (logger.isDebug()) { + String[] msgArgs = new String[1]; + msgArgs[0] = gvo.toString(); + logger.debug(ExceptionUtil.make("RDCEAIAAC018", msgArgs)); + } + addAdapterGroupVO(gvo); + + try { + LifecycleListener[] listeners = this.lifecycle.findLifecycleListeners(); + if (listeners != null) { + for (int j = 0; j < listeners.length; j++) { + gvo.addLifecycleListener(listeners[j]); + } + } + + if (!gvo.isUsedFlag()) { + if (logger.isDebug()) + logger.debug("Not Used Adapter>> " + gvo); + continue; + } + gvo.start(); + } catch (Exception e) { + if (logger.isError()) + logger.error(ExceptionUtil.getErrorCode(e, "RECEAIAAC019")); + } + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAIAAC020"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + logger.warn("Stop Inbound Adapters ..."); + for (Iterator it = this.adapterGroups.values().iterator(); it.hasNext();) { + AdapterGroupVO vo = it.next(); + if ("I".equals(vo.getGubun())) { + try { + if (!vo.isStarted()) { + logger.warn("AdapterGroup not started skip stop. - " + vo); + continue; + } + if (vo instanceof Lifecycle) { + vo.stop(); + } + } catch (LifecycleException e) { + String[] msgArgs = { vo.toString() }; + String errText = ExceptionUtil.make("RECEAIAAC021", msgArgs); + if (logger.isError()) + logger.error(errText); + } + } + } + + logger.warn("Stop Outbound Adapters ..."); + for (Iterator it = this.adapterGroups.values().iterator(); it.hasNext();) { + AdapterGroupVO vo = it.next(); + if (!"I".equals(vo.getGubun())) { + try { + if (!vo.isStarted()) + continue; + if (vo instanceof Lifecycle) { + vo.stop(); + } + } catch (LifecycleException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = vo.toString(); + String errText = ExceptionUtil.make("RECEAIAAC021", msgArgs); + if (logger.isError()) + logger.error(errText); + } + } + } + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public boolean isStarted() { + return this.started; + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public AdapterVO getAdapterVO(String adapterGroupName, String adapterName) { + AdapterGroupVO gvo = adapterGroups.get(adapterGroupName); + if (gvo == null) + return null; + return gvo.getAdapterVO(adapterName); + } + + public AdapterGroupVO getAdapterGroupVO(String adapterGroupName) { + return adapterGroups.get(adapterGroupName); + } + + public AdapterGroupVO getAdapterGroup(String adapterGroupName) throws DAOException { + return adapterGroups.get(adapterGroupName); + } + + public AdapterGroupVO loadAdapterGroup(String adapterGroupName) throws DAOException { + return adapterDAO.getAdapterGroup(adapterGroupName); + } + + public void addAdapterGroupVO(AdapterGroupVO vo) { + if (vo != null) { + adapterGroups.put(vo.getName(), vo); + } + } + + public HashMap getAllAdapterGroupVO() { + return adapterGroups; + } + + public List getAllAdapterGroupNames() { + ArrayList al = new ArrayList<>(); + Iterator it = this.adapterGroups.keySet().iterator(); + while (it.hasNext()) { + al.add(it.next()); + } + Collections.sort(al); + return al; + } + + public void updateAdapterGroupVO(AdapterGroupVO vo) { + if (vo != null) + adapterGroups.put(vo.getName(), vo); + } + + public void removeAdapterGroupVO(String name) { + adapterGroups.remove(name); + } + + public void print() { + if (logger.isDebug()) + logger.debug("AdapterManager] All Adapter List>> " + this.adapterGroups); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/AdapterPropGroupDAO.java b/src/main/java/com/eactive/eai/adapter/AdapterPropGroupDAO.java new file mode 100644 index 0000000..e87f7c9 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/AdapterPropGroupDAO.java @@ -0,0 +1,65 @@ +package com.eactive.eai.adapter; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.adapter.loader.AdapterPropGroupLoader; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.adapter.AdapterPropGroup; + +@Service +@Transactional +public class AdapterPropGroupDAO extends BaseDAO { + + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private AdapterPropGroupLoader adapterPropGroupLoader; + + public Map getAllProperties() throws DAOException { + + Map adapterPropGroupVos = new HashMap<>(); + try { + logger.info("[ @@ Load Adapter Properties Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + Iterable adapterPropGroups = adapterPropGroupLoader + .loadAll() + .collect(Collectors.toList()); + + for (AdapterPropGroup adapterPropGroup : adapterPropGroups) { + AdapterPropGroupVO adapterPropGroupVO = getProperties(adapterPropGroup); + adapterPropGroupVos.put(adapterPropGroup.getPrptygroupname(), adapterPropGroupVO); + } + + logger.info("[>>Load Adapter Properties Configuration - ended ]"); + return adapterPropGroupVos; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICPM101")); + } + } + + private AdapterPropGroupVO getProperties(AdapterPropGroup adapterPropGroup) { + AdapterPropGroupVO adapterPropGroupVO = new AdapterPropGroupVO(adapterPropGroup.getPrptygroupname()); + adapterPropGroup.getAdapterProps().forEach(adapterProp -> adapterPropGroupVO + .addProperty(adapterProp.getId().getPrptyname(), adapterProp.getPrpty2val())); + return adapterPropGroupVO; + } + + public AdapterPropGroupVO getProperties(String grpNm) throws DAOException { + try { + AdapterPropGroup adapterPropGroup = adapterPropGroupLoader.getById(grpNm); + return getProperties(adapterPropGroup); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.make("RECEAICPM103", grpNm)); + } + } + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/AdapterPropGroupVO.java b/src/main/java/com/eactive/eai/adapter/AdapterPropGroupVO.java new file mode 100644 index 0000000..fd9ae39 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/AdapterPropGroupVO.java @@ -0,0 +1,106 @@ +package com.eactive.eai.adapter; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Properties; + +import com.eactive.eai.common.util.NullControl; + +/** +* 1. 기능 : 어뎁터 프라퍼티 정보를 를 정의한 Java Value Object 클래스 +* 2. 처리 개요 : 어뎁터 프라퍼티 정보를 정의한다. +* * - +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class AdapterPropGroupVO implements Serializable +{ + private String name; //어뎁터 프라퍼티 그룹명[TSEAIAD14.PrptyGroupName] + private String description; //어뎁터 프라퍼티 그룹설명[TSEAIAD14.PrptyGroupDesc] + private Properties props; //어뎁터 프라퍼티 명, 프라퍼티2값[TSEAIAD15.PrptyName, TSEAIAD15.Prpty2Val] + + public AdapterPropGroupVO() { + this(""); + } + + public AdapterPropGroupVO(String name) { + this(name,""); + } + + public AdapterPropGroupVO(String name, String description) { + this.name = name; + this.description = description; + this.props = new Properties(); + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + return NullControl.trimSpace(this.description); + } + + public String getProperty(String key) { + return (String)props.get(key); + } + + public String getProperty(String key, String defaultValue) { + String value = (String)props.get(key); + return (value==null) ? defaultValue : value; + } + + public void addProperty(String key, String value) { + props.put(key, NullControl.trimSpace(value)); + } + + public void setProperty(String key, String value) { + props.put(key,value); + } + + public void removeProperty(String key) { + props.remove(key); + } + + public String[] keys() { + Iterator it = this.props.keySet().iterator(); + String[] propKeys = new String[this.props.size()]; + for(int i = 0; it.hasNext(); i++){ + propKeys[i] = (String)it.next(); + } + Arrays.sort(propKeys); + return propKeys; + } + + public Properties getProperties() { + return props; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("AdapterPropGroupVO[ name=").append(name); + sb.append(", description=").append(description); + sb.append(", Properties=").append(props); + sb.append(" ]"); + + return sb.toString(); + } + + public void setProperties(Properties prop){ + this.props = prop; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/AdapterPropManager.java b/src/main/java/com/eactive/eai/adapter/AdapterPropManager.java new file mode 100644 index 0000000..f566276 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/AdapterPropManager.java @@ -0,0 +1,185 @@ +package com.eactive.eai.adapter; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; +import java.util.Properties; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class AdapterPropManager implements Lifecycle { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private PropertyChangeSupport property = new PropertyChangeSupport(this); + + private Map groups; + + private boolean started; + + @Autowired + private AdapterPropGroupDAO adapterPropGroupDAO; + + public static AdapterPropManager getInstance() { + return ApplicationContextProvider.getContext().getBean(AdapterPropManager.class); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + property.addPropertyChangeListener(listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + property.removePropertyChangeListener(listener); + } + + private PropertyChangeEvent createEvent(AdapterPropGroupVO source, String propertyName, Object oldValue, + Object newValue) { + return new PropertyChangeEvent(source, propertyName, oldValue, newValue); + } + + public boolean isStarted() { + return this.started; + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICPM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICPM201")); + } + + started = true; + if (logger.isWarn()) { + logger.warn("AdapterPropManager] It is started."); + } + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + this.groups = adapterPropGroupDAO.getAllProperties(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("AdapterPropManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("AdapterPropManager] reload all finished ..."); + } + } + + public synchronized void reload(String keyName) throws Exception { + AdapterPropGroupVO vo = adapterPropGroupDAO.getProperties(keyName); + if (vo != null) { + this.groups.put(keyName, vo); + } else { + throw new Exception("AdapterPropManager not found in Database : key[" + keyName + "]"); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICPM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + started = false; + + if (logger.isWarn()) { + logger.warn("AdapterPropManager] It is stopped."); + } + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public void addAdapterPropGroupVO(String name, String description) { + groups.put(name, new AdapterPropGroupVO(name, description)); + } + + public AdapterPropGroupVO getAdapterPropGroupVO(String name) { + return groups.get(name); + } + + public String getProperty(String key) { + + return getProperty(com.eactive.eai.common.server.Keys.DEFAULT_SERVER, key); + } + + public String getProperty(String group, String key) { + AdapterPropGroupVO vo = groups.get(group); + if (vo == null) + return null; + return vo.getProperty(key); + } + + public Properties getProperties(String group) { + AdapterPropGroupVO vo = groups.get(group); + if (vo == null) + throw new RuntimeException("Cannot find the Property Group in AdapterPropManager. - " + group); + if (vo.getProperties() == null) { + return new Properties(); + } + return (Properties) vo.getProperties().clone(); + } + + public void setProperty(String group, String key, String value) { + AdapterPropGroupVO gvo = groups.get(group); + String oldValue = gvo.getProperty(key); + gvo.setProperty(key, value); + + if (oldValue != null && !oldValue.equals(value)) { + property.firePropertyChange(createEvent(gvo, key, oldValue, value)); + } + } + + public void setAdapterPropGroupVO(String group, AdapterPropGroupVO vo) { + groups.put(group, vo); + } + + public void removeAdapterPropGroupVO(String name) { + groups.remove(name); + } + + public String[] getAllPropGroupNames() { + Iterator it = this.groups.keySet().iterator(); + String[] name = new String[this.groups.size()]; + for (int i = 0; it.hasNext(); i++) { + name[i] = it.next(); + } + + Arrays.sort(name); + return name; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/AdapterVO.java b/src/main/java/com/eactive/eai/adapter/AdapterVO.java new file mode 100644 index 0000000..b98600f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/AdapterVO.java @@ -0,0 +1,271 @@ +package com.eactive.eai.adapter; + +import java.io.Serializable; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListener; +import com.eactive.eai.adapter.listener.ListenerUtil; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.testcall.TestCallManager; +import com.eactive.eai.common.util.Logger; + +public class AdapterVO implements Serializable, Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private AdapterGroupVO adapterGroupVO; // 어댑터 그룹 + + private String adapterGroupName; // 어뎁터업무그룹명[TSEAIAD02.AdptrBzwkGroupName] + private String name; // 어뎁터업무명[TSEAIAD02.AdptrBzwkName] + private String eaiSevrInstncName; // 서버인스탄스명[TSEAIAD02.EAISevrInstncName] - migration added. + private String listenerClass; // 리스너클래스명[TSEAIAD02.LstnerClsName] + private String testCallClass; // 테스터클래스명[TSEAIAD02.TestClsName] + private String propGroupName; // 프라퍼티그룹명[TSEAIAD02.PrptyGroupName] + private String description; // 어댑터설명[TSEAIAD02.AdptrDesc] + private String propGroupDesc; // 프라퍼티그룹설명 + + private boolean status; + private transient AdapterListener adapterListener; + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private int requestCount; + private int weight; + + public int getWeight() { + return weight; + } + + public void setWeight(int weight) { + this.weight = weight; + } + + public int getRequestCount() { + return requestCount; + } + + public synchronized void incrementRequestCount() { + requestCount++; + } + + public synchronized void decrementRequestCount() { + requestCount--; + } + + public AdapterVO() { + this.requestCount = 0; + this.weight = 1; + } + + public AdapterVO(String name) { + this.name = name; + this.requestCount = 0; + this.weight = 1; + } + + public boolean isStarted() { + return this.started; + } + + public void setAdapterGroupName(String adapterGroupName) { + this.adapterGroupName = adapterGroupName; + } + + public String getAdapterGroupName() { + return this.adapterGroupName; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void setListenerClass(String listenerClass) { + this.listenerClass = listenerClass; + } + + public String getListenerClass() { + return this.listenerClass; + } + + public void setTestCallClass(String testCallClass) { + this.testCallClass = testCallClass; + } + + public String getTestCallClass() { + return this.testCallClass; + } + + public void setPropGroupName(String propGroupName) { + this.propGroupName = propGroupName; + } + + public String getPropGroupName() { + return this.propGroupName; + } + + public void setAdapterGroupVO(AdapterGroupVO group) { + this.adapterGroupVO = group; + } + + public AdapterGroupVO getAdapterGroupVO() { + return this.adapterGroupVO; + } + + private void setStatus(boolean status, boolean checkTestCall) { + this.status = status; + + if (checkTestCall && !this.status && this.testCallClass != null && !this.testCallClass.equals("")) { + TestCallManager tmanager = TestCallManager.getInstance(); + try { + tmanager.addTester(this); + + String[] msgArgs = new String[1]; + msgArgs[0] = this.toString(); + if (logger.isInfo()) + logger.info(ExceptionUtil.make("RICEAIAAC034", msgArgs)); + } catch (Exception e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RICEAIAAC035"), e); + } + } + + if (this.status) { + this.adapterGroupVO.active(this); + } else { + this.adapterGroupVO.disable(this); + } + } + + public synchronized void setStatus(boolean status) { + setStatus(status, true); + } + + public synchronized void setStatusForcely(boolean status) { + setStatus(status, false); + } + + public synchronized boolean isStatus() { + return this.status; + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAIAAC036"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + if (StringUtils.isEmpty(listenerClass)) { + listenerClass = ListenerUtil.getDefaultListenerClass(adapterGroupVO.getType(), adapterGroupVO.getGubun()); + if(logger.isWarn() && StringUtils.isNotEmpty(listenerClass)) { + logger.warn("Use DefaultListenerClass {} - {}",adapterGroupVO.getName(), listenerClass); + } + } + + if (StringUtils.isNotEmpty(listenerClass)) { + try { + adapterListener = (AdapterListener) Class.forName(listenerClass).newInstance(); + adapterListener.setAdapterInfo(this); + adapterListener.start(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAIAAC037"), e); + } + } + + started = true; + // SocketAdapter 기동시에 설정하므로 + // socket2일 때는 status 를 setting 하지 않음. + if (adapterListener == null) { + status = true; + this.adapterGroupVO.active(this); + } else { + if (!(adapterListener instanceof com.eactive.eai.adapter.socket2.SocketAdapterListener)) { + status = true; + } else { + this.adapterGroupVO.active(this); + } + } + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + if(logger.isWarn()) { + logger.warn("Adapter started {} {} - {}",adapterGroupVO.getName(), getName(), listenerClass); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAIAAC038"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + try { + if (adapterListener != null) + adapterListener.stop(); + } catch (AdapterException e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAIAAC039"), e); + } + + started = false; + status = false; + this.adapterGroupVO.disable(this); + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + return this.description; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("AdapterVO[ name=").append(name); + sb.append(", adapterGroupName=").append(adapterGroupName); + sb.append(", eaiSevrInstncName=").append(eaiSevrInstncName); + sb.append(", listenerClass=").append(listenerClass); + sb.append(", testCallClass=").append(testCallClass); + sb.append(", propGroupName=").append(propGroupName); + sb.append(", description=").append(description); + sb.append(", status=").append(status); + sb.append(", requestCount=").append(requestCount); + sb.append(" ]"); + + return sb.toString(); + } + + public void setEaiSevrInstncName(String eaiSevrInstncName) { + this.eaiSevrInstncName = eaiSevrInstncName; + } + + public String getEaiSevrInstncName() { + return this.eaiSevrInstncName; + } + + public void setPropGroupDesc(String propGroupDesc) { + this.propGroupDesc = propGroupDesc; + } + + public String getPropGroupDesc() { + return this.propGroupDesc; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/EAIException.java b/src/main/java/com/eactive/eai/adapter/EAIException.java new file mode 100644 index 0000000..367b934 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/EAIException.java @@ -0,0 +1,26 @@ +package com.eactive.eai.adapter; + +public class EAIException extends Exception { + private String code; + + public EAIException(String code, String msg) { + super(msg); + this.code = code; + } + + public EAIException(String msg) { + this("", msg); + } + + public EAIException(Throwable cause) { + super(cause); + } + + public EAIException(String msg, Throwable cause) { + super(msg, cause); + } + + public String getExceptionCode() { + return this.code; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/ElinkAdapter.java b/src/main/java/com/eactive/eai/adapter/ElinkAdapter.java new file mode 100644 index 0000000..b6f4396 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/ElinkAdapter.java @@ -0,0 +1,11 @@ +package com.eactive.eai.adapter; + +import java.util.Properties; + +// EAI 엔진에서 어댑터을 common하게 접근하기 위한 Interface +public interface ElinkAdapter { + public Object callService(String adapterGroupName, Properties prop, Object message, Properties tempProp) + throws Exception; + + public Object execute(Properties prop, Object message, Properties tempProp) throws Exception; +} diff --git a/src/main/java/com/eactive/eai/adapter/ElinkAdapterFactory.java b/src/main/java/com/eactive/eai/adapter/ElinkAdapterFactory.java new file mode 100644 index 0000000..121a550 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/ElinkAdapterFactory.java @@ -0,0 +1,75 @@ +package com.eactive.eai.adapter; + +import java.util.concurrent.ConcurrentHashMap; + +import com.eactive.eai.adapter.amq.AMQSenderAdapter; +import com.eactive.eai.adapter.app.BusinessApplicationAdapter; +import com.eactive.eai.adapter.http.client.HttpClientAdapterMain; +import com.eactive.eai.adapter.jtc.JtcClientAdapter; +import com.eactive.eai.adapter.socket2.SocketAdapterFacade; +import com.eactive.eai.adapter.wca.SNAAdapterClient; +import com.eactive.eai.adapter.websocket.WebSocketAdapterFacade; +import com.eactive.eai.adapter.webt.WebTClientAdapter; +import com.eactive.eai.common.util.Logger; + +public class ElinkAdapterFactory { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static final ElinkAdapterFactory factory = new ElinkAdapterFactory(); + private ConcurrentHashMap adapterMap; + + private ElinkAdapterFactory() { + adapterMap = new ConcurrentHashMap<>(); + } + + public static ElinkAdapterFactory newInstance() { + return factory; + } + + public ElinkAdapter getElinkAdapter(String adapterTypeName) throws Exception { + ElinkAdapter adapter = adapterMap.get(adapterTypeName); + if (adapter == null) { + adapter = createAdapter(adapterTypeName); + } + if (adapter == null) { + throw new RuntimeException("등록된 어댑터 타입을 찾을 수 없습니다. - " + adapterTypeName); + } + return adapter; + } + + private ElinkAdapter createAdapter(String adapterTypeName) throws Exception { + if (adapterTypeName == null) { + return null; + } + + ElinkAdapter adapter = null; + + if (adapterTypeName.equals(Keys.TYPE_HTTP)) { + adapter = new HttpClientAdapterMain(); + adapterMap.put(Keys.TYPE_HTTP, adapter); + } else if (adapterTypeName.equals(Keys.TYPE_NET2)) { + adapter = SocketAdapterFacade.getInstance(); + adapterMap.put(Keys.TYPE_NET2, adapter); + } else if (adapterTypeName.equals(Keys.TYPE_WSK)) { + adapter = WebSocketAdapterFacade.getInstance(); + adapterMap.put(Keys.TYPE_WSK, adapter); + } else if (adapterTypeName.equals(Keys.TYPE_WBT)) { + adapter = new WebTClientAdapter(); + adapterMap.put(Keys.TYPE_WBT, adapter); + } else if (adapterTypeName.equals(Keys.TYPE_JTC)) { + adapter = new JtcClientAdapter(); + adapterMap.put(Keys.TYPE_JTC, adapter); + } else if (adapterTypeName.equals(Keys.TYPE_APP)) { + adapter = new BusinessApplicationAdapter(); + adapterMap.put(Keys.TYPE_APP, adapter); + } else if (adapterTypeName.equals(Keys.TYPE_SNA)) { + adapter = new SNAAdapterClient(); + adapterMap.put(Keys.TYPE_SNA, adapter); + } else if (adapterTypeName.equals(Keys.TYPE_AMQ)) { + adapter = new AMQSenderAdapter(); + adapterMap.put(Keys.TYPE_SNA, adapter); + } else { + logger.warn("Unknown adapter type : " + adapterTypeName); + } + return adapter; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/ElinkDefaultAdapter.java b/src/main/java/com/eactive/eai/adapter/ElinkDefaultAdapter.java new file mode 100644 index 0000000..800ec72 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/ElinkDefaultAdapter.java @@ -0,0 +1,65 @@ +package com.eactive.eai.adapter; + +import java.net.SocketTimeoutException; +import java.nio.charset.Charset; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; + +public class ElinkDefaultAdapter implements ElinkAdapter { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private AdapterManager manager; + + public ElinkDefaultAdapter() { + this.manager = AdapterManager.getInstance(); + } + + public Object callService(String adapterGroupName, Properties prop, Object message, Properties tempProp) + throws Exception { + String adapterName = tempProp.getProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_NAME); + AdapterGroupVO group = this.manager.getAdapterGroupVO(adapterGroupName); + if (group == null) { + String code = "RECEAIAAC027"; + String[] msgArgs = new String[1]; + msgArgs[0] = adapterGroupName; + String errText = ExceptionUtil.make(code, msgArgs); + if (logger.isError()) + logger.error(errText); + throw new Exception(errText); + } + + AdapterVO adapterVO = null; + if(StringUtils.isNotEmpty(adapterName)) { + adapterVO = group.getAdapterVO(adapterName); + } + + group.increase(); + + tempProp.setProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_GROUP_NAME, adapterGroupName); + // set AdapterGroup charset + tempProp.setProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_OUT, + StringUtils.defaultIfBlank(group.getMessageEncode(), Charset.defaultCharset().name())); + + try { + if(adapterVO != null) adapterVO.incrementRequestCount(); + return execute(prop, message, tempProp); + } catch (SocketTimeoutException ste) { + throw ste; + } catch (HttpStatusException hse) { + throw hse; + } catch (Exception e) { + throw e; + } finally { + group.decrease(); + if(adapterVO != null) adapterVO.decrementRequestCount(); + } + } + + public Object execute(Properties prop, Object message, Properties tempProp) throws Exception { + throw new java.lang.UnsupportedOperationException("RECEAIAAC029"); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/Keys.java b/src/main/java/com/eactive/eai/adapter/Keys.java new file mode 100644 index 0000000..eeae7aa --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/Keys.java @@ -0,0 +1,48 @@ +package com.eactive.eai.adapter; + +// adapter 패키지에서 사용하는 상수를 정의한 Interface +public interface Keys { + public static final String OUT_ADAPTER_GROUP_NAME = "OUT_ADAPTER_GROUP_NAME"; + public static final String OUT_ADAPTER_NAME = "OUT_ADAPTER_NAME"; + + public static final String GUBUN_IN = "INBOUND"; + public static final String GUBUN_OUT = "OUTBOUND"; + + public static final String LB_WEIGHT = "LB_WEIGHT"; + + // inbound adapter charset + public static final String CHARSET_KEY_IN = "CHARSET_IN"; + // outbound adapter charset + public static final String CHARSET_KEY_OUT = "CHARSET_OUT"; + + public static final String TYPE_HTTP = "HTT"; + //HTTP custom port - undertow + public static final String TYPE_HTTP_CUSTOM = "HTC"; + public static final String TYPE_REST = "RST"; + public static final String TYPE_NET2 = "NET"; + public static final String TYPE_SNA = "SNA"; + public static final String TYPE_WSK = "WSK"; + public static final String TYPE_WBT = "WBT"; + public static final String TYPE_JTC = "JTC"; + public static final String TYPE_JCO = "JCO"; + public static final String TYPE_APP = "APP"; + public static final String TYPE_AMQ = "AMQ"; + + public static final String IF_NONSTANDARD = "N"; + public static final String IF_STANDARD = "K"; + public static final String IF_SUBSTANDARD = "B"; + + public static final String TESTMASTER_DEFAULT = "0"; + public static final String TESTMASTER_TAS = "1"; + public static final String TESTMASTER_TAS_INFO = "2"; + + public static final String ADAPTRER_IN = "I"; + public static final String ADAPTER_OUT = "O"; + + public static final String NO_KESA = "0"; + public static final String N_KESA = "1"; + public static final String U_KESA = "2"; + public static final String Z_KESA = "3"; + public static final String CARD_KESA = "C"; + +} diff --git a/src/main/java/com/eactive/eai/adapter/RequestDispatcher.java b/src/main/java/com/eactive/eai/adapter/RequestDispatcher.java new file mode 100644 index 0000000..3eb57d7 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/RequestDispatcher.java @@ -0,0 +1,136 @@ +package com.eactive.eai.adapter; + +import java.nio.charset.Charset; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.state.ElinkState; +import com.eactive.eai.common.state.ElinkStateException; +import com.eactive.eai.common.state.ElinkStateManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.inbound.processor.ProcessorFactory; + +public class RequestDispatcher { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static boolean isTASEnabledEAIServer = true; + static { + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + isTASEnabledEAIServer = eaiServerManager.isTASEnabledEAIServer(); + } + + private static ConcurrentHashMap dispatchers = new ConcurrentHashMap<>(); + + private String adapterGroupName; + private Processor processor; + + private RequestDispatcher(String adapterGroupName) { + this.adapterGroupName = adapterGroupName; + processor = ProcessorFactory.newInstance(); + } + + public static RequestDispatcher getRequestDispatcher(String adapterGroupName) { + return dispatchers.computeIfAbsent(adapterGroupName, k -> new RequestDispatcher(adapterGroupName)); + } + + public Object handle(String adapterName, Object message, Properties prop) throws Exception { + AdapterManager manager = AdapterManager.getInstance(); + + String inAdapterGroupName = this.adapterGroupName; + String actionClass = ""; + String adptrMsgPtrnCd = ""; + String messageType = MessageType.ASC; + + AdapterGroupVO group = manager.getAdapterGroupVO(inAdapterGroupName); + if (group == null) { + String code = "RECEAIAAC042"; + String[] msgArgs = new String[2]; + msgArgs[0] = adapterGroupName; + msgArgs[1] = adapterName; + String errText = ExceptionUtil.make(code, msgArgs); + if (logger.isError()) { + logger.error(errText); + } + throw new Exception(errText); + } + + AdapterVO adapter = group.getAdapterVO(adapterName); + if (adapter == null) { + String code = "RECEAIAAC022"; + String[] msgArgs = { adapterGroupName, adapterName, group.toString() }; + String errText = ExceptionUtil.make(code, msgArgs); + if (logger.isError()) { + logger.error(errText); + } + throw new Exception(errText); + } + + if (prop == null) { + prop = new Properties(); + } + + actionClass = group.getRefClass(); + adptrMsgPtrnCd = group.getAdptrMsgPtrnCd(); + messageType = group.getMessageType(); + try { + prop.put(Processor.ADAPTER_GROUP_NAME, inAdapterGroupName); + prop.put(Processor.ADAPTER_NAME, adapterName); + prop.put(Processor.STD_MESSAGE, adptrMsgPtrnCd); + prop.put(Processor.REQUEST_ACTION, actionClass); + prop.put(Processor.MESSAGE_TYPE, messageType); + + // set Inbound AdapterGroup charset + prop.setProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN, + StringUtils.defaultIfBlank(group.getMessageEncode(), Charset.defaultCharset().name())); + } catch (Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAIAAC024")); + } + + Object obj = null; + + // Check Elink lifecycle is STARTED + // otherwise reject this request + if(ElinkStateManager.getInstance().getState() != ElinkState.STARTED) { + logger.error("Elink STATE FAIL - " + ElinkStateManager.getInstance().getState()); + throw new ElinkStateException("Elink STATE FAIL - " + ElinkStateManager.getInstance().getState()); + } + + try { + ElinkStateManager.getInstance().startRequest(); + group.increase(); + adapter.incrementRequestCount(); + obj = processor.execute(message, prop); + group.increaseSuccess(); + } catch (HttpStatusException e) { + group.increaseError(); + throw e; + } catch (Exception e) { + group.increaseError(); + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAIAAC025")); + } finally { + group.decrease(); + adapter.decrementRequestCount(); + ElinkStateManager.getInstance().completeRequest(); + } + + if (obj != null) { + return obj; + } + else { + if (message instanceof byte[]) { + return new byte[0]; + } else if (message instanceof String) { + return ""; + } else { + return new Object(); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/amq/AMQAdapterConstants.java b/src/main/java/com/eactive/eai/adapter/amq/AMQAdapterConstants.java new file mode 100644 index 0000000..10626fb --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/amq/AMQAdapterConstants.java @@ -0,0 +1,30 @@ +package com.eactive.eai.adapter.amq; + +public class AMQAdapterConstants { + + // adapter properties + public static final String PROP_BROKER_URL = "BROKER_URL"; + public static final String PROP_USER_NAME = "BROKER_USER_NAME"; + public static final String PROP_PASSWORD = "BROKER_PASSWORD"; + public static final String PROP_POOL_MAX_CONNECTIONS = "POOL_MAX_CONNECTIONS"; + public static final String PROP_POOL_IDLE_TIMEOUT = "POOL_IDLE_TIMEOUT"; + public static final String PROP_POOL_EXPIRY_TIMEOUT = "POOL_EXPIRY_TIMEOUT"; + public static final String PROP_REQUEST_QUEUE_NAME = "REQUEST_QUEUE_NAME"; + public static final String PROP_REPLY_QUEUE_NAME = "REPLY_QUEUE_NAME"; + public static final String PROP_MESSAGE_TIME_TO_LIVE = "MESSAGE_TIME_TO_LIVE"; + public static final String PROP_MESSAGE_RECEIVE_TIMEOUT = "REPLY_MESSAGE_RECEIVE_TIMEOUT"; + public static final String PROP_RECEIVE_QUEUE_NAME = "RECEIVE_QUEUE_NAME"; + public static final String PROP_RECEIVE_MAX_CONCURRENT_CONSUMERS = "RECEIVE_MAX_CONCURRENT_CONSUMERS"; + public static final String PROP_REPLY_POOL_MAX_CONNECTIONS = "REPLY_POOL_MAX_CONNECTIONS"; + public static final String PROP_REPLY_POOL_IDLE_TIMEOUT = "REPLY_POOL_IDLE_TIMEOUT"; + public static final String PROP_REPLY_POOL_EXPIRY_TIMEOUT = "REPLY_POOL_EXPIRY_TIMEOUT"; + public static final String PROP_RELAY_PROPERTY_GROUP = "RELAY_PROPERTY_GROUP"; + public static final String PROP_RELAY_REQUEST_PROPERTY_KEYS = "RELAY_REQUEST_PROPERTY_KEYS"; + public static final String PROP_RELAY_RESPONSE_PROPERTY_KEYS = "RELAY_RESPONSE_PROPERTY_KEYS"; + + public static final String TEMP_INTERFACE_RESPONSE_TYPE = "INTERFACE_RESPONSE_TYPE"; + public static final String TEMP_MESSAGE_TYPE = "MESSAGE_TYPE"; + + public static final int DEFAULT_POOL_MAX_CONNECTIONS = 8; + public static final long DEFAULT_MESSAGE_RECEIVE_TIMEOUT = 30; +} diff --git a/src/main/java/com/eactive/eai/adapter/amq/AMQAdapterListener.java b/src/main/java/com/eactive/eai/adapter/amq/AMQAdapterListener.java new file mode 100644 index 0000000..8ac32ad --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/amq/AMQAdapterListener.java @@ -0,0 +1,53 @@ +package com.eactive.eai.adapter.amq; + +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListenerSupport; +import com.eactive.eai.common.util.Logger; + +/** + * @formatter:off + * ActiveMQ 어댑터 LISTENER 클래스 + * ActiveMQ 어댑터를 기동/중지한다 + * @formatter:on + */ +public class AMQAdapterListener extends AdapterListenerSupport { + public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + @Override + public void start() throws AdapterException { + if (logger.isInfo()) { + logger.info("= AMQAdapterListener start........."); + } + + try { + if (info == null) { + throw new Exception("AMQAdapterListener | AdapterVO가 NULL입니다."); + } + + AMQAdapterManager manager = AMQAdapterManager.getInstance(); + info.setStatus(true); + manager.start(info); + } catch (Throwable e) { + logger.error("[" + info.getName() + "] 구동 실패", e); + } + } + + @Override + public void stop() throws AdapterException { + if (logger.isInfo()) { + logger.info("= AMQAdapterListener stop........."); + } + + try { + if (info == null) { + throw new Exception("AMQAdapterListener | AdapterVO가 NULL입니다."); + } + + AMQAdapterManager manager = AMQAdapterManager.getInstance(); + manager.stop(info); + info.setStatus(false); + } catch (Throwable e) { + logger.error("[" + info.getName() + "] 중지 실패", e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/amq/AMQAdapterManager.java b/src/main/java/com/eactive/eai/adapter/amq/AMQAdapterManager.java new file mode 100644 index 0000000..e8875b9 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/amq/AMQAdapterManager.java @@ -0,0 +1,127 @@ +package com.eactive.eai.adapter.amq; + +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.jms.pool.PooledConnectionFactory; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +public class AMQAdapterManager { + public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + private static AMQAdapterManager instance = new AMQAdapterManager(); + + // adapterName - Outbound Queue PooledConnectionFactory + private ConcurrentHashMap adapterConFacMap = new ConcurrentHashMap<>(); + + // adapterName - Inbound Queue Listener + private ConcurrentHashMap receiverAdapterMap = new ConcurrentHashMap<>(); + + public static AMQAdapterManager getInstance() { + return instance; + } + + public PooledConnectionFactory getOutboundPooledConnectionFactory(String adapterName) { + return adapterConFacMap.get(adapterName); + } + + public void start(AdapterVO adapterVO) throws Exception { + if (logger.isDebug()) { + logger.debug("= AMQAdapterManager.start..."); + } + + AdapterGroupVO adapterGroupVO = adapterVO.getAdapterGroupVO(); + AdapterPropManager propManager = AdapterPropManager.getInstance(); + Properties queueProp = propManager.getProperties(adapterVO.getPropGroupName()); + String brokerUrl = queueProp.getProperty(AMQAdapterConstants.PROP_BROKER_URL); + if (StringUtils.isBlank(brokerUrl)) { + throw new CommandException(AMQAdapterConstants.PROP_BROKER_URL + " is a required."); + } + + if (StringUtils.equals(adapterGroupVO.getGubun(), "I")) { + AMQReceiverAdapter receiverAdapter = new AMQReceiverAdapter(adapterVO); + receiverAdapter.start(); + receiverAdapterMap.put(adapterVO.getName(), receiverAdapter); + + // Sync 거래일 경우 응답 Queue 연결 + String replyQueue = queueProp.getProperty(AMQAdapterConstants.PROP_REPLY_QUEUE_NAME); + if (StringUtils.isNotBlank(replyQueue)) { + String userName = queueProp.getProperty(AMQAdapterConstants.PROP_USER_NAME); + String password = queueProp.getProperty(AMQAdapterConstants.PROP_PASSWORD); + String maxConnections = queueProp.getProperty(AMQAdapterConstants.PROP_REPLY_POOL_MAX_CONNECTIONS); + String idleTimeout = queueProp.getProperty(AMQAdapterConstants.PROP_REPLY_POOL_IDLE_TIMEOUT); + String expiryTimeout = queueProp.getProperty(AMQAdapterConstants.PROP_REPLY_POOL_EXPIRY_TIMEOUT); + adapterConFacMap.put(adapterVO.getName(), getPooledConnectionFactory(brokerUrl, userName, password, + maxConnections, idleTimeout, expiryTimeout)); + } + } else { + String userName = queueProp.getProperty(AMQAdapterConstants.PROP_USER_NAME); + String password = queueProp.getProperty(AMQAdapterConstants.PROP_PASSWORD); + String maxConnections = queueProp.getProperty(AMQAdapterConstants.PROP_POOL_MAX_CONNECTIONS); + String idleTimeout = queueProp.getProperty(AMQAdapterConstants.PROP_POOL_IDLE_TIMEOUT); + String expiryTimeout = queueProp.getProperty(AMQAdapterConstants.PROP_POOL_EXPIRY_TIMEOUT); + adapterConFacMap.put(adapterVO.getName(), getPooledConnectionFactory(brokerUrl, userName, password, + maxConnections, idleTimeout, expiryTimeout)); + } + } + + public void stop(AdapterVO adapterVO) throws Exception { + AdapterGroupVO adapterGroupVO = adapterVO.getAdapterGroupVO(); + + if (StringUtils.equals(adapterGroupVO.getGubun(), "I")) { + AMQReceiverAdapter receiverAdapter = receiverAdapterMap.get(adapterVO.getName()); + if (receiverAdapter != null) { + receiverAdapterMap.remove(adapterVO.getName()); + receiverAdapter.stop(); + } + + // Sync 거래일 경우 응답 Queue 연결 해제 + PooledConnectionFactory connectionFactory = adapterConFacMap.get(adapterVO.getName()); + if (connectionFactory != null) { + adapterConFacMap.remove(adapterVO.getName()); + connectionFactory.clear(); + } + } else { + PooledConnectionFactory connectionFactory = adapterConFacMap.get(adapterVO.getName()); + if (connectionFactory != null) { + adapterConFacMap.remove(adapterVO.getName()); + connectionFactory.clear(); + } + } + + if (logger.isDebug()) { + logger.debug("= AMQAdapterManager.stoped..."); + } + } + + private PooledConnectionFactory getPooledConnectionFactory(String brokerUrl, String userName, String password, + String maxConnections, String idleTimeout, String expiryTimeout) throws Exception { + // Queue Connection pool 생성 + ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory(brokerUrl); + if (StringUtils.isNotBlank(userName)) { + activeMQConnectionFactory.setUserName(userName); + activeMQConnectionFactory.setPassword(StringUtils.defaultString(password)); + } + activeMQConnectionFactory.setTrustAllPackages(true); + + PooledConnectionFactory connectionFactory = new PooledConnectionFactory(); + connectionFactory.setConnectionFactory(activeMQConnectionFactory); + connectionFactory + .setMaxConnections(NumberUtils.toInt(maxConnections, AMQAdapterConstants.DEFAULT_POOL_MAX_CONNECTIONS)); + if (NumberUtils.isParsable(idleTimeout)) { + connectionFactory.setIdleTimeout(NumberUtils.toInt(idleTimeout) * 1000); + } + if (NumberUtils.isParsable(expiryTimeout)) { + connectionFactory.setExpiryTimeout(NumberUtils.toLong(expiryTimeout) * 1000); + } + + return connectionFactory; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/amq/AMQReceiverAdapter.java b/src/main/java/com/eactive/eai/adapter/amq/AMQReceiverAdapter.java new file mode 100644 index 0000000..6e0c907 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/amq/AMQReceiverAdapter.java @@ -0,0 +1,220 @@ +package com.eactive.eai.adapter.amq; + +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.Session; +import javax.jms.TextMessage; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.jms.pool.PooledConnectionFactory; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.jms.core.MessageCreator; +import org.springframework.jms.listener.DefaultMessageListenerContainer; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.RequestDispatcher; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.Logger; + +public class AMQReceiverAdapter { + private static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + private AdapterVO adapterVo; + DefaultMessageListenerContainer listenerContainer = null; + + public AMQReceiverAdapter(AdapterVO adapterVo) { + this.adapterVo = adapterVo; + } + + public void start() throws Exception { + AdapterPropManager propManager = AdapterPropManager.getInstance(); + Properties queueProp = propManager.getProperties(adapterVo.getPropGroupName()); + String brokerUrl = queueProp.getProperty(AMQAdapterConstants.PROP_BROKER_URL); + if (StringUtils.isBlank(brokerUrl)) { + throw new CommandException(AMQAdapterConstants.PROP_BROKER_URL + " is a required."); + } + String userName = queueProp.getProperty(AMQAdapterConstants.PROP_USER_NAME); + String password = queueProp.getProperty(AMQAdapterConstants.PROP_PASSWORD); + String receiveQueue = queueProp.getProperty(AMQAdapterConstants.PROP_RECEIVE_QUEUE_NAME); + if (StringUtils.isBlank(receiveQueue)) { + throw new Exception("No have receive Queue name"); + } + String concurrency = queueProp.getProperty(AMQAdapterConstants.PROP_RECEIVE_MAX_CONCURRENT_CONSUMERS); + String replyQueue = queueProp.getProperty(AMQAdapterConstants.PROP_REPLY_QUEUE_NAME); + String relayPropertyGroup = queueProp.getProperty(AMQAdapterConstants.PROP_RELAY_PROPERTY_GROUP); + String relayRequestPropertyKeys = queueProp.getProperty(AMQAdapterConstants.PROP_RELAY_REQUEST_PROPERTY_KEYS); + + // Queue Connection pool 생성 + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(brokerUrl); + if (StringUtils.isNotBlank(userName)) { + connectionFactory.setUserName(userName); + connectionFactory.setPassword(StringUtils.defaultString(password)); + } + connectionFactory.setTrustAllPackages(true); + + listenerContainer = new DefaultMessageListenerContainer(); + listenerContainer.setConnectionFactory(connectionFactory); + listenerContainer.setDestinationName(receiveQueue); + if (NumberUtils.isParsable(concurrency)) { + listenerContainer.setConcurrency(concurrency); + } + listenerContainer.setMessageListener(new MessageListener() { + @Override + public void onMessage(Message message) { + try { + if (message instanceof TextMessage) { + if (logger.isDebug()) { + logger.debug("Received from " + receiveQueue + ": " + ((TextMessage) message).getText()); + } + + String receivedMsg = convertMessageToString(message); + + Properties prop = new Properties(); + // RestDataAdapterGroupParseRequestAction 오류 방지 위해 set + prop.setProperty(HttpAdapterServiceKey.INBOUND_METHOD, "QUEUE"); + + Object returnObject = RequestDispatcher.getRequestDispatcher(adapterVo.getAdapterGroupName()) + .handle(adapterVo.getName(), receivedMsg, prop); + + // reply queue가 설정되어 있으면(Sync) 전송 + if (StringUtils.isNotBlank(replyQueue)) { + replyMessage((String) returnObject, replyQueue, relayPropertyGroup); + } + } else { + logger.error("Only supports TextMessage."); + throw new IllegalArgumentException( + "Only supports TextMessage: " + message.getClass().getName()); + } + } catch (Exception e) { + logger.error(e.getMessage()); + throw new RuntimeException(e); + } + } + + @SuppressWarnings({ "deprecation", "unchecked" }) + private String convertMessageToString(Message message) throws Exception { + String strMsg = ((TextMessage) message).getText(); + + // Queue property relay + if (MessageType.JSON.equals(adapterVo.getAdapterGroupVO().getMessageType()) + && StringUtils.isNotBlank(relayPropertyGroup) + && StringUtils.isNotBlank(relayRequestPropertyKeys)) { + JSONObject jsonMessage = (JSONObject) JSONValue.parse(StringUtils.defaultString(strMsg)); + JSONObject propertyJson = new JSONObject(); + if (StringUtils.equalsIgnoreCase(relayRequestPropertyKeys, "ALL")) { + Enumeration propertyNames = message.getPropertyNames(); + while (propertyNames.hasMoreElements()) { + try { + String propertyName = propertyNames.nextElement(); + propertyJson.put(propertyName, message.getStringProperty(propertyName)); + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(e.getMessage()); + } + } + } + } else { + String[] relayKeyArr = org.springframework.util.StringUtils + .tokenizeToStringArray(relayRequestPropertyKeys, ","); + for (String key : relayKeyArr) { + try { + String propertyValue = message.getStringProperty(key); + if (StringUtils.isNotBlank(propertyValue)) { + propertyJson.put(key, propertyValue); + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(e.getMessage()); + } + } + } + } + + if (propertyJson.size() > 0) { + jsonMessage.put(relayPropertyGroup, propertyJson); + strMsg = jsonMessage.toJSONString(); + } + } + + return strMsg; + } + + private void replyMessage(String replyMessage, String replyQueue, String relayPropertyGroup) + throws Exception { + PooledConnectionFactory connectionFactory = AMQAdapterManager.getInstance() + .getOutboundPooledConnectionFactory(adapterVo.getName()); + + JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory); + jmsTemplate.setExplicitQosEnabled(true); + jmsTemplate.setDeliveryPersistent(false); + + jmsTemplate.send(replyQueue, new MessageCreator() { + @SuppressWarnings("deprecation") + public Message createMessage(Session session) throws JMSException { + String strMsg = replyMessage; + + // relay to Queue property + HashMap properties = new HashMap<>(); + if (MessageType.JSON.equals(adapterVo.getAdapterGroupVO().getMessageType()) + && StringUtils.isNotBlank(relayPropertyGroup) + && StringUtils.contains(replyMessage, relayPropertyGroup)) { + try { + JSONObject dataObject = (JSONObject) JSONValue.parse(replyMessage); + JSONObject propertyObject = (JSONObject) dataObject.get(relayPropertyGroup); + if (propertyObject != null) { + for (Object key : propertyObject.keySet()) { + + Object obj = propertyObject.get(key); + if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { + continue; + } + + properties.put((String) key, (String) obj); + } + + dataObject.remove(relayPropertyGroup); + strMsg = dataObject.toJSONString(); + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(e.getMessage()); + } + } + } + + Message ms = session.createTextMessage(strMsg); + for (Map.Entry entry : properties.entrySet()) { + ms.setStringProperty(entry.getKey(), entry.getValue()); + } + + return ms; + } + }); + } + }); + + listenerContainer.afterPropertiesSet(); + listenerContainer.start(); + } + + public void stop() throws Exception { + if (listenerContainer != null) { + listenerContainer.stop(); + listenerContainer.shutdown(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/amq/AMQSenderAdapter.java b/src/main/java/com/eactive/eai/adapter/amq/AMQSenderAdapter.java new file mode 100644 index 0000000..4945765 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/amq/AMQSenderAdapter.java @@ -0,0 +1,358 @@ +package com.eactive.eai.adapter.amq; + +import java.nio.charset.Charset; +import java.util.Enumeration; +import java.util.Properties; +import java.util.UUID; + +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.MessageConsumer; +import javax.jms.MessageProducer; +import javax.jms.Session; +import javax.jms.TextMessage; + +import org.apache.activemq.jms.pool.PooledConnectionFactory; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.springframework.jms.core.JmsTemplate; +import org.springframework.jms.core.MessageCreator; +import org.springframework.jms.core.SessionCallback; +import org.springframework.jms.support.JmsUtils; +import org.springframework.jms.support.destination.DestinationResolver; + +import com.eactive.eai.adapter.ElinkDefaultAdapter; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ElinkConfig; + +public class AMQSenderAdapter extends ElinkDefaultAdapter { + public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public static final String ADAPTER_NAME = "ADAPTER_NAME"; + + private static final class ProducerConsumer implements SessionCallback { + private final String msg; + private final DestinationResolver destinationResolver; + private final String queue; + private final String receiveQueue; + private final Long receiveTimeoutSeconds; + private final Long timeToLiveSeconds; + private final String messageType; + private final String relayPropertyGroup; + + public ProducerConsumer(final String msg, String queue, String receiveQueue, + final DestinationResolver destinationResolver, Long receiveTimeoutSeconds, Long timeToLiveSeconds, + String messageType, String relayPropertyGroup) { + this.msg = msg; + this.queue = queue; + this.receiveQueue = receiveQueue; + this.destinationResolver = destinationResolver; + this.receiveTimeoutSeconds = receiveTimeoutSeconds; + this.timeToLiveSeconds = timeToLiveSeconds; + this.messageType = messageType; + this.relayPropertyGroup = relayPropertyGroup; + } + + public Message doInJms(final Session session) throws JMSException { + MessageConsumer consumer = null; + MessageProducer producer = null; + try { + final String correlationId = UUID.randomUUID().toString(); + if (logger.isDebug()) { + logger.debug("correlationId=====" + correlationId); + } + final Destination requestQueue = destinationResolver.resolveDestinationName(session, queue, false); + final Destination replyQueue = destinationResolver.resolveDestinationName(session, receiveQueue, false); + + // Create the consumer first! + consumer = session.createConsumer(replyQueue, "JMSCorrelationID = '" + correlationId + "'"); + + JSONObject propObject = new JSONObject(); + String strMsg = AMQSenderAdapter.extractRequestProperties(propObject, msg, messageType, + relayPropertyGroup); + final Message textMessage = session.createTextMessage(strMsg); + textMessage.setJMSCorrelationID(correlationId); + textMessage.setJMSReplyTo(replyQueue); + AMQSenderAdapter.assignRequestProperties(textMessage, propObject); + + // Send the request second! + producer = session.createProducer(requestQueue); + if (timeToLiveSeconds != null) { + producer.setTimeToLive(timeToLiveSeconds.longValue() * 1000); + } + producer.send(requestQueue, textMessage); + + // Block on receiving the response with a timeout + if (receiveTimeoutSeconds != null && receiveTimeoutSeconds.longValue() > 0) { + return consumer.receive(receiveTimeoutSeconds.longValue() * 1000); + } else { + return consumer.receive(AMQAdapterConstants.DEFAULT_MESSAGE_RECEIVE_TIMEOUT * 1000); + } + } catch (JMSException jmse) { + throw jmse; + } catch (Exception e) { + throw new JMSException(e.getMessage()); + } finally { + JmsUtils.closeMessageConsumer(consumer); + JmsUtils.closeMessageProducer(producer); + } + } + } + + @Override + public Object execute(Properties prop, Object message, Properties tempProp) throws Exception { + String syncAsync = tempProp.getProperty(AMQAdapterConstants.TEMP_INTERFACE_RESPONSE_TYPE); + if (StringUtils.equals(syncAsync, EAIMessageKeys.ASYNC_SVC)) { + return executeAsync(prop, message, tempProp); + } + + String sendQueue = prop.getProperty(AMQAdapterConstants.PROP_REQUEST_QUEUE_NAME); + if (StringUtils.isBlank(sendQueue)) { + throw new Exception("No have send Queue name"); + } + + String replyQueue = prop.getProperty(AMQAdapterConstants.PROP_REPLY_QUEUE_NAME); + if (StringUtils.isBlank(replyQueue)) { + throw new Exception("No have reply Queue name"); + } + + String timeToLive = prop.getProperty(AMQAdapterConstants.PROP_MESSAGE_TIME_TO_LIVE); + Long timeToLiveSeconds = null; + if (NumberUtils.isParsable(timeToLive)) { + timeToLiveSeconds = new Long(timeToLive); + } + + String receiveTimeout = prop.getProperty(AMQAdapterConstants.PROP_MESSAGE_RECEIVE_TIMEOUT); + Long receiveTimeoutSeconds = AMQAdapterConstants.DEFAULT_MESSAGE_RECEIVE_TIMEOUT; + if (NumberUtils.isParsable(receiveTimeout)) { + receiveTimeoutSeconds = new Long(receiveTimeout); + } + + // 인터페이스 정보에 설정된 타임아웃이 우선 + String interfaceTimeout = tempProp.getProperty(com.eactive.eai.common.routing.Process.INTERFACE_TIME_OUT); + if (NumberUtils.isParsable(interfaceTimeout)) { + long miliseconds = NumberUtils.toLong(interfaceTimeout); + if (miliseconds >= 1000) { + receiveTimeoutSeconds = new Long(miliseconds / 1000); + } + } + + String encode = tempProp.getProperty(Keys.CHARSET_KEY_OUT, Charset.defaultCharset().name()); + String sendMsg = ""; + if (message instanceof String) { + sendMsg = (String) message; + } else if (message instanceof byte[]) { + sendMsg = new String((byte[]) message, encode); + } + + String relayPropertyGroup = prop.getProperty(AMQAdapterConstants.PROP_RELAY_PROPERTY_GROUP); + String relayResponsePropertyKeys = prop.getProperty(AMQAdapterConstants.PROP_RELAY_RESPONSE_PROPERTY_KEYS); + String messageType = tempProp.getProperty(AMQAdapterConstants.TEMP_MESSAGE_TYPE); + + String adapterName = tempProp.getProperty(ADAPTER_NAME); + + try { + PooledConnectionFactory connectionFactory = AMQAdapterManager.getInstance() + .getOutboundPooledConnectionFactory(adapterName); + + JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory); + jmsTemplate.setExplicitQosEnabled(true); + jmsTemplate.setDeliveryPersistent(false); + jmsTemplate.setReceiveTimeout(receiveTimeoutSeconds.longValue() * 1000); + if (timeToLiveSeconds != null) { + jmsTemplate.setTimeToLive(timeToLiveSeconds.longValue() * 1000); + } + + Message receiveMessage = jmsTemplate + .execute(new ProducerConsumer(sendMsg, sendQueue, replyQueue, jmsTemplate.getDestinationResolver(), + receiveTimeoutSeconds, timeToLiveSeconds, messageType, relayPropertyGroup), true); + + String returnMsg = ""; + if (receiveMessage != null) { + returnMsg = assignResponseProperties(receiveMessage, messageType, relayPropertyGroup, + relayResponsePropertyKeys); + + if (logger.isDebugEnabled()) { + logger.debug("AMQSenderAdapter] Received message: {}", returnMsg); + } + } else { + throw new JMSException( + "Received NULL(The timeout expires or this message consumer is concurrently closed)"); + } + + return returnMsg; + } catch (Exception e) { + logger.error("AMQSenderAdapter] Exception (" + adapterName + ") : " + e.getMessage(), e); + throw e; + } catch (Throwable t) { + logger.error("AMQSenderAdapter] Throwable (" + adapterName + ") : " + t.getMessage(), t); + throw t; + } + } + + @SuppressWarnings({ "unchecked", "deprecation" }) + private String assignResponseProperties(Message receiveMessage, String messageType, String relayPropertyGroup, + String relayResponsePropertyKeys) throws Exception { + if (!(receiveMessage instanceof TextMessage)) { + return receiveMessage.toString(); + } + + String returnMsg = ((TextMessage) receiveMessage).getText(); + + // Queue property to JSON + try { + if (MessageType.JSON.equals(messageType) && StringUtils.isNotBlank(relayPropertyGroup) + && StringUtils.isNotBlank(relayResponsePropertyKeys)) { + String[] relayKeyArr = org.springframework.util.StringUtils + .tokenizeToStringArray(relayResponsePropertyKeys, ","); + JSONObject propertyJson = new JSONObject(); + if (StringUtils.equalsIgnoreCase(relayResponsePropertyKeys, "ALL")) { + Enumeration propertyNames = receiveMessage.getPropertyNames(); + while (propertyNames.hasMoreElements()) { + String propertyName = propertyNames.nextElement(); + propertyJson.put(propertyName, receiveMessage.getStringProperty(propertyName)); + } + } else { + for (String key : relayKeyArr) { + String value = receiveMessage.getStringProperty(key); + if (value != null) { + propertyJson.put(key, value); + } + } + } + + if (propertyJson.size() <= 0) { + return returnMsg; + } + + JSONObject bodyJson = null; + if (StringUtils.isBlank(returnMsg)) { + bodyJson = new JSONObject(); + } else { + bodyJson = (JSONObject) JSONValue.parse(returnMsg); + } + + // malformed json message + if (bodyJson == null) { + return returnMsg; + } + + bodyJson.put(relayPropertyGroup, propertyJson); + return bodyJson.toJSONString(); + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(e.getMessage()); + } + } + + return returnMsg; + } + + private Object executeAsync(Properties prop, Object message, Properties tempProp) throws Exception { + String sendQueue = prop.getProperty(AMQAdapterConstants.PROP_REQUEST_QUEUE_NAME); + if (StringUtils.isBlank(sendQueue)) { + throw new Exception("No have send Queue name"); + } + + String relayPropertyGroup = prop.getProperty(AMQAdapterConstants.PROP_RELAY_PROPERTY_GROUP); + String messageType = tempProp.getProperty(AMQAdapterConstants.TEMP_MESSAGE_TYPE); + String timeToLive = prop.getProperty(AMQAdapterConstants.PROP_MESSAGE_TIME_TO_LIVE); + + String encode = tempProp.getProperty(Keys.CHARSET_KEY_OUT, Charset.defaultCharset().name()); + final String sendMsg; + if (message instanceof String) { + sendMsg = (String) message; + } else if (message instanceof byte[]) { + sendMsg = new String((byte[]) message, encode); + } else { + sendMsg = ""; + } + + String adapterName = tempProp.getProperty(ADAPTER_NAME); + + try { + PooledConnectionFactory connectionFactory = AMQAdapterManager.getInstance() + .getOutboundPooledConnectionFactory(adapterName); + + JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory); + jmsTemplate.setExplicitQosEnabled(true); + jmsTemplate.setDeliveryPersistent(false); + if (NumberUtils.isParsable(timeToLive)) { + jmsTemplate.setTimeToLive(NumberUtils.toLong(timeToLive) * 1000); + } + + jmsTemplate.send(sendQueue, new MessageCreator() { + public Message createMessage(Session session) throws JMSException { + JSONObject propObject = new JSONObject(); + String strMsg = AMQSenderAdapter.extractRequestProperties(propObject, sendMsg, messageType, + relayPropertyGroup); + Message ms = session.createTextMessage(strMsg); + AMQSenderAdapter.assignRequestProperties(ms, propObject); + + return ms; + } + }); + + return ElinkConfig.getAsyncDummyData(null); + } catch (Exception e) { + logger.error("AMQSenderAdapter Async] Exception (" + adapterName + ") : " + e.getMessage(), e); + throw e; + } catch (Throwable t) { + logger.error("AMQSenderAdapter Async] Throwable (" + adapterName + ") : " + t.getMessage(), t); + throw t; + } + } + + @SuppressWarnings({ "deprecation", "unchecked" }) + protected static String extractRequestProperties(JSONObject propObject, String sendMsg, String messageType, + String relayPropertyGroup) { + String strMsg = sendMsg; + if (MessageType.JSON.equals(messageType) && StringUtils.isNotBlank(relayPropertyGroup) + && StringUtils.contains(strMsg, relayPropertyGroup)) { + try { + JSONObject dataObject = (JSONObject) JSONValue.parse(strMsg); + JSONObject tmpPropObject = (JSONObject) dataObject.get(relayPropertyGroup); + if (tmpPropObject != null) { + propObject.putAll(tmpPropObject); + dataObject.remove(relayPropertyGroup); + strMsg = dataObject.toJSONString(); + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(e.getMessage()); + } + } + } + + return strMsg; + } + + protected static void assignRequestProperties(Message ms, JSONObject propObject) { + if (propObject == null || propObject.size() == 0) { + return; + } + + for (Object key : propObject.keySet()) { + Object obj = propObject.get(key); + if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { + continue; + } + + try { + ms.setStringProperty((String) key, (String) obj); + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(e.getMessage()); + } + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/app/BusinessApplication.java b/src/main/java/com/eactive/eai/adapter/app/BusinessApplication.java new file mode 100644 index 0000000..6680918 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/app/BusinessApplication.java @@ -0,0 +1,9 @@ +package com.eactive.eai.adapter.app; + +import java.util.Properties; + +public interface BusinessApplication { + public static final String EAI_SVC_NAME = "eaiSvcName"; + + public Object executeApplication(Properties prop, Object message, Properties tempProp) throws Exception; +} diff --git a/src/main/java/com/eactive/eai/adapter/app/BusinessApplicationAdapter.java b/src/main/java/com/eactive/eai/adapter/app/BusinessApplicationAdapter.java new file mode 100644 index 0000000..e57d0c4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/app/BusinessApplicationAdapter.java @@ -0,0 +1,45 @@ +package com.eactive.eai.adapter.app; + +import com.eactive.eai.adapter.ElinkDefaultAdapter; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.common.util.Logger; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.util.Properties; + +public class BusinessApplicationAdapter extends ElinkDefaultAdapter { + public static final String ADAPTER_PROP_CLASS_NAME = "BUSINESS_CLASS_NAME"; + public static final String REST_OPTION_CLASS_NAME = "businessClassName"; + + @Override + public Object execute(Properties prop, Object message, Properties tempProp) throws Exception { + String restOption = prop.getProperty(HttpClientAdapterServiceKey.REST_OPTION); + JSONObject restOptionObject = parseJson(restOption); + + String businessClassName = null; + if (restOptionObject != null) { + businessClassName = (String) restOptionObject.get(REST_OPTION_CLASS_NAME); + } + + if (StringUtils.isBlank(businessClassName)) { + businessClassName = prop.getProperty(ADAPTER_PROP_CLASS_NAME); + if (StringUtils.isBlank(businessClassName)) { + throw new Exception(ADAPTER_PROP_CLASS_NAME + " is not set."); + } + } + + BusinessApplication app = BusinessApplicationFactory.createApplication(businessClassName); + return app.executeApplication(prop, message, tempProp); + } + + @SuppressWarnings("deprecation") + private JSONObject parseJson(String message) { + if (StringUtils.isBlank(message)) { + return null; + } + + return (JSONObject) JSONValue.parse(message); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/app/BusinessApplicationFactory.java b/src/main/java/com/eactive/eai/adapter/app/BusinessApplicationFactory.java new file mode 100644 index 0000000..bc690c4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/app/BusinessApplicationFactory.java @@ -0,0 +1,26 @@ +package com.eactive.eai.adapter.app; + +import java.util.concurrent.ConcurrentHashMap; + +public class BusinessApplicationFactory { + static private ConcurrentHashMap h = new ConcurrentHashMap(); + + @SuppressWarnings("rawtypes") + public static BusinessApplication createApplication(String className) throws Exception { + if (h.containsKey(className)) { + return (BusinessApplication) h.get(className); + } + + BusinessApplication app = null; + try { + Class cl = Class.forName(className); + app = (BusinessApplication) cl.newInstance(); + if (app != null) { + h.put(className, app); + } + } catch (Exception e) { + throw new Exception("Cannot create a BusinessApplication. - " + className); + } + return app; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/app/impl/OnlineToFileWriter.java b/src/main/java/com/eactive/eai/adapter/app/impl/OnlineToFileWriter.java new file mode 100644 index 0000000..411d216 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/app/impl/OnlineToFileWriter.java @@ -0,0 +1,84 @@ +package com.eactive.eai.adapter.app.impl; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; + +import com.eactive.eai.adapter.app.BusinessApplication; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.StringUtil; + +public class OnlineToFileWriter implements BusinessApplication { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static final String CLASS_PROPS = "BUSINESS_CLASS_PROPS"; + public static final String CLASS_PROPS_BASE_FILE_PATH = "baseFilePath"; + public static final String CLASS_PROPS_ENCODE = "encode"; + public static final String CLASS_PROPS_FILE_PATH_EXT = "fileExt"; + + /** + * @formatter:off + * Adapter property ¼³Á¤: BUSINESS_CLASS_PROPS + * - ex) baseFilePath=/data/onlineToJson, fileExt=json + * @formatter:on + */ + @Override + public Object executeApplication(Properties prop, Object message, Properties tempProp) throws Exception { + String classPropsStr = prop.getProperty(CLASS_PROPS); + Properties classProp = StringUtil.getProperties(classPropsStr); + String baseFilePath = classProp.getProperty(CLASS_PROPS_BASE_FILE_PATH); + if (StringUtils.isBlank(baseFilePath)) { + throw new Exception(String.format("Property(%s) is not setted", CLASS_PROPS_BASE_FILE_PATH)); + } + + String encode = classProp.getProperty(CLASS_PROPS_ENCODE, "UTF-8"); + String fileExt = classProp.getProperty(CLASS_PROPS_FILE_PATH_EXT, "txt"); + String eaiSvcName = tempProp.getProperty(BusinessApplication.EAI_SVC_NAME); + if (StringUtils.isBlank(eaiSvcName)) { + throw new Exception("Can not find serviceId"); + } + String dirStr = StringUtils.removeEnd(baseFilePath, "/") + "/" + eaiSvcName; + File dir = new File(dirStr); + if (!dir.exists()) { + dir.mkdirs(); + } + + String fileName = DatetimeUtil.getFormattedDate("yyyyMMdd-HHmmssSSS") + "." + fileExt; + File file = new File(dir, fileName); + + Map resultMap = new HashMap<>(); + + try ( + FileWriter fw = new FileWriter(file); + BufferedWriter bw = new BufferedWriter(fw); + ){ + if (message == null) { + logger.warn("message is null"); + } else if (message instanceof byte[]) { + byte[] buff = (byte[]) message; + bw.write(new String(buff, encode)); + } else { + bw.write(message.toString()); + } + bw.flush(); + + resultMap.put("RESULTCD", "000"); + resultMap.put("RESULTMSG", "Success"); + resultMap.put("FILENAME", fileName); + } catch (Exception e) { + logger.error("OnlineToFileWriter error", e); + throw e; + } + + JSONObject resultJsonObject = new JSONObject(); + resultJsonObject.putAll(resultMap); + return resultJsonObject.toJSONString().getBytes(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/db/DBAdapterKeys.java b/src/main/java/com/eactive/eai/adapter/db/DBAdapterKeys.java new file mode 100644 index 0000000..65b06e4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/db/DBAdapterKeys.java @@ -0,0 +1,29 @@ +package com.eactive.eai.adapter.db; + +public class DBAdapterKeys { + public static final String ADAPTER_GROUPNAME = "adapterGroupName"; + public static final String ADAPTER_NAME = "adapterName"; + public static final String ADAPTER_PROPGN = "propGroupName"; + + // jdbc common + public static final String DRIVER = "jdbc.driver"; + public static final String URL = "jdbc.url"; + public static final String USER = "jdbc.user"; + public static final String PVAL = "jdbc.pval"; + public static final String DATASOURCE = "jdbc.datasource"; // optional + public static final String ENCODE = "encode"; // optional + + // inbound query + public static final String SELECT = "jdbc.select"; // select query + public static final String UPDATE = "jdbc.update"; // update query + // inbound scheduler + public static final String RUN_CRONEXP = "run.cronexp"; // Quartz [ 0/10 * * * * ? ] + public static final String RUN_INTVL = "run.interval"; // 0...N + public static final String RUN_RETRY = "run.retry"; // Y|N + public static final String RUN_RETRYCNT = "run.retrycnt"; // 0...N + public static final String RUN_RETRYINTVL = "run.retryinterval"; //ms + public static final String RUN_MSGTYPE = "run.msgtype"; // XML | JSON + + // Outbound + public static final String QUERY = "query"; +} diff --git a/src/main/java/com/eactive/eai/adapter/db/sql/AdapterUtils.java b/src/main/java/com/eactive/eai/adapter/db/sql/AdapterUtils.java new file mode 100644 index 0000000..28279ec --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/db/sql/AdapterUtils.java @@ -0,0 +1,50 @@ +package com.eactive.eai.adapter.db.sql; + +import com.eactive.eai.adapter.AdapterPropManager; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Properties; + +public class AdapterUtils { + + public static void main(String[] args) { + String updateSql = "update EAIINF01 set RFLAG = 'C' where UNID = '%UNID%'"; + LinkedHashMap map = new LinkedHashMap(); + map.put("Unid", "ID00000001"); + + String prefix = "%", surfix = "%"; + System.out.println(updateSql); + System.out.println(getUpdateQuery(updateSql, map, prefix, surfix)); + } + + public static Properties getAdapterProerties(String propGroupName) { + AdapterPropManager pmanager = AdapterPropManager.getInstance(); + Properties prop = null; + if(pmanager == null) { + prop = new Properties(); + } + else { + prop = pmanager.getProperties(propGroupName); + } + return prop; + } + + public static String getUpdateQuery(String updateSql, HashMap map) { + return getUpdateQuery(updateSql, map, "%", "%"); + } + + public static String getUpdateQuery(String updateSql, HashMap map, String prefix, String surfix) { + String convertedSql = updateSql; + + String paramName = null; + for(String colName : map.keySet()) { + paramName = prefix+colName.toUpperCase()+surfix; + if(updateSql.indexOf(paramName) > -1) { + convertedSql = convertedSql.replaceAll(paramName, (String)map.get(colName)); + } + } + return convertedSql; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapter.java b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapter.java new file mode 100644 index 0000000..7a4797b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapter.java @@ -0,0 +1,284 @@ +package com.eactive.eai.adapter.db.sql; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.RequestDispatcher; +import com.eactive.eai.adapter.db.DBAdapterKeys; +import com.eactive.eai.adapter.wca.jdbc.JDBCException; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ServiceLocator; + +import javax.sql.DataSource; +import java.sql.*; +import java.util.LinkedHashMap; +import java.util.Properties; + +public class DBInboudSqlAdapter { + public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + private boolean isLocalTest = false; + + + private String logPrefix = ""; + private boolean isRunning = false; + private boolean stopRunning = false; + + private AdapterVO vo; + private Properties configProperties = null; + + public boolean isRunningState() { + return isRunning; + } + + public void setAdapterVO(AdapterVO vo) { + this.vo = vo; + } + + public void setProperties(Properties p) { + this.configProperties = p; + } + + public void stop() { + stopRunning = true; + } + + public DBInboudSqlAdapter(AdapterVO vo, Properties configProperties) { + super(); + this.vo = vo; + this.configProperties = configProperties; + if(vo == null) { + logPrefix = this.getClass().getSimpleName() +"] "; + } + else { + logPrefix = vo.getName() +"] "; + } + String isLocal = System.getProperty("isLocal"); + if(isLocal != null && "true".equalsIgnoreCase(isLocal)) { + isLocalTest = true; + } + System.out.println("$$$ DBInboudSqlAdapter] isLocalTest = " + isLocalTest); + } + + public boolean execute() { + isRunning = true; + int chunkSize = 15; + Connection con = null; + PreparedStatement pstmt = null; + PreparedStatement pstmtUpdate = null; + ResultSet rs = null; + + String datasoureName = configProperties.getProperty(DBAdapterKeys.DATASOURCE) ; + String selectQuery = configProperties.getProperty(DBAdapterKeys.SELECT) ; + String updateQuery = configProperties.getProperty(DBAdapterKeys.UPDATE) ; + + int runInterval = 0; + String runIntervalStr = configProperties.getProperty(DBAdapterKeys.RUN_INTVL) ; + try { + runInterval = Integer.parseInt(runIntervalStr); + } + catch(Exception e) { + runInterval = 0; + } + + String runRetry = configProperties.getProperty(DBAdapterKeys.RUN_RETRY, "N") ; // Y | N + + int runRetryCnt = 0; + String runRetryCntStr = configProperties.getProperty(DBAdapterKeys.RUN_RETRYCNT, "0") ; + try { + runRetryCnt = Integer.parseInt(runRetryCntStr); + } + catch(Exception e) { + runRetryCnt = 0; + } + + int runRetryInterval = 0; + String runRetryIntervalStr = configProperties.getProperty(DBAdapterKeys.RUN_RETRYINTVL, "0") ; + try { + runRetryInterval = Integer.parseInt(runRetryIntervalStr); + } + catch(Exception e) { + runRetryInterval = 0; + } + + int rowIndex = 0; + int colCount = 0; + try { + if(datasoureName != null && datasoureName.trim().length() > 0) { + con = getDataSourceConnection(datasoureName); + } + else { + con = getJDBCConnection(configProperties); + } + // default : row unit commit + con.setAutoCommit(true); + + // select chunk record + pstmt = con.prepareStatement(selectQuery); + rs = pstmt.executeQuery(); + + rowIndex = 0; + colCount = rs.getMetaData().getColumnCount(); + debug(String.format("$$$ RUNNING Query [%s] - colCount = %s", selectQuery, colCount) ); + + String rowString = null; + + // LOOP - Inbound Call + LinkedHashMap map = new LinkedHashMap(); + boolean isSuccess = false; + int retryExecCounter = 0; + boolean retryFailed = false; + while(rs.next() && !retryFailed){ + debug(String.format("==> run [%s]", (rowIndex+1)) ); + if(stopRunning) { + debug(String.format("$$$ STOP RUNNING stopRunning[%s]", stopRunning) ); + break; + } + + for(int i = 1; i <= colCount; i++){ + String key = rs.getMetaData().getColumnName(i); + String value = rs.getString(i); + if(value == null){ + value = ""; + } + map.put(key, value); + } + + if("JSON".equals(configProperties.getProperty(DBAdapterKeys.RUN_MSGTYPE))) { + rowString = ResultParser.toJsonString(map); + } + if("XML".equals(configProperties.getProperty(DBAdapterKeys.RUN_MSGTYPE))) { + rowString = ResultParser.toXmlString(map); + } + + debug(String.format("==> run [%s] : ", (rowIndex+1)) + rowString); + //-- start sudo test code +// debug(String.format("Sleep 1 secs - run [%s/%s]", (rowIndex+1), chunkSize) ); + + //-- end sudo test code + + byte[] request = rowString.getBytes(); + byte[] response = null; + String elinkResponseCode = null; + while(true) { + try { + isSuccess = false; + RequestDispatcher dispatcher = RequestDispatcher.getRequestDispatcher(vo.getAdapterGroupName()); + response = (byte[]) dispatcher.handle(vo.getName(), request, this.configProperties); + + elinkResponseCode = configProperties.getProperty(EAIMessageKeys.ELINK_RET_CODE); + debug("RequestProcessor.ELINK_RET_CODE ["+ elinkResponseCode +"]" ); + + // Sunncess check with elink F/W response code ESBEAI111111 + if(EAIMessageKeys.EAI_SUCCESS_CODE.equals(elinkResponseCode) + || EAIMessageKeys.EAI_DEFAULT_CODE.equals(elinkResponseCode)) { + isSuccess = true; + } + } catch (Exception e) { + logger.error("RequestDispatcher call error",e); + } + + if(isSuccess) { + // check response + if(response != null) debug("Response Message : " + new String(response)); + + // if success, update CHK column + String mappedUpdate = AdapterUtils.getUpdateQuery(updateQuery, map); + debug("mappedUpdate - "+ mappedUpdate); + pstmtUpdate = con.prepareStatement(mappedUpdate); + int cnt = pstmtUpdate.executeUpdate(); + debug("mappedUpdate result - "+ cnt); + // if success, skip retry + break; + } + else { + // if failed, retry or break, check retry options + if("Y".equals(runRetry)) { + debug(String.format(">> RETRY [%s / %s]", retryExecCounter, runRetryCnt) ); + + if(retryExecCounter < runRetryCnt) { + debug(String.format(">> RETRY runRetry=%s", runRetry) ); + ++retryExecCounter; + if(runRetryInterval > 0) { + debug("Sleep run.retryinterval - " +runRetryInterval); + Thread.sleep(runRetryInterval); + } + continue; + } + else { + debug(String.format(">> RETRY COMPLETED [%s / %s], STOP JOB", retryExecCounter, runRetryCnt) ); + retryFailed = true; + break; + } + } + else { + debug(String.format(">> RETRY Disabled, runRetry=%s", runRetry) ); + retryFailed = true; + break; + } + } + } // end retry LOOP + rowIndex++; + if(runInterval > 0) { + debug("Sleep run.interval - " +runInterval); + Thread.sleep(runInterval); + } + } + // end row LOOP + } + catch(Exception ex) { + ex.printStackTrace(); + } + isRunning = false; + debug(String.format("JOB Completed. isRunning=%s, executed ROWCount=%s", isRunning, rowIndex) ); + return isRunning; + } + + private Connection getJDBCConnection(Properties p) throws SQLException { + try { + Class.forName(p.getProperty(DBAdapterKeys.DRIVER)); + Connection con = DriverManager.getConnection(p.getProperty(DBAdapterKeys.URL), + p.getProperty(DBAdapterKeys.USER), p.getProperty(DBAdapterKeys.PVAL)); + return con; + } catch (Exception e) { + throw new SQLException("DBAdapter] Cannot create a JDBC Connection. - " + e.getMessage()); + } + } + + private Connection getDataSourceConnection(String dataSourceName) throws JDBCException + { + DataSource dataSource = null; + try { + ServiceLocator sl = ServiceLocator.getInstance(); + dataSource = sl.getDataSource(dataSourceName); + return dataSource.getConnection(); + } + catch(Exception e) { + e.printStackTrace(); + throw new JDBCException("["+dataSourceName+"]을 얻을 수 없습니다."); + } + } + + private java.sql.Date toDate(String sDate) throws Exception { + java.sql.Date s = null; + if(sDate.length() == 10 && sDate.indexOf("-") > 0) { + s = java.sql.Date.valueOf(sDate); + } + else if(sDate.length() == 8) { + java.util.Date d = new java.text.SimpleDateFormat("yyyyMMdd").parse(sDate); + s = new java.sql.Date(d.getTime()); + } + else { + throw new Exception("Invalid Date String - "+sDate); + } + return s; + } + + private void debug(String msg) { + if(isLocalTest) { + System.out.println (logPrefix + msg); + } + else { + logger.info(logPrefix + msg); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapterJob.java b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapterJob.java new file mode 100644 index 0000000..aac4008 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapterJob.java @@ -0,0 +1,62 @@ +package com.eactive.eai.adapter.db.sql; + +import com.eactive.eai.adapter.db.DBAdapterKeys; +import com.eactive.eai.common.util.Logger; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.utils.Key; + +public class DBInboudSqlAdapterJob implements Job { + + public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + private static boolean isLocalTest = false; + + static { + String isLocal = System.getProperty("isLocalTest"); + if(isLocal != null && "true".equalsIgnoreCase(isLocal)) { + isLocalTest = true; + } + } + + private void debug(String msg) { + if(isLocalTest) { + System.out.println (msg); + } + else { + logger.info(msg); + } + } + +// private DBInboudSqlAdapter adapter = null; + public void execute(JobExecutionContext context) throws JobExecutionException { + // JobKey jobKey = context.getJobDetail().getKey(); + Key jobKey = context.getJobDetail().getKey(); + String data = ""; + for (String key : context.getJobDetail().getJobDataMap().getKeys()) { + data = data + key + "=" + context.getJobDetail().getJobDataMap().getString(key) + ","; + } + debug( jobKey + " start data(" + data + ")"); + logger.warn(">> " + jobKey + " start data(" + data + ")"); + String jobKeyName = jobKey.getName(); + + String adapterName = context.getJobDetail().getJobDataMap().getString(DBAdapterKeys.ADAPTER_NAME); + String propGroupName = context.getJobDetail().getJobDataMap().getString(DBAdapterKeys.ADAPTER_PROPGN); + debug("adapterName=" + adapterName + ", propGroupName"+ propGroupName ); + + + DBInboudSqlAdapter adapter = DBInboudSqlAdapterManager.getInstance().get(adapterName); + if(adapter == null) { + debug(jobKey + " : @@@@ Adapter not found in JobDataMap"); + } + else { + if(adapter.isRunningState()) { + debug(jobKey + " : Adapter already RUNNING with previous scledule"); + } + else { + debug(jobKey + " : Adapter Called."); + adapter.execute(); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapterListener.java b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapterListener.java new file mode 100644 index 0000000..bfc888c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapterListener.java @@ -0,0 +1,208 @@ +package com.eactive.eai.adapter.db.sql; + +import com.eactive.eai.adapter.db.DBAdapterKeys; +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListenerSupport; +import com.eactive.eai.common.exception.ExceptionUtil; +import org.quartz.*; +import org.quartz.impl.StdSchedulerFactory; + +import java.util.Date; +import java.util.Properties; + +import static org.quartz.CronScheduleBuilder.cronSchedule; +import static org.quartz.JobBuilder.newJob; +import static org.quartz.TriggerBuilder.newTrigger; + +public class DBInboudSqlAdapterListener extends AdapterListenerSupport { + + String className = this.getClass().getName(); + Scheduler scheduler = null; + private static boolean isLocalTest = false; + private String SCHE_GROUP_NAME = "DBQ_GROUP"; + + public boolean startScheduler(Properties prop) { + boolean isStart = false; + try { + debug(className + " Scheduler start"); + logger.warn(className + " Scheduler start"); + if(scheduler != null) { + logger.warn("Scheduler shutdown previous RUN !"); + scheduler.shutdown(); + } + String adapterName = prop.getProperty("adapterName"); + scheduler = new StdSchedulerFactory().getScheduler(); + String jobName = "DBInboudSqlAdapterJob"; + String jobClassName = "com.eactive.eai.adapter.db.sql.DBInboudSqlAdapterJob"; + String cronExp = prop.getProperty( DBAdapterKeys.RUN_CRONEXP ); // "0/10 * * * * ?"; + registJob(jobName, jobClassName, cronExp, prop); + scheduler.start(); + isStart = true; + } + catch(SchedulerException se) { + logger.error("Scheduler start failed", se); + } + catch(Exception e) { + logger.error("Scheduler start failed", e); + } + return isStart; + } + + private String getTriggerName(String jobName) { + return jobName + "-trigger"; + } + + public boolean registJob(String jobName, String jobClassName, String cronExp, Properties p) { + try { + //configure the scheduler time + Class jobClass = Class.forName(jobClassName); + + JobBuilder jobBuilder = newJob(jobClass); + + jobBuilder = jobBuilder.withIdentity(jobName, Scheduler.DEFAULT_GROUP); + + // pass adapter name : not used this time + jobBuilder.usingJobData(DBAdapterKeys.ADAPTER_NAME, p.getProperty(DBAdapterKeys.ADAPTER_NAME)); + jobBuilder.usingJobData(DBAdapterKeys.ADAPTER_PROPGN, p.getProperty(DBAdapterKeys.ADAPTER_PROPGN)); + + JobDetail job = jobBuilder.build(); + + CronTrigger trigger = newTrigger().withIdentity( getTriggerName(jobName), SCHE_GROUP_NAME ) + .withSchedule(cronSchedule(cronExp)) + .build(); + + Date ft = scheduler.scheduleJob(job, trigger); + logger.warn(String.format("%s has been scheduled to run at: %s and repeat based on expression: %s", job.getKey(), ft, + trigger.getCronExpression()) ); + + return true; + } + catch(Exception e) { + logger.warn("registJob failed", e); + return false; + } + } + + private void printProperties(Properties prop) throws Exception { + if(prop == null) { + debug("printProperties - Properties is null"); + return; + } + for (Object key: prop.keySet()) { + debug(key + ": " + prop.getProperty(key.toString())); + } +// prop.forEach((key, value) -> debug("Key : " + key + ", Value : " + value)); + } + + private void init(Properties prop) throws Exception { + debug("Start init"); + printProperties(prop); + startScheduler(prop); + } + + public void start() throws AdapterException { + Properties prop = null; + String adapterName = null; + if(info != null) { + String propGroupName = info.getPropGroupName(); + prop = AdapterUtils.getAdapterProerties(propGroupName); + adapterName = info.getName(); + prop.setProperty(DBAdapterKeys.ADAPTER_PROPGN, propGroupName); + } + // TODO : Application Test Code. + // in real system, remove this block + else { + prop = new Properties(); + + prop.setProperty(DBAdapterKeys.RUN_CRONEXP, "0/10 * * * * ?"); + prop.setProperty(DBAdapterKeys.RUN_INTVL, "1000"); + prop.setProperty(DBAdapterKeys.RUN_RETRY, "N"); + prop.setProperty(DBAdapterKeys.RUN_RETRYCNT, "2"); + prop.setProperty(DBAdapterKeys.RUN_RETRYINTVL, "5000"); + prop.setProperty(DBAdapterKeys.RUN_MSGTYPE, "JSON"); + + prop.setProperty(DBAdapterKeys.DRIVER, "oracle.jdbc.driver.OracleDriver"); + prop.setProperty(DBAdapterKeys.URL, "jdbc:oracle:thin:@localhost:1521:XE"); + prop.setProperty(DBAdapterKeys.USER, "eai"); + prop.setProperty(DBAdapterKeys.PVAL, "eaiadmin"); +// prop.setProperty(DBAdapterKeys.SELECT, "select * from APIJOBSCHE"); + prop.setProperty(DBAdapterKeys.SELECT, "select * from EAIINF01 where RFLAG IS null ORDER BY UNID"); + prop.setProperty(DBAdapterKeys.UPDATE, "update EAIINF01 set RFLAG = 'C' where UNID = '%UNID%' "); + + debug("Start Scheduler"); + adapterName = "_EAI_IN_DBQ_SyC"; + } + // TODO : Application Test Code End. + + prop.setProperty(DBAdapterKeys.ADAPTER_NAME, adapterName); + // Start Scheduler + try{ + logger.warn(className + " STARTING"); + init(prop); + DBInboudSqlAdapterManager maanger = DBInboudSqlAdapterManager.getInstance(); + // init adapter configuration values + DBInboudSqlAdapter adapter = new DBInboudSqlAdapter(info, prop); + maanger.put(adapterName, adapter); + } catch(Exception e) { + e.printStackTrace(); + } + } + + public void stop() throws AdapterException { + try { + String adapterName = ""; + if (info == null) { + adapterName = "_EAI_IN_DBQ_SyC"; +// throw new Exception(this.getClass().getName() +" | AdapterVO°¡ NULLÀÔ´Ï´Ù."); + } + else { + adapterName = info.getName(); + } + if(scheduler != null) { + try { + DBInboudSqlAdapterManager manager = DBInboudSqlAdapterManager.getInstance(); + DBInboudSqlAdapter adapter = manager.get(adapterName); + logger.warn("stop adapter - " + adapterName); + adapter.stop(); + // Stop Scheduler + logger.warn("stop scheduler - " + scheduler.getSchedulerName()); + JobKey key = new JobKey(adapterName, SCHE_GROUP_NAME ); + scheduler.deleteJob(key); + scheduler.shutdown(); + } + catch(SchedulerException se) { + logger.error("stop scheduler failed", se); + } + } + } catch (Exception e) { + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIOIA009"); + throw new AdapterException(errCode); + } + } + + private void debug(String msg) { + if(isLocalTest) { + System.out.println (msg); + } + else { + logger.info(msg); + } + } + + public static void main(String[] args) { + try { + isLocalTest = true; + System.setProperty("isLocal", "true"); + DBInboudSqlAdapterListener listener = new DBInboudSqlAdapterListener(); + int testSecs = 60; + System.out.println (String.format(">> Test while %s secs ...", testSecs)); + listener.start(); + Thread.sleep(testSecs * 1000); + System.out.println ("<< Test end."); + listener.stop(); + } + catch(Exception ex) { + ex.printStackTrace(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapterManager.java b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapterManager.java new file mode 100644 index 0000000..85fa0a1 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/db/sql/DBInboudSqlAdapterManager.java @@ -0,0 +1,21 @@ +package com.eactive.eai.adapter.db.sql; + +import java.util.concurrent.ConcurrentHashMap; + +public class DBInboudSqlAdapterManager { + private static DBInboudSqlAdapterManager instance = new DBInboudSqlAdapterManager(); + + private static ConcurrentHashMap adapters = new ConcurrentHashMap(); + + public static DBInboudSqlAdapterManager getInstance() { + return instance; + } + + public synchronized void put(String adapterName, DBInboudSqlAdapter adapter) { + adapters.put(adapterName, adapter); + } + + public synchronized DBInboudSqlAdapter get(String adapterName) { + return adapters.get(adapterName); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/db/sql/ResultParser.java b/src/main/java/com/eactive/eai/adapter/db/sql/ResultParser.java new file mode 100644 index 0000000..72d3095 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/db/sql/ResultParser.java @@ -0,0 +1,27 @@ +package com.eactive.eai.adapter.db.sql; + +import org.json.simple.JSONObject; + +import java.util.LinkedHashMap; + +public class ResultParser { + public static String toJsonString(LinkedHashMap map) { + JSONObject jsonObject = new JSONObject(); + for (String key : map.keySet()) { + jsonObject.put(key, map.get(key)); + } + return jsonObject.toJSONString(); + } + + public static String toXmlString(LinkedHashMap map) { + StringBuilder sb = new StringBuilder(); + sb.append(""); + for (String key : map.keySet()) { + sb.append("<").append(key).append(">"); + sb.append(map.get(key)); + sb.append(""); + } + sb.append(""); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandler.java b/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandler.java new file mode 100644 index 0000000..7699f95 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.handler; + +import java.util.Properties; + +import com.eactive.eai.message.StandardMessage; + +public interface AdapterErrorMessageHandler { + public Object generateNonStandardErrorResponseMessage(String inboudnAdapterGroupName, String inboudnAdapterName, Properties callProp, Object outboundRequestData, StandardMessage resStandardMessage) throws Exception; +} + \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandlerFactory.java b/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandlerFactory.java new file mode 100644 index 0000000..69143c4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/handler/AdapterErrorMessageHandlerFactory.java @@ -0,0 +1,31 @@ +package com.eactive.eai.adapter.handler; + +import java.util.concurrent.ConcurrentHashMap; + +import com.eactive.eai.common.util.Logger; + +public class AdapterErrorMessageHandlerFactory { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + static private ConcurrentHashMap h = new ConcurrentHashMap(); + + @SuppressWarnings("rawtypes") + public static AdapterErrorMessageHandler createHandler(String handlerClassName) { + if (h.containsKey(handlerClassName)) { + return (AdapterErrorMessageHandler) h.get(handlerClassName); + } + + AdapterErrorMessageHandler handler = null; + try { + Class cl = Class.forName(handlerClassName); + handler = (AdapterErrorMessageHandler) cl.newInstance(); + } catch (Exception e) { + logger.error("Cannot create a AdapterErrorMessageHandler. - {}", handlerClassName); + } + if (handler != null) { + h.put(handlerClassName, handler); + return handler; + } else { + return null; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/handler/DefaultAdapterErrorMessageHandler.java b/src/main/java/com/eactive/eai/adapter/handler/DefaultAdapterErrorMessageHandler.java new file mode 100644 index 0000000..35275fb --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/handler/DefaultAdapterErrorMessageHandler.java @@ -0,0 +1,15 @@ +package com.eactive.eai.adapter.handler; + +import java.util.Properties; + +import com.eactive.eai.message.StandardMessage; + +public class DefaultAdapterErrorMessageHandler implements AdapterErrorMessageHandler { + + @Override + public Object generateNonStandardErrorResponseMessage(String inboudnAdapterGroupName, String inboudnAdapterName, + Properties callProp, Object outboundRequestData, StandardMessage resStandardMessage) throws Exception { + return null; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/EntityEnclosingDeleteMethod.java b/src/main/java/com/eactive/eai/adapter/http/EntityEnclosingDeleteMethod.java new file mode 100644 index 0000000..3ade5f6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/EntityEnclosingDeleteMethod.java @@ -0,0 +1,18 @@ +package com.eactive.eai.adapter.http; + +import org.apache.commons.httpclient.methods.EntityEnclosingMethod; + +public class EntityEnclosingDeleteMethod extends EntityEnclosingMethod { + + public EntityEnclosingDeleteMethod() { + } + + public EntityEnclosingDeleteMethod(String uri) { + super(uri); + } + + @Override + public String getName() { + return "DELETE"; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/EntityEnclosingGetMethod.java b/src/main/java/com/eactive/eai/adapter/http/EntityEnclosingGetMethod.java new file mode 100644 index 0000000..db949a8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/EntityEnclosingGetMethod.java @@ -0,0 +1,25 @@ +package com.eactive.eai.adapter.http; + +import org.apache.commons.httpclient.methods.EntityEnclosingMethod; + +import com.eactive.eai.common.util.Logger; + +public class EntityEnclosingGetMethod extends EntityEnclosingMethod { + public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public EntityEnclosingGetMethod() { + setFollowRedirects(true); + } + + public EntityEnclosingGetMethod(String uri) { + super(uri); + if (logger.isDebugEnabled()) { + logger.debug("enter GetMethod(String)"); + } + } + + @Override + public String getName() { + return "GET"; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/HttpAdapter.java b/src/main/java/com/eactive/eai/adapter/http/HttpAdapter.java new file mode 100644 index 0000000..552b83b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/HttpAdapter.java @@ -0,0 +1,154 @@ +//package com.eactive.eai.adapter.http; +// +//import java.net.URLDecoder; +//import java.net.URLEncoder; +//import java.util.Properties; +//import javax.naming.Context; +//import javax.naming.InitialContext; +//import javax.servlet.ServletException; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +// +//import com.eactive.eai.adapter.RequestDispatcher; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.util.LogKeys; +//import com.eactive.eai.common.util.Logger; +//import com.eactive.eai.common.util.StringUtil; +// +///** +//* 1. 기능 : HTTP 웹 요청을 수신해 EAI 프레임웍에 전달하는 HTTP 어댑터 +//* 2. 처리 개요 : +//* * - 약속된 URL 파라미터(“_message_”)의 값을 얻어 RequestDispatcher의 handle() 메서드를 호출한다. +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : EAIHttpAdapter.java, RequestDispatcher.java +//* @since : +//* : +//*/ +//public class HttpAdapter extends HttpServlet +//{ +// /* +// * URL 파리미터 이름 +// */ +// static final String PARAMETER_MESSAGE = "_message_"; +// /* +// * Http Adapter 이름 +// */ +// static final String HTTP_ADAPTER_NAME = "HTTP_ADAPTER_NAME"; +// /* +// * Http Adapter Group 이름 +// */ +// static final String HTTP_ADAPTER_GROUP_NAME = "HTTP_ADAPTER_GROUP_NAME"; +// +// private String adapterGroupName; +// private String adapterName; +// /* +// * Adapter Logger +// */ +// static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); +// +// /** +// * 1. 기능 : Http Adapter의 property 속성을 설정한다. +// * 2. 처리 개요 : +// * - +// * 3. 주의사항 +// * +// **/ +// public void init() { +// //------------------------------------------------------- +// // Edited 2007.09.12 : DHLEE +// //------------------------------------------------------- +// this.adapterName = this.getInitParameter(HTTP_ADAPTER_NAME); +// this.adapterGroupName = this.getInitParameter(HTTP_ADAPTER_GROUP_NAME); +// //------------------------------------------------------- +// +// if(this.adapterName == null) this.adapterName = "IN_HTTP_STD_Sync01"; +// if(this.adapterGroupName == null) this.adapterGroupName = "HttpAdapter{STD}"; +// +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.adapterGroupName; +// msgArgs[1] = this.adapterName; +// String resMsg = ExceptionUtil.make("RDCEAIAHA004", msgArgs); +// if(logger.isDebug()){ +// logger.debug("HttpAdapter] " + resMsg); +// } +// } +// +// /** +// * 1. 기능 : 로컬 서비스 호출하는 비지니스 로직 +// * 2. 처리 개요 : +// * - 로컬 서비스를 호출 하여 업무를 처리하고 결과를 리턴 한다. +// * 3. 주의사항 +// * +// * @param message 요청 메시지 +// * @return prop Http Adapter 속성 정보 +// * @exception Exception 리턴 Object의 타입이 틀릴 경우 +// **/ +// protected byte[] service(byte[] message, Properties prop) throws Exception { +// Object obj = RequestDispatcher.getRequestDispatcher(this.adapterGroupName).handle(adapterName,message,prop); +// if(obj == null) return null; +// if(obj instanceof byte[]) { +// return (byte[])obj; +// } else if(obj instanceof String) { +// return ((String)obj).getBytes(); +// } else { +// throw new Exception("RECEAIAHA001"); +// } +// } +// +// /** +// * 1. 기능 : Http Servlet service 구현 메소드 +// * 2. 처리 개요 : +// * - 로컬 서비스 호출 +// * 3. 주의사항 +// * +// * @param request Http Servlet Request +// * @return response Http Servlet Response +// * @exception Exception PARAMETER_MESSAGE가 null 이거나 로컬 서비스 호출 중 오류가 발생할 경우 +// **/ +// public void service(HttpServletRequest request, HttpServletResponse response) { +// try { +// +// String paramValue = request.getParameter(PARAMETER_MESSAGE); +// if(paramValue==null) +// throw new ServletException("RECEAIAHA002"); +// +// //byte[] message = StringUtil.hex2Bytes(hexMessage); +// String message = URLDecoder.decode(paramValue); +// //logger.info("HttpAdapter] "+this.adapterGroupName+" (RCEV) - "+message); +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.adapterGroupName; +// msgArgs[1] = message; +// String resMsg = ExceptionUtil.make("RICEAIAHA005", msgArgs); +// +// if(logger.isInfo()){ +// logger.info("HttpAdapter] " + resMsg); +// } +// +// Properties prop = new Properties(); +// // 로컬 서비스 호출 +// byte[] result = service(message.getBytes(),prop); +// if(message != null) { +// //response.getWriter().print(message); +// //hexMessage = StringUtil.bytes2Hex(message); +// paramValue = URLEncoder.encode(new String(result)); +// response.getWriter().print(paramValue); +// } +// +// } catch (Exception e) { +// logger.error("HttpAdapter] "+adapterGroupName+"-"+adapterName+">>"+e.getMessage(),e); +// response.setStatus(500); +// try { +// response.getWriter().println(e.getMessage()); +// String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA003"); +// throw new Exception(errCode); +// } catch (Exception ex) { +// // IGNORE +// } +// } +// +// } +//} diff --git a/src/main/java/com/eactive/eai/adapter/http/HttpAdapterTestCall.java b/src/main/java/com/eactive/eai/adapter/http/HttpAdapterTestCall.java new file mode 100644 index 0000000..040e678 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/HttpAdapterTestCall.java @@ -0,0 +1,82 @@ +package com.eactive.eai.adapter.http; + +import com.eactive.eai.adapter.*; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.testcall.TestCallException; +import com.eactive.eai.common.testcall.TestCallManager; +import com.eactive.eai.common.testcall.TestCallSupport; +import com.eactive.eai.common.util.Logger; + +import java.util.Properties; + +public class HttpAdapterTestCall extends TestCallSupport +{ + public static final String MESSAGE = "EAI TestCall Message"; + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public boolean isAlive() throws TestCallException + { +// int nConnected = 0 ; + try { + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = factory.getElinkAdapter(Keys.TYPE_HTTP); + AdapterVO vo = this.getAdapterInfo(); + String pgoName = vo.getPropGroupName(); + //PropManager manager = PropManager.getInstance(); + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties prop = (Properties)(manager.getProperties(pgoName)).clone(); + + String testCallUrl = (String)prop.get("TEST_CALL_URL"); + + // MFC_FAILOVER : FAILOVER = Y 일 경우 무조건 2센터로 테스트콜을 처리한다 (2020-10-16) + PropManager pmanager = PropManager.getInstance(); + String mfcFailOver = pmanager.getProperty("MFC_FAILOVER", "FAILOVER"); + + if(mfcFailOver != null && "Y".equals(mfcFailOver.toUpperCase())) { + String testCallUrl2Grp = (String)prop.get("TEST_CALL_URL_2GRP"); + if (testCallUrl2Grp != null && testCallUrl2Grp.trim().length() > 0) { + testCallUrl = testCallUrl2Grp; + if (logger.isWarn()) logger.warn(pgoName + " - USE TEST_CALL_URL_2GRP - " + testCallUrl ); + } + } + // MFC_FAILOVER : FAILOVER = Y 일 경우 무조건 2센터로 테스트콜을 처리한다 (2020-10-16) + + if (testCallUrl != null && testCallUrl.trim().length() > 0) { + prop.put("URL", testCallUrl); + } + + Properties testCallProp = PropManager.getInstance().getProperties(TestCallManager.PROP_GROUP); + String responseType = testCallProp.getProperty(TestCallManager.RESPONSE_TYPE, "SYNC"); + String httpTimeout = testCallProp.getProperty(TestCallManager.HTTP_TIME_OUT, "5000"); + String connectionTimeout = testCallProp.getProperty(TestCallManager.CONNECTION_TIMEOUT, "3000"); + + prop.setProperty(TestCallManager.RESPONSE_TYPE,responseType); + prop.setProperty(TestCallManager.HTTP_TIME_OUT, httpTimeout); + prop.setProperty(TestCallManager.CONNECTION_TIMEOUT, connectionTimeout); + Properties tempProp = new Properties(); + tempProp.setProperty(TestCallManager.TESTCALL_YN, "Y"); + + if(logger.isWarn()) { + logger.warn("HttpAdapterTestCall] TestCall ["+vo.getAdapterGroupName()+"] URL = " + prop.getProperty("URL") ); + logger.warn("HttpAdapterTestCall] TestCall ["+vo.getAdapterGroupName()+"] " + TestCallManager.RESPONSE_TYPE +" = " + prop.getProperty(TestCallManager.RESPONSE_TYPE) ); + logger.warn("HttpAdapterTestCall] TestCall ["+vo.getAdapterGroupName()+"] " + TestCallManager.HTTP_TIME_OUT +" = " + prop.getProperty(TestCallManager.HTTP_TIME_OUT) ); + logger.warn("HttpAdapterTestCall] TestCall ["+vo.getAdapterGroupName()+"] " + TestCallManager.CONNECTION_TIMEOUT +" = " + prop.getProperty(TestCallManager.CONNECTION_TIMEOUT) ); + logger.warn("HttpAdapterTestCall] TestCall ["+vo.getAdapterGroupName()+"] " + TestCallManager.TESTCALL_YN +" = " + tempProp.getProperty(TestCallManager.TESTCALL_YN) ); + + } + + Object result = adapter.callService(vo.getAdapterGroupName(),prop,MESSAGE.getBytes(), tempProp); + if(logger.isWarn()) { + logger.warn("HttpAdapterTestCall] TestCall["+vo.getAdapterGroupName()+"], result ="+ result ); + } + return true; + } catch(HttpStatusException hse) { + logger.warn("HttpAdapterTestCall] Error - "+hse.getClass().getName()+" : "+hse.getMessage()); + return true; + } catch(Exception e) { + //e.printStackTrace(); + logger.warn("HttpAdapterTestCall] Error - "+e.getClass().getName()+" : "+e.getMessage()); + return false; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/HttpClientAdapter.java b/src/main/java/com/eactive/eai/adapter/http/HttpClientAdapter.java new file mode 100644 index 0000000..e762108 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/HttpClientAdapter.java @@ -0,0 +1,915 @@ +// +//package com.eactive.eai.adapter.http; +// +//import java.net.ConnectException; +//import java.net.SocketTimeoutException; +//import java.util.Properties; +//import org.apache.commons.httpclient.HttpClient; +//import org.apache.commons.httpclient.HttpMethod; +//import org.apache.commons.httpclient.HttpMethodRetryHandler; +//import org.apache.commons.httpclient.HttpStatus; +//import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +//import org.apache.commons.httpclient.NoHttpResponseException; +//import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; +//import org.apache.commons.httpclient.methods.GetMethod; +//import org.apache.commons.httpclient.methods.PostMethod; +//import org.apache.commons.httpclient.params.HttpClientParams; +//import org.apache.commons.httpclient.params.HttpMethodParams; +// +//import com.eactive.eai.adapter.WLIDefaultAdapter; +//import com.eactive.eai.common.errorcode.ErrorCodeHandler; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.util.Logger; +// +// +///** +//* 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 +//* GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +//* 2. 처리 개요 : +//* * - 2009.11.24 retry 로직 제거 : 강길수차장요청 +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +//* @since : +// +//*/ +//public class HttpClientAdapter extends WLIDefaultAdapter +//{ +// public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); +// +// public static final String URL = "URL"; +// public static final String METHOD = "METHOD"; +// public static final String PARAMETER_NAME = "PARAMETER_NAME"; +// +// // encode 추가 : 20071207 +// public static final String ENCODE = "ENCODE"; +// +// public static final String METHOD_GET = "GET"; +// public static final String METHOD_POST = "POST"; +// +// //------------------------------------------------- +// // 전자무역 상태조회 : +// // 2009.01.09 +// public static final String METHOD_SOAP = "SOAP"; +// public static final String METHOD_SOAP_ACTION = "SOAPAction"; +// //------------------------------------------------- +// +// public static final String HTTP_CONNECTION_STALE_CHECKING_ENABLED = "HTTP_CONNECTION_STALE_CHECKING_ENABLED"; +// /* +// * 호스트 마다 최대 연결 수 +// */ +// public static final String HTTP_MAX_CONNECTION_PER_HOST = "HTTP_MAX_CONNECTION_PER_HOST"; +// /* +// * 최대 HTTP 연결 수 +// */ +// public static final String HTTP_MAX_TOTAL_CONNECTIONS = "HTTP_MAX_TOTAL_CONNECTIONS"; +// +// static final String PARAMETER_MESSAGE = "_message_"; +// +// private HttpClient client; +// +// // 2008.01.21 이동훈 +// // HttpClient 2.0 Timeout Setting +// public static final String HTTP_TIME_OUT = "HTTP_TIME_OUT"; +// public static final int DEFAULT_TIME_OUT = 30 *1000; +// // HttpClient 2.0 Timeout Setting +// +// /** +// * 1. 기능 : HttpClientAdapter default 생성자 +// * 2. 처리 개요 : +// * - property 정보를 가져와 MultiThreadedHttpConnectionManager 속성 설정 +// * - HttpClient의 instance 생성 +// * 3. 주의사항 +// * +// **/ +// public HttpClientAdapter() { +// MultiThreadedHttpConnectionManager cm = new MultiThreadedHttpConnectionManager(); +// PropManager manager = PropManager.getInstance(); +// String enabled = manager.getProperty(HTTP_CONNECTION_STALE_CHECKING_ENABLED); +// +// if(enabled==null) { +// +// enabled="true"; +// +// String code = "RWCEAIAHA006"; +// String msg = ErrorCodeHandler.getMessage(code); +// if(logger.isWarn()){ +// logger.warn(ExceptionUtil.make(code, msg)); +// } +// } +// +// +// try { +// +// cm.getParams().setStaleCheckingEnabled(new Boolean(enabled).booleanValue()); +// +// } catch(Exception e) { +// e.printStackTrace(); +// String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA007"); +// throw new RuntimeException(errCode); +// } +// +// +// String connPerHost = manager.getProperty(HTTP_MAX_CONNECTION_PER_HOST); +// +// if(connPerHost==null) { +// connPerHost = "10"; +// String code = "RWCEAIAHA008"; +// String msg = ErrorCodeHandler.getMessage(code); +// if(logger.isWarn()){ +// logger.warn(ExceptionUtil.make(code, msg)); +// } +// } +// +// +// try { +// //cm.setMaxConnectionsPerHost(new Integer(connPerHost).intValue()); +// cm.getParams().setDefaultMaxConnectionsPerHost(new Integer(connPerHost).intValue()); +// } catch(Exception e) { +// String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA009"); +// throw new RuntimeException(errCode); +// } +// +// +// String totalConnections = manager.getProperty(HTTP_MAX_TOTAL_CONNECTIONS); +// if(totalConnections==null) { +// totalConnections = "50"; +// String code = "RWCEAIAHA010"; +// String msg = ErrorCodeHandler.getMessage(code); +// if(logger.isWarn()){ +// logger.warn(ExceptionUtil.make(code, msg)); +// } +// } +// +// +// try { +// //cm.setMaxTotalConnections(new Integer(totalConnections).intValue()); +// cm.getParams().setMaxTotalConnections(new Integer(totalConnections).intValue()); +// } catch(Exception e) { +// String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA011"); +// throw new RuntimeException(errCode); +// } +// +// this.client = new HttpClient(cm); +// +// +// } +// +// /** +// * 1. 기능 : 현재 사용중인 Connection 수 +// * 2. 처리 개요 : +// * - +// * 3. 주의사항 +// * +// * @return int 사용중인 Connection 수 +// **/ +// public int getConnectionsInPool() { +// MultiThreadedHttpConnectionManager mgr = (MultiThreadedHttpConnectionManager)this.client.getHttpConnectionManager(); +// return mgr.getConnectionsInPool(); +// } +// +// /** +// * 1. 기능 : 생성된 총 Connection 수 +// * 2. 처리 개요 : +// * - +// * 3. 주의사항 +// * +// * @return int 총 Connection 수 +// **/ +// public int getMaxTotalConnections() { +// MultiThreadedHttpConnectionManager mgr = (MultiThreadedHttpConnectionManager)this.client.getHttpConnectionManager(); +// return mgr.getParams().getMaxTotalConnections(); +// } +// +// /** +// * 1. 기능 : 호스트 당 할당된 총 Connection 수 +// * 2. 처리 개요 : +// * - +// * 3. 주의사항 +// * +// * @return int 총 Connection 수 +// **/ +// public int getMaxConnectionsPerHost() { +// MultiThreadedHttpConnectionManager mgr = (MultiThreadedHttpConnectionManager)this.client.getHttpConnectionManager(); +// return mgr.getParams().getDefaultMaxConnectionsPerHost(); +// } +// +// /** +// * 1. 기능 : 전문과 같은 Raw Data 통신에 사용 +// * 2. 처리 개요 : +// * - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. +// * 3. 주의사항 +// * +// * @param prop Http Adapter 속성 정보 +// * @param message 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// public Object execute(Properties prop, Object message) throws Exception +// { +// +// byte[] data = null; +// if(message instanceof byte[]) { +// data = (byte[])message; +// } else if( message instanceof String) { +// data = ((String)message).getBytes(); +// } else { +// throw new Exception("RECEAIAHA011"); +// } +// String url = prop.getProperty(URL); +// String parameterName = prop.getProperty(PARAMETER_NAME); +// String httpMethod = prop.getProperty(METHOD); +// String encode = prop.getProperty(ENCODE); +// String httpTimeOut = prop.getProperty(HTTP_TIME_OUT); +// +// String soapAction = prop.getProperty(METHOD_SOAP_ACTION); +// +// //------------------------------------------- +// // trim 처리 : 2009.03.27 +// //------------------------------------------- +// if(url != null) { +// url = url.trim(); +// } +// +// if(parameterName != null) { +// parameterName = parameterName.trim(); +// } +// +// if(httpMethod != null) { +// httpMethod = httpMethod.trim(); +// } +// +// if(encode != null) { +// encode = encode.trim(); +// } +// +// if(soapAction != null) { +// soapAction = soapAction.trim(); +// } +// +// //---------------------------------- +// // 2008.02.15 이동훈 +// // 설정값이 없을 경우 무한대로 기다리도록 +// // 0 으로 설정하도록 함 +// //---------------------------------- +// if(httpTimeOut == null) { +// httpTimeOut = "0"; +// } +// else { +// httpTimeOut = httpTimeOut.trim(); +// } +// +// int timeout = -1; +// try { +// timeout = new Integer(httpTimeOut).intValue(); +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] HTTP TIMEOUT SET ["+httpTimeOut+"]"); +// } +// } catch(Exception e) { +// if(logger.isWarn()){ +// logger.warn("HttpClientAdapter] HTTP TIMEOUT 설정값을 확인하세요. ["+httpTimeOut+"]"); +// } +// } +// +// +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] Send("+httpMethod+") Data ["+new String(data)+"]"); +// } +// +// if(httpMethod!=null && httpMethod.equals(METHOD_POST)) { +// return callPostService(url, parameterName, data, encode, timeout); +// } +// else if(httpMethod!=null && httpMethod.equals(METHOD_SOAP)) { +// return callSoapService(url, soapAction, data, encode, timeout); +// } +// else if(httpMethod!=null && httpMethod.equals("MEMO")) { +// return callMemoService(url, data, encode, timeout); +// } +// else if(httpMethod!=null && httpMethod.equals("ANN")) { +// return callAnnounceService(url, data, encode, timeout); +// } +// else if(httpMethod!=null && httpMethod.equals("POPUP")) { +// return callPopupService(url, data, encode, timeout); +// } +// else if(httpMethod!=null && httpMethod.equals("CDSVC")) { +// return callChangeDateService(url, data, encode, timeout); +// } +// else { +// return callGetService(url, parameterName, data, encode, timeout); +// } +// } +// +// /** +// * 1. 기능 : 수동 시스템에 Post 방식으로 서비스 호출 +// * 2. 처리 개요 : +// * - 수동 시스템에 서비스 요청 하고 결과를 리턴 한다. +// * 3. 주의사항 +// * +// * @param url 수동 시스템 웹 컴포넌트 URL +// * @param parameterName URL 파리미터 이름 +// * @param data 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// private byte[] callPostService(String url, String parameterName, byte[] data, String encode, int timeout) +// throws Exception { +// PostMethod method = new PostMethod(url); +// +// //2008.02.15 : Timeout 처리로직 변경 (0 : 무한대 설정가능하게 함) +// if(timeout > -1) { +// method.getParams().setSoTimeout(timeout); +// } +// +// //method.setRequestHeader("Content-Type","text/html; charset=euc-kr"); +// +// String sendData = null; +// HttpClient mclient = new HttpClient(new MultiThreadedHttpConnectionManager()); +// +// if(encode != null && encode.length() > 0) { +// +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] ENCODE("+encode+") "); +// } +// +// try { +// mclient.getParams().setContentCharset(encode); +// sendData = new String(data,encode); +// } catch(Exception e) { +// if(logger.isError()){ +// logger.error("HttpClientAdapter] ENCODE("+encode+") ERROR : "+ e.toString()); +// logger.error("HttpClientAdapter] ENCODE("+encode+") SKIP "); +// } +// sendData = new String(data); +// } +// } +// else { +// //신용보증기금에 필요 분기 - 조현덕 추가(2008.11.04) +// if(parameterName.equals("SHINBO")){ +// ; +// }else{ +// sendData = java.net.URLEncoder.encode(new String(data)); +// } +// } +// +// +// if(parameterName==null || parameterName.equals("")) { +// method.addParameter(PARAMETER_MESSAGE, sendData); +// +// //신용보증기금에 필요 분기 - 조현덕 추가(2008.05.06) +// } else if(parameterName.equals("SHINBO")){ +// method.setRequestBody(sendData); +// } else { +// method.addParameter(parameterName, sendData); +// } +// +// +// int status = -1; +// +// +// try { +// status = mclient.executeMethod(method); +// //---------------------------------------------------------- +// // 2008.01.23 : 응답이 깨지는 것 수정 +// //---------------------------------------------------------- +// //String responseMessage = method.getResponseBodyAsString(); +// String responseMessage = new String(method.getResponseBody()); +// //---------------------------------------------------------- +// +// return responseMessage.getBytes(); +// +// } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// ste.printStackTrace(); +// System.out.println("HttpClientAdapter] SocketTimeoutException : " + ste.toString() ); +// throw ste; +// } catch(ConnectException ce) { +// ce.printStackTrace(); +// System.out.println("HttpClientAdapter] Connection Exception : " + ce.toString() ); +// throw ce; +// } catch(Exception e) { +// e.printStackTrace(); +// throw e; +// } finally { +// method.releaseConnection(); +// if(status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if(logger.isDebug()){ +// logger.debug(resMsg); +// } +// } +// } +// } +// +// /** +// * 1. 기능 : 수동 시스템에 Get 방식으로 서비스 호출 +// * 2. 처리 개요 : +// * - 수동 시스템에 서비스 요청 하고 결과를 리턴 한다. +// * 3. 주의사항 +// * +// * @param url 수동 시스템 웹 컴포넌트 URL +// * @param parameterName URL 파리미터 이름 +// * @param data 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// private byte[] callGetService(String url, String parameterName, byte[] data, String encode, int timeout) +// throws Exception { +// GetMethod method = new GetMethod(url); +// +// //2008.02.15 : Timeout 처리로직 변경 (0 : 무한대 설정가능하게 함) +// if(timeout > -1) { +// method.getParams().setSoTimeout(timeout); +// } +// +// String sendData = null; +// +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] GET Method URLEncoder"); +// } +// sendData = java.net.URLEncoder.encode(new String(data)); +// +// /* +// if(encode != null && encode.length() > 0) { +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] ENCODE("+encode+") "); +// } +// +// try { +// sendData = new String(data, encode); +// } catch(Exception e) { +// if(logger.isError()){ +// logger.error("HttpClientAdapter] ENCODE("+encode+") ERROR : "+ e.toString()); +// logger.error("HttpClientAdapter] ENCODE("+encode+") SKIP "); +// } +// sendData = new String(data); +// } +// } +// else { +// sendData = new String(data); +// +// } +// */ +// +// method.setQueryString(parameterName+"=" + sendData); +// +// int status = -1; +// try { +// status = client.executeMethod(method); +// //---------------------------------------------------------- +// // 2008.01.23 : 응답이 깨지는 것 수정 +// //---------------------------------------------------------- +// //String responseMessage = method.getResponseBodyAsString(); +// String responseMessage = new String(method.getResponseBody()); +// //---------------------------------------------------------- +// return responseMessage.getBytes(); +// } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// ste.printStackTrace(); +// System.out.println("HttpClientAdapter] SocketTimeoutException : " + ste.toString() ); +// throw ste; +// } catch(ConnectException ce) { +// ce.printStackTrace(); +// System.out.println("HttpClientAdapter] Connection Exception : " + ce.toString() ); +// throw ce; +// } catch(Exception e) { +// e.printStackTrace(); +// throw e; +// } finally { +// method.releaseConnection(); +// if(status!=HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA014", msgArgs); +// if(logger.isDebug()){ +// logger.debug(resMsg); +// } +// } +// } +// } +// +// /** +// * 1. 기능 : 수동 시스템에 SOAP 방식으로 서비스 호출 +// * 2. 처리 개요 : +// * - 수동 시스템에 서비스 요청 하고 결과를 리턴 한다. +// * 3. 주의사항 +// * +// * @param url 수동 시스템 웹 컴포넌트 URL +// * @param soapAction soapAction 이름 +// * @param data 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// private byte[] callSoapService(String url, String soapAction, byte[] data, String encode, int timeout) +// throws Exception { +// PostMethod method = new PostMethod(url); +// +// if(timeout > -1) { +// method.getParams().setSoTimeout(timeout); +// } +// +// ByteArrayRequestEntity entity = new ByteArrayRequestEntity(data); +// +// method.setRequestEntity(entity); +// method.setRequestHeader("SOAPAction", soapAction); +// +// int status = -1; +// +// +// try { +// status = client.executeMethod(method); +// //---------------------------------------------------------- +// // 2008.01.23 : 응답이 깨지는 것 수정 +// //---------------------------------------------------------- +// //String responseMessage = method.getResponseBodyAsString(); +// String responseMessage = new String(method.getResponseBody()); +// //---------------------------------------------------------- +// +// return responseMessage.getBytes(); +// +// } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// ste.printStackTrace(); +// System.out.println("HttpClientAdapter] SocketTimeoutException : " + ste.toString() ); +// throw ste; +// } catch(ConnectException ce) { +// ce.printStackTrace(); +// System.out.println("HttpClientAdapter] Connection Exception : " + ce.toString() ); +// throw ce; +// } catch(Exception e) { +// e.printStackTrace(); +// throw e; +// } finally { +// method.releaseConnection(); +// if(status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if(logger.isDebug()){ +// logger.debug(resMsg); +// } +// } +// } +// } +// +// /** +// * 1. 기능 : 수동 시스템에 Post 방식으로 메신저 연계서비스 호출 +// * 2. 처리 개요 : +// * - 수동 시스템에 서비스 요청 하고 결과를 리턴 한다. +// * 3. 주의사항 +// * +// * @param url 수동 시스템 웹 컴포넌트 URL +// * @param data 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// private byte[] callMemoService(String url, byte[] data, String encode, int timeout) +// throws Exception { +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] callMemoService called "); +// } +// +// PostMethod method = new PostMethod(url); +// +// //2008.02.15 : Timeout 처리로직 변경 (0 : 무한대 설정가능하게 함) +// if(timeout > -1) { +// method.getParams().setSoTimeout(timeout); +// } +// +// // 2009.08.24 강길수차장 요청 +// // MEMO Data Size : 161 Bytes -> 587 (항목 및 길이가 변경됨) +// int memoMinSize = 587; +// +// if(data.length >= memoMinSize) { +// if(encode != null && encode.length() > 0) { +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] callMemoService ENCODE("+encode+") "); +// } +// method.addParameter("SRV_CODE", new String(data, 0, 6, encode) ); +// method.addParameter("SER_TYPE", new String(data, 6, 1, encode) ); +// method.addParameter("RECIPIENT", new String(data, 7, 7, encode) ); +// method.addParameter("SEND", new String(data, 14, 7, encode) ); +// method.addParameter("TITLE", new String(data, 21, 40, encode) ); +// method.addParameter("BODY", new String(data, 61,500, encode) ); +// method.addParameter("URGENT", new String(data,561, 1, encode) ); +// method.addParameter("SAVEOPTION", new String(data,562, 1, encode) ); +// method.addParameter("RCV_IP", new String(data,563, 24, encode) ); +// } +// else { +// method.addParameter("SRV_CODE", new String(data, 0, 6) ); +// method.addParameter("SER_TYPE", new String(data, 6, 1) ); +// method.addParameter("RECIPIENT", new String(data, 7, 7) ); +// method.addParameter("SEND", new String(data, 14, 7) ); +// method.addParameter("TITLE", new String(data, 21, 40) ); +// method.addParameter("BODY", new String(data, 61,500) ); +// method.addParameter("URGENT", new String(data,561, 1) ); +// method.addParameter("SAVEOPTION", new String(data,562, 1) ); +// method.addParameter("RCV_IP", new String(data,563, 24) ); +// } +// } +// else { +// if(logger.isError()){ +// logger.error("HttpClientAdapter] callMemoService Invalid Data Length (" + data.length + ") < "+memoMinSize); +// } +// throw new Exception("HttpClientAdapter.callMemoService Error : MessageSize("+(data.length)+" Bytes) too small < "+memoMinSize); +// } +// +// int status = -1; +// +// +// try { +// HttpClient mclient = new HttpClient(new MultiThreadedHttpConnectionManager()); +// mclient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); +// mclient.getParams().setContentCharset("EUC_KR"); +// status = mclient.executeMethod(method); +// String responseMessage = new String(method.getResponseBody()); +// +// return responseMessage.getBytes(); +// +// } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// ste.printStackTrace(); +// System.out.println("HttpClientAdapter] SocketTimeoutException : " + ste.toString() ); +// throw ste; +// } catch(ConnectException ce) { +// ce.printStackTrace(); +// System.out.println("HttpClientAdapter] Connection Exception : " + ce.toString() ); +// throw ce; +// } catch(Exception e) { +// e.printStackTrace(); +// throw e; +// } finally { +// method.releaseConnection(); +// if(status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if(logger.isDebug()){ +// logger.debug(resMsg); +// } +// } +// } +// } +// +// /** +// * 1. 기능 : 수동 시스템에 Post 방식으로 메신저 연계서비스 호출 +// * 2. 처리 개요 : +// * - 수동 시스템에 서비스 요청 하고 결과를 리턴 한다. +// * 3. 주의사항 +// * +// * @param url 수동 시스템 웹 컴포넌트 URL +// * @param data 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// private byte[] callAnnounceService(String url, byte[] data, String encode, int timeout) +// throws Exception { +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] callAnnounceService called "); +// } +// +// PostMethod method = new PostMethod(url); +// +// //2008.02.15 : Timeout 처리로직 변경 (0 : 무한대 설정가능하게 함) +// if(timeout > -1) { +// method.getParams().setSoTimeout(timeout); +// } +// +// // Announce Data Size : 113 Bytes +// int annMinSize = 113; +// +// if(data.length >= annMinSize) { +// if(encode != null && encode.length() > 0) { +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] callAnnounceService ENCODE("+encode+") "); +// } +// method.addParameter("SRV_CODE", new String(data, 0, 6, encode) ); +// method.addParameter("RECIPIENT", new String(data, 6, 7, encode) ); +// method.addParameter("BODY", new String(data, 13,100, encode) ); +// if(data.length > 153) { +// method.addParameter("URL", new String(data, 113, data.length-annMinSize,encode) ); +// } +// } +// else { +// method.addParameter("SRV_CODE", new String(data, 0, 6) ); +// method.addParameter("RECIPIENT", new String(data, 6, 7) ); +// method.addParameter("BODY", new String(data, 13,100) ); +// if(data.length > 153) { +// method.addParameter("URL", new String(data,113, data.length-annMinSize) ); +// } +// } +// } +// else { +// if(logger.isError()){ +// logger.error("HttpClientAdapter] callAnnounceService Invalid Data Length (" + data.length + ") < "+annMinSize); +// } +// throw new Exception("HttpClientAdapter.callAnnounceService Error : MessageSize("+(data.length)+" Bytes) too small < "+annMinSize); +// } +// +// int status = -1; +// +// +// try { +// HttpClient mclient = new HttpClient(new MultiThreadedHttpConnectionManager()); +// mclient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); +// mclient.getParams().setContentCharset("EUC_KR"); +// status = mclient.executeMethod(method); +// String responseMessage = new String(method.getResponseBody()); +// +// return responseMessage.getBytes(); +// +// } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// ste.printStackTrace(); +// System.out.println("HttpClientAdapter] SocketTimeoutException : " + ste.toString() ); +// throw ste; +// } catch(ConnectException ce) { +// ce.printStackTrace(); +// System.out.println("HttpClientAdapter] Connection Exception : " + ce.toString() ); +// throw ce; +// } catch(Exception e) { +// e.printStackTrace(); +// throw e; +// } finally { +// method.releaseConnection(); +// if(status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if(logger.isDebug()){ +// logger.debug(resMsg); +// } +// } +// } +// } +// +// /** +// * 1. 기능 : 수동 시스템에 Post 방식으로 메신저 연계서비스 호출 +// * 2. 처리 개요 : +// * - 수동 시스템에 서비스 요청 하고 결과를 리턴 한다. +// * 3. 주의사항 +// * +// * @param url 수동 시스템 웹 컴포넌트 URL +// * @param data 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// private byte[] callPopupService(String url, byte[] data, String encode, int timeout) +// throws Exception { +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] callPopupService called "); +// } +// +// PostMethod method = new PostMethod(url); +// +// +// //2008.02.15 : Timeout 처리로직 변경 (0 : 무한대 설정가능하게 함) +// if(timeout > -1) { +// method.getParams().setSoTimeout(timeout); +// } +// +// // Popup Data Size : 153 Bytes +// int popupMinSize = 153; +// +// if(data.length >= popupMinSize) { +// if(encode != null && encode.length() > 0) { +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] callPopupService ENCODE("+encode+") "); +// } +// method.addParameter("SRV_CODE", new String(data, 0, 6, encode) ); +// method.addParameter("RECIPIENT", new String(data, 6, 7, encode) ); +// method.addParameter("TITLE", new String(data, 13, 40, encode) ); +// method.addParameter("BODY", new String(data, 53,100, encode) ); +// } +// else { +// method.addParameter("SRV_CODE", new String(data, 0, 6) ); +// method.addParameter("RECIPIENT", new String(data, 6, 7) ); +// method.addParameter("TITLE", new String(data, 13, 40) ); +// method.addParameter("BODY", new String(data, 53,100) ); +// } +// } +// else { +// if(logger.isError()){ +// logger.error("HttpClientAdapter] callPopupService Invalid Data Length (" + data.length + ") < "+popupMinSize); +// } +// throw new Exception("HttpClientAdapter.callPopupService Error : MessageSize("+(data.length)+" Bytes) too small < "+popupMinSize); +// } +// +// int status = -1; +// +// +// try { +// HttpClient mclient = new HttpClient(new MultiThreadedHttpConnectionManager()); +// mclient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); +// mclient.getParams().setContentCharset("EUC_KR"); +// status = mclient.executeMethod(method); +// String responseMessage = new String(method.getResponseBody()); +// +// return responseMessage.getBytes(); +// +// } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// ste.printStackTrace(); +// System.out.println("HttpClientAdapter] SocketTimeoutException : " + ste.toString() ); +// throw ste; +// } catch(ConnectException ce) { +// ce.printStackTrace(); +// System.out.println("HttpClientAdapter] Connection Exception : " + ce.toString() ); +// throw ce; +// } catch(Exception e) { +// e.printStackTrace(); +// throw e; +// } finally { +// method.releaseConnection(); +// if(status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if(logger.isDebug()){ +// logger.debug(resMsg); +// } +// } +// } +// } +// +// /** +// * 1. 기능 : 수동 시스템에 Post 방식으로 일자전환이벤트 호출 +// * 2. 처리 개요 : +// * - 수동 시스템에 서비스 요청 하고 결과를 리턴 한다. +// * 3. 주의사항 +// * +// * @param url 수동 시스템 웹 컴포넌트 URL +// * @param data 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// private byte[] callChangeDateService(String url, byte[] data, String encode, int timeout) +// throws Exception { +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] callChangeDateService called "); +// } +// +// PostMethod method = new PostMethod(url); +// +// //2008.02.15 : Timeout 처리로직 변경 (0 : 무한대 설정가능하게 함) +// if(timeout > -1) { +// method.getParams().setSoTimeout(timeout); +// } +// +// // Data Size : 15 Bytes +// int popupMinSize = 15; +// +// if(data.length >= popupMinSize) { +// if(encode != null && encode.length() > 0) { +// if(logger.isDebug()){ +// logger.debug("HttpClientAdapter] callChangeDateService ENCODE("+encode+") "); +// } +// method.addParameter("req", new String(data, 0, 7, encode).trim() ); +// method.addParameter("date", new String(data, 7, 8, encode) ); +// } +// else { +// method.addParameter("req", new String(data, 0, 7).trim() ); +// method.addParameter("date", new String(data, 7, 8) ); +// } +// } +// else { +// if(logger.isError()){ +// logger.error("HttpClientAdapter] callChangeDateService Invalid Data Length (" + data.length + ") < "+popupMinSize); +// } +// throw new Exception("HttpClientAdapter.callChangeDateService Error : MessageSize("+(data.length)+" Bytes) too small < "+popupMinSize); +// } +// +// int status = -1; +// +// +// try { +// HttpClient mclient = new HttpClient(new MultiThreadedHttpConnectionManager()); +// mclient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); +// mclient.getParams().setContentCharset("EUC_KR"); +// status = mclient.executeMethod(method); +// String responseMessage = new String(method.getResponseBody()); +// +// return responseMessage.getBytes(); +// +// } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// ste.printStackTrace(); +// System.out.println("HttpClientAdapter] SocketTimeoutException : " + ste.toString() ); +// throw ste; +// } catch(ConnectException ce) { +// ce.printStackTrace(); +// System.out.println("HttpClientAdapter] Connection Exception : " + ce.toString() ); +// throw ce; +// } catch(Exception e) { +// e.printStackTrace(); +// throw e; +// } finally { +// method.releaseConnection(); +// if(status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if(logger.isDebug()){ +// logger.debug(resMsg); +// } +// } +// } +// } +//} diff --git a/src/main/java/com/eactive/eai/adapter/http/HttpClientTest.java b/src/main/java/com/eactive/eai/adapter/http/HttpClientTest.java new file mode 100644 index 0000000..17fca07 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/HttpClientTest.java @@ -0,0 +1,94 @@ +package com.eactive.eai.adapter.http; +//import org.apache.commons.httpclient.params.HttpClientParams; + + +public class HttpClientTest +{ +// public static void main(String args[]) throws Exception { +// MultiThreadedHttpConnectionManager cm = new MultiThreadedHttpConnectionManager(); +// +// +// cm.setConnectionStaleCheckingEnabled(false); +// cm.setMaxConnectionsPerHost(10); +// cm.setMaxTotalConnections(1); +// +// // 2.0 +// HttpClient client = new HttpClient(cm); +// +// //--------------------------------------------- +// // 3.1 +// //--------------------------------------------- +// /* +// HttpClientParams params = new HttpClientParams(); +// params.setSoTimeout(10 * 1000); +// HttpClient client = new HttpClient(params, cm); +// */ +// //--------------------------------------------- +// +// // Client Timeout 2.0 +// //client.setTimeout(1000); +// String url = "http://172.29.65.69:7001/servlets/knova/svc/servlet/KBServlet"; +// //String url = "http://search.empas.com/error.html"; +// //String url = "http://172.17.33.237:7001/servlets/knova/svc/servlet/KBServlet"; +// +// PostMethod method = new PostMethod(url); +// DefaultMethodRetryHandler retryhandler = new DefaultMethodRetryHandler(); +// retryhandler.setRequestSentRetryEnabled(false); +// retryhandler.setRetryCount(3); +// method.setMethodRetryHandler(retryhandler); +// +// method.getParams().setSoTimeout(5000); +// +// System.out.println("HttpClientAdapter] getContentCharset("+client.getParams().getContentCharset()+") "); +// //client.getParams().setContentCharset("KSC5601"); +// System.out.println("HttpClientAdapter] getContentCharset("+client.getParams().getContentCharset()+") "); +// +// String encode = "ISO8859_1"; +// byte[] data = "000924KCO.11YE#0803249920000026 0200NOV01500001 20080324175117 HOSTDOM NOVDOM BB2B YE#0803249920000026 4001 000306604151345551013205062155211 이기옥             EL08022500020000000000000000056020080324200902261 ? 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 " +// .getBytes(); +// String sendData = null; +// if(encode != null && encode.length() > 0) { +// System.out.println("HttpClientAdapter] ENCODE("+encode+") "); +// +// try { +// sendData = new String(data,encode); +// } catch(Exception e) { +// System.out.println("HttpClientAdapter] ENCODE("+encode+") ERROR : "+ e.toString()); +// System.out.println("HttpClientAdapter] ENCODE("+encode+") SKIP "); +// sendData = new String(data); +// } +// } +// else { +// sendData = java.net.URLEncoder.encode(new String(data)); +// } +// +// method.addParameter("_ELD_", sendData); +// +// int status = -1; +// try { +// status = client.executeMethod(method); +// //String responseMessage = method.getResponseBodyAsString(); +// byte[] responseBytes = method.getResponseBody(); +// System.out.println("method.getRequestCharSet() [" + method.getRequestCharSet() +"]"); +// System.out.println("method.getResponseCharSet() [" + method.getResponseCharSet() +"]"); +// System.out.println("responseMessage [" +new String(responseBytes) +"]"); +// System.out.println("ISO8859_1 [" + new String(responseBytes, "ISO8859_1") +"]"); +// System.out.println("EUC-KR [" + new String(responseBytes, "EUC-KR") +"]"); +// } catch(ConnectException ce) { +// System.out.println("Connection Exception : " + ce.toString() ); +// } catch(HttpRecoverableException hre) { // HttpClient 2.0일 경우에 발생 +// System.out.println("HttpRecoverableException : " + hre.toString() ); +// } catch(SocketTimeoutException ste) { // HttpClient 3.1일 경우에 발생 +// System.out.println("SocketTimeoutException : " + ste.toString() ); +// } catch(Exception e) { +// e.printStackTrace(); +// throw e; +// } finally { +// method.releaseConnection(); +// if(status != HttpStatus.SC_OK) { +// System.out.println("HttpStatus ["+status+"]"); +// } +// } +// } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/HttpExtOrgClientAdapterTestCall.java b/src/main/java/com/eactive/eai/adapter/http/HttpExtOrgClientAdapterTestCall.java new file mode 100644 index 0000000..1cb51a3 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/HttpExtOrgClientAdapterTestCall.java @@ -0,0 +1,79 @@ +package com.eactive.eai.adapter.http; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.testcall.TestCallException; +import com.eactive.eai.common.testcall.TestCallSupport; +import com.eactive.eai.common.util.Logger; + +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Properties; + +//HttpQuicsClientAdapter의 통신상태를 체크하는 클래스 +public class HttpExtOrgClientAdapterTestCall extends TestCallSupport +{ + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public boolean isAlive() throws TestCallException + { + logger.debug("HttpExtOrgClientAdapterTestCall started"); + + try { + AdapterVO vo = this.getAdapterInfo(); + String pgoName = vo.getPropGroupName(); + //PropManager manager = PropManager.getInstance(); + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties prop = manager.getProperties(pgoName); + + + String url = prop.getProperty("URL"); + //String url = "101.88.50.120:8285"; + logger.debug("HttpExtOrgClientAdapterTestCall URL]["+url+"s]"); + + URL u = null; + try { + logger.debug("HttpExtOrgClientAdapterTestCall] url - ["+url+"]"); + u = new URL(url); + } catch (MalformedURLException e) { + logger.warn("HttpExtOrgClientAdapterTestCall] Error at new URL - "+e.getClass().getName()+" : "+e.getMessage()); + return false; + } + + HttpURLConnection conn = null; + + try { + conn = (HttpURLConnection) u.openConnection(); + } catch (Exception e) { + logger.warn("HttpExtOrgClientAdapterTestCall] Error at openConnection - "+e.getClass().getName()+" : "+e.getMessage()); + return false; + } + + if(conn == null){ + logger.warn("HttpExtOrgClientAdapterTestCall] Error at HttpURLConnection is null "); + return false; + } + logger.debug("HttpExtOrgClientAdapterTestCall ] try HttpURLConnection connect"); + conn.connect(); + logger.debug("HttpExtOrgClientAdapterTestCall end"); + return true; + + } catch(Exception e) { + //e.printStackTrace(); + logger.warn("HttpExtOrgClientAdapterTestCall] Error - "+e.getClass().getName()+" : "+e.getMessage()); + return false; + } + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// HttpExtOrgClientAdapterTestCall test = new HttpExtOrgClientAdapterTestCall(); +// System.out.println("HttpExtOrgClientAdapterTestCall ] isAlive - ["+test.isAlive()+"]"); +// } +} + diff --git a/src/main/java/com/eactive/eai/adapter/http/HttpMemoryLogger.java b/src/main/java/com/eactive/eai/adapter/http/HttpMemoryLogger.java new file mode 100644 index 0000000..d1c580d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/HttpMemoryLogger.java @@ -0,0 +1,127 @@ +package com.eactive.eai.adapter.http; + +import com.eactive.eai.transformer.util.CircularQueue; +import com.eactive.eai.transformer.util.ExceptionStackTrace; + +import java.util.LinkedHashMap; + + +public class HttpMemoryLogger { + final static int MAX_LOG_MESSAGE_SIZE = 500000; + + static LinkedHashMap txQueues = new LinkedHashMap(); + static LinkedHashMap errorQueues = new LinkedHashMap(); + static LinkedHashMap errorCounts = new LinkedHashMap(); + static LinkedHashMap txCounts = new LinkedHashMap(); + + static private void checkTxQueue(String adapterGroupName){ + if (txQueues.get(adapterGroupName) == null){ + txQueues.put(adapterGroupName,new CircularQueue(20)); + } + } + static private void checkErrorQueue(String adapterGroupName){ + if (errorQueues.get(adapterGroupName) == null){ + errorQueues.put(adapterGroupName,new CircularQueue(20)); + } + } + static private void checkErrorCount(String adapterGroupName){ + if (errorCounts.get(adapterGroupName) == null){ + errorCounts.put(adapterGroupName,new Long(0)); + } + } + static private void checkTxCount(String adapterGroupName){ + if (txCounts.get(adapterGroupName) == null){ + txCounts.put(adapterGroupName,new Long(0)); + } + } + static public long getTransactionCount(String adapterGroupName) { + checkTxCount(adapterGroupName); + if (txCounts.get(adapterGroupName) == null) + return 0; + return txCounts.get(adapterGroupName); + } + + static public String[] getTransactions(String adapterGroupName) { + checkTxQueue(adapterGroupName); + return txQueues.get(adapterGroupName).getRecords(); + } + + +// static public void txlog(String adapterGroupName, String message) { +// if (message == null) +// return; +// if (message.length() > MAX_LOG_MESSAGE_SIZE) +// message = message.substring(0, MAX_LOG_MESSAGE_SIZE); +// checkTxQueue(adapterGroupName); +// txQueues.get(adapterGroupName).addRecord(message); +// } + + static public void txlog(String adapterGroupName, String message) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE); + synchronized(HttpMemoryLogger.class) { + checkTxCount(adapterGroupName); + checkTxQueue(adapterGroupName); + Long l = txCounts.get(adapterGroupName); + txCounts.put(adapterGroupName,++l); + } + txQueues.get(adapterGroupName).addRecord(message); + } + + + static public long getErrorCount(String adapterGroupName) { + checkErrorCount(adapterGroupName); + if (errorCounts.get(adapterGroupName) == null) + return 0; + return errorCounts.get(adapterGroupName); + } + + static public String[] getErrors(String adapterGroupName) { + checkErrorQueue(adapterGroupName); + return errorQueues.get(adapterGroupName).getRecords(); + } + + static public void error(String adapterGroupName, String message) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE); + + synchronized(HttpMemoryLogger.class) { + checkErrorCount(adapterGroupName); + checkErrorQueue(adapterGroupName); + Long l = errorCounts.get(adapterGroupName); + errorCounts.put(adapterGroupName,++l); + } + errorQueues.get(adapterGroupName).addRecord(message); + //txQueues.get(adapterGroupName).addRecord("" + message + ""); + } + + static public void error(String adapterGroupName,String message, Throwable t) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE); + + synchronized(HttpMemoryLogger.class) { + checkErrorCount(adapterGroupName); + checkErrorQueue(adapterGroupName); + Long l = errorCounts.get(adapterGroupName); + errorCounts.put(adapterGroupName,++l); + } + errorQueues.get(adapterGroupName).addRecord(message + " | " + ExceptionStackTrace.dump(t)); + //txQueues.get(adapterGroupName).addRecord("" + message + "\n" + ExceptionStackTrace.dump(t) + ""); + } + static public boolean isMemoryLogEnabled(String adapterGroupName) { + return true; +// PropGroupVO propGroupVO = PropManager.getInstance().getPropGroupVO("Transformer"); +// if (propGroupVO == null) +// return false; +// String value = propGroupVO.getProperty("memory.log"); +// if ("1".equals(value)) +// return true; +// return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/HttpMethodType.java b/src/main/java/com/eactive/eai/adapter/http/HttpMethodType.java new file mode 100644 index 0000000..5631af6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/HttpMethodType.java @@ -0,0 +1,26 @@ +package com.eactive.eai.adapter.http; + +public enum HttpMethodType { + POST, + PUT, + DELETE, + GET, + UNKNOWN; + public static HttpMethodType getValue(String value) { + try { + return valueOf(value.toUpperCase()); + } catch (Exception e) { + return UNKNOWN; + } + } + +// public static void main(String[] args) throws Exception { +// +// if ("DELETE".equals(HttpMethodType.DELETE.toString())){ +// System.out.println("delete"); +// }else{ +// +// System.out.println("not delete"); +// } +// } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/HttpStatusException.java b/src/main/java/com/eactive/eai/adapter/http/HttpStatusException.java new file mode 100644 index 0000000..b8a82cf --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/HttpStatusException.java @@ -0,0 +1,63 @@ +package com.eactive.eai.adapter.http; + +import org.apache.commons.lang3.StringUtils; + +public class HttpStatusException extends Exception { + /** + * + */ + private static final long serialVersionUID = 1L; + private int status = 200; + private String code; + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : Default Constructor + * 3. 주의사항 + * + **/ + public HttpStatusException() { + super("HttpStatusException is occured."); + } + + /** + * 1. 기능 : Exception message를 초기화하는 Constructor + * 2. 처리 개요 : Exception message를 초기화하는 Constructor + * - + * 3. 주의사항 + * + * @param msg Exception message + **/ + public HttpStatusException(String msg) { + super(msg); + } + public HttpStatusException(String msg, int status) { + super(msg); + this.status = status; + } + public HttpStatusException(String msg, String code, int status) { + super(msg); + this.setCode(code); + this.status = status; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getCode() { + if (StringUtils.isBlank(code)) { + return String.format("Http Status: %d", status); + } else { + return code; + } + } + + public void setCode(String code) { + this.code = code; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/async/AppAsyncListener.java b/src/main/java/com/eactive/eai/adapter/http/async/AppAsyncListener.java new file mode 100644 index 0000000..3d1a9b5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/async/AppAsyncListener.java @@ -0,0 +1,39 @@ +package com.eactive.eai.adapter.http.async; + +import javax.servlet.AsyncEvent; +import javax.servlet.AsyncListener; +import javax.servlet.ServletResponse; +import java.io.IOException; +import java.io.PrintWriter; + +//@WebListener +public class AppAsyncListener implements AsyncListener { + + @Override + public void onComplete(AsyncEvent asyncEvent) throws IOException { +// System.out.println("AppAsyncListener onComplete"); + // we can do resource cleanup activity here + } + + @Override + public void onError(AsyncEvent asyncEvent) throws IOException { +// System.out.println("AppAsyncListener onError"); + //we can return error response to client + } + + @Override + public void onStartAsync(AsyncEvent asyncEvent) throws IOException { +// System.out.println("AppAsyncListener onStartAsync"); + //we can log the event here + } + + @Override + public void onTimeout(AsyncEvent asyncEvent) throws IOException { +// System.out.println("AppAsyncListener onTimeout"); + //we can send appropriate response to client + ServletResponse response = asyncEvent.getAsyncContext().getResponse(); + PrintWriter out = response.getWriter(); + out.write("TimeOut Error in Processing"); + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/async/AppContextListener.java b/src/main/java/com/eactive/eai/adapter/http/async/AppContextListener.java new file mode 100644 index 0000000..ef9fae5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/async/AppContextListener.java @@ -0,0 +1,28 @@ +package com.eactive.eai.adapter.http.async; + +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +//@WebListener +public class AppContextListener implements ServletContextListener { + + public void contextInitialized(ServletContextEvent servletContextEvent) { + // Default Timeout Setting 60sec + ThreadPoolExecutor executor = new ThreadPoolExecutor(100, 200, 60000L, + TimeUnit.MILLISECONDS, new ArrayBlockingQueue(100)); + servletContextEvent.getServletContext().setAttribute("executor", + executor); +// System.out.println("AppContextListener contextInitialized::set ThreadPoolExecutor"); + } + + public void contextDestroyed(ServletContextEvent servletContextEvent) { + ThreadPoolExecutor executor = (ThreadPoolExecutor) servletContextEvent + .getServletContext().getAttribute("executor"); + executor.shutdown(); +// System.out.println("AppContextListener contextDestroyed::shutdown ThreadPoolExecutor"); + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/async/AsyncRequestProcessor.java b/src/main/java/com/eactive/eai/adapter/http/async/AsyncRequestProcessor.java new file mode 100644 index 0000000..289690a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/async/AsyncRequestProcessor.java @@ -0,0 +1,92 @@ +package com.eactive.eai.adapter.http.async; + +import com.eactive.eai.adapter.RequestDispatcher; +import com.eactive.eai.common.util.Logger; + +import javax.servlet.AsyncContext; +import javax.servlet.ServletInputStream; +import javax.servlet.ServletRequest; +import java.io.IOException; +import java.io.PrintWriter; +import java.nio.ByteBuffer; +import java.util.Properties; + +public class AsyncRequestProcessor implements Runnable { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private AsyncContext asyncContext; + + private String adapterGroupName; + private String adapterName; + private String encode = "euc-kr"; + + public AsyncRequestProcessor() { + } + + public AsyncRequestProcessor(AsyncContext asyncCtx) { + this.asyncContext = asyncCtx; + + // TODO : define adapter name rule + this.adapterGroupName = "_EAI_IN_HTT_SyS"; + this.adapterName = "_EAI_IN_HTT_SyS{ALL}"; + } + + @Override + public void run() { +// System.out.println("Async Supported? " +// + asyncContext.getRequest().isAsyncSupported()); + + ServletRequest request = asyncContext.getRequest(); + + ServletInputStream sis; + byte[] requestBytes = null; + byte[] result = null; + try { + sis = request.getInputStream(); + + ByteBuffer bb = ByteBuffer.allocate(1024); + int i=0; + byte[] cbuf = new byte[1024]; + while( ( i = sis.read(cbuf, 0, 1024) ) != -1 ) { + if (i==1024){ + bb.put(cbuf); + }else{ + byte[] tail = new byte[i]; + System.arraycopy(cbuf, 0, tail, 0, i); + bb.put(tail); + } + } + requestBytes = new byte[bb.position()]; + bb.position(0); + bb.get(requestBytes); + + Properties prop = new Properties(); + // call Inbound Proxy + result = service(requestBytes, prop); + PrintWriter out = asyncContext.getResponse().getWriter(); + String encodedResponse = new String(result, encode); + out.write(encodedResponse); + } catch (IOException e1) { + logger.error("AsyncRequestProcessor IOException", e1); + } catch (Exception e) { + logger.error("AsyncRequestProcessor Exception", e); + } + finally { + if(asyncContext != null) { + asyncContext.complete(); + } + } + } + + protected byte[] service(byte[] message, Properties prop) throws Exception { + Object obj = RequestDispatcher.getRequestDispatcher(this.adapterGroupName).handle(adapterName, message, prop); + if(obj == null) return null; + if(obj instanceof byte[]) { + return (byte[])obj; + } else if(obj instanceof String) { + return ((String)obj).getBytes(); + } else { + throw new Exception("RECEAIAHA001"); + } + } +} + diff --git a/src/main/java/com/eactive/eai/adapter/http/async/AsyncServlet.java b/src/main/java/com/eactive/eai/adapter/http/async/AsyncServlet.java new file mode 100644 index 0000000..d9bbd3d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/async/AsyncServlet.java @@ -0,0 +1,54 @@ +package com.eactive.eai.adapter.http.async; + +import javax.servlet.AsyncContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.concurrent.ThreadPoolExecutor; + +//@WebServlet(urlPatterns = "/AsyncServlet", asyncSupported = true) +public class AsyncServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + @Override + protected void doPost(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + handle(request, response); + } + @Override + protected void doGet(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + handle(request, response); + } + + private void handle(HttpServletRequest request, + HttpServletResponse response) { +// long startTime = System.currentTimeMillis(); +// System.out.println("AsyncServlet Start::Name=" +// + Thread.currentThread().getName() + "::ID=" +// + Thread.currentThread().getId()); + + request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true); + + AsyncContext asyncCtx = request.startAsync(); + AppAsyncListener asyncListener = new AppAsyncListener(); + asyncCtx.addListener(asyncListener); + asyncCtx.setTimeout(30000); // Async Timeout 30 secs + +// ThreadPoolExecutor executor = (ThreadPoolExecutor) request +// .getServletContext().getAttribute("executor"); +// executor.execute(new AsyncRequestProcessor(asyncCtx)); + + asyncCtx.start(new AsyncRequestProcessor(asyncCtx)); + +// long endTime = System.currentTimeMillis(); +// System.out.println("AsyncServlet End::Name=" +// + Thread.currentThread().getName() + "::ID=" +// + Thread.currentThread().getId() + "::Time Taken=" +// + (endTime - startTime) + " ms."); + + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java new file mode 100644 index 0000000..80655b5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClient5AdapterServiceSupport.java @@ -0,0 +1,538 @@ + +package com.eactive.eai.adapter.http.client; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URISyntaxException; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.HashMap; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.net.ssl.SSLContext; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.hc.client5.http.classic.HttpClient; +import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TrustAllStrategy; +import org.apache.hc.core5.http.HttpRequest; +import org.apache.hc.core5.http.HttpRequestInterceptor; +import org.apache.hc.core5.http.HttpResponseInterceptor; +import org.apache.hc.core5.ssl.SSLContextBuilder; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.secure.HttpClient5SSLContextFactory; +import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.util.HttpAdapterExtraLogUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; +import com.eactive.eai.util.TestModeChecker; + +public abstract class HttpClient5AdapterServiceSupport implements HttpClientAdapterService, HttpClientAdapterServiceKey { + protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + protected HttpClient client; + PoolingHttpClientConnectionManager connectionManager; + + private static boolean testMode = TestModeChecker.isTestMode(); + + public synchronized void close() { + if(connectionManager != null) { + connectionManager.close(); + } + } + + protected HttpClientAdapterVO setting(Properties prop, Properties tempProp) { + String url = null; + String parameterName = null; + String method = null; + String contentType = null; + String encode = null; + String testCallYn = null; + String adapterGroupName = null; + String adapterName = null; + String responseType = null; + String urlEncodeYn = null; + String adapterHeader = null; + + boolean useMtls = false; + String keyStorePath = null; + String keyStorePassword = null; + String trustStorePath = null; + String trustStorePassword = null; + + int connectionTimeout = 0; + int timeout = -1; + int traceLevel = 0; + long slowTranTime = 2000L; + + url = prop.getProperty(URL); + + String url2grp = tempProp.getProperty(URL); + if (!StringUtils.isEmpty(url2grp)) { + url = url2grp; + } + method = prop.getProperty(METHOD); + parameterName = prop.getProperty(PARAMETER_NAME, PARAMETER_MESSAGE); + contentType = prop.getProperty(CONTENT_TYPE, ""); + responseType = prop.getProperty(RESPONSE_TYPE, "SYNC"); + urlEncodeYn = prop.getProperty(URL_ENCODE_YN, "N"); + String connectionTimeoutTemp = prop.getProperty(CONNECTION_TIMEOUT, "0"); + + String httpVersion = prop.getProperty(HTTP_VERSION); + adapterHeader = prop.getProperty(ADAPTER_HEADER, ""); + + String traceLevelTemp = prop.getProperty(TRACE_LEVEL, "0"); + String timeoutTemp = prop.getProperty(HTTP_TIME_OUT, "0"); + + useMtls = StringUtils.equalsIgnoreCase(prop.getProperty(HttpClientAdapterServiceKey.USE_MTLS),"Y"); + keyStorePath = prop.getProperty(HttpClientAdapterServiceKey.KEYSTORE_PATH); + keyStorePassword = prop.getProperty(HttpClientAdapterServiceKey.KEYSTORE_PWD); + trustStorePath = prop.getProperty(HttpClientAdapterServiceKey.TRUSTSTORE_PATH); + trustStorePassword = prop.getProperty(HttpClientAdapterServiceKey.TRUSTSTORE_PWD); + + encode = tempProp.getProperty(Keys.CHARSET_KEY_OUT, Charset.defaultCharset().name()); + testCallYn = tempProp.getProperty(TESTCALL_YN, "N"); + adapterGroupName = tempProp.getProperty(ADAPTER_GROUP_NAME); + adapterName = tempProp.getProperty(ADAPTER_NAME); + // 인터페이스 정보에 설정된 타임아웃 + String interfaceTimeout = tempProp.getProperty("INTERFACE_TIME_OUT"); + if (StringUtils.isNotBlank(interfaceTimeout) && NumberUtils.toInt(interfaceTimeout) > 0) { + timeoutTemp = interfaceTimeout; + } + + url = StringUtils.trim(url); + parameterName = StringUtils.trim(parameterName); + method = StringUtils.trim(method); + encode = StringUtils.trim(encode); + contentType = StringUtils.trim(contentType); + + try { + connectionTimeout = Integer.parseInt(connectionTimeoutTemp); + } catch (Exception e) { + logger.debug("HttpClientAdapterSupport] connectionTimeoutTemp not int"); + } + + try { + timeout = Integer.parseInt(timeoutTemp); + } catch (NumberFormatException e) { + logger.warn("HttpClientAdapterSupport] timeoutTemp not int", e); + } + + try { + traceLevel = Integer.parseInt(traceLevelTemp); + } catch (Exception e) { + logger.warn("HttpClientAdapterSupport] traceLevelTemp not int", e); + } + + // client 중 BODY,POST,GET,NexCore 방식만 적용 + HashMap adapterHeaders = new HashMap<>(); + try { + Matcher matcher = Pattern + .compile("\\{[ ]*\"[ ]*([a-zA-Z0-9_-]+)[ ]*\"[ ]*,[ ]*\"[ ]*([a-zA-Z0-9/;,\\*=_ -]+)[ ]*\"[ ]*\\}[ ]*") + .matcher(adapterHeader.trim()); + while (matcher.find()) { + String key = matcher.group(1).trim(); + String value = matcher.group(2).trim(); + adapterHeaders.put(key, value); + } + } catch (Exception e) { + if(logger.isDebug()) logger.debug("HttpClientAdapterSupport] adapter header parsing error " + adapterHeader); + } + // GW 전달 로직 추가 + // tempProp로 넘겨서 하는 이유는 outboundProp가 clone 안하는 로직이라 outboundProp로 넘길시 문제의 소지가있음 + String transactionId = tempProp.getProperty(HttpClientAdapterServiceKey.TRANSACTION_ID); + String instanceId = tempProp.getProperty(HttpClientAdapterServiceKey.INSTANCE_ID); + if (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(instanceId)) { + adapterHeaders.put(HttpClientAdapterServiceKey.TRANSACTION_ID, transactionId); + adapterHeaders.put(HttpClientAdapterServiceKey.INSTANCE_ID, instanceId); + } + + HttpClientAdapterVO vo = new HttpClientAdapterVO(); + vo.setUrl(url); + vo.setMethod(method); + vo.setParameterName(parameterName); + vo.setEncode(encode); + vo.setContentType(contentType); + vo.setTestCallYn(testCallYn); + vo.setResponseType(responseType); + vo.setUrlEncodeYn(urlEncodeYn); + vo.setAdapterGroupName(adapterGroupName); + vo.setAdapterName(adapterName); + + vo.setMaxTotalConnections(getMaxTotalConnections()); + vo.setMaxHostConnections(getMaxConnectionsPerHost()); + vo.setConnectionTimeout(connectionTimeout); + + vo.setTimeout(timeout); + vo.setTraceLevel(traceLevel); + vo.setSlowTranTime(slowTranTime); + vo.setAdapterHeaders(adapterHeaders); + if (StringUtils.equalsAny(httpVersion, HTTP_VERSION_FULL_1_1, HTTP_VERSION_1_1)) { + vo.setHttpVersion(HTTP_VERSION_1_1); + } + else if (StringUtils.equals(httpVersion, HTTP_VERSION_2_0)) { + vo.setHttpVersion(HTTP_VERSION_2_0); + } + else { + vo.setHttpVersion(HTTP_VERSION_1_0); + } + vo.setUseMtls(useMtls); + vo.setKeyStorePath(keyStorePath); + vo.setKeyStorePassword(keyStorePassword); + vo.setTrustStorePath(trustStorePath); + vo.setTrustStorePassword(trustStorePassword); + if (logger.isDebug()) { + logger.debug(vo.toString()); + } + return vo; + } + + protected HttpClient5AdapterServiceSupport() { + } + + public synchronized void init(String adapterName, + boolean useMtls, HttpOutTlsInfoVO mtlsInfo, + int maxTotalConnections, int maxHostConnections) { + + if(connectionManager != null) { + if( (connectionManager.getMaxTotal() == maxTotalConnections) + && (connectionManager.getDefaultMaxPerRoute() == maxHostConnections) ) { + if(logger.isInfo()) { + logger.info("ConnectionManager REUSE : AdapterName=" + adapterName + + " MaxTotalConnection (" + connectionManager.getMaxTotal() + + ") MaxHostConnections (" + connectionManager.getDefaultMaxPerRoute() + + ")" + ); + } + return; + } + else { + if(logger.isWarn()) { + logger.warn("ConnectionManager RELOAD : AdapterName=" + adapterName + + " MaxTotalConnection (" + connectionManager.getMaxTotal() + " -> " + maxTotalConnections + + ") MaxHostConnections (" + connectionManager.getDefaultMaxPerRoute() + " -> " + maxHostConnections + + ")" + ); + } + connectionManager.close(); + connectionManager = null; + this.client = null; + } + } + if(logger.isWarn()) { + logger.warn("ConnectionManager INIT : AdapterName=" + adapterName + + " MaxTotalConnection (" + maxTotalConnections + + ") MaxHostConnections (" + maxHostConnections + + ")" + ); + } + + PoolingHttpClientConnectionManagerBuilder cmBuilder = PoolingHttpClientConnectionManagerBuilder.create(); + + + + try { + if(logger.isWarn()) { + logger.warn("mTLS Config : AdapterName=" + adapterName + + " useMtls (" + useMtls + ") mtlsInfo - " + mtlsInfo); + } + + SSLContext sslContext = null; + if (useMtls && mtlsInfo != null) { + String storeType = mtlsInfo.getStoreType(); + String keyStoreInfo = mtlsInfo.getKeystoreInfo(); + String keyStorePassword = mtlsInfo.getKeystorePassword(); + String trustStoreInfo = mtlsInfo.getTruststoreInfo(); + String trustStorePassword = mtlsInfo.getTruststorePassword(); + + String[] tlsVersions = null; +// { +// "TLSv1.0" +// , "TLSv1.1" +// , "TLSv1.2" +// , "TLSv1.3" +// }; + String[] cipherSuites = null; +// { +// "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", +// "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", +// "TLS_RSA_WITH_AES_256_CBC_SHA256", +// "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", +// "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", +// "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", +// "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", +// "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", +// "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", +// "TLS_RSA_WITH_AES_256_CBC_SHA", +// "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", +// "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", +// "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", +// "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", +// "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", +// "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", +// "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", +// "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", +// "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", +// "TLS_RSA_WITH_AES_128_CBC_SHA", +// "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", +// "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", +// "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", +// "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", +// "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", +// "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", +// "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", +// "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", +// "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", +// "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", +// "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" +// }; + + if( StringUtils.isAnyEmpty(keyStoreInfo, keyStorePassword) ) { + throw new Exception("mTLS keyStore config error"); + } + + boolean skipTrust = false; + // kbank에서는 trustStore를 사용하지 않음 + if( StringUtils.isAnyEmpty(trustStoreInfo, trustStorePassword) ) { +// throw new Exception("mTLS trustStore config error"); + if(logger.isWarn()) logger.warn("Skip trustStore validation adapterName : " + adapterName); + skipTrust = true; + } + + sslContext = HttpClient5SSLContextFactory.createMTLSContextFromContent( + storeType, + keyStoreInfo, keyStorePassword, + trustStoreInfo, trustStorePassword, skipTrust + ,tlsVersions, cipherSuites); + + // SSLConnectionSocketFactory 생성 +// Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: Certificate for doesn't match common name of the certificate subject: elink +// at org.apache.hc.client5.http.ssl.DefaultHostnameVerifier.matchCN(DefaultHostnameVerifier.java:180) +// at org.apache.hc.client5.http.ssl.DefaultHostnameVerifier.verify(DefaultHostnameVerifier.java:118) +// at org.apache.hc.client5.http.ssl.TlsSessionValidator.verifySession(TlsSessionValidator.java:112) +// => NoopHostnameVerifier.INSTANCE + + SSLConnectionSocketFactory sslSocketFactory = null; + if(testMode) { + // Hostname verifier 비활성화 (테스트용) + sslSocketFactory = new SSLConnectionSocketFactory( + sslContext + , NoopHostnameVerifier.INSTANCE + ); + } + else { + sslSocketFactory = new SSLConnectionSocketFactory( + sslContext + ); + } + cmBuilder.setSSLSocketFactory(sslSocketFactory); + } + else { + sslContext = SSLContextBuilder.create().loadTrustMaterial(new TrustAllStrategy()).build(); + SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); + cmBuilder.setSSLSocketFactory(csf); + } + + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException + | CertificateException | IOException | UnrecoverableKeyException e) { + throw new RuntimeException(e); + } + catch (Exception e) { + throw new RuntimeException(e); + } + this.connectionManager = cmBuilder.build(); + + connectionManager.setMaxTotal(maxTotalConnections); + connectionManager.setDefaultMaxPerRoute(maxHostConnections); + + + HttpRequestInterceptor requestLogInterceptor = (request, entity, context) -> { + try { + String uuid = (String) context.getAttribute(TransactionContextKeys.TRANSACTION_UUID); + String contextAdapterGroupName = (String) context.getAttribute(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME); + String contextAdapterName = (String) context.getAttribute(HttpClientAdapterServiceKey.ADAPTER_NAME); + String url = request.getUri().toString(); + + Integer logProcessNo = (Integer) context.getAttribute(HttpClientAdapterServiceKey.LOG_PROCESS_NO); + if (logProcessNo == null || logProcessNo <= 0) { + logProcessNo = 200; + } + + HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(uuid, logProcessNo, + contextAdapterGroupName, contextAdapterName, request.getHeaders(), url, request.getMethod()); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + }; + + HttpResponseInterceptor responseLogInterceptor = (response, entity, context) -> { + try{ + HttpRequest request = (HttpRequest)context.getAttribute("http.request"); + String url = request.getUri().toString(); + String uuid = (String) context.getAttribute(TransactionContextKeys.TRANSACTION_UUID); + String contextAdapterGroupName = (String) context.getAttribute(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME); + String contextAdapterName = (String) context.getAttribute(HttpClientAdapterServiceKey.ADAPTER_NAME); + Integer logProcessNo = (Integer) context.getAttribute(HttpClientAdapterServiceKey.LOG_PROCESS_NO); + if (logProcessNo == null || logProcessNo <= 0) { + logProcessNo = 300; + }else if(logProcessNo == 400){ + return; + }else{ + logProcessNo += 100; + } + + HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(uuid, logProcessNo, + contextAdapterGroupName, contextAdapterName, response.getHeaders(), url, request.getMethod(), response.getCode()); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + }; + + this.client = HttpClients.custom() + .addRequestInterceptorLast(requestLogInterceptor) + .addResponseInterceptorFirst(responseLogInterceptor) + .setConnectionManager(connectionManager) + .build(); + } + + public int getConnectionsInPool() { + if (this.client == null || this.connectionManager == null) + return 0; + return this.connectionManager.getTotalStats().getAvailable() + this.connectionManager.getTotalStats().getLeased(); + } + + public int getMaxTotalConnections() { + if (this.client == null || this.connectionManager == null) + return 0; + return this.connectionManager.getMaxTotal(); + } + + public int getMaxConnectionsPerHost() { + if (this.client == null || this.connectionManager == null) + return 0; + return this.connectionManager.getDefaultMaxPerRoute(); + } + + public String getResponseCharSet(String httpResponseCharset, String adapterGroupName) { + if (StringUtils.isNotBlank(httpResponseCharset)) { + return httpResponseCharset; + } else { + AdapterManager m = AdapterManager.getInstance(); + AdapterGroupVO agvo = m.getAdapterGroupVO(adapterGroupName); + return agvo.getMessageEncode(); + } + } + + /** + * encoding에 대한 정의 필요 고려할 문제 + * 1. 어댑터그룹이 UJN 타입일경우 return 은 UTF-8 로 getBytes 된 + * 데이터여야됨. + * 2. http response에 받은 encoding 타입은 고려대상임. 결론 : response Encoding 과 + * 어댑터의 MESSAGE_TYPE 다르면 변환, 나머지면 return 어댑터의 ENCODE은 요청전문 encoding에서만 사용 + * + * 예) 어댑터의 ENCODE, 어댑터의 MESSAGE TYPE, RESPNSE ENCODING TYPE, 처리내용 + * 예) ,ECU-KR ,JSN , EUC-KR , 응답받은 메시지를 return 예) ,ECU-KR , JSN , UTF-8 , 응답받은 메시지를 new + * String(xxx,"UTF-8") => getBytes("EUC-KR") 예) ,ECU-KR , UJN , EUC-KR , 응답받은 + * 메시지를 new String(xxx,"EUC-KR") => getBytes("UTF-8") 예) ,ECU-KR , UJN , UTF-8 , + * 응답받은 메시지를 return 예) ,UTF-8 , JSN , EUC-KR , 응답받은 메시지를 return + * 예) ,UTF-8 , JSN , UTF-8 , 응답받은 메시지를 new String(xxx,"UTF-8") => getBytes(EUC-KR") 예) ,UTF-8 , + * UJN , EUC-KR , 응답받은 메시지를 new String(xxx,"EUC-KR") => getBytes("UTF-8") 예) + * ,UTF-8 , UJN , UTF-8 , 응답받은 메시지를 return + * + * + */ + public byte[] getEncodingConvert(String httpResponseCharset, String adapterGroupName, byte[] message) { + byte[] responseMessage = null; + if (StringUtils.isNotBlank(httpResponseCharset)) { + AdapterManager m = AdapterManager.getInstance(); + AdapterGroupVO agvo = m.getAdapterGroupVO(adapterGroupName); + String adapterTypeEncoding = StringUtils.defaultIfBlank(agvo.getMessageEncode(), + Charset.defaultCharset().name()); + Charset responseCharset = null; + Charset adapterCharset = null; + try { + responseCharset = Charset.forName(httpResponseCharset); + adapterCharset = Charset.forName(adapterTypeEncoding); + if (responseCharset.compareTo(adapterCharset) == 0) { + responseMessage = message; + } else {// http 응답 charset 과 어댑터의 charset 이 다를경우 charset 변환 필요 + String encodingString = new String(message, httpResponseCharset); + responseMessage = encodingString.getBytes(adapterTypeEncoding); + } + } catch (UnsupportedCharsetException | UnsupportedEncodingException e) { + responseMessage = message; + } + } else { + responseMessage = message; + } + return responseMessage; + } + + public void configureHttpClient(RequestConfig.Builder requestConfigBuilder, HttpClientAdapterVO vo, HttpUriRequestBase method) { + + if (vo.getConnectionTimeout() != 0) { + requestConfigBuilder.setConnectTimeout(vo.getConnectionTimeout(), TimeUnit.MILLISECONDS); + } + + if (vo.getTimeout() > -1) { + requestConfigBuilder.setResponseTimeout(vo.getTimeout(), TimeUnit.MILLISECONDS); + } + + /* + if (HTTP_VERSION_1_1.equals(vo.getHttpVersion())) { + method.addHeader("Connection", "close"); + } + */ + + org.apache.hc.core5.http.HttpVersion httpVersion ; + if (HTTP_VERSION_1_0.equals(vo.getHttpVersion())) { + httpVersion = org.apache.hc.core5.http.HttpVersion.HTTP_1_0; + } + else if (HTTP_VERSION_2_0.equals(vo.getHttpVersion())) { + httpVersion = org.apache.hc.core5.http.HttpVersion.HTTP_2_0; + } + else { + httpVersion = org.apache.hc.core5.http.HttpVersion.HTTP_1_1; + method.addHeader("Connection", "close"); + } + method.setVersion(httpVersion); + + RequestConfig requestConfig = requestConfigBuilder + .setConnectTimeout(vo.getConnectionTimeout(), TimeUnit.MILLISECONDS) // 연결 시간 초과를 5초로 설정 + .setResponseTimeout(vo.getTimeout(), TimeUnit.MILLISECONDS) // 응답 시간 초과를 5초로 설정 + .build(); + + method.setConfig(requestConfig); + } + + public abstract Object execute(Properties prop, Object message, Properties tempProp) throws Exception; +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterListener.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterListener.java new file mode 100644 index 0000000..99593b0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterListener.java @@ -0,0 +1,55 @@ +package com.eactive.eai.adapter.http.client; + +import java.util.Properties; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.http.dynamic.HttpLoggerManager; +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListenerSupport; +import com.eactive.eai.common.util.Logger; + +public class HttpClientAdapterListener extends AdapterListenerSupport { + final static Logger logger2 = HttpLoggerManager.getInstance().getLogger(); + final static Logger errLogger = HttpLoggerManager.getInstance().getErrLogger(); + + public void start() throws AdapterException { + + try { + if (info == null) { + throw new Exception("HttpClientAdapterListener | AdapterVO가 NULL입니다."); + } + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties outboundProp = manager.getProperties(info.getPropGroupName()); + String adapterGroupName = info.getAdapterGroupName(); + String adapterName = info.getName(); + String httpType = outboundProp.getProperty(HttpClientAdapterServiceKey.HTTP_TYPE); + HttpClientAdapterServiceFactory.createFactory(httpType, adapterGroupName, adapterName); + if(logger2.isInfo()) { + logger2.info("[HttpClientAdapterListener] AdapterName [" + info.getAdapterGroupName() + "." + info.getName() + + "] httpType [" + httpType + "] start"); + } + info.setStatus(true); + } catch (Exception e) { + logger.error(info.getName() + " | HttpClientAdapterListener | cannot start : " + e.getMessage(), e); + throw new AdapterException(info.getName() + " | HttpClientAdapterListener | cannot start - " + e.getMessage()); + } + } + + public void stop() throws AdapterException { + try { + if (info == null) { + throw new Exception("HttpClientAdapterListener | AdapterVO가 NULL입니다."); + } + String adapterName = info.getName(); + HttpClientAdapterServiceFactory.removeFactory(adapterName); + if(logger2.isInfo()) { + logger2.info("[HttpClientAdapterListener] AdapterName [" + info.getAdapterGroupName() + "." + info.getName() + + "] adapter info [" + info + "] stop"); + } + info.setStatus(false); + } catch (Exception e) { + logger.error(info.getName() + " | HttpClientAdapterListener | cannot stop : " + e.getMessage(), e); + throw new AdapterException(info.getName() + " | HttpClientAdapterListener | cannot stop - " + e.getMessage()); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterMain.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterMain.java new file mode 100644 index 0000000..5189c54 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterMain.java @@ -0,0 +1,22 @@ + +package com.eactive.eai.adapter.http.client; + +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkDefaultAdapter; +import com.eactive.eai.common.util.Logger; + +public class HttpClientAdapterMain extends ElinkDefaultAdapter { + private static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public Object execute(Properties prop, Object message, Properties tempProp) throws Exception { + String httpType = prop.getProperty(HttpClientAdapterServiceKey.HTTP_TYPE); // Http Type에 대한 class name + String adapterGroupName = tempProp.getProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_GROUP_NAME); + String adapterName = tempProp.getProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_NAME); + HttpClientAdapterService service = HttpClientAdapterServiceFactory.createFactory(httpType, adapterGroupName, adapterName); + if (service == null) { + throw new Exception("Can not create HttpClientAdapterService httpType=" + httpType +" adapterName="+adapterName); + } + return service.execute(prop, message, tempProp); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterService.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterService.java new file mode 100644 index 0000000..ed5b2ef --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterService.java @@ -0,0 +1,14 @@ + +package com.eactive.eai.adapter.http.client; + +import java.util.Properties; + +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; + +public interface HttpClientAdapterService { + public Object execute(Properties prop, Object message, Properties tempProp) throws Exception; + public void close(); + public void init(String adapterName, + boolean useMtls, HttpOutTlsInfoVO mtlsInfo, + int maxTotalConnections, int maxHostConnections); +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceFactory.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceFactory.java new file mode 100644 index 0000000..c8d4f5f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceFactory.java @@ -0,0 +1,119 @@ +package com.eactive.eai.adapter.http.client; + +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; + +public class HttpClientAdapterServiceFactory { + private static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + private static ConcurrentHashMap adapters = new ConcurrentHashMap<>(); + private static ConcurrentHashMap adapterClass = new ConcurrentHashMap<>(); + + private HttpClientAdapterServiceFactory() { + super(); + } + + public static HttpClientAdapterService createFactory(String className, String adapterGroupName, String adapterName) throws Exception { + HttpClientAdapterService service = null; + if (adapters.containsKey(adapterName)) { + service = adapters.get(adapterName); + if (className.equals(adapterClass.get(adapterName))) { + return service; + } + else { + service.close(); + service = null; + } + } + + try { + Class cl = Class.forName(className); + service = (HttpClientAdapterService) cl.newInstance(); + + boolean useMtls = false; + + int maxTotalConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_TOTAL_CONNECTIONS; + int maxHostConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_CONNECTION_PER_HOST; + AdapterVO adapterVo = AdapterManager.getInstance().getAdapterVO(adapterGroupName, adapterName); + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties outboundProp = manager.getProperties(adapterVo.getPropGroupName()); + + try { + maxTotalConnections = Integer.parseInt(outboundProp.getProperty(HttpClientAdapterServiceKey.MAX_TOTAL_CONNECTIONS)); + } + catch(NumberFormatException ex) { + maxTotalConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_TOTAL_CONNECTIONS; + if(logger.isWarn()) { + logger.warn("HttpClientAdapterService. : {}, adatperName : {} UseDefault {}={}, {}" + , className, adapterName,HttpClientAdapterServiceKey.MAX_TOTAL_CONNECTIONS, maxTotalConnections, ex.toString()); + } + } + + try { + maxHostConnections = Integer.parseInt(outboundProp.getProperty(HttpClientAdapterServiceKey.MAX_CONNECTION_PER_HOST)); + } + catch(NumberFormatException ex) { + maxHostConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_CONNECTION_PER_HOST; + if(logger.isWarn()) { + logger.warn("HttpClientAdapterService. : {}, adatperName : {} UseDefault {}={}, {}" + , className, adapterName,HttpClientAdapterServiceKey.MAX_CONNECTION_PER_HOST, maxHostConnections, ex.toString()); + } + } + + // clientID -> mTLS 인증정보 획득 + useMtls = StringUtils.equalsIgnoreCase(outboundProp.getProperty(HttpClientAdapterServiceKey.USE_MTLS),"Y"); + + AdapterGroupVO adapterGroup = AdapterManager.getInstance().getAdapterGroup(adapterGroupName); + // outboundProp.getProperty(HttpClientAdapterServiceKey.CLIENT_ID); + String clientId = adapterGroup.getClientId(); + + if(logger.isInfo()) { + logger.info("MTLS adapterName. : {}, useMtls. : {}, clientId : {}", adapterName, useMtls, clientId); + } + HttpOutTlsInfoVO mtlsInfo = null; + if(useMtls) { + HttpOutTlsInfoManager tlsManager = HttpOutTlsInfoManager.getInstance(); + if(StringUtils.isNotEmpty(clientId)) { + mtlsInfo = tlsManager.getHttpOutTlsInfo(clientId); + } + } +// keyStorePath = outboundProp.getProperty(HttpClientAdapterServiceKey.KEYSTORE_PATH); +// keyStorePassword = outboundProp.getProperty(HttpClientAdapterServiceKey.KEYSTORE_PWD); +// trustStorePath = outboundProp.getProperty(HttpClientAdapterServiceKey.TRUSTSTORE_PATH); +// trustStorePassword = outboundProp.getProperty(HttpClientAdapterServiceKey.TRUSTSTORE_PWD); + + service.init(adapterName, + useMtls, mtlsInfo, + maxTotalConnections, maxHostConnections); + + if (service != null) { + adapters.put(adapterName, service); + adapterClass.put(adapterName, className); + } + } catch (Exception e) { + logger.error("Cannot create a HttpClientAdapterService. : {}, adatperName : {}", className, adapterName, e); + throw e; + } + return service; + } + + public static void removeFactory(String adapterName) { + String className = null; + if (adapters.containsKey(adapterName)) { + adapters.remove(adapterName); + className = adapterClass.remove(adapterName); + if(logger.isWarn()) { + logger.warn("Remove HttpClientAdapterService. : {}, adatperName : {}", className, adapterName); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java new file mode 100644 index 0000000..0238cbc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceKey.java @@ -0,0 +1,90 @@ + +package com.eactive.eai.adapter.http.client; + +public interface HttpClientAdapterServiceKey { + + public static final String ADAPTER_GROUP_NAME = "ADAPTER_GROUP_NAME"; + public static final String ADAPTER_NAME = "ADAPTER_NAME"; + + public static final String HTTP_TYPE = "HTTP_TYPE"; + public static final String URL = "URL"; + public static final String URL_2GRP = "URL_2GRP"; + + public static final String METHOD = "METHOD"; + public static final String PARAMETER_NAME = "PARAMETER_NAME"; + + public static final String TRAN_CODE = "TRAN_CODE"; + public static final String LOCAL_CALL = "LOCAL_CALL"; + public static final String LOCAL_CALL_Y = "Y"; + public static final String LOG_PROCESS_NO = "LOG_PROCESS_NO"; + public static final String LOCAL_IP = "LOCAL_IP"; + + public static final String ENCODE = "ENCODE"; + + public static final String CONTENT_TYPE = "CONTENT_TYPE"; + public static final String CONTENT_TYPE_KEY = "Content-Type"; + + public static final String METHOD_GET = "GET"; + public static final String METHOD_POST = "POST"; + + public static final String RESPONSE_TYPE = "RESPONSE_TYPE"; + public static final String RESPONSE_TYPE_SYNC = "SYNC"; + public static final String RESPONSE_TYPE_ASYNC = "ASYN"; + + public static final String METHOD_SOAP = "SOAP"; + public static final String METHOD_SOAP_ACTION = "SOAPAction"; + + public static final String REST_OPTION = "REST_OPTION"; + public static final String TOUTVAL = "TOUTVAL"; + + public static final String CONNECTION_STALE_CHECKING_ENABLED = "CONNECTION_STALE_CHECKING_ENABLED"; + + // 호스트 마다 최대 연결 수 + public static final int DEFAULT_MAX_CONNECTION_PER_HOST = 10; + public static final String MAX_CONNECTION_PER_HOST = "MAX_CONNECTION_PER_HOST"; + // 최대 HTTP 연결 수 + public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 100; + public static final String MAX_TOTAL_CONNECTIONS = "MAX_TOTAL_CONNECTIONS"; + + static final String PARAMETER_MESSAGE = "_message_"; + + static final String URL_ENCODE_YN = "URL_ENCODE_YN"; + + static final String CONNECTION_TIMEOUT = "CONNECTION_TIMEOUT"; + static final String ADAPTER_HEADER = "ADAPTER_HEADER"; + + public static final String HTTP_TIME_OUT = "HTTP_TIME_OUT"; + public static final int DEFAULT_TIME_OUT = 30 * 1000; + + public static final String TESTCALL_URL = "TESTCALL_URL"; + public static final String TESTCALL_YN = "TESTCALL_YN"; + public static final String TRACE_LEVEL = "TRACE_LEVEL"; + + public static final String HEALTHCHECK_URL = "HEALTHCHECK_URL"; + public static final String HEALTHCHECK_TIMEOUTMS = "HEALTHCHECK_TIMEOUTMS"; + + public static final String INBOUND_METHOD = "INBOUND_METHOD"; + public static final String INBOUND_URI = "INBOUND_URI"; + public static final String INBOUND_EXTURI = "INBOUND_EXTURI"; + public static final String INBOUND_HEADER = "INBOUND_HEADER"; + + public static final String HTTP_VERSION = "HTTP_VERSION"; + public static final String HTTP_VERSION_1_0 = "1.0"; + public static final String HTTP_VERSION_1_1 = "1.1"; + public static final String HTTP_VERSION_2_0 = "2.0"; + + public static final String HTTP_VERSION_FULL_1_1 = "HTTP_1_1"; + public static final String HTTP_VERSION_FULL_1_0 = "HTTP_1_0"; + + public static final String USE_MTLS = "USE_MTLS"; + public static final String CLIENT_ID = "CLIENT_ID"; + public static final String KEYSTORE_PATH = "KEYSTORE_PATH"; + public static final String KEYSTORE_PWD = "KEYSTORE_PWD"; + public static final String TRUSTSTORE_PATH = "TRUSTSTORE_PATH"; + public static final String TRUSTSTORE_PWD = "TRUSTSTORE_PWD"; + + public static final String TRANSACTION_ID = "transactionId"; + public static final String INSTANCE_ID = "instanceId"; + + public static final String TRANSACTION_SVC_PATTERN ="TRANSACTION_SVC_PATTERN";//(SYNC/ASYN)-(SYNC/ASYN) +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java new file mode 100644 index 0000000..941a92b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceSupport.java @@ -0,0 +1,439 @@ + +package com.eactive.eai.adapter.http.client; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.nio.charset.UnsupportedCharsetException; +import java.util.HashMap; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.net.ssl.SSLContext; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpMethodBase; +import org.apache.commons.httpclient.HttpVersion; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +import com.eactive.eai.adapter.http.secure.CustomSSLProtocolSocketFactory; +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.adapter.http.secure.SSLContextFactory; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; + +public abstract class HttpClientAdapterServiceSupport implements HttpClientAdapterService, HttpClientAdapterServiceKey { + protected static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + protected HttpClient client; + private MultiThreadedHttpConnectionManager connectionManager; + + public synchronized void close() { + if (connectionManager != null) { + connectionManager.shutdown(); + } + } + + protected HttpClientAdapterVO setting(Properties prop, Properties tempProp) { + String url = null; + String parameterName = null; + String method = null; + String contentType = null; + String encode = null; + String testCallYn = null; + String adapterGroupName = null; + String adapterName = null; + String responseType = null; + String urlEncodeYn = null; + String adapterHeader = null; + + boolean useMtls = false; + String keyStorePath = null; + String keyStorePassword = null; + String trustStorePath = null; + String trustStorePassword = null; + + int connectionTimeout = 0; + int timeout = -1; + int traceLevel = 0; + long slowTranTime = 2000L; + + url = prop.getProperty(URL); + + String url2grp = tempProp.getProperty(URL); + if (!StringUtils.isEmpty(url2grp)) { + url = url2grp; + } + method = prop.getProperty(METHOD); + parameterName = prop.getProperty(PARAMETER_NAME, PARAMETER_MESSAGE); + contentType = prop.getProperty(CONTENT_TYPE, ""); + responseType = prop.getProperty(RESPONSE_TYPE, "SYNC"); + urlEncodeYn = prop.getProperty(URL_ENCODE_YN, "N"); + String connectionTimeoutTemp = prop.getProperty(CONNECTION_TIMEOUT, "0"); + + String httpVersion = prop.getProperty(HTTP_VERSION); + adapterHeader = prop.getProperty(ADAPTER_HEADER, ""); + + String traceLevelTemp = prop.getProperty(TRACE_LEVEL, "0"); + String timeoutTemp = prop.getProperty(HTTP_TIME_OUT); + + useMtls = StringUtils.equalsIgnoreCase(prop.getProperty(HttpClientAdapterServiceKey.USE_MTLS), "Y"); + keyStorePath = prop.getProperty(HttpClientAdapterServiceKey.KEYSTORE_PATH); + keyStorePassword = prop.getProperty(HttpClientAdapterServiceKey.KEYSTORE_PWD); + trustStorePath = prop.getProperty(HttpClientAdapterServiceKey.TRUSTSTORE_PATH); + trustStorePassword = prop.getProperty(HttpClientAdapterServiceKey.TRUSTSTORE_PWD); + + encode = tempProp.getProperty(Keys.CHARSET_KEY_OUT, Charset.defaultCharset().name()); + testCallYn = tempProp.getProperty(TESTCALL_YN, "N"); + adapterGroupName = tempProp.getProperty(ADAPTER_GROUP_NAME); + adapterName = tempProp.getProperty(ADAPTER_NAME); + // 인터페이스 정보에 설정된 타임아웃 + String interfaceTimeout = tempProp.getProperty("INTERFACE_TIME_OUT"); + if (StringUtils.isNotBlank(interfaceTimeout) && NumberUtils.toInt(interfaceTimeout) > 0) { + timeoutTemp = interfaceTimeout; + } + + url = StringUtils.trim(url); + parameterName = StringUtils.trim(parameterName); + method = StringUtils.trim(method); + encode = StringUtils.trim(encode); + contentType = StringUtils.trim(contentType); + + if (timeoutTemp == null) { + timeoutTemp = "0"; + } else { + timeoutTemp = timeoutTemp.trim(); + } + + try { + connectionTimeout = Integer.parseInt(connectionTimeoutTemp); + } catch (Exception e) { + logger.debug("HttpClientAdapterSupport] connectionTimeoutTemp not int"); + } + try { + timeout = Integer.parseInt(timeoutTemp); + } catch (NumberFormatException e) { + logger.warn("HttpClientAdapterSupport] timeoutTemp not int", e); + } + + try { + traceLevel = Integer.parseInt(traceLevelTemp); + } catch (Exception e) { + logger.warn("HttpClientAdapterSupport] traceLevelTemp not int", e); + } + + // client 중 BODY,POST,GET,NexCore 방식만 적용 + HashMap adapterHeaders = new HashMap<>(); + try { + Matcher matcher = Pattern.compile( + "\\{[ ]*\"[ ]*([a-zA-Z0-9_-]+)[ ]*\"[ ]*,[ ]*\"[ ]*([a-zA-Z0-9/;,\\*=_ -]+)[ ]*\"[ ]*\\}[ ]*") + .matcher(adapterHeader.trim()); + while (matcher.find()) { + String key = matcher.group(1).trim(); + String value = matcher.group(2).trim(); + adapterHeaders.put(key, value); + } + } catch (Exception e) { + if (logger.isDebug()) + logger.debug("HttpClientAdapterSupport] adapter header parsing error " + adapterHeader); + } + // GW 전달 로직 추가 + // tempProp로 넘겨서 하는 이유는 outboundProp가 clone 안하는 로직이라 outboundProp로 넘길시 문제의 소지가있음 + String transactionId = tempProp.getProperty(HttpClientAdapterServiceKey.TRANSACTION_ID); + String instanceId = tempProp.getProperty(HttpClientAdapterServiceKey.INSTANCE_ID); + if (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(instanceId)) { + adapterHeaders.put(HttpClientAdapterServiceKey.TRANSACTION_ID, transactionId); + adapterHeaders.put(HttpClientAdapterServiceKey.INSTANCE_ID, instanceId); + } + + HttpClientAdapterVO vo = new HttpClientAdapterVO(); + vo.setUrl(url); + vo.setMethod(method); + vo.setParameterName(parameterName); + vo.setEncode(encode); + vo.setContentType(contentType); + vo.setTestCallYn(testCallYn); + vo.setResponseType(responseType); + vo.setUrlEncodeYn(urlEncodeYn); + vo.setAdapterGroupName(adapterGroupName); + vo.setAdapterName(adapterName); + + vo.setMaxTotalConnections(getMaxTotalConnections()); + vo.setMaxHostConnections(getMaxConnectionsPerHost()); + vo.setConnectionTimeout(connectionTimeout); + + vo.setTimeout(timeout); + vo.setTraceLevel(traceLevel); + vo.setSlowTranTime(slowTranTime); + vo.setAdapterHeaders(adapterHeaders); + if (StringUtils.equalsAny(httpVersion, HTTP_VERSION_FULL_1_1, HTTP_VERSION_1_1)) { + vo.setHttpVersion(HTTP_VERSION_1_1); + } else { + vo.setHttpVersion(HTTP_VERSION_1_0); + } + vo.setUseMtls(useMtls); + vo.setKeyStorePath(keyStorePath); + vo.setKeyStorePassword(keyStorePassword); + vo.setTrustStorePath(trustStorePath); + vo.setTrustStorePassword(trustStorePassword); + + if (logger.isDebug()) { + logger.debug(vo.toString()); + } + return vo; + } + + protected HttpClientAdapterServiceSupport() { + + } + + public synchronized void init(String adapterName, boolean useMtls, HttpOutTlsInfoVO mtlsInfo, + int maxTotalConnections, int maxHostConnections) { + if (connectionManager != null) { + if ((connectionManager.getParams().getMaxTotalConnections() == maxTotalConnections) + && (connectionManager.getParams().getDefaultMaxConnectionsPerHost() == maxHostConnections)) { + if (logger.isInfo()) { + logger.info("ConnectionManager REUSE : AdapterName=" + adapterName + " MaxTotalConnection (" + + connectionManager.getParams().getMaxTotalConnections() + ") MaxHostConnections (" + + connectionManager.getParams().getDefaultMaxConnectionsPerHost() + ")"); + } + return; + } else { + if (logger.isWarn()) { + logger.warn("ConnectionManager RELOAD : AdapterName=" + adapterName + " MaxTotalConnection (" + + connectionManager.getParams().getMaxTotalConnections() + " -> " + maxTotalConnections + + ") MaxHostConnections (" + connectionManager.getParams().getDefaultMaxConnectionsPerHost() + + " -> " + maxHostConnections + ")"); + } + connectionManager.shutdown(); + connectionManager = null; + this.client = null; + } + } + + if (logger.isWarn()) { + logger.warn("ConnectionManager INIT : AdapterName=" + adapterName + " MaxTotalConnection (" + + maxTotalConnections + ") MaxHostConnections (" + maxHostConnections + ")"); + } + connectionManager = new MultiThreadedHttpConnectionManager(); + connectionManager.getParams().setStaleCheckingEnabled(true); + connectionManager.getParams().setMaxTotalConnections(maxTotalConnections); + connectionManager.getParams().setDefaultMaxConnectionsPerHost(maxHostConnections); + + this.client = new HttpClient(connectionManager); + } + + public int getConnectionsInPool() { + if (this.client == null) + return 0; + MultiThreadedHttpConnectionManager mgr = (MultiThreadedHttpConnectionManager) this.client + .getHttpConnectionManager(); + return mgr.getConnectionsInPool(); + } + + public int getMaxTotalConnections() { + if (this.client == null) + return 0; + MultiThreadedHttpConnectionManager mgr = (MultiThreadedHttpConnectionManager) this.client + .getHttpConnectionManager(); + return mgr.getParams().getMaxTotalConnections(); + } + + public int getMaxConnectionsPerHost() { + if (this.client == null) + return 0; + MultiThreadedHttpConnectionManager mgr = (MultiThreadedHttpConnectionManager) this.client + .getHttpConnectionManager(); + return mgr.getParams().getDefaultMaxConnectionsPerHost(); + } + + public String getResponseCharSet(String httpResponseCharset, String adapterGroupName) { + if (StringUtils.isNotBlank(httpResponseCharset)) { + return httpResponseCharset; + } else { + AdapterManager m = AdapterManager.getInstance(); + AdapterGroupVO agvo = m.getAdapterGroupVO(adapterGroupName); + return agvo.getMessageEncode(); + } + } + + /** + * encoding에 대한 정의 필요 고려할 문제 1. 어댑터그룹이 UJN 타입일경우 return 은 UTF-8 로 getBytes 된 + * 데이터여야됨. 2. http response에 받은 encoding 타입은 고려대상임. 결론 : response Encoding 과 + * 어댑터의 MESSAGE_TYPE 다르면 변환, 나머지면 return 어댑터의 ENCODE은 요청전문 encoding에서만 사용 + * + * 예) 어댑터의 ENCODE, 어댑터의 MESSAGE TYPE, RESPNSE ENCODING TYPE, 처리내용 예) ,ECU-KR + * ,JSN , EUC-KR , 응답받은 메시지를 return 예) ,ECU-KR , JSN , UTF-8 , 응답받은 메시지를 new + * String(xxx,"UTF-8") => getBytes("EUC-KR") 예) ,ECU-KR , UJN , EUC-KR , 응답받은 + * 메시지를 new String(xxx,"EUC-KR") => getBytes("UTF-8") 예) ,ECU-KR , UJN , UTF-8 , + * 응답받은 메시지를 return 예) ,UTF-8 , JSN , EUC-KR , 응답받은 메시지를 return 예) ,UTF-8 , JSN + * , UTF-8 , 응답받은 메시지를 new String(xxx,"UTF-8") => getBytes(EUC-KR") 예) ,UTF-8 , + * UJN , EUC-KR , 응답받은 메시지를 new String(xxx,"EUC-KR") => getBytes("UTF-8") 예) + * ,UTF-8 , UJN , UTF-8 , 응답받은 메시지를 return + * + * + */ + public byte[] getEncodingConvert(String httpResponseCharset, String adapterGroupName, byte[] message) { + byte[] responseMessage = null; + if (StringUtils.isNotBlank(httpResponseCharset)) { + AdapterManager m = AdapterManager.getInstance(); + AdapterGroupVO agvo = m.getAdapterGroupVO(adapterGroupName); + String adapterTypeEncoding = StringUtils.defaultIfBlank(agvo.getMessageEncode(), + Charset.defaultCharset().name()); + Charset responseCharset = null; + Charset adapterCharset = null; + try { + responseCharset = Charset.forName(httpResponseCharset); + adapterCharset = Charset.forName(adapterTypeEncoding); + if (responseCharset.compareTo(adapterCharset) == 0) { + responseMessage = message; + } else {// http 응답 charset 과 어댑터의 charset 이 다를경우 charset 변환 필요 + String encodingString = new String(message, httpResponseCharset); + responseMessage = encodingString.getBytes(adapterTypeEncoding); + } + } catch (UnsupportedCharsetException | UnsupportedEncodingException e) { + responseMessage = message; + } + } else { + responseMessage = message; + } + return responseMessage; + } + + @SuppressWarnings("deprecation") + public void configureHttpClient(HttpClient mclient, HttpMethodBase method, HttpClientAdapterVO vo, String url, + String contentType) throws Exception { + if (StringUtils.isNotBlank(vo.getEncode())) { + mclient.getParams().setContentCharset(vo.getEncode()); + } + + if (vo.getConnectionTimeout() != 0) { + mclient.getHttpConnectionManager().getParams().setConnectionTimeout(vo.getConnectionTimeout()); + } + + if (vo.getTimeout() > -1) { + mclient.getHttpConnectionManager().getParams().setSoTimeout(vo.getTimeout()); + } + + if (HTTP_VERSION_1_1.equals(vo.getHttpVersion())) { + method.setRequestHeader("Connection", "close"); + method.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_1); + } else { + method.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_0); + } + + method.setFollowRedirects(false); + + if (StringUtils.startsWith(url, "https")) { + if (vo.isUseMtls()) { + HttpOutTlsInfoManager tlsManager = HttpOutTlsInfoManager.getInstance(); + String clientId = vo.getClientId(); + HttpOutTlsInfoVO mtlsInfo = tlsManager.getHttpOutTlsInfo(clientId); + String storeType = mtlsInfo.getStoreType(); + String keyStoreInfo = mtlsInfo.getKeystoreInfo(); + String keyStorePassword = mtlsInfo.getKeystorePassword(); + String trustStoreInfo = mtlsInfo.getTruststoreInfo(); + String trustStorePassword = mtlsInfo.getTruststorePassword(); + + // Server negotiation 에 의해 변경될 수 있음 + String[] tlsVersions = null; +// { +// "TLSv1.0" +// , "TLSv1.1" +// , "TLSv1.2" +// , "TLSv1.3" +// }; + String[] cipherSuites = null; +// { +// "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", +// "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", +// "TLS_RSA_WITH_AES_256_CBC_SHA256", +// "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", +// "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", +// "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", +// "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", +// "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", +// "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", +// "TLS_RSA_WITH_AES_256_CBC_SHA", +// "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", +// "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", +// "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", +// "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", +// "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", +// "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", +// "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", +// "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", +// "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", +// "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", +// "TLS_RSA_WITH_AES_128_CBC_SHA", +// "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", +// "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", +// "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", +// "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", +// "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", +// "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", +// "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", +// "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", +// "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", +// "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", +// "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", +// "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", +// "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" +// }; + + if (StringUtils.isAnyEmpty(keyStoreInfo, keyStorePassword)) { + throw new Exception("mTLS keyStore config error"); + } + + boolean skipTrust = false; + // kbank에서는 trustStore를 사용하지 않음 + if (StringUtils.isAnyEmpty(trustStoreInfo, trustStorePassword)) { +// throw new Exception("mTLS trustStore config error"); + if (logger.isWarn()) + logger.warn("Skip trustStore validation adapterName : " + vo.getAdapterName()); + skipTrust = true; + } + + SSLContext sslContext = SSLContextFactory.createMTLSContextFromContent(storeType, keyStoreInfo, + keyStorePassword, trustStoreInfo, trustStorePassword, skipTrust, tlsVersions, cipherSuites); + // SSLProtocolSocketFactory 생성 + ProtocolSocketFactory socketFactory = new CustomSSLProtocolSocketFactory(sslContext); + Protocol.registerProtocol("https", new Protocol("https", socketFactory, 443)); + } else { + Protocol.registerProtocol("https", + new Protocol("https", new CustomHttpsSocketFactory(new EasySSLProtocolSocketFactory()), 443)); + } + } + + if (StringUtils.equalsIgnoreCase(method.getName(), "POST") + || StringUtils.equalsIgnoreCase(method.getName(), "PUT")) { + if (StringUtils.isNotBlank(contentType)) { + if (StringUtils.isBlank(vo.getEncode())) { + method.setRequestHeader("Content-Type", contentType); + } else { + method.setRequestHeader("Content-Type", + String.format("%s; charset=%s", contentType, vo.getEncode())); + } + } + } + } + + public abstract Object execute(Properties prop, Object message, Properties tempProp) throws Exception; +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceType.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceType.java new file mode 100644 index 0000000..2112740 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterServiceType.java @@ -0,0 +1,16 @@ +package com.eactive.eai.adapter.http.client; + +public enum HttpClientAdapterServiceType { + STANDARD, + EXTORG, + QUICS, + REST, + UNKNOWN; + public static HttpClientAdapterServiceType getValue(String value) { + try { + return valueOf(value.toUpperCase()); + } catch (Exception e) { + return UNKNOWN; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterVO.java b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterVO.java new file mode 100644 index 0000000..d1be29c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/HttpClientAdapterVO.java @@ -0,0 +1,268 @@ + +package com.eactive.eai.adapter.http.client; + +import java.util.HashMap; + +public class HttpClientAdapterVO { + protected String url = null; + protected String parameterName = null; + protected String method = null; + + protected String contentType = null; + + protected String encode = null; + protected String testCallYn = null; + + protected String adapterGroupName = null; + protected String adapterName = null; + protected String responseType = null; + protected String urlEncodeYn = null; + + protected int connectionTimeout = 0; + protected int maxTotalConnections = 50; + protected int maxHostConnections = 10; + protected int timeout = -1; + protected int traceLevel = 0; + + protected long slowTranTime = 2000L; + + protected String httpVersion = null; + + // client header 값 추가 + protected HashMap adapterHeaders = null; + + // mTLS + boolean useMtls = false; + String clientId = null; + String keyStorePath = null; + String keyStorePassword = null; + String trustStorePath = null; + String trustStorePassword = null; + + public int getMaxTotalConnections() { + return maxTotalConnections; + } + + public void setMaxTotalConnections(int maxTotalConnections) { + this.maxTotalConnections = maxTotalConnections; + } + + public int getMaxHostConnections() { + return maxHostConnections; + } + + public void setMaxHostConnections(int maxHostConnections) { + this.maxHostConnections = maxHostConnections; + } + + public String getHttpVersion() { + return httpVersion; + } + + public void setHttpVersion(String httpVersion) { + this.httpVersion = httpVersion; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getParameterName() { + return parameterName; + } + + public void setParameterName(String parameterName) { + this.parameterName = parameterName; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getEncode() { + return encode; + } + + public void setEncode(String encode) { + this.encode = encode; + } + + public String getTestCallYn() { + return testCallYn; + } + + public void setTestCallYn(String testCallYn) { + this.testCallYn = testCallYn; + } + + public String getAdapterGroupName() { + return adapterGroupName; + } + + public void setAdapterGroupName(String adapterGroupName) { + this.adapterGroupName = adapterGroupName; + } + + public String getAdapterName() { + return adapterName; + } + + public void setAdapterName(String adapterName) { + this.adapterName = adapterName; + } + + public String getResponseType() { + return responseType; + } + + public void setResponseType(String responseType) { + this.responseType = responseType; + } + + public String getUrlEncodeYn() { + return urlEncodeYn; + } + + public void setUrlEncodeYn(String urlEncodeYn) { + this.urlEncodeYn = urlEncodeYn; + } + + public int getConnectionTimeout() { + return connectionTimeout; + } + + public void setConnectionTimeout(int connectionTimeout) { + this.connectionTimeout = connectionTimeout; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public int getTraceLevel() { + return traceLevel; + } + + public void setTraceLevel(int traceLevel) { + this.traceLevel = traceLevel; + } + + public long getSlowTranTime() { + return slowTranTime; + } + + public void setSlowTranTime(long slowTranTime) { + this.slowTranTime = slowTranTime; + } + + public HashMap getAdapterHeaders() { + return adapterHeaders; + } + + public void setAdapterHeaders(HashMap adapterHeaders) { + this.adapterHeaders = adapterHeaders; + } + + + public boolean isUseMtls() { + return useMtls; + } + + public void setUseMtls(boolean useMtls) { + this.useMtls = useMtls; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getKeyStorePath() { + return keyStorePath; + } + + public void setKeyStorePath(String keyStorePath) { + this.keyStorePath = keyStorePath; + } + + public String getKeyStorePassword() { + return keyStorePassword; + } + + public void setKeyStorePassword(String keyStorePassword) { + this.keyStorePassword = keyStorePassword; + } + + public String getTrustStorePath() { + return trustStorePath; + } + + public void setTrustStorePath(String trustStorePath) { + this.trustStorePath = trustStorePath; + } + + public String getTrustStorePassword() { + return trustStorePassword; + } + + public void setTrustStorePassword(String trustStorePassword) { + this.trustStorePassword = trustStorePassword; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("HttpClientAdapterVO [adapterGroupName=" + adapterGroupName + ", adapterGroupName=" + adapterGroupName + ", responseType=" + responseType ); + sb.append("\n"); + sb.append("url=" + url + ", parameterName=" + parameterName + ", method=" + method ); + sb.append("\n"); + sb.append(", contentType=" + contentType + ", encode=" + encode + ", testCallYn=" + testCallYn ); + sb.append("\n"); + sb.append(", urlEncodeYn=" + urlEncodeYn + ", connectionTimeout=" + connectionTimeout ); + sb.append("\n"); + sb.append(", maxTotalConnections=" + maxTotalConnections + ", maxHostConnections=" + maxHostConnections ); + sb.append("\n"); + sb.append(", timeout=" + timeout + ", traceLevel=" + traceLevel + ", slowTranTime=" + slowTranTime ); + sb.append("\n"); + sb.append(", httpVersion=" + httpVersion + "]" ); + if(adapterHeaders != null) { + sb.append("\nadapter header [\n"); + for (String key : adapterHeaders.keySet()) { + sb.append(key).append("=").append(adapterHeaders.get(key)); + sb.append("\n"); + } + sb.append("\n]"); + } + sb.append("\n"); + sb.append(", useMtls=" + useMtls + ", clientId=" + clientId); + sb.append(", keyStorePath=" + keyStorePath + ", keyStorePassword=" + keyStorePassword ); + sb.append(", trustStorePath=" + trustStorePath + ", trustStorePassword=" + trustStorePassword ); + return sb.toString(); + + } + + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceBody.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceBody.java new file mode 100644 index 0000000..5bfc866 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceBody.java @@ -0,0 +1,206 @@ +package com.eactive.eai.adapter.http.client.impl; + +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.client.HttpClient5AdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.util.CommonLib; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.apache.hc.core5.http.protocol.BasicHttpContext; +import org.apache.hc.core5.http.protocol.HttpContext; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; + +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.Properties; + +public class HttpClient5AdapterServiceBody extends HttpClient5AdapterServiceSupport { + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + + boolean isAsync = false; + if (RESPONSE_TYPE_ASYNC.equals(vo.getResponseType())) { + isAsync = true; + } + + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + + boolean useForwardProxy = StringUtils.equalsIgnoreCase(prop.getProperty("FORWARD_PROXY_USE_YN", "N"), "Y"); + String forwardProxyUrl = prop.getProperty("FORWARD_PROXY_URL"); + + if(useForwardProxy) { + java.net.URL url = new java.net.URL(forwardProxyUrl); + + // 프로토콜, 호스트, 포트 추출 + String protocol = url.getProtocol(); + String host = url.getHost(); + int port = url.getPort(); + HttpHost proxy = new HttpHost(protocol,host, port); + requestConfigBuilder.setProxy(proxy); + } + + String sendData = ""; + if (data instanceof String) { + sendData = (String) data; + } else if (data instanceof byte[]) { + sendData = new String((byte[]) data, vo.getEncode()); + } + + ObjectMapper mapper = new ObjectMapper(); + ObjectNode jsonNode = (ObjectNode) mapper.readTree(sendData); + ObjectNode headerPart = (ObjectNode) jsonNode.get("header_part"); + + if( headerPart.get("mciIntfId") != null && headerPart.get("mciIntfId").asText().trim().length() > 0 ) { + headerPart.put("eaiIntfId", ""); + sendData = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode); + } + + if ("Y".equals(vo.getUrlEncodeYn())) { + sendData = java.net.URLEncoder.encode(sendData); + } + + ContentType contentTypeObj ; + if (StringUtils.isNotEmpty(vo.getContentType())) { + //주석이유 : ContentType.create에서 "application/json;charset=UTF-8" 이런 형태면 오류발생 +// String contentTypeValue ; +// if (StringUtils.isNotEmpty(vo.getEncode())) { +// contentTypeValue = vo.getContentType() + "; charset=" + vo.getEncode(); +// } else { +// contentTypeValue = vo.getContentType(); +// } + contentTypeObj = ContentType.create(vo.getContentType(), vo.getEncode()); + }else{ + contentTypeObj = ContentType.APPLICATION_JSON; + } + + HttpPost method = new HttpPost(vo.getUrl()); + // POST 요청 본문 설정 + if (sendData != null) { + method.setEntity(new StringEntity(sendData, contentTypeObj)); + } + + if (vo.getAdapterHeaders() != null) { + for (String key : vo.getAdapterHeaders().keySet()) { + method.setHeader(key, vo.getAdapterHeaders().get(key)); + } + } + if (logger.isInfoEnabled()) { + logger.info("" + CONTENT_TYPE_KEY + "(" + contentTypeObj + ")"); + } + + configureHttpClient(requestConfigBuilder, vo, method); + + int status = -1; + + try { + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug( + "SEND (" + vo.getAdapterGroupName() + ") = [" + sendData + "]"); + logger.debug("SEND (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(sendData)); + } + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "SEND [" + sendData + "]" + CommonLib.getDumpMessage(sendData)); + } + + String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID); + HttpContext context = new BasicHttpContext(); + context.setAttribute(TransactionContextKeys.TRANSACTION_UUID, uuid); + context.setAttribute(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME, vo.getAdapterGroupName()); + context.setAttribute(HttpClientAdapterServiceKey.ADAPTER_NAME, vo.getAdapterName()); + Integer logProcessNo = (Integer) tempProp.get(HttpClientAdapterServiceKey.LOG_PROCESS_NO); + if (logProcessNo != null && logProcessNo > 0) { + context.setAttribute(HttpClientAdapterServiceKey.LOG_PROCESS_NO, logProcessNo); + } + + byte[] responseMessage = null; + String responseString = ""; + try (CloseableHttpResponse response = (CloseableHttpResponse) this.client.execute(method, context)) { + status = response.getCode(); + responseMessage = EntityUtils.toByteArray(response.getEntity()); + responseString = new String(responseMessage, vo.getEncode()); + if (logger.isDebug()) { + logger.debug("[received status]" + status); + logger.debug("HttpClientAdapterServiceBody] RECV (" + vo.getAdapterGroupName() + ") = [" + responseString + "]"); + } + } catch (ConnectException e) { + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceBody] responseType =" + vo.getResponseType()); + } + throw new Exception("excuteMethod java.net.ConnectException = " + e.getMessage()); + } + + stopWatch.stop(); + + + if (status >= 400 && status < 500) { + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), vo.getUrl(), "post", responseString); + throw new Exception(errMsg); + } else if(status != HttpStatus.SC_OK) { + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), vo.getUrl(), "post", responseString); + throw new Exception(errMsg); + } + + if (isAsync && stopWatch.getTime() > vo.getSlowTranTime() && (logger.isWarn())) { + logger.warn("URL[" + vo.getUrl() + "] lazy async response time = " + + stopWatch.toString() + " responseMessage=" + responseString); + } + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "RECV [" + responseString + "]" + + CommonLib.getDumpMessage(responseMessage)); + } + + return responseMessage; + + } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "SocketTimeoutException : " + ste.toString(), ste); + } + if (logger.isError()) { + logger.error("SocketTimeoutException : " + ste.toString(), ste); + } + throw ste; + } catch (ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "Connection Exception : " + ce.toString(), ce); + } + if (logger.isError()) { + logger.error("Connection Exception : " + ce.toString(), ce); + } + throw ce; + } catch (Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "Exception : " + e.toString(), e); + } + if (logger.isError()) { + logger.error("Exception : " + e.toString(), e); + } + throw e; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java new file mode 100644 index 0000000..2605db0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClient5AdapterServiceRest.java @@ -0,0 +1,895 @@ +package com.eactive.eai.adapter.http.client.impl; + +import java.io.IOException; +import java.io.StringReader; +import java.math.BigDecimal; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.net.URI; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.eactive.eai.common.property.PropManager; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.apache.hc.client5.http.classic.HttpClient; +import org.apache.hc.client5.http.classic.methods.HttpDelete; +import org.apache.hc.client5.http.classic.methods.HttpGet; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.classic.methods.HttpPut; +import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.Header; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.HttpStatus; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.apache.hc.core5.http.message.BasicNameValuePair; +import org.apache.hc.core5.http.protocol.BasicHttpContext; +import org.apache.hc.core5.http.protocol.HttpContext; +import org.apache.hc.core5.net.URIBuilder; +import org.dom4j.Document; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpMethodType; +import com.eactive.eai.adapter.http.client.HttpClient5AdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.authoutbound.AccessTokenManagerByDB; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.CommonLib; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import com.openbanking.eai.common.token.AccessTokenManager; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; + +/** + * 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 + * 기능을 제공한다.
+ * 2. 처리 개요 :
+ * * - 2020-09-25: Http Header 받아서 처리할 수 있게 기능 추가
+ * 3. 주의사항
+ * + * @author : + * @version : v 1.0.0 + * @see : HttpClientAdapterServiceFactory.java, + * HttpClientAdapterServiceSupport.java + * @since : + * + */ +public class HttpClient5AdapterServiceRest extends HttpClient5AdapterServiceSupport + implements HttpClientAdapterServiceKey { + public static final String TYPE_VARIABLE_URL_REQUEST = "variableUrlRequest"; + public static final String TYPE_SIMPLE_REQUEST = "simpleRequest"; + public static final String REST_OPTION = "REST_OPTION"; + //public static final String HEADER_CONTENT_TYPE = "Content-Type"; + public static final String HEADER_GROUP = "HEADER_GROUP"; + public static final String HTTP_STATUS = "HTTP_STATUS"; + public static final String HEADER_KEYS = "HEADER_KEYS"; + public static final String AUTH_TOKEN = "AUTH_TOKEN"; + + /** + * 1. 기능 : REST API 통신에 사용
+ * 2. 처리 개요 : - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다.
+ * 3. 주의사항
+ * + * @param prop Http Adapter 속성 정보 + * @return 반환 된 Object + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + @SuppressWarnings({ "unchecked" }) + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + + // 2025.04.09 Authorization 헤더값을 프로퍼티(AUTH_TOKEN)에서 지정하여 설정할 수 있도록 수정 + // 2025.05.29 프로퍼티 그룹 AUTH_TOKEN이 없을때 Null Point Exception 발생하여 수정 + String bizCode = ""; + String authToken = ""; + try { + Properties authProp = PropManager.getInstance().getProperties(AUTH_TOKEN); //Authorization + bizCode = vo.getAdapterGroupName().substring(1, 4); + authToken = authProp.getProperty(bizCode, ""); + } catch (Exception e) { + logger.debug("Property Group AUTH_TOKEN is not Exist !!"); + } + + logger.debug("authToken :::::::::::::::::::::::::::::::::::" + authToken); + + String headerGroupName = prop.getProperty(HEADER_GROUP); + String relayResponseHeaderKeys = prop.getProperty(HEADER_KEYS, ""); + boolean useAdapterToken = StringUtils.equalsIgnoreCase(prop.getProperty("ADAPTER_TOKEN_USE_YN", "N"), "Y"); + + boolean useForwardProxy = StringUtils.equalsIgnoreCase(prop.getProperty("FORWARD_PROXY_USE_YN", "N"), "Y"); + String forwardProxyUrl = prop.getProperty("FORWARD_PROXY_URL"); + + // ex) $.dataHeader.GW_RSLT_CD + String tokenErrorCodeKey = prop.getProperty("ADAPTER_TOKEN_ERROR_CODE_KEY"); + String tokenErrorCodeValues = prop.getProperty("ADAPTER_TOKEN_ERROR_CODE_VALUES"); + String tokenErrorHttpStatusCode = prop.getProperty("ADAPTER_TOKEN_ERROR_HTTP_STATUS_CODE"); // 200 or 400번대 + + // 레이아웃 메시지 타입 REST URL 추출 시 활용. Default JSON + String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); + String inboundMethod = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_METHOD, "POST"); + + /** + * @formatter:off + * TSEAIHE02.RESTOPTION 정보 => JSON 형태로 구성 + * - type : simpleRequest, variableUrlRequest + * - extraPath : 어댑터 프로퍼티 URL에 추가될 HTTP REST URL + * - method : get, delete, post, put + * - contentType: application/json(default), application/x-www-form-urlencoded + * - adapterTokenUseYn: Y, N(default) + * ex) + * {"type":"simpleRequest","extraPath":"v2.0/accout/balance","method":"post"} + * @formatter:on + */ + + String restOptionData = tempProp.getProperty(REST_OPTION); + + JSONObject restOptionObject = parseJson(restOptionData); + if (restOptionObject == null) { + throw new Exception("OptionData parsing result is NULL"); + } + + String rmethod = (String) restOptionObject.getOrDefault("method", inboundMethod); + String contentType = (String) restOptionObject.getOrDefault("contentType", "application/json"); + String adapterTokenUseYn = (String) restOptionObject.get("adapterTokenUseYn"); + if (StringUtils.isNotBlank(adapterTokenUseYn)) { // interface 에 설정된게 우선한다. + useAdapterToken = StringUtils.equalsIgnoreCase(adapterTokenUseYn, "Y"); + } + + HttpClient mclient = this.client; + String sendData = ""; + if (data instanceof String) { + sendData = (String) data; + } else if (data instanceof byte[]) { + sendData = new String((byte[]) data, vo.getEncode()); + } + + ////mclient.getParams().setContentCharset(vo.getEncode()); + + JSONObject dataObject = null; + Object httpHeader = null; + Object dataContent = null; + + if (MessageType.JSON.equals(messageType)) { + + Object parsed = parseJsonGeneric(sendData); + + if(parsed instanceof JSONObject) { + dataObject = parseJson(sendData); + if (dataObject != null && StringUtils.isNotBlank(headerGroupName)) { + httpHeader = dataObject.get(headerGroupName); + dataObject.remove(headerGroupName); + } + + dataContent = dataObject; + if (dataObject.containsKey("innerList")) { + JSONArray innerList = (JSONArray) dataObject.get("innerList"); + dataContent = innerList; + } + } + } + +// if (MessageType.JSON.equals(messageType)) { +// dataObject = parseJson(sendData); +// if (dataObject != null && StringUtils.isNotBlank(headerGroupName)) { +// httpHeader = dataObject.get(headerGroupName); +// dataObject.remove(headerGroupName); +// } +// } + + logger.debug("HttpClientAdapterServiceRest] dataObject1 = [" + dataObject + "]"); + + // interface 에 설정된게 우선한다. + String uri = null; + if (dataObject == null) { + uri = changeUrl(messageType, vo.getUrl(), restOptionData, sendData); + } else { + uri = changeUrl(messageType, vo.getUrl(), restOptionData, dataObject); + } + + logger.debug("HttpClientAdapterServiceRest] dataObject2 = [" + dataObject + "]"); + +// ////if (vo.getConnectionTimeout() != 0) { +// mclient.getHttpConnectionManager().getParams().setConnectionTimeout(vo.getConnectionTimeout()); +// } + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") URL=[" + vo.getUrl() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") PARAMETER_NAME=[" + vo.getParameterName() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") ENCODE=[" + vo.getEncode() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") RESPONSE_TYPE=[" + vo.getResponseType() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") URL_ENCODE_YN=[" + vo.getUrlEncodeYn() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") CONNECTION_TIMEOUT=[" + vo.getConnectionTimeout() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") REST_OPTION=[" + restOptionData + "] "); + } + + HttpUriRequestBase method = null; + + + // 메소드 타입에 따라 HttpRequestBase 인스턴스 생성 + switch (HttpMethodType.getValue(rmethod)) { + case GET: + method = new HttpGet(uri); + break; + case DELETE: + method = new HttpDelete(uri); + break; + case POST: + method = new HttpPost(uri); + break; + case PUT: + method = new HttpPut(uri); + break; + default: + method = new HttpGet(uri); + break; + } + + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + + if(useForwardProxy) { + java.net.URL url = new java.net.URL(forwardProxyUrl); + + // 프로토콜, 호스트, 포트 추출 + String protocol = url.getProtocol(); + String host = url.getHost(); + int port = url.getPort(); + HttpHost proxy = new HttpHost(protocol,host, port); + requestConfigBuilder.setProxy(proxy); + } + + configureHttpClient(requestConfigBuilder, vo, method); + + switch (HttpMethodType.getValue(rmethod)) { + case GET: + case DELETE: + HashMap h = getParameters(dataObject); + URIBuilder uriBuilder = new URIBuilder(uri); + for (Map.Entry entry : h.entrySet()) { + uriBuilder.addParameter(entry.getKey(), entry.getValue()); + } + URI fullUri = uriBuilder.build(); + if (method instanceof HttpGet) { + ((HttpGet) method).setUri(fullUri); + } else if (method instanceof HttpDelete) { + ((HttpDelete) method).setUri(fullUri); + } + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceRest] (get Method) QueryString = [" + fullUri.getQuery() + "]"); + } + break; + case PUT: + case POST: +// assignPostBody(dataObject, contentType, vo.getEncode(), method); + assignPostBody(dataContent, contentType, vo.getEncode(), method); + break; + default: + break; + } + + if (logger.isDebugEnabled()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") method.getParams()=[" + + method.getEntity() + "] "); + } + + OAuth2AccessTokenVO accessToken = null; + if (useAdapterToken) { + AccessTokenManagerByDB tokenManager = AccessTokenManagerByDB.getInstance(); + accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); + + // 토큰이 없거나 만료 됐으면 재발급 + if (accessToken == null || accessToken.isExpired()) { + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, + oldToken); + } + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") TOKEN = [" + + accessToken + "]"); + } + + setAuthHeaders(method, accessToken); + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + + ") RequestHeader [Authorization=" + method.getHeader("Authorization") + "]"); + } + } + + if(!StringUtils.isBlank(authToken)) { + setAuthHeaders(method, authToken); + } + + // 전달 header 셋팅 + // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) + assignRequestHeaders(method, httpHeader); + + int status = -1; + + try { + byte[] responseMessage = null; + Header[] responseHeaders; + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + if (dataObject != null) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = [" + + dataObject.toJSONString() + "]"); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(dataObject.toJSONString())); + } else { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = [" + sendData + + "]"); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(sendData)); + } + } + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "SEND [" + sendData + "]" + CommonLib.getDumpMessage(sendData)); + } + + String uuid = tempProp.getProperty(TransactionContextKeys.TRANSACTION_UUID); + HttpContext context = new BasicHttpContext(); + context.setAttribute(TransactionContextKeys.TRANSACTION_UUID, uuid); + context.setAttribute(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME, vo.getAdapterGroupName()); + context.setAttribute(HttpClientAdapterServiceKey.ADAPTER_NAME, vo.getAdapterName()); + Integer logProcessNo = (Integer) tempProp.get(HttpClientAdapterServiceKey.LOG_PROCESS_NO); + if (logProcessNo != null && logProcessNo > 0) { + context.setAttribute(HttpClientAdapterServiceKey.LOG_PROCESS_NO, logProcessNo); + } + + try { + if (logger.isDebug()) { + logger.debug("[method getName]" + method.getMethod()); + logger.debug("[method getEntity]" + method.getEntity()); + logger.debug("[method getRequestHeaders]" + method.getHeaders().toString()); + logger.debug("[method getURI]" + method.getPath()); + } + try (CloseableHttpResponse response = (CloseableHttpResponse) mclient.execute(method, context)) { + status = response.getCode(); + + responseMessage = EntityUtils.toByteArray(response.getEntity()); + responseHeaders = response.getHeaders(); + + if (logger.isDebug()) { + logger.debug("[received status]" + status); + logger.debug("HttpClientAdapterServiceRest] RECV (" + vo.getAdapterGroupName() + ") = [" + responseMessage + "]"); + } + } + } catch (ConnectException e) { + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] responseType =" + vo.getResponseType()); + } + throw new Exception("excuteMethod java.net.ConnectException = " + e.getMessage()); + } + + stopWatch.stop(); + + /** + * @formatter:off + * OAuth 토큰 응답 체크(Adapter properties로 설정) + * 응답코드에 따라 유효한 토큰 확인(토큰 재발급 여부 확인) + * API 서비스 마다 정책이 다름(보통 400대에서 체크하나 200에서도 체크할 수 있음) + * + * TOKEN_ERROR_CODE_KEY: 응답 json error code key + * __ex) $.dataHeader.resultCode + * TOKEN_ERROR_CODE_VALUES: 토큰 재발급이 필요한 응답 error codes(ex: O0001,O0002,O0003) + * TOKEN_ERROR_HTTP_STATUS_CODE: 보통 400대에서 체크하나 API 제공자에 따라 200에서도 체클할수 있음 + * ex) TOKEN_ERROR_HTTP_STATUS_CODE = 200 + * @formatter:on + */ + boolean needReissue = false; + + Properties responseHeaderProp = assignRelayDataToInbound(tempProp, responseHeaders); + String responseString = new String(responseMessage, vo.getEncode()); + + Map map = new HashMap(); + tempProp.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, map); + map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_HEADERS, responseHeaderProp); + map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_MESSAGE, responseString); + map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_STATUS, status); + + if (status >= 200 && status <= 207) { + if (useAdapterToken && StringUtils.equals(tokenErrorHttpStatusCode, "200")) { + needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, + vo.getEncode()); + } + } else if (status == 302) { + if (!StringUtils.contains(relayResponseHeaderKeys, "Location")) { + relayResponseHeaderKeys += ",Location"; + } + } else { + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), uri, rmethod, responseString); +// logger.error(errMsg); + + if (status >= 400 && status < 500) { + if (useAdapterToken) { + needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, + vo.getEncode()); + } + + if (!needReissue) { + throw new Exception(errMsg); + } + } else { + + throw new Exception(errMsg); + } + } + + // ---------------------------------------------------------- + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] responseType =" + vo.getResponseType()); + logger.debug("HttpClientAdapterServiceRest] RECV " + vo.getEncode() + "(" + vo.getAdapterGroupName() + ") = [" + new String(responseMessage, vo.getEncode()) + "]"); +// logger.debug("HttpClientAdapterServiceRest] RECV MS949 (" + vo.getAdapterGroupName() + ") = [" + new String(responseMessage, "MS949") + "]"); +// logger.debug("HttpClientAdapterServiceRest] RECV euc-kr (" + vo.getAdapterGroupName() + ") = [" + new String(responseMessage, "euc-kr") + "]"); + logger.debug("HttpClientAdapterServiceRest] RECV (" + vo.getAdapterGroupName() + ") = " + CommonLib.getDumpMessage(responseMessage)); + } + + if (useAdapterToken) { + if (responseMessage == null) { + throw new Exception("responseMessage is NULL, HttpStatus=" + status); + } + + // OAuth 토큰 재요청 코드 확인 + if (needReissue) { + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] retry access token response code = [" + + vo.getResponseType() + "] message = [" + new String(responseMessage, vo.getEncode()) + + "]"); + } + + // 토큰 재발급 + AccessTokenManager tokenManager = AccessTokenManager.getInstance(); + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + OAuth2AccessTokenVO newaccessToken = (OAuth2AccessTokenVO) tokenManager + .retryAccessTokenVO(vo.getAdapterGroupName(), prop, oldToken); + method.setHeader("Authorization", newaccessToken.getAuthorization()); + + setAuthHeaders(method, newaccessToken); + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + + ") RETRY TOKEN = [" + newaccessToken + "]"); + } + + try (CloseableHttpResponse response = (CloseableHttpResponse) mclient.execute(method)) { + status = response.getCode(); + responseMessage = EntityUtils.toByteArray(response.getEntity()); + + if (logger.isDebug()) { + logger.debug("[received status]" + status); + logger.debug("HttpClientAdapterServiceRest] RECV (" + vo.getAdapterGroupName() + ") = [" + new String(responseMessage, vo.getEncode()) + "]"); + } + }catch (IOException e){ + throw new Exception("retry excuteMethod Exceptioin = " + e.getMessage()); + } + + + if (status == 302) { + if (!StringUtils.contains(relayResponseHeaderKeys, "Location")) { + relayResponseHeaderKeys += ",Location"; + } + } else { + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), uri, rmethod, responseMessage); + throw new Exception(errMsg); + } + + // ---------------------------------------------------------- + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] RETRY responseType =" + vo.getResponseType()); + logger.debug("HttpClientAdapterServiceRest] RETRY RECV " + vo.getEncode() + "(" + + vo.getAdapterGroupName() + ") = [" + new String(responseMessage, vo.getEncode()) + + "]"); + logger.debug("HttpClientAdapterServiceRest] RETRY RECV (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(responseMessage)); + } + // ---------------------------------------------------------- + } + } + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "RECV [" + new String(responseMessage, vo.getEncode()) + "]" + + CommonLib.getDumpMessage(responseMessage)); + } + + + return assignResponseHeaders(method, responseMessage, headerGroupName, vo.getEncode(), messageType, + relayResponseHeaderKeys, status, responseHeaderProp); + } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceRest] SocketTimeoutException (" + vo.getAdapterGroupName() + ") : " + + ste.toString(), + ste); + } + logger.error("HttpClientAdapterServiceRest] SocketTimeoutException (" + vo.getAdapterGroupName() + ") : " + + ste.toString(), ste); + throw ste; + } catch (ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceRest] Connection Exception (" + vo.getAdapterGroupName() + ") : " + + ce.toString(), + ce); + } + logger.error("HttpClientAdapterServiceRest] Connection Exception (" + vo.getAdapterGroupName() + ") : " + + ce.toString(), ce); + throw ce; + } catch (Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), e.toString(), e); + } + logger.error("HttpClientAdapterServiceRest] Exception (" + vo.getAdapterGroupName() + ") : " + e.toString(), + e); + throw e; + } finally { + if (status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); + if (logger.isDebug()) { + logger.debug(resMsg); + } + } + } + } + + private Properties assignRelayDataToInbound(Properties prop, Header[] responseHeaders) { + Properties headerProp = new Properties(); + if (responseHeaders == null || responseHeaders.length == 0) { + return headerProp; + } + + for (Header header : responseHeaders) { + headerProp.put(header.getName(), header.getValue()); + } + + return headerProp; + } + + /** + * 현재 1단계 레이아웃에만 적용되도록 구현됨. + * + * @param method + * @param responseMessage + * @param headerGroupName + * @param encode + * @param messageType + * @param relayHeaderKeys + * @return + * @throws Exception + */ + @SuppressWarnings("unchecked") + private String assignResponseHeaders(HttpUriRequestBase method, byte[] responseMessage, String headerGroupName, + String encode, String messageType, String relayHeaderKeys, int status, Properties responseHeaderProp) throws Exception { + if (!MessageType.JSON.equals(messageType) || StringUtils.isBlank(headerGroupName) + || StringUtils.isBlank(relayHeaderKeys)) { + return new String(responseMessage, encode); + } + + String[] relayKeyArr = org.springframework.util.StringUtils.tokenizeToStringArray(relayHeaderKeys, ","); + JSONObject headerJson = new JSONObject(); + for (String key : relayKeyArr) { + String value = responseHeaderProp.getProperty(key); + if (StringUtils.isNotBlank(value)) { + headerJson.put(key, value); + } + } + + headerJson.put(HTTP_STATUS, String.valueOf(status)); + + if (headerJson.size() <= 0) { + return new String(responseMessage, encode); + } + + JSONObject message = null; + if (responseMessage == null || responseMessage.length == 0) { + message = new JSONObject(); + } else { + message = parseJson(new String(responseMessage, encode)); + if (message == null) { + message = new JSONObject(); + message.put("Malformed_Response_Message", new String(responseMessage, encode)); + } + } + + if (StringUtils.isNotBlank(headerGroupName) && message != null) + message.put(headerGroupName, headerJson); + return message.toJSONString(); + } + + private void setAuthHeaders(HttpUriRequestBase method, String authorization) throws Exception { + method.setHeader("Authorization", + String.format("%s", authorization)); + } + + private void setAuthHeaders(HttpUriRequestBase method, OAuth2AccessTokenVO accessToken) throws Exception { + method.setHeader("Authorization", + String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); + } + + private boolean checkTokenRetry(byte[] responseMessage, String tokenErrorCodeKey, String tokenErrorCodeValues, + String encode) { + if (responseMessage == null) { + return false; + } + + if (StringUtils.isBlank(tokenErrorCodeKey)) { + return false; + } + + if (StringUtils.isBlank(tokenErrorCodeValues)) { + return false; + } + + try { + DocumentContext jsonContext = JsonPath.parse(new String(responseMessage, encode)); + String responseCode = jsonContext.read(tokenErrorCodeKey); + if (StringUtils.isBlank(responseCode)) { + return false; + } + + String[] arr = org.springframework.util.StringUtils.tokenizeToStringArray(tokenErrorCodeValues, ","); + return ArrayUtils.contains(arr, responseCode); + } catch (Exception e) { + logger.error("HttpClientAdapterServiceRest] checkTokenRetry error=" + e.getMessage()); + } + + return false; + } + + private void assignRequestHeaders(HttpUriRequestBase method, Object httpHeader) { + if (httpHeader == null) { + return; + } + + if (httpHeader instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) httpHeader; + for (Object key : jsonObject.keySet()) { + Object obj = jsonObject.get(key); + if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { + continue; + } + + method.setHeader((String) key, (String) obj); + + if (logger.isDebugEnabled()) { + logger.debug("Request Header :" + (String) key + "=[" + (String) obj + "]"); + } + + } + } + } + + @SuppressWarnings("deprecation") + private void assignPostBody(Object eaiBody, String contentType, String charset, HttpUriRequestBase method) { + if (eaiBody == null) { + return; + } + + if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { + if (eaiBody instanceof JSONObject) { + List params = new ArrayList<>(); + JSONObject jsonObject = (JSONObject) eaiBody; + for (Object key : jsonObject.keySet()) { + params.add(new BasicNameValuePair((String) key, (String) jsonObject.get(key))); + } + + UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, StandardCharsets.UTF_8); + method.setEntity(entity); + } + } else { + ContentType contentTypeObj = ContentType.create(contentType, charset); + + // 요청 본문을 StringEntity 객체로 생성 + StringEntity entity = new StringEntity(eaiBody.toString(), contentTypeObj); + + // 요청에 본문 추가 + method.setEntity(entity); + } + } + + private HashMap getParameters(Object message) throws Exception { + + HashMap result = new HashMap(); + + if (message != null) { + if (message instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) message; + for (Object key : jsonObject.keySet()) { + Object obj = jsonObject.get(key); + if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { + continue; + } + result.put((String) key, getStringValue(obj)); + } + } else { + String[] messages = ((String) message).split("&"); + String[] data = null; + + for (int i = 0; i < messages.length; i++) { + data = messages[i].split("=", 2); + if (data.length == 2) { + result.put(data[0], data[1]); + } + } + } + } + + return result; + } + + public String getStringValue(Object obj) { + if (obj == null) { + return null; + } + + if (obj instanceof String) { + return (String) obj; + } else if (obj instanceof Long) { + return Long.toString((Long) obj); + } else if (obj instanceof BigDecimal) { + return ((BigDecimal) obj).toPlainString(); + } else { + return (String) obj; + } + } + + public static Object parseJsonGeneric(String jsonData) { + if (StringUtils.isBlank(jsonData)) { + return null; + } + + try { + JSONParser parser = new JSONParser(); + Object parsedObj = parser.parse(jsonData); + return parsedObj; + } catch (ParseException e) { + e.printStackTrace(); + return null; + } + } + + @SuppressWarnings("deprecation") + private JSONObject parseJson(String message) throws Exception { + if (message == null) { + return null; + } + + return (JSONObject) JSONValue.parse(message); + } + + private Document convertXmlDocument(String message) throws Exception { + SAXReader builder = new SAXReader(); + Document document = builder.read(new StringReader(message)); + return document; + } + + @SuppressWarnings("deprecation") + private String changeUrl(String messageType, String url, String restOption, Object sendData) { + if ((MessageType.JSON.equals(messageType) || MessageType.XML.equals(messageType))) { + try { + if (StringUtils.isBlank(restOption)) { + return url; + } + List urlVariableList = new ArrayList(); + JSONObject restOptionObject = parseJson(restOption); + + if (restOptionObject == null) + throw new Exception("restOption is NULL"); + + String type = (String) restOptionObject.get("type"); + String requestExtraPath = (String) restOptionObject.get("extraPath"); + url = getUrl(url, requestExtraPath); + if (TYPE_VARIABLE_URL_REQUEST.equals(type)) { + Pattern p = Pattern.compile("\\{(.*?)\\}"); + Matcher m = p.matcher(requestExtraPath); + List uriVariables = new ArrayList<>(); + while(m.find()) { + String fieldName = m.group(1); + uriVariables.add(fieldName); + } + if (MessageType.JSON.equals(messageType)) { + JSONObject jsonObject; + if (sendData instanceof JSONObject) { + jsonObject = (JSONObject) sendData; + } else { + jsonObject = (JSONObject) JSONValue.parse((String) sendData); + } + for (Object tempObject : uriVariables) { + String urlVaribleId = (String) tempObject; + String uriVariable = (String) jsonObject.get(urlVaribleId); + urlVariableList.add(uriVariable); + jsonObject.remove(urlVaribleId); + } + } else if (MessageType.XML.equals(messageType)) { + Document doc; + if (sendData instanceof Document) { + doc = (Document) sendData; + } else { + doc = convertXmlDocument((String) sendData); + } + for (Object tempObject : uriVariables) { + String urlVaribleId = (String) tempObject; + Element element = (Element) doc.selectSingleNode("//" + urlVaribleId); + urlVariableList.add(element.getText()); + if (doc.getRootElement() == element) { + doc = null; + } else { + element.getParent().remove(element); + } + } + } + if (urlVariableList.size() > 0) { + UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build(); + Object[] urls = urlVariableList.toArray(); + url = uriComponents.expand(urls).toUriString(); + logger.debug("HttpClientAdapterServiceRest] after extand url=[" + url + "] "); + } + } + } catch (Exception e) { + logger.error("Failed to change url", e); + } + } + return url; + } + + private String getUrl(String baseUrl, String extraPath) { + if (StringUtils.isBlank(extraPath)) { + return baseUrl; + } + + if (StringUtils.contains(extraPath, "http://") || StringUtils.contains(extraPath, "https://")) { + return extraPath; + } + + String targetUrl = baseUrl; + if (!targetUrl.endsWith("/")) { + targetUrl += "/"; + } + if (extraPath.startsWith("/")) { + targetUrl += extraPath.substring(1); + } else { + targetUrl += extraPath; + } + + logger.debug("HttpClientAdapterServiceRest] after concatenate url=[" + targetUrl + "] "); + return targetUrl; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceAnnounce.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceAnnounce.java new file mode 100644 index 0000000..7c284de --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceAnnounce.java @@ -0,0 +1,183 @@ +// +//package com.eactive.eai.adapter.http.client.impl; +// +//import com.eactive.eai.adapter.http.HttpMemoryLogger; +//import com.eactive.eai.adapter.http.HttpStatusException; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.util.CommonLib; +//import org.apache.commons.httpclient.HttpClient; +//import org.apache.commons.httpclient.HttpStatus; +//import org.apache.commons.httpclient.HttpVersion; +//import org.apache.commons.httpclient.methods.PostMethod; +// +//import java.net.ConnectException; +//import java.net.SocketTimeoutException; +//import java.util.Properties; +// +// +///** +//* 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 +//* GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +//* 2. 처리 개요 : +//* * - 2009.11.24 retry 로직 제거 : 요청 +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +//* @since : +// +//*/ +//public class HttpClientAdapterServiceAnnounce extends HttpClientAdapterServiceSupport{ +// +// /** +// * 1. 기능 : 전문과 같은 Raw Data 통신에 사용 +// * 2. 처리 개요 : +// * - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. +// * 3. 주의사항 +// * +// * @param prop Http Adapter 속성 정보 +// * @param message 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// public Object execute(Properties prop, byte[] data, Properties tempProp) throws Exception { +// +// HttpClientAdapterVO vo = super.setting(prop, tempProp); +// +// if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceAnnounce] SEND (" + vo.getMethod() + ") "); +// } +// PostMethod method = new PostMethod(vo.getUrl()); +// if (vo.getTimeout() > -1) { +// method.getParams().setSoTimeout(vo.getTimeout()); +// } +// HttpClient mclient = this.client; +// if ( vo.getConnectionTimeout() != 0){ +// mclient.getParams().setParameter("http.connection.timeout", vo.getConnectionTimeout()); +// } +// method.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_0); +// +// // Announce Data Size : 113 Bytes +// int annMinSize = 113; +// +// String srvCode = ""; +// String recipient = ""; +// String body = ""; +// String inurl = ""; +// +// if (data.length >= annMinSize) { +// if (vo.getEncode() != null && vo.getEncode().length() > 0) { +// if (logger.isDebug()) { +// logger.debug("HttpClientAdapterServiceAnnounce] ENCODE(" + vo.getEncode() + ") "); +// } +// srvCode = new String(data, 0, 6, vo.getEncode()); +// recipient = new String(data, 6, 7, vo.getEncode()); +// body = new String(data, 13, 100, vo.getEncode()); +// if (data.length > 153) { +// inurl = new String(data, 113, data.length - annMinSize, vo.getEncode()); +// } +// } else { +// srvCode = new String(data, 0, 6); +// recipient = new String(data, 6, 7); +// body = new String(data, 13, 100); +// if (data.length > 153) { +// inurl = new String(data, 113, data.length - annMinSize); +// } +// } +// method.addParameter("SRV_CODE", srvCode); +// method.addParameter("RECIPIENT", recipient); +// method.addParameter("BODY", body); +// if (data.length > 153) { +// method.addParameter("URL", inurl); +// } +// +// } else { +// if (logger.isError()) { +// logger.error("HttpClientAdapterServiceAnnounce] Invalid Data Length (" + data.length + ") < " + annMinSize); +// } +// throw new Exception("HttpClientAdapterServiceAnnounce Error : MessageSize(" + (data.length) + " Bytes) too small < " + annMinSize); +// } +// +// int status = -1; +// +// try { +// if (vo.getTraceLevel() >= 3){ +// if (data.length > 153){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), +// "[URL]"+ inurl + "\n" +// + "[SRV_CODE]" + srvCode + "\n" +// + "[RECIPIENT]" + recipient + "\n" +// + "[BODY]" + body + "\n" +// + "SEND ["+new String(data)+"]"+CommonLib.getDumpMessage(data) +"\n" +// ); +// }else{ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), +// "[SRV_CODE]" + srvCode + "\n" +// + "[RECIPIENT]" + recipient + "\n" +// + "[BODY]" + body + "\n" +// + "SEND ["+new String(data)+"]"+CommonLib.getDumpMessage(data) +"\n" +// ); +// +// } +// } +// //mclient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout); +// //mclient.getParams().setContentCharset("EUC_KR"); +// status = mclient.executeMethod(method); +// +// //status 200(정상) 이외에는 error 처리 +// if (status !=200){ +// try{ +// logger.error("HttpClientAdapterServiceAnnounce] receive status["+status+"] data[" + new String(method.getResponseBody()) +"]"); +// }catch(Exception e){ +// logger.error(e); +// } +// throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName="+vo.getAdapterGroupName()+"."+vo.getAdapterName(),status); +// } +// byte[] responseMessage = method.getResponseBody(); +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "RECV ["+new String(responseMessage)+"]"+CommonLib.getDumpMessage(responseMessage) ); +// } +// return responseMessage; +// +// } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceAnnounce] SocketTimeoutException : " + ste.toString() ,ste); +// } +// if (logger.isError()){ +// logger.error("HttpClientAdapterServiceAnnounce] SocketTimeoutException : " + ste.toString() ,ste); +// } +// throw ste; +// } catch(ConnectException ce) { +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceAnnounce] Connection Exception : " + ce.toString() ,ce); +// } +// if (logger.isError()){ +// logger.error("HttpClientAdapterServiceAnnounce] Connection Exception : " + ce.toString() ,ce); +// } +// throw ce; +// } catch(Exception e) { +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceAnnounce] Exception : " + e.toString() ,e); +// } +// if (logger.isError()){ +// logger.error("HttpClientAdapterServiceAnnounce] Exception : " + e.toString() ,e); +// } +// throw e; +// } finally { +// method.releaseConnection(); +// if (status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if (logger.isDebug()) { +// logger.debug(resMsg); +// } +// } +// } +// +// } +// +//} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceBody.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceBody.java new file mode 100644 index 0000000..011bb38 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceBody.java @@ -0,0 +1,160 @@ +package com.eactive.eai.adapter.http.client.impl; + +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.Properties; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.HttpVersion; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; + +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.CommonLib; + +public class HttpClientAdapterServiceBody extends HttpClientAdapterServiceSupport { + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + + boolean isAsync = false; + if (RESPONSE_TYPE_ASYNC.equals(vo.getResponseType())) { + isAsync = true; + } + PostMethod method = new PostMethod(vo.getUrl()); + HttpClient mclient = this.client; + + configureHttpClient(mclient, method, vo, vo.getUrl(), vo.getContentType()); + + String sendData = ""; + if (data instanceof String) { + sendData = (String) data; + } else if (data instanceof byte[]) { + sendData = new String((byte[]) data, vo.getEncode()); + } + + mclient.getParams().setContentCharset(vo.getEncode()); + + String contentTypeValue = null; + if (StringUtils.isNotEmpty(vo.getContentType())) { + if (StringUtils.isNotEmpty(vo.getEncode())) { + contentTypeValue = vo.getContentType() + "; charset=" + vo.getEncode(); + } else { + contentTypeValue = vo.getContentType(); + } + method.setRequestHeader(CONTENT_TYPE_KEY, contentTypeValue); + } + if (vo.getAdapterHeaders() != null) { + for (String key : vo.getAdapterHeaders().keySet()) { + method.addRequestHeader(key, vo.getAdapterHeaders().get(key)); + } + } + if (logger.isInfoEnabled()) { + logger.info("HttpClientAdapterServiceBody] " + CONTENT_TYPE_KEY + "(" + contentTypeValue + ")"); + } + + if ("Y".equals(vo.getUrlEncodeYn())) { + sendData = java.net.URLEncoder.encode(sendData); + } + + method.setRequestBody(sendData); + + int status = -1; + + try { + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug( + "HttpClientAdapterServiceBody] SEND (" + vo.getAdapterGroupName() + ") = [" + sendData + "]"); + logger.debug("HttpClientAdapterServiceBody] SEND (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(sendData)); + } + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "SEND [" + sendData + "]" + CommonLib.getDumpMessage(sendData)); + } + if (vo.getUrl() != null && vo.getUrl().startsWith("https")) { + Protocol.registerProtocol("https", + new Protocol("https", new CustomHttpsSocketFactory(new EasySSLProtocolSocketFactory()), 443)); + } + status = mclient.executeMethod(method); + stopWatch.stop(); + + String responseCharSet = getResponseCharSet(method.getResponseCharSet(), vo.getAdapterGroupName()); + + byte[] responseMessage = method.getResponseBody(); + // status 200(정상) 이외에는 error 처리 + if (status != 200) { + logger.error("HttpClientAdapterServiceBody] receive status[" + status + "] data[" + + new String(responseMessage) + "]"); + throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName=" + + vo.getAdapterGroupName() + "." + vo.getAdapterName(), status); + } + + if (isAsync && stopWatch.getTime() > vo.getSlowTranTime() && (logger.isWarn())) { + logger.warn("HttpClientAdapterServiceBody] URL[" + vo.getUrl() + "] lazy async response time = " + + stopWatch.toString() + " responseMessage=" + new String(responseMessage, responseCharSet)); + + } + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "RECV [" + new String(responseMessage, vo.getEncode()) + "]" + + CommonLib.getDumpMessage(responseMessage)); + } + + return responseMessage; + + } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceBody] SocketTimeoutException : " + ste.toString(), ste); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceBody] SocketTimeoutException : " + ste.toString(), ste); + } + throw ste; + } catch (ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceBody] Connection Exception : " + ce.toString(), ce); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceBody] Connection Exception : " + ce.toString(), ce); + } + throw ce; + } catch (Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceBody] Exception : " + e.toString(), e); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceBody] Exception : " + e.toString(), e); + } + throw e; + } finally { + method.releaseConnection(); + if (status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); + if (logger.isDebug()) { + logger.debug(resMsg); + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceBypass.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceBypass.java new file mode 100644 index 0000000..5a3db4d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceBypass.java @@ -0,0 +1,667 @@ +package com.eactive.eai.adapter.http.client.impl; + +import java.io.ByteArrayInputStream; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.BitSet; +import java.util.Formatter; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpMethodBase; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.EntityEnclosingMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.springframework.http.HttpHeaders; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +import com.eactive.eai.adapter.http.EntityEnclosingDeleteMethod; +import com.eactive.eai.adapter.http.EntityEnclosingGetMethod; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpMethodType; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.impl.HttpAdapterServiceBypass; +import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.CommonLib; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import com.openbanking.eai.common.token.AccessTokenManager; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; + +public class HttpClientAdapterServiceBypass extends HttpClientAdapterServiceSupport + implements HttpClientAdapterServiceKey { + public static final String TYPE_BYPASS_REQUEST = "bypassRequest"; + public static final String REST_OPTION = "REST_OPTION"; + + protected boolean doSendUrlFragment = true; + protected boolean doHandleCompression = false; + protected boolean doForwardIP = true; + + @SuppressWarnings({ "deprecation", "unchecked" }) + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + + boolean useAdapterToken = StringUtils.equalsIgnoreCase(prop.getProperty("ADAPTER_TOKEN_USE_YN", "N"), "Y"); + + // ex) $.dataHeader.GW_RSLT_CD + String tokenErrorCodeKey = prop.getProperty("ADAPTER_TOKEN_ERROR_CODE_KEY"); + String tokenErrorCodeValues = prop.getProperty("ADAPTER_TOKEN_ERROR_CODE_VALUES"); + String tokenErrorHttpStatusCode = prop.getProperty("ADAPTER_TOKEN_ERROR_HTTP_STATUS_CODE"); // 200 or 400번대 + + /** + * @formatter:off + * TSEAIHE02.RESTOPTION 정보 => JSON 형태로 구성 + * - type : simpleRequest, variableUrlRequest + * - extraPath : 어댑터 프로퍼티 URL에 추가될 HTTP REST URL + * - method : get, delete, post, put + * - contentType : application/json, application/x-www-form-urlencoded + * - adapterTokenUseYn: Y, N(default) + * ex) + * {"type":"variableUrlRequest","extraPath":"/aaa/{userId}","uriVariables":["userId"]} + * @formatter:on + */ + String restOptionData = tempProp.getProperty(REST_OPTION, "{}"); + + JSONObject restOptionObject = parseJson(restOptionData); + + String adapterTokenUseYn = (String) restOptionObject.get("adapterTokenUseYn"); + if (StringUtils.isNotBlank(adapterTokenUseYn)) { // interface 에 설정된게 우선한다. + useAdapterToken = StringUtils.equalsIgnoreCase(adapterTokenUseYn, "Y"); + } + + String inboundMethod = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_METHOD, "POST"); + String inboundRewritePath = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_REWRITE_PATH, ""); + String inboundQueryString = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_QUERY_STRING, ""); + Properties inboundHeaders = (Properties) tempProp.get(HttpAdapterServiceKey.INBOUND_HEADER); + Map inboundPathVariables = (Map) tempProp + .get(HttpAdapterServiceKey.INBOUND_PATH_VARIABLES); + + String restMethod = (String) restOptionObject.get("method"); + if (StringUtils.isBlank(restMethod)) { + restMethod = inboundMethod; + } + + String url = getRewriteUrl(vo, inboundRewritePath, inboundQueryString, restOptionObject, inboundPathVariables); + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceBypass] url = [" + url + "]"); + } + + HttpClient mclient = this.client; + + HttpMethodBase method = generateMethod(restMethod, url); + + assignRequestHeaders(method, inboundHeaders, tempProp); + + if (hasBody(data, inboundHeaders)) { + if (data instanceof byte[]) { + ((EntityEnclosingMethod) method).setRequestBody(new ByteArrayInputStream((byte[]) data)); + } else if (data instanceof String) { + ((EntityEnclosingMethod) method).setRequestBody((String) data); + } + } + + String contentType = (String) restOptionObject.get("contentType"); + if (StringUtils.isBlank(contentType) && inboundHeaders != null) { + contentType = getIgnoreCaseProp(inboundHeaders, HttpHeaders.CONTENT_TYPE); + contentType = StringUtils.substringBefore(contentType, ";"); + } + configureHttpClient(mclient, method, vo, url, contentType); + + OAuth2AccessTokenVO accessToken = null; + if (useAdapterToken) { + AccessTokenManager tokenManager = AccessTokenManager.getInstance(); + accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); + + // 토큰이 없거나 만료 됐으면 재발급 + if (accessToken == null || accessToken.isExpired()) { + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, + oldToken); + } + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceBypass] SEND (" + vo.getAdapterGroupName() + ") TOKEN = [" + + accessToken + "]"); + } + + setAuthHeaders(method, accessToken); + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceBypass] SEND (" + vo.getAdapterGroupName() + + ") RequestHeader [Authorization=" + method.getRequestHeader("Authorization") + "]"); + } + } + + int status = -1; + + try { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + byte[] responseMessage = null; + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "SEND [Bypass Request..]" + CommonLib.getDumpMessage(data)); + } + try { + if (logger.isDebug()) { + logger.debug("[method getName]" + method.getName()); + logger.debug("[method getRequestCharSet]" + method.getRequestCharSet()); + logger.debug("[method getRequestHeaders]" + method.getRequestHeaders().toString()); + logger.debug("[method getQueryString]" + method.getQueryString()); + logger.debug("[method getParams]" + method.getParams().toString()); + logger.debug("[method getURI]" + method.getURI()); + } + if (vo.getUrl() != null && vo.getUrl().startsWith("https")) { + Protocol.registerProtocol("https", + new Protocol("https", new CustomHttpsSocketFactory(new EasySSLProtocolSocketFactory()), 443)); + } + status = mclient.executeMethod(method); + if (logger.isDebug()) { + logger.debug("[received status]" + status); + } + } catch (ConnectException e) { + responseMessage = method.getResponseBody(); + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceBypass] responseType =" + vo.getResponseType()); + logger.debug("HttpClientAdapterServiceBypass] RECV (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(responseMessage)); + } + throw new Exception("excuteMethod java.net.ConnectException = " + e.getMessage()); + } + + stopWatch.stop(); + + /** + * @formatter:off + * OAuth 토큰 응답 체크(Adapter properties로 설정) + * 응답코드에 따라 유효한 토큰 확인(토큰 재발급 여부 확인) + * API 서비스 마다 정책이 다름(보통 400대에서 체크하나 200에서도 체크할 수 있음) + * + * TOKEN_ERROR_CODE_KEY: 응답 json error code key + * __ex) $.dataHeader.resultCode + * TOKEN_ERROR_CODE_VALUES: 토큰 재발급이 필요한 응답 error codes(ex: O0001,O0002,O0003) + * TOKEN_ERROR_HTTP_STATUS_CODE: 보통 400대에서 체크하나 API 제공자에 따라 200에서도 체클할수 있음 + * ex) TOKEN_ERROR_HTTP_STATUS_CODE = 200 + * @formatter:on + */ + boolean needReissue = false; + + if (status == 200) { + responseMessage = method.getResponseBody(); + if (useAdapterToken && StringUtils.equals(tokenErrorHttpStatusCode, "200")) { + needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, + vo.getEncode()); + } + } else if (status >= 400 && status < 500) { + responseMessage = method.getResponseBody(); + if (useAdapterToken) { + needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, + vo.getEncode()); + } + + if (!needReissue) { + // body 값이 없을때만 exception 처리하고, body가 있으면 bypass 한다. + if (responseMessage == null || responseMessage.length == 0) { + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), url, method, responseMessage); + throw new Exception(errMsg); + } + } + } else { + responseMessage = method.getResponseBody(); + // body 값이 없을때만 exception 처리하고, body가 있으면 bypass 한다. + if (responseMessage == null || responseMessage.length == 0) { + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), url, method, responseMessage); + throw new Exception(errMsg); + } + } + + if (useAdapterToken) { + if (responseMessage == null) { + throw new Exception("responseMessage is NULL, HttpStatus=" + status); + } + + // OAuth 토큰 재요청 코드 확인 + if (needReissue) { + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceBypass] retry access token response code = [" + + vo.getResponseType() + "] message = [" + new String(responseMessage, vo.getEncode()) + + "]"); + } + + // 토큰 재발급 + AccessTokenManager tokenManager = AccessTokenManager.getInstance(); + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + OAuth2AccessTokenVO newAccessToken = (OAuth2AccessTokenVO) tokenManager + .retryAccessTokenVO(vo.getAdapterGroupName(), prop, oldToken); + method.setRequestHeader("Authorization", newAccessToken.getAuthorization()); + + setAuthHeaders(method, newAccessToken); + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceBypass] SEND (" + vo.getAdapterGroupName() + + ") RETRY TOKEN = [" + newAccessToken + "]"); + } + + try { + status = mclient.executeMethod(method); + } catch (ConnectException e) { + throw new Exception("retry excuteMethod Exceptioin = " + e.getMessage()); + } + + if (status == 200) { + responseMessage = method.getResponseBody(); + } else { + responseMessage = method.getResponseBody(); + // body 값이 없을때만 exception 처리하고, body가 있으면 bypass 한다. + if (responseMessage == null || responseMessage.length == 0) { + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), url, method, + responseMessage); + throw new Exception(errMsg); + } + } + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceBypass] RETRY responseType =" + vo.getResponseType()); + logger.debug("HttpClientAdapterServiceBypass] RETRY RECV (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(responseMessage)); + } + } + } + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "RECV [Bypass Request..]" + CommonLib.getDumpMessage(responseMessage)); + } + assignRelayDataToInbound(tempProp, method.getResponseHeaders(), status); + return responseMessage; + } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceBypass] SocketTimeoutException (" + vo.getAdapterGroupName() + ") : " + + ste.toString(), + ste); + } + logger.error("HttpClientAdapterServiceBypass] SocketTimeoutException (" + vo.getAdapterGroupName() + ") : " + + ste.toString(), ste); + throw ste; + } catch (ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceBypass] Connection Exception (" + vo.getAdapterGroupName() + ") : " + + ce.toString(), + ce); + } + logger.error("HttpClientAdapterServiceBypass] Connection Exception (" + vo.getAdapterGroupName() + ") : " + + ce.toString(), ce); + throw ce; + } catch (Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), e.toString(), e); + } + logger.error( + "HttpClientAdapterServiceBypass] Exception (" + vo.getAdapterGroupName() + ") : " + e.toString(), + e); + throw e; + } finally { + method.releaseConnection(); + if (status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); + if (logger.isDebug()) { + logger.debug(resMsg); + } + } + } + } + + private boolean hasBody(Object data, Properties inboundHeaders) { + if (data == null) { + return false; + } + +// // spec: RFC 2616, sec 4.3 +// String contentLength = getIgnoreCaseProp(inboundHeaders, HttpHeaders.CONTENT_LENGTH); +// String transferEncoding = getIgnoreCaseProp(inboundHeaders, HttpHeaders.TRANSFER_ENCODING); +// if (StringUtils.isNotBlank(contentLength) || StringUtils.isNotBlank(transferEncoding)) { +// return true; +// } +// return false; + + // client adapter 단독으로 사용 가능하게 수정 + return true; + } + + private HttpMethodBase generateMethod(String restMethod, String url) { + HttpMethodBase method = null; + switch (HttpMethodType.getValue(restMethod)) { + case GET: + method = new EntityEnclosingGetMethod(url); + break; + case DELETE: + method = new EntityEnclosingDeleteMethod(url); + break; + case POST: + method = new PostMethod(url); + break; + case PUT: + method = new PutMethod(url); + break; + default: + // set default method + method = new PostMethod(url); + break; + } + return method; + } + + private String getRewriteUrl(HttpClientAdapterVO vo, String inboundRewritePath, String queryString, + JSONObject restOptionObject, Map inboundPathVariables) { + String fragment = null; + if (StringUtils.isNotBlank(queryString)) { + int fragIdx = queryString.indexOf('#'); + if (fragIdx >= 0) { + fragment = queryString.substring(fragIdx + 1); + queryString = queryString.substring(0, fragIdx); + } + } + + String restExtraPath = (String) restOptionObject.get("extraPath"); + if (StringUtils.isBlank(restExtraPath)) { + StringBuilder uri = new StringBuilder(500); + uri.append(vo.getUrl()).append(inboundRewritePath); + + if (StringUtils.isNotBlank(queryString)) { + uri.append('?'); + uri.append(encodeUriQuery(queryString, false)); + } + + if (doSendUrlFragment && fragment != null) { + uri.append('#'); + uri.append(encodeUriQuery(fragment, false)); + } + + return uri.toString(); + } else { + String type = (String) restOptionObject.get("type"); + String url = getUrl(vo.getUrl(), restExtraPath); + + if (StringUtils.equalsIgnoreCase(type, HttpClientAdapterServiceRest.TYPE_VARIABLE_URL_REQUEST)) { + inboundPathVariables = mergeInboundPathVariables(inboundPathVariables, queryString); + List urlVariableValueList = new ArrayList<>(); + JSONArray uriVariables = (JSONArray) restOptionObject.get("uriVariables"); + if (uriVariables != null && !uriVariables.isEmpty() && inboundPathVariables != null + && !inboundPathVariables.isEmpty()) { + for (Object tempObject : uriVariables) { + String urlVaribleId = (String) tempObject; + String uriVariableValue = inboundPathVariables.get(urlVaribleId); + urlVariableValueList.add(uriVariableValue); + } + + if (!urlVariableValueList.isEmpty()) { + UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build(); + Object[] urls = urlVariableValueList.toArray(); + url = uriComponents.expand(urls).toUriString(); + } + } + } else { + if (StringUtils.isNotBlank(queryString)) { + url += "?" + encodeUriQuery(queryString, false); + } + + if (doSendUrlFragment && fragment != null) { + url += "#" + encodeUriQuery(fragment, false); + } + } + + return url; + } + } + + private Map mergeInboundPathVariables(Map inboundPathVariables, + String queryString) { + if (StringUtils.isBlank(queryString)) { + return inboundPathVariables; + } + + if (inboundPathVariables == null) { + inboundPathVariables = new LinkedHashMap<>(); + } + + String[] pairs = queryString.split("&"); + for (String pair : pairs) { + int idx = pair.indexOf("="); + // URLDecoder.decode 필요?? + inboundPathVariables.put(pair.substring(0, idx), pair.substring(idx + 1)); + } + + return inboundPathVariables; + } + + private String getUrl(String baseUrl, String extraPath) { + if (StringUtils.isBlank(extraPath)) { + return baseUrl; + } + + if (StringUtils.contains(extraPath, "http://") || StringUtils.contains(extraPath, "https://")) { + return extraPath; + } + + String targetUrl = baseUrl; + if (!targetUrl.endsWith("/")) { + targetUrl += "/"; + } + if (extraPath.startsWith("/")) { + targetUrl += extraPath.substring(1); + } else { + targetUrl += extraPath; + } + + return targetUrl; + } + + protected CharSequence encodeUriQuery(CharSequence in, boolean encodePercent) { + // Note that I can't simply use URI.java to encode because it will escape + // pre-existing escaped things. + StringBuilder outBuf = null; + Formatter formatter = null; + for (int i = 0; i < in.length(); i++) { + char c = in.charAt(i); + boolean escape = true; + if (c < 128) { + if (asciiQueryChars.get(c) && !(encodePercent && c == '%')) { + escape = false; + } + } else if (!Character.isISOControl(c) && !Character.isSpaceChar(c)) {// not-ascii + escape = false; + } + if (!escape) { + if (outBuf != null) + outBuf.append(c); + } else { + // escape + if (outBuf == null) { + outBuf = new StringBuilder(in.length() + 5 * 3); + outBuf.append(in, 0, i); + formatter = new Formatter(outBuf); + } + // leading %, 0 padded, width 2, capital hex + formatter.format("%%%02X", (int) c);// TODO + } + } + return outBuf != null ? outBuf : in; + } + + protected static final BitSet asciiQueryChars; + static { + char[] c_unreserved = "_-!.~'()*".toCharArray();// plus alphanum + char[] c_punct = ",;:$&+=".toCharArray(); + char[] c_reserved = "/@".toCharArray();// plus punct. Exclude '?'; RFC-2616 3.2.2. Exclude '[', ']'; + // https://www.ietf.org/rfc/rfc1738.txt, unsafe characters + asciiQueryChars = new BitSet(128); + for (char c = 'a'; c <= 'z'; c++) + asciiQueryChars.set(c); + for (char c = 'A'; c <= 'Z'; c++) + asciiQueryChars.set(c); + for (char c = '0'; c <= '9'; c++) + asciiQueryChars.set(c); + for (char c : c_unreserved) + asciiQueryChars.set(c); + for (char c : c_punct) + asciiQueryChars.set(c); + for (char c : c_reserved) + asciiQueryChars.set(c); + + asciiQueryChars.set('%');// leave existing percent escapes in place + } + + private void assignRelayDataToInbound(Properties prop, Header[] responseHeaders, int status) { + if (responseHeaders == null || responseHeaders.length == 0) { + return; + } + + Properties headerProp = new Properties(); + for (Header header : responseHeaders) { + headerProp.put(header.getName(), header.getValue()); + } + + headerProp.put(HttpAdapterServiceBypass.HTTP_STATUS, String.valueOf(status)); + + Map map = new HashMap(); + map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_HEADERS, headerProp); + + prop.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, map); + } + + private void setAuthHeaders(HttpMethodBase method, OAuth2AccessTokenVO accessToken) throws Exception { + method.setRequestHeader("Authorization", + String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); + } + + private boolean checkTokenRetry(byte[] responseMessage, String tokenErrorCodeKey, String tokenErrorCodeValues, + String encode) { + if (responseMessage == null) { + return false; + } + + if (StringUtils.isBlank(tokenErrorCodeKey)) { + return false; + } + + if (StringUtils.isBlank(tokenErrorCodeValues)) { + return false; + } + + try { + DocumentContext jsonContext = JsonPath.parse(new String(responseMessage, encode)); + String responseCode = jsonContext.read(tokenErrorCodeKey); + if (StringUtils.isBlank(responseCode)) { + return false; + } + + String[] arr = org.springframework.util.StringUtils.tokenizeToStringArray(tokenErrorCodeValues, ","); + return ArrayUtils.contains(arr, responseCode); + } catch (Exception e) { + logger.error("HttpClientAdapterServiceBypass] checkTokenRetry error=" + e.getMessage()); + } + + return false; + } + + private void assignRequestHeaders(HttpMethodBase method, Properties headerProp, Properties inProp) { + if (headerProp == null) { + return; + } + + for (Entry e : headerProp.entrySet()) { + String key = (String) e.getKey(); + String value = (String) e.getValue(); + + if (StringUtils.equalsAnyIgnoreCase(key, HttpAdapterServiceBypass.HOP_BY_HOP_HEADERS) + || StringUtils.equalsIgnoreCase(key, HttpHeaders.CONTENT_LENGTH)) { + continue; + } + + if (doHandleCompression && StringUtils.equalsIgnoreCase(key, HttpHeaders.ACCEPT_ENCODING)) { + continue; + } + + method.setRequestHeader(key, value); + + if (logger.isDebugEnabled()) { + logger.debug("Request Header :" + key + "=[" + value + "]"); + } + } + + if (doForwardIP) { + String forHeaderName = "X-Forwarded-For"; + String forHeader = inProp.getProperty(HttpAdapterServiceKey.INBOUND_REMOTE_ADDR); + if (StringUtils.isNotBlank(forHeader)) { + String existingForHeader = headerProp.getProperty(forHeaderName); + if (existingForHeader != null) { + forHeader = existingForHeader + ", " + forHeader; + } + method.setRequestHeader(forHeaderName, forHeader); + } + + String protoHeaderName = "X-Forwarded-Proto"; + String protoHeader = inProp.getProperty(HttpAdapterServiceKey.INBOUND_SCHEME); + if (StringUtils.isNotBlank(protoHeader)) { + method.setRequestHeader(protoHeaderName, protoHeader); + } + } + } + + @SuppressWarnings("deprecation") + private JSONObject parseJson(String message) throws Exception { + if (message == null) { + return null; + } + + return (JSONObject) JSONValue.parse(message); + } + + public static final String getIgnoreCaseProp(Properties prop, String key) { + if (prop == null) { + return null; + } + + for (Entry e : prop.entrySet()) { + if (StringUtils.equalsIgnoreCase(key, (String) e.getKey())) { + return (String) e.getValue(); + } + } + + return null; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceChangedate.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceChangedate.java new file mode 100644 index 0000000..c3767f6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceChangedate.java @@ -0,0 +1,157 @@ +// +//package com.eactive.eai.adapter.http.client.impl; +// +//import com.eactive.eai.adapter.http.HttpMemoryLogger; +//import com.eactive.eai.adapter.http.HttpStatusException; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.util.CommonLib; +//import org.apache.commons.httpclient.HttpClient; +//import org.apache.commons.httpclient.HttpStatus; +//import org.apache.commons.httpclient.HttpVersion; +//import org.apache.commons.httpclient.methods.PostMethod; +// +//import java.net.ConnectException; +//import java.net.SocketTimeoutException; +//import java.util.Properties; +// +// +///** +//* 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 +//* GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +//* 2. 처리 개요 : +//* * - 2009.11.24 retry 로직 제거 : 요청 +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +//* @since : +// +//*/ +//public class HttpClientAdapterServiceChangedate extends HttpClientAdapterServiceSupport{ +// +// /** +// * 1. 기능 : 전문과 같은 Raw Data 통신에 사용 +// * 2. 처리 개요 : +// * - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. +// * 3. 주의사항 +// * +// * @param prop Http Adapter 속성 정보 +// * @param message 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// public Object execute(Properties prop, byte[] data, Properties tempProp) throws Exception { +// +// HttpClientAdapterVO vo = super.setting(prop, tempProp); +// +// if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceChangedate] SEND (" + vo.getMethod() + ") "); +// } +// PostMethod method = new PostMethod(vo.getUrl()); +// if (vo.getTimeout() > -1) { +// method.getParams().setSoTimeout(vo.getTimeout()); +// } +// HttpClient mclient = this.client; +// if ( vo.getConnectionTimeout() != 0){ +// mclient.getParams().setParameter("http.connection.timeout", vo.getConnectionTimeout()); +// } +// method.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_0); +// +// // Data Size : 15 Bytes +// int popupMinSize = 15; +// +// String req = ""; +// String date = ""; +// +// if (data.length >= popupMinSize) { +// if (vo.getEncode() != null && vo.getEncode().length() > 0) { +// if (logger.isDebug()) { +// logger.debug("HttpClientAdapterServiceChangedate] ENCODE(" + vo.getEncode() + ") "); +// } +// req = new String(data, 0, 7, vo.getEncode()).trim(); +// date = new String(data, 7, 8, vo.getEncode()); +// } else { +// req = new String(data, 0, 7 ).trim(); +// date = new String(data, 7, 8 ); +// } +// method.addParameter("req", req); +// method.addParameter("date", date); +// +// } else { +// if (logger.isError()) { +// logger.error("HttpClientAdapterServiceChangedate] Invalid Data Length (" + data.length + ") < " +// + popupMinSize); +// } +// throw new Exception("HttpClientAdapterServiceChangedate Error : MessageSize(" + (data.length) +// + " Bytes) too small < " + popupMinSize); +// } +// +// int status = -1; +// +// try { +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), +// "[req]"+ req + "\n" +// + "[date]" + date + "\n" +// + "SEND ["+new String(data)+"]"+CommonLib.getDumpMessage(data) +"\n" +// ); +// } +// //mclient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); +// //mclient.getParams().setContentCharset("EUC_KR"); +// status = mclient.executeMethod(method); +// //status 200(정상) 이외에는 error 처리 +// if (status !=200){ +// try{ +// logger.error("HttpClientAdapterServiceChangedate] receive status["+status+"] data[" + new String(method.getResponseBody()) +"]"); +// }catch(Exception e){ +// logger.error(e); +// } +// throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName="+vo.getAdapterGroupName()+"."+vo.getAdapterName(),status); +// } +// byte[] responseMessage = method.getResponseBody(); +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "RECV ["+new String(responseMessage)+"]"+CommonLib.getDumpMessage(responseMessage) ); +// } +// return responseMessage; +// +// } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient// 3.1일 경우 +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceChangedate] SocketTimeoutException : " + ste.toString() ,ste); +// } +// if (logger.isError()){ +// logger.error("HttpClientAdapterServiceChangedate] SocketTimeoutException : " + ste.toString() ,ste); +// } +// throw ste; +// } catch(ConnectException ce) { +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceChangedate] Connection Exception : " + ce.toString() ,ce); +// } +// if (logger.isError()){ +// logger.error("HttpClientAdapterServiceChangedate] Connection Exception : " + ce.toString() ,ce); +// } +// throw ce; +// } catch(Exception e) { +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceChangedate] Exception : " + e.toString() ,e); +// } +// if (logger.isError()){ +// logger.error("HttpClientAdapterServiceChangedate] Exception : " + e.toString() ,e); +// } +// throw e; +// } finally { +// method.releaseConnection(); +// if (status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if (logger.isDebug()) { +// logger.debug(resMsg); +// } +// } +// } +// } +// +//} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceExtorg.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceExtorg.java new file mode 100644 index 0000000..fe797c7 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceExtorg.java @@ -0,0 +1,152 @@ +// +//package com.eactive.eai.adapter.http.client.impl; +// +//import com.eactive.eai.adapter.http.HttpMemoryLogger; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +//import com.eactive.eai.common.util.CommonLib; +// +//import java.util.Hashtable; +//import java.util.Map; +//import java.util.Properties; +// +////import k4m.eCross.client.Context; +// +// +///** +//* 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 +//* GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +//* 2. 처리 개요 : +//* * - 2009.11.24 retry 로직 제거 : 요청 +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +//* @since : +// +//*/ +//public class HttpClientAdapterServiceExtorg extends HttpClientAdapterServiceSupport{ +// +// @Override +// protected void init(){ +// ; +// } +// /** +// * 1. 기능 : 전문과 같은 Raw Data 통신에 사용 +// * 2. 처리 개요 : +// * - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. +// * 3. 주의사항 +// * +// * @param prop Http Adapter 속성 정보 +// * @param message 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// public Object execute(Properties prop, byte[] data, Properties tempProp) throws Exception +// { +// HttpClientAdapterVO vo = super.setting(prop, tempProp); +// String msgNumber = ""; +// String ReceiverID = ""; +// +// if (logger.isDebug()){ +// logger.debug("HttpClientAdapterServiceExtorg: Body Size] ["+data.length+"]"); +// } +// +// if(data.length > 23){ +// msgNumber = new String(data, 19, 4); +// if (logger.isDebug()){ +// logger.debug("HttpClientAdapterServiceExtorg: msgNumber] ["+msgNumber+"]"); +// } +// //String ReceiverID = "770000"; +// +// /* 20081124 add MP at KIBO start------------------------------------*/ +// /* ReceiverID extract Message */ +// ReceiverID = new String(data, 12, 7).trim(); +// /* 20081124 add MP at KIBO start------------------------------------*/ +// +// if (logger.isDebug()){ +// logger.debug("HttpClientAdapterServiceExtorg: ReceiverID] ["+ReceiverID+"]"); +// } +// }else{ +// logger.warn("Invalid message length - Length["+data.length+"]"); +// } +// +// +// String url = prop.getProperty(URL); +// +// //flat데이타 +// String inputLine = " "+new String(data); +// String outputString = ""; +// +// +// try +// { +// Map inputStream = new Hashtable(); +// Map outStream = new Hashtable(); +// String serviceName = "MPS.Send.FlatSender"; +// inputStream.put("MessageNumber",msgNumber); +// inputStream.put("ReceiverID",ReceiverID); +// // 트랜젝션 ID 15바이트를 처리 +// inputStream.put("FlatStream",inputLine); +// +// +// if(logger.isDebug()){ +// logger.debug( "[serviceName]"+ serviceName + "\n" +// + "[MessageNumber]" + msgNumber + "\n" +// + "[ReceiverID]" + ReceiverID + "\n" +// + "[FlatStream]" + inputLine + "\n" +// + "SEND ["+new String(data)+"]"+CommonLib.getDumpMessage(data) +"\n"); +// } +// +// try{ +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), +// "[serviceName]"+ serviceName + "\n" +// + "[MessageNumber]" + msgNumber + "\n" +// + "[ReceiverID]" + ReceiverID + "\n" +// + "[FlatStream]" + inputLine + "\n" +// + "SEND ["+new String(data)+"]"+CommonLib.getDumpMessage(data) +"\n" +// ); +// } +// //eCross Partner 주소 +//// Context ctx = new Context(url,"demo","demo"); +//// outStream = ctx.CallService(serviceName,inputStream); +// //결과전문 +// outputString = (String)outStream.get("ReplyStream"); +// +// // 트렌젝션 ID 15바이트를 처리 +// try { +// outputString = outputString.substring(15); +// }catch(Exception ex){ +// logger.warn("substring error", ex); +// } +// +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), +// "RECV ["+outputString+"]"+CommonLib.getDumpMessage(outputString.getBytes()) +"\n" +// ); +// } +// }catch(Exception ee){ +// if(logger.isError()){ +// logger.error("HttpClientAdapterServiceExtorg] Exception"+ ee.getMessage(),ee); +// } +// } +// } catch (Exception e) { +// if(logger.isError()){ +// logger.error("HttpClientAdapterServiceExtorg] Exception"+ e.getMessage(),e); +// } +// } +// +// if(logger.isDebug()){ +// logger.debug("RECV ["+outputString+"]"+CommonLib.getDumpMessage(outputString.getBytes()) +"\n"); +// } +// +// if (outputString == null){ +// throw new Exception("HttpClientAdapterServiceExtorg ] execute - input message parse fail"); +// } +// +// return outputString.getBytes(); +// } +// +//} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceGet.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceGet.java new file mode 100644 index 0000000..7af4846 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceGet.java @@ -0,0 +1,167 @@ + +package com.eactive.eai.adapter.http.client.impl; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.MessageUtil; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.HttpVersion; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; + +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.net.URLEncoder; +import java.util.Properties; + +public class HttpClientAdapterServiceGet extends HttpClientAdapterServiceSupport { + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + boolean isAsync = false; + + GetMethod method = new GetMethod(vo.getUrl()); + HttpClient mclient = this.client; + + configureHttpClient(mclient, method, vo, vo.getUrl(), vo.getContentType()); + + String sendData = ""; + if (data instanceof String) { + sendData = URLEncoder.encode((String) data, vo.getEncode()); + } else if (data instanceof byte[]) { + sendData = URLEncoder.encode(new String((byte[]) data, vo.getEncode()), vo.getEncode()); + } + StringBuilder querySb = new StringBuilder(); + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceGet] GET Method URLEncoder"); + } + + if (RESPONSE_TYPE_ASYNC.equals(vo.getResponseType())) { + isAsync = true; + querySb.append("type=async&"); + } + querySb.append(vo.getParameterName()).append("="); + querySb.append(sendData); + method.setQueryString(querySb.toString()); + + String contentTypeValue = null; + if (StringUtils.isNotEmpty(vo.getContentType())) { + if (StringUtils.isNotEmpty(vo.getEncode())) { + contentTypeValue = vo.getContentType() + "; charset=" + vo.getEncode(); + } else { + contentTypeValue = vo.getContentType(); + } + method.setRequestHeader(CONTENT_TYPE_KEY, contentTypeValue); + } + if (vo.getAdapterHeaders() != null) { + for (String key : vo.getAdapterHeaders().keySet()) { + method.addRequestHeader(key, vo.getAdapterHeaders().get(key)); + } + } + if (logger.isInfoEnabled()) { + logger.info("HttpClientAdapterServiceGet] " + CONTENT_TYPE_KEY + "(" + contentTypeValue + ")"); + } + + int status = -1; + try { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "SEND [" + sendData + "]" + CommonLib.getDumpMessage(sendData)); + } + + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + if (vo.getUrl() != null && vo.getUrl().startsWith("https")) { + Protocol.registerProtocol("https", + new Protocol("https", new CustomHttpsSocketFactory(new EasySSLProtocolSocketFactory()), 443)); + } + status = mclient.executeMethod(method); + stopWatch.stop(); + + String responseCharSet = getResponseCharSet(method.getResponseCharSet(), vo.getAdapterGroupName()); + + // status 200(정상) 이외에는 error 처리 + if (status != 200) { + try { + logger.error("HttpClientAdapterServiceGet] receive status[" + status + "] data[" + + new String(method.getResponseBody()) + "]"); + } catch (Exception e) { + logger.error(e); + } + throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName=" + + vo.getAdapterGroupName() + "." + vo.getAdapterName(), status); + } + + byte[] responseMessage = method.getResponseBody(); + if (isAsync && stopWatch.getTime() > vo.getSlowTranTime() && logger.isWarn()) { + logger.warn("HttpClientAdapterServiceGet] URL[" + vo.getUrl() + "] lazy async response time = " + + stopWatch.toString() + " responseMessage=" + new String(responseMessage, responseCharSet)); + } + + responseMessage = getEncodingConvert(responseCharSet, vo.getAdapterGroupName(), responseMessage); + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "RECV [" + new String(responseMessage, responseCharSet) + "]" + + CommonLib.getDumpMessage(responseMessage)); + } + AdapterManager m = AdapterManager.getInstance(); + AdapterGroupVO agvo = m.getAdapterGroupVO(vo.getAdapterGroupName()); + if (MessageUtil.isBytesMessage(agvo.getMessageType())) { + return responseMessage; + } else { + return new String(responseMessage, vo.getEncode()); + } + } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceGet] SocketTimeoutException : " + ste.toString(), ste); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceGet] SocketTimeoutException : " + ste.toString(), ste); + } + throw ste; + } catch (ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceGet] Connection Exception : " + ce.toString(), ce); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceGet] Connection Exception : " + ce.toString(), ce); + } + throw ce; + } catch (Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceGet] Exception : " + e.toString(), e); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceGet] Exception : " + e.toString(), e); + } + throw e; + } finally { + method.releaseConnection(); + if (status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA014", msgArgs); + if (logger.isDebug()) { + logger.debug(resMsg); + } + } + } + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceMemo.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceMemo.java new file mode 100644 index 0000000..40ec674 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceMemo.java @@ -0,0 +1,203 @@ +// +//package com.eactive.eai.adapter.http.client.impl; +// +//import com.eactive.eai.adapter.http.HttpMemoryLogger; +//import com.eactive.eai.adapter.http.HttpStatusException; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.util.CommonLib; +//import org.apache.commons.httpclient.HttpClient; +//import org.apache.commons.httpclient.HttpStatus; +//import org.apache.commons.httpclient.HttpVersion; +//import org.apache.commons.httpclient.methods.PostMethod; +// +//import java.net.ConnectException; +//import java.net.SocketTimeoutException; +//import java.util.Properties; +// +// +///** +//* 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 +//* GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +//* 2. 처리 개요 : +//* * - 2009.11.24 retry 로직 제거 : 요청 +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +//* @since : +// +//*/ +//public class HttpClientAdapterServiceMemo extends HttpClientAdapterServiceSupport{ +// +// /** +// * 1. 기능 : 전문과 같은 Raw Data 통신에 사용 +// * 2. 처리 개요 : +// * - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. +// * 3. 주의사항 +// * +// * @param prop Http Adapter 속성 정보 +// * @param message 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// public Object execute(Properties prop, byte[] data, Properties tempProp) throws Exception { +// +// HttpClientAdapterVO vo = super.setting(prop, tempProp); +// +// if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceMemo] SEND (" + vo.getMethod() + ") "); +// } +// PostMethod method = new PostMethod(vo.getUrl()); +// if (vo.getTimeout() > -1) { +// method.getParams().setSoTimeout(vo.getTimeout()); +// } +// HttpClient mclient = this.client; +// if ( vo.getConnectionTimeout() != 0){ +// mclient.getParams().setParameter("http.connection.timeout", vo.getConnectionTimeout()); +// } +// method.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_0); +// int memoMinSize = 587; +// +// String srvCode = ""; +// String serType = ""; +// String recipient = ""; +// String send = ""; +// String title = ""; +// String body = ""; +// String urgent = ""; +// String saveOption = ""; +// String rcvIp = ""; +// +// if (data.length >= memoMinSize) { +// if (vo.getEncode() != null && vo.getEncode().length() > 0) { +// if (logger.isDebug()) { +// logger.debug("HttpClientAdapterServiceMemo] ENCODE(" + vo.getEncode() + ") "); +// } +// srvCode = new String(data, 0, 6, vo.getEncode()); +// serType = new String(data, 6, 1, vo.getEncode()); +// recipient = new String(data, 7, 7, vo.getEncode()); +// send = new String(data, 14, 7, vo.getEncode()); +// title = new String(data, 21, 40, vo.getEncode()); +// body = new String(data, 61, 500, vo.getEncode()); +// urgent = new String(data, 561, 1, vo.getEncode()); +// saveOption = new String(data, 562, 1, vo.getEncode()); +// rcvIp = new String(data, 563, 24, vo.getEncode()); +// +// } else { +// srvCode = new String(data, 0, 6); +// serType = new String(data, 6, 1); +// recipient = new String(data, 7, 7); +// send = new String(data, 14, 7); +// title = new String(data, 21, 40); +// body = new String(data, 61, 500); +// urgent = new String(data, 561, 1); +// saveOption = new String(data, 562, 1); +// rcvIp = new String(data, 563, 24); +// } +// method.addParameter("SRV_CODE", srvCode ); +// method.addParameter("SER_TYPE", serType ); +// method.addParameter("RECIPIENT", recipient ); +// method.addParameter("SEND", send ); +// method.addParameter("TITLE", title ); +// method.addParameter("BODY", body ); +// method.addParameter("URGENT", urgent ); +// method.addParameter("SAVEOPTION", saveOption); +// method.addParameter("RCV_IP", rcvIp ); +// +// } else { +// if (logger.isError()) { +// logger.error("HttpClientAdapterServiceMemo] Invalid Data Length (" + data.length + ") < " +// + memoMinSize); +// } +// throw new Exception("HttpClientAdapterServiceMemo Error : MessageSize(" + (data.length) +// + " Bytes) too small < " + memoMinSize); +// } +// +// int status = -1; +// +// try { +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), +// "[SRV_CODE] "+ srvCode + "\n" +// + "[SER_TYPE] "+ serType + "\n" +// + "[RECIPIENT] "+ recipient + "\n" +// + "[SEND] "+ send + "\n" +// + "[TITLE] "+ title + "\n" +// + "[BODY] "+ body + "\n" +// + "[URGENT] "+ urgent + "\n" +// + "[SAVEOPTION] "+ saveOption + "\n" +// + "[RCV_IP] "+ rcvIp + "\n" +// + "SEND ["+new String(data)+"]"+CommonLib.getDumpMessage(data) ); +// } +// //mclient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); +// if (vo.getEncode() != null && vo.getEncode().length() > 0) { +// mclient.getParams().setContentCharset(vo.getEncode()); +// } +// else { +// // ASIS 에서 DEFAULT로 EUC_KR로 설정했음 +// mclient.getParams().setContentCharset("EUC_KR"); +// } +// +// status = mclient.executeMethod(method); +// //status 200(정상) 이외에는 error 처리 +// if (status !=200){ +// try{ +// logger.error("HttpClientAdapterServiceMemo] receive status["+status+"] data[" + new String(method.getResponseBody()) +"]"); +// }catch(Exception e){ +// logger.error(e); +// } +// throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName="+vo.getAdapterGroupName()+"."+vo.getAdapterName(),status); +// } +// byte[] responseMessage = method.getResponseBody(); +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "RECV ["+new String(responseMessage)+"]"+CommonLib.getDumpMessage(responseMessage) ); +// } +// return responseMessage; +// +// } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient +// // 3.1일 경우 +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), +// "HttpClientAdapterServiceMemo] SocketTimeoutException : " + ste.toString(), ste); +// } +// if (logger.isError()) { +// logger.error("HttpClientAdapterServiceMemo] SocketTimeoutException : " + ste.toString(), ste); +// } +// throw ste; +// } catch (ConnectException ce) { +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), +// "HttpClientAdapterServiceMemo] Connection Exception : " + ce.toString(), ce); +// } +// if (logger.isError()) { +// logger.error("HttpClientAdapterServiceMemo] Connection Exception : " + ce.toString(), ce); +// } +// throw ce; +// } catch (Exception e) { +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), +// "HttpClientAdapterServiceMemo] Exception : " + e.toString(), e); +// } +// if (logger.isError()) { +// logger.error("HttpClientAdapterServiceMemo] Exception : " + e.toString(), e); +// } +// throw e; +// } finally { +// method.releaseConnection(); +// if (status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if (logger.isDebug()) { +// logger.debug(resMsg); +// } +// } +// } +// +// } +// +// +//} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceMsa.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceMsa.java new file mode 100644 index 0000000..8dd2cdc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceMsa.java @@ -0,0 +1,227 @@ + +package com.eactive.eai.adapter.http.client.impl; + +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.util.UrlUtil; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.HttpVersion; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.Properties; + +// Msa 는 LG Micro Service Architecture F/W과 통신하기 위한 Adapter로 관련 Site 전용 +public class HttpClientAdapterServiceMsa extends HttpClientAdapterServiceSupport { + + public static String DEFAULT_ENCODE = "UTF-8"; + + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + String svcName = tempProp.getProperty(TRAN_CODE, ""); + + if (StringUtils.isEmpty(svcName)) { + throw new Exception("service name is empty"); + } + + boolean isAsync = false; + + if (vo.getUrl() == null) { + throw new Exception("URL is NULL"); + } + + if (vo.getUrl().endsWith(".ajmd") || vo.getUrl().endsWith(".axmd")) { + isAsync = true; + } + + String msaUrl = vo.getUrl().replace("%" + TRAN_CODE + "%", svcName); + + // ENVR_INFO_DVSN_CD = L + // FRST_DMND_SYS_IP_VAL 로 라우팅하도록 함 + boolean localCall = LOCAL_CALL_Y.equals(tempProp.getProperty(LOCAL_CALL, "N")); + if (localCall) { + String newIp = tempProp.getProperty(LOCAL_IP); + if (newIp == null) { + if (logger.isWarn()) { + logger.warn("HttpClientAdapterServiceMsa] LOCAL_CALL FRST_DMND_SYS_IP_VAL is empty, SKIP : " + + msaUrl); + } + } else { + String newPort = PropManager.getInstance().getProperty("LOCAL", "port", "7001"); + msaUrl = UrlUtil.replaceIpAddress(msaUrl, newIp, newPort); + if (logger.isWarn()) { + logger.warn("HttpClientAdapterServiceMsa] LOCAL_CALL REPLACED_URL : " + msaUrl); + } + } + } + + PostMethod method = new PostMethod(msaUrl); + HttpClient mclient = this.client; + + configureHttpClient(mclient, method, vo, vo.getUrl(), vo.getContentType()); + + logger.debug("HttpClientAdapterServiceMsa] ENCODE(" + vo.getEncode() + ")"); + + try { + mclient.getParams().setContentCharset(vo.getEncode()); + } catch (Exception e) { + if (logger.isError()) { + logger.error("HttpClientAdapterServiceMsa] ENCODE(" + vo.getEncode() + ") ERROR : " + e.toString()); + logger.error("HttpClientAdapterServiceMsa] ENCODE(" + vo.getEncode() + ") SKIP "); + } + } + + String contentTypeValue = null; + if (StringUtils.isNotEmpty(vo.getContentType())) { + if (StringUtils.isNotEmpty(vo.getEncode())) { + contentTypeValue = vo.getContentType() + "; charset=" + vo.getEncode(); + } else { + contentTypeValue = vo.getContentType(); + } + method.setRequestHeader(CONTENT_TYPE_KEY, contentTypeValue); + } + if (vo.getAdapterHeaders() != null) { + for (String key : vo.getAdapterHeaders().keySet()) { + method.addRequestHeader(key, vo.getAdapterHeaders().get(key)); + } + } + if (logger.isInfoEnabled()) { + logger.info("HttpClientAdapterServiceMsa] " + CONTENT_TYPE_KEY + "(" + contentTypeValue + ")"); + } + + byte[] sendBytes = null; + if (data instanceof String) { + sendBytes = ((String) data).getBytes(vo.getEncode()); + } else if (data instanceof byte[]) { + sendBytes = (byte[]) data; + } + + InputStream in = new ByteArrayInputStream(sendBytes); // "utf-8" + method.setRequestBody(in); + + int status = -1; + + try { + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceMsa] SEND (" + vo.getAdapterGroupName() + ") = [" + + new String(sendBytes, vo.getEncode()) + "]"); + logger.debug("HttpClientAdapterServiceMsa] SEND (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(sendBytes)); + } + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "SEND [" + new String(sendBytes, vo.getEncode()) + "]" + CommonLib.getDumpMessage(sendBytes)); + } + if (vo.getUrl() != null && vo.getUrl().startsWith("https")) { + Protocol.registerProtocol("https", + new Protocol("https", new CustomHttpsSocketFactory(new EasySSLProtocolSocketFactory()), 443)); + } + status = mclient.executeMethod(method); + stopWatch.stop(); + + String responseCharSet = getResponseCharSet(method.getResponseCharSet(), vo.getAdapterGroupName()); + + if (status != 200) { + try { + logger.error("HttpClientAdapterServiceMsa] receive status[" + status + "] data[" + + new String(method.getResponseBody()) + "]"); + } catch (Exception e) { + logger.error(e); + } + throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName=" + + vo.getAdapterGroupName() + "." + vo.getAdapterName(), status); + } + + // 응답으로 온 byte[]를 그대로 전달한다. + byte[] responseMessage = method.getResponseBody(); + ; + if (isAsync && stopWatch.getTime() > vo.getSlowTranTime()) { + if (logger.isWarn()) { + logger.warn("HttpClientAdapterServiceMsa] URL[" + msaUrl + "] lazy async response time = " + + stopWatch.toString() + " responseMessage=" + + new String(responseMessage, responseCharSet)); + } + } + + responseMessage = getEncodingConvert(responseCharSet, vo.getAdapterGroupName(), responseMessage); + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceMsa] responseType =" + vo.getResponseType() + + ", responseCharSet=" + responseCharSet); + logger.debug("HttpClientAdapterServiceMsa] RECV (" + vo.getAdapterGroupName() + ") = [" + + new String(responseMessage, responseCharSet) + "]"); + logger.debug("HttpClientAdapterServiceMsa] RECV (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(responseMessage)); + } + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "RECV [" + new String(responseMessage, responseCharSet) + "]" + + CommonLib.getDumpMessage(responseMessage)); + } + + return responseMessage; + } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceMsa] SocketTimeoutException : " + ste.toString() + " url=" + + msaUrl, + ste); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceMsa] SocketTimeoutException : " + ste.toString() + " url=" + + msaUrl, ste); + } + throw ste; + } catch (ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceMsa] Connection Exception : " + ce.toString() + " url=" + msaUrl, + ce); + } + if (logger.isError()) { + logger.error( + "HttpClientAdapterServiceMsa] Connection Exception : " + ce.toString() + " url=" + msaUrl, + ce); + } + throw ce; + } catch (Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceMsa] Exception : " + e.toString() + " url=" + msaUrl, e); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceMsa] Exception : " + e.toString() + " url=" + msaUrl, e); + } + throw e; + } finally { + method.releaseConnection(); + if (status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); + if (logger.isDebug()) { + logger.debug(resMsg); + } + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNexCore.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNexCore.java new file mode 100644 index 0000000..4d2dbae --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceNexCore.java @@ -0,0 +1,227 @@ + +package com.eactive.eai.adapter.http.client.impl; + +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.util.UrlUtil; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.HttpVersion; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.Properties; + +// NexCore F/W과 통신하기 위한 Adapter로 관련 Site 전용 +public class HttpClientAdapterServiceNexCore extends HttpClientAdapterServiceSupport { + + public static String DEFAULT_ENCODE = "UTF-8"; + + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + String svcName = tempProp.getProperty(TRAN_CODE, ""); + + if (StringUtils.isEmpty(svcName)) { + throw new Exception("service name is empty"); + } + + boolean isAsync = false; + + if (vo.getUrl() == null) { + throw new Exception("URL is NULL"); + } + + if (vo.getUrl().endsWith(".ajmd") || vo.getUrl().endsWith(".axmd")) { + isAsync = true; + } + + String nKesaUrl = vo.getUrl().replace("%" + TRAN_CODE + "%", svcName); + + // ENVR_INFO_DVSN_CD = L + // FRST_DMND_SYS_IP_VAL 로 라우팅하도록 함 + boolean localCall = LOCAL_CALL_Y.equals(tempProp.getProperty(LOCAL_CALL, "N")); + if (localCall) { + String newIp = tempProp.getProperty(LOCAL_IP); + if (newIp == null) { + if (logger.isWarn()) { + logger.warn("HttpClientAdapterServiceNexCore] LOCAL_CALL FRST_DMND_SYS_IP_VAL is empty, SKIP : " + + nKesaUrl); + } + } else { + String newPort = PropManager.getInstance().getProperty("LOCAL", "port", "7001"); + nKesaUrl = UrlUtil.replaceIpAddress(nKesaUrl, newIp, newPort); + if (logger.isWarn()) { + logger.warn("HttpClientAdapterServiceNexCore] LOCAL_CALL REPLACED_URL : " + nKesaUrl); + } + } + } + + PostMethod method = new PostMethod(nKesaUrl); + HttpClient mclient = this.client; + + configureHttpClient(mclient, method, vo, vo.getUrl(), vo.getContentType()); + + logger.debug("HttpClientAdapterServiceNexCore] ENCODE(" + vo.getEncode() + ")"); + + try { + mclient.getParams().setContentCharset(vo.getEncode()); + } catch (Exception e) { + if (logger.isError()) { + logger.error("HttpClientAdapterServiceNexCore] ENCODE(" + vo.getEncode() + ") ERROR : " + e.toString()); + logger.error("HttpClientAdapterServiceNexCore] ENCODE(" + vo.getEncode() + ") SKIP "); + } + } + + String contentTypeValue = null; + if (StringUtils.isNotEmpty(vo.getContentType())) { + if (StringUtils.isNotEmpty(vo.getEncode())) { + contentTypeValue = vo.getContentType() + "; charset=" + vo.getEncode(); + } else { + contentTypeValue = vo.getContentType(); + } + method.setRequestHeader(CONTENT_TYPE_KEY, contentTypeValue); + } + if (vo.getAdapterHeaders() != null) { + for (String key : vo.getAdapterHeaders().keySet()) { + method.addRequestHeader(key, vo.getAdapterHeaders().get(key)); + } + } + if (logger.isInfoEnabled()) { + logger.info("HttpClientAdapterServiceNexCore] " + CONTENT_TYPE_KEY + "(" + contentTypeValue + ")"); + } + + byte[] sendBytes = null; + if (data instanceof String) { + sendBytes = ((String) data).getBytes(vo.getEncode()); + } else if (data instanceof byte[]) { + sendBytes = (byte[]) data; + } + + InputStream in = new ByteArrayInputStream(sendBytes); // "utf-8" + method.setRequestBody(in); + + int status = -1; + + try { + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceNexCore] SEND (" + vo.getAdapterGroupName() + ") = [" + + new String(sendBytes, vo.getEncode()) + "]"); + logger.debug("HttpClientAdapterServiceNexCore] SEND (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(sendBytes)); + } + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "SEND [" + new String(sendBytes, vo.getEncode()) + "]" + CommonLib.getDumpMessage(sendBytes)); + } + if (vo.getUrl() != null && vo.getUrl().startsWith("https")) { + Protocol.registerProtocol("https", + new Protocol("https", new CustomHttpsSocketFactory(new EasySSLProtocolSocketFactory()), 443)); + } + status = mclient.executeMethod(method); + stopWatch.stop(); + + String responseCharSet = getResponseCharSet(method.getResponseCharSet(), vo.getAdapterGroupName()); + + if (status != 200) { + try { + logger.error("HttpClientAdapterServiceNexCore] receive status[" + status + "] data[" + + new String(method.getResponseBody()) + "]"); + } catch (Exception e) { + logger.error(e); + } + throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName=" + + vo.getAdapterGroupName() + "." + vo.getAdapterName(), status); + } + + // 응답으로 온 byte[]를 그대로 전달한다. + byte[] responseMessage = method.getResponseBody(); + ; + if (isAsync && stopWatch.getTime() > vo.getSlowTranTime()) { + if (logger.isWarn()) { + logger.warn("HttpClientAdapterServiceNexCore] URL[" + nKesaUrl + "] lazy async response time = " + + stopWatch.toString() + " responseMessage=" + + new String(responseMessage, responseCharSet)); + } + } + + responseMessage = getEncodingConvert(responseCharSet, vo.getAdapterGroupName(), responseMessage); + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceNexCore] responseType =" + vo.getResponseType() + + ", responseCharSet=" + responseCharSet); + logger.debug("HttpClientAdapterServiceNexCore] RECV (" + vo.getAdapterGroupName() + ") = [" + + new String(responseMessage, responseCharSet) + "]"); + logger.debug("HttpClientAdapterServiceNexCore] RECV (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(responseMessage)); + } + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "RECV [" + new String(responseMessage, responseCharSet) + "]" + + CommonLib.getDumpMessage(responseMessage)); + } + + return responseMessage; + } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceNexCore] SocketTimeoutException : " + ste.toString() + " url=" + + nKesaUrl, + ste); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceNexCore] SocketTimeoutException : " + ste.toString() + " url=" + + nKesaUrl, ste); + } + throw ste; + } catch (ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceNexCore] Connection Exception : " + ce.toString() + " url=" + nKesaUrl, + ce); + } + if (logger.isError()) { + logger.error( + "HttpClientAdapterServiceNexCore] Connection Exception : " + ce.toString() + " url=" + nKesaUrl, + ce); + } + throw ce; + } catch (Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceNexCore] Exception : " + e.toString() + " url=" + nKesaUrl, e); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceNexCore] Exception : " + e.toString() + " url=" + nKesaUrl, e); + } + throw e; + } finally { + method.releaseConnection(); + if (status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); + if (logger.isDebug()) { + logger.debug(resMsg); + } + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServicePopup.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServicePopup.java new file mode 100644 index 0000000..7c739e1 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServicePopup.java @@ -0,0 +1,169 @@ +// +//package com.eactive.eai.adapter.http.client.impl; +// +//import com.eactive.eai.adapter.http.HttpMemoryLogger; +//import com.eactive.eai.adapter.http.HttpStatusException; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.util.CommonLib; +//import org.apache.commons.httpclient.HttpClient; +//import org.apache.commons.httpclient.HttpStatus; +//import org.apache.commons.httpclient.HttpVersion; +//import org.apache.commons.httpclient.methods.PostMethod; +// +//import java.net.ConnectException; +//import java.net.SocketTimeoutException; +//import java.util.Properties; +// +// +///** +//* 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 +//* GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +//* 2. 처리 개요 : +//* * - 2009.11.24 retry 로직 제거 : 요청 +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +//* @since : +// +//*/ +//public class HttpClientAdapterServicePopup extends HttpClientAdapterServiceSupport{ +// +// /** +// * 1. 기능 : 전문과 같은 Raw Data 통신에 사용 +// * 2. 처리 개요 : +// * - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. +// * 3. 주의사항 +// * +// * @param prop Http Adapter 속성 정보 +// * @param message 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// public Object execute(Properties prop, byte[] data, Properties tempProp) throws Exception { +// +// HttpClientAdapterVO vo = super.setting(prop, tempProp); +// +// if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapter] SEND (" + vo.getMethod() + ") "); +// } +// PostMethod method = new PostMethod(vo.getUrl()); +// if (vo.getTimeout() > -1) { +// method.getParams().setSoTimeout(vo.getTimeout()); +// } +// HttpClient mclient = this.client; +// if ( vo.getConnectionTimeout() != 0){ +// mclient.getParams().setParameter("http.connection.timeout", vo.getConnectionTimeout()); +// } +// method.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_0); +// +// // Popup Data Size : 153 Bytes +// int popupMinSize = 153; +// String srvCode = ""; +// String recipient = ""; +// String title = ""; +// String body = ""; +// +// +// if (data.length >= popupMinSize) { +// if (vo.getEncode() != null && vo.getEncode().length() > 0) { +// if (logger.isDebug()) { +// logger.debug("HttpClientAdapterServicePopup] ENCODE(" + vo.getEncode() + ") "); +// } +// srvCode = new String(data, 0, 6, vo.getEncode()); +// recipient = new String(data, 6, 7, vo.getEncode()); +// title = new String(data, 13, 40, vo.getEncode()); +// body = new String(data, 53, 100, vo.getEncode()); +// } else { +// srvCode = new String(data, 0, 6); +// recipient = new String(data, 6, 7); +// title = new String(data, 13, 40); +// body = new String(data, 53, 100); +// } +// method.addParameter("SRV_CODE", srvCode); +// method.addParameter("RECIPIENT", recipient); +// method.addParameter("TITLE", title); +// method.addParameter("BODY", body); +// } else { +// if (logger.isError()) { +// logger.error("HttpClientAdapterServicePopup] Invalid Data Length (" + data.length + ") < " +// + popupMinSize); +// } +// throw new Exception("HttpClientAdapterServicePopup Error : MessageSize(" + (data.length) +// + " Bytes) too small < " + popupMinSize); +// } +// +// int status = -1; +// +// try { +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), +// "[SRV_CODE] "+ srvCode + "\n" +// + "[RECIPIENT] "+ recipient + "\n" +// + "[TITLE] "+ title + "\n" +// + "[BODY] "+ body + "\n" +// + "SEND ["+new String(data)+"]"+CommonLib.getDumpMessage(data) ); +// } +// //mclient.getHttpConnectionManager().getParams().setConnectionTimeout(30000); +// //mclient.getParams().setContentCharset("EUC_KR"); +// status = mclient.executeMethod(method); +// //status 200(정상) 이외에는 error 처리 +// if (status !=200){ +// try{ +// logger.error("HttpClientAdapterServicePopup] receive status["+status+"] data[" + new String(method.getResponseBody()) +"]"); +// }catch(Exception e){ +// logger.error(e); +// } +// throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName="+vo.getAdapterGroupName()+"."+vo.getAdapterName(),status); +// } +// byte[] responseMessage = method.getResponseBody(); +// if (vo.getTraceLevel() >= 3){ +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "RECV ["+new String(responseMessage)+"]"+CommonLib.getDumpMessage(responseMessage) ); +// } +// return responseMessage; +// +// } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), +// "HttpClientAdapterServicePopup] SocketTimeoutException : " + ste.toString(), ste); +// } +// if (logger.isError()) { +// logger.error("HttpClientAdapterServicePopup] SocketTimeoutException : " + ste.toString(), ste); +// } +// throw ste; +// } catch (ConnectException ce) { +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), +// "HttpClientAdapterServicePopup] Connection Exception : " + ce.toString(), ce); +// } +// if (logger.isError()) { +// logger.error("HttpClientAdapterServicePopup] Connection Exception : " + ce.toString(), ce); +// } +// throw ce; +// } catch (Exception e) { +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), +// "HttpClientAdapterServicePopup] Exception : " + e.toString(), e); +// } +// if (logger.isError()) { +// logger.error("HttpClientAdapterServicePopup] Exception : " + e.toString(), e); +// } +// throw e; +// } finally { +// method.releaseConnection(); +// if (status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if (logger.isDebug()) { +// logger.debug(resMsg); +// } +// } +// } +// } +// +// +//} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServicePost.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServicePost.java new file mode 100644 index 0000000..b121c63 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServicePost.java @@ -0,0 +1,224 @@ + +package com.eactive.eai.adapter.http.client.impl; + +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.Properties; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.MessageUtil; + + +/** +* 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 +* GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +* 2. 처리 개요 : +* * - 2009.11.24 retry 로직 제거 : 요청 +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +* @since : + +*/ +public class HttpClientAdapterServicePost extends HttpClientAdapterServiceSupport{ + + /** + * 1. 기능 : 전문과 같은 Raw Data 통신에 사용 + * 2. 처리 개요 : + * - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. + * 3. 주의사항 + * + * @param prop Http Adapter 속성 정보 + * @param message 송신 전문 + * @return 반환 된 byte[] Object + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception + { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + boolean isAsync = false; + + PostMethod method = new PostMethod(vo.getUrl()); + HttpClient mclient = this.client; + + configureHttpClient(mclient, method, vo, vo.getUrl(), vo.getContentType()); + + String sendData = ""; + if (data instanceof String) { + sendData = (String) data; + } else if (data instanceof byte[]) { + sendData = new String((byte[]) data, vo.getEncode()); + } + + mclient.getParams().setContentCharset(vo.getEncode()); + + if ("Y".equals(vo.getUrlEncodeYn())){ + sendData = java.net.URLEncoder.encode(sendData); + } + + if(RESPONSE_TYPE_ASYNC.equals(vo.getResponseType())) { + isAsync = true; + method.addParameter("type", "async"); + } + + method.addParameter(vo.getParameterName(), sendData); + + String contentTypeValue = null; + if(StringUtils.isNotEmpty(vo.getContentType())) { + if(StringUtils.isNotEmpty(vo.getEncode())) { + contentTypeValue = vo.getContentType() +"; charset=" + vo.getEncode(); + } + else { + contentTypeValue = vo.getContentType(); + } + method.setRequestHeader(CONTENT_TYPE_KEY, contentTypeValue); + } + if (vo.getAdapterHeaders() != null){ + for(String key : vo.getAdapterHeaders().keySet()){ + method.addRequestHeader(key, vo.getAdapterHeaders().get(key)); + } + } + if(logger.isInfoEnabled()) { + logger.info("HttpClientAdapterServicePost] "+CONTENT_TYPE_KEY+"("+contentTypeValue+")"); + } + + int status = -1; + + try { + + if(logger.isDebug() && "N".equals(vo.getTestCallYn())){ + logger.debug("HttpClientAdapterServicePost] SEND ("+vo.getAdapterGroupName()+") = ["+sendData+"]"); + logger.debug("HttpClientAdapterServicePost] SEND ("+vo.getAdapterGroupName()+") = "+CommonLib.getDumpMessage(sendData)); + } + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + if (vo.getTraceLevel() >= 3){ + HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "SEND ["+sendData+"]"+CommonLib.getDumpMessage(sendData)); + } + if (vo.getUrl() != null && vo.getUrl().startsWith("https")) { + Protocol.registerProtocol("https", + new Protocol("https", new CustomHttpsSocketFactory(new EasySSLProtocolSocketFactory()), 443)); + } + status = mclient.executeMethod(method); + + stopWatch.stop(); + + String responseCharSet = getResponseCharSet(method.getResponseCharSet(),vo.getAdapterGroupName()); + + //status 200(정상) 이외에는 error 처리 + if (status !=200){ + try{ + logger.error("HttpClientAdapterServicePost] receive status["+status+"] data[" + new String(method.getResponseBody()) +"]"); + }catch(Exception e){ + logger.error(e); + } + throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName="+vo.getAdapterGroupName()+"."+vo.getAdapterName(),status); + } + + byte[] responseMessage = method.getResponseBody(); + if (isAsync && stopWatch.getTime() > vo.getSlowTranTime()) { + if (logger.isWarn()){ + logger.warn("HttpClientAdapterServicePost] URL[" + vo.getUrl() + "] lazy response time = " + stopWatch.toString()+ " responseMessage=" + new String(responseMessage,responseCharSet)); + } + } + responseMessage = getEncodingConvert(responseCharSet, vo.getAdapterGroupName(), responseMessage); +// if(vo.getEncode() != null && vo.getEncode().length() > 0) { +// Charset res = null; +// Charset adpt = null; +// byte[] orgResponse = method.getResponseBody(); +// try{ +// res = Charset.forName(responseCharSet); +// adpt = Charset.forName(vo.getEncode()); +// if (res.compareTo(adpt)==0){ +// responseMessage = orgResponse; +// }else{ +// String encodingString = new String(orgResponse, responseCharSet); +// responseMessage = encodingString.getBytes(vo.getEncode()); +// } +// }catch(UnsupportedCharsetException e){ +// responseMessage = orgResponse; +// } +// } +// else { +// responseMessage = method.getResponseBody(); +// } + //---------------------------------------------------------- + + + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())){ + logger.debug("HttpClientAdapterServicePost] responseType ="+ vo.getResponseType()); + logger.debug("HttpClientAdapterServicePost] RECV ("+vo.getAdapterGroupName()+") = ["+new String(responseMessage,responseCharSet)+"]"); + logger.debug("HttpClientAdapterServicePost] RECV ("+vo.getAdapterGroupName()+") = "+CommonLib.getDumpMessage(responseMessage)); + } + + if (vo.getTraceLevel() >= 3){ + HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "RECV ["+new String(responseMessage,responseCharSet)+"]"+CommonLib.getDumpMessage(responseMessage)); + } + + AdapterManager m = AdapterManager.getInstance(); + AdapterGroupVO agvo= m.getAdapterGroupVO(vo.getAdapterGroupName()); + if (MessageUtil.isBytesMessage(agvo.getMessageType())) { + return responseMessage; + } else { + return new String(responseMessage, vo.getEncode()); + } + } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3){ + HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServicePost] SocketTimeoutException : " + ste.toString() ,ste); + } + if (logger.isError()){ + logger.error("HttpClientAdapterServicePost] SocketTimeoutException : " + ste.toString() ,ste); + } + throw ste; + } catch(ConnectException ce) { + if (vo.getTraceLevel() >= 3){ + HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServicePost] Connection Exception : " + ce.toString() ,ce); + } + if (logger.isError()){ + logger.error("HttpClientAdapterServicePost] Connection Exception : " + ce.toString() ,ce); + } + throw ce; + } catch(Exception e) { + if (vo.getTraceLevel() >= 3){ + HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServicePost] Exception : " + e.toString() ,e); + } + if (logger.isError()){ + logger.error("HttpClientAdapterServicePost] Exception : " + e.toString() ,e); + } + throw e; + } finally { + method.releaseConnection(); + if(status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); + if(logger.isDebug()){ + logger.debug(resMsg); + } + } + } + + } + + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceRest.java new file mode 100644 index 0000000..27cd348 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceRest.java @@ -0,0 +1,829 @@ +package com.eactive.eai.adapter.http.client.impl; + +import java.io.StringReader; +import java.math.BigDecimal; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.httpclient.Header; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpMethodBase; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.DeleteMethod; +import org.apache.commons.httpclient.methods.EntityEnclosingMethod; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.dom4j.Document; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpMethodType; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.CommonLib; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import com.openbanking.eai.common.token.AccessTokenManager; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; + +/** + * 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 + * 기능을 제공한다.
+ * 2. 처리 개요 :
+ * * - 2020-09-25: Http Header 받아서 처리할 수 있게 기능 추가
+ * 3. 주의사항
+ * + * @author : + * @version : v 1.0.0 + * @see : HttpClientAdapterServiceFactory.java, + * HttpClientAdapterServiceSupport.java + * @since : + * + */ +public class HttpClientAdapterServiceRest extends HttpClientAdapterServiceSupport + implements HttpClientAdapterServiceKey { + public static final String TYPE_VARIABLE_URL_REQUEST = "variableUrlRequest"; + public static final String TYPE_SIMPLE_REQUEST = "simpleRequest"; + + public static final String REST_OPTION = "REST_OPTION"; + + ////public static final String HEADER_CONTENT_TYPE = "Content-Type"; + public static final String HEADER_GROUP = "HEADER_GROUP"; + public static final String HTTP_STATUS = "HTTP_STATUS"; + public static final String HEADER_KEYS = "HEADER_KEYS"; + + /** + * 1. 기능 : REST API 통신에 사용
+ * 2. 처리 개요 : - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다.
+ * 3. 주의사항
+ * + * @param prop Http Adapter 속성 정보 + * @param message 송신 전문(JSON) + * @return 반환 된 Object + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + @SuppressWarnings({ "unchecked" }) + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + + String headerGroupName = prop.getProperty(HEADER_GROUP); + String relayResponseHeaderKeys = prop.getProperty(HEADER_KEYS, ""); + boolean useAdapterToken = StringUtils.equalsIgnoreCase(prop.getProperty("ADAPTER_TOKEN_USE_YN", "N"), "Y"); + + // ex) $.dataHeader.GW_RSLT_CD + String tokenErrorCodeKey = prop.getProperty("ADAPTER_TOKEN_ERROR_CODE_KEY"); + String tokenErrorCodeValues = prop.getProperty("ADAPTER_TOKEN_ERROR_CODE_VALUES"); + String tokenErrorHttpStatusCode = prop.getProperty("ADAPTER_TOKEN_ERROR_HTTP_STATUS_CODE"); // 200 or 400번대 + + // 레이아웃 메시지 타입 REST URL 추출 시 활용. Default JSON + String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); + String inboundMethod = tempProp.getProperty(HttpAdapterServiceKey.INBOUND_METHOD, "POST"); + + /** + * @formatter:off + * TSEAIHE02.RESTOPTION 정보 => JSON 형태로 구성 + * - type : simpleRequest, variableUrlRequest + * - extraPath : 어댑터 프로퍼티 URL에 추가될 HTTP REST URL + * - method : get, delete, post, put + * - contentType: application/json(default), application/x-www-form-urlencoded + * - adapterTokenUseYn: Y, N(default) + * ex) + * {"type":"simpleRequest","extraPath":"v2.0/accout/balance","method":"post"} + * @formatter:on + */ + + String restOptionData = tempProp.getProperty(REST_OPTION); + + JSONObject restOptionObject = parseJson(restOptionData); + if (restOptionObject == null) { + throw new Exception("OptionData parsing result is NULL"); + } + + String rmethod = (String) restOptionObject.getOrDefault("method", inboundMethod); + String contentType = (String) restOptionObject.getOrDefault("contentType", "application/json"); + String adapterTokenUseYn = (String) restOptionObject.get("adapterTokenUseYn"); + if (StringUtils.isNotBlank(adapterTokenUseYn)) { // interface 에 설정된게 우선한다. + useAdapterToken = StringUtils.equalsIgnoreCase(adapterTokenUseYn, "Y"); + } + + HttpClient mclient = this.client; + String sendData = ""; + if (data instanceof String) { + sendData = (String) data; + } else if (data instanceof byte[]) { + sendData = new String((byte[]) data, vo.getEncode()); + } + + ////mclient.getParams().setContentCharset(vo.getEncode()); + + JSONObject dataObject = null; + Object httpHeader = null; + if (MessageType.JSON.equals(messageType)) { + dataObject = parseJson(sendData); + if (dataObject != null && StringUtils.isNotBlank(headerGroupName)) { + httpHeader = dataObject.get(headerGroupName); + dataObject.remove(headerGroupName); + } + } + + logger.debug("HttpClientAdapterServiceRest] dataObject1 = [" + dataObject + "]"); + + // interface 에 설정된게 우선한다. + String uri = null; + if (dataObject == null) { + uri = changeUrl(messageType, vo.getUrl(), restOptionData, sendData); + } else { + uri = changeUrl(messageType, vo.getUrl(), restOptionData, dataObject); + } + + logger.debug("HttpClientAdapterServiceRest] dataObject2 = [" + dataObject + "]"); + +// ////if (vo.getConnectionTimeout() != 0) { +// mclient.getHttpConnectionManager().getParams().setConnectionTimeout(vo.getConnectionTimeout()); +// } + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug( + "HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") URL=[" + vo.getUrl() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") PARAMETER_NAME=[" + + vo.getParameterName() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") ENCODE=[" + + vo.getEncode() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") RESPONSE_TYPE=[" + + vo.getResponseType() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") URL_ENCODE_YN=[" + + vo.getUrlEncodeYn() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") CONNECTION_TIMEOUT=[" + + vo.getConnectionTimeout() + "] "); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") REST_OPTION=[" + + restOptionData + "] "); + } + + HttpMethodBase method = null; + switch (HttpMethodType.getValue(rmethod)) { + case GET: + method = new GetMethod(uri); + break; + case DELETE: + method = new DeleteMethod(uri); + break; + case POST: + method = new PostMethod(uri); + break; + case PUT: + method = new PutMethod(uri); + break; + default: + // set default method + method = new GetMethod(uri); + break; + } + + configureHttpClient(mclient, method, vo, uri, contentType); + + switch (HttpMethodType.getValue(rmethod)) { + case GET: + case DELETE: + HashMap h = getParameters(dataObject); + NameValuePair[] params = new NameValuePair[h.size()]; + int count = 0; + for (String key : h.keySet()) { + String value = h.get(key); + params[count] = new NameValuePair(key, value); + count++; + } + method.setQueryString(params); + if (logger.isDebug()) { + logger.debug( + "HttpClientAdapterServiceRest] (get Method) QueryString = [" + method.getQueryString() + "]"); + } + + break; + case PUT: + case POST: + assignPostBody(dataObject, contentType, method); + break; + default: + break; + } + + if (logger.isDebugEnabled()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") method.getParams()=[" + + method.getParams().toString() + "] "); + } + + OAuth2AccessTokenVO accessToken = null; + if (useAdapterToken) { + AccessTokenManager tokenManager = AccessTokenManager.getInstance(); + accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); + + // 토큰이 없거나 만료 됐으면 재발급 + if (accessToken == null || accessToken.isExpired()) { + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, + oldToken); + } + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") TOKEN = [" + + accessToken + "]"); + } + + setAuthHeaders(method, accessToken); + + if (logger.isDebug()) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + + ") RequestHeader [Authorization=" + method.getRequestHeader("Authorization") + "]"); + } + } + + // 전달 header 셋팅 + // Adapter 레벨 header 보다 data로 넘어온 httpHeader를 우선 적용(header명이 같다면 덮어씀) + assignRequestHeaders(method, httpHeader); + + int status = -1; + + try { + byte[] responseMessage = null; + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + if (dataObject != null) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = [" + + dataObject.toJSONString() + "]"); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(dataObject.toJSONString())); + } else { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = [" + sendData + + "]"); + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(sendData)); + } + } + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "SEND [" + sendData + "]" + CommonLib.getDumpMessage(sendData)); + } + try { + if (logger.isDebug()) { + logger.debug("[method getName]" + method.getName()); + logger.debug("[method getRequestCharSet]" + method.getRequestCharSet()); + logger.debug("[method getRequestHeaders]" + method.getRequestHeaders().toString()); + logger.debug("[method getQueryString]" + method.getQueryString()); + logger.debug("[method getParams]" + method.getParams().toString()); + logger.debug("[method getURI]" + method.getURI()); + } + status = mclient.executeMethod(method); + if (logger.isDebug()) { + logger.debug("[received status]" + status); + } + } catch (ConnectException e) { + responseMessage = method.getResponseBody(); + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] responseType =" + vo.getResponseType()); + logger.debug("HttpClientAdapterServiceRest] RECV (" + vo.getAdapterGroupName() + ") = [" + + new String(responseMessage, vo.getEncode()) + "]"); + logger.debug("HttpClientAdapterServiceRest] RECV (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(responseMessage)); + } + throw new Exception("excuteMethod java.net.ConnectException = " + e.getMessage()); + } + + stopWatch.stop(); + + /** + * @formatter:off + * OAuth 토큰 응답 체크(Adapter properties로 설정) + * 응답코드에 따라 유효한 토큰 확인(토큰 재발급 여부 확인) + * API 서비스 마다 정책이 다름(보통 400대에서 체크하나 200에서도 체크할 수 있음) + * + * TOKEN_ERROR_CODE_KEY: 응답 json error code key + * __ex) $.dataHeader.resultCode + * TOKEN_ERROR_CODE_VALUES: 토큰 재발급이 필요한 응답 error codes(ex: O0001,O0002,O0003) + * TOKEN_ERROR_HTTP_STATUS_CODE: 보통 400대에서 체크하나 API 제공자에 따라 200에서도 체클할수 있음 + * ex) TOKEN_ERROR_HTTP_STATUS_CODE = 200 + * @formatter:on + */ + boolean needReissue = false; + + if (status == 200) { + responseMessage = method.getResponseBody(); + if (useAdapterToken && StringUtils.equals(tokenErrorHttpStatusCode, "200")) { + needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, + vo.getEncode()); + } + } else if (status == 302) { + responseMessage = method.getResponseBody(); + if (!StringUtils.contains(relayResponseHeaderKeys, "Location")) { + relayResponseHeaderKeys += ",Location"; + } + } else if (status >= 400 && status < 500) { + responseMessage = method.getResponseBody(); + if (useAdapterToken) { + needReissue = checkTokenRetry(responseMessage, tokenErrorCodeKey, tokenErrorCodeValues, + vo.getEncode()); + } + + if (!needReissue) { + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), uri, rmethod, responseMessage); + throw new Exception(errMsg); + } + } else { + responseMessage = method.getResponseBody(); + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), uri, rmethod, responseMessage); + throw new Exception(errMsg); + } + + // ---------------------------------------------------------- + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] responseType =" + vo.getResponseType()); + logger.debug("HttpClientAdapterServiceRest] RECV " + vo.getEncode() + "(" + vo.getAdapterGroupName() + + ") = [" + new String(responseMessage, vo.getEncode()) + "]"); + logger.debug("HttpClientAdapterServiceRest] RECV MS949 (" + vo.getAdapterGroupName() + ") = [" + + new String(responseMessage, "MS949") + "]"); + logger.debug("HttpClientAdapterServiceRest] RECV euc-kr (" + vo.getAdapterGroupName() + ") = [" + + new String(responseMessage, "euc-kr") + "]"); + logger.debug("HttpClientAdapterServiceRest] RECV (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(responseMessage)); + } + + if (useAdapterToken) { + if (responseMessage == null) { + throw new Exception("responseMessage is NULL, HttpStatus=" + status); + } + + // OAuth 토큰 재요청 코드 확인 + if (needReissue) { + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] retry access token response code = [" + + vo.getResponseType() + "] message = [" + new String(responseMessage, vo.getEncode()) + + "]"); + } + + // 토큰 재발급 + AccessTokenManager tokenManager = AccessTokenManager.getInstance(); + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + OAuth2AccessTokenVO newaccessToken = (OAuth2AccessTokenVO) tokenManager + .retryAccessTokenVO(vo.getAdapterGroupName(), prop, oldToken); + method.setRequestHeader("Authorization", newaccessToken.getAuthorization()); + + setAuthHeaders(method, newaccessToken); + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] SEND (" + vo.getAdapterGroupName() + + ") RETRY TOKEN = [" + newaccessToken + "]"); + } + + try { + status = mclient.executeMethod(method); + } catch (ConnectException e) { + throw new Exception("retry excuteMethod Exceptioin = " + e.getMessage()); + } + + if (status == 200) { + responseMessage = method.getResponseBody(); + } else if (status == 302) { + responseMessage = method.getResponseBody(); + if (!StringUtils.contains(relayResponseHeaderKeys, "Location")) { + relayResponseHeaderKeys += ",Location"; + } + } else { + responseMessage = method.getResponseBody(); + String errMsg = String.format( + "http receive status fail value=%d adapterName=%s.%s uri=%s method=%s response Data=%s", + status, vo.getAdapterGroupName(), vo.getAdapterName(), uri, rmethod, responseMessage); + throw new Exception(errMsg); + } + + // ---------------------------------------------------------- + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRest] RETRY responseType =" + vo.getResponseType()); + logger.debug("HttpClientAdapterServiceRest] RETRY RECV " + vo.getEncode() + "(" + + vo.getAdapterGroupName() + ") = [" + new String(responseMessage, vo.getEncode()) + + "]"); + logger.debug("HttpClientAdapterServiceRest] RETRY RECV (" + vo.getAdapterGroupName() + ") = " + + CommonLib.getDumpMessage(responseMessage)); + } + // ---------------------------------------------------------- + } + } + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName() + vo.getAdapterName(), + "RECV [" + new String(responseMessage, vo.getEncode()) + "]" + + CommonLib.getDumpMessage(responseMessage)); + } + + assignRelayDataToInbound(tempProp, method.getResponseHeaders()); + + return assignResponseHeaders(method, responseMessage, headerGroupName, vo.getEncode(), messageType, + relayResponseHeaderKeys, status); + } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceRest] SocketTimeoutException (" + vo.getAdapterGroupName() + ") : " + + ste.toString(), + ste); + } + logger.error("HttpClientAdapterServiceRest] SocketTimeoutException (" + vo.getAdapterGroupName() + ") : " + + ste.toString(), ste); + throw ste; + } catch (ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceRest] Connection Exception (" + vo.getAdapterGroupName() + ") : " + + ce.toString(), + ce); + } + logger.error("HttpClientAdapterServiceRest] Connection Exception (" + vo.getAdapterGroupName() + ") : " + + ce.toString(), ce); + throw ce; + } catch (Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), e.toString(), e); + } + logger.error("HttpClientAdapterServiceRest] Exception (" + vo.getAdapterGroupName() + ") : " + e.toString(), + e); + throw e; + } finally { + method.releaseConnection(); + if (status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); + if (logger.isDebug()) { + logger.debug(resMsg); + } + } + } + } + + private void assignRelayDataToInbound(Properties prop, Header[] responseHeaders) { + if (responseHeaders == null || responseHeaders.length == 0) { + return; + } + + Properties headerProp = new Properties(); + for (Header header : responseHeaders) { + headerProp.put(header.getName(), header.getValue()); + } + + Map map = new HashMap(); + map.put(HttpAdapterServiceKey.OUTBOUND_RESPONSE_HEADERS, headerProp); + + prop.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, map); + } + + /** + * 현재 1단계 레이아웃에만 적용되도록 구현됨. + * + * @param method + * @param responseMessage + * @param headerGroupName + * @param encode + * @param messageType + * @param relayHeaderKeys + * @return + * @throws Exception + */ + @SuppressWarnings("unchecked") + private String assignResponseHeaders(HttpMethodBase method, byte[] responseMessage, String headerGroupName, + String encode, String messageType, String relayHeaderKeys, int status) throws Exception { + if (!MessageType.JSON.equals(messageType) || StringUtils.isBlank(headerGroupName) + || StringUtils.isBlank(relayHeaderKeys)) { + return new String(responseMessage, encode); + } + + String[] relayKeyArr = org.springframework.util.StringUtils.tokenizeToStringArray(relayHeaderKeys, ","); + JSONObject headerJson = new JSONObject(); + for (String key : relayKeyArr) { + Header header = method.getResponseHeader(key); + if (header != null) { + headerJson.put(header.getName(), header.getValue()); + } + } + + headerJson.put(HTTP_STATUS, String.valueOf(status)); + + if (headerJson.size() <= 0) { + return new String(responseMessage, encode); + } + + JSONObject message = null; + if (responseMessage == null || responseMessage.length == 0) { + message = new JSONObject(); + } else { + message = parseJson(new String(responseMessage, encode)); + if (message == null) { + message = new JSONObject(); + message.put("Malformed_Response_Message", new String(responseMessage, encode)); + } + } + + if (StringUtils.isNotBlank(headerGroupName) && message != null) + message.put(headerGroupName, headerJson); + return message.toJSONString(); + } + + private void setAuthHeaders(HttpMethodBase method, OAuth2AccessTokenVO accessToken) throws Exception { + method.setRequestHeader("Authorization", + String.format("%s %s", AccessTokenVO.BEARER_TYPE, accessToken.getAccessToken())); + } + + private boolean checkTokenRetry(byte[] responseMessage, String tokenErrorCodeKey, String tokenErrorCodeValues, + String encode) { + if (responseMessage == null) { + return false; + } + + if (StringUtils.isBlank(tokenErrorCodeKey)) { + return false; + } + + if (StringUtils.isBlank(tokenErrorCodeValues)) { + return false; + } + + try { + DocumentContext jsonContext = JsonPath.parse(new String(responseMessage, encode)); + String responseCode = jsonContext.read(tokenErrorCodeKey); + if (StringUtils.isBlank(responseCode)) { + return false; + } + + String[] arr = org.springframework.util.StringUtils.tokenizeToStringArray(tokenErrorCodeValues, ","); + return ArrayUtils.contains(arr, responseCode); + } catch (Exception e) { + logger.error("HttpClientAdapterServiceRest] checkTokenRetry error=" + e.getMessage()); + } + + return false; + } + + private void assignRequestHeaders(HttpMethodBase method, Object httpHeader) { + if (httpHeader == null) { + return; + } + + if (httpHeader instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) httpHeader; + for (Object key : jsonObject.keySet()) { + Object obj = jsonObject.get(key); + if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { + continue; + } + + method.setRequestHeader((String) key, (String) obj); + + if (logger.isDebugEnabled()) { + logger.debug("Request Header :" + (String) key + "=[" + (String) obj + "]"); + } + + } + } + } + + @SuppressWarnings("deprecation") + private void assignPostBody(Object eaiBody, String contentType, HttpMethodBase method) { + if (eaiBody == null) { + return; + } + + if (StringUtils.contains(contentType, "application/x-www-form-urlencoded")) { + handleJsonValue("", eaiBody, method); + } else { + ((EntityEnclosingMethod) method).setRequestBody(eaiBody.toString()); + } + } + + @SuppressWarnings("deprecation") + private void handleJsonValue(String keyPath, Object value, HttpMethodBase method) { + if (value == null) { + return; + } + + if (value instanceof JSONObject) { + handleJsonObject(keyPath, (JSONObject) value, method); + } else if (value instanceof JSONArray) { + handleJsonArray(keyPath, (JSONArray) value, method); + } else { + String valueStr = String.valueOf(value); + if (StringUtils.isBlank(keyPath)) { + ((EntityEnclosingMethod) method).setRequestBody(valueStr); + } else { + if (keyPath.endsWith("]")) { + ((PostMethod) method).addParameter(keyPath, valueStr); + } else { + ((PostMethod) method).setParameter(keyPath, valueStr); + } + } + logger.debug(keyPath + "=" + valueStr); + } + } + + /** + * req_list[0].tran_no=12345
+ * req_list[0].org_tran_amt=12000
+ * req_list[1].tran_no=12445
+ * req_list[1].org_tran_amt=11000 + */ + private void handleJsonArray(String keyPath, JSONArray jsonArray, HttpMethodBase method) { + for (int i = 0; i < jsonArray.size(); i++) { + Object object = jsonArray.get(i); + String newKeyPath = null; + if (StringUtils.isBlank(keyPath)) { + newKeyPath = "NA[" + i + "]"; + } else { + newKeyPath = keyPath + "[" + i + "]"; + } + handleJsonValue(newKeyPath, object, method); + } + } + + /** + * obj.aaa=111
+ * obj.bbb=222
+ */ + private void handleJsonObject(String keyPath, JSONObject jsonObject, HttpMethodBase method) { + for (Object key : jsonObject.keySet()) { + Object object = jsonObject.get(key); + String newKeyPath = StringUtils.isBlank(keyPath) ? "" : keyPath + "."; + newKeyPath += key; + handleJsonValue(newKeyPath, object, method); + } + } + + private HashMap getParameters(Object message) throws Exception { + + HashMap result = new HashMap(); + + if (message != null) { + if (message instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) message; + for (Object key : jsonObject.keySet()) { + Object obj = jsonObject.get(key); + if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { + continue; + } + result.put((String) key, getStringValue(obj)); + } + } else { + String[] messages = ((String) message).split("&"); + String[] data = null; + + for (int i = 0; i < messages.length; i++) { + data = messages[i].split("=", 2); + if (data.length == 2) { + result.put(data[0], data[1]); + } + } + } + } + + return result; + } + + public String getStringValue(Object obj) { + if (obj == null) { + return null; + } + + if (obj instanceof String) { + return (String) obj; + } else if (obj instanceof Long) { + return Long.toString((Long) obj); + } else if (obj instanceof BigDecimal) { + return ((BigDecimal) obj).toPlainString(); + } else { + return (String) obj; + } + } + + @SuppressWarnings("deprecation") + private JSONObject parseJson(String message) throws Exception { + if (message == null) { + return null; + } + + return (JSONObject) JSONValue.parse(message); + } + + private Document convertXmlDocument(String message) throws Exception { + SAXReader builder = new SAXReader(); + Document document = builder.read(new StringReader(message)); + return document; + } + + @SuppressWarnings("deprecation") + private String changeUrl(String messageType, String url, String restOption, Object sendData) { + if ((MessageType.JSON.equals(messageType) || MessageType.XML.equals(messageType))) { + try { + if (StringUtils.isBlank(restOption)) { + return url; + } + List urlVariableList = new ArrayList(); + JSONObject restOptionObject = parseJson(restOption); + + if (restOptionObject == null) + throw new Exception("restOption is NULL"); + + String type = (String) restOptionObject.get("type"); + String requestExtraPath = (String) restOptionObject.get("extraPath"); + url = getUrl(url, requestExtraPath); + if (TYPE_VARIABLE_URL_REQUEST.equals(type)) { + JSONArray uriVariables = (JSONArray) restOptionObject.get("uriVariables"); + if (MessageType.JSON.equals(messageType)) { + JSONObject jsonObject; + if (sendData instanceof JSONObject) { + jsonObject = (JSONObject) sendData; + } else { + jsonObject = (JSONObject) JSONValue.parse((String) sendData); + } + for (Object tempObject : uriVariables) { + String urlVaribleId = (String) tempObject; + String uriVariable = (String) jsonObject.get(urlVaribleId); + urlVariableList.add(uriVariable); + jsonObject.remove(urlVaribleId); + } + } else if (MessageType.XML.equals(messageType)) { + Document doc; + if (sendData instanceof Document) { + doc = (Document) sendData; + } else { + doc = convertXmlDocument((String) sendData); + } + for (Object tempObject : uriVariables) { + String urlVaribleId = (String) tempObject; + Element element = (Element) doc.selectSingleNode("//" + urlVaribleId); + urlVariableList.add(element.getText()); + if (doc.getRootElement() == element) { + doc = null; + } else { + element.getParent().remove(element); + } + } + } + if (urlVariableList.size() > 0) { + UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).build(); + Object[] urls = urlVariableList.toArray(); + url = uriComponents.expand(urls).toUriString(); + logger.debug("HttpClientAdapterServiceRest] after extand url=[" + url + "] "); + } + } + } catch (Exception e) { + logger.error("Failed to change url", e); + } + } + return url; + } + + private String getUrl(String baseUrl, String extraPath) { + if (StringUtils.isBlank(extraPath)) { + return baseUrl; + } + + if (StringUtils.contains(extraPath, "http://") || StringUtils.contains(extraPath, "https://")) { + return extraPath; + } + + String targetUrl = baseUrl; + if (!targetUrl.endsWith("/")) { + targetUrl += "/"; + } + if (extraPath.startsWith("/")) { + targetUrl += extraPath.substring(1); + } else { + targetUrl += extraPath; + } + + logger.debug("HttpClientAdapterServiceRest] after concatenate url=[" + targetUrl + "] "); + return targetUrl; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceRestForCODEF.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceRestForCODEF.java new file mode 100644 index 0000000..f7fdc09 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceRestForCODEF.java @@ -0,0 +1,546 @@ +// +//package com.eactive.eai.adapter.http.client.impl; +// +//import java.io.StringReader; +//import java.net.ConnectException; +//import java.net.SocketTimeoutException; +//import java.net.URLDecoder; +//import java.net.URLEncoder; +//import java.util.Arrays; +//import java.util.HashMap; +//import java.util.List; +//import java.util.Map; +//import java.util.Properties; +// +//import org.apache.commons.httpclient.HttpClient; +//import org.apache.commons.httpclient.HttpMethodBase; +//import org.apache.commons.httpclient.HttpStatus; +//import org.apache.commons.httpclient.HttpVersion; +//import org.apache.commons.httpclient.NameValuePair; +//import org.apache.commons.httpclient.methods.DeleteMethod; +//import org.apache.commons.httpclient.methods.EntityEnclosingMethod; +//import org.apache.commons.httpclient.methods.GetMethod; +//import org.apache.commons.httpclient.methods.PostMethod; +//import org.apache.commons.httpclient.methods.PutMethod; +//import org.apache.commons.httpclient.protocol.Protocol; +//import org.apache.commons.lang.StringUtils; +//import org.apache.commons.lang.time.StopWatch; +//import org.dom4j.Document; +//import org.dom4j.Element; +//import org.dom4j.io.SAXReader; +//import org.json.simple.JSONObject; +//import org.json.simple.JSONValue; +//import org.springframework.web.util.UriComponents; +//import org.springframework.web.util.UriComponentsBuilder; +// +//import com.eactive.eai.adapter.http.HttpMemoryLogger; +//import com.eactive.eai.adapter.http.HttpMethodType; +//import com.eactive.eai.adapter.http.HttpStatusException; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +//import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +//import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +//import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.message.MessageType; +//import com.eactive.eai.common.util.CommonLib; +//import com.openbanking.eai.common.token.AccessTokenManager; +//import com.openbanking.eai.common.token.OAuth2AccessTokenVO; +// +// +///** +//* 1. 기능 : EAI HTTP OutBound 용 어댑터로 수동 시스템의 HTTP 웹 컴포넌트를 +//* GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +//* 2. 처리 개요 : +//* * - 2009.11.24 retry 로직 제거 : 요청 +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : +//* @since : +// +//*/ +//public class HttpClientAdapterServiceRestForCODEF extends HttpClientAdapterServiceSupport implements HttpClientAdapterServiceKey { +// +// public static final String TYPE_VARIABLE_URL_REQUEST = "variableUrlRequest"; +// public static final String TYPE_SIMPLE_REQUEST = "simpleRequest"; +// +// public static final String HTTP_HEADER = "HTTP_HEADER"; +// public static final String EAI_HEADER = "EAI_HEADER"; +// public static final String EAI_BODY = "EAI_BODY"; +// +// public static final String REST_OPTION = "REST_OPTION"; +// public static final String REST_TYPE = "type"; +// public static final String REST_EXTRA_PATH = "extraPath"; +// public static final String REST_METHOD = "method"; +// +// public static final String HEADER_CONTENT_TYPE = "Content-Type"; +// public static final String HEADER_ACEPT = "Acept"; +// +// public static final List RETRY_RESPONSE_CODE = Arrays.asList("invalid_token"); +// +// /** +// * 1. 기능 : 전문과 같은 Raw Data 통신에 사용 +// * 2. 처리 개요 : +// * - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. +// * 3. 주의사항 +// * +// * @param prop Http Adapter 속성 정보 +// * @param message 송신 전문 +// * @return 반환 된 byte[] Object +// * @exception Exception 수동 시스템 간 통신 중 발생 +// **/ +// public Object execute(Properties prop, byte[] data, Properties tempProp) throws Exception { +// HttpClientAdapterVO vo = super.setting(prop, tempProp); +// +// // 레이아웃 메세지 타입 REST URL 추출 시 활용. Default JSON +// String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); +// /* TSEAIHE02.RESTOPTION 정보 -> JSON 형태로 구성 +// * type : simpleRequest, variableUrlRequest +// * extraPath : 어댑터 프로퍼티 URL에 추가될 HTTP REST URL +// * method : get, delete, post, put +// * +// * ex) {"type":"simpleRequest", "extraPath":"v2.0/account/balance", "method": "post"} +// */ +//// String restOptionData = tempProp.getProperty(REST_OPTION); +// String restOptionData = prop.getProperty(REST_OPTION); +// +// JSONObject restOptionObject = parseJson(restOptionData); +// if(restOptionObject == null) { +// throw new Exception("OptionData parsing result is NULL"); +// } +// String rmethod = restOptionObject.containsKey("method") +// ? StringUtils.upperCase((String) restOptionObject.get("method")) +// : "POST"; +// +// String sendData = new String(data); +// Object eaiHeader = null; +// Object eaiBody = null; +// HttpClient mclient = this.client; +// +// HashMap header = new HashMap(); +//// for(Object obj : headerObject.keySet()){ +//// String key = (String)obj; +//// header.put(key, (String)headerObject.get(key)); +//// } +// //interface 에 설정된게 우선한다. +// String uri = changeUrl(messageType, vo.getUrl(), restOptionData, sendData); +// +// HttpMethodBase method = null; +// switch (HttpMethodType.getValue(rmethod)) { +// case GET : +// method = new GetMethod(uri); +// break; +// case DELETE : +// method = new DeleteMethod(uri); +// break; +// case POST : +// method = new PostMethod(uri); +// break; +// case PUT : +// method = new PutMethod(uri); +// break; +// default : +// // set default method +// method = new GetMethod(uri); +// break; +// } +// +// //2008.02.15 : Timeout 처리로직 변경 (0 : 무한대 설정가능하게 함) +// if(vo.getTimeout() > -1) { +// method.getParams().setSoTimeout(vo.getTimeout()); +// } +// +// if ( vo.getConnectionTimeout() != 0) { +// method.getParams().setParameter("http.connection.timeout", vo.getConnectionTimeout()); +// } +// method.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_0); +// +// if(uri != null && uri.startsWith("https")){ +// Protocol.registerProtocol("https", new Protocol("https", +// new CustomHttpsSocketFactory(new EasySSLProtocolSocketFactory()), 443)); +// } +// +// if (logger.isDebug()&& "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName() +") URL=["+vo.getUrl()+"] "); +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName() +") PARAMETER_NAME=["+vo.getParameterName()+"] "); +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName() +") ENCODE=["+vo.getEncode()+"] "); +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName() +") RESPONSE_TYPE=["+vo.getResponseType()+"] "); +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName() +") URL_ENCODE_YN=["+vo.getUrlEncodeYn()+"] "); +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName() +") CONNECTION_TIMEOUT=["+vo.getConnectionTimeout()+"] "); +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName() +") REST_OPTION=["+restOptionData+"] "); +// } +// +// if(vo.getEncode() != null && vo.getEncode().length() > 0) { +// try { +// mclient.getParams().setContentCharset(vo.getEncode()); +// sendData = new String(data, vo.getEncode()); +// } catch(Exception e) { +// if(logger.isError()){ +// logger.error("HttpClientAdapterServiceRestForCODEF] ENCODE("+vo.getEncode()+") ERROR : "+ e.toString()); +// logger.error("HttpClientAdapterServiceRestForCODEF] ENCODE("+vo.getEncode()+") SKIP "); +// } +// } +// } +// +//// if ("Y".equals(urlEncodeYn)) { +//// sendData = java.net.URLEncoder.encode(sendData); +//// } +// +// /* 레이아웃 메시지 타입이 JSON 형태만 처리 구현. REST를 처리하기 위해 아래 구성을 따라야함 +// * REST 레이아웃 구성 +// * HTTP_HEADER (X) : HTTP 헤더에 추가 정보가 필요할 경우 정의 +// * EAI_HEADER +// * EAI_BODY +// */ +// if (MessageType.JSON.equals(messageType)) { +// JSONObject dataObject = parseJson(sendData); +// if(dataObject != null) { +// eaiHeader = dataObject.containsKey(EAI_HEADER) ? dataObject.get(EAI_HEADER) : null; +// eaiBody = dataObject.containsKey(EAI_BODY) ? dataObject.get(EAI_BODY) : null; +// } +// } +// +// switch (HttpMethodType.getValue(rmethod)) { +// case GET : +// case DELETE : +// HashMap h = getParameters(eaiHeader); +// NameValuePair[] params = new NameValuePair[h.size()]; +// int count =0; +// for(String key : h.keySet()){ +// String value = h.get(key); +// params[count] = new NameValuePair(key, URLEncoder.encode(value, vo.getEncode())); +// count++; +// } +// method.setQueryString(params); +// break; +// case PUT : +// case POST : +// // OpenAPI는 json 타입. type이 다른 경우 헤더정보를 별도로 받아야함 +// method.setRequestHeader(HEADER_CONTENT_TYPE, "application/json; charset="+vo.getEncode()); +// if(eaiBody != null) { +// ((EntityEnclosingMethod) method).setRequestBody(URLEncoder.encode(eaiBody.toString(), vo.getEncode())); +// } +// +// break; +// default : +// break; +// } +// +// AccessTokenManager tokenManager = AccessTokenManager.getInstance(); +// OAuth2AccessTokenVO accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); +// +// // 토큰이 없거나 토큰이 만료 됐으면 재발급 +// if (accessToken == null || accessToken.isExpired()) { +// accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop); +// } +// +// method.setRequestHeader("Authorization", accessToken.getAuthorization()); +// +// if (logger.isDebug()&& "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName() +") TOKEN=["+accessToken+"] "); +// } +// +// // header 셋팅 +// if (header.size() > 0) { +// for (String key : header.keySet()) { +// method.setRequestHeader(key, header.get(key)); +// } +// } +// +// int status = -1; +// +// try { +// +// if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName()+") = ["+sendData+"]"); +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName()+") = "+CommonLib.getDumpMessage(sendData.getBytes())); +// } +// StopWatch stopWatch = new StopWatch(); +// stopWatch.start(); +// +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "SEND ["+sendData+"]"+CommonLib.getDumpMessage(sendData.getBytes())); +// } +// status = mclient.executeMethod(method); +// +// stopWatch.stop(); +// +// //status 200(정상) 이외에는 error 처리 +// if (status !=200){ +// try{ +// logger.error("HttpClientAdapterServiceRestForCODEF] receive status["+status+"] data[" + new String(method.getResponseBody()) +"]"); +// }catch(Exception e){ +// logger.error(e); +// } +// throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName="+vo.getAdapterGroupName()+"."+vo.getAdapterName(),status); +// } +// +// byte[] responseMessage = method.getResponseBody(); +// +// //---------------------------------------------------------- +// if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceRestForCODEF] responseType ="+ vo.getResponseType()); +// logger.debug("HttpClientAdapterServiceRestForCODEF] RECV ("+vo.getAdapterGroupName()+") = ["+new String(responseMessage)+"]"); +// logger.debug("HttpClientAdapterServiceRestForCODEF] RECV ("+vo.getAdapterGroupName()+") = "+CommonLib.getDumpMessage(responseMessage)); +// } +// if ("ASYNC".equals(vo.getResponseType())) { +// if (stopWatch.getTime() > vo.getSlowTranTime()) { +// if (logger.isInfo()){ +// logger.info("HttpClientAdapterServiceRestForCODEF] dummy response time = " + stopWatch.toString()+ " responseMessage=" + new String(responseMessage)); +// } +// } +// if ( ! java.util.Arrays.equals(ElinkConfig.getAsyncDummyDataForAdapterGroup(adptGrpName).getBytes(), responseMessage)){ +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"http return fail value= ["+responseMessage+"]" + CommonLib.getDumpMessage(responseMessage)); +// } +// throw new Exception ("http return fail value= " + new String(responseMessage)); +// } +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(),"RECV ["+new String(responseMessage)+"]"+CommonLib.getDumpMessage(responseMessage)); +// } +// return null; +// } else { +// /* OAuth 토큰 응답 체크 +// * +// * OAuth 응답 코드 +// * invalid_token +// */ +// JSONObject message = parseJson(URLDecoder.decode(new String(responseMessage), vo.getEncode())); +// if(message == null) { +// throw new Exception("responseMessage parsing result is NULL"); +// } +// +// String rspCode = (String) message.get("error"); +// String rspMessage = (String) message.get("message"); +// +// // OAuth 토큰 재요청 코드 확인 +// if (RETRY_RESPONSE_CODE.contains(rspCode)) { +// if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceRestForCODEF] retry access token response code= ["+rspCode+"] message= ["+rspMessage+"]"); +// } +// +// // 토큰 재발급 +// accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop); +// method.setRequestHeader("Authorization", accessToken.getAuthorization()); +// +// if (logger.isDebug()&& "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceRestForCODEF] SEND ("+vo.getAdapterGroupName() +") RETRY TOKEN=["+accessToken+"] "); +// } +// +// try { +// status = mclient.executeMethod(method); +// } catch (java.net.ConnectException e ) { +// throw new Exception ("retry excuteMethod Exceptioin = " + e.toString()); +// } +// +// //status 200(정상) 이외에는 error 처리 +// if (status !=200) { +// throw new Exception ("retry http receive status fail value= " + status + " adapterName="+vo.getAdapterGroupName()+"."+vo.getAdapterName() + " uri =" +uri +" method=" +rmethod); +// } +// +// responseMessage = method.getResponseBody(); +// +// if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { +// logger.debug("HttpClientAdapterServiceRestForCODEF] responseType ="+ vo.getResponseType()); +// logger.debug("HttpClientAdapterServiceRestForCODEF] retry RECV ("+vo.getAdapterGroupName()+") = ["+new String(responseMessage)+"]"); +// logger.debug("HttpClientAdapterServiceRestForCODEF] retry RECV ("+vo.getAdapterGroupName()+") = "+CommonLib.getDumpMessage(responseMessage)); +// } +// } +// } +// +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "RECV ["+new String(responseMessage)+"]"+CommonLib.getDumpMessage(responseMessage)); +// } +// +// String decodedMsg = URLDecoder.decode(new String(responseMessage), vo.getEncode()); +// +// return decodedMsg.getBytes(vo.getEncode()); +// } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceRestForCODEF] SocketTimeoutException ("+vo.getAdapterGroupName()+") : " + ste.toString(),ste); +// } +// logger.error("HttpClientAdapterServiceRestForCODEF] SocketTimeoutException ("+vo.getAdapterGroupName()+") : " + ste.toString() ,ste); +// throw ste; +// } catch(ConnectException ce) { +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceRestForCODEF] Connection Exception ("+vo.getAdapterGroupName()+") : " + ce.toString(),ce); +// } +// logger.error("HttpClientAdapterServiceRestForCODEF] Connection Exception ("+vo.getAdapterGroupName()+") : " + ce.toString() ,ce); +// throw ce; +// } catch(Exception e) { +// if (vo.getTraceLevel() >= 3) { +// HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),e.toString(),e); +// } +// logger.error("HttpClientAdapterServiceRestForCODEF] Exception ("+vo.getAdapterGroupName()+") : " + e.toString() ,e); +// throw e; +// } finally { +// if(method != null) method.releaseConnection(); +// if(status != HttpStatus.SC_OK) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(status); +// String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); +// if(logger.isDebug()){ +// logger.debug(resMsg); +// } +// } +// } +// +// } +// +// private HashMap getParameters(Object message) throws Exception { +// +// HashMap result = new HashMap(); +// +// if (message != null) { +// if (message instanceof JSONObject) { +// JSONObject jsonObject = (JSONObject) message; +// for (Object key : jsonObject.keySet()) { +// result.put((String) key, (String) jsonObject.get(key)); +// } +// } else { +// String[] messages = ((String) message).split("&"); +// String[] data = null; +// +// for (int i=0; i< messages.length;i++) { +// data = messages[i].split("=",2); +// if (data.length == 2 ){ +// result.put(data[0], data[1]); +// } +// } +// } +// } +// +// return result; +// } +// +// private JSONObject parseJson(String message) throws Exception { +// if (message == null) return null; +// +// return (JSONObject) JSONValue.parse(message); +// } +// +// private Document convertXmlDocument(String message) throws Exception{ +// SAXReader builder = new SAXReader(); +// Document document = builder.read(new StringReader(message)); +// return document; +// } +// +//// private Map changeUrlWithMessage(String messageType, String url, String extraPath, String sendData){ +//// Map responseMap = new HashMap(); +//// +//// try { +//// if (MessageType.JSON.equals(messageType)) { +//// JSONObject jsonObject = parseJson(sendData); +//// url = changeUrl(messageType, url, extraPath, jsonObject); +//// responseMap.put(URL, url); +//// } else if (MessageType.XML.equals(messageType)) { +//// Document doc = convertXmlDocument(sendData); +//// url = changeUrl(messageType, url, extraPath, doc); +//// responseMap.put(URL, url); +//// } +//// } catch (Exception e) { +//// logger.error("Failed to change url",e); +//// } +//// return responseMap; +//// } +// +// private String changeUrl(String messageType, String url, String restOption, Object sendData) { +// if ((MessageType.JSON.equals(messageType) || MessageType.XML.equals(messageType))) { +// try { +// if(StringUtils.isBlank(restOption)) { +// return url; +// } +// JSONObject restOptionObject = parseJson(restOption); +// if(restOptionObject == null) throw new Exception("restOption is null"); +// +// String type = (String) restOptionObject.get("type"); +// String extraPath = (String) restOptionObject.get("extraPath") ; +// String method = (String) restOptionObject.get("method"); +// url = getUrl(url, extraPath); +// if (TYPE_VARIABLE_URL_REQUEST.equals(type)) { +// HashMap uriVariables = new HashMap(); +// if (MessageType.JSON.equals(messageType)) { +// JSONObject jsonObject = null; +// JSONObject dataObject = null; +// if (sendData instanceof JSONObject) { +// jsonObject = (JSONObject) sendData; +// } else { +// jsonObject = (JSONObject) JSONValue.parse((String)sendData); +// } +// +// switch (HttpMethodType.getValue(method)) { +// case GET : +// case DELETE : +// dataObject = jsonObject.containsKey(EAI_HEADER) ? (JSONObject) jsonObject.get(EAI_HEADER) : null; +// break; +// case PUT : +// case POST : +// dataObject = jsonObject.containsKey(EAI_BODY) ? (JSONObject) jsonObject.get(EAI_BODY) : null; +// break; +// } +// +// if(dataObject != null) { +// for (Object key : dataObject.keySet()) { +// if (url.indexOf("{" + (String) key + "}") > 0) { +// uriVariables.put((String) key, (String) dataObject.get(key)); +// } +// } +// } +// } else if(MessageType.XML.equals(messageType)) { +// Document doc ; +// if (sendData instanceof Document) { +// doc = (Document) sendData; +// } else { +// doc = convertXmlDocument((String)sendData); +// } +// if(doc !=null) { +// for (Object branch : doc.content()) { +// Element element = (Element) branch; +// +// if (url.indexOf("{" + element.getName() + "}") > 0) { +// uriVariables.put(element.getName(), element.getText()); +// } +// } +// +//// for (Object tempObject : uriVariables) { +//// String urlVaribleId = (String) tempObject; +//// Element element = (Element) doc.selectSingleNode("//"+urlVaribleId); +//// urlVariableList.add(element.getText()); +//// if (doc.getRootElement() == element) { +////// doc = null; +//// break; +//// } else { +//// element.getParent().remove(element); +//// } +//// } +// } +// } +// +// if (uriVariables.size() > 0) { +// UriComponents uriComponents = UriComponentsBuilder.fromUriString(url).buildAndExpand(uriVariables); +// url = uriComponents.toUriString(); +// logger.debug("HttpClientAdapterServiceRestForCODEF] after extand url=["+url+"] "); +// } +// } +// } catch(Exception e) { +// logger.error("Failed to change url",e); +// } +// } +// return url; +// } +// +// private String getUrl(String baseUrl, String extraPath) { +// if (StringUtils.isBlank(extraPath)) { +// return baseUrl; +// } +// if (baseUrl != null && baseUrl.endsWith("/") == false) { +// baseUrl += "/"; +// } +// String targetUrl = baseUrl + extraPath; +// logger.debug("HttpClientAdapterServiceRestForCODEF] after concatenate url=["+targetUrl+"] "); +// return targetUrl; +// } +// +//} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceRestForKFTC.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceRestForKFTC.java new file mode 100644 index 0000000..415fefc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceRestForKFTC.java @@ -0,0 +1,492 @@ +package com.eactive.eai.adapter.http.client.impl; + +import java.io.StringReader; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpMethodBase; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.HttpVersion; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.methods.DeleteMethod; +import org.apache.commons.httpclient.methods.EntityEnclosingMethod; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.PutMethod; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.time.StopWatch; +import org.dom4j.Document; +import org.dom4j.Element; +import org.dom4j.io.SAXReader; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.springframework.web.util.UriComponents; +import org.springframework.web.util.UriComponentsBuilder; + +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpMethodType; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.env.ElinkConfig; +import com.openbanking.eai.common.token.AccessTokenManager; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; + +public class HttpClientAdapterServiceRestForKFTC extends HttpClientAdapterServiceSupport + implements HttpClientAdapterServiceKey { + + public static final String TYPE_VARIABLE_URL_REQUEST = "variableUrlRequest"; + public static final String TYPE_SIMPLE_REQUEST = "simpleRequest"; + + public static final String HTTP_HEADER = "HTTP_HEADER"; + public static final String EAI_HEADER = "EAI_HEADER"; + public static final String EAI_BODY = "EAI_BODY"; + + public static final String REST_OPTION = "REST_OPTION"; + public static final String REST_TYPE = "type"; + public static final String REST_EXTRA_PATH = "extraPath"; + public static final String REST_METHOD = "method"; + + public static final String HEADER_CONTENT_TYPE = "Content-Type"; + + public static final List RETRY_RESPONSE_CODE = Arrays.asList("O0001", "O0002", "O0003"); + + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + HttpClientAdapterVO vo = super.setting(prop, tempProp); + + // 레이아웃 메세지 타입 REST URL 추출 시 활용. Default JSON + String messageType = prop.getProperty("MESSAGE_TYPE", MessageType.JSON); + /* TSEAIHE02.RESTOPTION 정보 -> JSON 형태로 구성 + * type : simpleRequest, variableUrlRequest + * extraPath : 어댑터 프로퍼티 URL에 추가될 HTTP REST URL + * method : get, delete, post, put + * + * ex) {"type":"simpleRequest", "extraPath":"v2.0/account/balance", "method": "post"} + */ + + String restOptionData = tempProp.getProperty(REST_OPTION); + + JSONObject restOptionObject = parseJson(restOptionData); + if (restOptionObject == null) { + throw new Exception("OptionData parsing result is NULL"); + } + String rmethod = restOptionObject.containsKey("method") + ? StringUtils.upperCase((String) restOptionObject.get("method")) + : "POST"; + + Object eaiHeader = null; + Object eaiBody = null; + HttpClient mclient = this.client; + + + + String sendData = ""; + if (data instanceof byte[]) { + sendData = new String((byte[]) data, vo.getEncode()); + } else if (data instanceof String) { + sendData = (String) data; + } + + HashMap header = new HashMap(); + //interface 에 설정된게 우선한다. + String uri = changeUrl(messageType, vo.getUrl(), restOptionData, sendData); + + HttpMethodBase method = null; + switch (HttpMethodType.getValue(rmethod)) { + case GET : + method = new GetMethod(uri); + break; + case DELETE : + method = new DeleteMethod(uri); + break; + case POST : + method = new PostMethod(uri); + break; + case PUT : + method = new PutMethod(uri); + break; + default : + // set default method + method = new GetMethod(uri); + break; + } + + + + if (logger.isDebug()&& "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName() +") URL=["+vo.getUrl()+"] "); + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName() +") PARAMETER_NAME=["+vo.getParameterName()+"] "); + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName() +") ENCODE=["+vo.getEncode()+"] "); + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName() +") RESPONSE_TYPE=["+vo.getResponseType()+"] "); + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName() +") URL_ENCODE_YN=["+vo.getUrlEncodeYn()+"] "); + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName() +") CONNECTION_TIMEOUT=["+vo.getConnectionTimeout()+"] "); + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName() +") REST_OPTION=["+restOptionData+"] "); + } + + configureHttpClient(mclient, method, vo, vo.getUrl(), vo.getContentType()); + + if ("Y".equals(vo.getUrlEncodeYn())) { + sendData = java.net.URLEncoder.encode(sendData); + } + + /* 레이아웃 메시지 타입이 JSON 형태만 처리 구현. REST를 처리하기 위해 아래 구성을 따라야함 + * REST 레이아웃 구성 + * HTTP_HEADER (X) : HTTP 헤더에 추가 정보가 필요할 경우 정의 + * EAI_HEADER + * EAI_BODY + */ + if (MessageType.JSON.equals(messageType)) { + JSONObject dataObject = parseJson(sendData); + if(dataObject != null) { + eaiHeader = dataObject.containsKey(EAI_HEADER) ? dataObject.get(EAI_HEADER) : null; + eaiBody = dataObject.containsKey(EAI_BODY) ? dataObject.get(EAI_BODY) : null; + } + } + + switch (HttpMethodType.getValue(rmethod)) { + case GET : + case DELETE : + HashMap h = getParameters(eaiHeader); + NameValuePair[] params = new NameValuePair[h.size()]; + int count =0; + for(String key : h.keySet()){ + String value = h.get(key); + params[count] = new NameValuePair(key,value); + count++; + } + method.setQueryString(params); + break; + case PUT : + case POST : + // OpenAPI는 json 타입. type이 다른 경우 헤더정보를 별도로 받아야함 + method.setRequestHeader(HEADER_CONTENT_TYPE, "application/json; charset="+vo.getEncode()); + if(eaiBody != null) { + ((EntityEnclosingMethod) method).setRequestBody(eaiBody.toString()); + } + + break; + default : + break; + } + + AccessTokenManager tokenManager = AccessTokenManager.getInstance(); + OAuth2AccessTokenVO accessToken = (OAuth2AccessTokenVO) tokenManager.getAccessTokenVO(vo.getAdapterGroupName()); + + // 토큰이 없거나 토큰이 만료 됐으면 재발급 + if (accessToken == null || accessToken.isExpired()) { + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, oldToken); + } + + method.setRequestHeader("Authorization", accessToken.getAuthorization()); + + if (logger.isDebug()&& "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName() +") TOKEN=["+accessToken+"] "); + } + + // header 셋팅 + if (header.size() > 0) { + for (String key : header.keySet()) { + method.setRequestHeader(key, header.get(key)); + } + } + + int status = -1; + + try { + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName()+") = ["+sendData+"]"); + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName()+") = "+CommonLib.getDumpMessage(sendData)); + } + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "SEND ["+sendData+"]"+CommonLib.getDumpMessage(sendData)); + } + status = mclient.executeMethod(method); + + stopWatch.stop(); + + //status 200(정상) 이외에는 error 처리 + if (status !=200){ + try{ + logger.error("HttpClientAdapterServiceRestForKFTC] receive status["+status+"] data[" + new String(method.getResponseBody()) +"]"); + }catch(Exception e){ + logger.error(e); + } + throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName="+vo.getAdapterGroupName()+"."+vo.getAdapterName(),status); + } + + byte[] responseMessage = method.getResponseBody(); + + //---------------------------------------------------------- + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRestForKFTC] responseType ="+ vo.getResponseType()); + logger.debug("HttpClientAdapterServiceRestForKFTC] RECV ("+vo.getAdapterGroupName()+") = ["+new String(responseMessage)+"]"); + logger.debug("HttpClientAdapterServiceRestForKFTC] RECV ("+vo.getAdapterGroupName()+") = "+CommonLib.getDumpMessage(responseMessage)); + } + if ("ASYNC".equals(vo.getResponseType())) { + if (stopWatch.getTime() > vo.getSlowTranTime()) { + if (logger.isInfo()){ + logger.info("HttpClientAdapterServiceRestForKFTC] dummy response time = " + stopWatch.toString()+ " responseMessage=" + new String(responseMessage)); + } + } + if ( ! java.util.Arrays.equals(ElinkConfig.getAsyncDummyDataForAdapterGroup(vo.getAdapterGroupName()).getBytes(), responseMessage)){ + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"http return fail value= ["+responseMessage+"]" + CommonLib.getDumpMessage(responseMessage)); + } + throw new Exception ("http return fail value= " + new String(responseMessage)); + } + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(),"RECV ["+new String(responseMessage)+"]"+CommonLib.getDumpMessage(responseMessage)); + } + return null; + } else { + /* OAuth 토큰 응답 체크 + * + * OAuth 응답 코드 + * O0001 인증요청 거부-인증 파라미터 오류([error_code]) + * O0002 Access Token 거부 + * O0003 Access Token 만료 + */ + JSONObject message = parseJson(new String(responseMessage, vo.getEncode())); + if(message == null) { + throw new Exception("responseMessage parsing result is NULL"); + } + + String rspCode = (String) message.get("rsp_code"); + String rspMessage = (String) message.get("rsp_message"); + + // OAuth 토큰 재요청 코드 확인 + if (RETRY_RESPONSE_CODE.contains(rspCode)) { + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRestForKFTC] retry access token response code= ["+rspCode+"] message= ["+rspMessage+"]"); + } + + // 토큰 재발급 + String oldToken = accessToken == null ? null : accessToken.getAccessToken(); + accessToken = (OAuth2AccessTokenVO) tokenManager.retryAccessTokenVO(vo.getAdapterGroupName(), prop, oldToken); + method.setRequestHeader("Authorization", accessToken.getAuthorization()); + + if (logger.isDebug()&& "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRestForKFTC] SEND ("+vo.getAdapterGroupName() +") RETRY TOKEN=["+accessToken+"] "); + } + + try { + status = mclient.executeMethod(method); + } catch (java.net.ConnectException e ) { + throw new Exception ("retry excuteMethod Exceptioin = " + e.toString()); + } + + if (status !=200) { + throw new Exception ("retry http receive status fail value= " + status + " adapterName="+vo.getAdapterGroupName()+"."+vo.getAdapterName() + " uri =" +uri +" method=" +rmethod); + } + + responseMessage = method.getResponseBody(); + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapterServiceRestForKFTC] responseType ="+ vo.getResponseType()); + logger.debug("HttpClientAdapterServiceRestForKFTC] retry RECV ("+vo.getAdapterGroupName()+") = ["+new String(responseMessage)+"]"); + logger.debug("HttpClientAdapterServiceRestForKFTC] retry RECV ("+vo.getAdapterGroupName()+") = "+CommonLib.getDumpMessage(responseMessage)); + } + } + } + + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(vo.getAdapterGroupName()+vo.getAdapterName(), "RECV ["+new String(responseMessage)+"]"+CommonLib.getDumpMessage(responseMessage)); + } + + return responseMessage; + + } catch(SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceRestForKFTC] SocketTimeoutException ("+vo.getAdapterGroupName()+") : " + ste.toString(),ste); + } + logger.error("HttpClientAdapterServiceRestForKFTC] SocketTimeoutException ("+vo.getAdapterGroupName()+") : " + ste.toString() ,ste); + throw ste; + } catch(ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),"HttpClientAdapterServiceRestForKFTC] Connection Exception ("+vo.getAdapterGroupName()+") : " + ce.toString(),ce); + } + logger.error("HttpClientAdapterServiceRestForKFTC] Connection Exception ("+vo.getAdapterGroupName()+") : " + ce.toString() ,ce); + throw ce; + } catch(Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName()+vo.getAdapterName(),e.toString(),e); + } + logger.error("HttpClientAdapterServiceRestForKFTC] Exception ("+vo.getAdapterGroupName()+") : " + e.toString() ,e); + throw e; + } finally { + if(method != null) method.releaseConnection(); + if(status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); + if(logger.isDebug()){ + logger.debug(resMsg); + } + } + } + + } + + private HashMap getParameters(Object message) throws Exception { + HashMap result = new HashMap(); + if (message != null) { + if (message instanceof JSONObject) { + JSONObject jsonObject = (JSONObject) message; + for (Object key : jsonObject.keySet()) { + result.put((String) key, (String) jsonObject.get(key)); + } + } else { + String[] messages = ((String) message).split("&"); + String[] data = null; + + for (int i=0; i< messages.length;i++) { + data = messages[i].split("=",2); + if (data.length == 2 ){ + result.put(data[0], data[1]); + } + } + } + } + + return result; + } + + private JSONObject parseJson(String message) throws Exception { + if (message == null) return null; + + return (JSONObject) JSONValue.parse(message); + } + + private Document convertXmlDocument(String message) throws Exception{ + SAXReader builder = new SAXReader(); + Document document = builder.read(new StringReader(message)); + return document; + } + +// private Map changeUrlWithMessage(String messageType, String url, String extraPath, String sendData){ +// Map responseMap = new HashMap(); +// +// try { +// if (MessageType.JSON.equals(messageType)) { +// JSONObject jsonObject = parseJson(sendData); +// url = changeUrl(messageType, url, extraPath, jsonObject); +// responseMap.put(URL, url); +// } else if (MessageType.XML.equals(messageType)) { +// Document doc = convertXmlDocument(sendData); +// url = changeUrl(messageType, url, extraPath, doc); +// responseMap.put(URL, url); +// } +// } catch (Exception e) { +// logger.error("Failed to change url",e); +// } +// return responseMap; +// } + + private String changeUrl(String messageType, String url, String restOption, Object sendData) { + if ((MessageType.JSON.equals(messageType) || MessageType.XML.equals(messageType))) { + try { + if (StringUtils.isBlank(restOption)) { + return url; + } + JSONObject restOptionObject = parseJson(restOption); + if (restOptionObject == null) + throw new Exception("restOption is null"); + + String type = (String) restOptionObject.get("type"); + String extraPath = (String) restOptionObject.get("extraPath"); + String method = (String) restOptionObject.get("method"); + url = getUrl(url, extraPath); + if (TYPE_VARIABLE_URL_REQUEST.equals(type)) { + HashMap uriVariables = new HashMap(); + if (MessageType.JSON.equals(messageType)) { + JSONObject jsonObject = null; + JSONObject dataObject = null; + if (sendData instanceof JSONObject) { + jsonObject = (JSONObject) sendData; + } else { + jsonObject = (JSONObject) JSONValue.parse((String) sendData); + } + + switch (HttpMethodType.getValue(method)) { + case GET: + case DELETE: + dataObject = jsonObject.containsKey(EAI_HEADER) ? (JSONObject) jsonObject.get(EAI_HEADER) + : null; + break; + case PUT: + case POST: + dataObject = jsonObject.containsKey(EAI_BODY) ? (JSONObject) jsonObject.get(EAI_BODY) + : null; + break; + } + + if (dataObject != null) { + for (Object key : dataObject.keySet()) { + if (url.indexOf("{" + (String) key + "}") > 0) { + uriVariables.put((String) key, (String) dataObject.get(key)); + } + } + } + } else if (MessageType.XML.equals(messageType)) { + Document doc; + if (sendData instanceof Document) { + doc = (Document) sendData; + } else { + doc = convertXmlDocument((String) sendData); + } + if (doc != null) { + for (Object branch : doc.content()) { + Element element = (Element) branch; + + if (url.indexOf("{" + element.getName() + "}") > 0) { + uriVariables.put(element.getName(), element.getText()); + } + } + } + } + + if (uriVariables.size() > 0) { + UriComponents uriComponents = UriComponentsBuilder.fromUriString(url) + .buildAndExpand(uriVariables); + url = uriComponents.toUriString(); + logger.debug("HttpClientAdapterServiceRestForKFTC] after extand url=[" + url + "] "); + } + } + } catch (Exception e) { + logger.error("Failed to change url", e); + } + } + return url; + } + + private String getUrl(String baseUrl, String extraPath) { + if (StringUtils.isBlank(extraPath)) { + return baseUrl; + } + if (baseUrl != null && baseUrl.endsWith("/") == false) { + baseUrl += "/"; + } + String targetUrl = baseUrl + extraPath; + logger.debug("HttpClientAdapterServiceRestForKFTC] after concatenate url=[" + targetUrl + "] "); + return targetUrl; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceSoap.java b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceSoap.java new file mode 100644 index 0000000..f2dc8d5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/client/impl/HttpClientAdapterServiceSoap.java @@ -0,0 +1,134 @@ +package com.eactive.eai.adapter.http.client.impl; + +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.Properties; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; +import org.apache.commons.httpclient.methods.PostMethod; + +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceSupport; +import com.eactive.eai.adapter.http.client.HttpClientAdapterVO; +import com.eactive.eai.common.exception.ExceptionUtil; + +public class HttpClientAdapterServiceSoap extends HttpClientAdapterServiceSupport { + + public Object execute(Properties prop, Object data, Properties tempProp) throws Exception { + + HttpClientAdapterVO vo = super.setting(prop, tempProp); + String soapAction = prop.getProperty(METHOD_SOAP_ACTION); + if (soapAction != null) + soapAction = soapAction.trim(); + + if (logger.isDebug() && "N".equals(vo.getTestCallYn())) { + logger.debug("HttpClientAdapter] SEND (" + vo.getMethod() + ") "); + } + PostMethod method = new PostMethod(vo.getUrl()); + if (vo.getTimeout() > -1) { + method.getParams().setSoTimeout(vo.getTimeout()); + } + HttpClient mclient = this.client; + + byte[] sendBytes = null; + if (data instanceof String) { + sendBytes = ((String) data).getBytes(vo.getEncode()); + } else if (data instanceof byte[]) { + sendBytes = (byte[]) data; + } + ByteArrayRequestEntity entity = new ByteArrayRequestEntity(sendBytes); + + method.setRequestEntity(entity); + method.setRequestHeader("SOAPAction", soapAction); + + int status = -1; + + configureHttpClient(mclient, method, vo, vo.getUrl(), vo.getContentType()); + + try { + status = mclient.executeMethod(method); + // status 200(정상) 이외에는 error 처리 + if (status != 200) { + try { + logger.error("HttpClientAdapterServiceSoap] receive status[" + status + "] data[" + + new String(method.getResponseBody()) + "]"); + } catch (Exception e) { + logger.error(e); + } + throw new HttpStatusException("수신시스템을 확인하세요. HTTP 에러[ " + status + "] adapterName=" + + vo.getAdapterGroupName() + "." + vo.getAdapterName(), status); + } + byte[] responseMessage = method.getResponseBody(); + return responseMessage; + + // return removeSoap(responseMessage,function).getBytes(); + + } catch (SocketTimeoutException ste) { // Read Timeout :: HttpClient 3.1일 경우 + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceSoap] SocketTimeoutException : " + ste.toString(), ste); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceSoap] SocketTimeoutException : " + ste.toString(), ste); + } + throw ste; + } catch (ConnectException ce) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceSoap] Connection Exception : " + ce.toString(), ce); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceSoap] Connection Exception : " + ce.toString(), ce); + } + throw ce; + } catch (Exception e) { + if (vo.getTraceLevel() >= 3) { + HttpMemoryLogger.error(vo.getAdapterGroupName() + vo.getAdapterName(), + "HttpClientAdapterServiceSoap] Exception : " + e.toString(), e); + } + if (logger.isError()) { + logger.error("HttpClientAdapterServiceSoap] Exception : " + e.toString(), e); + } + throw e; + } finally { + method.releaseConnection(); + if (status != HttpStatus.SC_OK) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(status); + String resMsg = ExceptionUtil.make("RDCEAIAHA013", msgArgs); + if (logger.isDebug()) { + logger.debug(resMsg); + } + } + } + + } +// private String addSoap(String message) throws Exception { +// StringBuffer sb = new StringBuffer(); +// sb.append(""); +// sb.append(""); +// sb.append(message); +// sb.append(""); +// sb.append(""); +// return sb.toString(); +// } +// private String getFunction(String message) throws Exception { +// DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); +// dbFactory.setIgnoringElementContentWhitespace(true); +// DocumentBuilder docBuilder = dbFactory.newDocumentBuilder(); +// Document doc = docBuilder.parse(new InputSource(new StringReader(message.trim()))); +// return doc.getDocumentElement().getNodeName(); +// } +// private String removeSoap(String result,String function) throws Exception { +// DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); +// dbFactory.setIgnoringElementContentWhitespace(true); +// DocumentBuilder docBuilder = dbFactory.newDocumentBuilder(); +// Document doc = docBuilder.parse(new InputSource(new StringReader(result.trim()))); +// NodeList nodes = doc.getElementsByTagName(function + "Return"); +// return nodes.item(0).getFirstChild().getNodeValue(); +// } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterCustom.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterCustom.java new file mode 100644 index 0000000..76b7414 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterCustom.java @@ -0,0 +1,129 @@ +package com.eactive.eai.adapter.http.dynamic; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.InboundErrorLogger; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.UUIDGenerator; +import com.eactive.eai.inbound.error.InboundErrorInfoVO; +import io.undertow.servlet.handlers.DefaultServlet; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.Date; + +public class HttpAdapterCustom extends DefaultServlet implements HttpAdapterServiceKey { + + private static final long serialVersionUID = 1L; + + // Adapter Logger + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + protected void service(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + HttpDynamicPortInAdapterManager manager = HttpDynamicPortInAdapterManager.getInstance(); + Integer localPort = request.getLocalPort(); + String requestUrl = request.getRequestURI(); // /api/v1/public/getUserInfo.svc + + HttpDynamicInAdapterUri adptUri = findAdptUri(localPort, requestUrl, manager); + + if (logger.isDebug()) { + logger.debug("[HttpAdapterCustom] request adapter info : " + adptUri); + } + + if (adptUri == null) { + logError(request, response, null); + return; + } + + HttpAdapterService service = HttpAdapterServiceFactory.createFactory(adptUri.getAdptType()); + service.service(adptUri.getAdptGrpName(), adptUri.getAdptName(), request, response); + } + + /** + * url에서 뒤쪽 /이후를 제거하면서 찾는다.
+ * /api/v1/public/getUserInfo.svc + * + * @param apiUri + * @return + */ + private HttpDynamicInAdapterUri findAdptUri(Integer localPort, String apiUri, + HttpDynamicPortInAdapterManager manager) { + apiUri = StringUtils.removeEnd(apiUri, "/"); + if (StringUtils.isBlank(apiUri)) { + return null; + } + + HttpDynamicInAdapterUri adptUri = null; + for (int i = 0; i < 10; i++) { + adptUri = manager.getAdptUri(localPort, apiUri); + if (adptUri != null) { + return adptUri; + } + + // /api/v1/public + apiUri = StringUtils.substringBeforeLast(apiUri, "/"); + if (StringUtils.isBlank(apiUri)) { + return manager.getAdptUri(localPort, "/"); + } + } + + return null; + } + + private void logError(HttpServletRequest request, HttpServletResponse response, String msg) { + + InboundErrorInfoVO errorInfoVO = new InboundErrorInfoVO(); + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String serverName = eaiServerManager.getLocalServerName(); + String uuid = null; + StringBuffer sb = new StringBuffer(); + + String instanceid1 = serverName.substring(0,2); + String instanceid2 = serverName.substring(serverName.length()-2, serverName.length()); + String instid = instanceid1 + instanceid2; + uuid = instid + UUIDGenerator.getUUID(); + + String[] msgArgs = new String[1]; + msgArgs[0] = request.getRequestURI(); + + String errorCode = "RECEAIIRP010"; + String errorMsg = null; + if (msg == null) { + errorMsg = ExceptionUtil.make(new Exception("cat not find uri"), errorCode, msgArgs); + } else { + errorMsg = ExceptionUtil.make(new Exception(msg), errorCode, msgArgs); + } + + errorInfoVO.setEaiSvcSno(uuid); // EAI서비스일련번호 + errorInfoVO.setAdptBwkGrpNm("HTTP_IN_NO_URI"); // 어댑터업무그룹명 + errorInfoVO.setErrCd(errorCode); // 에러코드 + errorInfoVO.setErrTxt(errorMsg); // 에러내용 + errorInfoVO.setErrTm(DatetimeUtil.getCurrentTime(new Date().getTime())); // 에러발생시각 + errorInfoVO.setErrDstcd(" "); + sb.append("Remote Addr : ").append(request.getRemoteAddr()).append("\n") + .append("Request URI : ").append(request.getRequestURI()); + errorInfoVO.setBwkDataTxt(sb.toString()); // 업무데이터내용 + errorInfoVO.setEaiSvrInstNm(serverName); // EAI서버인스턴스명 + + InboundErrorLogger.error(errorInfoVO); + + response.setStatus(404); + try { + if (msg == null) { + response.getWriter().println("can not find uri '"+request.getRequestURI()+"'"); + } else { + response.getWriter().println(msg); + } + } catch (Exception ex) { + // IGNORE + } + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterListener.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterListener.java new file mode 100644 index 0000000..28b1fd4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterListener.java @@ -0,0 +1,54 @@ +package com.eactive.eai.adapter.http.dynamic; + +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListenerSupport; +import com.eactive.eai.common.util.Logger; + +public class HttpAdapterListener extends AdapterListenerSupport { + + final static Logger logger2 = HttpLoggerManager.getInstance().getLogger(); + final static Logger errLogger = HttpLoggerManager.getInstance().getErrLogger(); + + public void start() throws AdapterException { + HttpDynamicPortInAdapterManager manager = HttpDynamicPortInAdapterManager.getInstance(); + try { + if (info == null) { + throw new Exception("HttpAdapterListener | AdapterVO가 NULL입니다."); + } + manager.addAdapter(info); + + try { + manager.start(info); + if(logger2.isInfo()) { + logger2.info("[HttpAdapterListener] AdapterName [" + info.getAdapterGroupName() + "." + info.getName() + + "] config [" + info + "] start"); + } + } catch (Exception e) { + manager.removeAdapter(info); + throw e; + } + } catch (Exception e) { + logger.error(info.getName() + " | HttpAdapterListener | cannot start : " + e.getMessage(), e); + throw new AdapterException(info.getName() + " | HttpAdapterListener | cannot start - " + e.getMessage()); + } + } + + public void stop() throws AdapterException { + HttpDynamicPortInAdapterManager manager = HttpDynamicPortInAdapterManager.getInstance(); + try { + if (info == null) { + throw new Exception("HttpAdapterListener | AdapterVO가 NULL입니다."); + } + + manager.removeAdapter(info); + manager.stop(info); + if(logger2.isInfo()) { + logger2.info("[HttpAdapterListener] AdapterName [" + info.getAdapterGroupName() + "." + info.getName() + + "] adapter info [" + info + "] stop"); + } + } catch (Exception e) { + logger.error(info.getName() + " | HttpAdapterListener | cannot stop : " + e.getMessage(), e); + throw new AdapterException(info.getName() + " | HttpAdapterListener | cannot stop - " + e.getMessage()); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterMain.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterMain.java new file mode 100644 index 0000000..498a360 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterMain.java @@ -0,0 +1,123 @@ +package com.eactive.eai.adapter.http.dynamic; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.InboundErrorLogger; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.UUIDGenerator; +import com.eactive.eai.inbound.error.InboundErrorInfoVO; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.List; + +public class HttpAdapterMain extends HttpServlet implements HttpAdapterServiceKey { + public void init() { + } + + public void service(HttpServletRequest request, HttpServletResponse response) { + Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + HttpDynamicInAdapterManager manager = HttpDynamicInAdapterManager.getInstance(); + String orgUri = request.getRequestURI().replaceAll(request.getContextPath(), "");// context path 제거 + + String customUri = getCustomUri(orgUri, 3); // adapter name 이후 제거 + HttpDynamicInAdapterUri adptUri = manager.getAdptUri(customUri); + + if (logger.isDebug()) { + logger.debug("HttpDynamicInAdapter] service request uri : " + request.getRequestURI()); + } + + if (adptUri == null) { + logError(request, response); + return; + } + + // rest일때만 하위 uri 허용 + if (!orgUri.equals(customUri) && !HttpAdapterServiceType.REST.toString().equals(adptUri.getAdptType())) { + logError(request, response); + return; + } + + HttpAdapterService service = HttpAdapterServiceFactory.createFactory(adptUri.getAdptType()); + if (service == null) { + logger.debug("HttpDynamicInAdapter] HttpAdapterService create Error : " + adptUri.getAdptType()); + logError(request, response); + } else { + service.service(adptUri.getAdptGrpName(), adptUri.getAdptName(), request, response); + } + } + + private void logError(HttpServletRequest request, HttpServletResponse response) { + Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + InboundErrorInfoVO errorInfoVO = new InboundErrorInfoVO(); + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + + String serverName = eaiServerManager.getLocalServerName(); + String uuid = null; + StringBuffer sb = new StringBuffer(); +// +// String instanceid1 = ""; +// String instanceid2 = ""; +// if(serverName != null) { +// //juns 서버명 변경에 따른 인스턴스 룰 추출변경 +// //ex)EAIDSG_i11 => EAIDS01_i01 결과 EA11 +// instanceid1 = serverName.substring(0,2); +// // String instanceid2 = serverName.substring(serverName.length()-2, serverName.length()); +// instanceid2 = serverName.substring(serverName.length()-5, serverName.length()-4) +// + serverName.substring(serverName.length()-1, serverName.length()); +// } + String instid = eaiServerManager.getGroupInstId(); + uuid = instid + UUIDGenerator.getUUID(); + + String[] msgArgs = new String[1]; + msgArgs[0] = request.getRequestURI(); + + String errorCode = "RECEAIIRP010"; + String errorMsg = ExceptionUtil.make(new Exception("cat not find uri"), errorCode, msgArgs); + + errorInfoVO.setEaiSvcSno(uuid); // EAI서비스일련번호 + errorInfoVO.setAdptBwkGrpNm("HTTP_IN_NO_URI"); // 어댑터업무그룹명 + errorInfoVO.setErrCd(errorCode); // 에러코드 + errorInfoVO.setErrTxt(errorMsg); // 에러내용 + errorInfoVO.setErrTm(DatetimeUtil.getCurrentTime(new Date().getTime())); // 에러발생시각 + errorInfoVO.setErrDstcd(" "); + sb.append("Remote Addr : ").append(request.getRemoteAddr()).append("\n").append("Request URI : ") + .append(request.getRequestURI()); + errorInfoVO.setBwkDataTxt(sb.toString()); // 업무데이터내용 + errorInfoVO.setEaiSvrInstNm(serverName); // EAI서버인스턴스명 + + InboundErrorLogger.error(errorInfoVO); + + response.setStatus(404); + try { + response.getWriter().println("can not find uri '" + request.getRequestURI() + "'"); + } catch (Exception ex) { + logger.error("write error", ex); + } + + } +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String orgUri = "/HTT/CbsInHttpSys/ABC/DEF"; +//// System.out.println(getCustomUri(orgUri,3)); +// +// } + public static String getCustomUri(String url, int length) { + // return + // Stream.of(url.split("/")).limit(length).collect(Collectors.joining("/")) ; + String[] urls = url.split("/"); + List newUrls = new ArrayList<>(); + Collections.addAll(newUrls, urls); + return StringUtils.join(newUrls.subList(0, length).toArray(), "/"); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterService.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterService.java new file mode 100644 index 0000000..d0259af --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterService.java @@ -0,0 +1,9 @@ +package com.eactive.eai.adapter.http.dynamic; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public interface HttpAdapterService { + public abstract void service(String adptGrpName, String adptName, HttpServletRequest request, + HttpServletResponse response); +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceFactory.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceFactory.java new file mode 100644 index 0000000..6a7cf33 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceFactory.java @@ -0,0 +1,43 @@ +package com.eactive.eai.adapter.http.dynamic; + +import java.util.concurrent.ConcurrentHashMap; + +import com.eactive.eai.common.util.Logger; + +public class HttpAdapterServiceFactory { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + static private ConcurrentHashMap h = new ConcurrentHashMap(); + + /** + * + */ + public HttpAdapterServiceFactory() { + super(); + } + + /** + * 공통코드 HTTP_ADAPTER_SERVICE_CLASS 에 정의된 구현체를 생성 한다. + * + * @param className + * @return + */ + @SuppressWarnings("rawtypes") + public static HttpAdapterService createFactory(String className) { + if (h.containsKey(className)) { + return h.get(className); + } + + HttpAdapterService service = null; + try { + Class cl = Class.forName(className); + service = (HttpAdapterService) cl.newInstance(); + if (service != null) { + h.put(className, service); + } + } catch (Exception e) { + logger.error("Cannot create a HttpAdapterService. - {}", className); + } + + return service; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java new file mode 100644 index 0000000..4bc9084 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceKey.java @@ -0,0 +1,77 @@ +package com.eactive.eai.adapter.http.dynamic; + +public interface HttpAdapterServiceKey { + // URL 파리미터 DEFAULT 이름 + static final String PARAMETER_MESSAGE = "_message_"; + + // URL 파리미터 이름 + static final String PARAMETER_NAME = "PARAMETER_NAME"; + + // Http Adapter 이름 + static final String HTTP_ADAPTER_NAME = "HTTP_ADAPTER_NAME"; + + // Http Adapter Group 이름 + static final String HTTP_ADAPTER_GROUP_NAME = "HTTP_ADAPTER_GROUP_NAME"; + + // Http Response Type 이름 + static final String RESPONSE_TYPE = "RESPONSE_TYPE"; + + public static final String RESPONSE_TYPE_SYNC = "SYNC"; + public static final String RESPONSE_TYPE_ASYNC = "ASYN"; + + // Http Encode 이름 + static final String ENCODE = "ENCODE"; + + // Http URL Decode 여부 + static final String URL_DECODE_YN = "URL_DECODE_YN"; + + // Body data 사용 여부 + static final String REQUEST_BODY_YN = "REQUEST_BODY_YN"; + + // 삭제할 데이타 길이 + static final String REMOVE_LENGTH = "REMOVE_LENGTH"; + + // 추가할 데이타 + static final String ADD_DATA = "ADD_DATA"; + + // 거래 로그 + static final String TRACE_LEVEL = "TRACE_LEVEL"; + + static final String ERROR_RESPONSE_FORMAT = "ERROR_RESPONSE_FORMAT"; + + // REST용 전달값 + static final String INBOUND_METHOD = "INBOUND_METHOD"; + static final String INBOUND_URI = "INBOUND_URI"; + static final String INBOUND_EXTURI = "INBOUND_EXTURI"; + static final String INBOUND_HEADER = "INBOUND_HEADER"; + static final String INBOUND_QUERY_STRING = "INBOUND_QUERY_STRING"; + static final String INBOUND_REWRITE_PATH = "INBOUND_REWRITE_PATH"; + static final String INBOUND_REMOTE_ADDR = "INBOUND_REMOTE_ADDR"; + static final String INBOUND_SCHEME = "INBOUND_SCHEME"; + static final String INBOUND_PATH_VARIABLES = "INBOUND_PATH_VARIABLES"; + static final String INBOUND_REQUEST_MESSAGE = "INBOUND_REQUEST_MESSAGE"; + static final String INBOUND_CLIENT_IP = "INBOUND_CLIENT_IP"; + + static final String INBOUND_SYNC_ASYNC_TYPE = "INBOUND_SYNC_ASYNC_TYPE"; + + public static final String OUTBOUND_RESPONSE_HEADERS = "OUTBOUND_RESPONSE_HEADERS"; + public static final String OUTBOUND_RESPONSE_MESSAGE = "OUTBOUND_RESPONSE_MESSAGE"; + public static final String OUTBOUND_RESPONSE_STATUS = "OUTBOUND_RESPONSE_STATUS"; + public static final String OUTBOUND_PROPERTY_MAP = "OUTBOUND_PROPERTY_MAP"; + + // API path + static final String API_PATH = "API_PATH"; + + // 요청전 수행할 필터(쉼표(,)로 구분) + static final String PRE_FILTERS = "PRE_FILTERS"; + + // 요청후 수행할 필터(쉼표(,)로 구분) + static final String POST_FILTERS = "POST_FILTERS"; + + static final String ALLOW_IP = "ALLOW_IP"; + + static final String ENC_PATHS = "ENC_PATHS"; + + //응답 처리 용 표준 전문 오브젝트 + static final String STANDARD_MESSAGE_OBJECT = "STANDARD_MESSAGE_OBJECT"; +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java new file mode 100644 index 0000000..0077de4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceSupport.java @@ -0,0 +1,122 @@ +package com.eactive.eai.adapter.http.dynamic; + +import java.util.Properties; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.RequestDispatcher; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilter; +import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilterFactory; +import com.eactive.eai.adapter.http.dynamic.filter.HttpAdapterFilterType; +import com.eactive.eai.data.entity.onl.adapter.AdapterProp; + +public abstract class HttpAdapterServiceSupport implements HttpAdapterService, HttpAdapterServiceKey { + protected long slowTranTime = 2000L; + public static final String HEADER_NAME_CLIENT_ID = "x-elink-client-id"; + public static final String PROPERTIES_NAME_CLIENT_ID = "clientId"; + + public Object service(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + try { + String clientId = request.getHeader(HEADER_NAME_CLIENT_ID); + if (StringUtils.isNotBlank(clientId)) { + prop.put(PROPERTIES_NAME_CLIENT_ID, clientId); + } + + String transactionId = request.getHeader(HttpClientAdapterServiceKey.TRANSACTION_ID); + if (StringUtils.isNotBlank(transactionId)) { + prop.put(HttpClientAdapterServiceKey.TRANSACTION_ID, transactionId); + } + + String instanceId = request.getHeader(HttpClientAdapterServiceKey.INSTANCE_ID); + if (StringUtils.isNotBlank(instanceId)) { + prop.put(HttpClientAdapterServiceKey.INSTANCE_ID, instanceId); + } + } catch (Exception e) { + } + + message = doPreFilters(adptGrpName, adptName, message, prop, request, response); + Object obj = RequestDispatcher.getRequestDispatcher(adptGrpName).handle(adptName, message, prop); + obj = doPostFilters(adptGrpName, adptName, obj, prop, request, response); + if (obj == null) { + return null; + } else if (obj instanceof byte[]) { + return (byte[]) obj; + } else if (obj instanceof String) { + return (String) obj; + } else { + throw new Exception("RECEAIAHA001"); + } + } + + private Object doPreFilters(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + AdapterManager manager = AdapterManager.getInstance(); + AdapterGroupVO group = manager.getAdapterGroup(adptGrpName); + + if (!"HTC".equals(group.getType())) { + String allowIp = prop.getProperty(ALLOW_IP,""); + if (StringUtils.isNotBlank(allowIp)) { + HttpAdapterFilter adapterFilter = HttpAdapterFilterFactory.createFilter(HttpAdapterFilterType.ADAPTERALLOWIPLISTFILTER.toString()); + if (adapterFilter != null) { + message = adapterFilter.doPreFilter(adptGrpName, adptName, message, prop, request, response); + } + } + } + + String preFiltersStr = prop.getProperty(PRE_FILTERS); + if (StringUtils.isBlank(preFiltersStr)) { + return message; + } + + String[] preFilters = StringUtils.split(preFiltersStr, ","); + for (String filterName : preFilters) { + if (StringUtils.isBlank(filterName)) { + continue; + } + + HttpAdapterFilter adapterFilter = HttpAdapterFilterFactory.createFilter(filterName.trim()); + if (adapterFilter != null) { + message = adapterFilter.doPreFilter(adptGrpName, adptName, message, prop, request, response); + } else { + throw new Exception("Failed get Filter Class: " + filterName); + } + } + return message; + } + + private Object doPostFilters(String adptGrpName, String adptName, Object resultMessage, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + String postFiltersStr = prop.getProperty(POST_FILTERS); + if (StringUtils.isBlank(postFiltersStr)) { + return resultMessage; + } + + String[] postFilters = StringUtils.split(postFiltersStr, ","); + for (String filterName : postFilters) { + if (StringUtils.isBlank(filterName)) { + continue; + } + + HttpAdapterFilter adapterFilter = HttpAdapterFilterFactory.createFilter(filterName.trim()); + if (adapterFilter != null) { + resultMessage = adapterFilter.doPostFilter(adptGrpName, adptName, resultMessage, prop, request, + response); + } else { + throw new Exception("Failed get Filter Class: " + filterName); + } + } + return resultMessage; + } + + public abstract void service(String adptGrpName, String adptName, HttpServletRequest request, + HttpServletResponse response); +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceType.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceType.java new file mode 100644 index 0000000..a61a8ce --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpAdapterServiceType.java @@ -0,0 +1,17 @@ +package com.eactive.eai.adapter.http.dynamic; + +public enum HttpAdapterServiceType { + STANDARD, + CHNL, + PASS, + REST, + UNKNOWN + ; + public static HttpAdapterServiceType getValue(String value) { + try { + return valueOf(value.toUpperCase()); + } catch (Exception e) { + return UNKNOWN; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java new file mode 100644 index 0000000..cba7002 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterManager.java @@ -0,0 +1,199 @@ +package com.eactive.eai.adapter.http.dynamic; + +import com.eactive.eai.adapter.*; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.util.CamelCaseUtil; +import com.eactive.eai.common.util.Logger; +import org.apache.commons.lang3.StringUtils; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +public class HttpDynamicInAdapterManager implements Lifecycle { + + public static String HTTP_PARAM_TYPE = "HTTP_TYPE"; + public static String API_PATH = "API_PATH"; + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static HttpDynamicInAdapterManager instance = new HttpDynamicInAdapterManager(); + + private ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); + + public static HttpDynamicInAdapterManager getInstance() { + return instance; + } + + public HttpDynamicInAdapterUri getAdptUri(String uri) { + return adptUriMap.get( uri ); + } + + public void removeAdptUri(AdapterVO avo) { + try { + AdapterGroupVO gvo = avo.getAdapterGroupVO(); + if ( gvo.getType().equals(Keys.TYPE_HTTP) && gvo.getGubun().equals("I") ) { + removeAdptUri(avo.getAdapterGroupName(), avo.getName()); + } + } catch (Exception e) { + logger.error("HttpDynamicInAdapterManager] dynamic HTTP adpater remove error." + avo.toString(), e); + } + } + + public void removeAdptUri(String adptGrpName, String adptName) { + for( HttpDynamicInAdapterUri adptUri : adptUriMap.values() ) { + if ( adptUri.isEqualsAdpt(adptGrpName, adptName) ) { + adptUriMap.remove( adptUri.getUri() ); + if ( logger.isDebug() ) { + logger.debug("HttpDynamicInAdapterManager] remove " + adptGrpName + "-" + adptName ); + } + + break; + } + } + } + + public void setDynamicUrl(AdapterVO avo) throws Exception { + try { + AdapterGroupVO gvo = avo.getAdapterGroupVO(); + + if(gvo == null){ + removeAdptUriMapByAdapterGroupName(avo.getAdapterGroupName()); + } + else if ( gvo.getType().equals(Keys.TYPE_HTTP) && gvo.getGubun().equals("I") ) { + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties httpProp = manager.getProperties(avo.getPropGroupName()); + String httpType = httpProp.getProperty(HTTP_PARAM_TYPE,"STANDARD"); + String httpUrl = "/HTT/"+CamelCaseUtil.converCamelCaseWithBrace(avo.getAdapterGroupName(),"_"); + adptUriMap.put( httpUrl, new HttpDynamicInAdapterUri(avo.getAdapterGroupName(), avo.getName(), httpUrl, httpType)); + if ( logger.isDebug() ) { + logger.debug("HttpDynamicInAdapterManager] set " + avo.getAdapterGroupName() + "-" + avo.getName() + ", uri:" + httpUrl ); + } + } else if (gvo.getType().equals(Keys.TYPE_REST) && gvo.getGubun().equals("I")) { + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties httpProp = manager.getProperties(avo.getPropGroupName()); + String httpType = httpProp.getProperty(HTTP_PARAM_TYPE, "REST"); + String httpUrl = httpProp.getProperty(API_PATH); + httpUrl = StringUtils.removeEnd(httpUrl, "/"); + if (StringUtils.isNotBlank(httpUrl)) { + // /api/vi/public + if (!StringUtils.startsWith(httpUrl, "/")) { + httpUrl = "/" + httpUrl; + } + + // 1. URL이 이미 있는데, 그 URL이 다른 어댑터에 이미 설정되어 있다면 오류처리(기존 어댑터 보호) + HttpDynamicInAdapterUri adapterUri = adptUriMap.get(httpUrl); + + logger.debug("#### setDynamicUrl:"+adptUriMap.toString()); + + if (adapterUri != null + && !StringUtils.equals(avo.getAdapterGroupName(), adapterUri.getAdptGrpName())) { + throw new CommandException("The URI is already in use by another adapter, "+adapterUri.getAdptGrpName()); + } + + // 2. 어댑터 기준 기존 데이터 삭제 + removeAdptUriMapByAdapterGroupName(avo.getAdapterGroupName()); + + // 3. 새로 추가 + adptUriMap.put(httpUrl, + new HttpDynamicInAdapterUri(avo.getAdapterGroupName(), avo.getName(), httpUrl, httpType)); + if (logger.isDebug()) { + logger.debug("HttpDynamicInAdapterManager] set " + avo.getAdapterGroupName() + "-" + + avo.getName() + ", uri:" + httpUrl); + logger.debug("HttpDynamicInAdapterManager] adptUriMap " + adptUriMap.toString()); + } + } + } + } catch (CommandException e) { + throw new Exception(e.getMessage()); + } catch (Exception e) { + logger.error("HttpDynamicInAdapterManager] dynamic HTTP adapter add error." + avo.toString(), e); + } + } + + public void removeAdptUriMapByAdapterGroupName(String adapterGroupName) throws Exception { + for (HttpDynamicInAdapterUri adptUri : adptUriMap.values()) { + if (StringUtils.equals(adptUri.getAdptGrpName(), adapterGroupName)) { + adptUriMap.remove(adptUri.getUri()); + if (logger.isDebug()) { + logger.debug("HttpDynamicInAdapterManager] remove " + adptUri.toString() + " for "+adapterGroupName); + } + + break; + } + } + } + + @Override + public void addLifecycleListener(LifecycleListener listener) { + + + } + + @Override + public LifecycleListener[] findLifecycleListeners() { + + return null; + } + + @Override + public void removeLifecycleListener(LifecycleListener listener) { + + + } + + @Override + public void start() throws LifecycleException { + + AdapterManager adptManager = AdapterManager.getInstance(); + HashMap adptGrps = null; + + try { + adptGrps = adptManager.getAllAdapterGroupVO(); + + for(Object obj : adptGrps.values()) { + AdapterGroupVO gvo = (AdapterGroupVO)obj; + if(logger.isDebug()){ + logger.debug("adpter : "+gvo.getName()+"-->"+gvo.toString()); + } + if ((gvo.getType().equals(Keys.TYPE_HTTP) || gvo.getType().equals(Keys.TYPE_REST)) + && gvo.getGubun().equals("I")) { + ArrayList adpts = null; + Iterator i = gvo.getAdapters(); + + while ( i.hasNext() ) { + AdapterVO avo = (AdapterVO)i.next(); + setDynamicUrl( avo ); + } + } + } + } catch (Exception e) { + logger.error("HttpDynamicInAdapterManager] start error", e); + } + } + + @Override + public void stop() throws LifecycleException { + + } + + @Override + public boolean isStarted() { + + return false; + } + + @SuppressWarnings("rawtypes") + public void reloadAdapterUrl(AdapterGroupVO reloadGroupVO) throws Exception { + Iterator i = reloadGroupVO.getAdapters(); + while (i.hasNext()) { + AdapterVO avo = (AdapterVO) i.next(); + setDynamicUrl(avo); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterUri.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterUri.java new file mode 100644 index 0000000..91af6ce --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicInAdapterUri.java @@ -0,0 +1,99 @@ +package com.eactive.eai.adapter.http.dynamic; + +public class HttpDynamicInAdapterUri { + + public String adptGrpName = null; + public String adptName = null; + public String uri = null; + public String adptType = null; + public Integer listenPort = 0; + + public HttpDynamicInAdapterUri(String adptGrpName, String adptName, Integer port, String uri, String adptType) { + this.adptGrpName = adptGrpName; + this.adptName = adptName; + this.uri = uri; + this.adptType = adptType; + this.listenPort = port; + } + + public HttpDynamicInAdapterUri(String adptGrpName, String adptName, String uri, String adptType) { + this.adptGrpName = adptGrpName; + this.adptName = adptName; + this.uri = uri; + this.adptType = adptType; + this.listenPort = 0; + } + + public boolean isEqualsAdpt(HttpDynamicInAdapterUri other) { + return isEqualsAdpt(other.getAdptGrpName(), other.getAdptName()); + } + + public boolean isEqualsAdpt(String adptGrpName, String adptNamer) { + if ( adptGrpName != null && adptGrpName.equals(this.adptGrpName) + && adptName != null && adptName.equals(this.adptName) ) { + return true; + } else { + return false; + } + } + + public boolean isEqualsAdpt(String adptGrpName) { + if ( adptGrpName != null && adptGrpName.equals(this.adptGrpName)) { + return true; + } else { + return false; + } + } + + public String getAdptGrpName() { + return adptGrpName; + } + + public void setAdptGrpName(String adptGrpName) { + this.adptGrpName = adptGrpName; + } + + public String getAdptName() { + return adptName; + } + + public void setAdptName(String adptName) { + this.adptName = adptName; + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getAdptType() { + return adptType; + } + + public void setAdptType(String adptType) { + this.adptType = adptType; + } + + public Integer getListenPort() { + return listenPort; + } + + public void setListenPort(Integer listenPort) { + this.listenPort = listenPort; + } + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("HttpDynamicInAdapterUri[ adptGrpName=").append(adptGrpName); + sb.append(", adptName=").append(adptName); + sb.append(", port=").append(listenPort); + sb.append(", uri=").append(uri); + sb.append(", adptType=").append(adptType); + sb.append(" ]"); + + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicPortInAdapterManager.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicPortInAdapterManager.java new file mode 100644 index 0000000..d008925 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpDynamicPortInAdapterManager.java @@ -0,0 +1,511 @@ +package com.eactive.eai.adapter.http.dynamic; + +import com.eactive.eai.adapter.*; +import com.eactive.eai.adapter.http.dynamic.wrapper.KeepAliveFalseWrapper; +import com.eactive.eai.adapter.http.dynamic.wrapper.KeepAliveTrueWrapper; +import com.eactive.eai.adapter.http.util.HttpsGenerator; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.util.Logger; +import io.undertow.Handlers; +import io.undertow.Undertow; +import io.undertow.UndertowOptions; +import io.undertow.server.handlers.*; +import io.undertow.servlet.Servlets; +import io.undertow.servlet.api.DeploymentInfo; +import io.undertow.servlet.api.DeploymentManager; +import io.undertow.servlet.api.ServletInfo; +import org.apache.commons.lang3.StringUtils; + +import javax.net.ssl.SSLContext; +import javax.servlet.ServletException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +public class HttpDynamicPortInAdapterManager implements Lifecycle { + public String HTTP_PARAM_TYPE = "HTTP_TYPE"; + public String HTTP_LISTEN_PORT = "LISTEN_PORT"; + public String API_PATH = "API_PATH"; + + public String HTTPS_USE_YN = "HTTPS_USE_YN"; + public String HTTPS_KEY_STORE = "HTTPS_KEY_STORE"; + public String HTTPS_KEY_PASS = "HTTPS_KEY_PASS"; + + public String MAX_CONNECTION = "MAX_CONNECTION"; + public String QUEUE_SIZE = "QUEUE_SIZE"; + public String ALLOW_IP = "ALLOW_IP"; + + public final String IO_THREADS = "IO_THREADS"; + public final String WORKER_THREADS = "WORKER_THREADS"; + + //keep alive 관련 + public final String KEEP_ALIVE_YN = "KEEP_ALIVE_YN"; + public final String KEEP_ALIVE_TIMEOUT = "KEEP_ALIVE_TIMEOUT"; + public final String MAX_REQUEST_COUNT = "MAX_REQUEST_COUNT"; + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static HttpDynamicPortInAdapterManager instance = new HttpDynamicPortInAdapterManager(); + + // url - Adapter Map + private ConcurrentHashMap adptUriMap = new ConcurrentHashMap(); + + // adapter Name - Adapter Map + private ConcurrentHashMap adptNameMap = new ConcurrentHashMap(); + + // Listen Port - Adapter Map + private ConcurrentHashMap adptPortMap = new ConcurrentHashMap(); + + // Listen Port - Adapter Map + private ConcurrentHashMap svrPortMap = new ConcurrentHashMap(); + + @SuppressWarnings("unchecked") + public void addAdapter(AdapterVO adapter) throws Exception { + String adapterFullName; + + HttpDynamicInAdapterUri oldAdapterUri, newAdapterUri; + + String oldUri, newUri; + + // Port별 Adapter 목록 매핑 + ConcurrentHashMap adptPortSubMap; + + // 기존 Port Listener + Undertow oldListener; + + AdapterGroupVO gvo = adapter.getAdapterGroupVO(); + + if (gvo != null & gvo.getType().equals(Keys.TYPE_HTTP_CUSTOM) && gvo.getGubun().equals("I")) { + // Server Adapter인 경우 초기화 + adapterFullName = adapter.getAdapterGroupName() + "." + adapter.getName(); + oldAdapterUri = adptNameMap.get(adapterFullName); + + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties httpProp = manager.getProperties(adapter.getPropGroupName()); + String httpType = httpProp.getProperty(HTTP_PARAM_TYPE, "STANDARD"); + String portString = httpProp.getProperty(HTTP_LISTEN_PORT, "0"); + Integer listenPort = Integer.valueOf(portString); + if (listenPort.intValue() == 0) { + throw new CommandException("LISTEN_PORT is required."); + } + + newUri = httpProp.getProperty(API_PATH); + if (!StringUtils.equals(newUri, "/")) { + newUri = StringUtils.removeEnd(newUri, "/"); + } + if (StringUtils.isBlank(newUri)) { + throw new CommandException("API_PATH is required."); + } + + // /api/vi/public + if (!StringUtils.startsWith(newUri, "/")) { + newUri = "/" + newUri; + } + + newAdapterUri = new HttpDynamicInAdapterUri(adapter.getAdapterGroupName(), adapter.getName(), listenPort, + newUri, httpType); + + adptPortSubMap = null; + oldListener = null; + } else { + // Client Adapter 인 경우 무시 + return; + } + + // 1. Adapter 명으로 기 등록된 Adapter인지 확인 + // -- 이미 등록된 Adapter 이면 + if (oldAdapterUri != null) { + + if (oldAdapterUri.getListenPort() != 0) { + oldUri = adapterFullName + "/" + oldAdapterUri.getUri(); + + // 2. Port별 Adapter 정보 확인 및 제거 + Integer listenPort = oldAdapterUri.getListenPort(); + + adptPortSubMap = adptPortMap.get(listenPort); + if (adptPortSubMap != null) { + adptPortSubMap.remove(adapterFullName); + } + + // 2.1 해당 Port에 추가 Adapter가 없는 경우 해당 Listener 제거 + if (adptPortSubMap == null || adptPortSubMap.size() == 0) { + + // 2.1.1 해당 Port에 추가 Adapter가 없는 경우 Port 매핑 제거 + adptPortMap.remove(listenPort); + // 2.1.2 해당 Port에 추가 Adapter가 없는 경우 해당 Listener 제거 + oldListener = svrPortMap.get(listenPort); + svrPortMap.remove(listenPort); + if (oldListener != null) + oldListener.stop(); + } + + // 3. Adapter명 별 Adapter 정보 확인 및 제거 + adptNameMap.remove(adapterFullName); + } else { + oldUri = oldAdapterUri.getUri(); + // Default Adapter (WAS) 처리 + // adptUriMap만 처리 + adptUriMap.remove(oldUri); + } + + } + + // 신규 Adapter 추가 + if (newAdapterUri.getListenPort() != 0) { + // Port 별 Adapter 정보 등록 + adptPortSubMap = adptPortMap.get(newAdapterUri.getListenPort()); + if (adptPortSubMap == null) { + adptPortSubMap = new ConcurrentHashMap(); + adptPortMap.put(newAdapterUri.getListenPort(), adptPortSubMap); + } + adptPortSubMap.put(newAdapterUri.getUri(), newAdapterUri); + + // Adapter명 별 Adapter 정보 등록 + adptNameMap.put(adapterFullName, newAdapterUri); + } else { + // Default Adapter (WAS) 처리 + // adptUriMap만 등록 + adptUriMap.put(newUri, newAdapterUri); + } + } + + @SuppressWarnings("unchecked") + public void removeAdapter(AdapterVO adapter) throws Exception { + + String adapterFullName; + HttpDynamicInAdapterUri oldAdapterUri; + + // Port별 Adapter 목록 매핑 + ConcurrentHashMap adptPortSubMap; + + // 기존 Port Listener + Undertow oldListener; + + AdapterGroupVO gvo = adapter.getAdapterGroupVO(); + + if (gvo != null && gvo.getType().equals(Keys.TYPE_HTTP_CUSTOM) && gvo.getGubun().equals("I")) { + // Server Adapter 인 경우 초기화 + adapterFullName = adapter.getAdapterGroupName() + "." + adapter.getName(); + oldAdapterUri = adptNameMap.get(adapterFullName); + adptPortSubMap = null; + oldListener = null; + } else { + // Client Adapter 인 경우 무시 + return; + } + + if (oldAdapterUri != null) { + if (oldAdapterUri.getListenPort() != 0) { + + // 2. Port 별 Adapter 정보 확인 및 제거 + Integer listenPort = oldAdapterUri.getListenPort(); + + adptPortSubMap = adptPortMap.get(listenPort); + HttpDynamicInAdapterUri httpDynamicInAdapterUri = adptPortSubMap.get(oldAdapterUri.getUri()); + + // 20211201 어댑터 그룹체크, 동일하면 삭제 + if (httpDynamicInAdapterUri.getAdptGrpName().equals(oldAdapterUri.getAdptGrpName())) { + adptPortSubMap.remove(oldAdapterUri.getUri()); + } + + // 2.1 해당 Port에 추가 Adapter 없는 경우 해당 Listener 제거 + if (adptPortSubMap.size() == 0) { + // 2.1.1 해당 Port에 추가 Adapter 없는 경우 Port 매핑 제거 + adptPortMap.remove(listenPort); + // 2.1.2 해당 Port에 추가 Adapter 없는 경우 해당 Listener 제거 + oldListener = svrPortMap.get(listenPort); + try { + if (oldListener != null) { + oldListener.stop(); + } + } catch (Throwable t) { + // 중지 실패시 원복 + adptPortSubMap.put(oldAdapterUri.getUri(), oldAdapterUri); + adptPortMap.put(listenPort, adptPortSubMap); + throw t; + } + + // stop 성공후 삭제 + svrPortMap.remove(listenPort); + } + + // 3. Adapter명 별 Adapter 정보 확인 및 제거 + adptNameMap.remove(adapterFullName); + } else { + // Default Adapter(WAS) 처리 + // adptUriMap만 처리 + adptUriMap.remove(oldAdapterUri.getUri()); + } + } + } + + public static HttpDynamicPortInAdapterManager getInstance() { + return instance; + } + + public HttpDynamicInAdapterUri getAdptUri(String uri) { + return adptUriMap.get(uri); + } + + @SuppressWarnings("unchecked") + public HttpDynamicInAdapterUri getAdptUri(Integer port, String uri) { + ConcurrentHashMap tmpAdptUriMap = adptPortMap.get(port); + if (tmpAdptUriMap != null) + return tmpAdptUriMap.get(uri); + return null; + } + + @Override + public void addLifecycleListener(LifecycleListener listener) { + + } + + @Override + public LifecycleListener[] findLifecycleListeners() { + + return null; + } + + @Override + public void removeLifecycleListener(LifecycleListener listener) { + + } + + public void start(AdapterVO adapter) throws Exception { + AdapterGroupVO gvo = adapter.getAdapterGroupVO(); + + if (gvo != null && gvo.getType().equals(Keys.TYPE_HTTP_CUSTOM) && gvo.getGubun().equals("I")) { + // Server Adapter 인 경우 정보 확인 + AdapterPropManager adapterManager = AdapterPropManager.getInstance(); + Properties httpProp = adapterManager.getProperties(adapter.getPropGroupName()); + + String httpsUseYn = httpProp.getProperty(HTTPS_USE_YN, "N"); + String httpsKeyStore = httpProp.getProperty(HTTPS_KEY_STORE, null); + String httpsKeyPass = httpProp.getProperty(HTTPS_KEY_PASS, null); + + Integer listenPort = Integer.valueOf(httpProp.getProperty(HTTP_LISTEN_PORT, "0")); + Integer max_connection = Integer.valueOf(httpProp.getProperty(MAX_CONNECTION, "100")); + Integer max_queue = Integer.valueOf(httpProp.getProperty(QUEUE_SIZE, "3000")); + String allowIp = httpProp.getProperty(ALLOW_IP, null); + + Integer ioThreads = Integer.valueOf(httpProp.getProperty(IO_THREADS, "2")); + Integer workerThreads = Integer.valueOf(httpProp.getProperty(WORKER_THREADS, "16")); + + String keepAliveYn = httpProp.getProperty(KEEP_ALIVE_YN, "Y"); + Integer keepAliveTimeout = Integer.valueOf(httpProp.getProperty(KEEP_ALIVE_TIMEOUT, "15")); + Integer maxRequestCount = Integer.valueOf(httpProp.getProperty(MAX_REQUEST_COUNT, "-1")); + + boolean isKeepAlive = false; + if ("Y".equals(keepAliveYn)) { + isKeepAlive = true; + } + + // Custom Adapter 인 경우 재시작 + if (listenPort != 0) { + Undertow server = svrPortMap.get(listenPort); + if (server != null) { + // server.stop(); + // svrPortMap.remove(listenPort); + + return; + } + + ServletInfo servletInfo = Servlets.servlet(HttpAdapterCustom.class); + servletInfo.addMapping("/*"); + ServletInfo healthCheckServletInfo = Servlets.servlet(UndertowHealthCheckServlet.class); + healthCheckServletInfo.addMapping("healthcheck.html"); + + DeploymentInfo servletBuilder = Servlets.deployment() + .setClassLoader(HttpDynamicPortInAdapterManager.class.getClassLoader()) + .setDeploymentName("HttpDynamicCustomAdapter").setContextPath("/") + .addServlet(healthCheckServletInfo).addServlet(servletInfo); + if (isKeepAlive) { + KeepAliveTrueWrapper wrapper = new KeepAliveTrueWrapper(); + wrapper.setKeepAliveTimeout(keepAliveTimeout); + wrapper.setMaxRequestCount(maxRequestCount); + servletBuilder.addInitialHandlerChainWrapper(wrapper); + } else { + servletBuilder.addInitialHandlerChainWrapper(new KeepAliveFalseWrapper()); + } + DeploymentManager manager = Servlets.defaultContainer().addDeployment(servletBuilder); + manager.deploy(); + + PathHandler path = null; + IPAddressAccessControlHandler ipAddressAccessControlHandler = null; + RequestLimitingHandler requestLimitHandler = null; + + try { + path = Handlers.path(Handlers.redirect("/")).addPrefixPath("/", manager.start()); + if (allowIp != null && allowIp.length() > 1) { + String[] allowIps = allowIp.split(","); + ipAddressAccessControlHandler = Handlers.ipAccessControl(path, false); + for (int i = 0; i < allowIps.length; i++) { + ipAddressAccessControlHandler.addAllow(allowIps[i]); + } + } + + RequestLimit requestLimit = new RequestLimit(max_connection, max_queue); + requestLimit.setFailureHandler(ResponseCodeHandler.HANDLE_500); + + if (ipAddressAccessControlHandler != null) { + requestLimitHandler = Handlers.requestLimitingHandler(requestLimit, + ipAddressAccessControlHandler); + } else { + requestLimitHandler = Handlers.requestLimitingHandler(requestLimit, path); + } + + } catch (ServletException e) { + logger.error(e.getMessage(), e); + } + + SSLContext sslContext = null; + if (StringUtils.equalsIgnoreCase(httpsUseYn, "Y")) { +// if ((httpsKeyStore != null && httpsKeyStore.length() > 1) +// && (httpsKeyPass != null && httpsKeyPass.length() > 1)) { + sslContext = HttpsGenerator.createSSLContext(httpsKeyStore, httpsKeyPass); +// } + } + + logger.debug("####[" + adapter.getName() + "] ioThreads-->" + ioThreads); + logger.debug("####[" + adapter.getName() + "] workerThreads-->" + workerThreads); + Undertow.Builder builder = Undertow.builder().setIoThreads(ioThreads).setWorkerThreads(workerThreads); + if (sslContext != null) { + builder.addHttpsListener(listenPort, "0.0.0.0", sslContext); +// server = Undertow.builder().setIoThreads(ioThreads).setWorkerThreads(workerThreads) +// .addHttpsListener(listenPort, "0.0.0.0", sslContext).setHandler(requestLimitHandler) +// .build(); + } else { + builder.addHttpListener(listenPort, "0.0.0.0"); +// server = Undertow.builder().setIoThreads(ioThreads).setWorkerThreads(workerThreads) +// .addHttpListener(listenPort, "0.0.0.0").setHandler(requestLimitHandler).build(); + } + if (isKeepAlive){ + builder.setServerOption(UndertowOptions.NO_REQUEST_TIMEOUT, keepAliveTimeout * 1000); + } + builder.setHandler(requestLimitHandler); + server = builder.build(); + + try { + server.start(); + } catch (Throwable t) { + logger.error(t.getMessage()); + String adapterFullName = adapter.getAdapterGroupName() + "." + adapter.getName(); + throw new Exception("failed start: " + adapterFullName); + } + + svrPortMap.put(listenPort, server); + } + } + } + + @SuppressWarnings("unchecked") + public void stop(AdapterVO adapter) throws Exception { + AdapterGroupVO gvo = adapter.getAdapterGroupVO(); + + if (gvo != null && gvo.getType().equals(Keys.TYPE_HTTP_CUSTOM) && gvo.getGubun().equals("I")) { + // Server Adapter 인 경우 정보 확인 + AdapterPropManager adapterManager = AdapterPropManager.getInstance(); + + Properties httpProp = adapterManager.getProperties(adapter.getPropGroupName()); + String portString = httpProp.getProperty(HTTP_LISTEN_PORT, "0"); + Integer listenPort = Integer.valueOf(portString); + + // Custom Adapter 인 경우 재시작 + if (listenPort != 0) { + ConcurrentHashMap uriMap = adptPortMap.get(listenPort); + // 해당 Port로 수신하는 Adapter가 1개 이상 존재하는 경우 재시작 하지 않음 - 성능/안전성 이슈 + if (uriMap != null && uriMap.size() > 0) + return; + + Undertow server = svrPortMap.get(listenPort); + if (server != null) { + server.stop(); + svrPortMap.remove(listenPort); + } + } + } + } + + @Override + @SuppressWarnings({ "rawtypes" }) + public void start() throws LifecycleException { + try { + AdapterManager adptManager = AdapterManager.getInstance(); + HashMap adptGrps = adptManager.getAllAdapterGroupVO(); + + for (Object obj : adptGrps.values()) { + AdapterGroupVO gvo = (AdapterGroupVO) obj; + if (gvo.getType().equals(Keys.TYPE_HTTP_CUSTOM) && gvo.getGubun().equals("I")) { + Iterator i = gvo.getAdapters(); + while (i.hasNext()) { + AdapterVO avo = (AdapterVO) i.next(); + addAdapter(avo); + } + } + } + +// adptPortMap.forEach((port,uriList) -> { +// Undertow server = svrPortMap.get(port); +// +// if (server == null) { +// ConcurrentHashMap uriMap = uriList; +// ServletInfo servletInfo = Servlets.servlet(com.eactive.eai.adapter.http.dynamic.HttpAdapterCustom.class); +// uriMap.forEach((url,adapterUri) -> { +// //servletInfo.addMapping(adapterUri.getUri()); +// servletInfo.addMapping(adapterUri.getUri() + "/*"); +// }); +// +// DeploymentInfo servletBuilder = Servlets +// .deployment() +// .setClassLoader(HttpDynamicPortInAdapterManager.class.getClassLoader()) +// .setDeploymentName("HttpDynamicCustomAdapter") +// .setContextPath("/") +// .addServlet(servletInfo); +// DeploymentManager manager = Servlets.defaultContainer().addDeployment(servletBuilder); +// manager.deploy(); +// +// PathHandler path = null; +// +// try { +// path = Handlers.path(Handlers.redirect("/")).addPrefixPath("/", manager.start()); +// } catch (ServletException e) { +// logger.error(e.getMessage(), e); +// } +// +// server = Undertow.builder().addHttpListener(port, "0.0.0.0").setHandler(path).build(); +// +// svrPortMap.put(port, server); +// server.start(); +// +// } +// }); + } catch (Exception e) { + logger.error("HttpDynamicPortInAdapterManager] start error", e); + } + } + + @Override + public void stop() throws LifecycleException { + + try { + adptPortMap.forEach((port, UriList) -> { + Undertow server = svrPortMap.get(port); + + if (server != null) { + server.stop(); + } + }); + } catch (Exception e) { + logger.error("HttpDynamicPortInAdapterManager] stop error", e); + } + } + + @Override + public boolean isStarted() { + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpLoggerManager.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpLoggerManager.java new file mode 100644 index 0000000..0417b65 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/HttpLoggerManager.java @@ -0,0 +1,123 @@ +package com.eactive.eai.adapter.http.dynamic; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +import java.util.HashMap; +import java.util.Properties; + +public class HttpLoggerManager { + + private static HttpLoggerManager instance = new HttpLoggerManager(); + + private HashMap pool = new HashMap(); // KEY:adapterGroupName, VALUE:Logger + private String eaiServer; + private static String DEFAULT_LOGGER_NAME = "HTT"; + private static String ERROR_LOGGER_NAME = "ERRORHTT"; + + public HttpLoggerManager() { + eaiServer = EAIServerManager.getInstance().getLocalServerName(); + if (eaiServer == null) eaiServer = ""; + } + + public static HttpLoggerManager getInstance() { + return instance; + } + + public void stop() { + this.stop(); + } + + public void removeAll() { + pool.clear(); + } + + public void start(String adapterGroupName) { + this.addLogger(adapterGroupName); + } + + public synchronized void addLogger(String adapterGroupName) { + String loggerName = this.getLoggerName( adapterGroupName ); + Logger logger = pool.get( loggerName ); + if (logger == null) { + synchronized (pool) { + logger = pool.get(loggerName); + if (logger == null) { + Logger logger2 = Logger.getLogger(loggerName); + pool.put(loggerName, logger2); + } + } + } + } + + private String getLoggerName(String adapterGroupName) { + StringBuffer sb = new StringBuffer(); + sb.append("FileLogger{").append(adapterGroupName).append("}_").append(this.eaiServer); + + return sb.toString(); + } + + private String getLoggerBase(String adapterGroupName) { + StringBuffer strBuff = new StringBuffer(); + strBuff.append("FileLogger{").append(adapterGroupName).append("}"); + + return strBuff.toString(); + } + + public void removeLogger(String adapterGroupName) { + pool.remove(this.getLoggerName(adapterGroupName)); + } + + public void stop(String adapterGroupName) { + // adapterGroupNameÀÇ Session Stop & Clear + this.removeLogger(adapterGroupName); + } + + public Logger getLogger(String adapterGroupName) { + return getLoggerGroup(adapterGroupName); + } + + public Logger getErrLogger() { + return getLoggerGroup(ERROR_LOGGER_NAME); + } + + public Logger getLoggerGroup(String adapterGroupName) { + + Logger logger = pool.get(this.getLoggerName(adapterGroupName)); + if (logger == null) { + if (DEFAULT_LOGGER_NAME.equals(adapterGroupName)) { + this.addLogger(adapterGroupName); + logger = pool.get(this.getLoggerName(adapterGroupName)); + } else { + AdapterPropManager propManager = AdapterPropManager.getInstance(); + Properties loggerInfo = null; + + try { + loggerInfo = propManager.getProperties(getLoggerBase(adapterGroupName)); + } catch(Exception e) { + // ¹«½Ã + } + + if (loggerInfo == null) { + logger = getLogger(); + } else { + this.addLogger(adapterGroupName); + logger = pool.get(this.getLoggerName(adapterGroupName)); + } + } + } + + return logger; + } + + public Logger getLogger() { + Logger logger = pool.get(this.getLoggerName(this.DEFAULT_LOGGER_NAME)); + if (logger == null) { + this.addLogger(DEFAULT_LOGGER_NAME); + logger = pool.get(this.getLoggerName(DEFAULT_LOGGER_NAME)); + } + + return logger; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/RestApiAdapterMain.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/RestApiAdapterMain.java new file mode 100644 index 0000000..d522e03 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/RestApiAdapterMain.java @@ -0,0 +1,112 @@ +package com.eactive.eai.adapter.http.dynamic; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.InboundErrorLogger; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.UUIDGenerator; +import com.eactive.eai.inbound.error.InboundErrorInfoVO; +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Date; + +@SuppressWarnings("serial") +public class RestApiAdapterMain extends HttpServlet implements HttpAdapterServiceKey { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public void init() { + } + + public void service(HttpServletRequest request, HttpServletResponse response) { + HttpDynamicInAdapterManager manager = HttpDynamicInAdapterManager.getInstance(); + // /ONLWeb/api/v1/public/getUserInfo.svc + String apiUri = request.getRequestURI(); + // /api/v1/public/getUserInfo.svc + apiUri = StringUtils.removeStart(apiUri, request.getContextPath()); + apiUri = StringUtils.removeEnd(apiUri, "/"); + HttpDynamicInAdapterUri adptUri = findAdptUri(apiUri, manager); + + if (logger.isDebug()) { + logger.debug("HttpDynamicInAdapter] service request uri : " + request.getRequestURI()); + } + + if (adptUri == null) { + logError(request, response); + return; + } + HttpAdapterService service = HttpAdapterServiceFactory.createFactory(adptUri.getAdptType()); + service.service(adptUri.getAdptGrpName(), adptUri.getAdptName(), request, response); + } + + /** + * url에서 뒤쪽 /이후를 제거하면서 찾는다.
+ * /api/v1/public/getUserInfo.svc + * + * @param apiUri + * @return + */ + private HttpDynamicInAdapterUri findAdptUri(String apiUri, HttpDynamicInAdapterManager manager) { + if (StringUtils.isBlank(apiUri)) { + return null; + } + + for (int i = 0; i < 10; i++) { + HttpDynamicInAdapterUri adptUri = manager.getAdptUri(apiUri); + if (adptUri != null) { + return adptUri; + } + + // /api/v1/public + apiUri = StringUtils.substringBeforeLast(apiUri, "/"); + if (apiUri.length() < 4) { // /api + return null; + } + } + + return null; + } + + private void logError(HttpServletRequest request, HttpServletResponse response) { + InboundErrorInfoVO errorInfoVO = new InboundErrorInfoVO(); + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String serverName = eaiServerManager.getLocalServerName(); + String uuid = null; + StringBuffer sb = new StringBuffer(); + + String instanceid1 = serverName.substring(0, 2); + String instanceid2 = serverName.substring(serverName.length() - 2, serverName.length()); + String instid = instanceid1 + instanceid2; + uuid = instid + UUIDGenerator.getUUID(); + + String[] msgArgs = new String[1]; + msgArgs[0] = request.getRequestURI(); + + String errorCode = "RECEAIIRP010"; + String errorMsg = ExceptionUtil.make(new Exception("cat not find uri"), errorCode, msgArgs); + + errorInfoVO.setEaiSvcSno(uuid); // EAI서비스일련번호 + errorInfoVO.setAdptBwkGrpNm("HTTP_IN_NO_URI"); // 어댑터업무그룹명 + errorInfoVO.setErrCd(errorCode); // 에러코드 + errorInfoVO.setErrTxt(errorMsg); // 에러내용 + errorInfoVO.setErrTm(DatetimeUtil.getCurrentTime(new Date().getTime())); // 에러발생시각 + errorInfoVO.setErrDstcd(" "); + sb.append("Remote Addr : ").append(request.getRemoteAddr()).append("\n").append("Request URI : ") + .append(request.getRequestURI()); + errorInfoVO.setBwkDataTxt(sb.toString()); // 업무데이터내용 + errorInfoVO.setEaiSvrInstNm(serverName); // EAI서버인스턴스명 + + InboundErrorLogger.error(errorInfoVO); + + response.setStatus(404); + try { + response.getWriter().println("can not find uri '" + request.getRequestURI() + "'"); + } catch (Exception ex) { + // IGNORE + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/UndertowHealthCheckServlet.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/UndertowHealthCheckServlet.java new file mode 100644 index 0000000..3826833 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/UndertowHealthCheckServlet.java @@ -0,0 +1,17 @@ +package com.eactive.eai.adapter.http.dynamic; + +import io.undertow.servlet.handlers.DefaultServlet; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@SuppressWarnings("serial") +public class UndertowHealthCheckServlet extends DefaultServlet { + + protected void service(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + response.getWriter().print(""); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/AdapterAllowIPListFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/AdapterAllowIPListFilter.java new file mode 100644 index 0000000..ec2c703 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/AdapterAllowIPListFilter.java @@ -0,0 +1,79 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.util.IpUtil; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpStatus; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class AdapterAllowIPListFilter implements HttpAdapterFilter { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + @Override + public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + + String requestIp = getClientIp(request); + try { + String allowedIps = prop.getProperty(HttpAdapterServiceKey.ALLOW_IP, ""); + if (StringUtils.isBlank(allowedIps)) { + return message; + } + + if (!IpUtil.isMatchIp(allowedIps, requestIp)) { + throw new HttpStatusException("This IP was not allowed-" + requestIp, HttpStatus.FORBIDDEN.value()); + } + } catch (HttpStatusException e) { + logger.debug(e.getMessage()); + throw e; + } catch (Exception e) { + logger.error(e.getMessage()); + throw new JwtAuthException(JwtAuthFilter.ERROR_AUTHORIZATION_FAIL, "Client IP check failed-" + requestIp); + } + + return message; + } + + private String getClientIp(HttpServletRequest request) { + String ipAddress = request.getHeader("X-FORWARDED-FOR"); + if (ipAddress == null) { + ipAddress = request.getRemoteAddr(); + } + if(ipAddress.indexOf(",") >= 0) { + ipAddress = org.springframework.util.StringUtils.tokenizeToStringArray(ipAddress, ",")[0]; + } + return ipAddress; + } + + private String assignClientId(Properties prop, HttpServletRequest request) { + String clientId = null; + try { + // 이전 filter에서 셋팅한 clientId 확보 + clientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); + + // 이전 filter에서 셋팅한 값이 없다면 header 정보에서 확보 + if (StringUtils.isBlank(clientId)) { + clientId = request.getHeader(HttpAdapterServiceSupport.HEADER_NAME_CLIENT_ID); + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + + return clientId; + } + + @Override + public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + return resultMessage; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java new file mode 100644 index 0000000..c3458e6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/ApiAuthFilter.java @@ -0,0 +1,258 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.authserver.vo.ClientVO; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageManager; +import com.eactive.eai.common.property.PropGroupVO; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.stdmessage.STDMessageManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.inbound.action.ActionFactory; +import com.eactive.eai.inbound.action.RequestAction; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.StandardMessageUtil; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.nimbusds.jose.JWSVerifier; +import com.nimbusds.jose.crypto.RSASSAVerifier; +import com.nimbusds.jose.util.IOUtils; +import com.nimbusds.jwt.SignedJWT; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.text.ParseException; +import java.util.Base64; +import java.util.Date; +import java.util.HashSet; +import java.util.Properties; + +public class ApiAuthFilter implements HttpAdapterFilter { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public static final String PROP_GROUP_AUTH_SERVER = "OAuthServer"; + public static final String PROP_KEYSTORE_PATH = "certification.publicKeyPath"; + + public static final String ERROR_AUTHENTICATION_FAIL = "E.AUTHENTICATION_FAIL"; + public static final String ERROR_AUTHORIZATION_FAIL = "E.AUTHORIZATION_FAIL"; + public static final String ERROR_TOKEN_EXPIRED = "E.TOKEN_EXPIRED"; + + public static final String PAYLOAD_PARAM_NAME_SCOPE = "scope"; + public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; + + private JWSVerifier jwsVerifier; + + public ApiAuthFilter() { + super(); + + PropGroupVO vo = PropManager.getInstance().getPropGroupVO(PROP_GROUP_AUTH_SERVER); + String publicKeyPath = "/certificate/elink-oauth-dev.pub"; + if (vo != null) { + publicKeyPath = vo.getProperty(PROP_KEYSTORE_PATH); + } else { + logger.warn("The properties has not been set.[" + PROP_GROUP_AUTH_SERVER + "]"); + } + + Resource resource = new ClassPathResource(publicKeyPath); + String publicKey = null; + try { + publicKey = IOUtils.readInputStreamToString(resource.getInputStream()); + publicKey = StringUtils.replace(publicKey, "-----BEGIN PUBLIC KEY-----", ""); + publicKey = StringUtils.replace(publicKey, "-----END PUBLIC KEY-----", ""); + publicKey = StringUtils.remove(publicKey, "\r"); + publicKey = StringUtils.remove(publicKey, "\n"); + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + jwsVerifier = new RSASSAVerifier((RSAPublicKey) keyFactory.generatePublic(keySpec)); + } catch (IOException | NoSuchAlgorithmException | RuntimeException | InvalidKeySpecException e) { + throw new RuntimeException(e); + } + } + + @Override + public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + String apiId = assignApiId(adptGrpName, adptName, message, prop, request); + if (StringUtils.isBlank(apiId)) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Can not find apiId(apiCode) info"); + } + + /** + * TODO: 중복되는 표준메시지 조회로 리소드 낭비가 있을 수 있으므로 체크 자체를 추후 RequestProcessor혹은 RestProcessor로 이동 필요 해 보임 + * ApiRequestProcessor을 만드는것도 괜찮을 수 있을 것 같으나 관리가 안될 것 같음 + */ + StandardMessage standardMessage = STDMessageManager.getInstance().getSTDMessage(apiId); + String eaiSvcCd = StandardMessageManager.getInstance().getMapper().getEaiSvcCode(standardMessage); + EAIMessage eaiMessage = EAIMessageManager.getInstance().getEAIMessage(eaiSvcCd); + + if(StringUtils.isBlank(eaiMessage.getAuthType())){ + return message; + } + + switch (eaiMessage.getAuthType()){ + case "oauth": + try { + String token = ApiAuthFilter.extractJWTToken(request); + SignedJWT signedJWT = SignedJWT.parse(token); + + if (new Date().after(signedJWT.getJWTClaimsSet().getExpirationTime())) { + throw new JwtAuthException(ERROR_TOKEN_EXPIRED, "Access token expired"); + } + + if (!signedJWT.verify(jwsVerifier)) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); + } + + OAuth2Manager manager = OAuth2Manager.getInstance(); + HashSet scopeSet = manager.getApiScopeMap().get(apiId); + if (!verifyScope(scopeSet, signedJWT)) { + throw new JwtAuthException(ERROR_AUTHORIZATION_FAIL, + String.format("Insufficient [Scope](Allowed Scope=%s)", scopeSet.toString())); + } + + // header 값으로 전송된 clientId와 토큰 소유 clientId check + if (!verifyClientId(prop, signedJWT)) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "client_id not matched(header/token)"); + } + } catch (JwtAuthException e) { + logger.debug(e.getMessage()); + throw e; + } catch (Exception e) { + logger.error(e.getMessage()); + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); + } + break; + case "api_key": + String apiKeyName = PropManager.getInstance().getProperty("ApiConfig", "api.key.name", "x-api-key"); + String apiKey = request.getHeader(apiKeyName); + if(apiKey == null){ + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Invalid or missing API key \""+apiKeyName+"\" in Http Header"); + } + prop.setProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, apiKey); + break; + case "none": + return message; + } + + String clientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); + ClientVO clientVO = OAuth2Manager.getInstance().getClientVO(clientId); + if(clientVO == null){ + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Unregistered APP"); + } + + if(clientVO.getApiMap().containsKey(eaiSvcCd) == false){ + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Unregistered API ["+eaiSvcCd+"] in ["+clientVO.getClientName()+"] APP"); + } + + return message; + } + + private boolean verifyClientId(Properties prop, SignedJWT signedJWT) { + try { + // 이전 filter에서 셋팅한 clientId 확보 + String headerClientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); + String tokenClientId = (String) signedJWT.getJWTClaimsSet().getClaim(PAYLOAD_PARAM_NAME_CLIENT_ID); + + // 이전 filter에서 셋팅한 값이 없다면 token 정보에서 확보 + if (StringUtils.isBlank(headerClientId)) { + if (StringUtils.isNotBlank(tokenClientId)) { + prop.put(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, tokenClientId); + } + } else { // header로 전달된 clientId가 있을때만 비교 + if (!headerClientId.equals(tokenClientId)) { + return false; + } + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + + return true; + } + + private String assignApiId(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request) { + String apiId = null; + try { + String actionName = prop.getProperty(Processor.REQUEST_ACTION); + RequestAction action = ActionFactory.createAction(actionName); + action.setAdapterInfo(adptGrpName, adptName, prop); + String[] keys = action.perform(message); + apiId = keys[0]; + + // PathVariable 지원 추가 + apiId = StandardMessageUtil.getMatchedKey(apiId, actionName); + } catch (Exception e) { + logger.error(e.getMessage()); + } + +// // header 에서 확보 +// String apiId = request.getHeader(HEADER_NAME_API_CODE); +// if (StringUtils.isBlank(apiId)) { +// // url에서 확보 +// // /ONLWeb/api/v1/public/getUserInfo.svc/ +// apiId = request.getRequestURI(); +// // /ONLWeb/api/v1/public/getUserInfo.svc +// apiId = StringUtils.removeEnd(apiId, "/"); +// // getUserInfo.svc +// apiId = StringUtils.substringAfterLast(apiId, "/"); +// } + + return apiId; + } + + @Override + public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + return resultMessage; + } + + private boolean verifyScope(HashSet scopeSet, SignedJWT signedJWT) throws ParseException { + if (scopeSet == null || scopeSet.isEmpty()) { + return true; // If no scope is specified in the api, all are allowed + } + + String[] scopeArr = signedJWT.getJWTClaimsSet().getStringArrayClaim(PAYLOAD_PARAM_NAME_SCOPE); + if (scopeArr == null || scopeArr.length == 0) { + return false; + } + + for (String scope : scopeArr) { + if (scopeSet.contains(scope)) { + return true; + } + } + + return false; + } + + public static String extractJWTToken(HttpServletRequest request) throws JwtAuthException { + String authorization = request.getHeader("Authorization"); + if (StringUtils.isBlank(authorization)) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "No have header info: Authorization"); + } + + String[] components = authorization.split("\\s"); + + if (components.length != 2) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Malformat [Authorization] content"); + } + + if (!StringUtils.equalsIgnoreCase(components[0], "Bearer")) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "[Bearer] is needed"); + } + + return components[1].trim(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilter.java new file mode 100644 index 0000000..600ed1a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilter.java @@ -0,0 +1,15 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +import java.util.Properties; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public interface HttpAdapterFilter { + + public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception; + + public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception; +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactory.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactory.java new file mode 100644 index 0000000..0f1837b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterFactory.java @@ -0,0 +1,52 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +import java.util.concurrent.ConcurrentHashMap; + +import com.eactive.eai.common.util.Logger; + +public class HttpAdapterFilterFactory { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + static private ConcurrentHashMap h = new ConcurrentHashMap(); + + public HttpAdapterFilterFactory() { + super(); + } + + @SuppressWarnings("rawtypes") + public static HttpAdapterFilter createFilter(String type) { + if (h.containsKey(type)) { + return (HttpAdapterFilter) h.get(type); + } + + HttpAdapterFilter filter = null; + switch (HttpAdapterFilterType.getValue(type)) { + case APIAUTHFILTER: + filter = new ApiAuthFilter(); + break; + case JWTAUTHFILTER: + filter = new JwtAuthFilter(); + break; + case IPWHITELISTFILTER: + filter = new IpWhiteListFilter(); + break; + case ADAPTERALLOWIPLISTFILTER: + filter = new AdapterAllowIPListFilter(); + break; + default: + try { + Class cl = Class.forName(type); + filter = (HttpAdapterFilter) cl.newInstance(); + } catch (Exception e) { + logger.error("Cannot create a HttpAdapterFilter. - {}", type); + } + break; + } + + if (filter != null) { + h.put(type, filter); + return filter; + } else { + return null; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java new file mode 100644 index 0000000..6231c74 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/HttpAdapterFilterType.java @@ -0,0 +1,17 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +public enum HttpAdapterFilterType { + APIAUTHFILTER, + JWTAUTHFILTER, + IPWHITELISTFILTER, + ADAPTERALLOWIPLISTFILTER, + UNKNOWN; + + public static HttpAdapterFilterType getValue(String type) { + try { + return valueOf(type.toUpperCase()); + } catch (Exception e) { + return UNKNOWN; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/IpWhiteListFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/IpWhiteListFilter.java new file mode 100644 index 0000000..28e00e6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/IpWhiteListFilter.java @@ -0,0 +1,90 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.authserver.vo.ClientVO; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.util.IpUtil; + +public class IpWhiteListFilter implements HttpAdapterFilter { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + @Override + public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + String clientId = assignClientId(prop, request); + if (StringUtils.isBlank(clientId)) { + throw new JwtAuthException(JwtAuthFilter.ERROR_AUTHORIZATION_FAIL, "Can not find clientId info"); + } + + String requestIp = getClientIp(request); + try { + ClientVO client = (ClientVO) OAuth2Manager.getInstance().getClientDeatilsStore().get(clientId); + if (client == null) { + throw new JwtAuthException(JwtAuthFilter.ERROR_AUTHORIZATION_FAIL, "Can not find client info"); + } + + String allowedIps = client.getAllowedIp(); + if (StringUtils.isBlank(allowedIps)) { + throw new JwtAuthException(JwtAuthFilter.ERROR_AUTHORIZATION_FAIL, + "Allowed IP is not set in client info"); + } + + if (!IpUtil.isMatchIp(allowedIps, requestIp)) { + throw new JwtAuthException(JwtAuthFilter.ERROR_AUTHORIZATION_FAIL, + "This IP was not allowed-" + requestIp); + } + } catch (JwtAuthException e) { + logger.debug(e.getMessage()); + throw e; + } catch (Exception e) { + logger.error(e.getMessage()); + throw new JwtAuthException(JwtAuthFilter.ERROR_AUTHORIZATION_FAIL, "Client IP check failed-" + requestIp); + } + + return message; + } + + private String getClientIp(HttpServletRequest request) { + String ipAddress = request.getHeader("X-FORWARDED-FOR"); + if (ipAddress == null) { + ipAddress = request.getRemoteAddr(); + } + if(ipAddress.indexOf(",") >= 0) { + ipAddress = org.springframework.util.StringUtils.tokenizeToStringArray(ipAddress, ",")[0]; + } + return ipAddress; + } + + private String assignClientId(Properties prop, HttpServletRequest request) { + String clientId = null; + try { + // 이전 filter에서 셋팅한 clientId 확보 + clientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); + + // 이전 filter에서 셋팅한 값이 없다면 header 정보에서 확보 + if (StringUtils.isBlank(clientId)) { + clientId = request.getHeader(HttpAdapterServiceSupport.HEADER_NAME_CLIENT_ID); + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + + return clientId; + } + + @Override + public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + return resultMessage; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthException.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthException.java new file mode 100644 index 0000000..3dbf36b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthException.java @@ -0,0 +1,28 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +@SuppressWarnings("serial") +public class JwtAuthException extends Exception { + private String code; + + public JwtAuthException(String message) { + super(message); + } + + public JwtAuthException(String code, String message) { + super(message); + this.code = code; + } + + public JwtAuthException(String code, String message, Throwable cause) { + super(message, cause); + this.code = code; + } + + public String getCode() { + return code; + } + + public String toString() { + return getClass().getName() + ": [" + code + "] " + getLocalizedMessage(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthFilter.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthFilter.java new file mode 100644 index 0000000..1de5a38 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/filter/JwtAuthFilter.java @@ -0,0 +1,218 @@ +package com.eactive.eai.adapter.http.dynamic.filter; + +import java.io.IOException; +import java.security.KeyFactory; +import java.security.NoSuchAlgorithmException; +import java.security.interfaces.RSAPublicKey; +import java.security.spec.InvalidKeySpecException; +import java.security.spec.X509EncodedKeySpec; +import java.text.ParseException; +import java.util.Base64; +import java.util.Date; +import java.util.HashSet; +import java.util.Properties; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.common.property.PropGroupVO; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.inbound.action.ActionFactory; +import com.eactive.eai.inbound.action.RequestAction; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessageUtil; +import com.nimbusds.jose.JWSVerifier; +import com.nimbusds.jose.crypto.RSASSAVerifier; +import com.nimbusds.jose.util.IOUtils; +import com.nimbusds.jwt.SignedJWT; + +public class JwtAuthFilter implements HttpAdapterFilter { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public static final String PROP_GROUP_AUTH_SERVER = "OAuthServer"; + public static final String PROP_KEYSTORE_PATH = "certification.publicKeyPath"; + + public static final String ERROR_AUTHENTICATION_FAIL = "E.AUTHENTICATION_FAIL"; + public static final String ERROR_AUTHORIZATION_FAIL = "E.AUTHORIZATION_FAIL"; + public static final String ERROR_TOKEN_EXPIRED = "E.TOKEN_EXPIRED"; + + public static final String PAYLOAD_PARAM_NAME_SCOPE = "scope"; + public static final String PAYLOAD_PARAM_NAME_CLIENT_ID = "client_id"; + + private JWSVerifier jwsVerifier; + + public JwtAuthFilter() { + super(); + + PropGroupVO vo = PropManager.getInstance().getPropGroupVO(PROP_GROUP_AUTH_SERVER); + String publicKeyPath = "/certificate/elink-oauth-dev.pub"; + if (vo != null) { + publicKeyPath = vo.getProperty(PROP_KEYSTORE_PATH); + } else { + logger.warn("The properties has not been set.[" + PROP_GROUP_AUTH_SERVER + "]"); + } + + Resource resource = new ClassPathResource(publicKeyPath); + String publicKey = null; + try { + publicKey = IOUtils.readInputStreamToString(resource.getInputStream()); + publicKey = StringUtils.replace(publicKey, "-----BEGIN PUBLIC KEY-----", ""); + publicKey = StringUtils.replace(publicKey, "-----END PUBLIC KEY-----", ""); + publicKey = StringUtils.remove(publicKey, "\r"); + publicKey = StringUtils.remove(publicKey, "\n"); + + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey)); + KeyFactory keyFactory = KeyFactory.getInstance("RSA"); + jwsVerifier = new RSASSAVerifier((RSAPublicKey) keyFactory.generatePublic(keySpec)); + } catch (IOException | NoSuchAlgorithmException | RuntimeException | InvalidKeySpecException e) { + throw new RuntimeException(e); + } + } + + @Override + public Object doPreFilter(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + String apiId = assignApiId(adptGrpName, adptName, message, prop, request); + if (StringUtils.isBlank(apiId)) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Can not find apiId(apiCode) info"); + } + + try { + String token = JwtAuthFilter.extractJWTToken(request); + SignedJWT signedJWT = SignedJWT.parse(token); + + if (new Date().after(signedJWT.getJWTClaimsSet().getExpirationTime())) { + throw new JwtAuthException(ERROR_TOKEN_EXPIRED, "Access token expired"); + } + + if (!signedJWT.verify(jwsVerifier)) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); + } + + OAuth2Manager manager = OAuth2Manager.getInstance(); + HashSet scopeSet = manager.getApiScopeMap().get(apiId); + if (!verifyScope(scopeSet, signedJWT)) { + throw new JwtAuthException(ERROR_AUTHORIZATION_FAIL, + String.format("Insufficient [Scope](Allowed Scope=%s)", scopeSet.toString())); + } + + // header 값으로 전송된 clientId와 토큰 소유 clientId check + if (!verifyClientId(prop, signedJWT)) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "client_id not matched(header/token)"); + } + } catch (JwtAuthException e) { + logger.debug(e.getMessage()); + throw e; + } catch (Exception e) { + logger.error(e.getMessage()); + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Token invalid"); + } + + return message; + } + + private boolean verifyClientId(Properties prop, SignedJWT signedJWT) { + try { + // 이전 filter에서 셋팅한 clientId 확보 + String headerClientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); + String tokenClientId = (String) signedJWT.getJWTClaimsSet().getClaim(PAYLOAD_PARAM_NAME_CLIENT_ID); + + // 이전 filter에서 셋팅한 값이 없다면 token 정보에서 확보 + if (StringUtils.isBlank(headerClientId)) { + if (StringUtils.isNotBlank(tokenClientId)) { + prop.put(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID, tokenClientId); + } + } else { // header로 전달된 clientId가 있을때만 비교 + if (!headerClientId.equals(tokenClientId)) { + return false; + } + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + + return true; + } + + private String assignApiId(String adptGrpName, String adptName, Object message, Properties prop, + HttpServletRequest request) { + String apiId = null; + try { + String actionName = prop.getProperty(Processor.REQUEST_ACTION); + RequestAction action = ActionFactory.createAction(actionName); + action.setAdapterInfo(adptGrpName, adptName, prop); + String[] keys = action.perform(message); + apiId = keys[0]; + + // PathVariable 지원 추가 + apiId = StandardMessageUtil.getMatchedKey(apiId, actionName); + } catch (Exception e) { + logger.error(e.getMessage()); + } + +// // header 에서 확보 +// String apiId = request.getHeader(HEADER_NAME_API_CODE); +// if (StringUtils.isBlank(apiId)) { +// // url에서 확보 +// // /ONLWeb/api/v1/public/getUserInfo.svc/ +// apiId = request.getRequestURI(); +// // /ONLWeb/api/v1/public/getUserInfo.svc +// apiId = StringUtils.removeEnd(apiId, "/"); +// // getUserInfo.svc +// apiId = StringUtils.substringAfterLast(apiId, "/"); +// } + + return apiId; + } + + @Override + public Object doPostFilter(String adptGrpName, String adptName, Object resultMessage, Properties prop, + HttpServletRequest request, HttpServletResponse response) throws Exception { + return resultMessage; + } + + private boolean verifyScope(HashSet scopeSet, SignedJWT signedJWT) throws ParseException { + if (scopeSet == null || scopeSet.isEmpty()) { + return true; // If no scope is specified in the api, all are allowed + } + + String[] scopeArr = signedJWT.getJWTClaimsSet().getStringArrayClaim(PAYLOAD_PARAM_NAME_SCOPE); + if (scopeArr == null || scopeArr.length == 0) { + return false; + } + + for (String scope : scopeArr) { + if (scopeSet.contains(scope)) { + return true; + } + } + + return false; + } + + public static String extractJWTToken(HttpServletRequest request) throws JwtAuthException { + String authorization = request.getHeader("Authorization"); + if (StringUtils.isBlank(authorization)) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "No have header info: Authorization"); + } + + String[] components = authorization.split("\\s"); + + if (components.length != 2) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "Malformat [Authorization] content"); + } + + if (!StringUtils.equalsIgnoreCase(components[0], "Bearer")) { + throw new JwtAuthException(ERROR_AUTHENTICATION_FAIL, "[Bearer] is needed"); + } + + return components[1].trim(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java new file mode 100644 index 0000000..0d47483 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceBypass.java @@ -0,0 +1,508 @@ +package com.eactive.eai.adapter.http.dynamic.impl; + +import java.net.HttpCookie; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Properties; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.apache.mina.common.ByteBuffer; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.util.AntPathMatcher; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.inbound.action.ActionFactory; +import com.eactive.eai.inbound.action.RequestAction; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessageUtil; + +public class HttpAdapterServiceBypass extends HttpAdapterServiceSupport { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public static final String HTTP_STATUS = "HTTP_STATUS"; + public static final String PROPERTIES_NAME_HTTP_REQUEST_METHOD = "httpRequestMethod"; + public static final String[] HOP_BY_HOP_HEADERS = new String[] { "Connection", "Keep-Alive", "Proxy-Authenticate", + "Proxy-Authorization", "TE", "Trailers", "Transfer-Encoding", "Upgrade" }; + + protected boolean doPreserveCookies = false; + protected boolean doPreserveCookiePath = false; + + /** + * 1. 기능 : Header 값과 Body 값을 Bypass 한다. + * + * @param request Http Servlet Request + * @return response Http Servlet Response + * @exception Exception + **/ + public void service(String adptGrpName, String adptName, HttpServletRequest request, HttpServletResponse response) { + int traceLevel = 0; + + AdapterVO adptVO = null; + AdapterPropManager manager = null; + + Properties httpProp = null; + String responseType = null; + String encode = null; + + String traceLevelTemp = null; + + StopWatch stopWatch = null; + Properties prop = null; + String errorResponseFormat = null; + + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + adptVO = adapterManager.getAdapterVO(adptGrpName, adptName); + if (adptVO == null) { + throw new Exception("Adapter not found error"); + } + + manager = AdapterPropManager.getInstance(); + + httpProp = manager.getProperties(adptVO.getPropGroupName()); + responseType = httpProp.getProperty(RESPONSE_TYPE, "SYNC"); + encode = StringUtils.defaultIfBlank(adptVO.getAdapterGroupVO().getMessageEncode(), "UTF-8"); + traceLevelTemp = httpProp.getProperty(TRACE_LEVEL, "0"); + errorResponseFormat = httpProp.getProperty(ERROR_RESPONSE_FORMAT); + + try { + traceLevel = Integer.parseInt(traceLevelTemp); + } catch (Exception e) { + logger.warn("traceLevel parsing error - " + traceLevelTemp); + } + + stopWatch = new StopWatch(); + stopWatch.start(); + + logger.debug("시작 >> encode = [" + encode + "]"); + + String requestData = ""; + if (request.getHeader(HttpHeaders.CONTENT_LENGTH) != null + || request.getHeader(HttpHeaders.TRANSFER_ENCODING) != null) { + ServletInputStream sis = request.getInputStream(); + ByteBuffer bb = ByteBuffer.allocate(1024).setAutoExpand(true); + int i = 0; + byte[] cbuf = new byte[1024]; + while ((i = sis.read(cbuf, 0, 1024)) != -1) { + if (i == 1024) { + bb.put(cbuf); + } else { + byte[] tail = new byte[i]; + System.arraycopy(cbuf, 0, tail, 0, i); + bb.put(tail); + } + } + byte[] data = new byte[bb.position()]; + bb.position(0); + bb.get(data); + requestData = new String(data, encode); + + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, + "RECV " + "[Bypass Request..]" + CommonLib.getDumpMessage(requestData)); + } + } + + prop = new Properties(); + prop.put(INBOUND_METHOD, request.getMethod()); + prop.put(INBOUND_URI, request.getRequestURI()); + prop.put(INBOUND_QUERY_STRING, StringUtils.defaultString(request.getQueryString())); + prop.put(INBOUND_HEADER, getHeaders(request)); + if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) + || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { + // /api/v1/public/getUserInfo.svc + String extUrl = StringUtils.removeStart(request.getRequestURI(), request.getContextPath()); + prop.put(INBOUND_EXTURI, extUrl); + } else { + prop.put(INBOUND_EXTURI, getExtUri(request)); + } + prop.put(Processor.REQUEST_ACTION, adptVO.getAdapterGroupVO().getRefClass()); + prop.put(API_PATH, httpProp.getProperty(API_PATH, "")); + prop.put(INBOUND_REWRITE_PATH, + getRewritePath(prop.getProperty(INBOUND_EXTURI), prop.getProperty(API_PATH))); + prop.put(INBOUND_REMOTE_ADDR, request.getRemoteAddr()); + prop.put(INBOUND_SCHEME, request.getScheme()); + prop.put(PRE_FILTERS, httpProp.getProperty(PRE_FILTERS, "")); + prop.put(POST_FILTERS, httpProp.getProperty(POST_FILTERS, "")); + prop.put(PROPERTIES_NAME_HTTP_REQUEST_METHOD, request.getMethod()); + prop.put(ALLOW_IP, httpProp.getProperty(ALLOW_IP, "")); + + Map pathVariables = assignPathVariables(request, adptGrpName, adptName, null, prop); + if (pathVariables != null) { + prop.put(INBOUND_PATH_VARIABLES, pathVariables); + } + + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceBypass] INBOUND_METHOD= " + prop.getProperty(INBOUND_METHOD)); + logger.debug("HttpAdapterServiceBypass] INBOUND_URI= " + prop.getProperty(INBOUND_URI)); + logger.debug("HttpAdapterServiceBypass] INBOUND_EXTURI= " + prop.getProperty(INBOUND_EXTURI)); + logger.debug( + "HttpAdapterServiceBypass] INBOUND_QUERY_STRING= " + prop.getProperty(INBOUND_QUERY_STRING)); + } + +// // check(현재 어댑터 = 서비스정보의 기동어댑터) +// if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST)) { +// validateServiceAndAdapter(adptGrpName, adptName, message.getBytes(encode), prop); +// } + + // 로컬 서비스 호출 + String result = (String) service(adptGrpName, adptName, requestData, prop, request, response); + + stopWatch.stop(); + logger.info("종료 >> encode = [" + encode + "]"); + + if (RESPONSE_TYPE_ASYNC.equals(responseType)) { + String responseData = ""; + if (stopWatch.getTime() > slowTranTime) { + if (logger.isWarn()) { + logger.warn("HttpAdapterServiceBypass] lazy async response time = " + stopWatch.toString() + + ", message = " + requestData); + } + } + + if (result == null) { + responseData = ElinkConfig.getAsyncDummyDataForAdapterGroup(adptGrpName);; + } else { + responseData = result; + } + + long contentLength = result.getBytes(encode).length; + response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength)); + response.setCharacterEncoding(encode); + response.getWriter().print(responseData); + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, "SEND " + "[" + responseData + "]" + + ((responseData == null) ? "" : CommonLib.getDumpMessage(responseData))); + } + } else { + assignResponseHeaders(request, response, prop); + + if (result != null) { + + long contentLength = result.getBytes(encode).length; + response.setHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(contentLength)); + if (logger.isDebug()) { + logger.debug("Response Content Lenght(Reset)=" + contentLength); + } + + response.setCharacterEncoding(encode); + response.getWriter().print(result); + } + + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, + "SEND " + "[Bypass Response..]" + CommonLib.getDumpMessage(result)); + } + } + } catch (HttpStatusException e) { + if (traceLevel >= 3) { + HttpMemoryLogger.error(adptGrpName + adptName, e.toString(), e); + } + logger.warn("HttpAdapter] " + adptGrpName + "-" + adptName + ">>" + e.getMessage()); + response.setStatus(e.getStatus()); + try { + String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptVO.getAdapterGroupVO().getMessageType(), + encode, e.getCode(), e.getMessage(), errorResponseFormat); + response.getWriter().println(errorMsg); + } catch (Exception ex) { + // IGNORE + } + } catch (JwtAuthException e) { + if (traceLevel >= 3) { + HttpMemoryLogger.error(adptGrpName + adptName, e.toString(), e); + } + logger.error("HttpAdapterServiceRest] " + adptGrpName + "-" + adptName + ">>" + e.getMessage(), e); + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + try { + String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptVO.getAdapterGroupVO().getMessageType(), + encode, e.getCode(), e.getMessage(), errorResponseFormat); + response.getWriter().println(errorMsg); + } catch (Exception ex) { + // IGNORE + } + } catch (Exception e) { + if (traceLevel >= 3) { + HttpMemoryLogger.error(adptGrpName + adptName, e.toString(), e); + } + logger.error("HttpAdapterServiceBypass] " + adptGrpName + "-" + adptName + ">>" + e.getMessage(), e); + response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); + try { + response.getWriter().println(e.getMessage()); + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA003"); + throw new Exception(errCode); + } catch (Exception ex) { + // IGNORE + logger.warn("HttpAdapterServiceBypass] " + adptGrpName + "-" + adptName + ">>" + e.getMessage(), e); + } + } + } + +// private void validateServiceAndAdapter(String adptGrpName, String adptName, byte[] requestBytes, Properties prop) +// throws JwtAuthException { +// try { +// String actionName = prop.getProperty(Processor.REQUEST_ACTION); +// RequestAction action = ActionFactory.createAction(actionName); +// action.setAdapterInfo(adptGrpName, adptName, prop); +// String[] keys = action.perform(requestBytes); +// String apiId = keys[0]; +// +// // PathVariable 지원 추가 +// apiId = StandardMessageUtil.getMatchedKey(apiId, actionName); +// if (apiId == null) { +// throw new Exception("apiId"); +// } +// +//// STDMessageManager stdheaderManager = STDMessageManager.getInstance(); +//// STDMessage stdmessage = stdheaderManager.getSTDMessage(apiId); +//// if (stdmessage == null) { +//// throw new Exception("stdMsg"); +//// } +// +// long msgRcvTm = System.currentTimeMillis(); +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adptGrpName); +// ProcessVO processVO = setProcessVO(apiId, adptGrpVO.getOsidInstiNo(), msgRcvTm, adptGrpName, adptName); +// ExtMessage extMessage = ExtMessageConverter.getExtMessageForNonStandard(requestBytes, requestBytes, processVO); +// +// EAIMessageManager eaiMsgManager = EAIMessageManager.getInstance(); +//// String eaiSvcCd = stdmessage.getEAITranName() + stdmessage.getSTDHeader().getMesgDvcd(); +// String eaiSvcCd = extMessage.getEAIServiceCode(); +// if (eaiSvcCd == null) { +// eaiSvcCd = extMessage.getInterfaceId() + extMessage.getSendRecv() + extMessage.getDirection(); +// } +// EAIMessage eaiMsg = eaiMsgManager.getEAIMessage(eaiSvcCd); +// logger.warn("adptGrpName=[" + adptGrpName + "],eaiSvcCd=[" + eaiSvcCd + "],eaiMsg=[" + eaiMsg +// + "],getSngSysItfTp=[" + "]"); +// if (eaiMsg == null) { +// throw new Exception("eaiMsg"); +// } +// +// if (!StringUtils.equals(eaiMsg.getSngSysItfTp(), adptGrpName)) { +// throw new Exception("adapter"); +// } +// } catch (Exception e) { +// String msg = String.format("The resource does not exist or does not have permissions(%s): %s", +// e.getMessage(), prop.get(INBOUND_EXTURI)); +// throw new JwtAuthException(JwtAuthFilter.ERROR_AUTHORIZATION_FAIL, msg); +// } +// } + +// private ProcessVO setProcessVO(String apiId, String osidInstiNo, long msgRcvTm, String adptGrpName, +// String adptName) { +// ProcessVO vo = new ProcessVO(); +// vo.setSelectedKey(apiId); +// vo.setAdapterGroupName(adptGrpName); +// vo.setAdapterName(adptName); +// vo.setInAdapterOsidInstiNo(osidInstiNo); +// vo.setErrTm(msgRcvTm); +// return vo; +// } + + private String getRewritePath(String extUri, String basePath) { + return StringUtils.removeStart(extUri, StringUtils.removeEnd(basePath, "/")); + } + + private Map assignPathVariables(HttpServletRequest request, String adptGrpName, String adptName, + Object requestBytes, Properties prop) { + Map variablesMap = null; + // QueryString 있을때는 체크(X) + if (StringUtils.isBlank(request.getQueryString())) { + try { + String actionName = prop.getProperty(Processor.REQUEST_ACTION); + RequestAction action = ActionFactory.createAction(actionName); + action.setAdapterInfo(adptGrpName, adptName, prop); + String[] keys = action.perform(requestBytes); + String requestPath = keys[0]; + + // PathVariable 지원 추가 + String ruledPath = StandardMessageUtil.getMatchedKey(requestPath, actionName); + if (!StringUtils.equals(requestPath, ruledPath) && StringUtils.contains(ruledPath, "{")) { + variablesMap = new AntPathMatcher().extractUriTemplateVariables(ruledPath, requestPath); + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + + return variablesMap; + } + + /** + * request header 를 Properties로 조립 + * + * @param request + * @return + */ + private Properties getHeaders(HttpServletRequest request) { + Properties prop = new Properties(); + + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String key = headerNames.nextElement(); + String value = request.getHeader(key); + prop.setProperty(key, value); + } + + return prop; + } + + @SuppressWarnings("unchecked") + private void assignResponseHeaders(HttpServletRequest request, HttpServletResponse response, Properties prop) { + Map outboundPropertyMap = (Map) prop.get(OUTBOUND_PROPERTY_MAP); + if (outboundPropertyMap == null) { + return; + } + + Properties headerProp = (Properties) outboundPropertyMap.get(OUTBOUND_RESPONSE_HEADERS); + if (headerProp == null) { + return; + } + + String httpStatus = "200"; + for (Entry e : headerProp.entrySet()) { + String key = (String) e.getKey(); + String value = (String) e.getValue(); + + if (StringUtils.equalsAnyIgnoreCase(key, HOP_BY_HOP_HEADERS)) { + continue; + } + + if (StringUtils.equalsIgnoreCase(key, HttpHeaders.CONTENT_LENGTH)) { + if (logger.isDebug()) { + logger.debug("Response Content Lenght(Header)=" + value); + } + continue; + } + + if (StringUtils.equalsAnyIgnoreCase(key, HttpHeaders.SET_COOKIE, HttpHeaders.SET_COOKIE2)) { + for (HttpCookie cookie : HttpCookie.parse(value)) { + Cookie servletCookie = createProxyCookie(request, cookie); + response.addCookie(servletCookie); + } + continue; + } + + if (StringUtils.equalsIgnoreCase(key, HTTP_STATUS)) { + if (StringUtils.isNotBlank(value)) { + httpStatus = value; + continue; + } + } + + if (StringUtils.equalsIgnoreCase(key, HttpHeaders.LOCATION)) { + if (!StringUtils.startsWith(httpStatus, "3")) { + httpStatus = "302"; + } + } + + response.addHeader(key, value); + } + response.setStatus(Integer.parseInt(httpStatus)); + } + + /** + * Creates a proxy cookie from the original cookie. + * + * @param servletRequest original request + * @param cookie original cookie + * @return proxy cookie + */ + protected Cookie createProxyCookie(HttpServletRequest servletRequest, HttpCookie cookie) { + String proxyCookieName = getProxyCookieName(cookie); + Cookie servletCookie = new Cookie(proxyCookieName, cookie.getValue()); + servletCookie.setPath(this.doPreserveCookiePath ? cookie.getPath() : // preserve original cookie path + buildProxyCookiePath(servletRequest) // set to the path of the proxy servlet + ); + servletCookie.setComment(cookie.getComment()); + servletCookie.setMaxAge((int) cookie.getMaxAge()); + // don't set cookie domain + servletCookie.setSecure(servletRequest.isSecure() && cookie.getSecure()); + servletCookie.setVersion(cookie.getVersion()); + servletCookie.setHttpOnly(cookie.isHttpOnly()); + return servletCookie; + } + + /** + * Set cookie name prefixed with a proxy value so it won't collide with other + * cookies. + * + * @param cookie cookie to get proxy cookie name for + * @return non-conflicting proxy cookie name + */ + protected String getProxyCookieName(HttpCookie cookie) { + return doPreserveCookies ? cookie.getName() : getCookieNamePrefix(cookie.getName()) + cookie.getName(); + } + + /** + * Create path for proxy cookie. + * + * @param servletRequest original request + * @return proxy cookie path + */ + protected String buildProxyCookiePath(HttpServletRequest servletRequest) { + String path = servletRequest.getContextPath(); // path starts with / or is empty string + path += servletRequest.getServletPath(); // servlet path starts with / or is empty string + if (path.isEmpty()) { + path = "/"; + } + return path; + } + + /** The string prefixing rewritten cookies. */ + protected String getCookieNamePrefix(String name) { + return "!Proxy!eLink"; + } + + /** + * 어댑터 명 이후를 가져온다. + * + * @param request + * @return + */ + private String getExtUri(HttpServletRequest request) { + String orgUri = request.getRequestURI().replaceAll(request.getContextPath(), ""); + String uri = getExtUri(orgUri, 3); + if (uri != null && uri.trim().length() > 0) { + return "/" + uri; + } else { + return ""; + } + } + + private static String getExtUri(String url, int length) { + String[] urls = url.split("/"); + List newUrls = new ArrayList<>(); + Collections.addAll(newUrls, urls); + return StringUtils.join(newUrls.subList(length, urls.length).toArray(), "/"); + } + + public static void main(String[] args) throws Exception { + String orgUri = "/HTT/CbsInNetSys/abcd/123456"; + String result = ""; + result = getExtUri(orgUri, 3); + System.out.println(result); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceChannel.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceChannel.java new file mode 100644 index 0000000..3365aea --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceChannel.java @@ -0,0 +1,943 @@ +package com.eactive.eai.adapter.http.dynamic.impl; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Properties; + +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang.time.StopWatch; +import org.apache.commons.lang3.StringUtils; +import org.apache.mina.common.ByteBuffer; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpMethodType; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.dao.DAOFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.property.PropertyLoginKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.session.ChannelSessionFacade; +import com.eactive.eai.common.session.ChannelSessionFacade.LogoutType; +import com.eactive.eai.common.session.SessionHistoryLogger; +import com.eactive.eai.common.session.SessionManager; +import com.eactive.eai.common.session.SessionVO; +import com.eactive.eai.common.sessioninfo.SessionHistoryDTO; +import com.eactive.eai.common.sessioninfo.SessionHistoryVO; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.UUIDGenerator; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.inbound.error.InboundErrorInfoDAO; +import com.eactive.eai.inbound.error.InboundErrorInfoVO; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.message.service.InterfaceMapper; +import com.ext.eai.common.stdmessage.STDMessageErrorKeys; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class HttpAdapterServiceChannel extends HttpAdapterServiceSupport { + + private static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + private static String instid = null; + private static String serverName = null; + static { + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + instid = eaiServerManager.getInstId(); + serverName = eaiServerManager.getLocalServerName(); + } + + /** + * 1. 기능 : Http Servlet service 구현 메소드 + * 2. 처리 개요 : - 로컬 서비스 호출 + * 3. 주의사항 + * + * @param request Http Servlet Request + * @return response Http Servlet Response + * @exception Exception PARAMETER_MESSAGE가 null 이거나 로컬 서비스 호출 중 오류가 발생할 경우 + **/ + public void service(String adptGrpName, String adptName, HttpServletRequest request, HttpServletResponse response) { + + try { + + ChannelServiceDataBundle bundle = new ChannelServiceDataBundle(adptGrpName, adptName, request, response); + + try { + + /** SERVICE START **/ + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + logger.info("시작 >> encode = [" + bundle.getEncode() + "] Method [" + request.getMethod() + "]"); + + response.addHeader("Access-Control-Allow-Origin", "*"); + response.addHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS"); + response.addHeader("Access-Control-Allow-Headers", "Origin,Accept,X-Requested-With,Access-Control-Request-Method,Access-Control-Request-Header,Authorization,Cookie,Content-Type,Content-Length"); + response.addHeader("Access-Control-Expose-Headers", "Set-Cookie,X-Powered-By"); + response.addHeader("Access-Control-Allow-Credentials", "true"); + response.addHeader("Access-Control-Max-Age", "3600"); + + switch (HttpMethodType.getValue(request.getMethod())) { + case GET: + case DELETE: + case POST: + case PUT: + break; + default: + if (logger.isInfo()) { + logger.info("HttpAdapterServiceChannel] SET RESPONSE HEADER FOR ACAO Method[" + request.getMethod() + "] remoteAddress=" + request.getRemoteAddr()); + } + return; + } + + ChannelResponseDivider responseDivider = new ChannelResponseDivider(bundle); + + /** Phase 1 **/ + switch(responseDivider.dividePhase1()) { + + case HttpPoll: + httpPollResponse(request, response, bundle); + return; // * return service + + case DupLoginCheck: + dupLoginCheckResponse(request, response, bundle); + return; // * return service + + case LoginValidation: + loginValidationResponse(request, response, bundle); + return; // * return service + + case LoginUuidValidation: + loginUuidValidationResponse(request, response, bundle); + return; // * return service + + default: + break; // go phase 2 + } + + stopWatch.stop(); + + if(logger.isDebug()){ + String[] msgArgs = { adptGrpName, new String(bundle.getRequestBytes(), bundle.getEncode()) }; + String resMsg = ExceptionUtil.make("RICEAIAHA005", msgArgs); + logger.debug("HttpAdapterServiceChannel] " + resMsg); + } + + // 로컬 서비스 호출 + logger.warn("HttpAdapterServiceChannel] REAL CALL HttpSession userId = " + bundle.getUserId() + ", message = " + new String(bundle.getRequestBytes(), bundle.getEncode())); + Object obj = service(adptGrpName, adptName, bundle.getRequestBytes(), new Properties(), request, response ); + AdapterManager manager = AdapterManager.getInstance(); + AdapterGroupVO group = manager.getAdapterGroupVO(adptGrpName); + + byte[] result = null; + + if (obj instanceof byte[]) { + result = (byte[])obj; + }else if (obj instanceof String){ + result = ((String)obj).getBytes(StringUtils.defaultIfBlank(group.getMessageEncode(), Charset.defaultCharset().name())); + } + + /** Phase 2 **/ + switch(responseDivider.dividePhase2()) { + + case Async: + asyncResponse(request, response, bundle, stopWatch, result); + break; + + case LoginTransaction: + result = loginResponse(request, response, bundle, result); + break; + + case LogoutTransaction: + result = logoutResponse(request, response, bundle, result); + break; + + default: + break; + + } + + String responseData = new String(result, bundle.getEncode()); // UI와 통신시(UTF-8) 변환오류로 ENCODE 제거 + logger.info("종료 >> encode = [" + bundle.getEncode() + "]"); + + if (bundle.getAddData().length() > 0) { + responseData = bundle.getAddData() + responseData; + } + + response.setContentType("application/json"); // FIXME ContentType application/json으로 임시 셋팅 추후 어댑터 설정으로 변경 필요 + response.setCharacterEncoding(bundle.getEncode()); // UI와 통신시(UTF-8) 변환오류로 ENCODE 제거 + response.getWriter().print(responseData); + + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceChannel] SEND (" + adptGrpName + ") = [" + responseData + "]"); + logger.debug("HttpAdapterServiceChannel] SEND (" + adptGrpName + ") = " + ((responseData == null) ? "" : CommonLib.getDumpMessage(responseData.getBytes(bundle.getEncode())))); + } + + if (bundle.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, "SEND " + "[" + responseData + "]" + ((responseData == null) ? "" : CommonLib.getDumpMessage(responseData.getBytes(bundle.getEncode())))); + } + + + } catch (Exception e) { + if (bundle.getTraceLevel() >= 3) { + HttpMemoryLogger.error(adptGrpName + adptName, e.toString(), e); + } + logger.error("HttpAdapterServiceChannel] " + adptGrpName + "-" + adptName + " guid=" + bundle.getGuid(), e); + response.setStatus(500); + try { + response.getWriter().println(e.getMessage()); + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA003"); + throw new Exception(errCode); + } catch (Exception ex) { + logger.warn("error", ex); + } + } + + + } catch (ServletException | IOException e) { + logger.error("HttpAdapterServiceChannel] " + adptGrpName + "-" + adptName, e); + response.setStatus(500); + try { + response.getWriter().println(e.getMessage()); + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA003"); + throw new Exception(errCode); + } catch (Exception ex) { + logger.warn("error", ex); + } + } + + } + + private void httpPollResponse(HttpServletRequest request, HttpServletResponse response, ChannelServiceDataBundle bundle) throws IOException { + + String message = new String(bundle.getRequestBytes(), bundle.getEncode()); + + if (logger.isInfo()) { + logger.info("HttpAdapterServiceChannel] HTTPPOLL remoteAddress=" + request.getRemoteAddr() + " response=" + message); + } + String userId = message.substring(9, 9 + 9); + String uuid = message.substring(9 + 9, 58); + + String responseMessage; + + SessionVO sVo = SessionManager.getInstance().getHttpLogin(uuid); + String trimingId = StringUtils.trim(userId); + + if (sVo == null) { + //ERROR + logger.warn("HttpAdapterServiceChannel] HTTPPOLL loginId=(" + trimingId + ") uuid[" + uuid + "] HTTPLOGIN not found"); + responseMessage = "POLLERR@@" + userId + uuid; + + } else { + //RESPONSE + PropManager pManager = PropManager.getInstance(); + String cacheType = pManager.getProperty(SessionManager.SESSION_MANAGER_GROUPNAME, + SessionManager.SESSION_MANAGER_CACHETYPE, "EHCACHE"); + logger.info("HttpAdapterServiceChannel] HTTPPOLL loginId=(" + trimingId + ") uuid[" + uuid + "] refresh HTTPLOGIN"); + + ChannelSessionFacade.getInstance().refreshHttpLoginCache(uuid, sVo); + + responseMessage = "POLLRES@@" + userId + uuid; + } + + logger.info("HttpAdapterServiceChannel] HTTPPOLL loginId=(" + trimingId + ") uuid[" + uuid + "] RESPONSE[" + responseMessage + "]"); + + response.setCharacterEncoding(bundle.getEncode()); + response.getWriter().print(responseMessage); + + } + + private void loginValidationResponse(HttpServletRequest request, HttpServletResponse response, ChannelServiceDataBundle bundle) throws Exception { + + Properties prop = PropManager.getInstance().getProperties(PropertyLoginKeys.LOGIN); + + String CODE = prop.getProperty(PropertyLoginKeys.VALIDATION_LOGIN_CODE, STDMessageErrorKeys.NOT_LOGIN_ERROR_CODE_VALUE); + String MSG = prop.getProperty(PropertyLoginKeys.VALIDATION_LOGIN_MSG, STDMessageErrorKeys.NOT_LOGIN_ERROR_MSG_VALUE); + + logger.error("HttpAdapterServiceChannel] NOTLOGIN OR EXPIRED SESSION userId[" + bundle.getUserId() + "] - RETURN ERROR."); + + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + InterfaceMapper mapper = standardManager.getMapper(); + AdapterGroupVO vo = AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()); + String messageType = vo.getMessageType(); + String messageEncode = vo.getMessageEncode(); + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(messageType); + reader.parse(standardMessage, bundle.getRequestBytes()); + // 표준전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(messageEncode); + standardManager.getMessageCoordinator().coordinateSetStandardMessageError(standardMessage, mapper, "RECEAIAHA020", null); + String responseData = standardMessage.getDataString(messageType, messageEncode); + +// ExtMessage extMessage = ExtMessageConverter.getExtMessageForStandard(bundle.getRequestBytes(), AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()).getMessageType()); +// byte[] result = ExtMessageConverter.getDuplicateLoginResponseForStandard(extMessage, "", MSG, CODE, MSG); +// String responseData = new String(result, bundle.getEncode()); + +// response.setCharacterEncoding(bundle.getEncode()); + response.setContentType("application/json");// FIXME ContentType application/json으로 임시 셋팅 추후 어댑터 설정으로 변경필요" + response.setCharacterEncoding(messageEncode); + response.getWriter().print(responseData); + + //정의되지 않는 메시지에 로그추가 + logUnknown(bundle,CODE,MSG); + + + } + private void loginUuidValidationResponse(HttpServletRequest request, HttpServletResponse response, ChannelServiceDataBundle bundle) throws Exception { + + Properties prop = PropManager.getInstance().getProperties(PropertyLoginKeys.LOGIN); + + String CODE = prop.getProperty(PropertyLoginKeys.VALIDATION_LOGIN_CODE, STDMessageErrorKeys.UUID_MISMATCH_ERROR_CODE_VALUE); + String MSG = prop.getProperty(PropertyLoginKeys.VALIDATION_LOGIN_MSG, STDMessageErrorKeys.UUID_MISMATCH_ERROR_MSG_VALUE); + + logger.error("HttpAdapterServiceChannel] UUID mismatch userId[" + bundle.getUserId() + "] - RETURN ERROR."); + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + InterfaceMapper mapper = standardManager.getMapper(); + AdapterGroupVO vo = AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()); + String messageType = vo.getMessageType(); + String messageEncode = vo.getMessageEncode(); + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(messageType); + reader.parse(standardMessage, bundle.getRequestBytes()); + // 표준전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(messageEncode); + standardManager.getMessageCoordinator().coordinateSetStandardMessageError(standardMessage, mapper, "RECEAIAHA022", null); + String responseData = standardMessage.getDataString(messageType, messageEncode); +// ExtMessage extMessage = ExtMessageConverter.getExtMessageForStandard(bundle.getRequestBytes(), AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()).getMessageType()); +// byte[] result = ExtMessageConverter.getDuplicateLoginResponseForStandard(extMessage, "", MSG, CODE, MSG); +// String responseData = new String(result, bundle.getEncode()); + + response.setContentType("application/json");// FIXME ContentType application/json으로 임시 셋팅 추후 어댑터 설정으로 변경필요" + response.setCharacterEncoding(messageEncode); + response.getWriter().print(responseData); + + //정의되지 않는 메시지에 로그추가 + logUnknown(bundle,CODE,MSG); + + } + + //login validation 오류 로그 추가 2022-11-09 + private void logUnknown(ChannelServiceDataBundle bundle,String errorCode,String errorMsg) throws Exception { + String uuid = instid + UUIDGenerator.getUUID(); + + InboundErrorInfoVO errorInfoVO = new InboundErrorInfoVO(); + errorInfoVO.setEaiSvcSno(uuid); // EAI서비스일련번호 + errorInfoVO.setAdptBwkGrpNm(bundle.getAdptGrpName()); // 어댑터업무그룹명 + errorInfoVO.setEaiSvcCd(""); + errorInfoVO.setErrCd(errorCode); // 에러코드 + errorInfoVO.setErrTxt(errorMsg); // 에러내용 + errorInfoVO.setErrTm(DatetimeUtil.getCurrentTimeMillis()); // 에러발생시각 + errorInfoVO.setErrDstcd("IE"); + errorInfoVO.setBzwkSvcKeyName(""); + errorInfoVO.setBwkDataTxt(new String(bundle.getRequestBytes(), bundle.getEncode())); // 업무데이터내용 + errorInfoVO.setEaiSvrInstNm(serverName); // EAI서버인스턴스명 + try { + InboundErrorInfoDAO dao = ApplicationContextProvider.getContext().getBean(InboundErrorInfoDAO.class); + dao.addInboundErrorInfo(errorInfoVO); + } catch(DAOException e) { + if (logger.isError()) logger.error("RequestProcessor] Unknown Message Logging Error", e); + } + + if (logger.isError()) { + logger.error("======================================================================" ); + logger.error(" HttpAdapterServiceChannel] GET LOGIN VALIDATION ERROR MESSAGE"); + logger.error(" ADAPTER GROUP NAME [" + bundle.getAdptGrpName() + "]"); + logger.error(" ADAPTER NAME [" + bundle.getAdptName() + "]"); + logger.error(" USER_ID [" + bundle.getUserId() + "]"); + logger.error("======================================================================" ); + } + } + + private void dupLoginCheckResponse(HttpServletRequest request, HttpServletResponse response, ChannelServiceDataBundle bundle) throws Exception { + + Properties prop = PropManager.getInstance().getProperties(PropertyLoginKeys.LOGIN); + + logger.error("HttpAdapterServiceChannel] LOGIN-DUPLICATED loginUserId= " + bundle.getUserId()); + + String DUPLICATE_LOGIN_CODE = prop.getProperty(PropertyLoginKeys.DUPLICATE_LOGIN_CODE, STDMessageErrorKeys.DUP_LOGIN_ERROR_CODE_VALUE); + String DUPLICATE_LOGIN_MSG = prop.getProperty(PropertyLoginKeys.DUPLICATE_LOGIN_MSG, STDMessageErrorKeys.DUP_LOGIN_ERROR_MSG_VALUE); + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + InterfaceMapper mapper = standardManager.getMapper(); + AdapterGroupVO vo = AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()); + String messageType = vo.getMessageType(); + String messageEncode = vo.getMessageEncode(); + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(messageType); + reader.parse(standardMessage, bundle.getRequestBytes()); + // 표준전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(messageEncode); + standardManager.getMessageCoordinator().coordinateSetStandardMessageError(standardMessage, mapper,"RECEAIAHA021", null); + String responseData = standardMessage.getDataString(messageType, messageEncode); + +// response.setCharacterEncoding(bundle.getEncode()); + response.getWriter().print(responseData); + + String remoteIp = request.getHeader("X-Forwarded-For") != null ? request.getHeader("X-Forwarded-For") : request.getRemoteAddr(); + + SessionHistoryLogger.getInstance().log( + new SessionHistoryDTO(new String(bundle.getRequestBytes(), bundle.getEncode()), SessionHistoryVO.HISTORYDSTCD_DUPLOGIN, "E", null, remoteIp, true)); + + } + + private void asyncResponse(HttpServletRequest request, HttpServletResponse response, ChannelServiceDataBundle bundle, StopWatch stopWatch, byte[] serviced) throws IOException { + + if (stopWatch.getTime() > slowTranTime) { + if (logger.isWarn()) { + logger.warn("HttpAdapterServiceChannel] lazy async response time = " + stopWatch.toString() + ", message = " + new String(bundle.getRequestBytes(), bundle.getEncode())); + } + } + + String responseData = serviced == null ? ElinkConfig.getAsyncDummyData("K") : new String(serviced, bundle.getEncode()); + + response.setCharacterEncoding(bundle.getEncode()); + response.getWriter().print(responseData); + + if (bundle.getTraceLevel() >= 3) { + HttpMemoryLogger.txlog(bundle.getAdptGrpName() + bundle.getAdptName(), "SEND " + "[" + responseData + "]" + ((responseData == null) ? "" : CommonLib.getDumpMessage(responseData.getBytes()))); + } + + } + + private byte[] loginResponse(HttpServletRequest request, HttpServletResponse response, ChannelServiceDataBundle bundle, byte[] serviced) throws Exception { + + String uuid = "UUID" + UUIDGenerator.getUUID(); + // set uuid to STDMessage Header MCI_INTF_SESN_ID + /* + * 응답전문 변경 및 로그인 거래 일 경우에만 수행하므로 개발 용이성을 위해 + * ExtMessageConverter.getExtMessageForStandard 코드를 유지 + */ +// ExtMessage resExtMessage = ExtMessageConverter.getExtMessageForStandard(serviced, AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()).getMessageType()); + + // 정상응답인지 확인 : RSPNS_RSLT_DVSN_CD = N +// String respRsltDvsnCode = resExtMessage.getResponseType(); + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + InterfaceMapper mapper = standardManager.getMapper(); + AdapterGroupVO vo = AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()); + String messageType = vo.getMessageType(); + String messageEncode = vo.getMessageEncode(); + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(messageType); + reader.parse(standardMessage, serviced); + // 표준전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(messageEncode); + String respRsltDvsnCode = mapper.getResponseType(standardMessage); + if (STDMessageKeys.RESPONSE_TYPE_CODE_N.equals(respRsltDvsnCode)) { // FIXME + + // 2023. 12. 12. KAKAOBANK-CARD userId From Response Standard Header + bundle.setUserId(mapper.getUserId(standardMessage)); + + mapper.setSessionId(standardMessage, uuid); + mapper.setInstCode(standardMessage, EAIServerManager.getInstance().getLocalServerName()); +// resExtMessage.setSessionId(uuid); +// STDMessage stdMsg = (STDMessage)resExtMessage.getStdMessage(); +// byte[] bizData = (byte[]) resExtMessage.getBizData()[0]; +// JSONObject resultJson = (JSONObject) JSONValue.parse(new String((byte[]) bizData, MessageType.UJSON_ENCODE)); + +// serviced = ExtMessageConverter.toJsonBytes(resExtMessage, bundle.getEncode()); + JSONObject resultJson = (JSONObject) JSONValue.parse(standardMessage.getBizData()); + serviced = standardMessage.getDataBytes(messageType, messageEncode); + ChannelSessionFacade.getInstance().login(bundle.getUserId(), uuid, resultJson); + + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceChannel] loginId=(" + bundle.getUserId() + ") uuid[" + uuid + "]"); + } + + } else { + logger.warn("HttpAdapterServiceChannel] LOGIN Failed RSPNS_RSLT_DVSN_CD =" + respRsltDvsnCode); + } + + String remoteIp = request.getHeader("X-Forwarded-For") != null ? request.getHeader("X-Forwarded-For") : request.getRemoteAddr(); + + SessionHistoryLogger.getInstance().log( + new SessionHistoryDTO(new String(bundle.getRequestBytes(), bundle.getEncode()), SessionHistoryVO.HISTORYDSTCD_LOGIN, respRsltDvsnCode, uuid, remoteIp, true)); + + return serviced; + } + + private byte[] logoutResponse(HttpServletRequest request, HttpServletResponse response, ChannelServiceDataBundle bundle, byte[] serviced) throws Exception { + +// ExtMessage resExtMessage = ExtMessageConverter.getExtMessageForStandard(serviced, AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()).getMessageType()); + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + InterfaceMapper mapper = standardManager.getMapper(); + AdapterGroupVO vo = AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()); + String messageType = vo.getMessageType(); + String messageEncode = vo.getMessageEncode(); + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(messageType); + reader.parse(standardMessage, serviced); + // 표준전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(messageEncode); + String respRsltDvsnCode = mapper.getResponseType(standardMessage); + + // 정상응답인지 확인 : RSPNS_RSLT_DVSN_CD = N +// String respRsltDvsnCode = resExtMessage.getResponseType(); + String uuid = ""; + if (STDMessageKeys.RESPONSE_TYPE_CODE_N.contentEquals(respRsltDvsnCode)) { + SessionVO sessionVo = SessionManager.getInstance().getLogin(bundle.getUserId()); + if (sessionVo == null) { + logger.warn("HttpAdapterServiceChannel] LOGOUT Login Session Not found userId =" + bundle.getUserId()); + } else { + uuid = sessionVo.getUuid(); + ChannelSessionFacade.getInstance().logout(sessionVo.getLoginUserId(), sessionVo.getUuid(), false, LogoutType.Logout); + } + } else { + logger.warn("HttpAdapterServiceChannel] LOGOUT Failed RSPNS_RSLT_DVSN_CD =" + respRsltDvsnCode); + } + + SessionHistoryLogger.getInstance().log( + new SessionHistoryDTO(new String(bundle.getRequestBytes(), bundle.getEncode()), SessionHistoryVO.HISTORYDSTCD_LOGOUT, respRsltDvsnCode, uuid, null, true)); + + return serviced; + } + +} + +class ChannelServiceDataBundle { + + private Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + private String adptGrpName; + private String adptName; + + private int traceLevel = 0; + + private String responseType; + private String urlDecodeYn; + private String encode; + private String requestBodyYn; + private String parameterName; + private String removeLength; + private String addData; + + private byte[] requestBytes; + private int removeLen; + + /** lazy setting **/ + private String guid; + private String userId; + + private String apiPath; + private String extUri; + private String standardApiPath; + + public ChannelServiceDataBundle(String adptGrpName, String adptName, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + this.adptGrpName = adptGrpName; + this.adptName = adptName; + + AdapterVO adptVO = AdapterManager.getInstance().getAdapterVO(adptGrpName, adptName); + if (adptVO == null) { + throw new ServletException("Adapter not Found adptName=" + adptName); + } + + Properties httpProp = AdapterPropManager.getInstance().getProperties(adptVO.getPropGroupName()); + + this.responseType = httpProp.getProperty(HttpAdapterServiceKey.RESPONSE_TYPE, "SYNC"); + this.urlDecodeYn = httpProp.getProperty(HttpAdapterServiceKey.URL_DECODE_YN, "N"); + this.encode = httpProp.getProperty(HttpAdapterServiceKey.ENCODE, "MS949"); +// this.requestBodyYn = httpProp.getProperty(HttpAdapterServiceKey.REQUEST_BODY_YN, "N"); + this.requestBodyYn ="Y"; + this.parameterName = httpProp.getProperty(HttpAdapterServiceKey.PARAMETER_NAME, HttpAdapterServiceKey.PARAMETER_MESSAGE); + this.removeLength = httpProp.getProperty(HttpAdapterServiceKey.REMOVE_LENGTH, "0"); + this.addData = httpProp.getProperty(HttpAdapterServiceKey.ADD_DATA, ""); + String traceLevelTemp = httpProp.getProperty(HttpAdapterServiceKey.TRACE_LEVEL, "0"); + this.apiPath = httpProp.getProperty(HttpAdapterServiceKey.API_PATH, ""); + + if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) + || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { + // /api/v1/public/getUserInfo.svc + String extUrl = StringUtils.removeStart(request.getRequestURI(), request.getContextPath()); + this.extUri = extUrl; + } else { + this.extUri = getExtUri(request); + } + + standardApiPath = extUri.replaceAll(apiPath, ""); + if (!standardApiPath.startsWith("/")) { + standardApiPath = standardApiPath + "/"; + } + + try { + traceLevel = Integer.parseInt(traceLevelTemp); + } catch (Exception e) { + traceLevel = 0; + } + this.removeLen = 0; + try { + removeLen = Integer.parseInt(removeLength); + } catch (Exception e) { + removeLen = 0; + } + + if ("Y".equals(requestBodyYn)) { + this.requestBytes = requestBytesSetting(request); + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, "RECV " + "[" + new String(requestBytes, encode) + "]" + CommonLib.getDumpMessage(requestBytes)); + } + } else { + String paramValue = request.getParameter(parameterName); + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, "RECV " + "[" + paramValue + "]" + ((paramValue == null) ? "" : CommonLib.getDumpMessage(paramValue.getBytes()))); + } + this.requestBytes = requestBytesFromParameterValue(paramValue, urlDecodeYn, encode); + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceChannel] RECV (" + adptGrpName + ") = [" + paramValue + "]"); + logger.debug("HttpAdapterServiceChannel] RECV (" + adptGrpName + ") = " + ((paramValue == null) ? "" : CommonLib.getDumpMessage(paramValue.getBytes()))); + } + } + + if (removeLen > 0) { + byte[] cuttedBytes = new byte[requestBytes.length - removeLen]; + System.arraycopy(requestBytes, removeLen, cuttedBytes, 0, cuttedBytes.length); + this.requestBytes = cuttedBytes; + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceChannel] RECV after remove (" + adptGrpName + ") = [" + new String(requestBytes, encode) + "]"); + logger.debug("HttpAdapterServiceChannel] RECV after remove (" + adptGrpName + ") = " + CommonLib.getDumpMessage(requestBytes)); + } + } + + } + + private byte[] requestBytesSetting(HttpServletRequest request) throws IOException { + + byte[] result = null; + + ServletInputStream sis = request.getInputStream(); + ByteBuffer bb = ByteBuffer.allocate(1024).setAutoExpand(true); + int i = 0; + byte[] cbuf = new byte[1024]; + while ((i = sis.read(cbuf, 0, 1024)) != -1) { + if (i == 1024) { + bb.put(cbuf); + } else { + byte[] tail = new byte[i]; + System.arraycopy(cbuf, 0, tail, 0, i); + bb.put(tail); + } + } + result = new byte[bb.position()]; + bb.position(0); + bb.get(result); + + return result; + } + + private byte[] requestBytesFromParameterValue(String paramValue, String urlDecodeYn, String encode) throws ServletException, UnsupportedEncodingException { + + if (paramValue == null) + throw new ServletException("RECEAIAHA002"); + + if ("Y".equals(urlDecodeYn)) { + paramValue = URLDecoder.decode(paramValue, encode); + } + + return paramValue.getBytes(encode); + } + + public String getAdptGrpName() { + return adptGrpName; + } + + public String getAdptName() { + return adptName; + } + + public int getTraceLevel() { + return traceLevel; + } + + public String getResponseType() { + return responseType; + } + + public String getUrlDecodeYn() { + return urlDecodeYn; + } + + public String getEncode() { + return encode; + } + + public String getRequestBodyYn() { + return requestBodyYn; + } + + public String getParameterName() { + return parameterName; + } + + public String getRemoveLength() { + return removeLength; + } + + public String getAddData() { + return addData; + } + + public byte[] getRequestBytes() { + return requestBytes; + } + + public int getRemoveLen() { + return removeLen; + } + + public String getGuid() { + return guid; + } + + public String getUserId() { + return userId; + } + + public void setGuid(String guid) { + this.guid = guid; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getApiPath() { + return apiPath; + } + + public void setApiPath(String apiPath) { + this.apiPath = apiPath; + } + + public String getExtUri() { + return extUri; + } + + public void setExtUri(String extUri) { + this.extUri = extUri; + } + + public String getStandardApiPath() { + return standardApiPath; + } + + public void setStandardApiPath(String standardApiPath) { + this.standardApiPath = standardApiPath; + } + private String getExtUri(HttpServletRequest request) { + String orgUri = request.getRequestURI().replaceAll(request.getContextPath(), ""); + String uri = getExtUri(orgUri, 3); + if (uri != null && uri.trim().length() > 0) { + return "/" + uri; + } else { + return ""; + } + } + + private static String getExtUri(String url, int length) { + String[] urls = url.split("/"); + List newUrls = new ArrayList<>(); + Collections.addAll(newUrls, urls); + return StringUtils.join(newUrls.subList(length, urls.length).toArray(), "/"); + } + +} + +class ChannelResponseDivider { + + private Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + private ChannelServiceDataBundle bundle; + + private boolean loginTransaction = false; + private boolean logoutTransaction = false; + private boolean skipTransaction = false; + + public ChannelResponseDivider(ChannelServiceDataBundle bundle) { + this.bundle = bundle; + } + + public enum ResponseType_Phase1 { + HttpPoll, DupLoginCheck, LoginValidation, LoginUuidValidation, Skip + } + + public enum ResponseType_Phase2 { + Async, LoginTransaction, LogoutTransaction, Skip + } + + public ResponseType_Phase1 dividePhase1() throws Exception { + + if(bundle.getRequestBytes().length == 58) { + String message = new String(bundle.getRequestBytes(), bundle.getEncode()); + if (message.startsWith("POLLREQ@@")) { + return ResponseType_Phase1.HttpPoll; + } + } + + AdapterGroupVO agvo = AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()); + String LOGINSERVICEID = ""; + String LOGOUTSERVICEID = ""; + String SKIP_SERVICEID = ""; + + String userId = ""; + String uuid = ""; + + if (MessageType.JSON.equals(agvo.getMessageType())) { + + PropManager pManager = PropManager.getInstance(); + Properties prop = pManager.getProperties(PropertyLoginKeys.LOGIN); + LOGINSERVICEID = prop.getProperty(PropertyLoginKeys.LOGIN_SERVICE_ID); + LOGOUTSERVICEID = prop.getProperty(PropertyLoginKeys.LOGOUT_SERVICE_ID); + SKIP_SERVICEID = prop.getProperty(PropertyLoginKeys.SKIP_SERVICE_ID, "");// 비밀번호 변경 등등 + + String requestStr = new String(bundle.getRequestBytes(), bundle.getEncode()); + logger.debug("HttpAdapterServiceChannel] LOGIN_SERVICE_ID = " + LOGINSERVICEID); + logger.debug("HttpAdapterServiceChannel] LOGOUT_SERVICE_ID = " + LOGOUTSERVICEID); + logger.debug("HttpAdapterServiceChannel] SKIP_SERVICE_ID = " + SKIP_SERVICEID); + logger.debug("HttpAdapterServiceChannel] Request-JSON = " + requestStr); + + /* + * 모든 거래가 서비스ID, 사용자ID를 가져오기 위해 표준전문 파싱을 하는것은 낭비라고 판단하여 JSON에서 직접 가져오도록 변경 + */ + // 표준전문 파싱으로 변경. + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + InterfaceMapper mapper = standardManager.getMapper(); + AdapterGroupVO vo = AdapterManager.getInstance().getAdapterGroupVO(bundle.getAdptGrpName()); + String messageType = vo.getMessageType(); + String messageEncode = vo.getMessageEncode(); + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(messageType); + reader.parse(standardMessage, bundle.getRequestBytes()); + // 표준전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(messageEncode); + + String standardApiPath = bundle.getStandardApiPath(); + + String serviceId = ""; + + if (standardApiPath.length() > 1) { + serviceId = standardApiPath; + } else { + serviceId = mapper.getServiceId(standardMessage); + } + + uuid = mapper.getSessionId(standardMessage); + userId = mapper.getUserId(standardMessage); + bundle.setGuid(mapper.getGuid(standardMessage)); + bundle.setUserId(userId); + + if (LOGINSERVICEID.equals(serviceId)) { + + loginTransaction = true; +// 2023.12.11 KAKAOBANK-CARD 중복 로그인 체크 안함 +// SessionVO sessionVo = SessionManager.getInstance().getLogin(userId); +// if (sessionVo != null) { +// String LOGIN_DUP_CHECK_YN = prop.getProperty(PropertyLoginKeys.LOGIN_DUP_CHECK_YN, "Y"); +// if ("Y".equals(LOGIN_DUP_CHECK_YN)) { +// return ResponseType_Phase1.DupLoginCheck; +// } else { +// logger.error("HttpAdapterServiceChannel] LOGIN-DUPLICATED loginUserId= " + userId + " skip"); +// } +// } + + } + + if (LOGOUTSERVICEID.equals(serviceId)) { + logoutTransaction = true; + } + + //통합로그 비로그인 거래 처리(2022-08-12) AA요구사항 + //대내 MCI 및 전사공통 선처리에서 사용자 ID가 가상 사용자( 'VRxxxxxxx') 인 경우 로그인 여부등 유효성 검증 SKIP(대내MCI/전사공통) + if (SKIP_SERVICEID.indexOf(serviceId) >= 0 /* || userId.startsWith("VR")*/) { + skipTransaction = true; + } + logger.debug("HttpAdapterServiceChannel] loginTransaction = " + loginTransaction); + logger.debug("HttpAdapterServiceChannel] logoutTransaction = " + logoutTransaction); + logger.debug("HttpAdapterServiceChannel] skipTransaction = " + skipTransaction); + + } + + if (!(loginTransaction || skipTransaction)) { + + // FIXME : 로그인 여부를 체크할 것인가 ? + PropManager pManager = PropManager.getInstance(); + Properties prop = pManager.getProperties(PropertyLoginKeys.LOGIN); + String LOGIN_VALIDATION_YN = prop.getProperty(PropertyLoginKeys.LOGIN_VALIDATION_YN, "N");// 로그인 validation + String UUID_VALIDATION_YN = prop.getProperty(PropertyLoginKeys.UUID_VALIDATION_YN, "N");// uuid validation + + if ("Y".equals(LOGIN_VALIDATION_YN)) { + SessionVO sessionVo = SessionManager.getInstance().getLogin(userId); + if(sessionVo == null) { + return ResponseType_Phase1.LoginValidation; + } + }else if ("Y".equals(UUID_VALIDATION_YN)) { + //UUID validation 추가 + SessionVO sessionVo = SessionManager.getInstance().getHttpLogin(uuid); + if (sessionVo == null || !userId.equals(sessionVo.getLoginUserId())) { + return ResponseType_Phase1.LoginUuidValidation; + } + } else { + logger.error("HttpAdapterServiceChannel] NOTLOGIN OR EXPIRED SESSION userId[" + userId + "] - continue."); + } + + } + + return ResponseType_Phase1.Skip; + } + + public ResponseType_Phase2 dividePhase2() { + + if (HttpAdapterServiceKey.RESPONSE_TYPE_ASYNC.equals(bundle.getResponseType())) { + + return ResponseType_Phase2.Async; + + } else { + + if (bundle.getRequestBytes() != null) { + if (loginTransaction) { + + return ResponseType_Phase2.LoginTransaction; + + } else if (logoutTransaction) { + + return ResponseType_Phase2.LogoutTransaction; + } + } + + } + + return ResponseType_Phase2.Skip; + } + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServicePass.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServicePass.java new file mode 100644 index 0000000..b6d1fb1 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServicePass.java @@ -0,0 +1,153 @@ +package com.eactive.eai.adapter.http.dynamic.impl; + +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; +import org.apache.commons.httpclient.methods.PostMethod; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.ConnectException; +import java.net.SocketTimeoutException; +import java.util.Properties; + +public class HttpAdapterServicePass extends HttpAdapterServiceSupport { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + private static final int BUFFER_SIZE = 1024; + private static final String FROM = "From"; + private static final String FILE_TYPE = "FileType"; + private static final String FILE_NAME = "FileName"; + private static final String USER_AGENT = "User-Agent"; + private static final String USER_HEADER = "User-Header"; + private static final String CONTENT_TYPE = "Content-Type"; + + public void service(String adptGrpName, String adptName, HttpServletRequest request, HttpServletResponse response) { + + PropManager manager = PropManager.getInstance(); + + Properties prop = manager.getProperties("BYPASS_REU"); + String url = prop.getProperty("URL", "http://192.168.12.224:8068/ForexWeb/ForexServiceServlet"); + int connectionTimeout = 30000; + int timeout = 30000; + + if (prop != null) { + try { + connectionTimeout = Integer.parseInt(prop.getProperty("CONNECTION_TIMEOUT", "30000")); + } catch (NumberFormatException e) { + connectionTimeout = 30000; + } + try { + timeout = Integer.parseInt(prop.getProperty("TIMEOUT", "30000")); + } catch (NumberFormatException e) { + timeout = 30000; + } + } + + String from = request.getHeader(FROM); + String fileType = request.getHeader(FILE_TYPE); + String fileName = request.getHeader(FILE_NAME); + String userAgent = request.getHeader(USER_AGENT);// "Forex HTTP Connector" + String userHeader = request.getHeader(USER_HEADER); + String contentType = request.getHeader(CONTENT_TYPE);// "text/plain" + ByteArrayOutputStream outStream = null; + DataInputStream inStream = null; + byte[] data = null; + + try { + int c = -1; + byte[] bytes = new byte[BUFFER_SIZE]; + inStream = new DataInputStream(request.getInputStream()); + outStream = new ByteArrayOutputStream(); + + while ((c = inStream.read(bytes, 0, bytes.length)) != -1) { + outStream.write(bytes, 0, c); + } + data = new byte[outStream.toByteArray().length]; + data = outStream.toByteArray(); + } catch (IOException e1) { + if (logger.isError()) + logger.error("HttpPassAdapter] IOException ", e1); + } finally { + try { + if (inStream != null) { + inStream.close(); + } + } catch (Exception e) { + logger.warn(e); + } + try { + if (outStream != null) { + outStream.close(); + } + } catch (Exception e) { + logger.warn(e); + } + } + + HttpClient httpClient = new HttpClient(); + + httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(connectionTimeout); + httpClient.getHttpConnectionManager().getParams().setSoTimeout(timeout); + + PostMethod post = new PostMethod(url); + + post.setRequestHeader(FROM, from); + post.setRequestHeader(FILE_TYPE, fileType); + post.setRequestHeader(FILE_NAME, fileName); + post.setRequestHeader(USER_AGENT, userAgent); + post.setRequestHeader(USER_HEADER, userHeader); + post.setRequestHeader(CONTENT_TYPE, contentType); + +// post.setRequestBody(new ByteArrayInputStream(data)); +// if (data != null) { +// post.setRequestContentLength(data.length); +// } + ByteArrayRequestEntity entity = new ByteArrayRequestEntity(data); + post.setRequestEntity(entity); + + int status = -1; + + try { + status = httpClient.executeMethod(post); + } catch (SocketTimeoutException ste) { + if (logger.isError()) { + logger.error("HttpPassAdapter] SocketTimeoutException : " + ste.toString(), ste); + } + } catch (ConnectException ce) { + if (logger.isError()) { + logger.error("HttpPassAdapter] Connection Exception : " + ce.toString(), ce); + } + } catch (Exception e) { + if (logger.isError()) { + logger.error("HttpPassAdapter] Exception : " + e.toString(), e); + } + } finally { + post.releaseConnection(); + if (status != HttpStatus.SC_OK) { + logger.error("Http error status=" + status); + } + } + response.setContentType("text/html"); + PrintWriter writer = null; + try { + writer = response.getWriter(); + writer.print(post.getResponseBodyAsString()); + } catch (IOException e) { + if (logger.isError()) { + logger.error("HttpPassAdapter] IOException : " + e.toString(), e); + } + } finally { + try { + if (writer != null) { + writer.close(); + } + } catch (Exception e) { + logger.warn(e); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java new file mode 100644 index 0000000..dfa8bd8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceRest.java @@ -0,0 +1,783 @@ +package com.eactive.eai.adapter.http.dynamic.impl; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.InputStream; +import java.net.URLDecoder; +import java.util.*; + +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.util.HttpAdapterExtraLogUtil; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.apache.mina.common.ByteBuffer; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.util.AntPathMatcher; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpMethodType; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.inbound.action.ActionFactory; +import com.eactive.eai.inbound.action.RequestAction; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessageUtil; + +public class HttpAdapterServiceRest extends HttpAdapterServiceSupport { + public static final String HEADER_GROUP = "HEADER_GROUP"; + // HEADER_GROUP JSON에 추가할 항목 정의, 없으면 전체 header 추가 + public static final String HEADER_KEYS = "HEADER_KEYS"; + public static final String HTTP_STATUS = "HTTP_STATUS"; + public static final String PROPERTIES_NAME_HTTP_REQUEST_METHOD = "httpRequestMethod"; + + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + private String logPrefix = "HttpAdapterServiceRest] "; + + private static final String JSON_CONTENT_TYPE = "application/json"; + private static final String JSON_FIELD_NAME = "json-body"; + private static final String FILE_GROUP_NAME = "image-file"; + private static final String UPLOAD_ROOT_PATH = "UPLOAD_ROOT_PATH"; + + private String readMultipartBody(HttpServletRequest request) throws Exception { + String jsonString = null; + // Create a factory for disk-based file items + DiskFileItemFactory factory = new DiskFileItemFactory(); + + // Set the maximum size of the files to be uploaded + factory.setSizeThreshold(1024 * 1024); + + // Set the temporary directory to store uploaded files + File tempDir = (File) request.getSession().getServletContext().getAttribute("javax.servlet.context.tempdir"); + factory.setRepository(tempDir); + + ServletFileUpload upload = new ServletFileUpload(factory); + Map fileMap = new HashMap<>(); + + InputStream fin = null; + try { + byte[] buffer = new byte[1024]; + int read = 0; + + List items = upload.parseRequest(request); + for (FileItem item : items) { + if (!item.isFormField()) { + // file + String fieldName = item.getFieldName(); + String fileName = item.getName(); + fin = item.getInputStream(); + ByteArrayOutputStream fo = new ByteArrayOutputStream(); + while ((read = fin.read(buffer)) > 0) { + fo.write(buffer, 0, read); + } + int fileSize = fo.size(); + byte[] fileBytes = fo.toByteArray(); + String fileContents = new String(fileBytes); + if (logger.isInfo()) { + logger.info("[FILE]-------------------------------------------------->"); + logger.info("Field name = " + fieldName); + logger.info("File name = " + fileName + " contents length = " + fileSize); + logger.info("File Contents [" + fileContents + "]"); + logger.info("[FILE]<--------------------------------------------------"); + } + fileMap.put(fileName, fileContents); + fin.close(); + } else { + // regular form field + String fieldName = item.getFieldName(); + String fieldValue = item.getString(); + if (logger.isInfo()) { + logger.info("[FIELD] " + fieldName + " [" + fieldValue + "]"); + } + if (JSON_CONTENT_TYPE.equalsIgnoreCase(item.getContentType()) + || JSON_FIELD_NAME.equals(fieldName)) { + jsonString = fieldValue; + } + } + } + + if (logger.isInfo()) { + logger.info("Json body [" + jsonString + "]"); + } + + if (jsonString == null) { + jsonString = "{}"; + } else { + // parsing json & add file contents + JSONObject jsonObject = (JSONObject) JSONValue.parse(jsonString); + if (jsonObject == null) { + jsonString = "{}"; + } else { + JSONObject fileGroup = new JSONObject(); + + for (Map.Entry entry : fileMap.entrySet()) { + fileGroup.put("fileName", entry.getKey()); + fileGroup.put("fileContents", entry.getValue()); + } + jsonObject.put(FILE_GROUP_NAME, fileGroup); + jsonString = jsonObject.toJSONString(); + } + } + + if (logger.isInfo()) { + logger.info("Json with file [" + jsonString + "]"); + } + return jsonString; + } catch (Exception e) { + logger.error("Read multipart body error.", e); + throw e; + } finally { + if (fin != null) { + try { + fin.close(); + } catch (Exception ex) { + // empty + } + } + } + } + + private String checkRootPath(String path) { + if (StringUtils.isEmpty(path)) { + logger.info("upload dir not set(UPLOAD_ROOT_PATH), use system temp " + path); + return System.getProperty("java.io.tmpdir"); + } + File file = new File(path); + if (!file.exists()) { + file.mkdirs(); + } + return path; + } + + private String uploadMultipartBody(HttpServletRequest request, String uploadRootPath) throws Exception { + String jsonString = null; + // Create a factory for disk-based file items + DiskFileItemFactory factory = new DiskFileItemFactory(); + + // Set the maximum size of the files to be uploaded + factory.setSizeThreshold(1024 * 1024); + + // Set the temporary directory to store uploaded files + File tempDir = (File) request.getSession().getServletContext().getAttribute("javax.servlet.context.tempdir"); + factory.setRepository(tempDir); + + ServletFileUpload upload = new ServletFileUpload(factory); + try { + // if not exist, create folders + String uploadDir = checkRootPath(uploadRootPath); + List items = upload.parseRequest(request); + for (FileItem item : items) { + if (!item.isFormField()) { + // file + String fieldName = item.getFieldName(); + String fileName = item.getName(); + String uploadFilePath = uploadDir + File.separator + fileName; + File uploadFile = new File(uploadFilePath); + item.write(uploadFile); + + if (logger.isInfo()) { + logger.info("[FILE]-------------------------------------------------->"); + logger.info("Field name = " + fieldName); + logger.info("File name = " + fileName + " path = " + uploadFile.getAbsolutePath()); + logger.info("[FILE]<--------------------------------------------------"); + } + } else { + // regular form field + String fieldName = item.getFieldName(); + String fieldValue = item.getString(); + if (logger.isInfo()) { + logger.info("[FIELD] " + fieldName + " [" + fieldValue + "]"); + } + if (JSON_CONTENT_TYPE.equalsIgnoreCase(item.getContentType()) + || JSON_FIELD_NAME.equals(fieldName)) { + jsonString = fieldValue; + } + } + } + + if (logger.isInfo()) { + logger.info("Json body [" + jsonString + "]"); + } + return jsonString; + } catch (Exception e) { + logger.error("Read multipart body error.", e); + throw e; + } + } + + @SuppressWarnings({ "unchecked", "deprecation" }) + public void service(String adptGrpName, String adptName, HttpServletRequest request, HttpServletResponse response) { + int traceLevel = 0; + + AdapterVO adptVO = null; + AdapterPropManager manager = null; + + Properties httpProp = null; + String responseType = null; + String urlDecodeYn = null; + String encode = null; + + String traceLevelTemp = null; + String relayRequestHeaderKeys = null; + String headerGroupName = null; + + boolean isParameterType = false; + String message = null; + + StopWatch stopWatch = null; + Properties prop = null; + String paramValue = null; + String adptMsgType = null; + String errorResponseFormat = null; + String uploadRootPath = null; + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + adptVO = adapterManager.getAdapterVO(adptGrpName, adptName); + if (adptVO == null) { + throw new Exception("Adapter not found error"); + } + + manager = AdapterPropManager.getInstance(); + + httpProp = manager.getProperties(adptVO.getPropGroupName()); + responseType = httpProp.getProperty(RESPONSE_TYPE, "SYNC"); + urlDecodeYn = httpProp.getProperty(URL_DECODE_YN, "N"); + // encode = httpProp.getProperty(ENCODE, "UTF-8"); + encode = StringUtils.defaultIfBlank(adapterManager.getAdapterGroupVO(adptGrpName).getMessageEncode(), + "UTF-8"); + traceLevelTemp = httpProp.getProperty(TRACE_LEVEL, "0"); + relayRequestHeaderKeys = httpProp.getProperty(HEADER_KEYS); + headerGroupName = httpProp.getProperty(HEADER_GROUP); + errorResponseFormat = httpProp.getProperty(ERROR_RESPONSE_FORMAT); + uploadRootPath = httpProp.getProperty(UPLOAD_ROOT_PATH); + prop = new Properties(); + prop.put(INBOUND_METHOD, request.getMethod()); + prop.put(INBOUND_URI, request.getRequestURI()); + prop.put(INBOUND_HEADER, getHeaders(request)); + if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) + || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { + // /api/v1/public/getUserInfo.svc + String extUrl = StringUtils.removeStart(request.getRequestURI(), request.getContextPath()); + prop.put(INBOUND_EXTURI, extUrl); + } else { + prop.put(INBOUND_EXTURI, getExtUri(request)); + } + prop.put(Processor.REQUEST_ACTION, adptVO.getAdapterGroupVO().getRefClass()); + prop.put(API_PATH, httpProp.getProperty(API_PATH, "")); + prop.put(PRE_FILTERS, httpProp.getProperty(PRE_FILTERS, "")); + prop.put(POST_FILTERS, httpProp.getProperty(POST_FILTERS, "")); + prop.put(PROPERTIES_NAME_HTTP_REQUEST_METHOD, request.getMethod()); + prop.put(ALLOW_IP, httpProp.getProperty(ALLOW_IP, "")); + + isParameterType = false; + try { + traceLevel = Integer.parseInt(traceLevelTemp); + } catch (Exception e) { + traceLevel = 0; + } + + stopWatch = new StopWatch(); + stopWatch.start(); + + logger.debug("시작 >> encode = [" + encode + "]"); + + switch (HttpMethodType.getValue(request.getMethod())) { + case GET: + case DELETE: + isParameterType = true; + break; + case POST: + case PUT: + if (StringUtils.contains(request.getContentType(), "application/x-www-form-urlencoded")) { + isParameterType = true; + } else { + isParameterType = false; + } + break; + default: + break; + } + + if (isParameterType) { + paramValue = request.getQueryString(); + if (paramValue == null) + paramValue = ""; + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, + "RECV " + "[" + paramValue + "]" + CommonLib.getDumpMessage(paramValue)); + } + + // json으로 변환 + StringBuilder sb = new StringBuilder(); + sb.append("{"); + Map paramMap = assignParameterMap(request, adptGrpName, adptName, null, prop); + int i = 0; + for (Map.Entry entry : paramMap.entrySet()) { + if (i > 0) { + sb.append(","); + } + sb.append("\"").append(entry.getKey()).append("\":"); + String[] values = entry.getValue(); + if (values.length > 1) { + // ["111", "222"] + sb.append("["); + for (int j = 0; j < values.length; j++) { + if (j > 0) { + sb.append(","); + } + sb.append("\"").append(JSONValue.escape(values[j])).append("\""); + } + sb.append("]"); + } else { + sb.append("\"").append(JSONValue.escape(values[0])).append("\""); + } + + i++; + } + + sb.append("}"); + + paramValue = sb.toString(); + } else { + if (ServletFileUpload.isMultipartContent(request)) { + // TODO : 아래의 로직은 업무에 맞게 수정이 필요함. + // 불필요할 경우 제거 +// if(StringUtils.isEmpty(uploadRootPath)) { +// uploadRootPath = System.getProperty("java.io.tmpdir"); +// } + + // 임시로직 : UPLOAD_ROOT_PATH 가 없는 경우에는 JSON에 추가 + if (StringUtils.isEmpty(uploadRootPath)) { + paramValue = readMultipartBody(request); + } else { + paramValue = uploadMultipartBody(request, uploadRootPath); + } + // TEST : 테스트용 임시코드 +// response.setCharacterEncoding(encode); +// response.getWriter().print(paramValue); +// return; + } else { + ServletInputStream sis = request.getInputStream(); + ByteBuffer bb = ByteBuffer.allocate(1024).setAutoExpand(true); + int i = 0; + byte[] cbuf = new byte[1024]; + while ((i = sis.read(cbuf, 0, 1024)) != -1) { + if (i == 1024) { + bb.put(cbuf); + } else { + byte[] tail = new byte[i]; + System.arraycopy(cbuf, 0, tail, 0, i); + bb.put(tail); + } + } + byte[] data = new byte[bb.position()]; + bb.position(0); + bb.get(data); + paramValue = new String(data, encode); + + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, + "RECV " + "[" + paramValue + "]" + CommonLib.getDumpMessage(paramValue)); + } + } + } + + if (paramValue == null) { // parameter가 없는 경우때문에 처리 + paramValue = ""; + } + + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceRest] RECV (" + adptGrpName + ") = [" + paramValue + "]\n" + + CommonLib.getDumpMessage(paramValue)); + } + + if ("Y".equals(urlDecodeYn) && isParameterType) { + message = URLDecoder.decode(paramValue); + } else { + message = paramValue; + } + + if (logger.isDebug()) { + String[] msgArgs = new String[2]; + msgArgs[0] = adptGrpName; + msgArgs[1] = message; + String resMsg = ExceptionUtil.make("RICEAIAHA005", msgArgs); + logger.debug(logPrefix + resMsg); + } + + adptMsgType = adptVO.getAdapterGroupVO().getMessageType(); + if (StringUtils.equals(adptMsgType, MessageType.JSON)) { + response.setContentType(JSON_CONTENT_TYPE+"; charset="+encode); + } + + // HEADER_GROUP 셋팅 + if (MessageType.JSON.equals(adptMsgType) && StringUtils.isNotBlank(headerGroupName) + && StringUtils.isNotBlank(relayRequestHeaderKeys)) { + JSONObject jsonMessage = (JSONObject) JSONValue.parse(message); + JSONObject headerJson = new JSONObject(); + if (StringUtils.equalsIgnoreCase(relayRequestHeaderKeys, "ALL")) { + for (Enumeration e = request.getHeaderNames(); e.hasMoreElements();) { + String key = e.nextElement(); + headerJson.put(key, request.getHeader(key)); + } + } else { + String[] relayKeyArr = org.springframework.util.StringUtils + .tokenizeToStringArray(relayRequestHeaderKeys, ","); + + for (String key : relayKeyArr) { + String headerValue = request.getHeader(key); + if (StringUtils.isNotBlank(headerValue)) { + headerJson.put(key, headerValue); + } + } + } + + if (headerJson.size() > 0) { + jsonMessage.put(headerGroupName, headerJson); + message = jsonMessage.toJSONString(); + } + } + + if (message == null) { + message = ""; + } + + // 로컬 서비스 호출 ,encoding 처리 추가 + String result = (String) service(adptGrpName, adptName, message, prop, request, response); + + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceRest] result " + encode + " (" + adptGrpName + ") = [" + result + "]"); + } + + stopWatch.stop(); + + String responseData = ""; + if (RESPONSE_TYPE_ASYNC.equals(responseType)) { + if (stopWatch.getTime() > slowTranTime && (logger.isInfo())) { + logger.info("HttpAdapterServiceRest] dummy response time = " + stopWatch.toString() + ", message = " + + message); + + } + if (result == null) { + responseData = ElinkConfig.getAsyncDummyDataForAdapterGroup(adptGrpName); + } else { + responseData = result; + } + response.setCharacterEncoding(encode); + response.getWriter().print(responseData); + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, + "SEND " + "[" + responseData + "]" + CommonLib.getDumpMessage(responseData)); + } + } else { + responseData = result; + logger.info("종료 >> encode = [" + encode + "]"); + + JSONObject dataObject = null; + if (MessageType.JSON.equals(adptMsgType)) { + dataObject = (JSONObject) JSONValue.parse(responseData); + } + + // HEADER_GROUP 하위 필드를 response Header에 세팅한다. + HashMap header = new HashMap<>(); + boolean redirect = assignHttpHeaders(header, dataObject, headerGroupName); + + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceRest] response header field (" + adptGrpName + ") = [" + + header.toString() + "]"); + } + + if (redirect) { + response.setStatus(302); + logger.debug("HttpAdapterServiceRest] set response status_code: 302"); + } else { + String httpStatus = header.get(HTTP_STATUS); + if (httpStatus != null && !"".equals(httpStatus)) + response.setStatus(Integer.parseInt(httpStatus)); + header.remove(HTTP_STATUS); + } + + // response header 셋팅 + for (Map.Entry entry : header.entrySet()) { + response.setHeader(entry.getKey(), entry.getValue()); + } + + if (dataObject != null) { + responseData = dataObject.toJSONString(); + } + + // UI와 통신시(UTF-8) 변환오류로 ENCODE 제거 + response.setCharacterEncoding(encode); + response.getWriter().print(responseData); + if (logger.isDebug()) { + logger.debug("HttpAdapterServiceRest] SEND (" + adptGrpName + ") = [" + responseData + "]"); + logger.debug("HttpAdapterServiceRest] SEND (" + adptGrpName + ") = " + + CommonLib.getDumpMessage(responseData)); + } + if (traceLevel >= 3) { + HttpMemoryLogger.txlog(adptGrpName + adptName, + "SEND " + "[" + responseData + "]" + CommonLib.getDumpMessage(responseData)); + } + } + } catch (HttpStatusException e) { + if (traceLevel >= 3) { + HttpMemoryLogger.error(adptGrpName + adptName, e.toString(), e); + } + logger.warn("HttpAdapter] " + adptGrpName + "-" + adptName + ">>" + e.getMessage()); + response.setStatus(e.getStatus()); + try { + String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, e.getCode(), + e.getMessage(), errorResponseFormat); + response.getWriter().println(errorMsg); + } catch (Exception ex) { + // IGNORE + } + } catch (JwtAuthException e) { + if (traceLevel >= 3) { + HttpMemoryLogger.error(adptGrpName + adptName, e.toString(), e); + } + logger.error(logPrefix + adptGrpName + "-" + adptName + ">>" + e.getMessage(), e); + response.setStatus(HttpStatus.UNAUTHORIZED.value()); + try { + String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, e.getCode(), + e.getMessage(), errorResponseFormat); + response.getWriter().println(errorMsg); + } catch (Exception ex) { + // IGNORE + } + } catch (Exception e) { + if (traceLevel >= 3) { + HttpMemoryLogger.error(adptGrpName + adptName, e.toString(), e); + } + logger.error(logPrefix + adptGrpName + "-" + adptName + ">>" + e.getMessage(), e); + response.setStatus(HttpStatus.INTERNAL_SERVER_ERROR.value()); + try { + response.getWriter().println(e.getMessage()); + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA003"); + throw new Exception(errCode); + } catch (Exception ex) { + // IGNORE + logger.warn(logPrefix + adptGrpName + "-" + adptName + ">>" + e.getMessage(), e); + } + } finally { + String uuid = prop.getProperty(TransactionContextKeys.TRANSACTION_UUID); + String url = prop.getProperty(HttpClientAdapterServiceKey.INBOUND_EXTURI); + String method = prop.getProperty(HttpClientAdapterServiceKey.INBOUND_METHOD); + String adapterGroupName = prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME); + String adapterName = prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_NAME); + int httpStatusCode = response.getStatus(); + HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(uuid, 400, adapterGroupName, adapterName, new HashMap<>(), url, method, httpStatusCode); + } + } + + private Map assignParameterMap(HttpServletRequest request, String adptGrpName, String adptName, + Object requestBytes, Properties prop) { + // PathVariable 체크 + if (StringUtils.equalsAnyIgnoreCase(request.getMethod(), HttpMethod.GET.name(), HttpMethod.DELETE.name()) + && StringUtils.isBlank(request.getQueryString())) { + try { + String actionName = prop.getProperty(Processor.REQUEST_ACTION); + RequestAction action = ActionFactory.createAction(actionName); + action.setAdapterInfo(adptGrpName, adptName, prop); + String[] keys = action.perform(requestBytes); + String requestPath = keys[0]; + + // PathVariable 지원 추가 + String ruledPath = StandardMessageUtil.getMatchedKey(requestPath, actionName); + if (!StringUtils.equals(requestPath, ruledPath) && StringUtils.contains(ruledPath, "{")) { + Map paramMap = new AntPathMatcher().extractUriTemplateVariables(ruledPath, + requestPath); + if (paramMap != null && paramMap.size() > 0) { + Map returnMap = new HashMap<>(); + for (String key : paramMap.keySet()) { + if (StringUtils.equalsIgnoreCase(key, "method")) { + continue; + } + returnMap.put(key, new String[] { paramMap.get(key) }); + } + + return returnMap; + } + } + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + + return request.getParameterMap(); + } + + private void validateServiceAndAdapter(String adptGrpName, String adptName, byte[] requestBytes, Properties prop) + throws JwtAuthException { +// try { +// String actionName = prop.getProperty(Processor.REQUEST_ACTION); +// RequestAction action = ActionFactory.createAction(actionName); +// action.setAdapterInfo(adptGrpName, adptName, prop); +// String[] keys = action.perform(requestBytes); +// String apiId = keys[0]; +// +// // PathVariable 지원 추가 +// apiId = StandardMessageUtil.getMatchedKey(apiId, actionName); +// if (apiId == null) { +// throw new Exception("apiId"); +// } +// +//// STDMessageManager stdheaderManager = STDMessageManager.getInstance(); +//// STDMessage stdmessage = stdheaderManager.getSTDMessage(apiId); +//// if (stdmessage == null) { +//// throw new Exception("stdMsg"); +//// } +// +// long msgRcvTm = System.currentTimeMillis(); +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adptGrpName); +// ProcessVO processVO = setProcessVO(apiId, adptGrpVO.getOsidInstiNo(), msgRcvTm, adptGrpName, adptName); +// ExtMessage extMessage = ExtMessageConverter.getExtMessageForNonStandard(requestBytes, requestBytes, processVO); +// +// EAIMessageManager eaiMsgManager = EAIMessageManager.getInstance(); +//// String eaiSvcCd = stdmessage.getEAITranName() + stdmessage.getSTDHeader().getMesgDvcd(); +// String eaiSvcCd = extMessage.getEAIServiceCode(); +// if (eaiSvcCd == null) { +// eaiSvcCd = extMessage.getInterfaceId() + extMessage.getSendRecv() + extMessage.getDirection(); +// } +// EAIMessage eaiMsg = eaiMsgManager.getEAIMessage(eaiSvcCd); +// logger.warn("adptGrpName=[" + adptGrpName + "],eaiSvcCd=[" + eaiSvcCd + "],eaiMsg=[" + eaiMsg +// + "],getSngSysItfTp=[" + "]"); +// if (eaiMsg == null) { +// throw new Exception("eaiMsg"); +// } +// +// if (!StringUtils.equals(eaiMsg.getSngSysItfTp(), adptGrpName)) { +// throw new Exception("adapter"); +// } +// } catch (Exception e) { +// String msg = String.format("The resource does not exist or does not have permissions(%s): %s", +// e.getMessage(), prop.get(INBOUND_EXTURI)); +// throw new JwtAuthException(JwtAuthFilter.ERROR_AUTHORIZATION_FAIL, msg); +// } + } + +// private ProcessVO setProcessVO(String apiId, String osidInstiNo, long msgRcvTm, String adptGrpName, +// String adptName) { +// ProcessVO vo = new ProcessVO(); +// vo.setSelectedKey(apiId); +// vo.setAdapterGroupName(adptGrpName); +// vo.setAdapterName(adptName); +// vo.setInAdapterOsidInstiNo(osidInstiNo); +// vo.setErrTm(msgRcvTm); +// return vo; +// } + + /** + * request header 를 hashmap으로 조립 + * + * @param request + * @return + */ + private Properties getHeaders(HttpServletRequest request) { + Properties prop = new Properties(); + + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String key = headerNames.nextElement(); + String value = request.getHeader(key); + prop.setProperty(key, value); + } + + return prop; + } + + /** + * adapter property의 HEADER_GROUP으로 정의된 (MFE_HEADER) 그룹의 하위 필드를 http Header에 + * 세팅한다. + * + * @param header + * @param object + */ + private boolean assignHttpHeaders(HashMap header, Object msg, String headerGroupName) { + boolean redirect = false; + + if (msg == null || StringUtils.isBlank(headerGroupName)) { + return false; + } + + if (msg instanceof JSONObject) { + JSONObject headerObject = (JSONObject) ((JSONObject) msg).get(headerGroupName); + + if (headerObject == null) { + return false; + } + + // List headerKeys = new ArrayList<>(); + for (Object key : headerObject.keySet()) { + + Object obj = headerObject.get(key); + if ((obj instanceof JSONObject) || (obj instanceof JSONArray)) { + continue; + } + + header.put((String) key, (String) obj); + + if (StringUtils.equalsIgnoreCase((String) key, "Location")) { + redirect = true; + } + } + + ((JSONObject) msg).remove(headerGroupName); + } + + return redirect; + } + + /** + * 어댑터 명 이후의 URI값을 가져온다. + * + * @param request + * @return + */ + private String getExtUri(HttpServletRequest request) { + String orgUri = request.getRequestURI().replaceAll(request.getContextPath(), ""); + String uri = getExtUri(orgUri, 3); + if (uri != null && uri.trim().length() > 0) { + return "/" + uri; + } else { + return ""; + } + } + + private static String getExtUri(String url, int length) { + String[] urls = url.split("/"); + List newUrls = new ArrayList<>(); + Collections.addAll(newUrls, urls); + return StringUtils.join(newUrls.subList(length, urls.length).toArray(), "/"); + } + +// public static void main(String[] args) throws Exception { +// String orgUri = "/HTT/CbsInNetSys/abcd/123456"; +// String result = ""; +// result = getExtUri(orgUri, 3); +// System.out.println(result); +// } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java new file mode 100644 index 0000000..fc2da76 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/impl/HttpAdapterServiceStandard.java @@ -0,0 +1,306 @@ +package com.eactive.eai.adapter.http.dynamic.impl; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.inbound.processor.Processor; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.time.StopWatch; +import org.apache.mina.common.ByteBuffer; + +import javax.servlet.ServletException; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.List; +import java.util.Properties; + +public class HttpAdapterServiceStandard extends HttpAdapterServiceSupport +{ + public static final String PROPERTIES_NAME_HTTP_REQUEST_METHOD = "httpRequestMethod"; + /* + * Adapter Logger + */ + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + /** + * 1. 기능 : Http Servlet service 구현 메소드 + * 2. 처리 개요 : + * - 로컬 서비스 호출 + * 3. 주의사항 + * + * @param request Http Servlet Request + * @return response Http Servlet Response + * @exception Exception PARAMETER_MESSAGE가 null 이거나 로컬 서비스 호출 중 오류가 발생할 경우 + **/ + public void service(String adptGrpName, String adptName, HttpServletRequest request, HttpServletResponse response) { + int traceLevel = 0; + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterVO adptVO = adapterManager.getAdapterVO(adptGrpName,adptName); + + AdapterPropManager manager = AdapterPropManager.getInstance(); + + if(adptVO == null) { + throw new ServletException("Adapter not Found adptName="+adptName); + } + + Properties httpProp = manager.getProperties(adptVO.getPropGroupName()); + String responseType = httpProp.getProperty(RESPONSE_TYPE,"SYNC"); + String urlDecodeYn = httpProp.getProperty(URL_DECODE_YN,"N"); + String encode = StringUtils.defaultIfBlank(adapterManager.getAdapterGroupVO(adptGrpName).getMessageEncode(), "MS949"); + String messageType = adapterManager.getAdapterGroupVO(adptGrpName).getMessageType(); + String requestBodyYn = httpProp.getProperty(REQUEST_BODY_YN,"N"); + String parameterName = httpProp.getProperty(PARAMETER_NAME,PARAMETER_MESSAGE); + String removeLength = httpProp.getProperty(REMOVE_LENGTH,"0"); + String addData = httpProp.getProperty(ADD_DATA,""); + String traceLevelTemp = httpProp.getProperty(TRACE_LEVEL,"0"); + try{ + traceLevel = Integer.parseInt(traceLevelTemp); + }catch(Exception e){ + traceLevel = 0; + } + + String paramValue = null; + + int removeLen = 0; + try{ + removeLen = Integer.parseInt(removeLength); + }catch(Exception e){ + removeLen = 0; + } + + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + logger.info("시작 >> encode = [" + encode + "]"); + + byte[] requestBytes = null; + + if ("Y".equals(requestBodyYn)){ + ServletInputStream sis = request.getInputStream(); + ByteBuffer bb = ByteBuffer.allocate(1024).setAutoExpand(true); + int i=0; + byte[] cbuf = new byte[1024]; + while( ( i = sis.read(cbuf, 0, 1024) ) != -1 ) { + if (i==1024){ + bb.put(cbuf); + }else{ + byte[] tail = new byte[i]; + System.arraycopy(cbuf, 0, tail, 0, i); + bb.put(tail); + } + } + requestBytes = new byte[bb.position()]; + bb.position(0); + bb.get(requestBytes); + if (traceLevel >= 3){ + HttpMemoryLogger.txlog(adptGrpName+adptName, "RECV "+"["+new String(requestBytes, encode)+"]"+ CommonLib.getDumpMessage(requestBytes)); + } + }else{ + paramValue = request.getParameter(parameterName); + if (traceLevel >= 3){ + HttpMemoryLogger.txlog(adptGrpName+adptName, "RECV "+"["+paramValue+"]"+ + ((paramValue == null)?"":CommonLib.getDumpMessage(paramValue)) + ); + } + + if(paramValue==null) + throw new ServletException("RECEAIAHA002"); + + if ("Y".equals(urlDecodeYn)){ + paramValue = URLDecoder.decode(paramValue); + } + + if (logger.isDebug()){ + logger.debug("HttpAdapter] RECV ("+adptGrpName+") = [" + paramValue + "]"); + logger.debug("HttpAdapter] RECV ("+adptGrpName+") = " + + ((paramValue == null)?"":CommonLib.getDumpMessage(paramValue)) + ); + } + requestBytes = paramValue.getBytes(encode); + } + + if (removeLen > 0 ) { + byte[] cuttedBytes = new byte[requestBytes.length-removeLen]; + System.arraycopy(requestBytes, removeLen, cuttedBytes, 0, cuttedBytes.length); + requestBytes = cuttedBytes; + if (logger.isDebug()){ + logger.debug("HttpAdapter] RECV after remove ("+adptGrpName+") = [" + new String(requestBytes, encode) + "]"); + logger.debug("HttpAdapter] RECV after remove ("+adptGrpName+") = " + CommonLib.getDumpMessage(requestBytes)); + } + } + + if(logger.isDebug()){ + String[] msgArgs = new String[2]; + msgArgs[0] = adptGrpName; + msgArgs[1] = new String(requestBytes, encode); + String resMsg = ExceptionUtil.make("RICEAIAHA005", msgArgs); + logger.debug("HttpAdapter] " + resMsg); + } + + Properties prop = new Properties(); + prop.put(INBOUND_METHOD, request.getMethod()); + prop.put(INBOUND_URI, request.getRequestURI()); + prop.put(INBOUND_HEADER, getHeaders(request)); + if (StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_REST) + || StringUtils.equals(adptVO.getAdapterGroupVO().getType(), Keys.TYPE_HTTP_CUSTOM)) { + // /api/v1/public/getUserInfo.svc + String extUrl = StringUtils.removeStart(request.getRequestURI(), request.getContextPath()); + prop.put(INBOUND_EXTURI, extUrl); + } else { + prop.put(INBOUND_EXTURI, getExtUri(request)); + } + prop.put(Processor.REQUEST_ACTION, adptVO.getAdapterGroupVO().getRefClass()); + prop.put(API_PATH, httpProp.getProperty(API_PATH, "")); + prop.put(PRE_FILTERS, httpProp.getProperty(PRE_FILTERS, "")); + prop.put(POST_FILTERS, httpProp.getProperty(POST_FILTERS, "")); + prop.put(PROPERTIES_NAME_HTTP_REQUEST_METHOD, request.getMethod()); + prop.put(ALLOW_IP, httpProp.getProperty(ALLOW_IP, "")); + + // 로컬 서비스 호출 + Object result = null; + if (MessageUtil.isBytesMessage(messageType)) { + result = service(adptGrpName, adptName, requestBytes, prop, request, response); + } else { + result = service(adptGrpName, adptName, new String(requestBytes, encode), prop, request, response); + } + + stopWatch.stop(); + + String responseData = ""; + if (RESPONSE_TYPE_ASYNC.equals(responseType)){ + if (stopWatch.getTime() > slowTranTime){ + if (logger.isWarn()){ + logger.warn("HttpAdapter] lazy async response time = " + stopWatch.toString() + ", message = "+new String(requestBytes, encode)); + } + } + + if (result == null) { + responseData = ElinkConfig.getAsyncDummyDataForAdapterGroup(adptGrpName); + } else if (result instanceof byte[]) { + responseData = new String((byte[]) result, encode); + } else if (result instanceof String) { + responseData = (String) result; + } + + response.setCharacterEncoding(encode); + response.getWriter().print(responseData); + if (traceLevel >= 3){ + HttpMemoryLogger.txlog(adptGrpName+adptName, "SEND "+"["+responseData+"]"+ + ((responseData == null)?"":CommonLib.getDumpMessage(responseData)) + ); + } + } else { + if(requestBytes != null) { + if (result instanceof byte[]) { + responseData = new String((byte[]) result, encode); + } else if (result instanceof String) { + responseData = (String) result; + } + + logger.info("종료 >> encode = [" + encode + "]"); + + if (addData.length() > 0){ + responseData = addData + responseData; + } + // UI와 통신시(UTF-8) 변환오류로 ENCODE 제거 + response.setContentType("text/plain"); + response.setCharacterEncoding(encode); + response.getWriter().print(responseData); + if (logger.isDebug()){ + logger.debug("HttpAdapter] SEND ("+adptGrpName+") = [" + responseData + "]"); + logger.debug("HttpAdapter] SEND ("+adptGrpName+") = " + + ((responseData == null)?"":CommonLib.getDumpMessage(responseData)) + ); + } + if (traceLevel >= 3){ + HttpMemoryLogger.txlog(adptGrpName+adptName, "SEND "+"["+responseData+"]"+ + ((responseData == null)?"":CommonLib.getDumpMessage(responseData)) + ); + } + } + } + } catch (HttpStatusException e) { + if (traceLevel >= 3) { + HttpMemoryLogger.error(adptGrpName + adptName, e.toString(), e); + } + logger.warn("HttpAdapter] " + adptGrpName + "-" + adptName + ">>" + e.getMessage()); + response.setStatus(e.getStatus()); + try { + String errorMsg = String.format("(%d) %s", e.getStatus(), e.getMessage()); + response.getWriter().println(errorMsg); + } catch (Exception ex) { + // IGNORE + } + } catch (Exception e) { + if (traceLevel >= 3){ + HttpMemoryLogger.error(adptGrpName+adptName, e.toString(),e); + } + logger.error("HttpAdapter] "+adptGrpName+"-"+adptName, e); + response.setStatus(500); + try { + response.getWriter().println(e.getMessage()); + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIAHA003"); + throw new Exception(errCode); + } catch (Exception ex) { + logger.warn("error", ex); + } + } + } + + /** + * 어댑터 명 이후의 URI값을 가져온다. + * + * @param request + * @return + */ + private String getExtUri(HttpServletRequest request) { + String orgUri = request.getRequestURI().replaceAll(request.getContextPath(), ""); + String uri = getExtUri(orgUri, 3); + if (uri != null && uri.trim().length() > 0) { + return "/" + uri; + } else { + return ""; + } + } + + private static String getExtUri(String url, int length) { + String[] urls = url.split("/"); + List newUrls = new ArrayList<>(); + Collections.addAll(newUrls, urls); + return StringUtils.join(newUrls.subList(length, urls.length).toArray(), "/"); + } + /** + * request header 를 hashmap으로 조립 + * + * @param request + * @return + */ + private Properties getHeaders(HttpServletRequest request) { + Properties prop = new Properties(); + + Enumeration headerNames = request.getHeaderNames(); + while (headerNames.hasMoreElements()) { + String key = headerNames.nextElement(); + String value = request.getHeader(key); + prop.setProperty(key, value); + } + + return prop; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveFalseWrapper.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveFalseWrapper.java new file mode 100644 index 0000000..d0c8e57 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveFalseWrapper.java @@ -0,0 +1,20 @@ +package com.eactive.eai.adapter.http.dynamic.wrapper; + +import io.undertow.server.HandlerWrapper; +import io.undertow.server.HttpHandler; +import io.undertow.server.HttpServerExchange; +import io.undertow.util.Headers; + +public class KeepAliveFalseWrapper implements HandlerWrapper { + @Override + public HttpHandler wrap(HttpHandler handler) { + return new HttpHandler() { + @Override + public void handleRequest(HttpServerExchange exchange) throws Exception { + handler.handleRequest(exchange); + exchange.getResponseHeaders().put(Headers.CONNECTION, "close"); + } + }; + } +} + diff --git a/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveTrueWrapper.java b/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveTrueWrapper.java new file mode 100644 index 0000000..ae9e4fc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/dynamic/wrapper/KeepAliveTrueWrapper.java @@ -0,0 +1,69 @@ +package com.eactive.eai.adapter.http.dynamic.wrapper; + +import io.undertow.server.HandlerWrapper; +import io.undertow.server.HttpHandler; +import io.undertow.server.HttpServerExchange; +import io.undertow.server.ServerConnection; +import io.undertow.util.AttachmentKey; +import io.undertow.util.Headers; + +public class KeepAliveTrueWrapper implements HandlerWrapper { + private final AttachmentKey MAX_COUNT = AttachmentKey.create(Integer.class); + private int keepAliveTimeout = 15; + private int maxRequestCount = -1; // 최대 요청 횟수 설정 + + public int getKeepAliveTimeout() { + return keepAliveTimeout; + } + + public void setKeepAliveTimeout(int keepAliveTimeout) { + this.keepAliveTimeout = keepAliveTimeout; + } + + public int getMaxRequestCount() { + return maxRequestCount; + } + + public void setMaxRequestCount(int maxRequestCount) { + this.maxRequestCount = maxRequestCount; + } + + @Override + public HttpHandler wrap(HttpHandler handler) { + return new HttpHandler() { + @Override + public void handleRequest(HttpServerExchange exchange) throws Exception { + // max requst count 가 제한이 없을경우 + if (maxRequestCount == -1) { + handler.handleRequest(exchange); + exchange.getResponseHeaders().put(Headers.KEEP_ALIVE, "timeout=" + keepAliveTimeout); + return; + } + + // 현재 연결의 요청 횟수 가져오기 + ServerConnection con = exchange.getConnection(); + int count = 0; + try { + count = con.getAttachment(MAX_COUNT); + } catch (Exception e) { + + } + count++; + + con.putAttachment(MAX_COUNT, count); + // 최대 요청 횟수를 초과한 경우 연결을 종료하고 로그를 출력 + if (count > maxRequestCount) { + exchange.getConnection().close(); + System.out.println("Connection closed due to exceeding max requests limit."); + return; + } + handler.handleRequest(exchange); + if (count > maxRequestCount - 1) { + exchange.getResponseHeaders().put(Headers.CONNECTION, "close"); + } + exchange.getResponseHeaders().put(Headers.KEEP_ALIVE, + "timeout=" + keepAliveTimeout + ", max=" + (maxRequestCount - count)); + } + }; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/healthcheck/HttpHealthChecker.java b/src/main/java/com/eactive/eai/adapter/http/healthcheck/HttpHealthChecker.java new file mode 100644 index 0000000..3877a1f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/healthcheck/HttpHealthChecker.java @@ -0,0 +1,76 @@ +package com.eactive.eai.adapter.http.healthcheck; + +import java.net.HttpURLConnection; +import java.net.URL; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.util.Logger; + +public class HttpHealthChecker { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private String healthCheckUrl; + private AdapterVO adapter; + int timeoutMillis = 2000; + + + public int getTimeoutMillis() { + return timeoutMillis; + } + + public void setTimeoutMillis(int timeoutMillis) { + this.timeoutMillis = timeoutMillis; + } + + public String getHealthCheckUrl() { + return healthCheckUrl; + } + + public void setHealthCheckUrl(String healthCheckUrl) { + this.healthCheckUrl = healthCheckUrl; + } + + public AdapterVO getAdapter() { + return adapter; + } + + public void setAdapter(AdapterVO adapter) { + this.adapter = adapter; + } + + public boolean isAlive() { + HttpURLConnection connection = null; + String debugPrefix = "HttpHealthChecker] " + adapter.getName() + " healthCheckUrl " + healthCheckUrl; + try { + if(logger.isInfo()) { + logger.info(debugPrefix); + } + URL url = new URL(healthCheckUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(timeoutMillis); // Set connection timeout + connection.setReadTimeout(timeoutMillis); // Set read timeout + + int responseCode = connection.getResponseCode(); + boolean result = false; + if (responseCode == HttpURLConnection.HTTP_OK) { + result = true; + } + + if(logger.isInfo()) { + logger.info(debugPrefix + " returned a response code: " + responseCode); + } + return result; + } + catch(Exception ex) { + logger.error(debugPrefix + " error", ex); + return false; + } + finally { + if(connection != null) { + connection.disconnect(); + } + } + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/healthcheck/HttpTargetMonitor.java b/src/main/java/com/eactive/eai/adapter/http/healthcheck/HttpTargetMonitor.java new file mode 100644 index 0000000..26ad337 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/healthcheck/HttpTargetMonitor.java @@ -0,0 +1,54 @@ +package com.eactive.eai.adapter.http.healthcheck; + +import java.util.Iterator; +import java.util.TimerTask; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.util.Logger; + +public class HttpTargetMonitor extends TimerTask { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private HttpTargetMonitorManager manager; + + public void setManager(HttpTargetMonitorManager manager) { + this.manager = manager; + } + + public void run() { + logger.warn("HttpTargetMonitor] run"); + + if (this.manager == null || !this.manager.isStarted()) { + logger.warn("HttpTargetMonitorManager is stopped. stop HttpTargetMonitor."); + return; + } + + Iterator adapterNames = manager.getAllAdapterNames(); + + ExecutorService executor = Executors.newFixedThreadPool(20); + try { + while (adapterNames.hasNext()) { + String name = adapterNames.next(); + HttpHealthChecker checker = manager.getHttpHeacthChecker(name); + AdapterVO vo = checker.getAdapter(); + if (checker == null || vo == null) { + logger.warn("Target HealthCheck remove - " + name); + manager.removeHttpHeacthChecker(name); + } else { + executor.submit(() -> { + try { + vo.setStatus(checker.isAlive()); + } catch (Exception e) { + if (logger.isError()) { + logger.error("Target HealthCheck error", e); + } + } + }); + } + } + } finally { + executor.shutdown(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/healthcheck/HttpTargetMonitorManager.java b/src/main/java/com/eactive/eai/adapter/http/healthcheck/HttpTargetMonitorManager.java new file mode 100644 index 0000000..b0120bd --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/healthcheck/HttpTargetMonitorManager.java @@ -0,0 +1,239 @@ +package com.eactive.eai.adapter.http.healthcheck; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Timer; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; + +public class HttpTargetMonitorManager implements Lifecycle { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static final String threadName = "HttpTargetMonitorManager"; + + public static final String PROP_GROUP = "HttpTargetMonitor"; + public static final String CHECK_INTERVAL_SECS = "check.interval.secs"; + private static final int CHECK_INTERVAL_MINSECS = 30; + + private int checkIntervalSecs = 60; + + private static HttpTargetMonitorManager manager = new HttpTargetMonitorManager(); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private boolean started; + + private ConcurrentHashMap checkers = new ConcurrentHashMap<>(); + + private HttpTargetMonitor runner; + + private Timer timer; + + public static HttpTargetMonitorManager getInstance() { + return manager; + } + + private void loadHttpAdapterList() { + AdapterManager adapterManager = AdapterManager.getInstance(); + + HashMap adapterGroups = adapterManager.getAllAdapterGroupVO(); + for(AdapterGroupVO adapterGroup : adapterGroups.values()) { + if( adapterGroup.isUsedFlag() + && ( StringUtils.equals(Keys.ADAPTER_OUT, adapterGroup.getGubun()) ) + && ( StringUtils.equals(Keys.TYPE_HTTP, adapterGroup.getType()) || StringUtils.equals(Keys.TYPE_REST, adapterGroup.getType())) + ) { + addAdapterGroup(adapterGroup); + } + } + } + + public void addAdapterGroup(AdapterGroupVO adapterGroup) { + AdapterPropManager propManager = AdapterPropManager.getInstance(); + Iterator adapters = adapterGroup.getAdapters(); + while(adapters.hasNext()) { + AdapterVO adapter = adapters.next(); + String healthCheckUrl = propManager.getProperty(adapter.getPropGroupName(), HttpClientAdapterServiceKey.HEALTHCHECK_URL); + String timeoutMs = propManager.getProperty(adapter.getPropGroupName(), HttpClientAdapterServiceKey.HEALTHCHECK_TIMEOUTMS); + + if(StringUtils.isNotBlank(healthCheckUrl)) { + if(adapterGroup.isUsedFlag()) { + if(logger.isInfo()) { + logger.info(String.format("loadHttpAdapterList AdapterName=%s, healthCheckUrl=%s timeoutMs=%s", adapter.getName(), healthCheckUrl, timeoutMs)); + } + addHttpHeacthChecker(healthCheckUrl, timeoutMs, adapter); + } + else { + if(logger.isInfo()) { + logger.info(String.format("removeHttpHeacthChecker AdapterName=%s, healthCheckUrl=%s timeoutMs=%s", adapter.getName(), healthCheckUrl, timeoutMs)); + } + removeHttpHeacthChecker(adapter); + } + } + else { + if(logger.isInfo()) { + logger.info(String.format("removeHttpHeacthChecker AdapterName=%s, healthCheckUrl=%s timeoutMs=%s", adapter.getName(), healthCheckUrl, timeoutMs)); + } + removeHttpHeacthChecker(adapter); + } + } + } + + public void start() throws LifecycleException { + logger.error(threadName +"] is start"); + if (started) + throw new LifecycleException("RECEAICTM001"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + loadHttpAdapterList(); + + PropManager pmanager = PropManager.getInstance(); + // default 1 mins + + try { + checkIntervalSecs = Integer.parseInt(pmanager.getProperty(PROP_GROUP, CHECK_INTERVAL_SECS)); + } catch (NumberFormatException e) { + logger.warn( String.format("%s %s not number", PROP_GROUP, CHECK_INTERVAL_SECS), e); + } + + if(checkIntervalSecs < CHECK_INTERVAL_MINSECS) { + logger.warn( String.format("%s %s too small, use default %s", CHECK_INTERVAL_SECS, checkIntervalSecs, CHECK_INTERVAL_MINSECS)); + checkIntervalSecs = CHECK_INTERVAL_MINSECS; + } + + this.runner = new HttpTargetMonitor(); + this.runner.setManager(this); + + this.timer = new Timer(threadName); + + long period = (checkIntervalSecs * 1000); + this.timer.schedule(this.runner, period, period); + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICTM002"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + this.timer.cancel(); + this.timer = null; + this.runner = null; + + if (this.checkers != null) { + this.checkers.clear(); + this.checkers = null; + } + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, null); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public void addHttpHeacthChecker(String healthCheckUrl, String timeoutMsVal, AdapterVO vo) { + HttpHealthChecker checker = new HttpHealthChecker(); + checker.setHealthCheckUrl(healthCheckUrl); + + int timeoutMs = 2000; + if(StringUtils.isNoneBlank(timeoutMsVal)) { + try { + timeoutMs = Integer.parseInt(timeoutMsVal); + } + catch(NumberFormatException ne) { + timeoutMs = 2000; + } + } + + if(checkIntervalSecs <= timeoutMs / 1000) { + logger.warn( String.format("%s timeoutMs %s too big, use default %s", vo.getName(), timeoutMs, (checkIntervalSecs-1) * 1000)); + timeoutMs = (checkIntervalSecs-1) * 1000; + } + + checker.setTimeoutMillis(timeoutMs); + checker.setAdapter(vo); + this.checkers.put(vo.getAdapterGroupName() + "-" + vo.getName(), checker); + } + + public void removeHttpHeacthChecker(AdapterVO vo) { + this.checkers.remove(vo.getAdapterGroupName() + "-" + vo.getName()); + } + + public Iterator getAllAdapterNames() { + HashMap map = new HashMap<>(checkers); + return map.keySet().iterator(); + } + + public String[] getAllAdapterNamesWithGroupName(String adapterGroupName) { + HashMap map = new HashMap<>(checkers); + String namePrefix = adapterGroupName + "-"; + Iterator it = map.keySet().iterator(); + List list = new ArrayList<>(); + while(it.hasNext()) { + String key = it.next(); + if(key.startsWith(namePrefix)) { + list.add(key); + } + } + return list.toArray(new String[0]); + } + + public HttpHealthChecker getHttpHeacthChecker(String adapterName) { + return this.checkers.get(adapterName); + } + + public void removeHttpHeacthChecker(String adapterName) { + this.checkers.remove(adapterName); + } + + public void removeHttpHeacthCheckerWithGroupName(String adapterGroupName) { + if(logger.isInfo()) { + logger.info("removeHttpHeacthCheckerWithGroupName - " +adapterGroupName); + } + String[] adatperNames = getAllAdapterNamesWithGroupName(adapterGroupName); + for(int i=0; i< adatperNames.length; i++) { + if(logger.isInfo()) { + logger.info("removeHttpHeacthCheckerWithGroupName remove - " +adatperNames[i]); + } + this.checkers.remove(adatperNames[i]); + } + } + + public int getCheckerCount() { + return this.checkers.size(); + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/secure/CustomHttpsSocketFactory.java b/src/main/java/com/eactive/eai/adapter/http/secure/CustomHttpsSocketFactory.java new file mode 100644 index 0000000..6f156d8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/secure/CustomHttpsSocketFactory.java @@ -0,0 +1,55 @@ +package com.eactive.eai.adapter.http.secure; + +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; +import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; + +import javax.net.ssl.SSLSocket; +import java.io.IOException; +import java.net.InetAddress; +import java.net.Socket; + +public class CustomHttpsSocketFactory implements SecureProtocolSocketFactory +{ + + private final SecureProtocolSocketFactory base; + + public CustomHttpsSocketFactory(ProtocolSocketFactory base) + { + if(base == null || !(base instanceof SecureProtocolSocketFactory)) throw new IllegalArgumentException(); + this.base = (SecureProtocolSocketFactory) base; + } + + private Socket acceptOnlyTLS12(Socket socket) + { + if(!(socket instanceof SSLSocket)) return socket; + SSLSocket sslSocket = (SSLSocket) socket; + sslSocket.setEnabledProtocols(new String[]{"TLSv1", "TLSv1.1", "TLSv1.2"}); + +// for(int i=0; i< sslSocket.getEnabledProtocols().length; i++) +// System.out.println("EnabledProtocols : " + i + " - " + sslSocket.getEnabledProtocols()[i]); + + return sslSocket; + } + + public Socket createSocket(String host, int port) throws IOException + { + return acceptOnlyTLS12(base.createSocket(host, port)); + } + + public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException + { + return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort)); + } + + public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException + { + return acceptOnlyTLS12(base.createSocket(host, port, localAddress, localPort, params)); + } + + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException + { + return acceptOnlyTLS12(base.createSocket(socket, host, port, autoClose)); + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/secure/CustomSSLProtocolSocketFactory.java b/src/main/java/com/eactive/eai/adapter/http/secure/CustomSSLProtocolSocketFactory.java new file mode 100644 index 0000000..547ec26 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/secure/CustomSSLProtocolSocketFactory.java @@ -0,0 +1,58 @@ +package com.eactive.eai.adapter.http.secure; + +import org.apache.commons.httpclient.ConnectTimeoutException; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocket; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.UnknownHostException; + +public class CustomSSLProtocolSocketFactory implements SecureProtocolSocketFactory { + private SSLContext sslContext; + + public CustomSSLProtocolSocketFactory(SSLContext sslContext) { + this.sslContext = sslContext; + } + + @Override + public Socket createSocket(String host, int port) throws IOException, UnknownHostException { + return sslContext.getSocketFactory().createSocket(host, port); + } + + @Override + public Socket createSocket(String host, int port, java.net.InetAddress localAddress, int localPort) throws IOException, UnknownHostException { + return sslContext.getSocketFactory().createSocket(host, port, localAddress, localPort); + } + + @Override + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException { + return sslContext.getSocketFactory().createSocket(socket, host, port, autoClose); + } + + @Override + public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, + HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + int timeout = params.getConnectionTimeout(); + SocketFactory socketfactory = sslContext.getSocketFactory(); + if (timeout == 0) { + return socketfactory.createSocket(host, port, localAddress, localPort); + } else { + Socket socket = socketfactory.createSocket(); + SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); + SocketAddress remoteaddr = new InetSocketAddress(host, port); + socket.bind(localaddr); + socket.connect(remoteaddr, timeout); + return socket; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/secure/EasySSLProtocolSocketFactory.java b/src/main/java/com/eactive/eai/adapter/http/secure/EasySSLProtocolSocketFactory.java new file mode 100644 index 0000000..e87638d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/secure/EasySSLProtocolSocketFactory.java @@ -0,0 +1,254 @@ +package com.eactive.eai.adapter.http.secure; + +/* + * $HeadURL$ + * $Revision$ + * $Date$ + * + * ==================================================================== + * + * 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 + * + * http://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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.UnknownHostException; +import java.security.cert.X509Certificate; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.httpclient.ConnectTimeoutException; +import org.apache.commons.httpclient.HttpClientError; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + + +/** + *

+ * EasySSLProtocolSocketFactory can be used to creats SSL {@link Socket}s + * that accept self-signed certificates. + *

+ *

+ * This socket factory SHOULD NOT be used for productive systems + * due to security reasons, unless it is a concious decision and + * you are perfectly aware of security implications of accepting + * self-signed certificates + *

+ * + *

+ * Example of using custom protocol socket factory for a specific host: + *

+ *     Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
+ *
+ *     URI uri = new URI("https://localhost/", true);
+ *     // use relative url only
+ *     GetMethod httpget = new GetMethod(uri.getPathQuery());
+ *     HostConfiguration hc = new HostConfiguration();
+ *     hc.setHost(uri.getHost(), uri.getPort(), easyhttps);
+ *     HttpClient client = new HttpClient();
+ *     client.executeMethod(hc, httpget);
+ *     
+ *

+ *

+ * Example of using custom protocol socket factory per default instead of the standard one: + *

+ *     Protocol easyhttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
+ *     Protocol.registerProtocol("https", easyhttps);
+ *
+ *     HttpClient client = new HttpClient();
+ *     GetMethod httpget = new GetMethod("https://localhost/");
+ *     client.executeMethod(httpget);
+ *     
+ *

+ * + * @author Oleg Kalnichevski + * + *

+ * DISCLAIMER: HttpClient developers DO NOT actively support this component. + * The component is provided as a reference material, which may be inappropriate + * for use without additional customization. + *

+ */ + +public class EasySSLProtocolSocketFactory implements SecureProtocolSocketFactory { + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(EasySSLProtocolSocketFactory.class); + + private SSLContext sslcontext = null; + + /** + * Constructor for EasySSLProtocolSocketFactory. + */ + public EasySSLProtocolSocketFactory() { + super(); + } + + private static SSLContext createEasySSLContext() { + try { + //--------------------------------------------- + // 인증서 없이 하는 방법 + //--------------------------------------------- + TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, + String authType) { + } + + public void checkServerTrusted(X509Certificate[] certs, + String authType) { + } + } }; + //--------------------------------------------- + SSLContext context = SSLContext.getInstance("SSL"); + context.init( + null, +// new TrustManager[] {new EasyX509TrustManager(null)}, + trustAllCerts, + null); + return context; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + throw new HttpClientError(e.toString()); + } + } + + private SSLContext getSSLContext() { + if (this.sslcontext == null) { + this.sslcontext = createEasySSLContext(); + } + return this.sslcontext; + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int) + */ + public Socket createSocket( + String host, + int port, + InetAddress clientHost, + int clientPort) + throws IOException, UnknownHostException { + + return getSSLContext().getSocketFactory().createSocket( + host, + port, + clientHost, + clientPort + ); + } + + /** + * Attempts to get a new socket connection to the given host within the given time limit. + *

+ * To circumvent the limitations of older JREs that do not support connect timeout a + * controller thread is executed. The controller thread attempts to create a new socket + * within the given limit of time. If socket constructor does not return until the + * timeout expires, the controller terminates and throws an {@link ConnectTimeoutException} + *

+ * + * @param host the host name/IP + * @param port the port on the host + * @param clientHost the local host name/IP to bind the socket to + * @param clientPort the port on the local machine + * @param params {@link HttpConnectionParams Http connection parameters} + * + * @return Socket a new socket + * + * @throws IOException if an I/O error occurs while creating the socket + * @throws UnknownHostException if the IP address of the host cannot be + * determined + */ + public Socket createSocket( + final String host, + final int port, + final InetAddress localAddress, + final int localPort, + final HttpConnectionParams params + ) throws IOException, UnknownHostException, ConnectTimeoutException { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + int timeout = params.getConnectionTimeout(); + SocketFactory socketfactory = getSSLContext().getSocketFactory(); + if (timeout == 0) { + return socketfactory.createSocket(host, port, localAddress, localPort); + } else { + Socket socket = socketfactory.createSocket(); + SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); + SocketAddress remoteaddr = new InetSocketAddress(host, port); + socket.bind(localaddr); + socket.connect(remoteaddr, timeout); + return socket; + } + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.lang.String,int) + */ + public Socket createSocket(String host, int port) + throws IOException, UnknownHostException { + return getSSLContext().getSocketFactory().createSocket( + host, + port + ); + } + + /** + * @see SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean) + */ + public Socket createSocket( + Socket socket, + String host, + int port, + boolean autoClose) + throws IOException, UnknownHostException { + return getSSLContext().getSocketFactory().createSocket( + socket, + host, + port, + autoClose + ); + } + + public boolean equals(Object obj) { + return ((obj != null) && obj.getClass().equals(EasySSLProtocolSocketFactory.class)); + } + + public int hashCode() { + return EasySSLProtocolSocketFactory.class.hashCode(); + } + +} + diff --git a/src/main/java/com/eactive/eai/adapter/http/secure/EasyX509TrustManager.java b/src/main/java/com/eactive/eai/adapter/http/secure/EasyX509TrustManager.java new file mode 100644 index 0000000..64f4431 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/secure/EasyX509TrustManager.java @@ -0,0 +1,115 @@ +package com.eactive.eai.adapter.http.secure; + +/* + * ==================================================================== + * + * 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 + * + * http://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. + * ==================================================================== + * + * This software consists of voluntary contributions made by many + * individuals on behalf of the Apache Software Foundation. For more + * information on the Apache Software Foundation, please see + * . + * + */ + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +/** + *

+ * EasyX509TrustManager unlike default {@link X509TrustManager} accepts + * self-signed certificates. + *

+ *

+ * This trust manager SHOULD NOT be used for productive systems + * due to security reasons, unless it is a concious decision and + * you are perfectly aware of security implications of accepting + * self-signed certificates + *

+ * + * @author Adrian Sutton + * @author Oleg Kalnichevski + * + *

+ * DISCLAIMER: HttpClient developers DO NOT actively support this component. + * The component is provided as a reference material, which may be inappropriate + * for use without additional customization. + *

+ */ + +public class EasyX509TrustManager implements X509TrustManager +{ + private X509TrustManager standardTrustManager = null; + + /** Log object for this class. */ + private static final Log LOG = LogFactory.getLog(EasyX509TrustManager.class); + + /** + * Constructor for EasyX509TrustManager. + */ + public EasyX509TrustManager(KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException { + super(); + TrustManagerFactory factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + factory.init(keystore); + TrustManager[] trustmanagers = factory.getTrustManagers(); + if (trustmanagers.length == 0) { + throw new NoSuchAlgorithmException("no trust manager found"); + } + this.standardTrustManager = (X509TrustManager)trustmanagers[0]; + } + + /** + * @see X509TrustManager#checkClientTrusted(X509Certificate[],String authType) + */ + public void checkClientTrusted(X509Certificate[] certificates,String authType) throws CertificateException { + standardTrustManager.checkClientTrusted(certificates,authType); + } + + /** + * @see X509TrustManager#checkServerTrusted(X509Certificate[],String authType) + */ + public void checkServerTrusted(X509Certificate[] certificates,String authType) throws CertificateException { + if ((certificates != null) && LOG.isDebugEnabled()) { + LOG.debug("Server certificate chain:"); + for (int i = 0; i < certificates.length; i++) { + LOG.debug("X509Certificate[" + i + "]=" + certificates[i]); + } + } + if ((certificates != null) && (certificates.length == 1)) { + certificates[0].checkValidity(); + } else { + standardTrustManager.checkServerTrusted(certificates,authType); + } + } + + /** + * @see X509TrustManager#getAcceptedIssuers() + */ + public X509Certificate[] getAcceptedIssuers() { + return this.standardTrustManager.getAcceptedIssuers(); + } +} + diff --git a/src/main/java/com/eactive/eai/adapter/http/secure/HttpClient5SSLContextFactory.java b/src/main/java/com/eactive/eai/adapter/http/secure/HttpClient5SSLContextFactory.java new file mode 100644 index 0000000..edad554 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/secure/HttpClient5SSLContextFactory.java @@ -0,0 +1,156 @@ +package com.eactive.eai.adapter.http.secure; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.Base64; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; + +import org.apache.commons.codec.binary.StringUtils; +import org.apache.hc.core5.ssl.SSLContextBuilder; +import org.apache.hc.core5.ssl.TrustStrategy; + +import com.eactive.eai.util.TestModeChecker; + +public class HttpClient5SSLContextFactory { + + private static boolean testMode = TestModeChecker.isTestMode(); + + private HttpClient5SSLContextFactory() { + + } + + // not used (파일인증서 관리시 사용) + public static SSLContext createMTLSContextFromFile(String type, String keyStorePath, String keyStorePassword, + String trustStorePath, String trustStorePassword, boolean skipTrust, String[] tlsVersions, + String[] cipherSuites) throws SSLContextCreateException { + try { + KeyStore keyStore = KeyStore.getInstance(type); + try (FileInputStream keyStoreInput = new FileInputStream(new File(keyStorePath))) { + keyStore.load(keyStoreInput, keyStorePassword.toCharArray()); + } + + SSLContextBuilder sslContextBuilder = null; + if (skipTrust) { + if (testMode) { + // 모든 인증서 신뢰 설정 + TrustStrategy trustAllCertificates = new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] chain, String authType) { + return true; + } + }; + sslContextBuilder = SSLContextBuilder.create() + .loadKeyMaterial(keyStore, keyStorePassword.toCharArray()) // 클라이언트 키스토어 로드 + .loadTrustMaterial(null, trustAllCertificates); // 모든 인증서를 신뢰하도록 설정 + } else { + // 기본 TrustStore를 사용하여 신뢰 설정 + // java root CA를 사용함 (jvm 설정에 추가되어야 함 ) + sslContextBuilder = SSLContextBuilder.create() + .loadKeyMaterial(keyStore, keyStorePassword.toCharArray()) + .loadTrustMaterial((TrustStrategy) null); + } + } else { + KeyStore trustStore = KeyStore.getInstance(type); + try (FileInputStream trustStoreInput = new FileInputStream(new File(trustStorePath))) { + trustStore.load(trustStoreInput, trustStorePassword.toCharArray()); + } + + sslContextBuilder = SSLContextBuilder.create().loadKeyMaterial(keyStore, keyStorePassword.toCharArray()) + .loadTrustMaterial(trustStore, (TrustStrategy) null); + } + + SSLContext sslContext = sslContextBuilder.build(); + + SSLParameters sslParameters = sslContext.getDefaultSSLParameters(); + if (tlsVersions != null) { + sslParameters.setProtocols(tlsVersions); + } + if (cipherSuites != null) { + sslParameters.setCipherSuites(cipherSuites); + } + + return sslContext; + } catch (Exception e) { + String errorMessage = String.format("Failed to create SSLContext type(Algorithm): %s", type); + throw new SSLContextCreateException(errorMessage, e); + } + } + + public static SSLContext createMTLSContextFromContent(String type, String keyStoreBase64Content, + String keyStorePassword, String trustStoreBase64Content, String trustStorePassword, boolean skipTrust, + String[] tlsVersions, String[] cipherSuites) throws SSLContextCreateException { + try { + KeyStore keyStore = KeyStore.getInstance(type); + byte[] keyBytes = Base64.getDecoder().decode(keyStoreBase64Content); + try (ByteArrayInputStream bis = new ByteArrayInputStream(keyBytes)) { + keyStore.load(bis, keyStorePassword.toCharArray()); + } + + SSLContextBuilder sslContextBuilder = null; + if (skipTrust) { + if (testMode) { + // 모든 인증서를 신뢰함 + TrustStrategy trustAllCertificates = new TrustStrategy() { + @Override + public boolean isTrusted(X509Certificate[] chain, String authType) { + return true; + } + }; + sslContextBuilder = SSLContextBuilder.create() + .loadKeyMaterial(keyStore, keyStorePassword.toCharArray()) + .loadTrustMaterial(null, trustAllCertificates); + } else { + // java root CA를 사용함 (jvm 설정에 추가되어야 함) + // java root CA 사용 + sslContextBuilder = SSLContextBuilder.create() + .loadKeyMaterial(keyStore, keyStorePassword.toCharArray()) + .loadTrustMaterial((TrustStrategy) null); + } + } else { + KeyStore trustStore = KeyStore.getInstance(type); + byte[] trustBytes = Base64.getDecoder().decode(trustStoreBase64Content); + try (ByteArrayInputStream bis = new ByteArrayInputStream(trustBytes)) { + trustStore.load(bis, trustStorePassword.toCharArray()); + } + + sslContextBuilder = SSLContextBuilder.create().loadKeyMaterial(keyStore, keyStorePassword.toCharArray()) + .loadTrustMaterial(trustStore, (TrustStrategy) null); // 신뢰할 모든 인증서 + } + + SSLContext sslContext = sslContextBuilder.build(); + + SSLParameters sslParameters = sslContext.getDefaultSSLParameters(); + if (tlsVersions != null) { + sslParameters.setProtocols(tlsVersions); + } + if (cipherSuites != null) { + sslParameters.setCipherSuites(cipherSuites); + } + + return sslContext; + } catch (Exception e) { + String errorMessage = String.format("Failed to create SSLContext type(Algorithm): %s", type); + throw new SSLContextCreateException(errorMessage, e); + } + } + + public static SSLContext createMTLSContextForJKS(String keyStorePath, String keyStorePassword, + String trustStorePath, String trustStorePassword, String[] tlsVersions, String[] cipherSuites) + throws SSLContextCreateException { + return createMTLSContextFromFile("JKS", keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, + false, tlsVersions, cipherSuites); + } + + public static SSLContext createMTLSContextForP12(String keyStorePath, String keyStorePassword, + String trustStorePath, String trustStorePassword, String[] tlsVersions, String[] cipherSuites) + throws SSLContextCreateException { + return createMTLSContextFromFile("PKCS12", keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, + false, tlsVersions, cipherSuites); + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/http/secure/SSLContextCreateException.java b/src/main/java/com/eactive/eai/adapter/http/secure/SSLContextCreateException.java new file mode 100644 index 0000000..bd9c2e4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/secure/SSLContextCreateException.java @@ -0,0 +1,14 @@ +package com.eactive.eai.adapter.http.secure; + +public class SSLContextCreateException extends Exception { + private static final long serialVersionUID = 1L; + + public SSLContextCreateException(String message) { + super(message); + } + + public SSLContextCreateException(String message, Throwable cause) { + super(message, cause); + } +} + diff --git a/src/main/java/com/eactive/eai/adapter/http/secure/SSLContextFactory.java b/src/main/java/com/eactive/eai/adapter/http/secure/SSLContextFactory.java new file mode 100644 index 0000000..d85eee3 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/secure/SSLContextFactory.java @@ -0,0 +1,170 @@ +package com.eactive.eai.adapter.http.secure; + +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.security.KeyStore; +import java.security.cert.X509Certificate; +import java.util.Base64; + +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLParameters; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.codec.binary.StringUtils; + +import com.eactive.eai.util.TestModeChecker; + +public class SSLContextFactory { + + private static boolean testMode = TestModeChecker.isTestMode(); + + private SSLContextFactory() { + + } + + // not used (파일인증서 관리시 사용) + public static SSLContext createMTLSContextFromFile(String type, String keyStorePath, String keyStorePassword, + String trustStorePath, String trustStorePassword, boolean skipTrust, String[] tlsVersions, + String[] cipherSuites) throws SSLContextCreateException { + try { + KeyStore keyStore = KeyStore.getInstance(type); + try (FileInputStream keyStoreInput = new FileInputStream(new File(keyStorePath))) { + keyStore.load(keyStoreInput, keyStorePassword.toCharArray()); + } + + KeyStore trustStore = KeyStore.getInstance(type); + try (FileInputStream trustStoreInput = new FileInputStream(new File(trustStorePath))) { + trustStore.load(trustStoreInput, trustStorePassword.toCharArray()); + } + + KeyManagerFactory keyManagerFactory = KeyManagerFactory + .getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, trustStorePassword.toCharArray()); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + if (skipTrust) { + if (testMode) { + TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + } }; + sslContext.init(keyManagerFactory.getKeyManagers(), trustAllCerts, null); + } else { + // java root CA를 사용함 (jvm 설정에 추가되어야 함) + TrustManagerFactory trustManagerFactory = TrustManagerFactory + .getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init((KeyStore) null); + sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); + } + } else { + TrustManagerFactory trustManagerFactory = TrustManagerFactory + .getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(trustStore); + + sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); + } + + SSLParameters sslParameters = sslContext.getDefaultSSLParameters(); + if (tlsVersions != null) { + sslParameters.setProtocols(tlsVersions); + } + if (cipherSuites != null) { + sslParameters.setCipherSuites(cipherSuites); + } + + return sslContext; + } catch (Exception e) { + String errorMessage = String.format("Failed to create SSLContext type(Algorithm): %s", type); + throw new SSLContextCreateException(errorMessage, e); + } + } + + public static SSLContext createMTLSContextFromContent(String type, String keyStoreBase64Content, + String keyStorePassword, String trustStoreBase64Content, String trustStorePassword, boolean skipTrust, + String[] tlsVersions, String[] cipherSuites) throws SSLContextCreateException { + try { + KeyStore keyStore = KeyStore.getInstance(type); + byte[] keyBytes = Base64.getDecoder().decode(keyStoreBase64Content); + try (ByteArrayInputStream bis = new ByteArrayInputStream(keyBytes)) { + keyStore.load(bis, keyStorePassword.toCharArray()); + } + + KeyStore trustStore = KeyStore.getInstance(type); + byte[] trustBytes = Base64.getDecoder().decode(trustStoreBase64Content); + try (ByteArrayInputStream bis = new ByteArrayInputStream(trustBytes)) { + trustStore.load(bis, trustStorePassword.toCharArray()); + } + + KeyManagerFactory keyManagerFactory = KeyManagerFactory + .getInstance(KeyManagerFactory.getDefaultAlgorithm()); + keyManagerFactory.init(keyStore, keyStorePassword.toCharArray()); + + SSLContext sslContext = SSLContext.getInstance("TLS"); + if (skipTrust) { + if (testMode) { + TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return null; + } + + public void checkClientTrusted(X509Certificate[] certs, String authType) { + } + + public void checkServerTrusted(X509Certificate[] certs, String authType) { + } + } }; + sslContext.init(keyManagerFactory.getKeyManagers(), trustAllCerts, null); + } else { + // java root CA를 사용함 (jvm 설정에 추가되어야 함) + TrustManagerFactory trustManagerFactory = TrustManagerFactory + .getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init((KeyStore) null); + sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); + } + } else { + + TrustManagerFactory trustManagerFactory = TrustManagerFactory + .getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(trustStore); + sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null); + } + + SSLParameters sslParameters = sslContext.getDefaultSSLParameters(); + if (tlsVersions != null) { + sslParameters.setProtocols(tlsVersions); + } + if (cipherSuites != null) { + sslParameters.setCipherSuites(cipherSuites); + } + return sslContext; + } catch (Exception e) { + String errorMessage = String.format("Failed to create SSLContext type(Algorithm): %s", type); + throw new SSLContextCreateException(errorMessage, e); + } + } + + public static SSLContext createMTLSContextForJKS(String keyStorePath, String keyStorePassword, + String trustStorePath, String trustStorePassword, String[] tlsVersions, String[] cipherSuites) + throws SSLContextCreateException { + return createMTLSContextFromFile("JKS", keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, + false, tlsVersions, cipherSuites); + } + + public static SSLContext createMTLSContextForP12(String keyStorePath, String keyStorePassword, + String trustStorePath, String trustStorePassword, String[] tlsVersions, String[] cipherSuites) + throws SSLContextCreateException { + return createMTLSContextFromFile("PKCS12", keyStorePath, keyStorePassword, trustStorePath, trustStorePassword, + false, tlsVersions, cipherSuites); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/http/servlet/HttpAdapterLogServlet.java b/src/main/java/com/eactive/eai/adapter/http/servlet/HttpAdapterLogServlet.java new file mode 100644 index 0000000..219d986 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/servlet/HttpAdapterLogServlet.java @@ -0,0 +1,133 @@ +package com.eactive.eai.adapter.http.servlet; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.HttpMemoryLogger; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; + +import java.util.HashMap; +import java.util.List; + +public class HttpAdapterLogServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + + String command = request.getContext(); + if (command.lastIndexOf('/') == -1) { + command = ""; + } else { + command = command.substring(command.indexOf('/')+1); + } + + String result = ""; + + try { + if (command == null || "".equals(command) || "show".equals(command)) { + result = show(request.getParameter("adapter")); + } else if (command.startsWith("errorLog")) { + result = errorLog(request.getParameter("adapter")); + } else if (command.startsWith("txLog")) { + result = txLog(request.getParameter("adapter")); + } else { + response.setResponseCode(404); + return; + } + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html;charset=utf-8;"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + final static String SCRIPT = + " \n"; + + public String show(String key) { + StringBuffer sb = new StringBuffer(); + AdapterManager manager = AdapterManager.getInstance(); + //List list = manager.getAllAdapterGroupNames(); + + HashMap hm = manager.getAllAdapterGroupVO(); + List names = manager.getAllAdapterGroupNames(); + + sb.append(SCRIPT); + sb.append("http adapter log | keyword = " + key); + sb.append("
"); + + + for(String name : names){ + AdapterGroupVO vo = hm.get(name); + if ("HTT".equals(vo.getType())){ + if(name.indexOf(key) >=0){ + sb.append("
");
+    				sb.append(String.format("ⓖ %-50s ", name)+"\n");
+    				for(String adapter :  vo.getAdapterNames()){
+    					sb.append(String.format("    ⓐ %-50s ", adapter));
+    					sb.append("txLog : "+HttpMemoryLogger.getTransactionCount(name+adapter)+" ");
+    					sb.append("errorLog : "+HttpMemoryLogger.getErrorCount(name+adapter)+" ");
+    					sb.append("
"+"\n"); + } + sb.append("
"+"\n"); + + } + } + + } + + return sb.toString(); + } + public String txLog(String name) { + StringBuffer sb = new StringBuffer(); + + sb.append(SCRIPT); + sb.append("adapter ="+name+"
"); + String[] logs = HttpMemoryLogger.getTransactions(name); + for (int i=logs.length-1; i>=0; i--) { + sb.append("
"); + sb.append("
");
+    		sb.append(logs[i]);
+    	   	sb.append("
"); + sb.append("
"); + sb.append("
"); + + } + return sb.toString(); + } + public String errorLog(String name) { + StringBuffer sb = new StringBuffer(); + + sb.append(SCRIPT); + sb.append("adapter ="+name+"
"); + String[] logs = HttpMemoryLogger.getErrors(name); + for (int i=logs.length-1; i>=0; i--) { + sb.append("
"); + sb.append("
");
+    		sb.append(logs[i]);
+    	   	sb.append("
"); + sb.append("
"); + sb.append("
"); + + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/http/util/HttpsGenerator.java b/src/main/java/com/eactive/eai/adapter/http/util/HttpsGenerator.java new file mode 100644 index 0000000..ff7d6e8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/http/util/HttpsGenerator.java @@ -0,0 +1,207 @@ +package com.eactive.eai.adapter.http.util; + +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.common.util.Logger; +import org.apache.commons.httpclient.HostConfiguration; +import org.apache.commons.httpclient.URI; +import org.apache.commons.httpclient.URIException; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; + +import javax.net.ssl.*; +import java.io.*; +import java.security.*; + +public class HttpsGenerator { + + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + // TODO 프라퍼티에서 관리하는걸로 수정 할것 + private static final String PROP_KEYSTORE_PATH = "/certificate/keystore.p12"; + private static final String PROP_KEYSTORE_PW = "elink-ssl"; + + public static HostConfiguration getHostConfiguration(String url) { + + if(url.startsWith("https")){ + + URI uri; + try { + uri = new URI(url,true); + } catch (URIException e1) { + return null; + } catch (NullPointerException e1) { + return null; + } + + Protocol httpsProtocol = new Protocol("https", new EasySSLProtocolSocketFactory(), 443); + HostConfiguration hc = new HostConfiguration(); + try { + hc.setHost(uri.getHost(), uri.getPort(), httpsProtocol); + } catch (URIException e) { + return null; + } + + return hc; + + } else { + return null; + } + } + + public static void setSSLTrust() { + + Protocol httpsProtocol = new Protocol("https", new EasySSLProtocolSocketFactory(), 443); + Protocol.registerProtocol("https", httpsProtocol); + } + + public static SSLContext createSSLContext(String keystoreFile, String keystorePass) { + + SSLContext sslContext = null; + try { + sslContext = SSLContext.getInstance("TLS"); + KeyManager[] keyManagers = createKeyManager(keystoreFile, keystorePass); + + // Client Auth 지원하지 않음. - 추후 지원시 Comment 제거 + // TrustManager[] trustManagers = createTrustManager(trustKey,trustPass); + TrustManager[] trustManagers = null; + + if (null == keyManagers) return null; + + sslContext.init(keyManagers, trustManagers, null); + + } catch (NoSuchAlgorithmException e) { + + logger.error(e.getMessage(), e); + return null; + + } catch (KeyManagementException e) { + + logger.error(e.getMessage(), e); + return null; + } + + return sslContext; + } + + public static KeyManager[] createKeyManager(String keystoreFile, String password) { + + KeyManager[] keyManagers = null; + File keyStoreFile = null; + if (StringUtils.isNotBlank(keystoreFile)) { + keyStoreFile = new File(keystoreFile); + } else { + Resource keystore = new ClassPathResource(PROP_KEYSTORE_PATH); + password = PROP_KEYSTORE_PW; + try { + keyStoreFile = keystore.getFile(); + } catch (IOException e) { + logger.error(e.getMessage(), e); + return null; + } + } + + try { + FileInputStream keyStoreInputStream = new FileInputStream(keyStoreFile); + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + KeyStore keyStore = getKeyStore(keyStoreInputStream,password); + + if (keyStore == null) return null; + + keyManagerFactory.init(keyStore,password.toCharArray()); + keyManagers = keyManagerFactory.getKeyManagers(); + + } catch (NoSuchAlgorithmException e) { + + logger.error(e.getMessage(), e); + return null; + + } catch (UnrecoverableKeyException e) { + + logger.error(e.getMessage(), e); + return null; + + } catch (KeyStoreException e) { + + logger.error(e.getMessage(), e); + return null; + + } catch (FileNotFoundException e) { + + logger.error(e.getMessage(), e); + return null; + } + + return keyManagers; + } + + public static TrustManager[] createTrustManager(String keystoreFile,String password) { + + if (null == keystoreFile) return null; + TrustManager[] trustManager = null; + + File keyStoreFile = new File(keystoreFile); + + try { + FileInputStream keyStoreInputStream = new FileInputStream(keyStoreFile); + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); + KeyStore trustStore = getKeyStore(keyStoreInputStream,password); + + if (trustStore == null) return null; + + trustManagerFactory.init(trustStore); + trustManager = trustManagerFactory.getTrustManagers(); + + } catch (NoSuchAlgorithmException e) { + + logger.error(e.getMessage(), e); + return null; + + } catch (KeyStoreException e) { + + logger.error(e.getMessage(), e); + return null; + + } catch (FileNotFoundException e) { + + logger.error(e.getMessage(), e); + return null; + } + + return trustManager; + } + + private static KeyStore getKeyStore(InputStream key, String password) { + + KeyStore keyStore = null; + + try { + keyStore = KeyStore.getInstance("JKS"); + keyStore.load(key, password.toCharArray()); + + } catch (KeyStoreException e) { + + logger.error(e.getMessage(), e); + return null; + + } catch (NoSuchAlgorithmException e) { + + logger.error(e.getMessage(), e); + return null; + + } catch (IOException e) { + + logger.error(e.getMessage(), e); + return null; + + } catch (java.security.cert.CertificateException e) { + + logger.error(e.getMessage(), e); + return null; + } + + return keyStore; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/jtc/FmlTable.java b/src/main/java/com/eactive/eai/adapter/jtc/FmlTable.java new file mode 100644 index 0000000..810d2d9 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/jtc/FmlTable.java @@ -0,0 +1,2568 @@ +package com.eactive.eai.adapter.jtc; + +import tmax.jtc.util.TuxFieldTable; + +import java.util.Hashtable; + + +/** +* 1. 기능 : FML Field Table 정의 Class +* 2. 처리 개요 : +* * - FML 버퍼에 Field를 정의한 Class +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public final class FmlTable + implements TuxFieldTable +{ + Hashtable nametofieldHashTable; + Hashtable fieldtonameHashTable; + /** number: 301 type: string */ + public final static int STRING1 = 167772461; + /** number: 302 type: string */ + public final static int STRING2 = 167772462; + /** number: 303 type: string */ + public final static int STRING3 = 167772463; + /** number: 304 type: string */ + public final static int STRING4 = 167772464; + /** number: 305 type: string */ + public final static int STRING5 = 167772465; + /** number: 306 type: string */ + public final static int STRING6 = 167772466; + /** number: 307 type: string */ + public final static int STRING7 = 167772467; + /** number: 308 type: string */ + public final static int STRING8 = 167772468; + /** number: 309 type: string */ + public final static int STRING9 = 167772469; + /** number: 310 type: string */ + public final static int STRING10 = 167772470; + /** number: 311 type: string */ + public final static int STRING11 = 167772471; + /** number: 312 type: string */ + public final static int STRING12 = 167772472; + /** number: 313 type: string */ + public final static int STRING13 = 167772473; + /** number: 314 type: string */ + public final static int STRING14 = 167772474; + /** number: 315 type: string */ + public final static int STRING15 = 167772475; + /** number: 316 type: string */ + public final static int STRING16 = 167772476; + /** number: 317 type: string */ + public final static int STRING17 = 167772477; + /** number: 318 type: string */ + public final static int STRING18 = 167772478; + /** number: 319 type: string */ + public final static int STRING19 = 167772479; + /** number: 320 type: string */ + public final static int STRING20 = 167772480; + /** number: 321 type: string */ + public final static int STRING21 = 167772481; + /** number: 322 type: string */ + public final static int STRING22 = 167772482; + /** number: 323 type: string */ + public final static int STRING23 = 167772483; + /** number: 324 type: string */ + public final static int STRING24 = 167772484; + /** number: 325 type: string */ + public final static int STRING25 = 167772485; + /** number: 326 type: string */ + public final static int STRING26 = 167772486; + /** number: 327 type: string */ + public final static int STRING27 = 167772487; + /** number: 328 type: string */ + public final static int STRING28 = 167772488; + /** number: 329 type: string */ + public final static int STRING29 = 167772489; + /** number: 330 type: string */ + public final static int STRING30 = 167772490; + /** number: 331 type: string */ + public final static int STRING31 = 167772491; + /** number: 332 type: string */ + public final static int STRING32 = 167772492; + /** number: 333 type: string */ + public final static int STRING33 = 167772493; + /** number: 334 type: string */ + public final static int STRING34 = 167772494; + /** number: 335 type: string */ + public final static int STRING35 = 167772495; + /** number: 336 type: string */ + public final static int STRING36 = 167772496; + /** number: 337 type: string */ + public final static int STRING37 = 167772497; + /** number: 338 type: string */ + public final static int STRING38 = 167772498; + /** number: 339 type: string */ + public final static int STRING39 = 167772499; + /** number: 340 type: string */ + public final static int STRING40 = 167772500; + /** number: 341 type: string */ + public final static int STRING41 = 167772501; + /** number: 342 type: string */ + public final static int STRING42 = 167772502; + /** number: 343 type: string */ + public final static int STRING43 = 167772503; + /** number: 344 type: string */ + public final static int STRING44 = 167772504; + /** number: 345 type: string */ + public final static int STRING45 = 167772505; + /** number: 346 type: string */ + public final static int STRING46 = 167772506; + /** number: 347 type: string */ + public final static int STRING47 = 167772507; + /** number: 348 type: string */ + public final static int STRING48 = 167772508; + /** number: 349 type: string */ + public final static int STRING49 = 167772509; + /** number: 350 type: string */ + public final static int STRING50 = 167772510; + /** number: 351 type: string */ + public final static int STRING51 = 167772511; + /** number: 352 type: string */ + public final static int STRING52 = 167772512; + /** number: 353 type: string */ + public final static int STRING53 = 167772513; + /** number: 354 type: string */ + public final static int STRING54 = 167772514; + /** number: 355 type: string */ + public final static int STRING55 = 167772515; + /** number: 356 type: string */ + public final static int STRING56 = 167772516; + /** number: 357 type: string */ + public final static int STRING57 = 167772517; + /** number: 358 type: string */ + public final static int STRING58 = 167772518; + /** number: 359 type: string */ + public final static int STRING59 = 167772519; + /** number: 360 type: string */ + public final static int STRING60 = 167772520; + /** number: 361 type: string */ + public final static int STRING61 = 167772521; + /** number: 362 type: string */ + public final static int STRING62 = 167772522; + /** number: 363 type: string */ + public final static int STRING63 = 167772523; + /** number: 364 type: string */ + public final static int STRING64 = 167772524; + /** number: 365 type: string */ + public final static int STRING65 = 167772525; + /** number: 366 type: string */ + public final static int STRING66 = 167772526; + /** number: 367 type: string */ + public final static int STRING67 = 167772527; + /** number: 368 type: string */ + public final static int STRING68 = 167772528; + /** number: 369 type: string */ + public final static int STRING69 = 167772529; + /** number: 370 type: string */ + public final static int STRING70 = 167772530; + /** number: 371 type: string */ + public final static int STRING71 = 167772531; + /** number: 372 type: string */ + public final static int STRING72 = 167772532; + /** number: 373 type: string */ + public final static int STRING73 = 167772533; + /** number: 374 type: string */ + public final static int STRING74 = 167772534; + /** number: 375 type: string */ + public final static int STRING75 = 167772535; + /** number: 376 type: string */ + public final static int STRING76 = 167772536; + /** number: 377 type: string */ + public final static int STRING77 = 167772537; + /** number: 378 type: string */ + public final static int STRING78 = 167772538; + /** number: 379 type: string */ + public final static int STRING79 = 167772539; + /** number: 380 type: string */ + public final static int STRING80 = 167772540; + /** number: 381 type: string */ + public final static int STRING81 = 167772541; + /** number: 382 type: string */ + public final static int STRING82 = 167772542; + /** number: 383 type: string */ + public final static int STRING83 = 167772543; + /** number: 384 type: string */ + public final static int STRING84 = 167772544; + /** number: 385 type: string */ + public final static int STRING85 = 167772545; + /** number: 386 type: string */ + public final static int STRING86 = 167772546; + /** number: 387 type: string */ + public final static int STRING87 = 167772547; + /** number: 388 type: string */ + public final static int STRING88 = 167772548; + /** number: 389 type: string */ + public final static int STRING89 = 167772549; + /** number: 390 type: string */ + public final static int STRING90 = 167772550; + /** number: 391 type: string */ + public final static int STRING91 = 167772551; + /** number: 392 type: string */ + public final static int STRING92 = 167772552; + /** number: 393 type: string */ + public final static int STRING93 = 167772553; + /** number: 394 type: string */ + public final static int STRING94 = 167772554; + /** number: 395 type: string */ + public final static int STRING95 = 167772555; + /** number: 396 type: string */ + public final static int STRING96 = 167772556; + /** number: 397 type: string */ + public final static int STRING97 = 167772557; + /** number: 398 type: string */ + public final static int STRING98 = 167772558; + /** number: 399 type: string */ + public final static int STRING99 = 167772559; + /** number: 400 type: string */ + public final static int STRING100 = 167772560; + /** number: 401 type: string */ + public final static int STRING101 = 167772561; + /** number: 402 type: string */ + public final static int STRING102 = 167772562; + /** number: 403 type: string */ + public final static int STRING103 = 167772563; + /** number: 404 type: string */ + public final static int STRING104 = 167772564; + /** number: 405 type: string */ + public final static int STRING105 = 167772565; + /** number: 406 type: string */ + public final static int STRING106 = 167772566; + /** number: 407 type: string */ + public final static int STRING107 = 167772567; + /** number: 408 type: string */ + public final static int STRING108 = 167772568; + /** number: 409 type: string */ + public final static int STRING109 = 167772569; + /** number: 410 type: string */ + public final static int STRING110 = 167772570; + /** number: 411 type: string */ + public final static int STRING111 = 167772571; + /** number: 412 type: string */ + public final static int STRING112 = 167772572; + /** number: 413 type: string */ + public final static int STRING113 = 167772573; + /** number: 414 type: string */ + public final static int STRING114 = 167772574; + /** number: 415 type: string */ + public final static int STRING115 = 167772575; + /** number: 416 type: string */ + public final static int STRING116 = 167772576; + /** number: 417 type: string */ + public final static int STRING117 = 167772577; + /** number: 418 type: string */ + public final static int STRING118 = 167772578; + /** number: 419 type: string */ + public final static int STRING119 = 167772579; + /** number: 420 type: string */ + public final static int STRING120 = 167772580; + /** number: 421 type: string */ + public final static int STRING121 = 167772581; + /** number: 422 type: string */ + public final static int STRING122 = 167772582; + /** number: 423 type: string */ + public final static int STRING123 = 167772583; + /** number: 424 type: string */ + public final static int STRING124 = 167772584; + /** number: 425 type: string */ + public final static int STRING125 = 167772585; + /** number: 426 type: string */ + public final static int STRING126 = 167772586; + /** number: 427 type: string */ + public final static int STRING127 = 167772587; + /** number: 428 type: string */ + public final static int STRING128 = 167772588; + /** number: 429 type: string */ + public final static int STRING129 = 167772589; + /** number: 430 type: string */ + public final static int STRING130 = 167772590; + /** number: 431 type: string */ + public final static int STRING131 = 167772591; + /** number: 432 type: string */ + public final static int STRING132 = 167772592; + /** number: 433 type: string */ + public final static int STRING133 = 167772593; + /** number: 434 type: string */ + public final static int STRING134 = 167772594; + /** number: 435 type: string */ + public final static int STRING135 = 167772595; + /** number: 436 type: string */ + public final static int STRING136 = 167772596; + /** number: 437 type: string */ + public final static int STRING137 = 167772597; + /** number: 438 type: string */ + public final static int STRING138 = 167772598; + /** number: 439 type: string */ + public final static int STRING139 = 167772599; + /** number: 440 type: string */ + public final static int STRING140 = 167772600; + /** number: 441 type: string */ + public final static int STRING141 = 167772601; + /** number: 442 type: string */ + public final static int STRING142 = 167772602; + /** number: 443 type: string */ + public final static int STRING143 = 167772603; + /** number: 444 type: string */ + public final static int STRING144 = 167772604; + /** number: 445 type: string */ + public final static int STRING145 = 167772605; + /** number: 446 type: string */ + public final static int STRING146 = 167772606; + /** number: 447 type: string */ + public final static int STRING147 = 167772607; + /** number: 448 type: string */ + public final static int STRING148 = 167772608; + /** number: 449 type: string */ + public final static int STRING149 = 167772609; + /** number: 450 type: string */ + public final static int STRING150 = 167772610; + /** number: 451 type: string */ + public final static int STRING151 = 167772611; + /** number: 452 type: string */ + public final static int STRING152 = 167772612; + /** number: 453 type: string */ + public final static int STRING153 = 167772613; + /** number: 454 type: string */ + public final static int STRING154 = 167772614; + /** number: 455 type: string */ + public final static int STRING155 = 167772615; + /** number: 456 type: string */ + public final static int STRING156 = 167772616; + /** number: 457 type: string */ + public final static int STRING157 = 167772617; + /** number: 458 type: string */ + public final static int STRING158 = 167772618; + /** number: 459 type: string */ + public final static int STRING159 = 167772619; + /** number: 460 type: string */ + public final static int STRING160 = 167772620; + /** number: 461 type: string */ + public final static int STRING161 = 167772621; + /** number: 462 type: string */ + public final static int STRING162 = 167772622; + /** number: 463 type: string */ + public final static int STRING163 = 167772623; + /** number: 464 type: string */ + public final static int STRING164 = 167772624; + /** number: 465 type: string */ + public final static int STRING165 = 167772625; + /** number: 466 type: string */ + public final static int STRING166 = 167772626; + /** number: 467 type: string */ + public final static int STRING167 = 167772627; + /** number: 468 type: string */ + public final static int STRING168 = 167772628; + /** number: 469 type: string */ + public final static int STRING169 = 167772629; + /** number: 470 type: string */ + public final static int STRING170 = 167772630; + /** number: 471 type: string */ + public final static int STRING171 = 167772631; + /** number: 472 type: string */ + public final static int STRING172 = 167772632; + /** number: 473 type: string */ + public final static int STRING173 = 167772633; + /** number: 474 type: string */ + public final static int STRING174 = 167772634; + /** number: 475 type: string */ + public final static int STRING175 = 167772635; + /** number: 476 type: string */ + public final static int STRING176 = 167772636; + /** number: 477 type: string */ + public final static int STRING177 = 167772637; + /** number: 478 type: string */ + public final static int STRING178 = 167772638; + /** number: 479 type: string */ + public final static int STRING179 = 167772639; + /** number: 480 type: string */ + public final static int STRING180 = 167772640; + /** number: 481 type: string */ + public final static int STRING181 = 167772641; + /** number: 482 type: string */ + public final static int STRING182 = 167772642; + /** number: 483 type: string */ + public final static int STRING183 = 167772643; + /** number: 484 type: string */ + public final static int STRING184 = 167772644; + /** number: 485 type: string */ + public final static int STRING185 = 167772645; + /** number: 486 type: string */ + public final static int STRING186 = 167772646; + /** number: 487 type: string */ + public final static int STRING187 = 167772647; + /** number: 488 type: string */ + public final static int STRING188 = 167772648; + /** number: 489 type: string */ + public final static int STRING189 = 167772649; + /** number: 490 type: string */ + public final static int STRING190 = 167772650; + /** number: 491 type: string */ + public final static int STRING191 = 167772651; + /** number: 492 type: string */ + public final static int STRING192 = 167772652; + /** number: 493 type: string */ + public final static int STRING193 = 167772653; + /** number: 494 type: string */ + public final static int STRING194 = 167772654; + /** number: 495 type: string */ + public final static int STRING195 = 167772655; + /** number: 496 type: string */ + public final static int STRING196 = 167772656; + /** number: 497 type: string */ + public final static int STRING197 = 167772657; + /** number: 498 type: string */ + public final static int STRING198 = 167772658; + /** number: 499 type: string */ + public final static int STRING199 = 167772659; + /** number: 500 type: string */ + public final static int STRING200 = 167772660; + /** number: 501 type: long */ + public final static int LONG1 = 33554933; + /** number: 502 type: long */ + public final static int LONG2 = 33554934; + /** number: 503 type: long */ + public final static int LONG3 = 33554935; + /** number: 504 type: long */ + public final static int LONG4 = 33554936; + /** number: 505 type: long */ + public final static int LONG5 = 33554937; + /** number: 506 type: long */ + public final static int LONG6 = 33554938; + /** number: 507 type: long */ + public final static int LONG7 = 33554939; + /** number: 508 type: long */ + public final static int LONG8 = 33554940; + /** number: 509 type: long */ + public final static int LONG9 = 33554941; + /** number: 510 type: long */ + public final static int LONG10 = 33554942; + /** number: 511 type: long */ + public final static int LONG11 = 33554943; + /** number: 512 type: long */ + public final static int LONG12 = 33554944; + /** number: 513 type: long */ + public final static int LONG13 = 33554945; + /** number: 514 type: long */ + public final static int LONG14 = 33554946; + /** number: 515 type: long */ + public final static int LONG15 = 33554947; + /** number: 516 type: long */ + public final static int LONG16 = 33554948; + /** number: 517 type: long */ + public final static int LONG17 = 33554949; + /** number: 518 type: long */ + public final static int LONG18 = 33554950; + /** number: 519 type: long */ + public final static int LONG19 = 33554951; + /** number: 520 type: long */ + public final static int LONG20 = 33554952; + /** number: 521 type: long */ + public final static int LONG21 = 33554953; + /** number: 522 type: long */ + public final static int LONG22 = 33554954; + /** number: 523 type: long */ + public final static int LONG23 = 33554955; + /** number: 524 type: long */ + public final static int LONG24 = 33554956; + /** number: 525 type: long */ + public final static int LONG25 = 33554957; + /** number: 526 type: long */ + public final static int LONG26 = 33554958; + /** number: 527 type: long */ + public final static int LONG27 = 33554959; + /** number: 528 type: long */ + public final static int LONG28 = 33554960; + /** number: 529 type: long */ + public final static int LONG29 = 33554961; + /** number: 530 type: long */ + public final static int LONG30 = 33554962; + /** number: 531 type: long */ + public final static int LONG31 = 33554963; + /** number: 532 type: long */ + public final static int LONG32 = 33554964; + /** number: 533 type: long */ + public final static int LONG33 = 33554965; + /** number: 534 type: long */ + public final static int LONG34 = 33554966; + /** number: 535 type: long */ + public final static int LONG35 = 33554967; + /** number: 536 type: long */ + public final static int LONG36 = 33554968; + /** number: 537 type: long */ + public final static int LONG37 = 33554969; + /** number: 538 type: long */ + public final static int LONG38 = 33554970; + /** number: 539 type: long */ + public final static int LONG39 = 33554971; + /** number: 540 type: long */ + public final static int LONG40 = 33554972; + /** number: 541 type: long */ + public final static int LONG41 = 33554973; + /** number: 542 type: long */ + public final static int LONG42 = 33554974; + /** number: 543 type: long */ + public final static int LONG43 = 33554975; + /** number: 544 type: long */ + public final static int LONG44 = 33554976; + /** number: 545 type: long */ + public final static int LONG45 = 33554977; + /** number: 546 type: long */ + public final static int LONG46 = 33554978; + /** number: 547 type: long */ + public final static int LONG47 = 33554979; + /** number: 548 type: long */ + public final static int LONG48 = 33554980; + /** number: 549 type: long */ + public final static int LONG49 = 33554981; + /** number: 550 type: long */ + public final static int LONG50 = 33554982; + /** number: 551 type: long */ + public final static int LONG51 = 33554983; + /** number: 552 type: long */ + public final static int LONG52 = 33554984; + /** number: 553 type: long */ + public final static int LONG53 = 33554985; + /** number: 554 type: long */ + public final static int LONG54 = 33554986; + /** number: 555 type: long */ + public final static int LONG55 = 33554987; + /** number: 556 type: long */ + public final static int LONG56 = 33554988; + /** number: 557 type: long */ + public final static int LONG57 = 33554989; + /** number: 558 type: long */ + public final static int LONG58 = 33554990; + /** number: 559 type: long */ + public final static int LONG59 = 33554991; + /** number: 560 type: long */ + public final static int LONG60 = 33554992; + /** number: 561 type: long */ + public final static int LONG61 = 33554993; + /** number: 562 type: long */ + public final static int LONG62 = 33554994; + /** number: 563 type: long */ + public final static int LONG63 = 33554995; + /** number: 564 type: long */ + public final static int LONG64 = 33554996; + /** number: 565 type: long */ + public final static int LONG65 = 33554997; + /** number: 566 type: long */ + public final static int LONG66 = 33554998; + /** number: 567 type: long */ + public final static int LONG67 = 33554999; + /** number: 568 type: long */ + public final static int LONG68 = 33555000; + /** number: 569 type: long */ + public final static int LONG69 = 33555001; + /** number: 570 type: long */ + public final static int LONG70 = 33555002; + /** number: 571 type: long */ + public final static int LONG71 = 33555003; + /** number: 572 type: long */ + public final static int LONG72 = 33555004; + /** number: 573 type: long */ + public final static int LONG73 = 33555005; + /** number: 574 type: long */ + public final static int LONG74 = 33555006; + /** number: 575 type: long */ + public final static int LONG75 = 33555007; + /** number: 576 type: long */ + public final static int LONG76 = 33555008; + /** number: 577 type: long */ + public final static int LONG77 = 33555009; + /** number: 578 type: long */ + public final static int LONG78 = 33555010; + /** number: 579 type: long */ + public final static int LONG79 = 33555011; + /** number: 580 type: long */ + public final static int LONG80 = 33555012; + /** number: 581 type: long */ + public final static int LONG81 = 33555013; + /** number: 582 type: long */ + public final static int LONG82 = 33555014; + /** number: 583 type: long */ + public final static int LONG83 = 33555015; + /** number: 584 type: long */ + public final static int LONG84 = 33555016; + /** number: 585 type: long */ + public final static int LONG85 = 33555017; + /** number: 586 type: long */ + public final static int LONG86 = 33555018; + /** number: 587 type: long */ + public final static int LONG87 = 33555019; + /** number: 588 type: long */ + public final static int LONG88 = 33555020; + /** number: 589 type: long */ + public final static int LONG89 = 33555021; + /** number: 590 type: long */ + public final static int LONG90 = 33555022; + /** number: 591 type: long */ + public final static int LONG91 = 33555023; + /** number: 592 type: long */ + public final static int LONG92 = 33555024; + /** number: 593 type: long */ + public final static int LONG93 = 33555025; + /** number: 594 type: long */ + public final static int LONG94 = 33555026; + /** number: 595 type: long */ + public final static int LONG95 = 33555027; + /** number: 596 type: long */ + public final static int LONG96 = 33555028; + /** number: 597 type: long */ + public final static int LONG97 = 33555029; + /** number: 598 type: long */ + public final static int LONG98 = 33555030; + /** number: 599 type: long */ + public final static int LONG99 = 33555031; + /** number: 600 type: long */ + public final static int LONG100 = 33555032; + /** number: 601 type: double */ + public final static int DOUBLE1 = 134218329; + /** number: 602 type: double */ + public final static int DOUBLE2 = 134218330; + /** number: 603 type: double */ + public final static int DOUBLE3 = 134218331; + /** number: 604 type: double */ + public final static int DOUBLE4 = 134218332; + /** number: 605 type: double */ + public final static int DOUBLE5 = 134218333; + /** number: 606 type: double */ + public final static int DOUBLE6 = 134218334; + /** number: 607 type: double */ + public final static int DOUBLE7 = 134218335; + /** number: 608 type: double */ + public final static int DOUBLE8 = 134218336; + /** number: 609 type: double */ + public final static int DOUBLE9 = 134218337; + /** number: 610 type: double */ + public final static int DOUBLE10 = 134218338; + /** number: 611 type: double */ + public final static int DOUBLE11 = 134218339; + /** number: 612 type: double */ + public final static int DOUBLE12 = 134218340; + /** number: 613 type: double */ + public final static int DOUBLE13 = 134218341; + /** number: 614 type: double */ + public final static int DOUBLE14 = 134218342; + /** number: 615 type: double */ + public final static int DOUBLE15 = 134218343; + /** number: 616 type: double */ + public final static int DOUBLE16 = 134218344; + /** number: 617 type: double */ + public final static int DOUBLE17 = 134218345; + /** number: 618 type: double */ + public final static int DOUBLE18 = 134218346; + /** number: 619 type: double */ + public final static int DOUBLE19 = 134218347; + /** number: 620 type: double */ + public final static int DOUBLE20 = 134218348; + /** number: 621 type: double */ + public final static int DOUBLE21 = 134218349; + /** number: 622 type: double */ + public final static int DOUBLE22 = 134218350; + /** number: 623 type: double */ + public final static int DOUBLE23 = 134218351; + /** number: 624 type: double */ + public final static int DOUBLE24 = 134218352; + /** number: 625 type: double */ + public final static int DOUBLE25 = 134218353; + /** number: 626 type: double */ + public final static int DOUBLE26 = 134218354; + /** number: 627 type: double */ + public final static int DOUBLE27 = 134218355; + /** number: 628 type: double */ + public final static int DOUBLE28 = 134218356; + /** number: 629 type: double */ + public final static int DOUBLE29 = 134218357; + /** number: 630 type: double */ + public final static int DOUBLE30 = 134218358; + /** number: 631 type: double */ + public final static int DOUBLE31 = 134218359; + /** number: 632 type: double */ + public final static int DOUBLE32 = 134218360; + /** number: 633 type: double */ + public final static int DOUBLE33 = 134218361; + /** number: 634 type: double */ + public final static int DOUBLE34 = 134218362; + /** number: 635 type: double */ + public final static int DOUBLE35 = 134218363; + /** number: 636 type: double */ + public final static int DOUBLE36 = 134218364; + /** number: 637 type: double */ + public final static int DOUBLE37 = 134218365; + /** number: 638 type: double */ + public final static int DOUBLE38 = 134218366; + /** number: 639 type: double */ + public final static int DOUBLE39 = 134218367; + /** number: 640 type: double */ + public final static int DOUBLE40 = 134218368; + /** number: 641 type: double */ + public final static int DOUBLE41 = 134218369; + /** number: 642 type: double */ + public final static int DOUBLE42 = 134218370; + /** number: 643 type: double */ + public final static int DOUBLE43 = 134218371; + /** number: 644 type: double */ + public final static int DOUBLE44 = 134218372; + /** number: 645 type: double */ + public final static int DOUBLE45 = 134218373; + /** number: 646 type: double */ + public final static int DOUBLE46 = 134218374; + /** number: 647 type: double */ + public final static int DOUBLE47 = 134218375; + /** number: 648 type: double */ + public final static int DOUBLE48 = 134218376; + /** number: 649 type: double */ + public final static int DOUBLE49 = 134218377; + /** number: 650 type: double */ + public final static int DOUBLE50 = 134218378; + /** number: 651 type: double */ + public final static int DOUBLE51 = 134218379; + /** number: 652 type: double */ + public final static int DOUBLE52 = 134218380; + /** number: 653 type: double */ + public final static int DOUBLE53 = 134218381; + /** number: 654 type: double */ + public final static int DOUBLE54 = 134218382; + /** number: 655 type: double */ + public final static int DOUBLE55 = 134218383; + /** number: 656 type: double */ + public final static int DOUBLE56 = 134218384; + /** number: 657 type: double */ + public final static int DOUBLE57 = 134218385; + /** number: 658 type: double */ + public final static int DOUBLE58 = 134218386; + /** number: 659 type: double */ + public final static int DOUBLE59 = 134218387; + /** number: 660 type: double */ + public final static int DOUBLE60 = 134218388; + /** number: 661 type: double */ + public final static int DOUBLE61 = 134218389; + /** number: 662 type: double */ + public final static int DOUBLE62 = 134218390; + /** number: 663 type: double */ + public final static int DOUBLE63 = 134218391; + /** number: 664 type: double */ + public final static int DOUBLE64 = 134218392; + /** number: 665 type: double */ + public final static int DOUBLE65 = 134218393; + /** number: 666 type: double */ + public final static int DOUBLE66 = 134218394; + /** number: 667 type: double */ + public final static int DOUBLE67 = 134218395; + /** number: 668 type: double */ + public final static int DOUBLE68 = 134218396; + /** number: 669 type: double */ + public final static int DOUBLE69 = 134218397; + /** number: 670 type: double */ + public final static int DOUBLE70 = 134218398; + /** number: 671 type: double */ + public final static int DOUBLE71 = 134218399; + /** number: 672 type: double */ + public final static int DOUBLE72 = 134218400; + /** number: 673 type: double */ + public final static int DOUBLE73 = 134218401; + /** number: 674 type: double */ + public final static int DOUBLE74 = 134218402; + /** number: 675 type: double */ + public final static int DOUBLE75 = 134218403; + /** number: 676 type: double */ + public final static int DOUBLE76 = 134218404; + /** number: 677 type: double */ + public final static int DOUBLE77 = 134218405; + /** number: 678 type: double */ + public final static int DOUBLE78 = 134218406; + /** number: 679 type: double */ + public final static int DOUBLE79 = 134218407; + /** number: 680 type: double */ + public final static int DOUBLE80 = 134218408; + /** number: 681 type: double */ + public final static int DOUBLE81 = 134218409; + /** number: 682 type: double */ + public final static int DOUBLE82 = 134218410; + /** number: 683 type: double */ + public final static int DOUBLE83 = 134218411; + /** number: 684 type: double */ + public final static int DOUBLE84 = 134218412; + /** number: 685 type: double */ + public final static int DOUBLE85 = 134218413; + /** number: 686 type: double */ + public final static int DOUBLE86 = 134218414; + /** number: 687 type: double */ + public final static int DOUBLE87 = 134218415; + /** number: 688 type: double */ + public final static int DOUBLE88 = 134218416; + /** number: 689 type: double */ + public final static int DOUBLE89 = 134218417; + /** number: 690 type: double */ + public final static int DOUBLE90 = 134218418; + /** number: 691 type: double */ + public final static int DOUBLE91 = 134218419; + /** number: 692 type: double */ + public final static int DOUBLE92 = 134218420; + /** number: 693 type: double */ + public final static int DOUBLE93 = 134218421; + /** number: 694 type: double */ + public final static int DOUBLE94 = 134218422; + /** number: 695 type: double */ + public final static int DOUBLE95 = 134218423; + /** number: 696 type: double */ + public final static int DOUBLE96 = 134218424; + /** number: 697 type: double */ + public final static int DOUBLE97 = 134218425; + /** number: 698 type: double */ + public final static int DOUBLE98 = 134218426; + /** number: 699 type: double */ + public final static int DOUBLE99 = 134218427; + /** number: 700 type: double */ + public final static int DOUBLE100 = 134218428; + /** number: 701 type: double */ + public final static int DOUBLE101 = 134218429; + /** number: 702 type: double */ + public final static int DOUBLE102 = 134218430; + /** number: 703 type: double */ + public final static int DOUBLE103 = 134218431; + /** number: 704 type: double */ + public final static int DOUBLE104 = 134218432; + /** number: 705 type: double */ + public final static int DOUBLE105 = 134218433; + /** number: 706 type: double */ + public final static int DOUBLE106 = 134218434; + /** number: 707 type: double */ + public final static int DOUBLE107 = 134218435; + /** number: 708 type: double */ + public final static int DOUBLE108 = 134218436; + /** number: 709 type: double */ + public final static int DOUBLE109 = 134218437; + /** number: 710 type: double */ + public final static int DOUBLE110 = 134218438; + /** number: 711 type: double */ + public final static int DOUBLE111 = 134218439; + /** number: 712 type: double */ + public final static int DOUBLE112 = 134218440; + /** number: 713 type: double */ + public final static int DOUBLE113 = 134218441; + /** number: 714 type: double */ + public final static int DOUBLE114 = 134218442; + /** number: 715 type: double */ + public final static int DOUBLE115 = 134218443; + /** number: 716 type: double */ + public final static int DOUBLE116 = 134218444; + /** number: 717 type: double */ + public final static int DOUBLE117 = 134218445; + /** number: 718 type: double */ + public final static int DOUBLE118 = 134218446; + /** number: 719 type: double */ + public final static int DOUBLE119 = 134218447; + /** number: 720 type: double */ + public final static int DOUBLE120 = 134218448; + /** number: 721 type: double */ + public final static int DOUBLE121 = 134218449; + /** number: 722 type: double */ + public final static int DOUBLE122 = 134218450; + /** number: 723 type: double */ + public final static int DOUBLE123 = 134218451; + /** number: 724 type: double */ + public final static int DOUBLE124 = 134218452; + /** number: 725 type: double */ + public final static int DOUBLE125 = 134218453; + /** number: 726 type: double */ + public final static int DOUBLE126 = 134218454; + /** number: 727 type: double */ + public final static int DOUBLE127 = 134218455; + /** number: 728 type: double */ + public final static int DOUBLE128 = 134218456; + /** number: 729 type: double */ + public final static int DOUBLE129 = 134218457; + /** number: 730 type: double */ + public final static int DOUBLE130 = 134218458; + /** number: 731 type: double */ + public final static int DOUBLE131 = 134218459; + /** number: 732 type: double */ + public final static int DOUBLE132 = 134218460; + /** number: 733 type: double */ + public final static int DOUBLE133 = 134218461; + /** number: 734 type: double */ + public final static int DOUBLE134 = 134218462; + /** number: 735 type: double */ + public final static int DOUBLE135 = 134218463; + /** number: 736 type: double */ + public final static int DOUBLE136 = 134218464; + /** number: 737 type: double */ + public final static int DOUBLE137 = 134218465; + /** number: 738 type: double */ + public final static int DOUBLE138 = 134218466; + /** number: 739 type: double */ + public final static int DOUBLE139 = 134218467; + /** number: 740 type: double */ + public final static int DOUBLE140 = 134218468; + /** number: 741 type: double */ + public final static int DOUBLE141 = 134218469; + /** number: 742 type: double */ + public final static int DOUBLE142 = 134218470; + /** number: 743 type: double */ + public final static int DOUBLE143 = 134218471; + /** number: 744 type: double */ + public final static int DOUBLE144 = 134218472; + /** number: 745 type: double */ + public final static int DOUBLE145 = 134218473; + /** number: 746 type: double */ + public final static int DOUBLE146 = 134218474; + /** number: 747 type: double */ + public final static int DOUBLE147 = 134218475; + /** number: 748 type: double */ + public final static int DOUBLE148 = 134218476; + /** number: 749 type: double */ + public final static int DOUBLE149 = 134218477; + /** number: 750 type: double */ + public final static int DOUBLE150 = 134218478; + /** number: 751 type: double */ + public final static int DOUBLE151 = 134218479; + /** number: 752 type: double */ + public final static int DOUBLE152 = 134218480; + /** number: 753 type: double */ + public final static int DOUBLE153 = 134218481; + /** number: 754 type: double */ + public final static int DOUBLE154 = 134218482; + /** number: 755 type: double */ + public final static int DOUBLE155 = 134218483; + /** number: 756 type: double */ + public final static int DOUBLE156 = 134218484; + /** number: 757 type: double */ + public final static int DOUBLE157 = 134218485; + /** number: 758 type: double */ + public final static int DOUBLE158 = 134218486; + /** number: 759 type: double */ + public final static int DOUBLE159 = 134218487; + /** number: 760 type: double */ + public final static int DOUBLE160 = 134218488; + /** number: 761 type: double */ + public final static int DOUBLE161 = 134218489; + /** number: 762 type: double */ + public final static int DOUBLE162 = 134218490; + /** number: 763 type: double */ + public final static int DOUBLE163 = 134218491; + /** number: 764 type: double */ + public final static int DOUBLE164 = 134218492; + /** number: 765 type: double */ + public final static int DOUBLE165 = 134218493; + /** number: 766 type: double */ + public final static int DOUBLE166 = 134218494; + /** number: 767 type: double */ + public final static int DOUBLE167 = 134218495; + /** number: 768 type: double */ + public final static int DOUBLE168 = 134218496; + /** number: 769 type: double */ + public final static int DOUBLE169 = 134218497; + /** number: 770 type: double */ + public final static int DOUBLE170 = 134218498; + /** number: 771 type: double */ + public final static int DOUBLE171 = 134218499; + /** number: 772 type: double */ + public final static int DOUBLE172 = 134218500; + /** number: 773 type: double */ + public final static int DOUBLE173 = 134218501; + /** number: 774 type: double */ + public final static int DOUBLE174 = 134218502; + /** number: 775 type: double */ + public final static int DOUBLE175 = 134218503; + /** number: 776 type: double */ + public final static int DOUBLE176 = 134218504; + /** number: 777 type: double */ + public final static int DOUBLE177 = 134218505; + /** number: 778 type: double */ + public final static int DOUBLE178 = 134218506; + /** number: 779 type: double */ + public final static int DOUBLE179 = 134218507; + /** number: 780 type: double */ + public final static int DOUBLE180 = 134218508; + /** number: 781 type: double */ + public final static int DOUBLE181 = 134218509; + /** number: 782 type: double */ + public final static int DOUBLE182 = 134218510; + /** number: 783 type: double */ + public final static int DOUBLE183 = 134218511; + /** number: 784 type: double */ + public final static int DOUBLE184 = 134218512; + /** number: 785 type: double */ + public final static int DOUBLE185 = 134218513; + /** number: 786 type: double */ + public final static int DOUBLE186 = 134218514; + /** number: 787 type: double */ + public final static int DOUBLE187 = 134218515; + /** number: 788 type: double */ + public final static int DOUBLE188 = 134218516; + /** number: 789 type: double */ + public final static int DOUBLE189 = 134218517; + /** number: 790 type: double */ + public final static int DOUBLE190 = 134218518; + /** number: 791 type: double */ + public final static int DOUBLE191 = 134218519; + /** number: 792 type: double */ + public final static int DOUBLE192 = 134218520; + /** number: 793 type: double */ + public final static int DOUBLE193 = 134218521; + /** number: 794 type: double */ + public final static int DOUBLE194 = 134218522; + /** number: 795 type: double */ + public final static int DOUBLE195 = 134218523; + /** number: 796 type: double */ + public final static int DOUBLE196 = 134218524; + /** number: 797 type: double */ + public final static int DOUBLE197 = 134218525; + /** number: 798 type: double */ + public final static int DOUBLE198 = 134218526; + /** number: 799 type: double */ + public final static int DOUBLE199 = 134218527; + /** number: 800 type: double */ + public final static int DOUBLE200 = 134218528; + /** number: 801 type: string */ + public final static int SVCNAME = 167772961; + /** number: 802 type: string */ + public final static int TPURCODE = 167772962; + + public String getFieldName(int fldid) + { + if ( fieldtonameHashTable == null ) { + fieldtonameHashTable = new Hashtable(); + fieldtonameHashTable.put(new Integer(STRING1), "STRING1"); + fieldtonameHashTable.put(new Integer(STRING2), "STRING2"); + fieldtonameHashTable.put(new Integer(STRING3), "STRING3"); + fieldtonameHashTable.put(new Integer(STRING4), "STRING4"); + fieldtonameHashTable.put(new Integer(STRING5), "STRING5"); + fieldtonameHashTable.put(new Integer(STRING6), "STRING6"); + fieldtonameHashTable.put(new Integer(STRING7), "STRING7"); + fieldtonameHashTable.put(new Integer(STRING8), "STRING8"); + fieldtonameHashTable.put(new Integer(STRING9), "STRING9"); + fieldtonameHashTable.put(new Integer(STRING10), "STRING10"); + fieldtonameHashTable.put(new Integer(STRING11), "STRING11"); + fieldtonameHashTable.put(new Integer(STRING12), "STRING12"); + fieldtonameHashTable.put(new Integer(STRING13), "STRING13"); + fieldtonameHashTable.put(new Integer(STRING14), "STRING14"); + fieldtonameHashTable.put(new Integer(STRING15), "STRING15"); + fieldtonameHashTable.put(new Integer(STRING16), "STRING16"); + fieldtonameHashTable.put(new Integer(STRING17), "STRING17"); + fieldtonameHashTable.put(new Integer(STRING18), "STRING18"); + fieldtonameHashTable.put(new Integer(STRING19), "STRING19"); + fieldtonameHashTable.put(new Integer(STRING20), "STRING20"); + fieldtonameHashTable.put(new Integer(STRING21), "STRING21"); + fieldtonameHashTable.put(new Integer(STRING22), "STRING22"); + fieldtonameHashTable.put(new Integer(STRING23), "STRING23"); + fieldtonameHashTable.put(new Integer(STRING24), "STRING24"); + fieldtonameHashTable.put(new Integer(STRING25), "STRING25"); + fieldtonameHashTable.put(new Integer(STRING26), "STRING26"); + fieldtonameHashTable.put(new Integer(STRING27), "STRING27"); + fieldtonameHashTable.put(new Integer(STRING28), "STRING28"); + fieldtonameHashTable.put(new Integer(STRING29), "STRING29"); + fieldtonameHashTable.put(new Integer(STRING30), "STRING30"); + fieldtonameHashTable.put(new Integer(STRING31), "STRING31"); + fieldtonameHashTable.put(new Integer(STRING32), "STRING32"); + fieldtonameHashTable.put(new Integer(STRING33), "STRING33"); + fieldtonameHashTable.put(new Integer(STRING34), "STRING34"); + fieldtonameHashTable.put(new Integer(STRING35), "STRING35"); + fieldtonameHashTable.put(new Integer(STRING36), "STRING36"); + fieldtonameHashTable.put(new Integer(STRING37), "STRING37"); + fieldtonameHashTable.put(new Integer(STRING38), "STRING38"); + fieldtonameHashTable.put(new Integer(STRING39), "STRING39"); + fieldtonameHashTable.put(new Integer(STRING40), "STRING40"); + fieldtonameHashTable.put(new Integer(STRING41), "STRING41"); + fieldtonameHashTable.put(new Integer(STRING42), "STRING42"); + fieldtonameHashTable.put(new Integer(STRING43), "STRING43"); + fieldtonameHashTable.put(new Integer(STRING44), "STRING44"); + fieldtonameHashTable.put(new Integer(STRING45), "STRING45"); + fieldtonameHashTable.put(new Integer(STRING46), "STRING46"); + fieldtonameHashTable.put(new Integer(STRING47), "STRING47"); + fieldtonameHashTable.put(new Integer(STRING48), "STRING48"); + fieldtonameHashTable.put(new Integer(STRING49), "STRING49"); + fieldtonameHashTable.put(new Integer(STRING50), "STRING50"); + fieldtonameHashTable.put(new Integer(STRING51), "STRING51"); + fieldtonameHashTable.put(new Integer(STRING52), "STRING52"); + fieldtonameHashTable.put(new Integer(STRING53), "STRING53"); + fieldtonameHashTable.put(new Integer(STRING54), "STRING54"); + fieldtonameHashTable.put(new Integer(STRING55), "STRING55"); + fieldtonameHashTable.put(new Integer(STRING56), "STRING56"); + fieldtonameHashTable.put(new Integer(STRING57), "STRING57"); + fieldtonameHashTable.put(new Integer(STRING58), "STRING58"); + fieldtonameHashTable.put(new Integer(STRING59), "STRING59"); + fieldtonameHashTable.put(new Integer(STRING60), "STRING60"); + fieldtonameHashTable.put(new Integer(STRING61), "STRING61"); + fieldtonameHashTable.put(new Integer(STRING62), "STRING62"); + fieldtonameHashTable.put(new Integer(STRING63), "STRING63"); + fieldtonameHashTable.put(new Integer(STRING64), "STRING64"); + fieldtonameHashTable.put(new Integer(STRING65), "STRING65"); + fieldtonameHashTable.put(new Integer(STRING66), "STRING66"); + fieldtonameHashTable.put(new Integer(STRING67), "STRING67"); + fieldtonameHashTable.put(new Integer(STRING68), "STRING68"); + fieldtonameHashTable.put(new Integer(STRING69), "STRING69"); + fieldtonameHashTable.put(new Integer(STRING70), "STRING70"); + fieldtonameHashTable.put(new Integer(STRING71), "STRING71"); + fieldtonameHashTable.put(new Integer(STRING72), "STRING72"); + fieldtonameHashTable.put(new Integer(STRING73), "STRING73"); + fieldtonameHashTable.put(new Integer(STRING74), "STRING74"); + fieldtonameHashTable.put(new Integer(STRING75), "STRING75"); + fieldtonameHashTable.put(new Integer(STRING76), "STRING76"); + fieldtonameHashTable.put(new Integer(STRING77), "STRING77"); + fieldtonameHashTable.put(new Integer(STRING78), "STRING78"); + fieldtonameHashTable.put(new Integer(STRING79), "STRING79"); + fieldtonameHashTable.put(new Integer(STRING80), "STRING80"); + fieldtonameHashTable.put(new Integer(STRING81), "STRING81"); + fieldtonameHashTable.put(new Integer(STRING82), "STRING82"); + fieldtonameHashTable.put(new Integer(STRING83), "STRING83"); + fieldtonameHashTable.put(new Integer(STRING84), "STRING84"); + fieldtonameHashTable.put(new Integer(STRING85), "STRING85"); + fieldtonameHashTable.put(new Integer(STRING86), "STRING86"); + fieldtonameHashTable.put(new Integer(STRING87), "STRING87"); + fieldtonameHashTable.put(new Integer(STRING88), "STRING88"); + fieldtonameHashTable.put(new Integer(STRING89), "STRING89"); + fieldtonameHashTable.put(new Integer(STRING90), "STRING90"); + fieldtonameHashTable.put(new Integer(STRING91), "STRING91"); + fieldtonameHashTable.put(new Integer(STRING92), "STRING92"); + fieldtonameHashTable.put(new Integer(STRING93), "STRING93"); + fieldtonameHashTable.put(new Integer(STRING94), "STRING94"); + fieldtonameHashTable.put(new Integer(STRING95), "STRING95"); + fieldtonameHashTable.put(new Integer(STRING96), "STRING96"); + fieldtonameHashTable.put(new Integer(STRING97), "STRING97"); + fieldtonameHashTable.put(new Integer(STRING98), "STRING98"); + fieldtonameHashTable.put(new Integer(STRING99), "STRING99"); + fieldtonameHashTable.put(new Integer(STRING100), "STRING100"); + fieldtonameHashTable.put(new Integer(STRING101), "STRING101"); + fieldtonameHashTable.put(new Integer(STRING102), "STRING102"); + fieldtonameHashTable.put(new Integer(STRING103), "STRING103"); + fieldtonameHashTable.put(new Integer(STRING104), "STRING104"); + fieldtonameHashTable.put(new Integer(STRING105), "STRING105"); + fieldtonameHashTable.put(new Integer(STRING106), "STRING106"); + fieldtonameHashTable.put(new Integer(STRING107), "STRING107"); + fieldtonameHashTable.put(new Integer(STRING108), "STRING108"); + fieldtonameHashTable.put(new Integer(STRING109), "STRING109"); + fieldtonameHashTable.put(new Integer(STRING110), "STRING110"); + fieldtonameHashTable.put(new Integer(STRING111), "STRING111"); + fieldtonameHashTable.put(new Integer(STRING112), "STRING112"); + fieldtonameHashTable.put(new Integer(STRING113), "STRING113"); + fieldtonameHashTable.put(new Integer(STRING114), "STRING114"); + fieldtonameHashTable.put(new Integer(STRING115), "STRING115"); + fieldtonameHashTable.put(new Integer(STRING116), "STRING116"); + fieldtonameHashTable.put(new Integer(STRING117), "STRING117"); + fieldtonameHashTable.put(new Integer(STRING118), "STRING118"); + fieldtonameHashTable.put(new Integer(STRING119), "STRING119"); + fieldtonameHashTable.put(new Integer(STRING120), "STRING120"); + fieldtonameHashTable.put(new Integer(STRING121), "STRING121"); + fieldtonameHashTable.put(new Integer(STRING122), "STRING122"); + fieldtonameHashTable.put(new Integer(STRING123), "STRING123"); + fieldtonameHashTable.put(new Integer(STRING124), "STRING124"); + fieldtonameHashTable.put(new Integer(STRING125), "STRING125"); + fieldtonameHashTable.put(new Integer(STRING126), "STRING126"); + fieldtonameHashTable.put(new Integer(STRING127), "STRING127"); + fieldtonameHashTable.put(new Integer(STRING128), "STRING128"); + fieldtonameHashTable.put(new Integer(STRING129), "STRING129"); + fieldtonameHashTable.put(new Integer(STRING130), "STRING130"); + fieldtonameHashTable.put(new Integer(STRING131), "STRING131"); + fieldtonameHashTable.put(new Integer(STRING132), "STRING132"); + fieldtonameHashTable.put(new Integer(STRING133), "STRING133"); + fieldtonameHashTable.put(new Integer(STRING134), "STRING134"); + fieldtonameHashTable.put(new Integer(STRING135), "STRING135"); + fieldtonameHashTable.put(new Integer(STRING136), "STRING136"); + fieldtonameHashTable.put(new Integer(STRING137), "STRING137"); + fieldtonameHashTable.put(new Integer(STRING138), "STRING138"); + fieldtonameHashTable.put(new Integer(STRING139), "STRING139"); + fieldtonameHashTable.put(new Integer(STRING140), "STRING140"); + fieldtonameHashTable.put(new Integer(STRING141), "STRING141"); + fieldtonameHashTable.put(new Integer(STRING142), "STRING142"); + fieldtonameHashTable.put(new Integer(STRING143), "STRING143"); + fieldtonameHashTable.put(new Integer(STRING144), "STRING144"); + fieldtonameHashTable.put(new Integer(STRING145), "STRING145"); + fieldtonameHashTable.put(new Integer(STRING146), "STRING146"); + fieldtonameHashTable.put(new Integer(STRING147), "STRING147"); + fieldtonameHashTable.put(new Integer(STRING148), "STRING148"); + fieldtonameHashTable.put(new Integer(STRING149), "STRING149"); + fieldtonameHashTable.put(new Integer(STRING150), "STRING150"); + fieldtonameHashTable.put(new Integer(STRING151), "STRING151"); + fieldtonameHashTable.put(new Integer(STRING152), "STRING152"); + fieldtonameHashTable.put(new Integer(STRING153), "STRING153"); + fieldtonameHashTable.put(new Integer(STRING154), "STRING154"); + fieldtonameHashTable.put(new Integer(STRING155), "STRING155"); + fieldtonameHashTable.put(new Integer(STRING156), "STRING156"); + fieldtonameHashTable.put(new Integer(STRING157), "STRING157"); + fieldtonameHashTable.put(new Integer(STRING158), "STRING158"); + fieldtonameHashTable.put(new Integer(STRING159), "STRING159"); + fieldtonameHashTable.put(new Integer(STRING160), "STRING160"); + fieldtonameHashTable.put(new Integer(STRING161), "STRING161"); + fieldtonameHashTable.put(new Integer(STRING162), "STRING162"); + fieldtonameHashTable.put(new Integer(STRING163), "STRING163"); + fieldtonameHashTable.put(new Integer(STRING164), "STRING164"); + fieldtonameHashTable.put(new Integer(STRING165), "STRING165"); + fieldtonameHashTable.put(new Integer(STRING166), "STRING166"); + fieldtonameHashTable.put(new Integer(STRING167), "STRING167"); + fieldtonameHashTable.put(new Integer(STRING168), "STRING168"); + fieldtonameHashTable.put(new Integer(STRING169), "STRING169"); + fieldtonameHashTable.put(new Integer(STRING170), "STRING170"); + fieldtonameHashTable.put(new Integer(STRING171), "STRING171"); + fieldtonameHashTable.put(new Integer(STRING172), "STRING172"); + fieldtonameHashTable.put(new Integer(STRING173), "STRING173"); + fieldtonameHashTable.put(new Integer(STRING174), "STRING174"); + fieldtonameHashTable.put(new Integer(STRING175), "STRING175"); + fieldtonameHashTable.put(new Integer(STRING176), "STRING176"); + fieldtonameHashTable.put(new Integer(STRING177), "STRING177"); + fieldtonameHashTable.put(new Integer(STRING178), "STRING178"); + fieldtonameHashTable.put(new Integer(STRING179), "STRING179"); + fieldtonameHashTable.put(new Integer(STRING180), "STRING180"); + fieldtonameHashTable.put(new Integer(STRING181), "STRING181"); + fieldtonameHashTable.put(new Integer(STRING182), "STRING182"); + fieldtonameHashTable.put(new Integer(STRING183), "STRING183"); + fieldtonameHashTable.put(new Integer(STRING184), "STRING184"); + fieldtonameHashTable.put(new Integer(STRING185), "STRING185"); + fieldtonameHashTable.put(new Integer(STRING186), "STRING186"); + fieldtonameHashTable.put(new Integer(STRING187), "STRING187"); + fieldtonameHashTable.put(new Integer(STRING188), "STRING188"); + fieldtonameHashTable.put(new Integer(STRING189), "STRING189"); + fieldtonameHashTable.put(new Integer(STRING190), "STRING190"); + fieldtonameHashTable.put(new Integer(STRING191), "STRING191"); + fieldtonameHashTable.put(new Integer(STRING192), "STRING192"); + fieldtonameHashTable.put(new Integer(STRING193), "STRING193"); + fieldtonameHashTable.put(new Integer(STRING194), "STRING194"); + fieldtonameHashTable.put(new Integer(STRING195), "STRING195"); + fieldtonameHashTable.put(new Integer(STRING196), "STRING196"); + fieldtonameHashTable.put(new Integer(STRING197), "STRING197"); + fieldtonameHashTable.put(new Integer(STRING198), "STRING198"); + fieldtonameHashTable.put(new Integer(STRING199), "STRING199"); + fieldtonameHashTable.put(new Integer(STRING200), "STRING200"); + fieldtonameHashTable.put(new Integer(LONG1), "LONG1"); + fieldtonameHashTable.put(new Integer(LONG2), "LONG2"); + fieldtonameHashTable.put(new Integer(LONG3), "LONG3"); + fieldtonameHashTable.put(new Integer(LONG4), "LONG4"); + fieldtonameHashTable.put(new Integer(LONG5), "LONG5"); + fieldtonameHashTable.put(new Integer(LONG6), "LONG6"); + fieldtonameHashTable.put(new Integer(LONG7), "LONG7"); + fieldtonameHashTable.put(new Integer(LONG8), "LONG8"); + fieldtonameHashTable.put(new Integer(LONG9), "LONG9"); + fieldtonameHashTable.put(new Integer(LONG10), "LONG10"); + fieldtonameHashTable.put(new Integer(LONG11), "LONG11"); + fieldtonameHashTable.put(new Integer(LONG12), "LONG12"); + fieldtonameHashTable.put(new Integer(LONG13), "LONG13"); + fieldtonameHashTable.put(new Integer(LONG14), "LONG14"); + fieldtonameHashTable.put(new Integer(LONG15), "LONG15"); + fieldtonameHashTable.put(new Integer(LONG16), "LONG16"); + fieldtonameHashTable.put(new Integer(LONG17), "LONG17"); + fieldtonameHashTable.put(new Integer(LONG18), "LONG18"); + fieldtonameHashTable.put(new Integer(LONG19), "LONG19"); + fieldtonameHashTable.put(new Integer(LONG20), "LONG20"); + fieldtonameHashTable.put(new Integer(LONG21), "LONG21"); + fieldtonameHashTable.put(new Integer(LONG22), "LONG22"); + fieldtonameHashTable.put(new Integer(LONG23), "LONG23"); + fieldtonameHashTable.put(new Integer(LONG24), "LONG24"); + fieldtonameHashTable.put(new Integer(LONG25), "LONG25"); + fieldtonameHashTable.put(new Integer(LONG26), "LONG26"); + fieldtonameHashTable.put(new Integer(LONG27), "LONG27"); + fieldtonameHashTable.put(new Integer(LONG28), "LONG28"); + fieldtonameHashTable.put(new Integer(LONG29), "LONG29"); + fieldtonameHashTable.put(new Integer(LONG30), "LONG30"); + fieldtonameHashTable.put(new Integer(LONG31), "LONG31"); + fieldtonameHashTable.put(new Integer(LONG32), "LONG32"); + fieldtonameHashTable.put(new Integer(LONG33), "LONG33"); + fieldtonameHashTable.put(new Integer(LONG34), "LONG34"); + fieldtonameHashTable.put(new Integer(LONG35), "LONG35"); + fieldtonameHashTable.put(new Integer(LONG36), "LONG36"); + fieldtonameHashTable.put(new Integer(LONG37), "LONG37"); + fieldtonameHashTable.put(new Integer(LONG38), "LONG38"); + fieldtonameHashTable.put(new Integer(LONG39), "LONG39"); + fieldtonameHashTable.put(new Integer(LONG40), "LONG40"); + fieldtonameHashTable.put(new Integer(LONG41), "LONG41"); + fieldtonameHashTable.put(new Integer(LONG42), "LONG42"); + fieldtonameHashTable.put(new Integer(LONG43), "LONG43"); + fieldtonameHashTable.put(new Integer(LONG44), "LONG44"); + fieldtonameHashTable.put(new Integer(LONG45), "LONG45"); + fieldtonameHashTable.put(new Integer(LONG46), "LONG46"); + fieldtonameHashTable.put(new Integer(LONG47), "LONG47"); + fieldtonameHashTable.put(new Integer(LONG48), "LONG48"); + fieldtonameHashTable.put(new Integer(LONG49), "LONG49"); + fieldtonameHashTable.put(new Integer(LONG50), "LONG50"); + fieldtonameHashTable.put(new Integer(LONG51), "LONG51"); + fieldtonameHashTable.put(new Integer(LONG52), "LONG52"); + fieldtonameHashTable.put(new Integer(LONG53), "LONG53"); + fieldtonameHashTable.put(new Integer(LONG54), "LONG54"); + fieldtonameHashTable.put(new Integer(LONG55), "LONG55"); + fieldtonameHashTable.put(new Integer(LONG56), "LONG56"); + fieldtonameHashTable.put(new Integer(LONG57), "LONG57"); + fieldtonameHashTable.put(new Integer(LONG58), "LONG58"); + fieldtonameHashTable.put(new Integer(LONG59), "LONG59"); + fieldtonameHashTable.put(new Integer(LONG60), "LONG60"); + fieldtonameHashTable.put(new Integer(LONG61), "LONG61"); + fieldtonameHashTable.put(new Integer(LONG62), "LONG62"); + fieldtonameHashTable.put(new Integer(LONG63), "LONG63"); + fieldtonameHashTable.put(new Integer(LONG64), "LONG64"); + fieldtonameHashTable.put(new Integer(LONG65), "LONG65"); + fieldtonameHashTable.put(new Integer(LONG66), "LONG66"); + fieldtonameHashTable.put(new Integer(LONG67), "LONG67"); + fieldtonameHashTable.put(new Integer(LONG68), "LONG68"); + fieldtonameHashTable.put(new Integer(LONG69), "LONG69"); + fieldtonameHashTable.put(new Integer(LONG70), "LONG70"); + fieldtonameHashTable.put(new Integer(LONG71), "LONG71"); + fieldtonameHashTable.put(new Integer(LONG72), "LONG72"); + fieldtonameHashTable.put(new Integer(LONG73), "LONG73"); + fieldtonameHashTable.put(new Integer(LONG74), "LONG74"); + fieldtonameHashTable.put(new Integer(LONG75), "LONG75"); + fieldtonameHashTable.put(new Integer(LONG76), "LONG76"); + fieldtonameHashTable.put(new Integer(LONG77), "LONG77"); + fieldtonameHashTable.put(new Integer(LONG78), "LONG78"); + fieldtonameHashTable.put(new Integer(LONG79), "LONG79"); + fieldtonameHashTable.put(new Integer(LONG80), "LONG80"); + fieldtonameHashTable.put(new Integer(LONG81), "LONG81"); + fieldtonameHashTable.put(new Integer(LONG82), "LONG82"); + fieldtonameHashTable.put(new Integer(LONG83), "LONG83"); + fieldtonameHashTable.put(new Integer(LONG84), "LONG84"); + fieldtonameHashTable.put(new Integer(LONG85), "LONG85"); + fieldtonameHashTable.put(new Integer(LONG86), "LONG86"); + fieldtonameHashTable.put(new Integer(LONG87), "LONG87"); + fieldtonameHashTable.put(new Integer(LONG88), "LONG88"); + fieldtonameHashTable.put(new Integer(LONG89), "LONG89"); + fieldtonameHashTable.put(new Integer(LONG90), "LONG90"); + fieldtonameHashTable.put(new Integer(LONG91), "LONG91"); + fieldtonameHashTable.put(new Integer(LONG92), "LONG92"); + fieldtonameHashTable.put(new Integer(LONG93), "LONG93"); + fieldtonameHashTable.put(new Integer(LONG94), "LONG94"); + fieldtonameHashTable.put(new Integer(LONG95), "LONG95"); + fieldtonameHashTable.put(new Integer(LONG96), "LONG96"); + fieldtonameHashTable.put(new Integer(LONG97), "LONG97"); + fieldtonameHashTable.put(new Integer(LONG98), "LONG98"); + fieldtonameHashTable.put(new Integer(LONG99), "LONG99"); + fieldtonameHashTable.put(new Integer(LONG100), "LONG100"); + fieldtonameHashTable.put(new Integer(DOUBLE1), "DOUBLE1"); + fieldtonameHashTable.put(new Integer(DOUBLE2), "DOUBLE2"); + fieldtonameHashTable.put(new Integer(DOUBLE3), "DOUBLE3"); + fieldtonameHashTable.put(new Integer(DOUBLE4), "DOUBLE4"); + fieldtonameHashTable.put(new Integer(DOUBLE5), "DOUBLE5"); + fieldtonameHashTable.put(new Integer(DOUBLE6), "DOUBLE6"); + fieldtonameHashTable.put(new Integer(DOUBLE7), "DOUBLE7"); + fieldtonameHashTable.put(new Integer(DOUBLE8), "DOUBLE8"); + fieldtonameHashTable.put(new Integer(DOUBLE9), "DOUBLE9"); + fieldtonameHashTable.put(new Integer(DOUBLE10), "DOUBLE10"); + fieldtonameHashTable.put(new Integer(DOUBLE11), "DOUBLE11"); + fieldtonameHashTable.put(new Integer(DOUBLE12), "DOUBLE12"); + fieldtonameHashTable.put(new Integer(DOUBLE13), "DOUBLE13"); + fieldtonameHashTable.put(new Integer(DOUBLE14), "DOUBLE14"); + fieldtonameHashTable.put(new Integer(DOUBLE15), "DOUBLE15"); + fieldtonameHashTable.put(new Integer(DOUBLE16), "DOUBLE16"); + fieldtonameHashTable.put(new Integer(DOUBLE17), "DOUBLE17"); + fieldtonameHashTable.put(new Integer(DOUBLE18), "DOUBLE18"); + fieldtonameHashTable.put(new Integer(DOUBLE19), "DOUBLE19"); + fieldtonameHashTable.put(new Integer(DOUBLE20), "DOUBLE20"); + fieldtonameHashTable.put(new Integer(DOUBLE21), "DOUBLE21"); + fieldtonameHashTable.put(new Integer(DOUBLE22), "DOUBLE22"); + fieldtonameHashTable.put(new Integer(DOUBLE23), "DOUBLE23"); + fieldtonameHashTable.put(new Integer(DOUBLE24), "DOUBLE24"); + fieldtonameHashTable.put(new Integer(DOUBLE25), "DOUBLE25"); + fieldtonameHashTable.put(new Integer(DOUBLE26), "DOUBLE26"); + fieldtonameHashTable.put(new Integer(DOUBLE27), "DOUBLE27"); + fieldtonameHashTable.put(new Integer(DOUBLE28), "DOUBLE28"); + fieldtonameHashTable.put(new Integer(DOUBLE29), "DOUBLE29"); + fieldtonameHashTable.put(new Integer(DOUBLE30), "DOUBLE30"); + fieldtonameHashTable.put(new Integer(DOUBLE31), "DOUBLE31"); + fieldtonameHashTable.put(new Integer(DOUBLE32), "DOUBLE32"); + fieldtonameHashTable.put(new Integer(DOUBLE33), "DOUBLE33"); + fieldtonameHashTable.put(new Integer(DOUBLE34), "DOUBLE34"); + fieldtonameHashTable.put(new Integer(DOUBLE35), "DOUBLE35"); + fieldtonameHashTable.put(new Integer(DOUBLE36), "DOUBLE36"); + fieldtonameHashTable.put(new Integer(DOUBLE37), "DOUBLE37"); + fieldtonameHashTable.put(new Integer(DOUBLE38), "DOUBLE38"); + fieldtonameHashTable.put(new Integer(DOUBLE39), "DOUBLE39"); + fieldtonameHashTable.put(new Integer(DOUBLE40), "DOUBLE40"); + fieldtonameHashTable.put(new Integer(DOUBLE41), "DOUBLE41"); + fieldtonameHashTable.put(new Integer(DOUBLE42), "DOUBLE42"); + fieldtonameHashTable.put(new Integer(DOUBLE43), "DOUBLE43"); + fieldtonameHashTable.put(new Integer(DOUBLE44), "DOUBLE44"); + fieldtonameHashTable.put(new Integer(DOUBLE45), "DOUBLE45"); + fieldtonameHashTable.put(new Integer(DOUBLE46), "DOUBLE46"); + fieldtonameHashTable.put(new Integer(DOUBLE47), "DOUBLE47"); + fieldtonameHashTable.put(new Integer(DOUBLE48), "DOUBLE48"); + fieldtonameHashTable.put(new Integer(DOUBLE49), "DOUBLE49"); + fieldtonameHashTable.put(new Integer(DOUBLE50), "DOUBLE50"); + fieldtonameHashTable.put(new Integer(DOUBLE51), "DOUBLE51"); + fieldtonameHashTable.put(new Integer(DOUBLE52), "DOUBLE52"); + fieldtonameHashTable.put(new Integer(DOUBLE53), "DOUBLE53"); + fieldtonameHashTable.put(new Integer(DOUBLE54), "DOUBLE54"); + fieldtonameHashTable.put(new Integer(DOUBLE55), "DOUBLE55"); + fieldtonameHashTable.put(new Integer(DOUBLE56), "DOUBLE56"); + fieldtonameHashTable.put(new Integer(DOUBLE57), "DOUBLE57"); + fieldtonameHashTable.put(new Integer(DOUBLE58), "DOUBLE58"); + fieldtonameHashTable.put(new Integer(DOUBLE59), "DOUBLE59"); + fieldtonameHashTable.put(new Integer(DOUBLE60), "DOUBLE60"); + fieldtonameHashTable.put(new Integer(DOUBLE61), "DOUBLE61"); + fieldtonameHashTable.put(new Integer(DOUBLE62), "DOUBLE62"); + fieldtonameHashTable.put(new Integer(DOUBLE63), "DOUBLE63"); + fieldtonameHashTable.put(new Integer(DOUBLE64), "DOUBLE64"); + fieldtonameHashTable.put(new Integer(DOUBLE65), "DOUBLE65"); + fieldtonameHashTable.put(new Integer(DOUBLE66), "DOUBLE66"); + fieldtonameHashTable.put(new Integer(DOUBLE67), "DOUBLE67"); + fieldtonameHashTable.put(new Integer(DOUBLE68), "DOUBLE68"); + fieldtonameHashTable.put(new Integer(DOUBLE69), "DOUBLE69"); + fieldtonameHashTable.put(new Integer(DOUBLE70), "DOUBLE70"); + fieldtonameHashTable.put(new Integer(DOUBLE71), "DOUBLE71"); + fieldtonameHashTable.put(new Integer(DOUBLE72), "DOUBLE72"); + fieldtonameHashTable.put(new Integer(DOUBLE73), "DOUBLE73"); + fieldtonameHashTable.put(new Integer(DOUBLE74), "DOUBLE74"); + fieldtonameHashTable.put(new Integer(DOUBLE75), "DOUBLE75"); + fieldtonameHashTable.put(new Integer(DOUBLE76), "DOUBLE76"); + fieldtonameHashTable.put(new Integer(DOUBLE77), "DOUBLE77"); + fieldtonameHashTable.put(new Integer(DOUBLE78), "DOUBLE78"); + fieldtonameHashTable.put(new Integer(DOUBLE79), "DOUBLE79"); + fieldtonameHashTable.put(new Integer(DOUBLE80), "DOUBLE80"); + fieldtonameHashTable.put(new Integer(DOUBLE81), "DOUBLE81"); + fieldtonameHashTable.put(new Integer(DOUBLE82), "DOUBLE82"); + fieldtonameHashTable.put(new Integer(DOUBLE83), "DOUBLE83"); + fieldtonameHashTable.put(new Integer(DOUBLE84), "DOUBLE84"); + fieldtonameHashTable.put(new Integer(DOUBLE85), "DOUBLE85"); + fieldtonameHashTable.put(new Integer(DOUBLE86), "DOUBLE86"); + fieldtonameHashTable.put(new Integer(DOUBLE87), "DOUBLE87"); + fieldtonameHashTable.put(new Integer(DOUBLE88), "DOUBLE88"); + fieldtonameHashTable.put(new Integer(DOUBLE89), "DOUBLE89"); + fieldtonameHashTable.put(new Integer(DOUBLE90), "DOUBLE90"); + fieldtonameHashTable.put(new Integer(DOUBLE91), "DOUBLE91"); + fieldtonameHashTable.put(new Integer(DOUBLE92), "DOUBLE92"); + fieldtonameHashTable.put(new Integer(DOUBLE93), "DOUBLE93"); + fieldtonameHashTable.put(new Integer(DOUBLE94), "DOUBLE94"); + fieldtonameHashTable.put(new Integer(DOUBLE95), "DOUBLE95"); + fieldtonameHashTable.put(new Integer(DOUBLE96), "DOUBLE96"); + fieldtonameHashTable.put(new Integer(DOUBLE97), "DOUBLE97"); + fieldtonameHashTable.put(new Integer(DOUBLE98), "DOUBLE98"); + fieldtonameHashTable.put(new Integer(DOUBLE99), "DOUBLE99"); + fieldtonameHashTable.put(new Integer(DOUBLE100), "DOUBLE100"); + fieldtonameHashTable.put(new Integer(DOUBLE101), "DOUBLE101"); + fieldtonameHashTable.put(new Integer(DOUBLE102), "DOUBLE102"); + fieldtonameHashTable.put(new Integer(DOUBLE103), "DOUBLE103"); + fieldtonameHashTable.put(new Integer(DOUBLE104), "DOUBLE104"); + fieldtonameHashTable.put(new Integer(DOUBLE105), "DOUBLE105"); + fieldtonameHashTable.put(new Integer(DOUBLE106), "DOUBLE106"); + fieldtonameHashTable.put(new Integer(DOUBLE107), "DOUBLE107"); + fieldtonameHashTable.put(new Integer(DOUBLE108), "DOUBLE108"); + fieldtonameHashTable.put(new Integer(DOUBLE109), "DOUBLE109"); + fieldtonameHashTable.put(new Integer(DOUBLE110), "DOUBLE110"); + fieldtonameHashTable.put(new Integer(DOUBLE111), "DOUBLE111"); + fieldtonameHashTable.put(new Integer(DOUBLE112), "DOUBLE112"); + fieldtonameHashTable.put(new Integer(DOUBLE113), "DOUBLE113"); + fieldtonameHashTable.put(new Integer(DOUBLE114), "DOUBLE114"); + fieldtonameHashTable.put(new Integer(DOUBLE115), "DOUBLE115"); + fieldtonameHashTable.put(new Integer(DOUBLE116), "DOUBLE116"); + fieldtonameHashTable.put(new Integer(DOUBLE117), "DOUBLE117"); + fieldtonameHashTable.put(new Integer(DOUBLE118), "DOUBLE118"); + fieldtonameHashTable.put(new Integer(DOUBLE119), "DOUBLE119"); + fieldtonameHashTable.put(new Integer(DOUBLE120), "DOUBLE120"); + fieldtonameHashTable.put(new Integer(DOUBLE121), "DOUBLE121"); + fieldtonameHashTable.put(new Integer(DOUBLE122), "DOUBLE122"); + fieldtonameHashTable.put(new Integer(DOUBLE123), "DOUBLE123"); + fieldtonameHashTable.put(new Integer(DOUBLE124), "DOUBLE124"); + fieldtonameHashTable.put(new Integer(DOUBLE125), "DOUBLE125"); + fieldtonameHashTable.put(new Integer(DOUBLE126), "DOUBLE126"); + fieldtonameHashTable.put(new Integer(DOUBLE127), "DOUBLE127"); + fieldtonameHashTable.put(new Integer(DOUBLE128), "DOUBLE128"); + fieldtonameHashTable.put(new Integer(DOUBLE129), "DOUBLE129"); + fieldtonameHashTable.put(new Integer(DOUBLE130), "DOUBLE130"); + fieldtonameHashTable.put(new Integer(DOUBLE131), "DOUBLE131"); + fieldtonameHashTable.put(new Integer(DOUBLE132), "DOUBLE132"); + fieldtonameHashTable.put(new Integer(DOUBLE133), "DOUBLE133"); + fieldtonameHashTable.put(new Integer(DOUBLE134), "DOUBLE134"); + fieldtonameHashTable.put(new Integer(DOUBLE135), "DOUBLE135"); + fieldtonameHashTable.put(new Integer(DOUBLE136), "DOUBLE136"); + fieldtonameHashTable.put(new Integer(DOUBLE137), "DOUBLE137"); + fieldtonameHashTable.put(new Integer(DOUBLE138), "DOUBLE138"); + fieldtonameHashTable.put(new Integer(DOUBLE139), "DOUBLE139"); + fieldtonameHashTable.put(new Integer(DOUBLE140), "DOUBLE140"); + fieldtonameHashTable.put(new Integer(DOUBLE141), "DOUBLE141"); + fieldtonameHashTable.put(new Integer(DOUBLE142), "DOUBLE142"); + fieldtonameHashTable.put(new Integer(DOUBLE143), "DOUBLE143"); + fieldtonameHashTable.put(new Integer(DOUBLE144), "DOUBLE144"); + fieldtonameHashTable.put(new Integer(DOUBLE145), "DOUBLE145"); + fieldtonameHashTable.put(new Integer(DOUBLE146), "DOUBLE146"); + fieldtonameHashTable.put(new Integer(DOUBLE147), "DOUBLE147"); + fieldtonameHashTable.put(new Integer(DOUBLE148), "DOUBLE148"); + fieldtonameHashTable.put(new Integer(DOUBLE149), "DOUBLE149"); + fieldtonameHashTable.put(new Integer(DOUBLE150), "DOUBLE150"); + fieldtonameHashTable.put(new Integer(DOUBLE151), "DOUBLE151"); + fieldtonameHashTable.put(new Integer(DOUBLE152), "DOUBLE152"); + fieldtonameHashTable.put(new Integer(DOUBLE153), "DOUBLE153"); + fieldtonameHashTable.put(new Integer(DOUBLE154), "DOUBLE154"); + fieldtonameHashTable.put(new Integer(DOUBLE155), "DOUBLE155"); + fieldtonameHashTable.put(new Integer(DOUBLE156), "DOUBLE156"); + fieldtonameHashTable.put(new Integer(DOUBLE157), "DOUBLE157"); + fieldtonameHashTable.put(new Integer(DOUBLE158), "DOUBLE158"); + fieldtonameHashTable.put(new Integer(DOUBLE159), "DOUBLE159"); + fieldtonameHashTable.put(new Integer(DOUBLE160), "DOUBLE160"); + fieldtonameHashTable.put(new Integer(DOUBLE161), "DOUBLE161"); + fieldtonameHashTable.put(new Integer(DOUBLE162), "DOUBLE162"); + fieldtonameHashTable.put(new Integer(DOUBLE163), "DOUBLE163"); + fieldtonameHashTable.put(new Integer(DOUBLE164), "DOUBLE164"); + fieldtonameHashTable.put(new Integer(DOUBLE165), "DOUBLE165"); + fieldtonameHashTable.put(new Integer(DOUBLE166), "DOUBLE166"); + fieldtonameHashTable.put(new Integer(DOUBLE167), "DOUBLE167"); + fieldtonameHashTable.put(new Integer(DOUBLE168), "DOUBLE168"); + fieldtonameHashTable.put(new Integer(DOUBLE169), "DOUBLE169"); + fieldtonameHashTable.put(new Integer(DOUBLE170), "DOUBLE170"); + fieldtonameHashTable.put(new Integer(DOUBLE171), "DOUBLE171"); + fieldtonameHashTable.put(new Integer(DOUBLE172), "DOUBLE172"); + fieldtonameHashTable.put(new Integer(DOUBLE173), "DOUBLE173"); + fieldtonameHashTable.put(new Integer(DOUBLE174), "DOUBLE174"); + fieldtonameHashTable.put(new Integer(DOUBLE175), "DOUBLE175"); + fieldtonameHashTable.put(new Integer(DOUBLE176), "DOUBLE176"); + fieldtonameHashTable.put(new Integer(DOUBLE177), "DOUBLE177"); + fieldtonameHashTable.put(new Integer(DOUBLE178), "DOUBLE178"); + fieldtonameHashTable.put(new Integer(DOUBLE179), "DOUBLE179"); + fieldtonameHashTable.put(new Integer(DOUBLE180), "DOUBLE180"); + fieldtonameHashTable.put(new Integer(DOUBLE181), "DOUBLE181"); + fieldtonameHashTable.put(new Integer(DOUBLE182), "DOUBLE182"); + fieldtonameHashTable.put(new Integer(DOUBLE183), "DOUBLE183"); + fieldtonameHashTable.put(new Integer(DOUBLE184), "DOUBLE184"); + fieldtonameHashTable.put(new Integer(DOUBLE185), "DOUBLE185"); + fieldtonameHashTable.put(new Integer(DOUBLE186), "DOUBLE186"); + fieldtonameHashTable.put(new Integer(DOUBLE187), "DOUBLE187"); + fieldtonameHashTable.put(new Integer(DOUBLE188), "DOUBLE188"); + fieldtonameHashTable.put(new Integer(DOUBLE189), "DOUBLE189"); + fieldtonameHashTable.put(new Integer(DOUBLE190), "DOUBLE190"); + fieldtonameHashTable.put(new Integer(DOUBLE191), "DOUBLE191"); + fieldtonameHashTable.put(new Integer(DOUBLE192), "DOUBLE192"); + fieldtonameHashTable.put(new Integer(DOUBLE193), "DOUBLE193"); + fieldtonameHashTable.put(new Integer(DOUBLE194), "DOUBLE194"); + fieldtonameHashTable.put(new Integer(DOUBLE195), "DOUBLE195"); + fieldtonameHashTable.put(new Integer(DOUBLE196), "DOUBLE196"); + fieldtonameHashTable.put(new Integer(DOUBLE197), "DOUBLE197"); + fieldtonameHashTable.put(new Integer(DOUBLE198), "DOUBLE198"); + fieldtonameHashTable.put(new Integer(DOUBLE199), "DOUBLE199"); + fieldtonameHashTable.put(new Integer(DOUBLE200), "DOUBLE200"); + fieldtonameHashTable.put(new Integer(SVCNAME), "SVCNAME"); + fieldtonameHashTable.put(new Integer(TPURCODE), "TPURCODE"); + } + + return ((String)fieldtonameHashTable.get(new Integer(fldid))); + } + + public int getFieldId(String name) + { + if ( nametofieldHashTable == null ) { + nametofieldHashTable = new Hashtable(); + nametofieldHashTable.put("STRING1", new Integer(STRING1)); + nametofieldHashTable.put("STRING2", new Integer(STRING2)); + nametofieldHashTable.put("STRING3", new Integer(STRING3)); + nametofieldHashTable.put("STRING4", new Integer(STRING4)); + nametofieldHashTable.put("STRING5", new Integer(STRING5)); + nametofieldHashTable.put("STRING6", new Integer(STRING6)); + nametofieldHashTable.put("STRING7", new Integer(STRING7)); + nametofieldHashTable.put("STRING8", new Integer(STRING8)); + nametofieldHashTable.put("STRING9", new Integer(STRING9)); + nametofieldHashTable.put("STRING10", new Integer(STRING10)); + nametofieldHashTable.put("STRING11", new Integer(STRING11)); + nametofieldHashTable.put("STRING12", new Integer(STRING12)); + nametofieldHashTable.put("STRING13", new Integer(STRING13)); + nametofieldHashTable.put("STRING14", new Integer(STRING14)); + nametofieldHashTable.put("STRING15", new Integer(STRING15)); + nametofieldHashTable.put("STRING16", new Integer(STRING16)); + nametofieldHashTable.put("STRING17", new Integer(STRING17)); + nametofieldHashTable.put("STRING18", new Integer(STRING18)); + nametofieldHashTable.put("STRING19", new Integer(STRING19)); + nametofieldHashTable.put("STRING20", new Integer(STRING20)); + nametofieldHashTable.put("STRING21", new Integer(STRING21)); + nametofieldHashTable.put("STRING22", new Integer(STRING22)); + nametofieldHashTable.put("STRING23", new Integer(STRING23)); + nametofieldHashTable.put("STRING24", new Integer(STRING24)); + nametofieldHashTable.put("STRING25", new Integer(STRING25)); + nametofieldHashTable.put("STRING26", new Integer(STRING26)); + nametofieldHashTable.put("STRING27", new Integer(STRING27)); + nametofieldHashTable.put("STRING28", new Integer(STRING28)); + nametofieldHashTable.put("STRING29", new Integer(STRING29)); + nametofieldHashTable.put("STRING30", new Integer(STRING30)); + nametofieldHashTable.put("STRING31", new Integer(STRING31)); + nametofieldHashTable.put("STRING32", new Integer(STRING32)); + nametofieldHashTable.put("STRING33", new Integer(STRING33)); + nametofieldHashTable.put("STRING34", new Integer(STRING34)); + nametofieldHashTable.put("STRING35", new Integer(STRING35)); + nametofieldHashTable.put("STRING36", new Integer(STRING36)); + nametofieldHashTable.put("STRING37", new Integer(STRING37)); + nametofieldHashTable.put("STRING38", new Integer(STRING38)); + nametofieldHashTable.put("STRING39", new Integer(STRING39)); + nametofieldHashTable.put("STRING40", new Integer(STRING40)); + nametofieldHashTable.put("STRING41", new Integer(STRING41)); + nametofieldHashTable.put("STRING42", new Integer(STRING42)); + nametofieldHashTable.put("STRING43", new Integer(STRING43)); + nametofieldHashTable.put("STRING44", new Integer(STRING44)); + nametofieldHashTable.put("STRING45", new Integer(STRING45)); + nametofieldHashTable.put("STRING46", new Integer(STRING46)); + nametofieldHashTable.put("STRING47", new Integer(STRING47)); + nametofieldHashTable.put("STRING48", new Integer(STRING48)); + nametofieldHashTable.put("STRING49", new Integer(STRING49)); + nametofieldHashTable.put("STRING50", new Integer(STRING50)); + nametofieldHashTable.put("STRING51", new Integer(STRING51)); + nametofieldHashTable.put("STRING52", new Integer(STRING52)); + nametofieldHashTable.put("STRING53", new Integer(STRING53)); + nametofieldHashTable.put("STRING54", new Integer(STRING54)); + nametofieldHashTable.put("STRING55", new Integer(STRING55)); + nametofieldHashTable.put("STRING56", new Integer(STRING56)); + nametofieldHashTable.put("STRING57", new Integer(STRING57)); + nametofieldHashTable.put("STRING58", new Integer(STRING58)); + nametofieldHashTable.put("STRING59", new Integer(STRING59)); + nametofieldHashTable.put("STRING60", new Integer(STRING60)); + nametofieldHashTable.put("STRING61", new Integer(STRING61)); + nametofieldHashTable.put("STRING62", new Integer(STRING62)); + nametofieldHashTable.put("STRING63", new Integer(STRING63)); + nametofieldHashTable.put("STRING64", new Integer(STRING64)); + nametofieldHashTable.put("STRING65", new Integer(STRING65)); + nametofieldHashTable.put("STRING66", new Integer(STRING66)); + nametofieldHashTable.put("STRING67", new Integer(STRING67)); + nametofieldHashTable.put("STRING68", new Integer(STRING68)); + nametofieldHashTable.put("STRING69", new Integer(STRING69)); + nametofieldHashTable.put("STRING70", new Integer(STRING70)); + nametofieldHashTable.put("STRING71", new Integer(STRING71)); + nametofieldHashTable.put("STRING72", new Integer(STRING72)); + nametofieldHashTable.put("STRING73", new Integer(STRING73)); + nametofieldHashTable.put("STRING74", new Integer(STRING74)); + nametofieldHashTable.put("STRING75", new Integer(STRING75)); + nametofieldHashTable.put("STRING76", new Integer(STRING76)); + nametofieldHashTable.put("STRING77", new Integer(STRING77)); + nametofieldHashTable.put("STRING78", new Integer(STRING78)); + nametofieldHashTable.put("STRING79", new Integer(STRING79)); + nametofieldHashTable.put("STRING80", new Integer(STRING80)); + nametofieldHashTable.put("STRING81", new Integer(STRING81)); + nametofieldHashTable.put("STRING82", new Integer(STRING82)); + nametofieldHashTable.put("STRING83", new Integer(STRING83)); + nametofieldHashTable.put("STRING84", new Integer(STRING84)); + nametofieldHashTable.put("STRING85", new Integer(STRING85)); + nametofieldHashTable.put("STRING86", new Integer(STRING86)); + nametofieldHashTable.put("STRING87", new Integer(STRING87)); + nametofieldHashTable.put("STRING88", new Integer(STRING88)); + nametofieldHashTable.put("STRING89", new Integer(STRING89)); + nametofieldHashTable.put("STRING90", new Integer(STRING90)); + nametofieldHashTable.put("STRING91", new Integer(STRING91)); + nametofieldHashTable.put("STRING92", new Integer(STRING92)); + nametofieldHashTable.put("STRING93", new Integer(STRING93)); + nametofieldHashTable.put("STRING94", new Integer(STRING94)); + nametofieldHashTable.put("STRING95", new Integer(STRING95)); + nametofieldHashTable.put("STRING96", new Integer(STRING96)); + nametofieldHashTable.put("STRING97", new Integer(STRING97)); + nametofieldHashTable.put("STRING98", new Integer(STRING98)); + nametofieldHashTable.put("STRING99", new Integer(STRING99)); + nametofieldHashTable.put("STRING100", new Integer(STRING100)); + nametofieldHashTable.put("STRING101", new Integer(STRING101)); + nametofieldHashTable.put("STRING102", new Integer(STRING102)); + nametofieldHashTable.put("STRING103", new Integer(STRING103)); + nametofieldHashTable.put("STRING104", new Integer(STRING104)); + nametofieldHashTable.put("STRING105", new Integer(STRING105)); + nametofieldHashTable.put("STRING106", new Integer(STRING106)); + nametofieldHashTable.put("STRING107", new Integer(STRING107)); + nametofieldHashTable.put("STRING108", new Integer(STRING108)); + nametofieldHashTable.put("STRING109", new Integer(STRING109)); + nametofieldHashTable.put("STRING110", new Integer(STRING110)); + nametofieldHashTable.put("STRING111", new Integer(STRING111)); + nametofieldHashTable.put("STRING112", new Integer(STRING112)); + nametofieldHashTable.put("STRING113", new Integer(STRING113)); + nametofieldHashTable.put("STRING114", new Integer(STRING114)); + nametofieldHashTable.put("STRING115", new Integer(STRING115)); + nametofieldHashTable.put("STRING116", new Integer(STRING116)); + nametofieldHashTable.put("STRING117", new Integer(STRING117)); + nametofieldHashTable.put("STRING118", new Integer(STRING118)); + nametofieldHashTable.put("STRING119", new Integer(STRING119)); + nametofieldHashTable.put("STRING120", new Integer(STRING120)); + nametofieldHashTable.put("STRING121", new Integer(STRING121)); + nametofieldHashTable.put("STRING122", new Integer(STRING122)); + nametofieldHashTable.put("STRING123", new Integer(STRING123)); + nametofieldHashTable.put("STRING124", new Integer(STRING124)); + nametofieldHashTable.put("STRING125", new Integer(STRING125)); + nametofieldHashTable.put("STRING126", new Integer(STRING126)); + nametofieldHashTable.put("STRING127", new Integer(STRING127)); + nametofieldHashTable.put("STRING128", new Integer(STRING128)); + nametofieldHashTable.put("STRING129", new Integer(STRING129)); + nametofieldHashTable.put("STRING130", new Integer(STRING130)); + nametofieldHashTable.put("STRING131", new Integer(STRING131)); + nametofieldHashTable.put("STRING132", new Integer(STRING132)); + nametofieldHashTable.put("STRING133", new Integer(STRING133)); + nametofieldHashTable.put("STRING134", new Integer(STRING134)); + nametofieldHashTable.put("STRING135", new Integer(STRING135)); + nametofieldHashTable.put("STRING136", new Integer(STRING136)); + nametofieldHashTable.put("STRING137", new Integer(STRING137)); + nametofieldHashTable.put("STRING138", new Integer(STRING138)); + nametofieldHashTable.put("STRING139", new Integer(STRING139)); + nametofieldHashTable.put("STRING140", new Integer(STRING140)); + nametofieldHashTable.put("STRING141", new Integer(STRING141)); + nametofieldHashTable.put("STRING142", new Integer(STRING142)); + nametofieldHashTable.put("STRING143", new Integer(STRING143)); + nametofieldHashTable.put("STRING144", new Integer(STRING144)); + nametofieldHashTable.put("STRING145", new Integer(STRING145)); + nametofieldHashTable.put("STRING146", new Integer(STRING146)); + nametofieldHashTable.put("STRING147", new Integer(STRING147)); + nametofieldHashTable.put("STRING148", new Integer(STRING148)); + nametofieldHashTable.put("STRING149", new Integer(STRING149)); + nametofieldHashTable.put("STRING150", new Integer(STRING150)); + nametofieldHashTable.put("STRING151", new Integer(STRING151)); + nametofieldHashTable.put("STRING152", new Integer(STRING152)); + nametofieldHashTable.put("STRING153", new Integer(STRING153)); + nametofieldHashTable.put("STRING154", new Integer(STRING154)); + nametofieldHashTable.put("STRING155", new Integer(STRING155)); + nametofieldHashTable.put("STRING156", new Integer(STRING156)); + nametofieldHashTable.put("STRING157", new Integer(STRING157)); + nametofieldHashTable.put("STRING158", new Integer(STRING158)); + nametofieldHashTable.put("STRING159", new Integer(STRING159)); + nametofieldHashTable.put("STRING160", new Integer(STRING160)); + nametofieldHashTable.put("STRING161", new Integer(STRING161)); + nametofieldHashTable.put("STRING162", new Integer(STRING162)); + nametofieldHashTable.put("STRING163", new Integer(STRING163)); + nametofieldHashTable.put("STRING164", new Integer(STRING164)); + nametofieldHashTable.put("STRING165", new Integer(STRING165)); + nametofieldHashTable.put("STRING166", new Integer(STRING166)); + nametofieldHashTable.put("STRING167", new Integer(STRING167)); + nametofieldHashTable.put("STRING168", new Integer(STRING168)); + nametofieldHashTable.put("STRING169", new Integer(STRING169)); + nametofieldHashTable.put("STRING170", new Integer(STRING170)); + nametofieldHashTable.put("STRING171", new Integer(STRING171)); + nametofieldHashTable.put("STRING172", new Integer(STRING172)); + nametofieldHashTable.put("STRING173", new Integer(STRING173)); + nametofieldHashTable.put("STRING174", new Integer(STRING174)); + nametofieldHashTable.put("STRING175", new Integer(STRING175)); + nametofieldHashTable.put("STRING176", new Integer(STRING176)); + nametofieldHashTable.put("STRING177", new Integer(STRING177)); + nametofieldHashTable.put("STRING178", new Integer(STRING178)); + nametofieldHashTable.put("STRING179", new Integer(STRING179)); + nametofieldHashTable.put("STRING180", new Integer(STRING180)); + nametofieldHashTable.put("STRING181", new Integer(STRING181)); + nametofieldHashTable.put("STRING182", new Integer(STRING182)); + nametofieldHashTable.put("STRING183", new Integer(STRING183)); + nametofieldHashTable.put("STRING184", new Integer(STRING184)); + nametofieldHashTable.put("STRING185", new Integer(STRING185)); + nametofieldHashTable.put("STRING186", new Integer(STRING186)); + nametofieldHashTable.put("STRING187", new Integer(STRING187)); + nametofieldHashTable.put("STRING188", new Integer(STRING188)); + nametofieldHashTable.put("STRING189", new Integer(STRING189)); + nametofieldHashTable.put("STRING190", new Integer(STRING190)); + nametofieldHashTable.put("STRING191", new Integer(STRING191)); + nametofieldHashTable.put("STRING192", new Integer(STRING192)); + nametofieldHashTable.put("STRING193", new Integer(STRING193)); + nametofieldHashTable.put("STRING194", new Integer(STRING194)); + nametofieldHashTable.put("STRING195", new Integer(STRING195)); + nametofieldHashTable.put("STRING196", new Integer(STRING196)); + nametofieldHashTable.put("STRING197", new Integer(STRING197)); + nametofieldHashTable.put("STRING198", new Integer(STRING198)); + nametofieldHashTable.put("STRING199", new Integer(STRING199)); + nametofieldHashTable.put("STRING200", new Integer(STRING200)); + nametofieldHashTable.put("LONG1", new Integer(LONG1)); + nametofieldHashTable.put("LONG2", new Integer(LONG2)); + nametofieldHashTable.put("LONG3", new Integer(LONG3)); + nametofieldHashTable.put("LONG4", new Integer(LONG4)); + nametofieldHashTable.put("LONG5", new Integer(LONG5)); + nametofieldHashTable.put("LONG6", new Integer(LONG6)); + nametofieldHashTable.put("LONG7", new Integer(LONG7)); + nametofieldHashTable.put("LONG8", new Integer(LONG8)); + nametofieldHashTable.put("LONG9", new Integer(LONG9)); + nametofieldHashTable.put("LONG10", new Integer(LONG10)); + nametofieldHashTable.put("LONG11", new Integer(LONG11)); + nametofieldHashTable.put("LONG12", new Integer(LONG12)); + nametofieldHashTable.put("LONG13", new Integer(LONG13)); + nametofieldHashTable.put("LONG14", new Integer(LONG14)); + nametofieldHashTable.put("LONG15", new Integer(LONG15)); + nametofieldHashTable.put("LONG16", new Integer(LONG16)); + nametofieldHashTable.put("LONG17", new Integer(LONG17)); + nametofieldHashTable.put("LONG18", new Integer(LONG18)); + nametofieldHashTable.put("LONG19", new Integer(LONG19)); + nametofieldHashTable.put("LONG20", new Integer(LONG20)); + nametofieldHashTable.put("LONG21", new Integer(LONG21)); + nametofieldHashTable.put("LONG22", new Integer(LONG22)); + nametofieldHashTable.put("LONG23", new Integer(LONG23)); + nametofieldHashTable.put("LONG24", new Integer(LONG24)); + nametofieldHashTable.put("LONG25", new Integer(LONG25)); + nametofieldHashTable.put("LONG26", new Integer(LONG26)); + nametofieldHashTable.put("LONG27", new Integer(LONG27)); + nametofieldHashTable.put("LONG28", new Integer(LONG28)); + nametofieldHashTable.put("LONG29", new Integer(LONG29)); + nametofieldHashTable.put("LONG30", new Integer(LONG30)); + nametofieldHashTable.put("LONG31", new Integer(LONG31)); + nametofieldHashTable.put("LONG32", new Integer(LONG32)); + nametofieldHashTable.put("LONG33", new Integer(LONG33)); + nametofieldHashTable.put("LONG34", new Integer(LONG34)); + nametofieldHashTable.put("LONG35", new Integer(LONG35)); + nametofieldHashTable.put("LONG36", new Integer(LONG36)); + nametofieldHashTable.put("LONG37", new Integer(LONG37)); + nametofieldHashTable.put("LONG38", new Integer(LONG38)); + nametofieldHashTable.put("LONG39", new Integer(LONG39)); + nametofieldHashTable.put("LONG40", new Integer(LONG40)); + nametofieldHashTable.put("LONG41", new Integer(LONG41)); + nametofieldHashTable.put("LONG42", new Integer(LONG42)); + nametofieldHashTable.put("LONG43", new Integer(LONG43)); + nametofieldHashTable.put("LONG44", new Integer(LONG44)); + nametofieldHashTable.put("LONG45", new Integer(LONG45)); + nametofieldHashTable.put("LONG46", new Integer(LONG46)); + nametofieldHashTable.put("LONG47", new Integer(LONG47)); + nametofieldHashTable.put("LONG48", new Integer(LONG48)); + nametofieldHashTable.put("LONG49", new Integer(LONG49)); + nametofieldHashTable.put("LONG50", new Integer(LONG50)); + nametofieldHashTable.put("LONG51", new Integer(LONG51)); + nametofieldHashTable.put("LONG52", new Integer(LONG52)); + nametofieldHashTable.put("LONG53", new Integer(LONG53)); + nametofieldHashTable.put("LONG54", new Integer(LONG54)); + nametofieldHashTable.put("LONG55", new Integer(LONG55)); + nametofieldHashTable.put("LONG56", new Integer(LONG56)); + nametofieldHashTable.put("LONG57", new Integer(LONG57)); + nametofieldHashTable.put("LONG58", new Integer(LONG58)); + nametofieldHashTable.put("LONG59", new Integer(LONG59)); + nametofieldHashTable.put("LONG60", new Integer(LONG60)); + nametofieldHashTable.put("LONG61", new Integer(LONG61)); + nametofieldHashTable.put("LONG62", new Integer(LONG62)); + nametofieldHashTable.put("LONG63", new Integer(LONG63)); + nametofieldHashTable.put("LONG64", new Integer(LONG64)); + nametofieldHashTable.put("LONG65", new Integer(LONG65)); + nametofieldHashTable.put("LONG66", new Integer(LONG66)); + nametofieldHashTable.put("LONG67", new Integer(LONG67)); + nametofieldHashTable.put("LONG68", new Integer(LONG68)); + nametofieldHashTable.put("LONG69", new Integer(LONG69)); + nametofieldHashTable.put("LONG70", new Integer(LONG70)); + nametofieldHashTable.put("LONG71", new Integer(LONG71)); + nametofieldHashTable.put("LONG72", new Integer(LONG72)); + nametofieldHashTable.put("LONG73", new Integer(LONG73)); + nametofieldHashTable.put("LONG74", new Integer(LONG74)); + nametofieldHashTable.put("LONG75", new Integer(LONG75)); + nametofieldHashTable.put("LONG76", new Integer(LONG76)); + nametofieldHashTable.put("LONG77", new Integer(LONG77)); + nametofieldHashTable.put("LONG78", new Integer(LONG78)); + nametofieldHashTable.put("LONG79", new Integer(LONG79)); + nametofieldHashTable.put("LONG80", new Integer(LONG80)); + nametofieldHashTable.put("LONG81", new Integer(LONG81)); + nametofieldHashTable.put("LONG82", new Integer(LONG82)); + nametofieldHashTable.put("LONG83", new Integer(LONG83)); + nametofieldHashTable.put("LONG84", new Integer(LONG84)); + nametofieldHashTable.put("LONG85", new Integer(LONG85)); + nametofieldHashTable.put("LONG86", new Integer(LONG86)); + nametofieldHashTable.put("LONG87", new Integer(LONG87)); + nametofieldHashTable.put("LONG88", new Integer(LONG88)); + nametofieldHashTable.put("LONG89", new Integer(LONG89)); + nametofieldHashTable.put("LONG90", new Integer(LONG90)); + nametofieldHashTable.put("LONG91", new Integer(LONG91)); + nametofieldHashTable.put("LONG92", new Integer(LONG92)); + nametofieldHashTable.put("LONG93", new Integer(LONG93)); + nametofieldHashTable.put("LONG94", new Integer(LONG94)); + nametofieldHashTable.put("LONG95", new Integer(LONG95)); + nametofieldHashTable.put("LONG96", new Integer(LONG96)); + nametofieldHashTable.put("LONG97", new Integer(LONG97)); + nametofieldHashTable.put("LONG98", new Integer(LONG98)); + nametofieldHashTable.put("LONG99", new Integer(LONG99)); + nametofieldHashTable.put("LONG100", new Integer(LONG100)); + nametofieldHashTable.put("DOUBLE1", new Integer(DOUBLE1)); + nametofieldHashTable.put("DOUBLE2", new Integer(DOUBLE2)); + nametofieldHashTable.put("DOUBLE3", new Integer(DOUBLE3)); + nametofieldHashTable.put("DOUBLE4", new Integer(DOUBLE4)); + nametofieldHashTable.put("DOUBLE5", new Integer(DOUBLE5)); + nametofieldHashTable.put("DOUBLE6", new Integer(DOUBLE6)); + nametofieldHashTable.put("DOUBLE7", new Integer(DOUBLE7)); + nametofieldHashTable.put("DOUBLE8", new Integer(DOUBLE8)); + nametofieldHashTable.put("DOUBLE9", new Integer(DOUBLE9)); + nametofieldHashTable.put("DOUBLE10", new Integer(DOUBLE10)); + nametofieldHashTable.put("DOUBLE11", new Integer(DOUBLE11)); + nametofieldHashTable.put("DOUBLE12", new Integer(DOUBLE12)); + nametofieldHashTable.put("DOUBLE13", new Integer(DOUBLE13)); + nametofieldHashTable.put("DOUBLE14", new Integer(DOUBLE14)); + nametofieldHashTable.put("DOUBLE15", new Integer(DOUBLE15)); + nametofieldHashTable.put("DOUBLE16", new Integer(DOUBLE16)); + nametofieldHashTable.put("DOUBLE17", new Integer(DOUBLE17)); + nametofieldHashTable.put("DOUBLE18", new Integer(DOUBLE18)); + nametofieldHashTable.put("DOUBLE19", new Integer(DOUBLE19)); + nametofieldHashTable.put("DOUBLE20", new Integer(DOUBLE20)); + nametofieldHashTable.put("DOUBLE21", new Integer(DOUBLE21)); + nametofieldHashTable.put("DOUBLE22", new Integer(DOUBLE22)); + nametofieldHashTable.put("DOUBLE23", new Integer(DOUBLE23)); + nametofieldHashTable.put("DOUBLE24", new Integer(DOUBLE24)); + nametofieldHashTable.put("DOUBLE25", new Integer(DOUBLE25)); + nametofieldHashTable.put("DOUBLE26", new Integer(DOUBLE26)); + nametofieldHashTable.put("DOUBLE27", new Integer(DOUBLE27)); + nametofieldHashTable.put("DOUBLE28", new Integer(DOUBLE28)); + nametofieldHashTable.put("DOUBLE29", new Integer(DOUBLE29)); + nametofieldHashTable.put("DOUBLE30", new Integer(DOUBLE30)); + nametofieldHashTable.put("DOUBLE31", new Integer(DOUBLE31)); + nametofieldHashTable.put("DOUBLE32", new Integer(DOUBLE32)); + nametofieldHashTable.put("DOUBLE33", new Integer(DOUBLE33)); + nametofieldHashTable.put("DOUBLE34", new Integer(DOUBLE34)); + nametofieldHashTable.put("DOUBLE35", new Integer(DOUBLE35)); + nametofieldHashTable.put("DOUBLE36", new Integer(DOUBLE36)); + nametofieldHashTable.put("DOUBLE37", new Integer(DOUBLE37)); + nametofieldHashTable.put("DOUBLE38", new Integer(DOUBLE38)); + nametofieldHashTable.put("DOUBLE39", new Integer(DOUBLE39)); + nametofieldHashTable.put("DOUBLE40", new Integer(DOUBLE40)); + nametofieldHashTable.put("DOUBLE41", new Integer(DOUBLE41)); + nametofieldHashTable.put("DOUBLE42", new Integer(DOUBLE42)); + nametofieldHashTable.put("DOUBLE43", new Integer(DOUBLE43)); + nametofieldHashTable.put("DOUBLE44", new Integer(DOUBLE44)); + nametofieldHashTable.put("DOUBLE45", new Integer(DOUBLE45)); + nametofieldHashTable.put("DOUBLE46", new Integer(DOUBLE46)); + nametofieldHashTable.put("DOUBLE47", new Integer(DOUBLE47)); + nametofieldHashTable.put("DOUBLE48", new Integer(DOUBLE48)); + nametofieldHashTable.put("DOUBLE49", new Integer(DOUBLE49)); + nametofieldHashTable.put("DOUBLE50", new Integer(DOUBLE50)); + nametofieldHashTable.put("DOUBLE51", new Integer(DOUBLE51)); + nametofieldHashTable.put("DOUBLE52", new Integer(DOUBLE52)); + nametofieldHashTable.put("DOUBLE53", new Integer(DOUBLE53)); + nametofieldHashTable.put("DOUBLE54", new Integer(DOUBLE54)); + nametofieldHashTable.put("DOUBLE55", new Integer(DOUBLE55)); + nametofieldHashTable.put("DOUBLE56", new Integer(DOUBLE56)); + nametofieldHashTable.put("DOUBLE57", new Integer(DOUBLE57)); + nametofieldHashTable.put("DOUBLE58", new Integer(DOUBLE58)); + nametofieldHashTable.put("DOUBLE59", new Integer(DOUBLE59)); + nametofieldHashTable.put("DOUBLE60", new Integer(DOUBLE60)); + nametofieldHashTable.put("DOUBLE61", new Integer(DOUBLE61)); + nametofieldHashTable.put("DOUBLE62", new Integer(DOUBLE62)); + nametofieldHashTable.put("DOUBLE63", new Integer(DOUBLE63)); + nametofieldHashTable.put("DOUBLE64", new Integer(DOUBLE64)); + nametofieldHashTable.put("DOUBLE65", new Integer(DOUBLE65)); + nametofieldHashTable.put("DOUBLE66", new Integer(DOUBLE66)); + nametofieldHashTable.put("DOUBLE67", new Integer(DOUBLE67)); + nametofieldHashTable.put("DOUBLE68", new Integer(DOUBLE68)); + nametofieldHashTable.put("DOUBLE69", new Integer(DOUBLE69)); + nametofieldHashTable.put("DOUBLE70", new Integer(DOUBLE70)); + nametofieldHashTable.put("DOUBLE71", new Integer(DOUBLE71)); + nametofieldHashTable.put("DOUBLE72", new Integer(DOUBLE72)); + nametofieldHashTable.put("DOUBLE73", new Integer(DOUBLE73)); + nametofieldHashTable.put("DOUBLE74", new Integer(DOUBLE74)); + nametofieldHashTable.put("DOUBLE75", new Integer(DOUBLE75)); + nametofieldHashTable.put("DOUBLE76", new Integer(DOUBLE76)); + nametofieldHashTable.put("DOUBLE77", new Integer(DOUBLE77)); + nametofieldHashTable.put("DOUBLE78", new Integer(DOUBLE78)); + nametofieldHashTable.put("DOUBLE79", new Integer(DOUBLE79)); + nametofieldHashTable.put("DOUBLE80", new Integer(DOUBLE80)); + nametofieldHashTable.put("DOUBLE81", new Integer(DOUBLE81)); + nametofieldHashTable.put("DOUBLE82", new Integer(DOUBLE82)); + nametofieldHashTable.put("DOUBLE83", new Integer(DOUBLE83)); + nametofieldHashTable.put("DOUBLE84", new Integer(DOUBLE84)); + nametofieldHashTable.put("DOUBLE85", new Integer(DOUBLE85)); + nametofieldHashTable.put("DOUBLE86", new Integer(DOUBLE86)); + nametofieldHashTable.put("DOUBLE87", new Integer(DOUBLE87)); + nametofieldHashTable.put("DOUBLE88", new Integer(DOUBLE88)); + nametofieldHashTable.put("DOUBLE89", new Integer(DOUBLE89)); + nametofieldHashTable.put("DOUBLE90", new Integer(DOUBLE90)); + nametofieldHashTable.put("DOUBLE91", new Integer(DOUBLE91)); + nametofieldHashTable.put("DOUBLE92", new Integer(DOUBLE92)); + nametofieldHashTable.put("DOUBLE93", new Integer(DOUBLE93)); + nametofieldHashTable.put("DOUBLE94", new Integer(DOUBLE94)); + nametofieldHashTable.put("DOUBLE95", new Integer(DOUBLE95)); + nametofieldHashTable.put("DOUBLE96", new Integer(DOUBLE96)); + nametofieldHashTable.put("DOUBLE97", new Integer(DOUBLE97)); + nametofieldHashTable.put("DOUBLE98", new Integer(DOUBLE98)); + nametofieldHashTable.put("DOUBLE99", new Integer(DOUBLE99)); + nametofieldHashTable.put("DOUBLE100", new Integer(DOUBLE100)); + nametofieldHashTable.put("DOUBLE101", new Integer(DOUBLE101)); + nametofieldHashTable.put("DOUBLE102", new Integer(DOUBLE102)); + nametofieldHashTable.put("DOUBLE103", new Integer(DOUBLE103)); + nametofieldHashTable.put("DOUBLE104", new Integer(DOUBLE104)); + nametofieldHashTable.put("DOUBLE105", new Integer(DOUBLE105)); + nametofieldHashTable.put("DOUBLE106", new Integer(DOUBLE106)); + nametofieldHashTable.put("DOUBLE107", new Integer(DOUBLE107)); + nametofieldHashTable.put("DOUBLE108", new Integer(DOUBLE108)); + nametofieldHashTable.put("DOUBLE109", new Integer(DOUBLE109)); + nametofieldHashTable.put("DOUBLE110", new Integer(DOUBLE110)); + nametofieldHashTable.put("DOUBLE111", new Integer(DOUBLE111)); + nametofieldHashTable.put("DOUBLE112", new Integer(DOUBLE112)); + nametofieldHashTable.put("DOUBLE113", new Integer(DOUBLE113)); + nametofieldHashTable.put("DOUBLE114", new Integer(DOUBLE114)); + nametofieldHashTable.put("DOUBLE115", new Integer(DOUBLE115)); + nametofieldHashTable.put("DOUBLE116", new Integer(DOUBLE116)); + nametofieldHashTable.put("DOUBLE117", new Integer(DOUBLE117)); + nametofieldHashTable.put("DOUBLE118", new Integer(DOUBLE118)); + nametofieldHashTable.put("DOUBLE119", new Integer(DOUBLE119)); + nametofieldHashTable.put("DOUBLE120", new Integer(DOUBLE120)); + nametofieldHashTable.put("DOUBLE121", new Integer(DOUBLE121)); + nametofieldHashTable.put("DOUBLE122", new Integer(DOUBLE122)); + nametofieldHashTable.put("DOUBLE123", new Integer(DOUBLE123)); + nametofieldHashTable.put("DOUBLE124", new Integer(DOUBLE124)); + nametofieldHashTable.put("DOUBLE125", new Integer(DOUBLE125)); + nametofieldHashTable.put("DOUBLE126", new Integer(DOUBLE126)); + nametofieldHashTable.put("DOUBLE127", new Integer(DOUBLE127)); + nametofieldHashTable.put("DOUBLE128", new Integer(DOUBLE128)); + nametofieldHashTable.put("DOUBLE129", new Integer(DOUBLE129)); + nametofieldHashTable.put("DOUBLE130", new Integer(DOUBLE130)); + nametofieldHashTable.put("DOUBLE131", new Integer(DOUBLE131)); + nametofieldHashTable.put("DOUBLE132", new Integer(DOUBLE132)); + nametofieldHashTable.put("DOUBLE133", new Integer(DOUBLE133)); + nametofieldHashTable.put("DOUBLE134", new Integer(DOUBLE134)); + nametofieldHashTable.put("DOUBLE135", new Integer(DOUBLE135)); + nametofieldHashTable.put("DOUBLE136", new Integer(DOUBLE136)); + nametofieldHashTable.put("DOUBLE137", new Integer(DOUBLE137)); + nametofieldHashTable.put("DOUBLE138", new Integer(DOUBLE138)); + nametofieldHashTable.put("DOUBLE139", new Integer(DOUBLE139)); + nametofieldHashTable.put("DOUBLE140", new Integer(DOUBLE140)); + nametofieldHashTable.put("DOUBLE141", new Integer(DOUBLE141)); + nametofieldHashTable.put("DOUBLE142", new Integer(DOUBLE142)); + nametofieldHashTable.put("DOUBLE143", new Integer(DOUBLE143)); + nametofieldHashTable.put("DOUBLE144", new Integer(DOUBLE144)); + nametofieldHashTable.put("DOUBLE145", new Integer(DOUBLE145)); + nametofieldHashTable.put("DOUBLE146", new Integer(DOUBLE146)); + nametofieldHashTable.put("DOUBLE147", new Integer(DOUBLE147)); + nametofieldHashTable.put("DOUBLE148", new Integer(DOUBLE148)); + nametofieldHashTable.put("DOUBLE149", new Integer(DOUBLE149)); + nametofieldHashTable.put("DOUBLE150", new Integer(DOUBLE150)); + nametofieldHashTable.put("DOUBLE151", new Integer(DOUBLE151)); + nametofieldHashTable.put("DOUBLE152", new Integer(DOUBLE152)); + nametofieldHashTable.put("DOUBLE153", new Integer(DOUBLE153)); + nametofieldHashTable.put("DOUBLE154", new Integer(DOUBLE154)); + nametofieldHashTable.put("DOUBLE155", new Integer(DOUBLE155)); + nametofieldHashTable.put("DOUBLE156", new Integer(DOUBLE156)); + nametofieldHashTable.put("DOUBLE157", new Integer(DOUBLE157)); + nametofieldHashTable.put("DOUBLE158", new Integer(DOUBLE158)); + nametofieldHashTable.put("DOUBLE159", new Integer(DOUBLE159)); + nametofieldHashTable.put("DOUBLE160", new Integer(DOUBLE160)); + nametofieldHashTable.put("DOUBLE161", new Integer(DOUBLE161)); + nametofieldHashTable.put("DOUBLE162", new Integer(DOUBLE162)); + nametofieldHashTable.put("DOUBLE163", new Integer(DOUBLE163)); + nametofieldHashTable.put("DOUBLE164", new Integer(DOUBLE164)); + nametofieldHashTable.put("DOUBLE165", new Integer(DOUBLE165)); + nametofieldHashTable.put("DOUBLE166", new Integer(DOUBLE166)); + nametofieldHashTable.put("DOUBLE167", new Integer(DOUBLE167)); + nametofieldHashTable.put("DOUBLE168", new Integer(DOUBLE168)); + nametofieldHashTable.put("DOUBLE169", new Integer(DOUBLE169)); + nametofieldHashTable.put("DOUBLE170", new Integer(DOUBLE170)); + nametofieldHashTable.put("DOUBLE171", new Integer(DOUBLE171)); + nametofieldHashTable.put("DOUBLE172", new Integer(DOUBLE172)); + nametofieldHashTable.put("DOUBLE173", new Integer(DOUBLE173)); + nametofieldHashTable.put("DOUBLE174", new Integer(DOUBLE174)); + nametofieldHashTable.put("DOUBLE175", new Integer(DOUBLE175)); + nametofieldHashTable.put("DOUBLE176", new Integer(DOUBLE176)); + nametofieldHashTable.put("DOUBLE177", new Integer(DOUBLE177)); + nametofieldHashTable.put("DOUBLE178", new Integer(DOUBLE178)); + nametofieldHashTable.put("DOUBLE179", new Integer(DOUBLE179)); + nametofieldHashTable.put("DOUBLE180", new Integer(DOUBLE180)); + nametofieldHashTable.put("DOUBLE181", new Integer(DOUBLE181)); + nametofieldHashTable.put("DOUBLE182", new Integer(DOUBLE182)); + nametofieldHashTable.put("DOUBLE183", new Integer(DOUBLE183)); + nametofieldHashTable.put("DOUBLE184", new Integer(DOUBLE184)); + nametofieldHashTable.put("DOUBLE185", new Integer(DOUBLE185)); + nametofieldHashTable.put("DOUBLE186", new Integer(DOUBLE186)); + nametofieldHashTable.put("DOUBLE187", new Integer(DOUBLE187)); + nametofieldHashTable.put("DOUBLE188", new Integer(DOUBLE188)); + nametofieldHashTable.put("DOUBLE189", new Integer(DOUBLE189)); + nametofieldHashTable.put("DOUBLE190", new Integer(DOUBLE190)); + nametofieldHashTable.put("DOUBLE191", new Integer(DOUBLE191)); + nametofieldHashTable.put("DOUBLE192", new Integer(DOUBLE192)); + nametofieldHashTable.put("DOUBLE193", new Integer(DOUBLE193)); + nametofieldHashTable.put("DOUBLE194", new Integer(DOUBLE194)); + nametofieldHashTable.put("DOUBLE195", new Integer(DOUBLE195)); + nametofieldHashTable.put("DOUBLE196", new Integer(DOUBLE196)); + nametofieldHashTable.put("DOUBLE197", new Integer(DOUBLE197)); + nametofieldHashTable.put("DOUBLE198", new Integer(DOUBLE198)); + nametofieldHashTable.put("DOUBLE199", new Integer(DOUBLE199)); + nametofieldHashTable.put("DOUBLE200", new Integer(DOUBLE200)); + nametofieldHashTable.put("SVCNAME", new Integer(SVCNAME)); + nametofieldHashTable.put("TPURCODE", new Integer(TPURCODE)); + } + + Integer fld = (Integer)nametofieldHashTable.get(name); + if (fld == null) { + return (-1); + } else { + return (fld.intValue()); + } + } + + public String[] getFldNames() + { + String retval[] = new String[502]; + retval[0] = new String("STRING1"); + retval[1] = new String("STRING2"); + retval[2] = new String("STRING3"); + retval[3] = new String("STRING4"); + retval[4] = new String("STRING5"); + retval[5] = new String("STRING6"); + retval[6] = new String("STRING7"); + retval[7] = new String("STRING8"); + retval[8] = new String("STRING9"); + retval[9] = new String("STRING10"); + retval[10] = new String("STRING11"); + retval[11] = new String("STRING12"); + retval[12] = new String("STRING13"); + retval[13] = new String("STRING14"); + retval[14] = new String("STRING15"); + retval[15] = new String("STRING16"); + retval[16] = new String("STRING17"); + retval[17] = new String("STRING18"); + retval[18] = new String("STRING19"); + retval[19] = new String("STRING20"); + retval[20] = new String("STRING21"); + retval[21] = new String("STRING22"); + retval[22] = new String("STRING23"); + retval[23] = new String("STRING24"); + retval[24] = new String("STRING25"); + retval[25] = new String("STRING26"); + retval[26] = new String("STRING27"); + retval[27] = new String("STRING28"); + retval[28] = new String("STRING29"); + retval[29] = new String("STRING30"); + retval[30] = new String("STRING31"); + retval[31] = new String("STRING32"); + retval[32] = new String("STRING33"); + retval[33] = new String("STRING34"); + retval[34] = new String("STRING35"); + retval[35] = new String("STRING36"); + retval[36] = new String("STRING37"); + retval[37] = new String("STRING38"); + retval[38] = new String("STRING39"); + retval[39] = new String("STRING40"); + retval[40] = new String("STRING41"); + retval[41] = new String("STRING42"); + retval[42] = new String("STRING43"); + retval[43] = new String("STRING44"); + retval[44] = new String("STRING45"); + retval[45] = new String("STRING46"); + retval[46] = new String("STRING47"); + retval[47] = new String("STRING48"); + retval[48] = new String("STRING49"); + retval[49] = new String("STRING50"); + retval[50] = new String("STRING51"); + retval[51] = new String("STRING52"); + retval[52] = new String("STRING53"); + retval[53] = new String("STRING54"); + retval[54] = new String("STRING55"); + retval[55] = new String("STRING56"); + retval[56] = new String("STRING57"); + retval[57] = new String("STRING58"); + retval[58] = new String("STRING59"); + retval[59] = new String("STRING60"); + retval[60] = new String("STRING61"); + retval[61] = new String("STRING62"); + retval[62] = new String("STRING63"); + retval[63] = new String("STRING64"); + retval[64] = new String("STRING65"); + retval[65] = new String("STRING66"); + retval[66] = new String("STRING67"); + retval[67] = new String("STRING68"); + retval[68] = new String("STRING69"); + retval[69] = new String("STRING70"); + retval[70] = new String("STRING71"); + retval[71] = new String("STRING72"); + retval[72] = new String("STRING73"); + retval[73] = new String("STRING74"); + retval[74] = new String("STRING75"); + retval[75] = new String("STRING76"); + retval[76] = new String("STRING77"); + retval[77] = new String("STRING78"); + retval[78] = new String("STRING79"); + retval[79] = new String("STRING80"); + retval[80] = new String("STRING81"); + retval[81] = new String("STRING82"); + retval[82] = new String("STRING83"); + retval[83] = new String("STRING84"); + retval[84] = new String("STRING85"); + retval[85] = new String("STRING86"); + retval[86] = new String("STRING87"); + retval[87] = new String("STRING88"); + retval[88] = new String("STRING89"); + retval[89] = new String("STRING90"); + retval[90] = new String("STRING91"); + retval[91] = new String("STRING92"); + retval[92] = new String("STRING93"); + retval[93] = new String("STRING94"); + retval[94] = new String("STRING95"); + retval[95] = new String("STRING96"); + retval[96] = new String("STRING97"); + retval[97] = new String("STRING98"); + retval[98] = new String("STRING99"); + retval[99] = new String("STRING100"); + retval[100] = new String("STRING101"); + retval[101] = new String("STRING102"); + retval[102] = new String("STRING103"); + retval[103] = new String("STRING104"); + retval[104] = new String("STRING105"); + retval[105] = new String("STRING106"); + retval[106] = new String("STRING107"); + retval[107] = new String("STRING108"); + retval[108] = new String("STRING109"); + retval[109] = new String("STRING110"); + retval[110] = new String("STRING111"); + retval[111] = new String("STRING112"); + retval[112] = new String("STRING113"); + retval[113] = new String("STRING114"); + retval[114] = new String("STRING115"); + retval[115] = new String("STRING116"); + retval[116] = new String("STRING117"); + retval[117] = new String("STRING118"); + retval[118] = new String("STRING119"); + retval[119] = new String("STRING120"); + retval[120] = new String("STRING121"); + retval[121] = new String("STRING122"); + retval[122] = new String("STRING123"); + retval[123] = new String("STRING124"); + retval[124] = new String("STRING125"); + retval[125] = new String("STRING126"); + retval[126] = new String("STRING127"); + retval[127] = new String("STRING128"); + retval[128] = new String("STRING129"); + retval[129] = new String("STRING130"); + retval[130] = new String("STRING131"); + retval[131] = new String("STRING132"); + retval[132] = new String("STRING133"); + retval[133] = new String("STRING134"); + retval[134] = new String("STRING135"); + retval[135] = new String("STRING136"); + retval[136] = new String("STRING137"); + retval[137] = new String("STRING138"); + retval[138] = new String("STRING139"); + retval[139] = new String("STRING140"); + retval[140] = new String("STRING141"); + retval[141] = new String("STRING142"); + retval[142] = new String("STRING143"); + retval[143] = new String("STRING144"); + retval[144] = new String("STRING145"); + retval[145] = new String("STRING146"); + retval[146] = new String("STRING147"); + retval[147] = new String("STRING148"); + retval[148] = new String("STRING149"); + retval[149] = new String("STRING150"); + retval[150] = new String("STRING151"); + retval[151] = new String("STRING152"); + retval[152] = new String("STRING153"); + retval[153] = new String("STRING154"); + retval[154] = new String("STRING155"); + retval[155] = new String("STRING156"); + retval[156] = new String("STRING157"); + retval[157] = new String("STRING158"); + retval[158] = new String("STRING159"); + retval[159] = new String("STRING160"); + retval[160] = new String("STRING161"); + retval[161] = new String("STRING162"); + retval[162] = new String("STRING163"); + retval[163] = new String("STRING164"); + retval[164] = new String("STRING165"); + retval[165] = new String("STRING166"); + retval[166] = new String("STRING167"); + retval[167] = new String("STRING168"); + retval[168] = new String("STRING169"); + retval[169] = new String("STRING170"); + retval[170] = new String("STRING171"); + retval[171] = new String("STRING172"); + retval[172] = new String("STRING173"); + retval[173] = new String("STRING174"); + retval[174] = new String("STRING175"); + retval[175] = new String("STRING176"); + retval[176] = new String("STRING177"); + retval[177] = new String("STRING178"); + retval[178] = new String("STRING179"); + retval[179] = new String("STRING180"); + retval[180] = new String("STRING181"); + retval[181] = new String("STRING182"); + retval[182] = new String("STRING183"); + retval[183] = new String("STRING184"); + retval[184] = new String("STRING185"); + retval[185] = new String("STRING186"); + retval[186] = new String("STRING187"); + retval[187] = new String("STRING188"); + retval[188] = new String("STRING189"); + retval[189] = new String("STRING190"); + retval[190] = new String("STRING191"); + retval[191] = new String("STRING192"); + retval[192] = new String("STRING193"); + retval[193] = new String("STRING194"); + retval[194] = new String("STRING195"); + retval[195] = new String("STRING196"); + retval[196] = new String("STRING197"); + retval[197] = new String("STRING198"); + retval[198] = new String("STRING199"); + retval[199] = new String("STRING200"); + retval[200] = new String("LONG1"); + retval[201] = new String("LONG2"); + retval[202] = new String("LONG3"); + retval[203] = new String("LONG4"); + retval[204] = new String("LONG5"); + retval[205] = new String("LONG6"); + retval[206] = new String("LONG7"); + retval[207] = new String("LONG8"); + retval[208] = new String("LONG9"); + retval[209] = new String("LONG10"); + retval[210] = new String("LONG11"); + retval[211] = new String("LONG12"); + retval[212] = new String("LONG13"); + retval[213] = new String("LONG14"); + retval[214] = new String("LONG15"); + retval[215] = new String("LONG16"); + retval[216] = new String("LONG17"); + retval[217] = new String("LONG18"); + retval[218] = new String("LONG19"); + retval[219] = new String("LONG20"); + retval[220] = new String("LONG21"); + retval[221] = new String("LONG22"); + retval[222] = new String("LONG23"); + retval[223] = new String("LONG24"); + retval[224] = new String("LONG25"); + retval[225] = new String("LONG26"); + retval[226] = new String("LONG27"); + retval[227] = new String("LONG28"); + retval[228] = new String("LONG29"); + retval[229] = new String("LONG30"); + retval[230] = new String("LONG31"); + retval[231] = new String("LONG32"); + retval[232] = new String("LONG33"); + retval[233] = new String("LONG34"); + retval[234] = new String("LONG35"); + retval[235] = new String("LONG36"); + retval[236] = new String("LONG37"); + retval[237] = new String("LONG38"); + retval[238] = new String("LONG39"); + retval[239] = new String("LONG40"); + retval[240] = new String("LONG41"); + retval[241] = new String("LONG42"); + retval[242] = new String("LONG43"); + retval[243] = new String("LONG44"); + retval[244] = new String("LONG45"); + retval[245] = new String("LONG46"); + retval[246] = new String("LONG47"); + retval[247] = new String("LONG48"); + retval[248] = new String("LONG49"); + retval[249] = new String("LONG50"); + retval[250] = new String("LONG51"); + retval[251] = new String("LONG52"); + retval[252] = new String("LONG53"); + retval[253] = new String("LONG54"); + retval[254] = new String("LONG55"); + retval[255] = new String("LONG56"); + retval[256] = new String("LONG57"); + retval[257] = new String("LONG58"); + retval[258] = new String("LONG59"); + retval[259] = new String("LONG60"); + retval[260] = new String("LONG61"); + retval[261] = new String("LONG62"); + retval[262] = new String("LONG63"); + retval[263] = new String("LONG64"); + retval[264] = new String("LONG65"); + retval[265] = new String("LONG66"); + retval[266] = new String("LONG67"); + retval[267] = new String("LONG68"); + retval[268] = new String("LONG69"); + retval[269] = new String("LONG70"); + retval[270] = new String("LONG71"); + retval[271] = new String("LONG72"); + retval[272] = new String("LONG73"); + retval[273] = new String("LONG74"); + retval[274] = new String("LONG75"); + retval[275] = new String("LONG76"); + retval[276] = new String("LONG77"); + retval[277] = new String("LONG78"); + retval[278] = new String("LONG79"); + retval[279] = new String("LONG80"); + retval[280] = new String("LONG81"); + retval[281] = new String("LONG82"); + retval[282] = new String("LONG83"); + retval[283] = new String("LONG84"); + retval[284] = new String("LONG85"); + retval[285] = new String("LONG86"); + retval[286] = new String("LONG87"); + retval[287] = new String("LONG88"); + retval[288] = new String("LONG89"); + retval[289] = new String("LONG90"); + retval[290] = new String("LONG91"); + retval[291] = new String("LONG92"); + retval[292] = new String("LONG93"); + retval[293] = new String("LONG94"); + retval[294] = new String("LONG95"); + retval[295] = new String("LONG96"); + retval[296] = new String("LONG97"); + retval[297] = new String("LONG98"); + retval[298] = new String("LONG99"); + retval[299] = new String("LONG100"); + retval[300] = new String("DOUBLE1"); + retval[301] = new String("DOUBLE2"); + retval[302] = new String("DOUBLE3"); + retval[303] = new String("DOUBLE4"); + retval[304] = new String("DOUBLE5"); + retval[305] = new String("DOUBLE6"); + retval[306] = new String("DOUBLE7"); + retval[307] = new String("DOUBLE8"); + retval[308] = new String("DOUBLE9"); + retval[309] = new String("DOUBLE10"); + retval[310] = new String("DOUBLE11"); + retval[311] = new String("DOUBLE12"); + retval[312] = new String("DOUBLE13"); + retval[313] = new String("DOUBLE14"); + retval[314] = new String("DOUBLE15"); + retval[315] = new String("DOUBLE16"); + retval[316] = new String("DOUBLE17"); + retval[317] = new String("DOUBLE18"); + retval[318] = new String("DOUBLE19"); + retval[319] = new String("DOUBLE20"); + retval[320] = new String("DOUBLE21"); + retval[321] = new String("DOUBLE22"); + retval[322] = new String("DOUBLE23"); + retval[323] = new String("DOUBLE24"); + retval[324] = new String("DOUBLE25"); + retval[325] = new String("DOUBLE26"); + retval[326] = new String("DOUBLE27"); + retval[327] = new String("DOUBLE28"); + retval[328] = new String("DOUBLE29"); + retval[329] = new String("DOUBLE30"); + retval[330] = new String("DOUBLE31"); + retval[331] = new String("DOUBLE32"); + retval[332] = new String("DOUBLE33"); + retval[333] = new String("DOUBLE34"); + retval[334] = new String("DOUBLE35"); + retval[335] = new String("DOUBLE36"); + retval[336] = new String("DOUBLE37"); + retval[337] = new String("DOUBLE38"); + retval[338] = new String("DOUBLE39"); + retval[339] = new String("DOUBLE40"); + retval[340] = new String("DOUBLE41"); + retval[341] = new String("DOUBLE42"); + retval[342] = new String("DOUBLE43"); + retval[343] = new String("DOUBLE44"); + retval[344] = new String("DOUBLE45"); + retval[345] = new String("DOUBLE46"); + retval[346] = new String("DOUBLE47"); + retval[347] = new String("DOUBLE48"); + retval[348] = new String("DOUBLE49"); + retval[349] = new String("DOUBLE50"); + retval[350] = new String("DOUBLE51"); + retval[351] = new String("DOUBLE52"); + retval[352] = new String("DOUBLE53"); + retval[353] = new String("DOUBLE54"); + retval[354] = new String("DOUBLE55"); + retval[355] = new String("DOUBLE56"); + retval[356] = new String("DOUBLE57"); + retval[357] = new String("DOUBLE58"); + retval[358] = new String("DOUBLE59"); + retval[359] = new String("DOUBLE60"); + retval[360] = new String("DOUBLE61"); + retval[361] = new String("DOUBLE62"); + retval[362] = new String("DOUBLE63"); + retval[363] = new String("DOUBLE64"); + retval[364] = new String("DOUBLE65"); + retval[365] = new String("DOUBLE66"); + retval[366] = new String("DOUBLE67"); + retval[367] = new String("DOUBLE68"); + retval[368] = new String("DOUBLE69"); + retval[369] = new String("DOUBLE70"); + retval[370] = new String("DOUBLE71"); + retval[371] = new String("DOUBLE72"); + retval[372] = new String("DOUBLE73"); + retval[373] = new String("DOUBLE74"); + retval[374] = new String("DOUBLE75"); + retval[375] = new String("DOUBLE76"); + retval[376] = new String("DOUBLE77"); + retval[377] = new String("DOUBLE78"); + retval[378] = new String("DOUBLE79"); + retval[379] = new String("DOUBLE80"); + retval[380] = new String("DOUBLE81"); + retval[381] = new String("DOUBLE82"); + retval[382] = new String("DOUBLE83"); + retval[383] = new String("DOUBLE84"); + retval[384] = new String("DOUBLE85"); + retval[385] = new String("DOUBLE86"); + retval[386] = new String("DOUBLE87"); + retval[387] = new String("DOUBLE88"); + retval[388] = new String("DOUBLE89"); + retval[389] = new String("DOUBLE90"); + retval[390] = new String("DOUBLE91"); + retval[391] = new String("DOUBLE92"); + retval[392] = new String("DOUBLE93"); + retval[393] = new String("DOUBLE94"); + retval[394] = new String("DOUBLE95"); + retval[395] = new String("DOUBLE96"); + retval[396] = new String("DOUBLE97"); + retval[397] = new String("DOUBLE98"); + retval[398] = new String("DOUBLE99"); + retval[399] = new String("DOUBLE100"); + retval[400] = new String("DOUBLE101"); + retval[401] = new String("DOUBLE102"); + retval[402] = new String("DOUBLE103"); + retval[403] = new String("DOUBLE104"); + retval[404] = new String("DOUBLE105"); + retval[405] = new String("DOUBLE106"); + retval[406] = new String("DOUBLE107"); + retval[407] = new String("DOUBLE108"); + retval[408] = new String("DOUBLE109"); + retval[409] = new String("DOUBLE110"); + retval[410] = new String("DOUBLE111"); + retval[411] = new String("DOUBLE112"); + retval[412] = new String("DOUBLE113"); + retval[413] = new String("DOUBLE114"); + retval[414] = new String("DOUBLE115"); + retval[415] = new String("DOUBLE116"); + retval[416] = new String("DOUBLE117"); + retval[417] = new String("DOUBLE118"); + retval[418] = new String("DOUBLE119"); + retval[419] = new String("DOUBLE120"); + retval[420] = new String("DOUBLE121"); + retval[421] = new String("DOUBLE122"); + retval[422] = new String("DOUBLE123"); + retval[423] = new String("DOUBLE124"); + retval[424] = new String("DOUBLE125"); + retval[425] = new String("DOUBLE126"); + retval[426] = new String("DOUBLE127"); + retval[427] = new String("DOUBLE128"); + retval[428] = new String("DOUBLE129"); + retval[429] = new String("DOUBLE130"); + retval[430] = new String("DOUBLE131"); + retval[431] = new String("DOUBLE132"); + retval[432] = new String("DOUBLE133"); + retval[433] = new String("DOUBLE134"); + retval[434] = new String("DOUBLE135"); + retval[435] = new String("DOUBLE136"); + retval[436] = new String("DOUBLE137"); + retval[437] = new String("DOUBLE138"); + retval[438] = new String("DOUBLE139"); + retval[439] = new String("DOUBLE140"); + retval[440] = new String("DOUBLE141"); + retval[441] = new String("DOUBLE142"); + retval[442] = new String("DOUBLE143"); + retval[443] = new String("DOUBLE144"); + retval[444] = new String("DOUBLE145"); + retval[445] = new String("DOUBLE146"); + retval[446] = new String("DOUBLE147"); + retval[447] = new String("DOUBLE148"); + retval[448] = new String("DOUBLE149"); + retval[449] = new String("DOUBLE150"); + retval[450] = new String("DOUBLE151"); + retval[451] = new String("DOUBLE152"); + retval[452] = new String("DOUBLE153"); + retval[453] = new String("DOUBLE154"); + retval[454] = new String("DOUBLE155"); + retval[455] = new String("DOUBLE156"); + retval[456] = new String("DOUBLE157"); + retval[457] = new String("DOUBLE158"); + retval[458] = new String("DOUBLE159"); + retval[459] = new String("DOUBLE160"); + retval[460] = new String("DOUBLE161"); + retval[461] = new String("DOUBLE162"); + retval[462] = new String("DOUBLE163"); + retval[463] = new String("DOUBLE164"); + retval[464] = new String("DOUBLE165"); + retval[465] = new String("DOUBLE166"); + retval[466] = new String("DOUBLE167"); + retval[467] = new String("DOUBLE168"); + retval[468] = new String("DOUBLE169"); + retval[469] = new String("DOUBLE170"); + retval[470] = new String("DOUBLE171"); + retval[471] = new String("DOUBLE172"); + retval[472] = new String("DOUBLE173"); + retval[473] = new String("DOUBLE174"); + retval[474] = new String("DOUBLE175"); + retval[475] = new String("DOUBLE176"); + retval[476] = new String("DOUBLE177"); + retval[477] = new String("DOUBLE178"); + retval[478] = new String("DOUBLE179"); + retval[479] = new String("DOUBLE180"); + retval[480] = new String("DOUBLE181"); + retval[481] = new String("DOUBLE182"); + retval[482] = new String("DOUBLE183"); + retval[483] = new String("DOUBLE184"); + retval[484] = new String("DOUBLE185"); + retval[485] = new String("DOUBLE186"); + retval[486] = new String("DOUBLE187"); + retval[487] = new String("DOUBLE188"); + retval[488] = new String("DOUBLE189"); + retval[489] = new String("DOUBLE190"); + retval[490] = new String("DOUBLE191"); + retval[491] = new String("DOUBLE192"); + retval[492] = new String("DOUBLE193"); + retval[493] = new String("DOUBLE194"); + retval[494] = new String("DOUBLE195"); + retval[495] = new String("DOUBLE196"); + retval[496] = new String("DOUBLE197"); + retval[497] = new String("DOUBLE198"); + retval[498] = new String("DOUBLE199"); + retval[499] = new String("DOUBLE200"); + retval[500] = new String("SVCNAME"); + retval[501] = new String("TPURCODE"); + return retval; + } + + public int getVersion() { + return 1; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/jtc/JtcBeanSample.java b/src/main/java/com/eactive/eai/adapter/jtc/JtcBeanSample.java new file mode 100644 index 0000000..705afc9 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/jtc/JtcBeanSample.java @@ -0,0 +1,84 @@ +package com.eactive.eai.adapter.jtc; + +import tmax.common.BufferAccess; +import tmax.jtc.io.TuxCarrayBuffer; +import tmax.jtc.io.TuxFieldBuffer; +import tmax.jtc.io.TuxStringBuffer; +import tmax.jtmax.JtmaxService; +import tmax.webt.WebtException; +import tmax.webt.WebtSystem; + +// TUXEDO -> JEUS +//1.2.2. Bean 서비스 호출 설정 +// JTC 인바운드 통신을 통해 Bean 서비스를 호출하려면 다음과 같은 설정이 필요하다. +// +// webt.properties 설정 ($JEUS_HOME/lib/application) +//JEUS SIDE +//webt.properties +//tux.beans.service.list = GSVC02 +//tux.beans.GSVC02.class = test.JtcBeanSample +// Tuxedo 환경설정 +//TUX Side +//*SERVICE +//GSVC02 +// Tuxedo 도메인 환경설정 +//*DM_REMOTE_SERVICES +//GSVC01 +// RNAME = "GSVC01" +// RDOM = "TUXGW1" +// +//*DM_TDOMAIN +//TUXGW1 NWADDR = "//192.168.37.100:9521" +// JEUS와 Tuxedo 기동 + +public class JtcBeanSample implements JtmaxService { + + public void destroy() throws Exception { + + } + + public void initialize() throws Exception { + + } + + public BufferAccess service(BufferAccess tux) throws WebtException { + String bufferType = tux.getBufferTypeString(); + if ("STRING".equals(bufferType)) { + TuxStringBuffer tuxbuf = (TuxStringBuffer) tux; + System.out.println("received string value : " + tuxbuf.getString()); + TuxStringBuffer ret = new TuxStringBuffer(WebtSystem.getDefaultCharset()); + ret.setString(tuxbuf.getString().toUpperCase()); + return ret; + } else if ("CARRAY".equals(bufferType)) { + TuxCarrayBuffer tuxbuf = (TuxCarrayBuffer) tux; + String rcvstr = null; + try { + rcvstr = new String( tuxbuf.getBytes(), WebtSystem.getDefaultCharset()); + } + catch(Exception ex) { + throw new WebtException(ex.getMessage()); + } + + String rtnstr = rcvstr.toUpperCase(); + System.out.println("received string value : " + rcvstr); + System.out.println("return string value : " + rtnstr); + TuxCarrayBuffer ret = new TuxCarrayBuffer(WebtSystem.getDefaultCharset()); + ret.setBytes(rtnstr.getBytes());; + return ret; + } else { + TuxFieldBuffer tuxbuf = (TuxFieldBuffer) tux; + // sample table = new sample(); + // String rcvstr = + // tuxbuf.getField(table.fml_sec100).get().stringValue(); + + String rcvstr = tuxbuf.getField("SEC100").get().stringValue(); + String rtnstr = rcvstr.toUpperCase(); + System.out.println("received string value : " + rcvstr); + System.out.println("return string value : " + rtnstr); + TuxFieldBuffer ret = new TuxFieldBuffer(false); // FML 16임으로 false로 + // ret.createField(sample.fml_sec2).add(rtnstr); + ret.createField("SEC2").add(rtnstr); + return ret; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/jtc/JtcClientAdapter.java b/src/main/java/com/eactive/eai/adapter/jtc/JtcClientAdapter.java new file mode 100644 index 0000000..9f683e4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/jtc/JtcClientAdapter.java @@ -0,0 +1,160 @@ +package com.eactive.eai.adapter.jtc; + +import com.eactive.eai.adapter.ElinkDefaultAdapter; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.Logger; +import tmax.jtc.TuxService; +import tmax.jtc.io.TuxBuffer; +import tmax.jtc.io.TuxCallDescripter; +import tmax.jtc.io.TuxFieldBuffer; + +import java.util.Properties; + +public class JtcClientAdapter extends ElinkDefaultAdapter { + private static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public static final String ADAPTER_GORUP_NAME="ADAPTER_GROUP_NAME"; + + public static final String DOMAIN_NAME = "domain.name"; + public static final String SERVICE_NAME = "service.name"; + public static final String BUFFER_TYPE = "buffer.type"; // CARRAY | STRING | FML | FML32 + public static final String DEFAULT_BUFFER_TYPE = "CARRAY"; + public static final String RESPONSE_TYPE = "response.type"; + + + /** + * 1. 기능 : HttpClientAdapter default 생성자 + * 2. 처리 개요 : + * - property 정보를 가져와 MultiThreadedHttpConnectionManager 속성 설정 + * - HttpClient의 instance 생성 + * 3. 주의사항 + * + **/ + public JtcClientAdapter() { + super(); + } + + /** + * 1. 기능 : 전문과 같은 Raw Data 통신에 사용 + * 2. 처리 개요 : + * - 속성 정보를 설정 하고 수동 시스템 서비스를 호출 한다. + * 3. 주의사항 + * + * @param prop WebT Adapter properties 속성 정보 + * @param message 송신 전문 + * @return 반환 된 byte[] Object + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + // -Dwebt.properties= + public Object execute(Properties prop, Object message) throws Exception + { +// String adapterGroupName = prop.getProperty(ADAPTER_GORUP_NAME); +// String adapterName = prop.getProperty("adapterName"); + + byte[] data = null; + if(message instanceof byte[]) { + data = (byte[])message; + } else if( message instanceof String) { + data = ((String)message).getBytes(); + } else { + throw new Exception("RECEAIAHA011"); + } + + String domainName = prop.getProperty(DOMAIN_NAME,"TDOM"); + String serviceName = prop.getProperty(SERVICE_NAME,"SEAIRECV"); + String bufferType = prop.getProperty(BUFFER_TYPE, DEFAULT_BUFFER_TYPE); + String responseType = prop.getProperty(RESPONSE_TYPE,"SYNC"); + + try{ + + TuxService service = new TuxService(domainName, serviceName); + + if (logger.isDebug()){ + logger.debug("JtcClientAdapter] ServiceName "+"["+serviceName+"]"); + } + + + if (logger.isDebug()){ + logger.debug("JtcClientAdapter] Send Data "+"["+new String(data)+"]"); + logger.debug("JtcClientAdapter] Send Data dump "+CommonLib.getDumpMessage(data)); + + } + + if (logger.isDebug()){ + logger.debug("JtcClientAdapter] BUFFER_TYPE "+"["+bufferType+"]"); + } + TuxBuffer sndbuf = null; + if(DEFAULT_BUFFER_TYPE.equals(bufferType)) { + sndbuf = service.createCarrayBuffer(); + sndbuf.setBytes(data); + } + else if("STRING".equals(bufferType)) { + sndbuf = service.createStringBuffer(); + sndbuf.setString(new String(data)); + } + else if("FML".equals(bufferType)) { + // TODO : create table class + // JSON to FML conversion + // -> make Converter class (JSON -> FML) +// sndbuf = service.createFieldBuffer(false, tuxFieldTable); + sndbuf = new TuxFieldBuffer(false); + sndbuf.createField("REQUEST").add(new String(data)); + } + else if("FML32".equals(bufferType)) { + sndbuf = new TuxFieldBuffer(true); + sndbuf.createField("REQUEST").add(new String(data)); + } + else { + throw new Exception("Invalid buffer.type ="+ bufferType); + } + + if ("ASYN".equals(responseType)){ + + TuxCallDescripter d = service.tpacall(sndbuf); + data = null; + if (logger.isDebug()){ + logger.debug("JtcClientAdapter] Recv Data Async "+"["+d.toString()+"]"); + } + }else{ + TuxBuffer rcvbuf = service.tpcall(sndbuf); + + if(DEFAULT_BUFFER_TYPE.equals(bufferType)) { + byte[] response = rcvbuf.getBytes(); + data = response; + } + else if("STRING".equals(bufferType)) { + String response = rcvbuf.getString(); + data = response.getBytes(); + } + else if("FML".equals(bufferType)) { + // TODO : FML to JSON conversion + String response =rcvbuf.getField("RESPONSE").get().stringValue(); + data = response.getBytes(); + } + else if("FML32".equals(bufferType)) { + String response =rcvbuf.getField("RESPONSE").get().stringValue(); + data = response.getBytes(); + } + + if (logger.isDebug()){ + logger.debug("JtcClientAdapter] Recv Data Sync "+"["+new String(data)+"]"); + logger.debug("JtcClientAdapter] Recv Data dump "+CommonLib.getDumpMessage(data)); + } + } + } catch (Exception e){ + try { + String errorCode = "RECEAIOWT001"; + String addMsg = ", "+e.getMessage()+",["+prop.getProperty(DOMAIN_NAME)+":"+prop.getProperty(SERVICE_NAME)+"]"; + SMSLogger.loggingSMSWithCode(errorCode, addMsg); + } catch(Throwable t){ + logger.error("[EAIDEBUG] SMS logging Error occured. but ignore this. - " + t.toString()); + } + throw e; + }finally{ + + } + + return data; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/jtc/JtcClientSample.java b/src/main/java/com/eactive/eai/adapter/jtc/JtcClientSample.java new file mode 100644 index 0000000..dd90520 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/jtc/JtcClientSample.java @@ -0,0 +1,100 @@ +package com.eactive.eai.adapter.jtc; + +import tmax.jtc.TuxService; +import tmax.jtc.io.TuxBuffer; +import tmax.webt.WebtException; + +// JEUS -> TUXEDO +//11. JEUS lifecycle-invocation 등록하기 +// +//JEUSMain.xml 파일 +// +// +// +// tmax.jtc.external.TuxBootstrapper +// +// +// init +// +// java.lang.String +// +// +// /user/barami/jeus5/lib/application/jtc.properties +// +//BOOT +// +// +// +// +// +// +// +//12. jtc.properties 환경파일 설정으로 primary의 경우 barami 계정의 tuxedo이고 backup의 경우chnam 계정의 tuxedo이다. +// +// +//log.level=debug +//log.dir=/user/barami/jeus5/logs/ +//log.file=jtc1.log +//log.bufsize=1024 +// +// +//tux.local.name=DM_M1_10 +//tux.remote.name.list=DM_A1_10,DM_A1_20 +//tux.default.remote=DM_A1_10 +// +// +//tux.buffer.size=1024 +//tux.default.timeout=60 +//tux.default.txtimeout=300 +// +// +//# Primary Tuxedo Server Setting +// +// +//tux.DM_A1_10.addr=192.167.10.48 +//tux.DM_A1_10.port=20010 +//tux.DM_A1_10.interval=10 +//tux.DM_A1_10.backup=DM_A1_20 +// +// +//# Backup Tuxedo Server Setting +// +// +//tux.DM_A1_20.addr=192.167.10.48 +//tux.DM_A1_20.port=20020 +//tux.DM_A1_20.interval=10 + + +public class JtcClientSample { + + public static void main(String[] args) { + TuxService service = new TuxService("TUXDOM", "SAMPLE"); +// TuxCallDescripter cd = service.tpconnect(false); + + try { +// if(cd == null) { + System.out.println("tpconnect failed!"); +// } +// else { + +// TuxBuffer sndbuf = service.createCarrayBuffer(); +// sndbuf.setBytes("test".getBytes()); + + TuxBuffer sndbuf = service.createStringBuffer(); + sndbuf.setString("conversation service"); + + TuxBuffer rcvbuf = service.tpcall(sndbuf); + System.out.println(rcvbuf.getString()); +// } + } + catch (WebtException e) { + e.printStackTrace(); + System.out.println("error Occurred"); + + } + finally { +// service.tpdiscon(cd); + } + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/jtc/JtcServerAdapterBean.java b/src/main/java/com/eactive/eai/adapter/jtc/JtcServerAdapterBean.java new file mode 100644 index 0000000..74ccd59 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/jtc/JtcServerAdapterBean.java @@ -0,0 +1,113 @@ +package com.eactive.eai.adapter.jtc; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.RequestDispatcher; +import com.eactive.eai.common.util.Logger; +import tmax.common.BufferAccess; +import tmax.jtc.io.TuxCarrayBuffer; +import tmax.jtc.io.TuxFieldBuffer; +import tmax.jtc.io.TuxStringBuffer; +import tmax.jtmax.JtmaxService; +import tmax.webt.WebtException; +import tmax.webt.WebtSystem; + +import java.util.Properties; + +// TUXEDO -> JEUS +//1.2.2. Bean 서비스 호출 설정 +// JTC 인바운드 통신을 통해 Bean 서비스를 호출하려면 다음과 같은 설정이 필요하다. +// +// webt.properties 설정 ($JEUS_HOME/lib/application) +//JEUS SIDE +//webt.properties +//tux.beans.service.list = GSVC02 +//tux.beans.GSVC02.class = test.JtcBeanSample +// Tuxedo 환경설정 +//TUX Side +//*SERVICE +//GSVC02 +// Tuxedo 도메인 환경설정 +//*DM_REMOTE_SERVICES +//GSVC01 +// RNAME = "GSVC01" +// RDOM = "TUXGW1" +// +//*DM_TDOMAIN +//TUXGW1 NWADDR = "//192.168.37.100:9521" +// JEUS와 Tuxedo 기동 + +public class JtcServerAdapterBean implements JtmaxService { + + public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + private String adapterGroupName = "JTC_INBOUND"; + private String adapterName = "JTC_INBOUND"; + + public void destroy() throws Exception { + + } + + public void initialize() throws Exception { + + } + + public BufferAccess service(BufferAccess tux) throws WebtException { + String bufferType = tux.getBufferTypeString(); + + AdapterPropManager pmanager = AdapterPropManager.getInstance(); + Properties prop = pmanager.getProperties(adapterName); + try { + if ("STRING".equals(bufferType)) { + TuxStringBuffer tuxbuf = (TuxStringBuffer) tux; + System.out.println("received string value : " + tuxbuf.getString()); + byte[] request = tuxbuf.getString().getBytes(); + RequestDispatcher dispatcher = RequestDispatcher.getRequestDispatcher(adapterGroupName); + byte[] response = (byte[]) dispatcher.handle(adapterName, request, prop); + + TuxStringBuffer ret = new TuxStringBuffer(WebtSystem.getDefaultCharset()); + ret.setString(new String(response)); + return ret; + } else if ("CARRAY".equals(bufferType)) { + TuxCarrayBuffer tuxbuf = (TuxCarrayBuffer) tux; + String rcvstr = null; + try { + rcvstr = new String( tuxbuf.getBytes(), WebtSystem.getDefaultCharset()); + } + catch(Exception ex) { + throw new WebtException(ex.getMessage()); + } + + byte[] request = tuxbuf.getBytes(); + RequestDispatcher dispatcher = RequestDispatcher.getRequestDispatcher(adapterGroupName); + byte[] response = (byte[]) dispatcher.handle(adapterName, request, prop); + + TuxCarrayBuffer ret = new TuxCarrayBuffer(WebtSystem.getDefaultCharset()); + ret.setBytes(response);; + return ret; + } else { + TuxFieldBuffer tuxbuf = (TuxFieldBuffer) tux; + // sample table = new sample(); + // String rcvstr = + // tuxbuf.getField(table.fml_sec100).get().stringValue(); + +// String rcvstr = tuxbuf.getField("SEC100").get().stringValue(); +// String rtnstr = rcvstr.toUpperCase(); +// System.out.println("received string value : " + rcvstr); +// System.out.println("return string value : " + rtnstr); + + byte[] request = tuxbuf.getBytes(); + RequestDispatcher dispatcher = RequestDispatcher.getRequestDispatcher(adapterGroupName); + byte[] response = (byte[]) dispatcher.handle(adapterName, request, prop); + + + TuxFieldBuffer ret = new TuxFieldBuffer(false); // FML 16임으로 false로 + // ret.createField(sample.fml_sec2).add(rtnstr); +// ret.createField("SEC2").add(rtnstr); + return ret; + } + } + catch(Exception ex) { + logger.error("JtcServerAdapter] exception - ", ex); + throw new WebtException(ex.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/jtc/TestMsgListener.java b/src/main/java/com/eactive/eai/adapter/jtc/TestMsgListener.java new file mode 100644 index 0000000..6ed12d0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/jtc/TestMsgListener.java @@ -0,0 +1,48 @@ +package com.eactive.eai.adapter.jtc; + +import tmax.jtc.TuxAsyncMsgListener; +import tmax.jtc.TuxAsyncService; +import tmax.jtc.io.TuxBuffer; + +import javax.transaction.xa.Xid; + + +// 비동기요청(JEUS->TUXEDO tpacall)에 대한 비동기 응답을 받을 경우 사용 +//TmaxXid xid = new TmaxXid(1,4,0); +//TuxAsyncService service = new TuxAsyncService("TUXGW1","TUX_INSERT"); +//try { +// service.getXAResource().start(xid, 0); +//} +//catch (XAException e) { +// +// e.printStackTrace(); +//} +//TuxBuffer input = service.createStringBuffer(); +//input.setString("abc"); +//TuxAsyncMsgListener listener = new TestMsgListener(service, xid); +//service.tpacall(input, null, listener ); + +public class TestMsgListener implements TuxAsyncMsgListener { + TuxAsyncService service; + Xid xid; + public TestMsgListener(TuxAsyncService service, Xid xid) { + this.service = service; + this.xid = xid; + } + + public void handleError(Exception e) { + System.out.println(e); + } + + public void handleEvent(TuxBuffer rcvBuffer) { + System.out.println(Thread.currentThread().getName() + +" ] rcv " + rcvBuffer); + try { + // TODO : Call Internal service + } + catch (Exception e) { + e.printStackTrace(); + } + } +} + \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/jtc/TuxBufferConverter.java b/src/main/java/com/eactive/eai/adapter/jtc/TuxBufferConverter.java new file mode 100644 index 0000000..bf8df2c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/jtc/TuxBufferConverter.java @@ -0,0 +1,225 @@ +package com.eactive.eai.adapter.jtc; + +public class TuxBufferConverter { + private static boolean DEBUG = true; + + //-------------------------------------------------------------------- + // TODO : table class 로 변경해야 함. + //-------------------------------------------------------------------- + // java -cp ..\webtJtc.jar tmax.webt.util.TuxFieldGen -32 com.eactive.eai.adapter.jtc FieldTable +// private static ConcurrentHashMap keyMap = new ConcurrentHashMap(); +// private static ConcurrentHashMap nameMap = new ConcurrentHashMap(); +// static { +// keyMap.put("STRING1", 167772461); +// keyMap.put("STRING2", 167772462); +// keyMap.put("LONG1", 33554933); +// +// nameMap.put(167772461, "STRING1"); +// nameMap.put(167772462, "STRING2"); +// nameMap.put(33554933, "LONG1"); +// } + +// private static FmlTable table = new FmlTable(); +// +// public static int getFldKeyFromFieldName(String fieldName) { +// int fldKey = -1; +// try { +// +//// fldKey = keyMap.get(fieldName); +// fldKey = table.getFieldId(fieldName); +// } +// catch(Exception e) { +// printLog("Invalid Field Name - " + fieldName); +// } +// return fldKey; +// } +// +// public static String getFieldNameFromFldKey(int fldKey) { +// String fieldName = "UNKNOWN"; +// try { +//// fieldName = nameMap.get(fldKey); +// +// fieldName = table.getFieldName(fldKey); +// } +// catch(Exception e) { +// printLog("Invalid Field Key - " + fldKey); +// } +// return fieldName; +// } +// //-------------------------------------------------------------------- +// +// private static void setDebug(boolean debug) { +// DEBUG = debug; +// } +// private static void printLog(String message) { +// if(DEBUG) { +// System.out.println(message); +// } +// } +// +// +// public static TuxFieldBuffer setJsonArrayToFml(TuxFieldBuffer tuxBuffer, String fieldName, JSONArray jsonFieldArray) { +// for(int i=0; i fieldKeyMap = new HashMap(); +// +// // TODO : convert TuxFieldBuffer to Json +// TuxFieldTable table = tuxBuffer.getFieldTable(); +// Vector fNamesVt = tuxBuffer.getFieldKeyNames(); +// if(fNamesVt == null) { +// Iterator it = tuxBuffer.getAllElementsIterator(); +// int pos = 0; +// +// JSONArray jsonFieldArray = null; +// +// while(it.hasNext()) { +// WebtFieldElement fieldElement = (WebtFieldElement)it.next(); +// WebtField f = fieldElement.getField(); +// printLog("Field [" + (pos++) + "]-> " + f); +// +// int fieldType = f.getFieldType(); +// +// printLog("FieldKey : " + f.getFieldKey()); +// printLog("FieldType : " + f.getFieldType()); +// +// +// if(fieldKeyMap.containsKey(f.getFieldKey())) { +// printLog("SKIP FieldKey : " + f.getFieldKey()); +// continue; +// } +// +// String fieldName = getFieldNameFromFldKey(f.getFieldKey()); +// +// fieldKeyMap.put(f.getFieldKey(), fieldName); +// +// +// Enumeration fe = f.getFieldEnumeration(); +// +// StringBuffer buf = new StringBuffer(); +// +// buf.append("data : "); +// jsonFieldArray = (JSONArray)message.get(fieldName); +// +// if(jsonFieldArray == null) { +// jsonFieldArray = new JSONArray(); +// } +// while (fe.hasMoreElements()) { +// WebtFieldElement e = (WebtFieldElement) fe.nextElement(); +// +// if (e == null) { +// buf.append("[]"); +// } else { +// switch (fieldType) { +// case 1 : +//// printLog(" >> byteValue : " + e.byteValue()); +// buf.append("[").append(e.byteValue()).append("]"); +// jsonFieldArray.add(e.byteValue()); +// break; +// case 2 : +//// printLog(" >> WebtFieldElement : " + e.shortValue()); +// buf.append("[").append(e.shortValue()).append("]"); +// jsonFieldArray.add(e.shortValue()); +// break; +// case 3 : +// case 4 : +//// printLog(" >> intValue : " + e.intValue()); +// buf.append("[").append(e.intValue()).append("]"); +// jsonFieldArray.add(e.intValue()); +// break; +// case 5 : +//// printLog(" >> floatValue : " + e.floatValue()); +// buf.append("[").append(e.floatValue()).append("]"); +// jsonFieldArray.add(e.floatValue()); +// break; +// case 6 : +//// printLog(" >> doubleValue : " + e.doubleValue()); +// buf.append("[").append(e.doubleValue()).append("]"); +// jsonFieldArray.add(e.doubleValue()); +// break; +// case 7 : +//// printLog(" >> stringValue : " + e.stringValue(f.getDefaultCharset())); +// buf.append("[").append(e.stringValue(f.getDefaultCharset())).append("]"); +// jsonFieldArray.add(e.stringValue(f.getDefaultCharset())); +// break; +// case 8 : +//// printLog(" >> bytesValue : " + e.bytesValue()); +// buf.append("[").append(e.bytesValue()).append("]"); +// jsonFieldArray.add(e.bytesValue()); +// +// } +// } +// message.put(fieldName, jsonFieldArray); +// } +// printLog("data : " + buf.toString()); +// +// } +// } +// else { +// for(int i=0; i listenerMap = new ConcurrentHashMap<>(); + static { + listenerMap.put("HTC-I", "com.eactive.eai.adapter.http.dynamic.HttpAdapterListener"); + listenerMap.put("HTT-O", "com.eactive.eai.adapter.http.client.HttpClientAdapterListener"); + listenerMap.put("RST-O", "com.eactive.eai.adapter.http.client.HttpClientAdapterListener"); + listenerMap.put("NET-I", "com.eactive.eai.adapter.socket2.SocketAdapterListener"); + listenerMap.put("NET-O", "com.eactive.eai.adapter.socket2.SocketAdapterListener"); + listenerMap.put("WBT-I", "com.eactive.eai.adapter.webt.WebTAsyncServerAdapterListener"); + listenerMap.put("WBT-O", "com.eactive.eai.adapter.webt.WebTClientAdapterListener"); + listenerMap.put("AMQ-I", "com.eactive.eai.adapter.amq.AMQAdapterListener"); + listenerMap.put("AMQ-O", "com.eactive.eai.adapter.amq.AMQAdapterListener"); + listenerMap.put("DBQ-I", "com.eactive.eai.adapter.db.sql.DBInboudSqlAdapterListener"); + listenerMap.put("WSK-I", "com.eactive.eai.adapter.websocket.WebSocketAdapterListener"); + } + + private ListenerUtil() { + super(); + } + + public static String getDefaultListenerClass(String adapterType, String ioType) { + String listenerClass = null; + String key = adapterType + "-" + ioType; + listenerClass = listenerMap.get(key); + return listenerClass; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/mapper/AdapterGroupMapper.java b/src/main/java/com/eactive/eai/adapter/mapper/AdapterGroupMapper.java new file mode 100644 index 0000000..2f11861 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/mapper/AdapterGroupMapper.java @@ -0,0 +1,43 @@ +package com.eactive.eai.adapter.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.data.entity.onl.adapter.AdapterGroup; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; +import com.eactive.eai.data.mapper.StringToBooleanMapper; +import com.eactive.eai.data.mapper.StringTrimMapper; + +@Mapper(config = BaseMapperConfig.class) +public interface AdapterGroupMapper extends GenericMapper { + + @Mapping(source = "adptrbzwkgroupname", target = "name") + @Mapping(source = "adptrmsgptrncd", target = "adptrMsgPtrnCd") + @Mapping(source = "eaibzwkdstcd", target = "eaiBizCode") + @Mapping(source = "adptrcd", target = "type") + @Mapping(source = "adptrmsgdstcd", target = "messageType") + @Mapping(source = "adptriodstcd", target = "gubun") + @Mapping(source = "refclsname", target = "refClass") + @Mapping(source = "sndrcvhmslogyn", target = "srLogFlag", qualifiedBy = StringToBooleanMapper.class) + @Mapping(source = "adptruseyn", target = "usedFlag", qualifiedBy = StringToBooleanMapper.class) + @Mapping(source = "spcfcluuseyn", target = "spcfcLUUseYn", qualifiedBy = StringToBooleanMapper.class) + @Mapping(source = "adptrbzwkgroupdesc", target = "description", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "osidinstino", target = "osidInstiNo", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "kesauseyn", target = "kesaUseYn", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "testmasteryn", target = "testMasterYn", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "adptrnickname", target = "adptrNickName", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "companycodedata", target = "companyCodeData", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "adptrinsticode", target = "adptrInstiCode", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "bidinterface", target = "bidInterface", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "msgencode", target = "messageEncode", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "linkedAdapterGroup", target = "linkedAdapterGroup") + @Mapping(source = "sameSessionYn", target = "sameSessionYn") + @Mapping(source = "pairAdapterYn", target = "pairAdapterYn") + @Mapping(source = "clientId", target = "clientId") + AdapterGroupVO toVo(AdapterGroup entity); + + @Mapping(target = "adapters", ignore = true) + AdapterGroup toEntity(AdapterGroupVO vo); +} diff --git a/src/main/java/com/eactive/eai/adapter/mapper/AdapterMapper.java b/src/main/java/com/eactive/eai/adapter/mapper/AdapterMapper.java new file mode 100644 index 0000000..9c355af --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/mapper/AdapterMapper.java @@ -0,0 +1,25 @@ +package com.eactive.eai.adapter.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.data.entity.onl.adapter.Adapter; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; +import com.eactive.eai.data.mapper.StringTrimMapper; + +@Mapper(config = BaseMapperConfig.class) +public interface AdapterMapper extends GenericMapper { + + @Mapping(source = "id.adptrbzwkgroupname", target = "adapterGroupName") + @Mapping(source = "id.adptrbzwkname", target = "name") + @Mapping(source = "eaisevrinstncname", target = "eaiSevrInstncName") + @Mapping(source = "lstnerclsname", target = "listenerClass", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "testclsname", target = "testCallClass", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "prptygroupname", target = "propGroupName", qualifiedBy = StringTrimMapper.class) + @Mapping(source = "adptrdesc", target = "description", qualifiedBy = StringTrimMapper.class) + @Override + AdapterVO toVo(Adapter entity); + +} diff --git a/src/main/java/com/eactive/eai/adapter/sna/SNAAdapterManager.java b/src/main/java/com/eactive/eai/adapter/sna/SNAAdapterManager.java new file mode 100644 index 0000000..146e89a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/sna/SNAAdapterManager.java @@ -0,0 +1,188 @@ +package com.eactive.eai.adapter.sna; + +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.util.RuntimeUtil; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : Softlink 및 SNAAdpaterManager(WCA) 관리 +* 2. 처리 개요 : +* - start 할 경우 +* 1. Softman에게 명령어를 전송하여 Softlink 구동한다. +* 2. SNAAdpaterManager(WCA) instance 생성한다. +* (DB에서 SNA Adapter 정보를 메모리에 로딩 관리한다.) +* - stop 할 경우 +* 1. Softman에게 명령어를 전송하여 Softlink 종료한다. -> 제거 +* 3. 주의사항 +* - EAI 로딩 우선순위가 AdapterManager 보다 먼저 로딩되어야 한다. +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class SNAAdapterManager implements Lifecycle +{ + /** + * SNAAdapterManager Single Instance + */ + private static SNAAdapterManager instance = new SNAAdapterManager(); + + /** + * LifeccyleSupport object + */ + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + /** + * 기동 여부 + */ + private boolean started; + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + /** + * softman 구동중 + */ + String SOFTMAN_RUNNING_MSG = "SoftMan is Already Running"; + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + private SNAAdapterManager() { + } + + /** + * 1. 기능 : SNAAdapterManager Singleton Object를 반환하는 getter method + * 2. 처리 개요 : SNAAdapterManager Singleton Object를 반환한다. + * 3. 주의사항 + * + * @return SNAAdapterManager Singleton object + **/ + public static SNAAdapterManager getInstance() { + return instance; + } + + /** + * 1. 기능 : Lifecycle의 start 메서드로 SNAAdapterManager 초기화하는 메서드 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception LifecycleException 이미 시작되었을 경우(RECEAICBM201) + * + **/ + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAIASA001"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + // Softlink 구동 + try { + RuntimeUtil.getInstance().startSoftlink(); + }catch(WCAException e){ + String errMsg = e.toString(); + // 이미 구동중일 경우 + if (errMsg.indexOf(SOFTMAN_RUNNING_MSG) != -1){ + if(adapter_logger.isInfo()){ + adapter_logger.info(errMsg); + } + } + else + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAIASA002")); + } + // SNAAdapter (WCA) Manager instance 생성 +// SNAAdapterManager smanager = SNAAdapterManager.getInstance(); + + started = true; + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + /** + * 1. 기능 : Lifecycle의 stop 메서드로 SNAAdapterManager를 종료하는 메서드 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception LifecycleException 이미 종료된 경우 발생(RECEAICBM203) + **/ + public void stop() throws LifecycleException { + // Validate and update our current component state + if (!started) + throw new LifecycleException("RECEAIASA003"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + // Softlink 종료 --> 제거 + /* + try { + RuntimeUtil.getInstance().stopSoftlink(); + }catch(WCAException e){ + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAIASA004")); + } + */ + started = false; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + /** + * 1. 기능 : LifecycleListener를 등록하는 메서드 + * 2. 처리 개요 : LifecycleListener를 등록한다. + * 3. 주의사항 + * + * @param listener LifecycleEvent를 수신한 LifecycleListener + **/ + public void addLifecycleListener(LifecycleListener listener) + { + lifecycle.addLifecycleListener(listener); + } + + /** + * 1. 기능 : 등록된 LifecycleListener 리스트를 반환하는 메서드 + * 2. 처리 개요 : 등록된 LifecycleListener 리스트를 반환하다. + * 3. 주의사항 + * + * @return 등록된 LifecycleListener 리스트 + **/ + public LifecycleListener[] findLifecycleListeners() + { + return lifecycle.findLifecycleListeners(); + } + + + /** + * 1. 기능 : 등록된 LifecycleListener를 삭제하는 메서드 + * 2. 처리 개요 : 파라미터의 LifecycleListener를 삭제한다. + * 3. 주의사항 + * + * @param listener 삭제할 LifecycleListener + **/ + public void removeLifecycleListener(LifecycleListener listener) + { + lifecycle.removeLifecycleListener(listener); + } + + /** + * 1. 기능 : SNAAdapterManager를 초기화 여부를 반환하는 getter 메서드 + * 2. 처리 개요 : SNAAdapterManager를 초기화 여부를 반환한다. + * 3. 주의사항 + * + * @return 초기화 여부 + **/ + public boolean isStarted() { + return this.started; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/EAIConnectException.java b/src/main/java/com/eactive/eai/adapter/socket2/EAIConnectException.java new file mode 100644 index 0000000..0fb57d2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/EAIConnectException.java @@ -0,0 +1,14 @@ +package com.eactive.eai.adapter.socket2; + +import com.eactive.eai.adapter.EAIException; + +public class EAIConnectException extends EAIException { + + public EAIConnectException(String msg) { + super(msg); + } + + public EAIConnectException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/EAINoAvailableConnectionException.java b/src/main/java/com/eactive/eai/adapter/socket2/EAINoAvailableConnectionException.java new file mode 100644 index 0000000..16e0139 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/EAINoAvailableConnectionException.java @@ -0,0 +1,14 @@ +package com.eactive.eai.adapter.socket2; + +import com.eactive.eai.adapter.EAIException; + +public class EAINoAvailableConnectionException extends EAIException { + + public EAINoAvailableConnectionException(String msg) { + super(msg); + } + + public EAINoAvailableConnectionException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/EAITimeoutException.java b/src/main/java/com/eactive/eai/adapter/socket2/EAITimeoutException.java new file mode 100644 index 0000000..39e365e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/EAITimeoutException.java @@ -0,0 +1,14 @@ +package com.eactive.eai.adapter.socket2; + +import com.eactive.eai.adapter.EAIException; + +public class EAITimeoutException extends EAIException { + + public EAITimeoutException(String msg) { + super(msg); + } + + public EAITimeoutException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/SingleSessionManager.java b/src/main/java/com/eactive/eai/adapter/socket2/SingleSessionManager.java new file mode 100644 index 0000000..a93952e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/SingleSessionManager.java @@ -0,0 +1,74 @@ +package com.eactive.eai.adapter.socket2; + +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.session.SessionManager; +import com.eactive.eai.common.session.SessionVO; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoSession; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +public class SingleSessionManager { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static SingleSessionManager instance ; + + private ConcurrentHashMap sessionMap ; + + private SingleSessionManager() { + this.sessionMap = new ConcurrentHashMap<>(); + } + + public static SingleSessionManager getInstance(){ + if (instance == null){ + instance = new SingleSessionManager(); + } + return instance; + } + public ConcurrentMap getSessionList(){ + return sessionMap; + } + + public synchronized void sessionOpen(String adapterGroupName, IoSession session) throws Exception { + logger.warn("SingleSessionManager ] sessionOpen - [" + adapterGroupName + "," + session + "]"); + sessionMap.put(adapterGroupName, session); + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String loginInstId = eaiServerManager.getLocalServerName(); + + SessionVO psessionVo = SessionManager.getInstance().getConnectionInfo(adapterGroupName); + if(psessionVo != null) { + throw new Exception("Connection already exist in other Server - " + psessionVo.getLoginInstId()); + } + + SessionVO sessionVo = new SessionVO(); + sessionVo.setLoginUserId(adapterGroupName); + sessionVo.setLoginInstId(loginInstId); + SessionManager.getInstance().putConnectionInfo(adapterGroupName, sessionVo); + } + + public synchronized void sessionClose(String adapterGroupName, IoSession session){ + try{ + logger.warn("SingleSessionManager ] closeSession - [" + adapterGroupName + "," + session + "]"); + if(adapterGroupName != null) { + sessionMap.remove(adapterGroupName); + } + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String loginInstId = eaiServerManager.getLocalServerName(); + + SessionVO sessionVo = SessionManager.getInstance().getConnectionInfo(adapterGroupName); + + if(loginInstId != null && sessionVo != null && loginInstId.equals(sessionVo.getLoginInstId())) { + SessionManager.getInstance().removeConnectionInfo(adapterGroupName); + } + }catch(Exception e){ + logger.error("SingleSessionManager ] Error Occured in Closing session - " + session,e ); + } + } + + public synchronized IoSession getSession(String adapterGroupName){ + IoSession session = sessionMap.get(adapterGroupName); + logger.warn("SingleSessionManager ] getSession - [" + adapterGroupName + "," + session + "]"); + return session; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/SocketAdapterFacade.java b/src/main/java/com/eactive/eai/adapter/socket2/SocketAdapterFacade.java new file mode 100644 index 0000000..6246a44 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/SocketAdapterFacade.java @@ -0,0 +1,116 @@ +package com.eactive.eai.adapter.socket2; + +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.mina.common.IoSession; + +import com.eactive.eai.adapter.ElinkDefaultAdapter; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.inbound.processor.GWSessionManager; + +/** +* 1. 기능 : Outbound Socket Adapter를 Access하기 위한 Java Class로 SocketControl에서 사용함. +* 2. 처리 개요 : +* * - OutboundControl Object를 통해 Outbound Socket을 통해 수동시스템과 Socket인터페이스를 위한 +* SocketAdapter Class +* 3. 주의사항 +* - Outbound Process에서 Outbound Socket의 Adapter Group Name에 대한 Property를 지정해야한다. +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +*/ +public class SocketAdapterFacade extends ElinkDefaultAdapter +{ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static SocketAdapterFacade socketAdapter = new SocketAdapterFacade(); + + private SocketAdapterFacade() { + } + + public static SocketAdapterFacade getInstance() + { + return socketAdapter; + } + + /** + * 1. 기능 : SocketAdapter의 실행 Method + * 2. 처리 개요 : + * - OutboundControl Object를 생성 후 요청된 메시지를 Assign한 후 CallService를 통해 + * 해당 Outbound Adapter Group의 Socket Connection을 얻은 후 메시지 송수신에 따른 결과를 + * 리턴한다. + * 3. 주의사항 + * + * @param prop WLI OutboundAdapter의 Property정보, SocketAdapter의 경우 ADAPTER_GROUP_NAME + * Property Key에 Adapter Group Name을 지정한다. + * @param message Outbound process에서 요청하는 메시지 Object로 byte[] 속성의 메시지여야한다. + * @return 결과메시지 Object로 SYNC 유형의 경우 byte[] 메시지가 리턴된다. + * @exception Exception + **/ + @Override + public Object execute(Properties prop, Object message, Properties tempProp) throws Exception { + String adapterGroupName = tempProp.getProperty(Keys.OUT_ADAPTER_GROUP_NAME); + String adapterName = tempProp.getProperty(Keys.OUT_ADAPTER_NAME); + if (logger.isDebug()) + logger.debug("[SocketAdapterFacade] | Outbound Adapter Group is " + adapterGroupName); + + byte[] request = null; + if ( message instanceof byte[]) { + request = (byte[]) message; + } else { + throw new Exception(adapterGroupName + " | [SocketAdapterFacade] cannot send object type : " + message.getClass().getName()); + } + + ISocketAdapter adapter = null; + + if(adapterGroupName != null) adapter = SocketAdapterManager.getInstance().getOutboundSocketAdapter(adapterGroupName, adapterName); + + if (adapter == null) + throw new Exception(adapterGroupName + " | [SocketAdapterFacade] 수동 어댑터 정보 없음 adapterGroupName="+adapterGroupName +", adapterName="+adapterName); + + byte[] response = null; + if (adapter.getContext().isSync()){ + /** + * adapter.getContext().getTimeout() 는 초단위 + * Process.INTERFACE_TIME_OUT 는 ms 단위 + * 초단위로 바꾸는 작업필요 + * TODO 전체적인 타임아웃값 확인필요 + */ + int responseTimeout = 0; + String interfaceTimeout = tempProp.getProperty("INTERFACE_TIME_OUT"); + if (interfaceTimeout == null || NumberUtils.toInt(interfaceTimeout) == 0){ + responseTimeout = adapter.getContext().getTimeout(); + }else{ + try{ + responseTimeout = Integer.parseInt(interfaceTimeout) / 1000;//ms 단위이기 때문에 + }catch(Exception e){ + responseTimeout = adapter.getContext().getTimeout(); + } + } + if (responseTimeout == adapter.getContext().getTimeout()){ + response = (byte[]) adapter.sendMessage(request ); + }else{ + response = (byte[]) adapter.sendMessage(request, responseTimeout ); + } + }else{ + String sessionId = tempProp.getProperty(HttpClientAdapterServiceKey.TRANSACTION_ID); + logger.debug("[SocketAdapterFacade] | sessionId: {}", sessionId); + if (StringUtils.isNotBlank(sessionId)) { + IoSession session = GWSessionManager.getInstance().getSession(sessionId); + response = (byte[]) adapter.sendMessage(session, request); + GWSessionManager.getInstance().sessionOut(sessionId); + } else { + response = (byte[]) adapter.sendMessage(request); + } + } + + + return response; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/SocketAdapterListener.java b/src/main/java/com/eactive/eai/adapter/socket2/SocketAdapterListener.java new file mode 100644 index 0000000..3829dd3 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/SocketAdapterListener.java @@ -0,0 +1,69 @@ +package com.eactive.eai.adapter.socket2; + +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListenerSupport; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; + +/** + * 1. 기능 : Socket Adapter의 기동/중지를 위한 Adapter Listener로 FrameWork에서 + * SocketAdapter를 중지/기동하기 위한 Socket Adapter Listener이다. 2. 처리 개요 : - + * SocketAdapterManager Instance를 얻은 후 해당 Adapter에 대한 Stop/Start 기능을 수행한다. 3. + * 주의사항 + * + * @param + * @return + * @exception + */ +public class SocketAdapterListener extends AdapterListenerSupport { + static final Logger errLogger = SocketLoggerManager.getInstance().getErrLogger(); + + @Override + public void start() throws AdapterException { +// SocketAdapterManager manager = SocketAdapterManager.getInstance(); + try { + if (info == null) + throw new Exception("SocketAdapterListener | AdapterVO가 NULL입니다."); + + ISocketAdapter adapter = SocketAdapterFactory.createSocketAdapter(info); + + adapter.getContext().setAdapterVO(info); + if (adapter.getContext().isPermanent()) { + adapter.setAdapterStatus(false); + } else { + adapter.setAdapterStatus(true); + } + + adapter.start(); //.join(); + } catch (Exception e) { + String errorMessage = info==null? "":info.getName() + " | SocketAdapterListener | cannot start : " + e.getMessage(); + logger.error(errorMessage, e); + throw new AdapterException(errorMessage); + } + } + + @Override + public void stop() throws AdapterException { + + SocketAdapterManager manager = SocketAdapterManager.getInstance(); + try { + if (info == null) + throw new Exception("SocketAdapterListener | AdapterVO가 NULL입니다."); + + ISocketAdapter adapter = manager.getSocketAdapter(info.getAdapterGroupName(), info.getName()); + if (adapter == null) + throw new Exception(info.getName() + " | [SocketAdapterListener] AdapterVO가 NULL입니다."); + + adapter.setAdapterStatus(false); + + adapter.stop().join(); + } catch (Exception e) { + String errorMessage = info==null? "":info.getName() + " | SocketAdapterListener | cannot stop : " + e.getMessage(); + logger.error(errorMessage, e); + throw new AdapterException(errorMessage); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/dump/DumpServer.java b/src/main/java/com/eactive/eai/adapter/socket2/app/dump/DumpServer.java new file mode 100644 index 0000000..707db00 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/dump/DumpServer.java @@ -0,0 +1,65 @@ +package com.eactive.eai.adapter.socket2.app.dump; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.IRequestProcessor; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + +public class DumpServer { + static public void main(String[] args) throws Exception { + if (args.length != 1) { + System.out.println("Usage : dump "); + return; + } + int port = Integer.parseInt(args[0]); + + SocketAdapterContext context = new SocketAdapterContext(); + context.setAdapterGroupName("DumpServerAdapterGroup"); + context.setAdapterName("DumpServerAdapter"); + context.setBoundUsage("INBOUND"); + context.setSocketType("SERVER"); + context.setHostName("localhost"); + context.setPortNumber(port); + context.setResponseType("ASYN"); + context.setTimeout(10); + context.setMaxConnection(10); + context.setTraceLevel(context.TRACE_LEVEL_DEBUG); + context.setPermanent("N"); + + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setLlFieldType("NONE"); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + // do nothing + return request; + } + }); + + ISocketAdapter adapter = SocketAdapterFactory.createSocketAdapter(context); + adapter.start().join(); + + + /** + * process command + */ + processCommand(); + } + + private static void processCommand() { + while(true) { + try { + System.out.print("> "); + String cmd = (new java.io.BufferedReader(new java.io.InputStreamReader(System.in))).readLine(); + if ("".equals(cmd)) { + System.out.println(SocketAdapterManager.getInstance()); + } else if ("exit".equals(cmd)) { + System.exit(1); + } + } catch(Exception e) { + System.out.println(e.toString()); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/echo/EchoServer.java b/src/main/java/com/eactive/eai/adapter/socket2/app/echo/EchoServer.java new file mode 100644 index 0000000..7f7d510 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/echo/EchoServer.java @@ -0,0 +1,58 @@ +package com.eactive.eai.adapter.socket2.app.echo; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + +public class EchoServer { + static public void main(String[] args) throws Exception { + /** + * Xecure Server - [1] BASIC + */ + SocketAdapterContext context = new SocketAdapterContext(); + context.setProtocol("XECURE"); + context.setAdapterGroupName("XecureServerAdapterGroup"); + context.setAdapterName("XecureBasicServerAdapter"); + context.setBoundUsage("IOBOUND"); + context.setSocketType("SERVER"); + context.setHostName("localhost"); + context.setPortNumber(9901); + context.setResponseType("SYNC"); + context.setTimeout(10); + context.setMaxConnection(10); + context.setTraceLevel(context.TRACE_LEVEL_DEBUG); + context.setPermanent("N"); + + context.setXecureType("BASIC"); + //context.setXecureTmode("10"); + //context.setXecureEncodeMode("BASE64"); + //context.setXecurePassword("qwer1234"); + context.setXecureConfigPath("modules/xecure/windows/conf/xc_conf.txt"); + + ISocketAdapter adapter = SocketAdapterFactory.createSocketAdapter(context); + adapter.start().join(); + + + /** + * process command + */ + processCommand(); + } + + private static void processCommand() { + while(true) { + try { + System.out.print("> "); + String cmd = (new java.io.BufferedReader(new java.io.InputStreamReader(System.in))).readLine(); + if ("".equals(cmd)) { + System.out.println(SocketAdapterManager.getInstance()); + } else if ("exit".equals(cmd)) { + System.exit(1); + } + } catch(Exception e) { + System.out.println("processCommand errpr "+ e.toString()); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/muxer/Muxer.java b/src/main/java/com/eactive/eai/adapter/socket2/app/muxer/Muxer.java new file mode 100644 index 0000000..d69560e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/muxer/Muxer.java @@ -0,0 +1,86 @@ +package com.eactive.eai.adapter.socket2.app.muxer; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.IRequestProcessor; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + +public class Muxer { + static public void startup(String inboundHostname, int inboundPort, String outboundHostname, int outboundPort) throws Exception { + /** + * Outbound Client + */ + SocketAdapterContext context = new SocketAdapterContext(); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setAdapterGroupName("MuxerGroup"); + context.setAdapterName("OutboundAdapter"); + context.setBoundUsage("IOBOUND"); + context.setSocketType("CLIENT"); + context.setHostName(outboundHostname); + context.setPortNumber(outboundPort); + context.setResponseType("SYNC"); + context.setMaxConnection(1); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_TRACE); + + ISocketAdapter outboundClient = SocketAdapterFactory.createSocketAdapter(context); + outboundClient.start().join(); + + /** + * Inbound Server + */ + context = new SocketAdapterContext(); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setAdapterGroupName("MuxerGroup"); + context.setAdapterName("InboundAdapter"); + context.setBoundUsage("IOBOUND"); + context.setSocketType("SERVER"); + context.setHostName(inboundHostname); + context.setPortNumber(inboundPort); + context.setResponseType("SYNC"); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_TRACE); + context.setRequestProcessor(new MuxerRequestProcessor(outboundClient)); + + ISocketAdapter inboundServer = SocketAdapterFactory.createSocketAdapter(context); + inboundServer.start().join(); + + } + + public synchronized byte[] handle(byte[] message) { + System.out.println("##############################################################"); + System.out.println("CiscoListener | message received : " + new String(message)); + System.out.println("##############################################################"); + return message; + } + + static public void main(String[] args) throws Exception { + if (args.length != 3) { + System.out.println("java " + Muxer.class.getName() + " "); + return; + } + + int inboundPort = Integer.parseInt(args[0]); + String outboundHostname = args[1]; + int outboundPort = Integer.parseInt(args[2]); + + startup("*", inboundPort, outboundHostname, outboundPort); + } +} + +class MuxerRequestProcessor implements IRequestProcessor { + ISocketAdapter outboundAdapter; + + public MuxerRequestProcessor(ISocketAdapter outboundAdapter) { + this.outboundAdapter = outboundAdapter; + } + + public synchronized byte[] handle(byte[] message) throws EAIException { + System.out.println("##############################################################"); + System.out.println("MuxerRequestProcessor | message received : " + new String(message)); + System.out.println("##############################################################"); + + return (byte[]) outboundAdapter.sendMessage(message); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/proxy/ProxyServer.java b/src/main/java/com/eactive/eai/adapter/socket2/app/proxy/ProxyServer.java new file mode 100644 index 0000000..38f238a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/proxy/ProxyServer.java @@ -0,0 +1,47 @@ +package com.eactive.eai.adapter.socket2.app.proxy; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + +public class ProxyServer { + static public void startup(String proxyHostname, int proxyPort, String remoteHostname, int remotePort) throws Exception { + + /** + * Proxy Server + */ + SocketAdapterContext context = new SocketAdapterContext(); + context.setProtocol("PROXY"); + context.setAdapterGroupName("AdminAdapterGroup"); + context.setAdapterName("ProxyAdapter"); + context.setBoundUsage("IOBOUND"); + context.setSocketType("SERVER"); + context.setHostName(proxyHostname); + context.setPortNumber(proxyPort); + context.setLocalHostName(remoteHostname); + context.setLocalPortNumber(remotePort); + context.setAckSupport("N"); + context.setPermanent("Y"); + context.setResponseType("SYNC"); + context.setTimeout(60); + context.setScript("proxy.groovy"); + context.setTraceLevel(context.TRACE_LEVEL_TRACE); + + //SocketAdapter adapter = new AdminServer(context); + ISocketAdapter adapter = SocketAdapterFactory.createSocketAdapter(context); + adapter.start().join(); + } + + static public void main(String[] args) throws Exception { + if (args.length != 3) { + System.out.println("java " + ProxyServer.class.getName() + " "); + return; + } + + int proxyPort = Integer.parseInt(args[0]); + String remoteHostname = args[1]; + int remotePort = Integer.parseInt(args[2]); + + startup("*", proxyPort, remoteHostname, remotePort); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/tester/AsyncSimulator.java b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/AsyncSimulator.java new file mode 100644 index 0000000..217723b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/AsyncSimulator.java @@ -0,0 +1,543 @@ +package com.eactive.eai.adapter.socket2.app.tester; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.IRequestProcessor; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + +public class AsyncSimulator { + String hostname; + String rHostname; + int rPort; + int mThread; + + final ISocketAdapter httpAdapter; +// final ISocketAdapter adapter11; + + final ISocketAdapter adapter21; + final ISocketAdapter adapter22; + final ISocketAdapter adapter23; + final ISocketAdapter adapter24; + final ISocketAdapter adapter25; + final ISocketAdapter adapter26; + + final ISocketAdapter adapter31; + final ISocketAdapter adapter32; + final ISocketAdapter adapter33; + final ISocketAdapter adapter34; + final ISocketAdapter adapter35; + final ISocketAdapter adapter36; + + final ISocketAdapter adapter41; + final ISocketAdapter adapter42; + final ISocketAdapter adapter43; + final ISocketAdapter adapter44; + final ISocketAdapter adapter45; + final ISocketAdapter adapter46; + + public AsyncSimulator(String hostname, String rHostname, int rPort, int mThread) throws Exception { + this.hostname = hostname; + this.rHostname = rHostname; + this.rPort = rPort; + this.mThread = mThread; + + SocketAdapterContext context = null; + + /** + * Http Server + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("AdminAdapterGroup"); + context.setAdapterName("HttpAdapter"); + context.setProtocol("HTTP"); + context.setBoundUsage("IOBOUND"); + context.setSocketType("SERVER"); + context.setHostName("*"); + context.setPortNumber(8282); + context.setAckSupport("N"); + context.setPermanent("N"); + context.setResponseType("SYNC"); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + context.setAclList("172.26.128.*,127.0.0.1"); + httpAdapter = SocketAdapterFactory.createSocketAdapter(context); + httpAdapter.start(); + + /** + * Inbound RECEIVER(SERVER) - 응답 수신 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-RECV_41"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(44041); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { +// System.out.print("."); + return request; + } + }); + + adapter41 = SocketAdapterFactory.createSocketAdapter(context); + adapter41.start(); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-RECV_42"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(44042); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { +// System.out.print("."); + return request; + } + }); + + adapter42 = SocketAdapterFactory.createSocketAdapter(context); + adapter42.start(); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-RECV_43"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(44043); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { +// System.out.print("."); + return request; + } + }); + + adapter43 = SocketAdapterFactory.createSocketAdapter(context); + adapter43.start(); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-RECV_44"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(44044); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { +// System.out.print("."); + return request; + } + }); + + adapter44 = SocketAdapterFactory.createSocketAdapter(context); + adapter44.start(); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-RECV_45"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(44045); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { +// System.out.print("."); + return request; + } + }); + + adapter45 = SocketAdapterFactory.createSocketAdapter(context); + adapter45.start(); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-RECV_46"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(44046); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { +// System.out.print("."); + return request; + } + }); + + adapter46 = SocketAdapterFactory.createSocketAdapter(context); + adapter46.start(); + + /** + * Outbound SENDER(CLIENT) - 응답 요청 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-SEND_31"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(rHostname); + context.setPortNumber(rPort + 1); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(mThread); + context.setMaxThread(mThread); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter31 = SocketAdapterFactory.createSocketAdapter(context); + adapter31.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter41.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-SEND_32"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(rHostname); + context.setPortNumber(rPort + 2); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(mThread); + context.setMaxThread(mThread); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter32 = SocketAdapterFactory.createSocketAdapter(context); + adapter32.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter42.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-SEND_33"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(rHostname); + context.setPortNumber(rPort + 3); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(mThread); + context.setMaxThread(mThread); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter33 = SocketAdapterFactory.createSocketAdapter(context); + adapter33.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter43.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-SEND_34"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(rHostname); + context.setPortNumber(rPort + 4); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(mThread); + context.setMaxThread(mThread); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter34 = SocketAdapterFactory.createSocketAdapter(context); + adapter34.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter44.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-SEND_35"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(rHostname); + context.setPortNumber(rPort + 5); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(mThread); + context.setMaxThread(mThread); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter35 = SocketAdapterFactory.createSocketAdapter(context); + adapter35.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter45.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("RES-SEND_36"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(rHostname); + context.setPortNumber(rPort + 6); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(mThread); + context.setMaxThread(mThread); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter36 = SocketAdapterFactory.createSocketAdapter(context); + adapter36.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter46.sendMessage(request); + return request; + } + }); + + /** + * Outbound RECEIVER(SERVER) - 요청 수신 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("REQ-RECV_21"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(42001); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter21 = SocketAdapterFactory.createSocketAdapter(context); + adapter21.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter31.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("REQ-RECV_22"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(42002); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter22 = SocketAdapterFactory.createSocketAdapter(context); + adapter22.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter32.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("REQ-RECV_23"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(42003); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter23 = SocketAdapterFactory.createSocketAdapter(context); + adapter23.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter33.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("REQ-RECV_24"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(42004); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter24 = SocketAdapterFactory.createSocketAdapter(context); + adapter24.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter34.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("REQ-RECV_25"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(42005); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter25 = SocketAdapterFactory.createSocketAdapter(context); + adapter25.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter35.sendMessage(request); + return request; + } + }); + + context = new SocketAdapterContext(); + context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); + context.setAdapterName("REQ-RECV_26"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setHostName(hostname); + context.setPortNumber(42006); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(100); + context.setMaxThread(100); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter26 = SocketAdapterFactory.createSocketAdapter(context); + adapter26.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + adapter36.sendMessage(request); + return request; + } + }); + + /** + * Inbound SENDER(CLIENT) - 요청 송신 + */ +// context = new SocketAdapterContext(); +// context.setAdapterGroupName("AsyncSimulatorAdapterGroup"); +// context.setAdapterName("Inbound-SEND"); +// context.setProtocol("FIXED_LENGTH_HEADER"); +// context.setSocketType("CLIENT"); +// context.setHostName(hostname); +// context.setPortNumber(42001); +// context.setLlFieldType("CHAR"); +// context.setLlFieldLength(4); +// context.setResponseType("ASYN"); +// context.setMaxConnection(100); +// context.setMaxThread(100); +// context.setTimeout(60); +// context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); +// adapter11 = SocketAdapterFactory.createSocketAdapter(context); +// adapter11.start().join(); + } + + static public void main(String[] args) throws Exception { + + //String hostname = "localhost"; + String hostname = args[0]; + String rHostname = args[1]; + int rPort = Integer.parseInt(args[2]); + int mThread = Integer.parseInt(args[3]); + new AsyncSimulator(hostname, rHostname, rPort, mThread); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/tester/EchoSimulator.java b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/EchoSimulator.java new file mode 100644 index 0000000..4805195 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/EchoSimulator.java @@ -0,0 +1,173 @@ +package com.eactive.eai.adapter.socket2.app.tester; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.IRequestProcessor; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + +public class EchoSimulator { + + final ISocketAdapter httpAdapter; +// final ISocketAdapter adapter11; + final ISocketAdapter adapter21; +// final ISocketAdapter adapter31; + final ISocketAdapter adapter41; + + public EchoSimulator(int echoPort, int destPort, int maxConn, String script, int adminPort, String llfieldinclude, String lloffsetexclude, String llInclude) throws Exception { + + SocketAdapterContext context = null; + + /** + * Http Server + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("AdminAdapterGroup"); + context.setAdapterName("HttpAdapter"); + context.setProtocol("HTTP"); + context.setBoundUsage("IOBOUND"); + context.setSocketType("SERVER"); + context.setHostName("*"); + context.setPortNumber(adminPort); + context.setAckSupport("N"); + context.setPermanent("N"); + context.setResponseType("SYNC"); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); +// context.setAclList("172.26.128.*,127.0.0.1"); + httpAdapter = SocketAdapterFactory.createSocketAdapter(context); + httpAdapter.start(); + + /** + * Inbound RECEIVER(SERVER) - 응답 수신[400] + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("EchoSimulatorAdapterGroup"); + context.setAdapterName("DestinationAsS"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + //context.setBoundUsage("INBOUND"); + //context.setHostName(hostname); + context.setPortNumber(destPort);//64001); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setLlFieldInclude(llfieldinclude); + context.setLlOffsetExclude(lloffsetexclude); + context.setLlInclude(llInclude); + context.setResponseType("ASYN"); + context.setMaxConnection(maxConn);//30); + context.setMaxThread(maxConn);//30); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter41 = SocketAdapterFactory.createSocketAdapter(context); + adapter41.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { +// System.out.print("."); + return request; + } + }); + + + /** + * Outbound SENDER(CLIENT) - 응답 요청[300] + */ +// context = new SocketAdapterContext(); +// context.setAdapterGroupName("EchoSimulatorAdapterGroup"); +// context.setAdapterName("RES-SEND_31"); +// context.setProtocol("FIXED_LENGTH_HEADER"); +// context.setSocketType("CLIENT"); +// context.setHostName(rHost); +// context.setPortNumber(rPort); +// //context.setLlFieldType("BIN"); +// //context.setLlFieldLength(2); +// context.setResponseType("ASYN"); +// context.setMaxConnection(30); +// context.setMaxThread(30); +// context.setTimeout(60); +//// context.setScript("sync-perm.groovy"); +// context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); +// adapter31 = SocketAdapterFactory.createSocketAdapter(context); +// adapter31.start(); + +// context.setRequestProcessor(new IRequestProcessor() { +// public byte[] handle(byte[] request) throws Exception { +//// adapter41.sendMessage(request); +// System.out.println(new String(request)); +// request[request.length-1] = (byte) '-'; +// return request; +// } +// }); + + + /** + * Outbound RECEIVER(SERVER) - 요청 수신[200] + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("EchoSimulatorAdapterGroup"); + context.setAdapterName("EchoAsS"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setBoundUsage("IOBOUND"); + //context.setHostName(hostname); + context.setPortNumber(echoPort);//62001); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setLlFieldOffset(0); + context.setLlFieldInclude(llfieldinclude); + context.setLlOffsetExclude(lloffsetexclude); + context.setLlInclude(llInclude); + context.setResponseType("ASYN"); + context.setMaxConnection(maxConn);//30); + context.setMaxThread(maxConn);//30); + context.setTimeout(60); + context.setScript(script);//"asyn-perm.groovy"); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + adapter21 = SocketAdapterFactory.createSocketAdapter(context); + adapter21.start(); + +// context.setRequestProcessor(new IRequestProcessor() { +// public byte[] handle(byte[] request) throws Exception { +// adapter31.sendMessage(request); +// return request; +// } +// }); + + + /** + * Inbound SENDER(CLIENT) - 요청 송신[100] + */ +// context = new SocketAdapterContext(); +// context.setAdapterGroupName("EchoSimulatorAdapterGroup"); +// context.setAdapterName("Inbound-SEND"); +// context.setProtocol("FIXED_LENGTH_HEADER"); +// context.setSocketType("CLIENT"); +// context.setHostName(hostname); +// context.setPortNumber(61001); +// context.setLlFieldType("BIN"); +// context.setLlFieldLength(2); +// context.setResponseType("ASYN"); +// context.setMaxConnection(30); +// context.setMaxThread(30); +// context.setTimeout(60); +// context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); +// adapter11 = SocketAdapterFactory.createSocketAdapter(context); +// adapter11.start().join(); + } + + static public void main(String[] args) throws Exception { + + // echoPort, destPort, maxConn, script, adminPort, llfieldinclude, lloffsetexclude, llinclude +// String eaiHost = args[0]; +// int eaiPort = Integer.parseInt(args[1]); + int echoPort = Integer.parseInt(args[0]); + int destPort = Integer.parseInt(args[1]); + int maxConn = Integer.parseInt(args[2]); + String script = args[3]; + int adminPort = Integer.parseInt(args[4]); + String llfieldinclude = args[5]; + String lloffsetexclude = args[6]; + String llInclude = args[7]; + new EchoSimulator(echoPort, destPort, maxConn, script, adminPort, llfieldinclude, lloffsetexclude, llInclude); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner.java b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner.java new file mode 100644 index 0000000..4d2ca64 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner.java @@ -0,0 +1,382 @@ +package com.eactive.eai.adapter.socket2.app.tester; + + +import com.eactive.eai.adapter.socket2.common.StopWatch; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.IRequestProcessor; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.UUIDGenerator; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + + +public class LoadRunner { + String hostname; + String message; + + final ISocketAdapter httpAdapter; + final ISocketAdapter adapter1; + final ISocketAdapter adapter2; + final ISocketAdapter adapter3; + final ISocketAdapter adapter4; + + int threadCount = 1; + int loopCount = 1; + long thinkTime = 0L; + CountDownLatch latch; + + + public LoadRunner(String hostname, String filename) throws Exception { + this.hostname = hostname; + this.message = readFile(filename); + + SocketAdapterContext context = null; + + /** + * Http Server + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("AdminAdapterGroup"); + context.setAdapterName("HttpAdapter"); + context.setProtocol("HTTP"); + context.setBoundUsage("IOBOUND"); + context.setSocketType("SERVER"); + context.setHostName("*"); + context.setPortNumber(8282); + context.setAckSupport("N"); + context.setPermanent("N"); + context.setResponseType("SYNC"); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + context.setAclList("172.26.127.*,127.0.0.1"); + httpAdapter = SocketAdapterFactory.createSocketAdapter(context); + httpAdapter.start(); + + /** + * port:10004 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("FixedLengthHeaderAdapterGroup"); + context.setAdapterName("Bin2ClientAdapter-10004"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(hostname); + context.setPortNumber(10004); + + //context.setLocalHostName("172.26.127.106"); + //context.setLocalPortNumber(12929); + + context.setResponseType("ASYN"); + context.setMaxConnection(10); + context.setMaxThread(100); + context.setTimeout(10); + context.setTraceLevel(context.TRACE_LEVEL_INFO); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + //System.out.println("[" + TimeUtil.formatDate(System.currentTimeMillis()) + "] " + new String(request)); + System.out.print("."); + latch.countDown(); + return request; + } + }); + + adapter4 = SocketAdapterFactory.createSocketAdapter(context); + adapter4.start(); + + /** + * port:10003 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("FixedLengthHeaderAdapterGroup"); + context.setAdapterName("Bin2ClientAdapter-10003"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(hostname); + context.setPortNumber(10003); + context.setResponseType("ASYN"); + context.setMaxConnection(10); + context.setMaxThread(100); + context.setTimeout(10); + context.setTraceLevel(context.TRACE_LEVEL_INFO); + adapter3 = SocketAdapterFactory.createSocketAdapter(context); + adapter3.start(); + + /** + * port:10002 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("FixedLengthHeaderAdapterGroup"); + context.setAdapterName("Bin2ClientAdapter-10002"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(hostname); + context.setPortNumber(10002); + context.setResponseType("ASYN"); + context.setMaxConnection(10); + context.setMaxThread(100); + context.setTimeout(10); + context.setTraceLevel(context.TRACE_LEVEL_INFO); + adapter2 = SocketAdapterFactory.createSocketAdapter(context); + adapter2.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + //System.out.print("2"); + adapter3.sendMessage(request); + //System.out.print("3"); + return request; + } + }); + + /** + * port:10001 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("FixedLengthHeaderAdapterGroup"); + context.setAdapterName("Bin2ClientAdapter-10001"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(hostname); + context.setPortNumber(10001); + context.setResponseType("ASYN"); + context.setMaxConnection(10); + context.setMaxThread(100); + context.setTimeout(10); + context.setTraceLevel(context.TRACE_LEVEL_INFO); + adapter1 = SocketAdapterFactory.createSocketAdapter(context); + adapter1.start().join(); + } + + public void start() throws Exception { + /** + * latch + */ + latch = new CountDownLatch(threadCount * loopCount); + + /** + * executor + */ + ExecutorService executor = Executors.newCachedThreadPool(); + + final CountDownLatch startLatch = new CountDownLatch(1); + final CountDownLatch stopLatch = new CountDownLatch(threadCount); + + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + for (int i = 0; i < threadCount; i++) { + executor.execute(new Runnable() { + public void run() { + try { + startLatch.await(); + for (int j=0; j "); + String line = (new BufferedReader(new java.io.InputStreamReader(System.in))).readLine(); + + if (line == null) { + break; + } else if ("".equals(line.trim())) { + } else if ("help".equals(line.trim())) { + System.out.println("==============================================================="); + System.out.println("LoadRunner v1.0 (http port = 8282)"); + System.out.println("==============================================================="); + System.out.println(" help : help"); + System.out.println(" start : start [thread count] [loop count] [think time]"); + System.out.println(" exit : exit"); + System.out.println(""); + } else if (line.trim().startsWith("start")) { + String[] tokens = line.trim().split("[ ]+"); + if (tokens.length > 1) + threadCount = Integer.parseInt(tokens[1]); + if (tokens.length > 2) + loopCount = Integer.parseInt(tokens[2]); + if (tokens.length > 3) + thinkTime = Long.parseLong(tokens[3]); + start(); + } else if ("exit".equals(line.trim())) { + System.exit(1); + } else { + System.out.println("Unknow command. type help."); + } + } catch(Exception e) { + System.out.println("Error " + e.toString()); + } + } + } + + + private String readFile(String filename) throws FileNotFoundException, IOException { + String line = ""; + ByteMessage data = new ByteMessage(); + BufferedReader br = new BufferedReader(new FileReader(filename)); + + try { + while ((line = br.readLine()) != null) { + while(line.indexOf("0x") != -1) { + data.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + data.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + data.append(line); + } + return data.getString(); + } + catch(Exception e) { + throw e; + } + finally { + try { + if(br != null) br.close(); + } + catch(Exception ee) { + System.out.println("close error"); + } + } + + + } + + static public void main(String[] args) throws Exception { +// /** +// * server - port:10004 +// */ +// SocketAdapterContext context = new SocketAdapterContext(); +// context.setAdapterGroupName("FixedLengthHeaderAdapterServerGroup"); +// context.setAdapterName("Bin2ServerAdapter-10004"); +// context.setProtocol("FIXED_LENGTH_HEADER"); +// context.setSocketType("SERVER"); +// context.setHostName("*"); +// context.setPortNumber(10004); +// context.setResponseType("ASYN"); +// context.setMaxConnection(10); +// context.setMaxThread(100); +// context.setTimeout(10); +// context.setTraceLevel(context.TRACE_LEVEL_INFO); +// final ISocketAdapter adapter4 = SocketAdapterFactory.createSocketAdapter(context); +// adapter4.start(); +// +// +// /** +// * server - port:10001 +// */ +// context = new SocketAdapterContext(); +// context.setAdapterGroupName("FixedLengthHeaderAdapterServerGroup"); +// context.setAdapterName("Bin2ServerAdapter-10001"); +// context.setProtocol("FIXED_LENGTH_HEADER"); +// context.setSocketType("SERVER"); +// context.setHostName("*"); +// context.setPortNumber(10001); +// context.setResponseType("ASYN"); +// context.setMaxConnection(10); +// context.setMaxThread(100); +// context.setTimeout(10); +// context.setTraceLevel(context.TRACE_LEVEL_INFO); +// +// context.setRequestProcessor(new IRequestProcessor() { +// public byte[] handle(final byte[] request) throws Exception { +//// ExecutorService executor = new ThreadPoolExecutor(16, 16, 60, TimeUnit.SECONDS, new LinkedBlockingQueue()); +//// executor.execute(new Runnable() { +//// public void run() { +//// try { +// adapter4.sendMessage(request); +//// } catch(Exception e) { +//// e.printStackTrace(); +//// } +//// } +//// }); +// return request; +// } +// }); +// +// final ISocketAdapter adapter1 = SocketAdapterFactory.createSocketAdapter(context); +// adapter1.start(); + + //---------------------------------------------------------------------- + if (System.getProperty("inst.Name") == null) + System.setProperty("inst.Name", System.getProperty("test")); + + String hostname = "localhost"; + String filename = ""; + + if (args.length == 2) { + hostname = args[0]; + System.out.println("remote host : " + hostname); + filename = args[1]; + } else { + System.out.println("Usage : loadrunner [ip] [file]"); + return; + } + + LoadRunner loadRunner = new LoadRunner(hostname, filename); + loadRunner.processCommand(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner2.java b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner2.java new file mode 100644 index 0000000..2248622 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/LoadRunner2.java @@ -0,0 +1,384 @@ +package com.eactive.eai.adapter.socket2.app.tester; + + +import com.eactive.eai.adapter.socket2.common.StopWatch; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.IRequestProcessor; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.UUIDGenerator; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + + +public class LoadRunner2 { + String hostname; + String message; + + final ISocketAdapter httpAdapter; + final ISocketAdapter adapter1; + final ISocketAdapter adapter2; + final ISocketAdapter adapter3; + final ISocketAdapter adapter4; + + int threadCount = 1; + int loopCount = 1; + long thinkTime = 0L; + CountDownLatch latch; + + + public LoadRunner2(String hostname, String filename) throws Exception { + this.hostname = hostname; + this.message = readFile(filename); + + SocketAdapterContext context = null; + + /** + * Http Server + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("AdminAdapterGroup"); + context.setAdapterName("HttpAdapter"); + context.setProtocol("HTTP"); + context.setBoundUsage("IOBOUND"); + context.setSocketType("SERVER"); + context.setHostName("*"); + context.setPortNumber(8282); + context.setAckSupport("N"); + context.setPermanent("N"); + context.setResponseType("SYNC"); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_DEFAULT); + context.setAclList("172.26.127.*,127.0.0.1"); + httpAdapter = SocketAdapterFactory.createSocketAdapter(context); + httpAdapter.start(); + + /** + * port:10006 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("FixedLengthHeaderAdapterGroup"); + context.setAdapterName("Bin2ClientAdapter-10006"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(hostname); + context.setPortNumber(10006); + + //context.setLocalHostName("172.26.127.106"); + //context.setLocalPortNumber(12929); + + context.setResponseType("ASYN"); + context.setMaxConnection(10); + context.setMaxThread(100); + context.setTimeout(10); + context.setTraceLevel(context.TRACE_LEVEL_INFO); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + //System.out.println("[" + TimeUtil.formatDate(System.currentTimeMillis()) + "] " + new String(request)); + System.out.print("."); + latch.countDown(); + return request; + } + }); + + adapter4 = SocketAdapterFactory.createSocketAdapter(context); + adapter4.start(); + + /** + * port:10003 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("FixedLengthHeaderAdapterGroup"); + context.setAdapterName("Bin2ClientAdapter-10003"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(hostname); + context.setPortNumber(10003); + context.setResponseType("ASYN"); + context.setMaxConnection(10); + context.setMaxThread(100); + context.setTimeout(10); + context.setTraceLevel(context.TRACE_LEVEL_INFO); + adapter3 = SocketAdapterFactory.createSocketAdapter(context); + adapter3.start(); + + /** + * port:10005 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("FixedLengthHeaderAdapterGroup"); + context.setAdapterName("Bin2ClientAdapter-10005"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(hostname); + context.setPortNumber(10005); + context.setResponseType("ASYN"); + context.setMaxConnection(10); + context.setMaxThread(100); + context.setTimeout(10); + context.setTraceLevel(context.TRACE_LEVEL_INFO); + adapter2 = SocketAdapterFactory.createSocketAdapter(context); + adapter2.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { + //System.out.print("2"); + adapter3.sendMessage(request); + //System.out.print("3"); + return request; + } + }); + + /** + * port:10001 + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("FixedLengthHeaderAdapterGroup"); + context.setAdapterName("Bin2ClientAdapter-10001"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("CLIENT"); + context.setHostName(hostname); + context.setPortNumber(10001); + context.setResponseType("ASYN"); + context.setMaxConnection(10); + context.setMaxThread(100); + context.setTimeout(10); + context.setTraceLevel(context.TRACE_LEVEL_INFO); + adapter1 = SocketAdapterFactory.createSocketAdapter(context); + adapter1.start().join(); + } + + public void start() throws Exception { + /** + * latch + */ + latch = new CountDownLatch(threadCount * loopCount); + + /** + * executor + */ + ExecutorService executor = Executors.newCachedThreadPool(); + + final CountDownLatch startLatch = new CountDownLatch(1); + final CountDownLatch stopLatch = new CountDownLatch(threadCount); + + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + for (int i = 0; i < threadCount; i++) { + executor.execute(new Runnable() { + public void run() { + try { + startLatch.await(); + for (int j=0; j "); + String line = (new BufferedReader(new java.io.InputStreamReader(System.in))).readLine(); + + if (line == null) { + break; + } else if ("".equals(line.trim())) { + } else if ("help".equals(line.trim())) { + System.out.println("==============================================================="); + System.out.println("LoadRunner v1.0 (http port = 8282)"); + System.out.println("==============================================================="); + System.out.println(" help : help"); + System.out.println(" start : start [thread count] [loop count] [think time]"); + System.out.println(" exit : exit"); + System.out.println(""); + } else if (line.trim().startsWith("start")) { + String[] tokens = line.trim().split("[ ]+"); + if (tokens.length > 1) + threadCount = Integer.parseInt(tokens[1]); + if (tokens.length > 2) + loopCount = Integer.parseInt(tokens[2]); + if (tokens.length > 3) + thinkTime = Long.parseLong(tokens[3]); + start(); + } else if ("exit".equals(line.trim())) { + System.exit(1); + } else { + System.out.println("Unknow command. type help."); + } + } catch(Exception e) { +// e.printStackTrace(); + System.out.println("Exception"); + } + } + } + + + private String readFile(String filename) throws FileNotFoundException, IOException { + BufferedReader br = new BufferedReader(new FileReader(filename)); + String line = ""; + + ByteMessage data = new ByteMessage(); + try { + while ((line = br.readLine()) != null) { + while(line.indexOf("0x") != -1) { + data.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + data.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + data.append(line); + } + } + catch(Exception e) { + System.out.println(e.toString()); + } + finally { + try { + br.close(); + } + catch(Exception e) { + System.out.println(e.toString()); + } + } + + return data.getString(); + } + + static public void main(String[] args) throws Exception { +// /** +// * server - port:10004 +// */ +// SocketAdapterContext context = new SocketAdapterContext(); +// context.setAdapterGroupName("FixedLengthHeaderAdapterServerGroup"); +// context.setAdapterName("Bin2ServerAdapter-10004"); +// context.setProtocol("FIXED_LENGTH_HEADER"); +// context.setSocketType("SERVER"); +// context.setHostName("*"); +// context.setPortNumber(10004); +// context.setResponseType("ASYN"); +// context.setMaxConnection(10); +// context.setMaxThread(100); +// context.setTimeout(10); +// context.setTraceLevel(context.TRACE_LEVEL_INFO); +// final ISocketAdapter adapter4 = SocketAdapterFactory.createSocketAdapter(context); +// adapter4.start(); +// +// +// /** +// * server - port:10001 +// */ +// context = new SocketAdapterContext(); +// context.setAdapterGroupName("FixedLengthHeaderAdapterServerGroup"); +// context.setAdapterName("Bin2ServerAdapter-10001"); +// context.setProtocol("FIXED_LENGTH_HEADER"); +// context.setSocketType("SERVER"); +// context.setHostName("*"); +// context.setPortNumber(10001); +// context.setResponseType("ASYN"); +// context.setMaxConnection(10); +// context.setMaxThread(100); +// context.setTimeout(10); +// context.setTraceLevel(context.TRACE_LEVEL_INFO); +// +// context.setRequestProcessor(new IRequestProcessor() { +// public byte[] handle(final byte[] request) throws Exception { +//// ExecutorService executor = new ThreadPoolExecutor(16, 16, 60, TimeUnit.SECONDS, new LinkedBlockingQueue()); +//// executor.execute(new Runnable() { +//// public void run() { +//// try { +// adapter4.sendMessage(request); +//// } catch(Exception e) { +//// e.printStackTrace(); +//// } +//// } +//// }); +// return request; +// } +// }); +// +// final ISocketAdapter adapter1 = SocketAdapterFactory.createSocketAdapter(context); +// adapter1.start(); + + //---------------------------------------------------------------------- + if (System.getProperty("inst.Name") == null) + System.setProperty("inst.Name", System.getProperty("test")); + + String hostname = "localhost"; + String filename = ""; + + if (args.length == 2) { + hostname = args[0]; + System.out.println("remote host : " + hostname); + filename = args[1]; + } else { + System.out.println("Usage : loadrunner [ip] [file]"); + return; + } + + LoadRunner2 loadRunner = new LoadRunner2(hostname, filename); + loadRunner.processCommand(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/tester/Xecure2Simulator.java b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/Xecure2Simulator.java new file mode 100644 index 0000000..45b6111 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/tester/Xecure2Simulator.java @@ -0,0 +1,104 @@ +package com.eactive.eai.adapter.socket2.app.tester; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.IRequestProcessor; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + +public class Xecure2Simulator { + + final ISocketAdapter httpAdapter; + final ISocketAdapter adapter21; + final ISocketAdapter adapter41; + + public Xecure2Simulator(int echoPort, int destPort, int maxConn, String script, int adminPort) throws Exception { + + SocketAdapterContext context = null; + + /** + * Http Server + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("AdminAdapterGroup"); + context.setAdapterName("HttpAdapter"); + context.setProtocol("HTTP"); + context.setBoundUsage("IOBOUND"); + context.setSocketType("SERVER"); + context.setHostName("*"); + context.setPortNumber(adminPort); + context.setAckSupport("N"); + context.setPermanent("N"); + context.setResponseType("SYNC"); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_TRACE); + context.setAclList("172.26.128.*,127.0.0.1"); + httpAdapter = SocketAdapterFactory.createSocketAdapter(context); + httpAdapter.start(); + + /** + * Inbound RECEIVER(SERVER) - 응답 수신[400] + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("EchoSimulatorAdapterGroup"); + context.setAdapterName("DestinationAsS"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + //context.setBoundUsage("INBOUND"); + //context.setHostName(hostname); + context.setPortNumber(destPort);//64001); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setResponseType("ASYN"); + context.setMaxConnection(maxConn);//30); + context.setMaxThread(maxConn);//30); + context.setTimeout(60); + context.setTraceLevel(context.TRACE_LEVEL_TRACE); + adapter41 = SocketAdapterFactory.createSocketAdapter(context); + adapter41.start(); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { +// System.out.print("."); + return request; + } + }); + + /** + * Outbound RECEIVER(SERVER) - 요청 수신[200] + */ + context = new SocketAdapterContext(); + context.setAdapterGroupName("EchoSimulatorAdapterGroup"); + context.setAdapterName("EchoAsS"); +// context.setProtocol("XECURE2"); + context.setProtocol("FIXED_LENGTH_HEADER"); + context.setSocketType("SERVER"); + context.setBoundUsage("IOBOUND"); + //context.setHostName(hostname); + context.setPortNumber(echoPort);//62001); + context.setLlFieldType("CHAR"); + context.setLlFieldLength(4); + context.setLlFieldOffset(0); + context.setLlFieldInclude("Y"); + context.setLlInclude("Y"); + context.setResponseType("ASYN"); + context.setMaxConnection(maxConn);//30); + context.setMaxThread(maxConn);//30); + context.setTimeout(60); + context.setScript(script);//"asyn-perm.groovy"); + context.setTraceLevel(context.TRACE_LEVEL_TRACE); + adapter21 = SocketAdapterFactory.createSocketAdapter(context); + adapter21.start(); + + } + + static public void main(String[] args) throws Exception { + + // eaiHost, eaiPort, echoPort, destPort, maxConn, script + int echoPort = Integer.parseInt(args[0]); + int destPort = Integer.parseInt(args[1]); + int maxConn = Integer.parseInt(args[2]); + String script = args[3]; + int adminPort = Integer.parseInt(args[4]); + new Xecure2Simulator(echoPort, destPort, maxConn, script, adminPort); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/app/udpquote/UdpQuote.java b/src/main/java/com/eactive/eai/adapter/socket2/app/udpquote/UdpQuote.java new file mode 100644 index 0000000..2507dc0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/app/udpquote/UdpQuote.java @@ -0,0 +1,46 @@ +package com.eactive.eai.adapter.socket2.app.udpquote; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.IRequestProcessor; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + + +public class UdpQuote { + static public void main(String[] args) throws Exception { + SocketAdapterContext context = new SocketAdapterContext(); + context.setAdapterGroupName("UdpServerAdapterGroup"); + context.setAdapterName("UdpServerAdapter"); + context.setBoundUsage("INBOUND"); + context.setResponseType("ASYN"); + +// context.setSocketType("CLIENT"); +// context.setHostName("121.189.63.31"); +// context.setPortNumber(61868); //45517); +// context.setLocalHostName("10.80.1.181"); +// context.setLocalPortNumber(45517); + + context.setSocketType("SERVER"); + context.setHostName("*"); + context.setPortNumber(45517); + + context.setProtocol("UDP_FIXED_LENGTH_PAYLOAD"); + context.setSendPayloadLength(63); + context.setRecvPayloadLength(63); + + context.setTimeout(60); + context.setMaxConnection(10); + context.setTraceLevel(context.TRACE_LEVEL_DEBUG); + + context.setRequestProcessor(new IRequestProcessor() { + public byte[] handle(byte[] request) throws Exception { +// System.out.println("[" + TimeUtil.formatDate(System.currentTimeMillis()) + +// "] '" + new String(request) + "'"); + return request; + } + }); + + ISocketAdapter client = SocketAdapterFactory.createSocketAdapter(context); + client.start().join(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/CircularQueue.java b/src/main/java/com/eactive/eai/adapter/socket2/common/CircularQueue.java new file mode 100644 index 0000000..5889d64 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/CircularQueue.java @@ -0,0 +1,111 @@ +package com.eactive.eai.adapter.socket2.common; + +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.common.util.Logger; +import org.apache.commons.collections.buffer.CircularFifoBuffer; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +public class CircularQueue extends CircularFifoBuffer { + static final Logger logger = SocketLoggerManager.getInstance().getLogger(); + + static final long AGE = 1000L * 60 * 60 * 24; // 1 day + static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("MM-dd HH:mm:ss"); + private String logPrefix = "CircularQueue | "; + + public CircularQueue(int maxSize) { + super(maxSize); + } + + @Override + public synchronized boolean add(Object o) { + try { + return super.add(o); + } catch(Exception e) { + super.clear(); + logger.warn(logPrefix + e.getMessage()); + return true; + } + } + + public synchronized void addRecord(String recordData) { + try { + super.add(new Tuple(System.currentTimeMillis(), recordData)); + } catch(Exception e) { + super.clear(); + logger.warn(logPrefix + e.getMessage()); + } + } + + public synchronized int getRecordCount() { + clearOldRecords(); + return size(); + } + + public synchronized String[]getRecords() { + clearOldRecords(); + + Object[] elements = toArray(); + String[] errors = new String[elements.length]; + for (int i=0; i AGE) { + this.remove(tuple); + } + } + } catch(Exception e) { + super.clear(); + logger.warn(logPrefix + e.getMessage()); + } + } + + public static class Tuple { + long time; + String message; + + public Tuple(long time, String message) { + this.time = time; + this.message = message; + } + + public long getTime() { + return time; + } + + public String getMessage() { + return message; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("CircularQueue max:" + maxSize() + " size:" + size() + "\n"); + sb.append("---------------------------------------------------------------------------------------------------------------------\n"); + Object[] elements = toArray(); + for (int i=elements.length-1; i>=0; i--) { + if (elements[i] == null) + continue; + sb.append(((String) elements[i]) + "\n"); + } + sb.append("---------------------------------------------------------------------------------------------------------------------\n"); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/CommonLib.java b/src/main/java/com/eactive/eai/adapter/socket2/common/CommonLib.java new file mode 100644 index 0000000..bc729bb --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/CommonLib.java @@ -0,0 +1,366 @@ +/* + * Created on 2005. 2. 26. + */ +package com.eactive.eai.adapter.socket2.common; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +/** + * 1. 기능 : SocketAdapter에서 사용되는 공통기능 제공 + * 2. 처리 개요 : + * - + * 3. 주의사항 + * + * @param + * @return + * @exception + **/ +import java.text.DecimalFormat; + +import org.apache.mina.common.ByteBuffer; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.common.errorcode.ErrorCodeHandler; + +/** + * @author janet + * 송수신 메시지 SPEC. + * llzz + syncFlag + user data(전문포맷전체를 사용자 DATA로 본다.) + * - llzz(2BYTE/4BYTE) UNSIGNED INTEGER로 처리한다. -- ConfigurationContext에 저장 + * default는 4byte로 한다. + * - syncFlag - 'S' - R/R, 'A' - ASYNC, 'K' - ACK ONLY(이 경우, SEVER의 ACK를 받는다. + * - llzz+K[ACK|NACK] + * - user data,... + */ +public class CommonLib { + + public static final char SPACE = ' '; + + public static final char ZERO = '0'; + + public static final String EMPTY_STRING = ""; + + public static final String[] EMPTY_STRING_ARRAY = new String[0]; + + public static final int NEGOTIATING_PROTOCOL = 1; + + public static final int PROCESSING_PROTOCOL = 2; + + public static final byte[] SYNC_PROTOCOL_MESSAGE = "SYNC".getBytes(); + + public static final byte[] ASYNC_PROTOCOL_MESSAGE = "ASYN".getBytes(); + + public static final byte[] NACK_MESSAGE = "NACK PROTOCOL VIOLATION".getBytes(); + + public static final byte[] ACK_MESSAGE = "ACK".getBytes(); + + private static final char[] HEX_CHAR_ARRAY = { '0', '1', '2', '3', '4', + '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; + + private CommonLib() { + + } + + /** + * BYTE ARRAY값을 HEXA STRING으로 변환하여 String을 리턴한다. + * @param abyte + * @return + */ + public static String byte2Hex(byte[] abyte) { + StringBuilder buf = new StringBuilder(); + int len = abyte.length; + + int high = 0; + int low = 0; + for (int i = 0; i < len; i++) { + high = ((abyte[i] & 0xf0) >> 4); + low = (abyte[i] & 0x0f); + buf.append(HEX_CHAR_ARRAY[high]); + buf.append(HEX_CHAR_ARRAY[low]); + } + return buf.toString(); + } + + + /** + * HEXA String값을 BYTE ARRAY로 변환한다. + * @param s + * @return + */ + public static byte[] hex2Bytes(String s) { + byte[] abyte = new byte[s.length() / 2]; + for (int j = 0; j < abyte.length; j++) + abyte[j] = (byte) Integer.parseInt(s.substring(2 * j, 2 * j + 2), 16); + return abyte; + } + + /** + * 주어진 String값을 주어진 길이많큼 Padding/Trim한다. + * @param svalue - 입력스트링 + * @param isRightJustify - true이면 RIGHT JUSTIFY, false이면 LEFT JUSTIFY + * @param padding - Padding 문자 + * @param length - 리턴할 스트링의 바이트수 + * @return 포맷팅된 String결과 + */ + public static String stringFormat(String svalue, boolean isRightJustify, char padding, int length) { + if ( svalue == null ) return svalue; + + StringBuilder mpad = new StringBuilder(); + StringBuilder fmtStr = new StringBuilder(); + + String tvalue = svalue; + int pLength = 0; + + pLength = length - svalue.getBytes().length; + + if (pLength == 0) + return svalue; + else if ( pLength < 0) { + byte[] abytes = null; + if (isRightJustify) { + abytes = (new String( svalue.getBytes(), -(pLength), length)).getBytes(); + } else { + abytes = (new String( svalue.getBytes(), 0, length)).getBytes(); + } + + if ( abytes.length == length ) { + return new String( abytes ); + } else { + tvalue = new String( abytes ); + pLength = length - tvalue.length(); + } + } + + for(int i =0; i < pLength ; i++) { + mpad.append( padding ); + } + + if ( isRightJustify ) { + return fmtStr.append(mpad).append(tvalue).toString(); + } else { + return fmtStr.append(tvalue).append(mpad).toString(); + } + } + + public static java.lang.String getFormatString(long value, int length) + { + DecimalFormat df = new DecimalFormat("000000000000000000"); + String fs = df.format( value ); + return fs.substring(fs.length() - length); + } + + public static java.lang.String getFormatString(int value, int length) + { + DecimalFormat df = new DecimalFormat("000000000000000000"); + String fs = df.format((long)value); + return fs.substring(fs.length() - length); + } + + /** + * 메시지 비교 + */ + public static boolean compare(byte[] source, byte[] target) { + if ( source.length != target.length ) return false; + + for ( int i=0; i < source.length; i++ ) { + if ( source[i] != target[i] ) return false; + } + return true; + } + + /** + * 송수신전문에 대한 DUMP를 프린트할 수 있는 포맷으로 변환하여 String Array로 리턴한다. + * @param bytes + * @return + */ + public static String[] makeDumpFormat(byte[] bytes) { + return makeDumpFormat(bytes, Charset.defaultCharset().toString()); + } + public static String[] makeDumpFormat(byte[] bytes, String encode) { + if (bytes == null || bytes.length == 0) + return CommonLib.EMPTY_STRING_ARRAY; + + String[] dumps = new String[bytes.length / 16 + ((bytes.length % 16) == 0 ? 4 : 5)]; + dumps[0] = " +----------------------------------------------------------------------+"; + dumps[1] = " | Offset | 0 1 2 3 4 5 6 7 8 9 A B C D E F | U S E R D A T A |"; + dumps[2] = " |----------+----------------------------------------+------------------|"; + dumps[dumps.length - 1] = " +----------------------------------------------------------------------+"; + + int len = 0; + final byte PERIOD = 0x2E; + char aChar ; + boolean isDBCS = false; + boolean isHalfDBCS = false; + + + for (int i = 3; i < dumps.length - 1; i++) { + len = ( ((bytes.length - (i - 2) * 16) >= 0) ? 16 : (bytes.length - (i - 3)*16) ); + byte[] buf = new byte[len]; + System.arraycopy( bytes, (i-3)*16, buf, 0, len ); + StringBuilder sb = new StringBuilder(); + + sb.append(" | ").append( stringFormat( Integer.toHexString((i-3)*16).toUpperCase(), true, ZERO, 8) ).append(" | "); + + String hexStr = byte2Hex( buf ); + StringBuilder fmtStr = new StringBuilder(); + + int k = hexStr.length()/8 + ((hexStr.length() % 8) == 0 ? 0 : 1); + for (int j=0; j < k ; j++) { + int l = ((hexStr.length() - (j+1)*8 ) >= 0 ? 8 : (hexStr.length() - j*8 )); + fmtStr.append( hexStr.substring(j*8, j*8 + l ) ).append(" "); + } + + sb.append( stringFormat(fmtStr.toString(), false, SPACE, 39) ).append("| "); + + k = 0; + // 한글 및 특수문자가 깨지게 표시되는 것 을 방지한다. + for ( int j=0; j < len; j++) { + if ( buf[j] >> 7 == 0 ) { + // Single Byte Character + if ( isDBCS ) { + isDBCS = false; + if ( k != 0 && ((k % 2) == 1 )) { + buf[j - 1] = PERIOD; + } + } + aChar = (char)buf[j]; + if ( Character.isWhitespace( aChar ) || Character.isISOControl( aChar ) || buf[j] == 0 ) { + buf[j] = PERIOD; + } + continue; + } + // Double Bytes Character. + if ( !isDBCS ) isDBCS = true; + if ( j == 0 && isHalfDBCS ) { + buf[j] = PERIOD; + isDBCS = false; + continue; + } + // To check the DBCS pairwise + k++; + } + if ( isDBCS && ((k%2)==1) ) { + buf[ len -1 ] = PERIOD; + isHalfDBCS = true; + } else { + isHalfDBCS = false; + } + try { + dumps[i] = sb.append(stringFormat(new String(buf, encode), false, SPACE, 16)).append(" |").toString(); + } catch (UnsupportedEncodingException e) { + dumps[i] = sb.append(stringFormat(new String(buf), false, SPACE, 16)).append(" |").toString(); + } + } + return dumps; + + } + public static String hexDump(byte[] message) { + return hexDump(message, true, Charset.defaultCharset().toString()); + } + + public static String hexDump(byte[] message, boolean printBytesInf) { + return hexDump(message, printBytesInf, Charset.defaultCharset().toString()); + } + public static String hexDump(byte[] message, boolean printBytesInfo, SocketAdapterContext context) { + if (context != null && context.getAdapterVO() != null && context.getAdapterVO().getAdapterGroupVO() != null && context.getAdapterVO().getAdapterGroupVO().getMessageEncode() != null) { + return hexDump(message, printBytesInfo, context.getAdapterVO().getAdapterGroupVO().getMessageEncode()); + }else { + return hexDump(message, printBytesInfo, Charset.defaultCharset().toString()); + } + } + public static String hexDump(byte[] message, boolean printBytesInfo, String encode) { + String[] dumpMsg = makeDumpFormat(message, encode); + StringBuilder dump = new StringBuilder(); + if (printBytesInfo) { + dump.append("byte[size=" + message.length + "]"); + } + dump.append("\n"); + for(int i=0; i < dumpMsg.length; i++) { + dump.append(dumpMsg[i]); + if (i < dumpMsg.length-1) + dump.append("\n"); + } + + return dump.toString(); + } + + + + /** + * ByteBuffer -> hexDump + */ + public static String hexDump(ByteBuffer buffer) { + return hexDump(buffer, Charset.defaultCharset().toString()); + } + public static String hexDump(ByteBuffer buffer, SocketAdapterContext context) { + if (context != null && context.getAdapterVO() != null && context.getAdapterVO().getAdapterGroupVO() != null && context.getAdapterVO().getAdapterGroupVO().getMessageEncode() != null) { + return hexDump(buffer, context.getAdapterVO().getAdapterGroupVO().getMessageEncode()); + }else { + return hexDump(buffer, Charset.defaultCharset().toString()); + } + } + public static String hexDump(ByteBuffer buffer, String encode) { + int mark = buffer.position(); + byte[] bytes = new byte[buffer.remaining()]; + buffer.get(bytes); + buffer.position(mark); + StringBuilder sb = new StringBuilder(); + sb.append("ByteBuffer[pos=" + mark); + sb.append(", lim=" + buffer.limit()); + sb.append(" ,cap=" + buffer.capacity() + "]"); + sb.append(hexDump(bytes, false, encode)); + return sb.toString(); + } + + public static String hexDumpRead(ByteBuffer buffer) { + return hexDumpRead(buffer, Charset.defaultCharset().toString()); + } + public static String hexDumpRead(ByteBuffer buffer, SocketAdapterContext context) { + if (context != null && context.getAdapterVO() != null && context.getAdapterVO().getAdapterGroupVO() != null && context.getAdapterVO().getAdapterGroupVO().getMessageEncode() != null) { + return hexDumpRead(buffer, context.getAdapterVO().getAdapterGroupVO().getMessageEncode()); + }else { + return hexDumpRead(buffer, Charset.defaultCharset().toString()); + } + } + public static String hexDumpRead(ByteBuffer buffer, String encode) { + StringBuilder sb = new StringBuilder(); + if (buffer.isDirect()) { + sb.append("DirectBuffer"); + } else { + sb.append("HeapBuffer"); + } + sb.append("[pos="); + sb.append(buffer.position()); + sb.append(" lim="); + sb.append(buffer.limit()); + sb.append(" cap="); + sb.append(buffer.capacity()); + sb.append("] - "); + int mark = buffer.position(); + int limit = buffer.limit(); + byte[] bytes = new byte[mark]; + buffer.position(0).limit(mark); + buffer.get(bytes); + buffer.position(mark); + buffer.limit(limit); + sb.append(hexDump(bytes, true, encode)); + return sb.toString(); + } + public static String getMessage(String msgCode, String[] params) { + StringBuilder sb = new StringBuilder(); + sb.append("[").append(msgCode).append("] ").append( ErrorCodeHandler.getMessage( msgCode, params ) ); + return sb.toString(); + } + + public static String getMessage(String msgCode) { + StringBuilder sb = new StringBuilder(); + sb.append("[").append(msgCode).append("] ").append( ErrorCodeHandler.getMessage( msgCode ) ); + return sb.toString(); + } + + public static String getDebugMessage(String msgCode, String[] params) { + StringBuilder sb = new StringBuilder(); + sb.append( ErrorCodeHandler.getMessage( msgCode, params ) ); + return ErrorCodeHandler.getMessage( msgCode, params ); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/Env.java b/src/main/java/com/eactive/eai/adapter/socket2/common/Env.java new file mode 100644 index 0000000..d5a41c8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/Env.java @@ -0,0 +1,35 @@ +package com.eactive.eai.adapter.socket2.common; + +import com.eactive.eai.common.server.Keys; + +public class Env { + static final boolean IS_WINDOWS = System.getProperty("os.name", "Windows").startsWith("Windows"); + static final boolean IS_ECHO = System.getProperty("echo") != null; + static final boolean IS_TEST = System.getProperty("test") != null; + static final boolean IS_STANDALONE = System.getProperty(Keys.SERVER_KEY) == null; + static final boolean IS_SMS_ENABLED = System.getProperty("sms.logging", "true").equalsIgnoreCase("true"); + + private Env() { + + } + + public static boolean isWindows() { + return IS_WINDOWS; + } + + public static boolean isEcho() { + return IS_ECHO; + } + + public static boolean isTest() { + return IS_TEST; + } + + public static boolean isStandalone() { + return IS_STANDALONE; + } + + public static boolean isSmsEnabled() { + return IS_SMS_ENABLED; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/ExceptionStackTrace.java b/src/main/java/com/eactive/eai/adapter/socket2/common/ExceptionStackTrace.java new file mode 100644 index 0000000..a38fc06 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/ExceptionStackTrace.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.common; + +public class ExceptionStackTrace { + private ExceptionStackTrace() { + + } + public static String dump(Throwable t) { + return ThreadDumpUtil.getStackTrace(t); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/ExecutionContext.java b/src/main/java/com/eactive/eai/adapter/socket2/common/ExecutionContext.java new file mode 100644 index 0000000..a097627 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/ExecutionContext.java @@ -0,0 +1,46 @@ +package com.eactive.eai.adapter.socket2.common; + +import java.util.Hashtable; + + +public class ExecutionContext extends ThreadLocal { + static ExecutionContext instance = new ExecutionContext(); + + public static ExecutionContext getInstance() { + return instance; + } + + private ExecutionContext() { + super(); + } + + protected Object initialValue() { + return new Hashtable(); + } + + public void set(String key, Object value) { + ((Hashtable) super.get()).put(key, value); + } + + public Object get(String key) { + return ((Hashtable) super.get()).get(key); + } + + public void remove(String key) { + ((Hashtable) super.get()).remove(key); + } + + public void set(Object value) { + throw new UnsupportedOperationException(); + } + + public Object get() { + throw new UnsupportedOperationException(); + } + + public void remove() { + throw new UnsupportedOperationException(); + } +} + + diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/ExpiringMap.java b/src/main/java/com/eactive/eai/adapter/socket2/common/ExpiringMap.java new file mode 100644 index 0000000..f1cc512 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/ExpiringMap.java @@ -0,0 +1,636 @@ +package com.eactive.eai.adapter.socket2.common; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * A map with expiration. + * + * @author The Apache Directory Project (mina-dev@directory.apache.org) + */ +public class ExpiringMap implements Map { + + /** The Constant DEFAULT_TIME_TO_LIVE. */ + public static final int DEFAULT_TIME_TO_LIVE = 60; + + /** The Constant DEFAULT_EXPIRATION_INTERVAL. */ + public static final int DEFAULT_EXPIRATION_INTERVAL = 1; + + /** The Constant DEFAULT_EXPIRATION_INTERVAL. */ + public static final String DEFAULT_NAME = "DEFAULT"; + + + /** The expirer count. */ + private static volatile int expirerCount = 1; + + private String name =null; + + /** The delegate. */ + private final ConcurrentHashMap delegate; + + /** The expirer. */ + private final Expirer expirer; + + /** + * Instantiates a new expiring map. + */ + public ExpiringMap() { + this(DEFAULT_NAME,DEFAULT_TIME_TO_LIVE, DEFAULT_EXPIRATION_INTERVAL); + } + /** + * Instantiates a new expiring map. + * + * @param timeToLive the time to live + */ + public ExpiringMap(int timeToLive) { + this(DEFAULT_NAME,timeToLive, DEFAULT_EXPIRATION_INTERVAL); + } + /** + * Instantiates a new expiring map. + * + * @param timeToLive the time to live + */ + public ExpiringMap(String name,int timeToLive) { + this(name,timeToLive, DEFAULT_EXPIRATION_INTERVAL); + } + /** + * Instantiates a new expiring map. + * + * @param timeToLive the time to live + * @param expirationInterval the expiration interval + */ + public ExpiringMap(int timeToLive, int expirationInterval) { + this(DEFAULT_NAME,new ConcurrentHashMap(), + timeToLive, + expirationInterval); + } + /** + * Instantiates a new expiring map. + * + * @param timeToLive the time to live + * @param expirationInterval the expiration interval + */ + public ExpiringMap(String name,int timeToLive, int expirationInterval) { + this(name,new ConcurrentHashMap(), + timeToLive, + expirationInterval); + } + + /** + * Instantiates a new expiring map. + * + * @param delegate the delegate + * @param expirationListeners the expiration listeners + * @param timeToLive the time to live + * @param expirationInterval the expiration interval + */ + private ExpiringMap(String name,ConcurrentHashMap delegate, + int timeToLive, int expirationInterval) { + this.name = name; + this.delegate = delegate; + + this.expirer = new Expirer(); + expirer.setExpirationInterval(expirationInterval); + expirer.setTimeToLive(timeToLive); + expirer.startExpiring(); + } + + /* (non-Javadoc) + * @see java.util.Map#put(java.lang.Object, java.lang.Object) + */ + public V put(K key, V value) { + ExpiringObject answer = delegate.put(key, new ExpiringObject(key, + value, System.currentTimeMillis())); + if (answer == null) { + return null; + } + + return answer.getValue(); + } + + /** + * Put. + * + * @param key the key + * @param value the value + * @param timeToLive the time to live + * + * @return the v + */ + public V put(K key, V value, int timeToLive) { + ExpiringObject answer = delegate.put(key, new ExpiringObject(key, + value, System.currentTimeMillis(), timeToLive)); + if (answer == null) { + return null; + } + + return answer.getValue(); + } + + /* (non-Javadoc) + * @see java.util.Map#get(java.lang.Object) + */ + public V get(Object key) { + ExpiringObject object = delegate.get(key); + if (object != null) { + return object.getValue(); + } + return null; + } + + /* (non-Javadoc) + * @see java.util.Map#remove(java.lang.Object) + */ + public V remove(Object key) { + ExpiringObject answer = delegate.remove(key); + if (answer == null) { + return null; + } + + return answer.getValue(); + } + + /* (non-Javadoc) + * @see java.util.Map#containsKey(java.lang.Object) + */ + public boolean containsKey(Object key) { + return delegate.containsKey(key); + } + + /* (non-Javadoc) + * @see java.util.Map#containsValue(java.lang.Object) + */ + public boolean containsValue(Object value) { + return delegate.containsValue(value); + } + + /* (non-Javadoc) + * @see java.util.Map#size() + */ + public int size() { + return delegate.size(); + } + + /* (non-Javadoc) + * @see java.util.Map#isEmpty() + */ + public boolean isEmpty() { + return delegate.isEmpty(); + } + + /* (non-Javadoc) + * @see java.util.Map#clear() + */ + public void clear() { + delegate.clear(); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return delegate.hashCode(); + } + + /* (non-Javadoc) + * @see java.util.Map#keySet() + */ + public Set keySet() { + return delegate.keySet(); + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return delegate.equals(obj); + } + + /* (non-Javadoc) + * @see java.util.Map#putAll(java.util.Map) + */ + public void putAll(Map inMap) { + for (Entry e : inMap.entrySet()) { + this.put(e.getKey(), e.getValue()); + } + } + + /* (non-Javadoc) + * @see java.util.Map#values() + */ + public Collection values() { + throw new UnsupportedOperationException(); + } + + /* (non-Javadoc) + * @see java.util.Map#entrySet() + */ + public Set> entrySet() { + throw new UnsupportedOperationException(); + } + + /** + * Gets the expirer. + * + * @return the expirer + */ + public Expirer getExpirer() { + return expirer; + } + + /** + * Gets the expiration interval. + * + * @return the expiration interval + */ + public int getExpirationInterval() { + return expirer.getExpirationInterval(); + } + + /** + * Gets the time to live. + * + * @return the time to live + */ + public int getTimeToLive() { + return expirer.getTimeToLive(); + } + + /** + * Sets the expiration interval. + * + * @param expirationInterval the new expiration interval + */ + public void setExpirationInterval(int expirationInterval) { + expirer.setExpirationInterval(expirationInterval); + } + + /** + * Sets the time to live. + * + * @param timeToLive the new time to live + */ + public void setTimeToLive(int timeToLive) { + expirer.setTimeToLive(timeToLive); + } + + /** + * The Class ExpiringObject. + *
    + *
  • 1. Function :
  • + *
  • 2. Summary :
  • + *
  • 3. Notification :
  • + *
+ * + * @author : $Author: $ + * @version : $Revision: 1.4 $ + */ + private class ExpiringObject { + + /** The key. */ + private K key; + + /** The value. */ + private V value; + + /** The access time. */ + private long accessTime; + + /** The time to live millis. */ + private long timeToLiveMillis; + + /** + * Instantiates a new expiring object. + * + * @param key the key + * @param value the value + * @param accessTime the access time + */ + ExpiringObject(K key, V value, long accessTime) { + this(key, value, accessTime, 0); + } + + /** + * Instantiates a new expiring object. + * + * @param key the key + * @param value the value + * @param accessTime the access time + * @param timeToLiveMillis the time to live millis + */ + ExpiringObject(K key, V value, long accessTime, int timeToLiveMillis) { + + if (value == null) { + throw new IllegalArgumentException( + "An expiring object cannot be null."); + } + + this.key = key; + this.value = value; + this.accessTime = accessTime; + this.timeToLiveMillis = timeToLiveMillis * 1000; + } + + /** + * Gets the time to live millis. + * + * @return the time to live millis + */ + public long getTimeToLiveMillis() { + return timeToLiveMillis; + } + + /** + * Sets the time to live millis. + * + * @param timeToLiveMillis the new time to live millis + */ + public void setTimeToLiveMillis(long timeToLiveMillis) { + this.timeToLiveMillis = timeToLiveMillis; + } + + /** + * Gets the access time. + * + * @return the access time + */ + public long getAccessTime() { + return accessTime; + } + + /** + * Sets the access time. + * + * @param lastAccessTime the new access time + */ + public void setAccessTime(long lastAccessTime) { + this.accessTime = lastAccessTime; + } + + /** + * Gets the key. + * + * @return the key + */ + public K getKey() { + return key; + } + + /** + * Gets the value. + * + * @return the value + */ + public V getValue() { + return value; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return value.equals(obj); + } + + /* (non-Javadoc) + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return value.hashCode(); + } + } + + /** + * The Class Expirer. + *
    + *
  • 1. Function :
  • + *
  • 2. Summary :
  • + *
  • 3. Notification :
  • + *
+ * + * @author : $Author: + * @version : $Revision: 1.4 $ + */ + public class Expirer implements Runnable { + + /** The state lock. */ + private ReadWriteLock stateLock = new ReentrantReadWriteLock(); + + /** The time to live millis. */ + private long timeToLiveMillis; + + /** The expiration interval millis. */ + private long expirationIntervalMillis; + + /** The running. */ + private boolean running = false; + + /** The expirer thread. */ + private final Thread expirerThread; + + /** + * Instantiates a new expirer. + */ + public Expirer() { + expirerThread = new Thread(this, "ExpiringMapExpirer-"+name+"-" + + (expirerCount++)); + expirerThread.setDaemon(true); + } + + /* (non-Javadoc) + * @see java.lang.Runnable#run() + */ + public void run() { + while (running) { + processExpires(); + + try { + Thread.sleep(expirationIntervalMillis); + } catch (InterruptedException e) { + } + } + } + + /** + * Process expires. + * expire : timeNow >= expireTime + * expireTime = accessTime + timeToLive + */ + private void processExpires() { + long timeNow = System.currentTimeMillis(); + + long timeToLiveMillis = 0; + + for (ExpiringObject o : delegate.values()) { + + if (o.getTimeToLiveMillis() > 0) { + timeToLiveMillis = o.getTimeToLiveMillis(); + } else { + timeToLiveMillis = this.timeToLiveMillis; + } + + if (timeToLiveMillis <= 0) + continue; + + long expireTime = o.getAccessTime() + timeToLiveMillis; + + if (timeNow >= expireTime) { + delegate.remove(o.getKey()); + } + } + } + + /** + * Start expiring. + */ + public void startExpiring() { + stateLock.writeLock().lock(); + + try { + if (!running) { + running = true; + expirerThread.start(); + } + } finally { + stateLock.writeLock().unlock(); + } + } + + /** + * Start expiring if not started. + */ + public void startExpiringIfNotStarted() { + stateLock.readLock().lock(); + try { + if (running) { + return; + } + } finally { + stateLock.readLock().unlock(); + } + + stateLock.writeLock().lock(); + try { + if (!running) { + running = true; + expirerThread.start(); + } + } finally { + stateLock.writeLock().unlock(); + } + } + + /** + * Stop expiring. + */ + public void stopExpiring() { + stateLock.writeLock().lock(); + + try { + if (running) { + running = false; + expirerThread.interrupt(); + } + } finally { + stateLock.writeLock().unlock(); + } + } + + /** + * Checks if is running. + * + * @return true, if is running + */ + public boolean isRunning() { + stateLock.readLock().lock(); + + try { + return running; + } finally { + stateLock.readLock().unlock(); + } + } + + /** + * Gets the time to live. + * + * @return the time to live + */ + public int getTimeToLive() { + stateLock.readLock().lock(); + + try { + return (int) timeToLiveMillis / 1000; + } finally { + stateLock.readLock().unlock(); + } + } + + /** + * Sets the time to live. + * + * @param timeToLive the new time to live + */ + public void setTimeToLive(long timeToLive) { + stateLock.writeLock().lock(); + + try { + this.timeToLiveMillis = timeToLive * 1000; + } finally { + stateLock.writeLock().unlock(); + } + } + + /** + * Gets the expiration interval. + * + * @return the expiration interval + */ + public int getExpirationInterval() { + stateLock.readLock().lock(); + + try { + return (int) expirationIntervalMillis / 1000; + } finally { + stateLock.readLock().unlock(); + } + } + + /** + * Sets the expiration interval. + * + * @param expirationInterval the new expiration interval + */ + public void setExpirationInterval(long expirationInterval) { + stateLock.writeLock().lock(); + + try { + this.expirationIntervalMillis = expirationInterval * 1000; + } finally { + stateLock.writeLock().unlock(); + } + } + } + public static void main (String[] args) throws Exception{ + ExpiringMap m = new ExpiringMap(1); + String key ="aaaaaaa"; + m.put(key,key); + System.out.println(m.get(key)); + Thread.sleep(1 * 1000L); + System.out.println(m.get(key)); + Thread.sleep(1 * 1000L); + System.out.println(m.get(key)); + Thread.sleep(1 * 1000L); + System.out.println(m.get(key)); + Thread.sleep(1 * 1000L); + System.out.println(m.get(key)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/FileUtil.java b/src/main/java/com/eactive/eai/adapter/socket2/common/FileUtil.java new file mode 100644 index 0000000..0d359c1 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/FileUtil.java @@ -0,0 +1,34 @@ +package com.eactive.eai.adapter.socket2.common; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + + +public class FileUtil { + private FileUtil() { + + } + public static byte[] readFile(String filename) throws IOException { + + try ( + BufferedReader br = new BufferedReader(new FileReader(filename)); + ) { + String line = ""; + ByteMessage m = new ByteMessage(); + while ((line = br.readLine()) != null) { + while(line.indexOf("0x") != -1) { + m.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + m.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + m.append(line); + } + return m.getBytes(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/FutureMap.java b/src/main/java/com/eactive/eai/adapter/socket2/common/FutureMap.java new file mode 100644 index 0000000..5bdd83d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/FutureMap.java @@ -0,0 +1,21 @@ +package com.eactive.eai.adapter.socket2.common; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +public class FutureMap { + Map map; + + public FutureMap() { + map = Collections.synchronizedMap(new HashMap()); + } + + public void put(String key, SimpleFuture future) { + map.put(key, future); + } + + public SimpleFuture get(String key) { + return map.remove(key); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/HexUtil.java b/src/main/java/com/eactive/eai/adapter/socket2/common/HexUtil.java new file mode 100644 index 0000000..2b79d07 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/HexUtil.java @@ -0,0 +1,23 @@ +package com.eactive.eai.adapter.socket2.common; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; + + +public class HexUtil { + private HexUtil() { + + } + public static byte[] string2Hex(String line) { + + ByteMessage m = new ByteMessage(); + + while(line.indexOf("0x") != -1) { + m.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + m.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + m.append(line); + return m.getBytes(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/SMSLogger.java b/src/main/java/com/eactive/eai/adapter/socket2/common/SMSLogger.java new file mode 100644 index 0000000..7344898 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/SMSLogger.java @@ -0,0 +1,28 @@ +package com.eactive.eai.adapter.socket2.common; + +import com.eactive.eai.common.util.SMSLogUtil; +import com.eactive.eai.common.util.StringUtil; + +public class SMSLogger { + private SMSLogger() { + + } + public static void loggingSMS(String svcName, String logMsg) { + if(Env.isSmsEnabled()) { + SMSLogUtil.loggingSMS(svcName, logMsg); + } + } + + public static void loggingSMSWithCode(String svcName, String code) { + if(Env.isSmsEnabled()) { + SMSLogUtil.loggingSMSWithCode(svcName, code); + } + } + + public static void loggingSMS4Soc(String adptName, String adptDesc, String code) { + if(Env.isSmsEnabled()) { + String svcName = StringUtil.chunkString(adptDesc, 12) + "|" + adptName; + SMSLogUtil.loggingSMSWithCode(svcName, code); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/SimpleFuture.java b/src/main/java/com/eactive/eai/adapter/socket2/common/SimpleFuture.java new file mode 100644 index 0000000..04994c0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/SimpleFuture.java @@ -0,0 +1,44 @@ +package com.eactive.eai.adapter.socket2.common; + +import com.eactive.eai.adapter.socket2.EAITimeoutException; + +public class SimpleFuture { + private Object result; + private boolean ready = false; + + public synchronized void init() { + ready = false; + } + + public synchronized void set(Object result) { + this.result = result; + this.ready = true; + notifyAll(); + } + + public synchronized Object join() { + //return join(60000L); // 60 seconds + + while (!ready) { + try { + wait(); + } catch (InterruptedException e) { + break; + } + } + return result; + } + + public synchronized Object join(long timeout) throws EAITimeoutException { + while (!ready) { + try { + wait(timeout); + } catch (InterruptedException e) { + break; + } + if (!ready) + throw new EAITimeoutException("timeout error (" + timeout + "ms)"); + } + return result; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/SocketAdapterException.java b/src/main/java/com/eactive/eai/adapter/socket2/common/SocketAdapterException.java new file mode 100644 index 0000000..c7cf110 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/SocketAdapterException.java @@ -0,0 +1,114 @@ +/* + * Created on 2005. 2. 26. + * + */ +package com.eactive.eai.adapter.socket2.common; + +import com.eactive.eai.adapter.EAIException; + +/** + * @author janet + * + */ +public class SocketAdapterException extends EAIException { + + public static final int UNEXPECTED_TERMINATION = 1; + + public static final int REMOTE_HOST_DISCONNECTED = 2; + + public static final int INTERNAL_ERROR = 5; + + public static final int CHANNEL_FAILURE = 6; + + public static final int CANCELLED_CONNECTION = 8; + + public static final int CONNECT_FAILED = 10; + + public static final int CONNECTION_CLOSED = 12; + + public static final int AGENT_ERROR = 13; + + public static final int SESSION_STREAM_ERROR = 15; + + int reason; + + Throwable cause; + + /** + * Create an exception with the given description and reason. + * @param msg + * @param reason + */ + + public SocketAdapterException(String msg, int reason) { + this(msg, reason, null); + } + + /** + * Create an exception with the given cause and reason. + * @param reason + * @param cause + */ + public SocketAdapterException(int reason, Throwable cause) { + this(null, reason, cause); + } + + /** + * Create an exception with the given description and cause. The reason given + * will be INTERNAL_ERROR. + * + * @param msg + * @param cause + */ + public SocketAdapterException(String msg, Throwable cause) { + this(msg, INTERNAL_ERROR, cause); + } + + /** + * + * @param msg + */ + public SocketAdapterException(String msg) { + this(msg, INTERNAL_ERROR, null); + } + + /** + * Create an exception by providing the cause of the error. This constructor + * sets the reason to INTERNAL_ERROR. + * @param cause + */ + public SocketAdapterException(Throwable cause) { + this("An unexpected exception was caught: " + cause.getMessage(), cause); + } + + /** + * Create an exception with the given description cause, reason. + * @param msg + * @param reason + * @param cause + */ + public SocketAdapterException(String msg, int reason, Throwable cause) { + super(msg); + this.cause = cause; + this.reason = reason; + } + + /** + * Get the reason for the exception + * @return + */ + public int getReason() { + return reason; + } + + /** + * If an INTERNAL_ERROR reason is given this method MAY return the cause of + * the error. + * @return + */ + @Override + public synchronized Throwable getCause() { + return cause; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/StopWatch.java b/src/main/java/com/eactive/eai/adapter/socket2/common/StopWatch.java new file mode 100644 index 0000000..1fb8aec --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/StopWatch.java @@ -0,0 +1,73 @@ +package com.eactive.eai.adapter.socket2.common; + + +public class StopWatch { + private long startTime = -1; + private long stopTime = -1; + private final int HIM = 60 * 60 * 1000; + private final int MIM = 60 * 1000; + + public StopWatch() { + super(); + } + + public void start() { + this.startTime = System.currentTimeMillis(); + } + + public void stop() { + this.stopTime = System.currentTimeMillis(); + } + + public void reset() { + this.startTime = -1; + this.stopTime = -1; + } + + public long getTime() { + if (stopTime == -1) { + return (System.currentTimeMillis() - this.startTime); + } else { + return (this.stopTime - this.startTime); + } + } + + public String toString() { + return getTimeString(); + } + + protected String getTimeString() { + int hours; + int minutes; + int seconds; + int milliseconds; + long time = getTime(); + hours = (int) (time / HIM); + time = time - (hours * HIM); + minutes = (int) (time / MIM); + time = time - (minutes * MIM); + seconds = (int) (time / 1000); + time = time - (seconds * 1000); + milliseconds = (int) time; + + return hours + "h:" + minutes + "m:" + seconds + "s:" + milliseconds + "ms"; + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// StopWatch stopWatch = new StopWatch(); +// stopWatch.start(); +// +// try { +// Thread.currentThread().sleep(1500); +// } catch (InterruptedException ie) { +// System.out.println("error"); +// } +// +// stopWatch.stop(); +// System.out.println(stopWatch); +// } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/common/ThreadDumpUtil.java b/src/main/java/com/eactive/eai/adapter/socket2/common/ThreadDumpUtil.java new file mode 100644 index 0000000..8662de3 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/common/ThreadDumpUtil.java @@ -0,0 +1,142 @@ +package com.eactive.eai.adapter.socket2.common; + +import java.util.Arrays; +import java.util.Hashtable; + + +public class ThreadDumpUtil { + public String threadDump() throws Exception { +// //name = "ExecuteThread: '"+name+"' for queue: 'weblogic.kernel.Default'"; +// ThreadGroup it = Thread.currentThread().getThreadGroup(); +// +// out.println("[group] " + it.getName() + "

"); +// +// Thread[] threads = new Thread[it.activeCount()] ; +// out.println("active count : "+it.activeCount() + "

"); +// it.enumerate(threads); +// out.println(""); +// for(int i=0;i"); +// out.println(getStackTrace(threads[i])); +// out.println(""); +// } +// } +// out.println("
"); + return null; + } + + static private String getStackTrace(Thread thread) { + StringBuffer sb = new StringBuffer(); + sb.append("■ " + thread.getName() + " "); + sb.append("prio=" + thread.getPriority() + " "); + sb.append(thread.isDaemon() ? "daemon " : " "); + + StackTraceElement stack[] = thread.getStackTrace(); + + if (stack==null || stack.length<1) + return sb.toString(); + + if (stack[0].getMethodName().equals("wait")) + sb.append("wait \n"); + else if (stack[0].getMethodName().equals("sleep")) + sb.append("sleep \n"); + else + sb.append(stack[0].getMethodName() + " \n"); + + for (int i=0; i at "); + else + sb.append(" at "); + sb.append(className + "." + methodName); + sb.append("(" + filename + ":" + (isNativeMethod ? "native" : String.valueOf(line)) + ")"); + if (!className.startsWith("java") && !className.startsWith("org.") && !className.startsWith("sun.") && !className.startsWith("com.sun.")) + sb.append("-"); + sb.append("\n"); + } + +// if (stack[0].getMethodName().equals("wait")) +// return "" + sb.toString() + ""; +// else if (stack[0].getMethodName().equals("sleep")) +// return "" + sb.toString() + ""; +// else + return sb.toString(); + } + + static public String dump() { + Hashtable hash = new Hashtable(); + + StringBuffer sb = new StringBuffer(); + ThreadGroup it = Thread.currentThread().getThreadGroup(); + //sb.append("[group] " + it.getName() + "\n"); + Thread[] threads = new Thread[it.activeCount()] ; + sb.append("active thread count : " + it.activeCount() + "\n"); + it.enumerate(threads); + + //---------------------------------------------------------------------- + ///* + String[] threadNames = new String[threads.length]; + for (int i=0; i Integer.parseInt(props[2])) return false; + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/config/Constants.java b/src/main/java/com/eactive/eai/adapter/socket2/config/Constants.java new file mode 100644 index 0000000..2d96fed --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/config/Constants.java @@ -0,0 +1,210 @@ +/* + * Created on 2005. 7. 10. + * + */ +package com.eactive.eai.adapter.socket2.config; + +/** +* 1. 기능 : Socket Adapter의 구성정보를 지정하기 위한 property의 KEY값을 나타낸다. +* 2. 처리 개요 : +* - +* 3. 주의사항 +* +* @param +* @return +* @exception +**/ +public interface Constants { + + //public static final String ADAPTER_NAME = "adapter.name"; + + /** + * Socket Adapter의 Adapter Group명을 나타낸는 KEY값 + */ + public static final String ADAPTER_GROUP_NAME = "adapter.group.name"; + + + /** + * protocol [FIXED_LENGTH_HEADER|CISCO|XECURE|CERT|ADMIN|HTTP] + */ + public static final String PROTOCOL = "protocol"; + + + /** + * Socket Adapter가 INBOUND/OUTBOUND/IOBOUND용인지 나타내기위한 KEY값 + */ + public static final String BOUND_USAGE = "bound.usage"; + + /** + * Socket Adapter의 SOCKET유형이 [SERVER|CLIENT]에 구분을 나타 + */ + public static final String SOCKET_TYPE = "socket.type"; + public static final String PERMANENT = "permanent"; + public static final String BLOCKING = "blocking"; + public static final String POLLING_TYPE = "polling.type"; + public static final String HOST_NAME = "host.name"; + public static final String HOST_NAME_DR = "host.name.dr"; + public static final String PORT_NUMBER = "port.number"; + public static final String PORT_NUMBER_DR = "port.number.dr"; + public static final String LOCAL_HOST_NAME = "local.host.name"; + public static final String LOCAL_PORT_NUMBER = "local.port.number"; + public static final String CONN_LIMIT_PER_IP = "connection.limit.per.ip"; + public static final String MAX_CONNECTION = "max.connection"; + public static final String MAX_THREAD = "max.thread"; + public static final String TIMEOUT = "timeout"; + public static final String IDLE_TIMEOUT = "idle.timeout"; + public static final String RESPONSE_TYPE = "response.type"; + public static final String SOCKET_REUSE = "socket.reuse"; + + public static final String LL_FIELD_TYPE = "ll.field.type"; // [BIN|CHAR|CISCO] + public static final String LL_FIELD_LENGTH = "ll.field.length"; + public static final String LL_FIELD_OFFSET = "ll.field.offset"; + public static final String LL_FIELD_INCLUDE = "ll.field.include"; + public static final String LL_OFFSET_EXCLUDE = "ll.offset.exclude"; + public static final String LL_INCLUDE = "ll.include"; + + public static final String LL_LENGTH_ADJUST = "ll.length.adjust"; + + public static final String SEND_HEADER_LENGTH = "send.header.length"; // 2012.10.30 Kwon Se Hwan + public static final String RECV_HEADER_LENGTH = "recv.header.length"; // 2012.10.30 Kwon Se Hwan + + public static final String SEND_PAYLOAD_LENGTH = "send.payload.length"; + public static final String RECV_PAYLOAD_LENGTH = "recv.payload.length"; + + public static final String ACK_SUPPORT = "ack.support"; + public static final String VALIDATION_RULE = "validation.rule"; + public static final String DATACONTROL_RULE = "datacontrol.rule"; + public static final String ACL_LIST = "acl.list"; + public static final String WORK_CLASS_CODE = "business.work.class.code"; + public static final String TRACE_LEVEL = "trace.level"; + public static final String DESCRIPTION = "description"; + + public static final String POLLING_USE = "polling.use"; + public static final String POLLING_ROLE = "polling.role"; + public static final String POLLING_ONEWAY = "polling.oneway"; + public static final String POLLING_TIMEOUT = "polling.timeout"; + public static final String POLLING_REQUEST = "polling.request"; + public static final String POLLING_REQUEST_PATTERN = "polling.request.pattern"; + public static final String POLLING_REPLACEMENT = "polling.replacement"; + public static final String POLLING_RESPONSE_PATTERN = "polling.response.pattern"; + + public static final String INIT_MSG_USE = "init.msg.use"; + public static final String INIT_MSG_ROLE = "init.msg.role"; + public static final String INIT_MSG_REQUEST = "init.msg.request"; + public static final String INIT_MSG_REQUEST_PATTERN = "init.msg.request.pattern"; + public static final String INIT_MSG_REPLACEMENT = "init.msg.replacement"; + public static final String INIT_MSG_RESPONSE_PATTERN = "init.msg.response.pattern"; + + public static final String SSL_USE = "ssl.use"; + public static final String SSL_CERT_STORE = "ssl.cert.store"; + public static final String SSL_CERT_PASSWORD = "ssl.cert.password"; + + public static final String DES_USE = "des.use"; + + public static final String SEED_USE = "seed.use"; + + /** + * inisafe + */ + public static final String INISAFE_CONFIG_PATH = "inisafe.config.path"; + public static final String INISAFE_RELATED_ADAPTER_GROUPS = "inisafe.related.adapter.groups"; + public static final String INISAFE_START_MESSAGE = "inisafe.start.message"; + public static final String INISAFE_STOP_MESSAGE = "inisafe.stop.message"; + + /** + * inisafe_payload 20100515 JGY + */ + public static final String INISAFE_ID_PASSWORD = "inisafe.id.password"; + + /** + * SMS running time + */ + public static final String SMS_RUNNING_TIME = "sms.running.time"; + + + /** + * xecure + */ + public static final String XECURE_TYPE = "xecure.type"; + public static final String XECURE_CONFIG_PATH = "xecure.config.path"; + public static final String XECURE_REMOTE_CERT = "xecure.remote.cert"; + + /** + * xecure2 + */ + public static final String XECURE2_CONFIG_PATH = "xecure2.config.path"; + public static final String XECURE2_SM_IP = "xecure2.sm.ip"; + public static final String XECURE2_SM_PORT = "xecure2.sm.port"; + + + /** + * xecure3 20100901 JGY + */ + public static final String XECURE3_CERT_STORE = "xecure3.cert.store"; + public static final String XECURE3_SERVER_CERT = "xecure3.server.cert"; + public static final String XECURE3_CLIENT_CERT = "xecure3.client.cert"; + public static final String XECURE3_CERT_KEY = "xecure3.cert.key"; + public static final String XECURE3_CERT_PASSWORD = "xecure3.cert.password"; + + /** + * xecure3 20210929 epb + */ + public static final String XC3EPB_PASSWORD = "xc3epb.password"; + public static final String XC3EPB_CONFIG_PATH = "xc3epb.config.path"; + + /** + * envelop + */ + public static final String ENVELOP_SIGNCERT_PATH = "envelop.signcert.path"; + public static final String ENVELOP_SIGNKEY_PATH = "envelop.signkey.path"; + public static final String ENVELOP_PASSWORD = "envelop.password"; + + /** + * tcseed 20101213 JGY + */ + public static final String TCSEED_KEY_STORE = "tcseed.key.store"; + + /** + * login client + */ + public static final String LOGIN_SEND = "login.send"; + public static final String LOGIN_RECV = "login.recv"; + public static final String BIND_TYPE = "bind.type"; + public static final String LL_FIELD_LENGTH_ALPHA = "ll.field.length.alpha"; + + /** + * inicis pg + */ + public static final String INICIS_KEY_PATH = "inicis.key.path"; + public static final String INICIS_KEY_PASS = "inicis.key.pass"; + + /** + * delimiter + */ + public static final String DELIMITER = "delimiter"; + /** + * append protocol + */ + public static final String APPEND_HEAD = "append.head"; + public static final String APPEND_TAIL = "append.tail"; + + /** + * block ip list + */ + public static final String BLOCK_IP_LIST = "block.ip.list"; + + /** + * l4 skip ip list + */ + public static final String L4_SKIP_IP_LIST = "l4.skip.ip.list"; + + public static final String IS_SINGLE_SESSION = "is.single.session"; + public static final String SINGLE_PRIMARY_INST = "single.primary.inst"; + + + public static final String DYNAMIC_OFFSET_PATTERN = "dynamic.offset.pattern"; + public static final String DATA_ADD_RULE = "data.add.rule"; + public static final String DATA_REMOVE_RULE = "data.remove.rule"; + + public static final String KEEP_ALIVE = "keep.alive"; +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/config/MonitoringUtil.java b/src/main/java/com/eactive/eai/adapter/socket2/config/MonitoringUtil.java new file mode 100644 index 0000000..611961e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/config/MonitoringUtil.java @@ -0,0 +1,300 @@ +package com.eactive.eai.adapter.socket2.config; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; + +public class MonitoringUtil { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + + private MonitoringUtil() { + + } + + public static String[][] adapterStatus(String adapterGroupName) throws Exception { + Vector list = new Vector<>(); + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups(); + AdapterManager gmanager = AdapterManager.getInstance(); + + if (existsAdapterGroup(adapterGroupName)) { + AdapterGroupVO gvo = gmanager.getAdapterGroupVO(adapterGroupName); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) { + String[] info = new String[12]; + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + info[0] = adapterGroupName; + info[1] = adapter.getContext().getAdapterName(); + info[2] = adapter.getContext().getDescription(); + info[3] = adapter.getContext().getBoundUsage(); + info[4] = String.valueOf(getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName())); + info[5] = ""; // gvo.getRealTimeGroupName(); + info[6] = "1"; // gvo.isRealTimeBzwkFlag() ? "1" : "0"; + info[7] = adapter.getState().toString(); + info[8] = gvo.getKesaUseYn(); + info[9] = gvo.getTestMasterYn(); + info[10] = gvo.getAdptrNickName(); + info[11] = gvo.getCompanyCodeData(); + list.add(info); + } + } + + String[][] adapters = new String[list.size()][5]; + for (int i = 0; i < list.size(); i++) { + adapters[i] = list.get(i); + } + return adapters; + } + + public static String[][] adapterList1() throws Exception { + Vector list = new Vector<>(); + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups(); + AdapterManager gmanager = AdapterManager.getInstance(); + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = (String) e.nextElement(); + if (!existsAdapterGroup(adapterGroupName)) { + continue; + } + AdapterGroupVO gvo = gmanager.getAdapterGroupVO(adapterGroupName); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) { + String[] info = new String[12]; + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + info[0] = adapterGroupName; + info[1] = adapter.getContext().getAdapterName(); + info[2] = adapter.getContext().getDescription(); + info[3] = adapter.getContext().getBoundUsage(); + info[4] = String.valueOf(getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName())); + info[5] = ""; // gvo.getRealTimeGroupName(); + info[6] = "1"; // gvo.isRealTimeBzwkFlag() ? "1" : "0"; + info[7] = adapter.getState().toString(); + info[8] = gvo.getKesaUseYn(); + info[9] = gvo.getTestMasterYn(); + info[10] = gvo.getAdptrNickName(); + info[11] = gvo.getCompanyCodeData(); + list.add(info); + } + } + + String[][] adapters = new String[list.size()][5]; + for (int i = 0; i < list.size(); i++) { + adapters[i] = list.get(i); + } + return adapters; + } + + public static String[][] adapterList2() throws Exception { + Vector list = new Vector(); + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups(); +// AdapterManager gmanager = AdapterManager.getInstance(); + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = (String) e.nextElement(); + if (!existsAdapterGroup(adapterGroupName)) { + continue; + } +// AdapterGroupVO gvo = gmanager.getAdapterGroupVO(adapterGroupName); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) { + String[] info = new String[11]; + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + info[0] = adapterGroupName; + info[1] = adapter.getContext().getAdapterName(); + info[2] = adapter.getContext().getDescription(); + info[3] = String.valueOf(adapter.getContext().getMaxConnection()); + info[4] = String.valueOf(adapter.getSessionPool().peekSize()); + info[5] = String.valueOf(adapter.getMessageSend()); + info[6] = String.valueOf(adapter.getMessageRecv()); + info[7] = String.valueOf(adapter.getRecentErrorCount()); + info[8] = String.valueOf(getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName())); + info[9] = ""; // gvo.getRealTimeGroupName(); + info[10] = "1"; // gvo.isRealTimeBzwkFlag() ? "1" : "0"; + list.add(info); + } + } + + String[][] adapters = new String[list.size()][7]; + for (int i = 0; i < list.size(); i++) { + adapters[i] = list.get(i); + } + return adapters; + } + + public static String[][] adapterInstList() throws Exception { + Vector list = new Vector(); + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups(); +// AdapterManager gmanager = AdapterManager.getInstance(); + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = (String) e.nextElement(); + if (!existsAdapterGroup(adapterGroupName)) { + continue; + } +// AdapterGroupVO gvo = gmanager.getAdapterGroupVO(adapterGroupName); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) { + String[] info = new String[6]; + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + info[0] = adapterGroupName; + info[1] = adapter.getContext().getAdapterName(); + info[2] = adapter.getContext().getDescription(); + info[3] = String.valueOf(adapter.getMessageSend()); + info[4] = String.valueOf(adapter.getMessageRecv()); + info[5] = String.valueOf(adapter.getRecentErrorCount()); + list.add(info); + } + } + + String[][] adapters = new String[list.size()][6]; + for (int i = 0; i < list.size(); i++) { + adapters[i] = list.get(i); + } + return adapters; + } + + public static String[][] adapterTraceLevel() throws Exception { + Vector list = new Vector(); + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups(); + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = (String) e.nextElement(); + if (!existsAdapterGroup(adapterGroupName)) { + continue; + } + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) { + String[] info = new String[5]; + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + info[0] = adapterGroupName; + info[1] = adapter.getContext().getAdapterName(); + info[2] = adapter.getContext().getDescription(); + info[3] = String.valueOf(getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName())); + info[4] = String.valueOf(adapter.getContext().getTraceLevel()); + list.add(info); + } + } + + String[][] adapters = new String[list.size()][4]; + for (int i = 0; i < list.size(); i++) { + adapters[i] = list.get(i); + } + return adapters; + } + + public static String[] adapterError(String adapterGroupName, String adapterName) throws Exception { +// StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterGroupName + "." + adapterName); + if (adapter == null) + return new String[0]; + + return adapter.getRecentErrors(); + } + + public static String[][] sessionList(String adapterGroupName) throws Exception { + Vector list = new Vector(); + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups(); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + + if (adapters == null || !existsAdapterGroup(adapterGroupName)) { + return new String[0][14]; + } + + for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) { + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + for (Iterator iter = adapter.getSessionPool().iterator(); iter.hasNext();) { + String[] info = new String[14]; + IoSession session = (IoSession) iter.next(); + info[0] = adapterGroupName; + info[1] = adapter.getContext().getAdapterName(); + info[2] = adapter.getContext().getDescription(); + info[3] = adapter.getContext().getBwkClsCd(); + info[4] = adapter.getContext().getBoundUsage(); + info[5] = adapter.getContext().getSocketType(); + info[6] = adapter.getContext().getAckSupport(); + info[7] = session.getLocalAddress().toString(); + info[8] = session.getRemoteAddress().toString(); + info[9] = String.valueOf(session.getWrittenMessages()); + info[10] = String.valueOf(session.getReadMessages()); + info[11] = getDateTime(session.getCreationTime()); + info[12] = getDateTime(session.getLastIoTime()); + info[13] = session.toString(); + list.add(info); + } + } + + String[][] sessions = new String[list.size()][13]; + for (int i = 0; i < list.size(); i++) { + sessions[i] = list.get(i); + } + return sessions; + } + + public static void adapterStart(String adapterGroupName, String adapterName) throws Exception { + SocketAdapterManager.getInstance().start(adapterGroupName, adapterName); + } + + public static void adapterStop(String adapterGroupName, String adapterName) throws Exception { + SocketAdapterManager.getInstance().stop(adapterGroupName, adapterName); + } + + public static void adapterChangeTraceLevel(String adapterGroupName, String adapterName, int traceLevel) + throws Exception { + ISocketAdapter adapter = SocketAdapterManager.getInstance().getSocketAdapter(adapterGroupName, adapterName); + if (adapter != null) + adapter.getContext().setTraceLevel(traceLevel); + } + +// public static void sessionClose(String adapterGroupName, String adapterName, String remoteAddress, String localAddress) throws Exception { +// ISocketAdapter adapter = SocketAdapterManager.getInstance().getSocketAdapter(adapterGroupName, adapterName); +// IoSession session = adapter.getSessionPool().find(remoteAddress, localAddress); +// if (session != null) +// session.close(); +// } + + public static void sessionClose(String adapterGroupName, String sessionName) throws Exception { +// Vector list = new Vector(); + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) manager.getSocketAdapterGroups(); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + + for (Enumeration ee = adapters.elements(); ee.hasMoreElements();) { + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + for (Iterator iter = adapter.getSessionPool().iterator(); iter.hasNext();) { + IoSession session = (IoSession) iter.next(); + if (sessionName.equals(session.toString())) { + session.close(); + return; + } + } + } + } + + private static boolean getAdapterStatus(String adapterGroupName, String adapterName) { + AdapterManager manager = AdapterManager.getInstance(); + AdapterVO vo = manager.getAdapterVO(adapterGroupName, adapterName); + if (vo != null) + return vo.isStatus(); + return false; + } + + private static boolean existsAdapterGroup(String adapterGroupName) { + AdapterManager manager = AdapterManager.getInstance(); + AdapterGroupVO gvo = manager.getAdapterGroupVO(adapterGroupName); + if (gvo != null) + return true; + return false; + } + + private static String getDateTime(long time) { + Instant instant = Instant.ofEpochMilli(time); + ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); + return dateFormat.format(zdt); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/config/SocketAdapterContext.java b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketAdapterContext.java new file mode 100644 index 0000000..245e677 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketAdapterContext.java @@ -0,0 +1,1329 @@ +package com.eactive.eai.adapter.socket2.config; + +import java.io.Serializable; +import java.util.Properties; +import java.util.concurrent.Semaphore; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.protocol.IRequestProcessor; + + +/** +* 1. 기능 : SocketAdapter의 구성정보 및 속성을 나타내는 Object Class +* 2. 처리 개요 : +* - 구성정보의 DEFAULT값을 갖고 있으며, 각 속성에 대한 getter/setter 기능을 제공한다. +* 3. 주의사항 +* - 해당 Property의 기본속성값을 확인하여, 해당 Property의 속성지정을 생략시 어떤 값을 갖는지 확인하여야한다. +**/ + +public class SocketAdapterContext implements Serializable { + public static final String INBOUND_SOCKET = "INBOUND"; + public static final String OUTBOUND_SOCKET = "OUTBOUND"; + public static final String IOBOUND_SOCKET = "IOBOUND"; + + public static final String SERVER_SOCKET = "SERVER"; + public static final String CLIENT_SOCKET = "CLIENT"; + public static final String ADMIN_SOCKET = "ADMIN"; + + public static final String SYNC_MODE = "SYNC"; + public static final String ASYNC_MODE = "ASYN"; + +// public static final String ACKON_MODE = "AKON"; + + public static final String TRUE_FLAG = "Y"; + public static final String FALSE_FLAG = "N"; + + /** + * trace level + */ + public static final int TRACE_LEVEL_DEFAULT = 0; // WARNING, ERROR, FATAL인 경우 에러로깅 + public static final int TRACE_LEVEL_INFO = 1; // INFO 수준의 LOGGING을 수행한다. + public static final int TRACE_LEVEL_DEBUG = 2; // DEBUG 수준의 송수신전문 및 에러 메인처리내용의 모든수준의 로깅을 수행한다. + public static final int TRACE_LEVEL_TRACE = 3; // TRACE 수준의 송수신전문 및 에러 메인처리내용의 모든수준의 로깅을 수행한다. + + /** + * xecure type + */ + public static final String XECURE_TYPE_BASIC = "BASIC"; + public static final String XECURE_TYPE_FIXED = "FIXED"; + public static final String XECURE_TYPE_WELCOME = "WELCOME"; + public static final String XECURE_TYPE_ENVELOPE = "ENVELOPE"; // 전자봉투 + public static final String XECURE_TYPE_FIXEDHEADER = "FIXEDHEADER"; + + /** + * Configuration properties + */ + private String adapterGroupName = "AdapterGroup"; // SOCKET ADADAPTER GROUP NAME + private String adapterName = "Adapter"; // SOCKET ADAPTER 구성 이름 + + private String protocol = "FIXED_LENGTH_HEADER"; //FIXED_LENGTH_HEADER | CISCO | ADMIN | XECURE | CERT | HTTP + private String permanent = "Y"; // Permanent or Non-Permanent + + private String boundUsage = IOBOUND_SOCKET; // INBOUND | OUTBOUND | IOBOUND + private String socketType = CLIENT_SOCKET; // SERVER | CLIENT + + + private String hostName = "localhost"; // BIND할 서버의 호스트명 또는 IP ADDRESS + private int portNumber = 0; // BIND할 서버의 PORT NUMBER + + private String localHostName = ""; // Client Socket Type에 한하여 설정 + private int localPortNumber = 0; // Client Socket Type으로 원격서버와 연결시 BIND할localPortNumber + + private int connLimitPerIp = 0; // SERVER TYPE SOCKET의 경우 REMOTE의 특정 IP별 CONNECTION 수를 제한시키는 것 + private int maxConnection = 0; // 원격시스템과 Socket Connection 최대허용 수 + // Server Socket의 경우 - Server Listening port로 접속허용할 최대 수 + // Client Socket의 경우 - Remote Host의 지정 포트로 연결할 최대 Connection 수 + private Semaphore maxConnSemaphore = null; + private boolean bCloseExistingConnection = false; // maxConnection < 0 일 경우 이전 'YOUNG' connection을 끊고 새로운 connection을 맺는다. + // negative(-) 옵션을 준 상태에서 세션이 Full 상태 일때, 가장 오래 된 세션을 끊고 새로운 세션을 연결한다. + private boolean bCloseExistingConnectionPerIpLimit = false; // maxConnectionPerIp < 0 일 경우 이전 'OLDEST' connection을 끊고 새로운 connection을 맺는다. + + private int maxThread = 10; // INBOUND의 경우한하여 의미가 있음. +// private int maxThread = 1; // Worker Thread default 1로 조정, 2009.10.16 + // Socket Adapter의 N개의 Connection에 대해 session을 연결할 최대 수 (실행 Thread Pool의 Session수) + + private int timeout = 60; // Socket Read Timeout & Transaction Timeout 값 설정 (단위 : 초) + + private int idleTimeout = 0; // 초단위 + + private String responseType = SYNC_MODE; // SYNC_MODE, ASYNC_MODE + private String socketReuse = TRUE_FLAG; // "Y" - Socket Connection reuse + + /** + * client & non-perm & fixed_length_header & sync + * 일 경우 서버에서 응답을 주고 connection 을 끊는 경우 처리를 위하여 + * 예) 데이콤 + */ + private String blocking = "N"; + + /** + * ll + */ + private String llFieldType = "BIN"; // BIN(Binary), CHAR(Numeric Character), CISCO + private int llFieldLength = 2; // LL필드길이 2-unsigned short, 4 ~ 8 Numeric Char + private int llFieldOffset = 0; // LL 필드가 중간에 있을 경우 offset + private String llFieldInclude = FALSE_FLAG; // LL 필드 length 가 (header=ll) 을 포함하는가? + private String llOffsetExclude = FALSE_FLAG; // Offset을 포함하여 LL Length를 계산할 것인가? + private String llInclude = FALSE_FLAG; // LL 필드를 포함하여 F/W 에 던질 것인가? + + private int llLenAdjust = 0; // 한은맘 헤더 길이 평문테스트 용 + + /** + * payload length + */ + private int sendPayloadLength = 0; + private int recvPayloadLength = 0; + + /** + * variable header length + */ + private int sendHeaderLength = 0; + private int recvHeaderLength = 0; + + + + private String ackSupport = FALSE_FLAG; // ACK송수신 여부 -- Client Type의 Socket에 적용되며, 서버는 Protocol에 의해 작동판단... + private String bwkClsCd = ""; // 업무구분코드 + + private String validationRule = ""; + + /** + * dataControlRule 금결원 + */ + private String dataControlRule = ""; + + private int traceLevel = TRACE_LEVEL_DEFAULT; // 추적관리 수준 - 0, 1, 2 + private String description = ""; // Socket Adapter Configuration에 대한 용도설명 + + /** + * acl + */ + private String aclList = ""; + + /** + * script (groovy | response message) + */ + private String script = ""; + + /** + * polling + */ + private String pollingUse = "N"; + private String pollingRole = ""; // SENDER|RECEIVER + private String pollingOneway = "N"; // Y|N + private int pollingTimeout = 600; + private String pollingRequest = "HDRREQPOLL%d{MMddHHmmss}"; + private String pollingRequestPattern = "(HDR)?(REQPOLL)([0-9]{10})"; + private String pollingReplacement = "$1RESPOLL$3"; + private String pollingResponsePattern = "(HDR)?(RESPOLL)([0-9]{10})"; + + /** + * init Message + */ + private String initMsgUse = "N"; + private String initMsgRole = ""; // SENDER|RECEIVER + private String initMsgRequest = "INITREQMSG%d{MMddHHmmss}"; + private String initMsgRequestPattern = "(INIT)?(REQMSG)([0-9]{10})"; + private String initMsgReplacement = "$1RESMSG$3"; + private String initMsgResponsePattern = "(INIT)?(RESMSG)([0-9]{10})"; + + /** + * Security - SSL + */ + private String sslUse = "N"; + private String sslCertStore = ""; // SSL용 보안 인증서, TCSEED용 Key저장소 + private String sslCertPassword = ""; // SSL용 인증서 암호 + + /** + * inisafe + */ + private String inisafeConfigPath = ""; + private String inisafeRelatedAdapterGroups = ""; + private String inisafeStartMessage = "STARTED"; + private String inisafeStopMessage = "STOPPED"; + + /** + * inisafe_payload + */ + private String inisafeIdPassword = ""; // 은행코드(3) + ID(8) + Password(20) + + /** + * SMS + */ + private String smsRunningTime = ""; + + /** + * XC (XecureConnect) + */ + private String xecureType = ""; // XC 보안 모듈 타입 (TYPEA, TYPEB, ..) + private String xecureConfigPath = ""; // XecureConnect 설정에 필요한 정보 (인증서정보, 세팅사항 등..) + private String xecurePassword = ""; // 개인키 추출을 위한 비밀번호 문자열 + private String xecureRemoteCert = ""; // 전자봉투 방식 - remote cert file + + /** + * Xecure2 Connect[Session Manager] + */ + private String xecure2ConfigPath = ""; // example : "/fshome/greai/eaiadm/softforum/xc20/conf/cert.txt"; + private String xecure2SmIp = "127.0.0.1"; + private int xecure2SmPort = 9300; + + /** + * Xecure3 Connect + */ + private String xecure3CertStore = "/fshome/greai/eaiadm/softforum/xc30/certstore"; + private String xecure3ServerCert = "/fshome/greai/eaiadm/softforum/xc30/cert/kb/SignCert.der"; + private String xecure3CertKey = "/fshome/greai/eaiadm/softforum/xc30/cert/kb/signPri.key"; + private String xecure3ClientCert = "/fshome/greai/eaiadm/softforum/xc30/cert/army/SignCert.der"; + private String xecure3CertPassword = "qwer1234"; + + /** + * Xecure3 epb + */ + private String xc3epbPassword = ""; // 개인키 추출을 위한 비밀번호 문자열 + private String xc3epbConfigPath = ""; // XecureConnect3 설정에 필요한 정보 (인증서정보, 세팅사항 등..) + + /** + * ENVELOP Connect[Session Manager] + */ + private String envelopSigncertPath = ""; // example : "/fshome/greai/eaiadm/softforum/xc20/conf/signCert.der" + private String envelopSignkeyPath = ""; // example : "/fshome/greai/eaiadm/softforum/xc20/conf/signPri.key" + private String envelopPassword = ""; // example : "qwer1234"; + + /** + * login client + */ + private String loginSend = ""; + private String loginRecv = ""; + private String bindType = ""; + private int llFieldLengthAlpha = 0; + + /** + * Security - TCSEED + */ + private String tcseedKeyStore = ""; // TCSEED용 Key저장소 + + /** + * inisis + */ + private String inicisKeyPath =""; + private String inicisKeyPass =""; + + /** + * append protocol + */ + private String appendHead =""; + private String appendTail =""; + + /** + * block ip list + */ + private String blockIpList =""; + + /** + * l4 skip ip list + */ + private String l4SkipIpList =""; + /** + * delimiter + */ + private String delimiter =""; + + /** + * IS_SINGLE_SESSION + */ + private String singleSession = "N"; // Y : 기관 허용세션이 1인 경우 + + // 기관 허용세션이 1이면서 Active/Active 인스던스 2개 운영시 Primary 인스던스명 - 싱글어댑터 속성 + private String primaryInstId = ""; + + + private String dynamicOffsetPattern = ""; + private String dataAddRule = ""; + private String dataRemoveRule = ""; + + /** + * SO_KEEPALIVE + */ + private String keepAlive = "N"; // Y : TCP KeepAlive option + + + /** + * + */ + private AdapterVO adapterVO = null; + private IRequestProcessor requestProcessor = null; + private boolean started = true; + + + + public SocketAdapterContext() { + } + + public SocketAdapterContext(Properties prop) { + this.adapterGroupName = prop.getProperty("ADAPTER_GROUP_NAME", "").trim(); + this.adapterName = prop.getProperty("ADAPTER_NAME", "").trim(); + this.hostName = prop.getProperty("HOST_NAME", "").trim(); + this.portNumber = Integer.parseInt(prop.getProperty("PORT_NUMBER", "").trim()); + this.traceLevel = Integer.parseInt(prop.getProperty("TRACE_LEVEL", "2").trim()); + + this.socketType = prop.getProperty("SOCKET_TYPE", CLIENT_SOCKET).trim(); + this.boundUsage = prop.getProperty("BOUND_USAGE", OUTBOUND_SOCKET).trim(); + this.ackSupport = prop.getProperty("ACK_SUPPORT", FALSE_FLAG).trim(); + this.protocol = prop.getProperty("PROTOCOL", "FIXED_LENGTH_HEADER").trim(); + this.llFieldType = prop.getProperty("LL_FIELD_TYPE", "BIN").trim(); + this.llFieldLength = Integer.parseInt(prop.getProperty("LL_FIELD_LENGTH", "2").trim()); + this.llFieldOffset = Integer.parseInt(prop.getProperty("LL_FIELD_OFFSET", "0").trim()); + this.llFieldInclude = prop.getProperty("LL_FIELD_INCLUDE", "N").trim(); + this.llOffsetExclude = prop.getProperty("LL_OFFSET_EXCLUDE", "N").trim(); + this.llInclude = prop.getProperty("LL_INCLUDE", "N").trim(); + this.responseType = prop.getProperty("RESPONSE_TYPE", "SYNC").trim(); + this.timeout = Integer.parseInt(prop.getProperty("TIMEOUT", "60").trim()); + this.maxConnection = Integer.parseInt(prop.getProperty("MAX_CONNECTION", "1").trim()); + this.maxConnSemaphore = new Semaphore(this.maxConnection > 0 ? this.maxConnection : -this.maxConnection); + this.permanent = prop.getProperty("PERMANENT", "Y").trim(); + this.aclList = prop.getProperty("ACL_LSIT", "").trim(); + + this.recvHeaderLength = Integer.parseInt(prop.getProperty("RECV_HEADER_LENGTH", "0").trim()); + this.sendHeaderLength = Integer.parseInt(prop.getProperty("SEND_HEADER_LENGTH", "0").trim()); + + this.smsRunningTime = prop.getProperty("SMS_RUNNING_TIME", "").trim(); + + this.pollingUse = prop.getProperty("POLLING_USE", "N").trim(); + + this.initMsgUse = prop.getProperty("INIT_MSG_USE", "N").trim(); + + this.singleSession = prop.getProperty("IS_SINGLE_SESSION", "N").trim(); + + this.keepAlive = prop.getProperty("KEEP_ALIVE", "N").trim(); + + } + + public String getAdapterGroupName() { + return adapterGroupName; + } + + public void setAdapterGroupName(String adapterGroupName) { + this.adapterGroupName = adapterGroupName; + } + + public String getAdapterName() { + return adapterName; + } + + public void setAdapterName(String adapterName) { + this.adapterName = adapterName; + } + + + public void setProtocol(String protocol) { + this.protocol = protocol; + } + + public String getProtocol() { + return this.protocol; + } + + public int getConnLimitPerIp() { + return connLimitPerIp; + } + + public void setConnLimitPerIp(int connLimitPerIp) { + if (connLimitPerIp < 0) { + setCloseExistingConnectionPerIpLimit(true); + this.connLimitPerIp = -connLimitPerIp; + } else { + this.connLimitPerIp = connLimitPerIp; + } + } + + public boolean getCloseExistingConnectionPerIpLimit() { + return this.bCloseExistingConnectionPerIpLimit; + } + + public void setCloseExistingConnectionPerIpLimit(boolean bCloseExistingConnectionPerIpLimit) { + this.bCloseExistingConnectionPerIpLimit = bCloseExistingConnectionPerIpLimit; + } + + public String getBwkClsCd() { + return bwkClsCd; + } + + public void setBwkClsCd(String bizCode) { + this.bwkClsCd = bizCode; + } + + public String getAckSupport() { + return ackSupport; + } + + public void setAckSupport(String ackSupport) { + this.ackSupport = ackSupport; + } + + public String getBoundUsage() { + return boundUsage; + } + + public void setBoundUsage(String boundUsage) { + this.boundUsage = boundUsage; + } + + public void setPermanent(String permanent) { + this.permanent = permanent; + } + + public String getPermanent() { + return permanent; + } + + public boolean isPermanent() { + return "Y".equals(permanent); + } + + public void setPollingUse(String pollingUse) { + this.pollingUse = pollingUse; + } + + public String getPollingUse() { + return pollingUse; + } + + public boolean isPollingUse() { + return "Y".equals(pollingUse); + } + + public void setPollingRole(String pollingRole) { + this.pollingRole = pollingRole; + } + + public String getPollingRole() { + return pollingRole; + } + + public boolean isPollingSender() { + if ("".equals(pollingRole)) { + return isClient(); + } else { + return "SENDER".equals(pollingRole); + } + } + + public boolean isPollingReceiver() { + return !isPollingSender(); + } + + public String getPollingOneway() { + return pollingOneway; + } + + public void setPollingOneway(String oneway) { + this.pollingOneway = oneway; + } + + public boolean isPollingOneway() { + return "Y".equals(pollingOneway); + } + + public void setPollingTimeout(int pollingTimeout) { + this.pollingTimeout = pollingTimeout; + } + + public int getPollingTimeout() { + return pollingTimeout; + } + + + public void setPollingRequest(String pollingRequest) { + this.pollingRequest = pollingRequest; + } + + public String getPollingRequest() { + return pollingRequest; + } + + public void setPollingRequestPattern(String pollingRequestPattern) { + this.pollingRequestPattern = pollingRequestPattern; + } + + public String getPollingRequestPattern() { + return pollingRequestPattern; + } + + public void setPollingResponsePattern(String pollingResponsePattern) { + this.pollingResponsePattern = pollingResponsePattern; + } + + public String getPollingResponsePattern() { + return pollingResponsePattern; + } + + public void setPollingReplacement(String pollingReplacement) { + this.pollingReplacement = pollingReplacement; + } + + public String getPollingReplacement() { + return pollingReplacement; + } + +//KSH + public void setInitMsgUse(String initMsgUse) { + this.initMsgUse = initMsgUse; + } + + public String getInitMsgUse() { + return initMsgUse; + } + + public boolean isInitMsgUse() { + return "Y".equals(initMsgUse); + } + + public void setInitMsgRole(String initMsgRole) { + this.initMsgRole = initMsgRole; + } + + public String getInitMsgRole() { + return initMsgRole; + } + + public boolean isInitMsgSender() { + if ("".equals(initMsgRole)) { + return isClient(); + } else { + return "SENDER".equals(initMsgRole); + } + } + + public boolean isInitMsgReceiver() { + return !isInitMsgSender(); + } + + public void setInitMsgRequest(String initMsgRequest) { + this.initMsgRequest = initMsgRequest; + } + + public String getInitMsgRequest() { + return initMsgRequest; + } + + public void setInitMsgRequestPattern(String initMsgRequestPattern) { + this.initMsgRequestPattern = initMsgRequestPattern; + } + + public String getInitMsgRequestPattern() { + return initMsgRequestPattern; + } + + public void setInitMsgResponsePattern(String initMsgResponsePattern) { + this.initMsgResponsePattern = initMsgResponsePattern; + } + + public String getInitMsgResponsePattern() { + return initMsgResponsePattern; + } + + public void setInitMsgReplacement(String initMsgReplacement) { + this.initMsgReplacement = initMsgReplacement; + } + + public String getInitMsgReplacement() { + return initMsgReplacement; + } + +//----------------------------- + + public String getValidationRule() { + return validationRule; + } + + public void setValidationRule(String validationRule) { + this.validationRule = validationRule; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getAclList() { + return aclList; + } + + public void setAclList(String aclList) { + this.aclList = aclList; + } + + public String getScript() { + return script; + } + + public void setScript(String script) { + this.script = script; + } + + public String getHostName() { + return hostName; + } + + public void setHostName(String hostName) { + this.hostName = hostName; + } + + /** + * ll field + */ + public String getLlFieldType() { + return llFieldType; + } + + public void setLlFieldType(String llFieldType) { + this.llFieldType = llFieldType; + } + + public int getLlFieldOffset() { + return llFieldOffset; + } + + public void setLlFieldOffset(int llFieldOffset) { + this.llFieldOffset = llFieldOffset; + } + + + public int getLlLenAdjust() { + return llLenAdjust; + } + + public void setLlLenAdjust(int llLenAdjust) { + this.llLenAdjust = llLenAdjust; + } + + public int getLlFieldLength() { + return llFieldLength; + } + + public void setLlFieldLength(int llFieldLength) { + this.llFieldLength = llFieldLength; + } + + public String getLlFieldInclude() { + return llFieldInclude; + } + + public void setLlFieldInclude(String llFieldInclude) { + this.llFieldInclude = llFieldInclude; + } + + public String getLlOffsetExclude() { + return llOffsetExclude; + } + + public void setLlOffsetExclude(String llOffsetExclude) { + this.llOffsetExclude = llOffsetExclude; + } + + public String getLlInclude() { + return llInclude; + } + + public void setLlInclude(String llInclude) { + this.llInclude = llInclude; + } + + /** + * payload length + */ + public int getSendPayloadLength() { + return sendPayloadLength; + } + + public void setSendPayloadLength(int sendPayloadLength) { + this.sendPayloadLength = sendPayloadLength; + } + + public int getRecvPayloadLength() { + return recvPayloadLength; + } + + public void setRecvPayloadLength(int recvPayloadLength) { + this.recvPayloadLength = recvPayloadLength; + } + + /** + * ssl + */ + public String getSslUse() { + return sslUse; + } + + public void setSslUse(String sslUse) { + this.sslUse = sslUse; + } + + public String getSslCertStore() { + return sslCertStore; + } + + public void setSslCertStore(String sslCertStore) { + this.sslCertStore = sslCertStore; + } + + public String getSslCertPassword() { + return sslCertPassword; + } + + public void setSslCertPassword(String sslCertPassword) { + this.sslCertPassword = sslCertPassword; + } + + public String getLocalHostName() { + return localHostName; + } + + public void setLocalHostName(String localHostName) { + this.localHostName = localHostName; + } + + public int getLocalPortNumber() { + return localPortNumber; + } + + public void setLocalPortNumber(int localPortNumber) { + this.localPortNumber = localPortNumber; + } + + public int getMaxConnection() { + return maxConnection; + } + + public void setMaxConnection(int maxConnection) { + if (maxConnection < 0) { + setCloseExistingConnection(true); + this.maxConnection = -maxConnection; + } else { + this.maxConnection = maxConnection; + } + + this.maxConnSemaphore = new Semaphore(this.maxConnection); + } + + public boolean getCloseExistingConnection() { + return this.bCloseExistingConnection; + } + + public void setCloseExistingConnection(boolean bCloseExistingConnection) { + this.bCloseExistingConnection = bCloseExistingConnection; + } + + public Semaphore getMaxConnSemaphore() { + return maxConnSemaphore; + } + + public int getMaxThread() { + return maxThread; + } + + public void setMaxThread(int maxThread) { + this.maxThread = maxThread; + } + + public int getPortNumber() { + return portNumber; + } + + public void setPortNumber(int portNumber) { + this.portNumber = portNumber; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public int getIdleTimeout() { + return idleTimeout; + } + + public void setIdleTimeout(int idleTimeout) { + this.idleTimeout = idleTimeout; + } + + public boolean isAckProtocol() { + return this.ackSupport.equals(TRUE_FLAG); + } + + public void setResponseType(String responseType) { + this.responseType = responseType; + } + + public String getResponseType() { + return responseType; + } + + public boolean isSync() { + return this.responseType.equals(SYNC_MODE); + } + + public void setSocketReuse(String socketReuse) { + this.socketReuse = socketReuse; + } + + public String getSocketReuse() { + return socketReuse; + } + + public boolean isSocketReuse() { + return socketReuse.equals(TRUE_FLAG); + } + + public String getSocketType() { + return socketType; + } + + public void setSocketType(String socketType) { + this.socketType = socketType; + } + + public boolean isClient() { + return CLIENT_SOCKET.equals(socketType); + } + + public boolean isServer() { + return SERVER_SOCKET.equals(socketType); + } + + public String getBlocking() { + return blocking; + } + + public void setBlocking(String blocking) { + this.blocking = blocking; + } + + public boolean isBlocking() { + return "Y".equals(blocking); + } + + public int getTraceLevel() { + return traceLevel; + } + + public void setTraceLevel(int traceLevel) { + this.traceLevel = traceLevel; + } + + /** + * inisafe protocol related + */ + public String getInisafeConfigPath() { + return inisafeConfigPath; + } + + public void setInisafeConfigPath(String inisafeConfigPath) { + this.inisafeConfigPath = inisafeConfigPath; + } + + public String getInisafeRelatedAdapterGroups() { + return inisafeRelatedAdapterGroups; + } + + public void setInisafeRelatedAdapterGroups(String inisafeRelatedAdapterGroups) { + this.inisafeRelatedAdapterGroups = inisafeRelatedAdapterGroups; + } + + public String getInisafeStartMessage() { + return inisafeStartMessage; + } + + public void setInisafeStartMessage(String inisafeStartMessage) { + this.inisafeStartMessage = inisafeStartMessage; + } + + public String getInisafeStopMessage() { + return inisafeStopMessage; + } + + public void setInisafeStopMessage(String inisafeStopMessage) { + this.inisafeStopMessage = inisafeStopMessage; + } + + public IRequestProcessor getRequestProcessor() { + return requestProcessor; + } + + public void setRequestProcessor(IRequestProcessor requestProcessor) { + this.requestProcessor = requestProcessor; + } + + public void setAdapterVO(AdapterVO adapterVO) { + this.adapterVO = adapterVO; + } + + public AdapterVO getAdapterVO() { + return adapterVO; + } + + public void setStarted(boolean on) { + this.started = on; + } + + public boolean isStarted() { + return this.started; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append( this.adapterName ).append( " [Adapter의 등록정보입니다. : " ); + sb.append("adapter.group.name=").append( this.adapterGroupName ); + sb.append(", bound.usage=").append( this.boundUsage ); + sb.append(", socket.type=").append( this.socketType ); + sb.append(", host.name=").append( this.hostName ); + sb.append(", port.number=").append( this.portNumber); + sb.append(", local.host.name=").append( this.localHostName ); + sb.append(", local.port.number=").append( this.localPortNumber ); + if ( this.connLimitPerIp > 0 ) { + sb.append(", connection.limit.per.ip=").append( this.connLimitPerIp ); + } else { + sb.append(", connection.limit.per.ip=0(UNLIMITED)" ); + } + + if ( this.maxConnection > 0 ) { + sb.append(", max.connection=").append( this.maxConnection ); + } else { + sb.append(", max.connection=0 (UNLIMITED)" ); + } + + sb.append(", max.thread=").append( this.maxThread ); + sb.append(", timeout=").append( this.timeout ); + sb.append(", response.type=").append( this.responseType ); + sb.append(", socket.reuse=").append( this.socketReuse ); + sb.append(", ll.field.type=").append( this.llFieldType ); + sb.append(", ll.field.offset=").append( this.llFieldOffset ); + sb.append(", ll.field.length=").append( this.llFieldLength ); + sb.append(", ll.field.include=").append( this.llFieldInclude ); + sb.append(", ll.include=").append( this.llInclude ); + sb.append(", variable.head.length=").append( this.sendHeaderLength ); + sb.append(", payload.length=").append( this.sendPayloadLength ); + sb.append(", ack.support=").append( this.ackSupport ); + sb.append(", business.work.class.code=").append( this.bwkClsCd ); + + sb.append(", trace.level="); + if ( this.traceLevel == 2 ) { + sb.append( this.traceLevel ).append("(DEBUG)"); + } else if ( this.traceLevel == 1 ) { + sb.append( this.traceLevel ).append("(INFO)"); + } else { + sb.append( this.traceLevel ).append("(ERROR)"); + } + + sb.append(", description=").append(this.description); + + if ("XECURE".equals(this.protocol)) { + sb.append(", xecure.type=").append(this.xecureType); + //sb.append(", xecure.tmode=").append(this.xecureTmode); + //sb.append(", xecure.encode.mode=").append(this.xecureEncodeMode); + sb.append(", xecure.config.path=").append(this.xecureConfigPath); + sb.append(", xecure.password=").append(this.xecurePassword); + } + + if ("XECURE2".equals(this.protocol)) { + sb.append(", xecure2.config.path=").append(this.xecure2ConfigPath); + sb.append(", xecure2.sm.ip=").append(this.xecure2SmIp); + sb.append(", xecure2.sm.port=").append( String.valueOf(this.xecure2SmPort) ); + } + + sb.append("]"); + + return sb.toString(); + } + + /** + * SMS + */ + public String getSmsRunningTime() { + return smsRunningTime; + } + + public void setSmsRunningTime(String smsRunningTime) { + this.smsRunningTime = smsRunningTime; + } + + /** + * xecure protocol related + */ + public String getXecureType() { + return xecureType; + } + + public void setXecureType(String xecureType) { + this.xecureType = xecureType; + } + + public String getXecureConfigPath() { + return xecureConfigPath; + } + + public void setXecureConfigPath(String xecureConfigPath) { + this.xecureConfigPath = xecureConfigPath; + } + + public String getXecureRemoteCert() { + return xecureRemoteCert; + } + + public void setXecureRemoteCert(String xecureRemoteCert) { + this.xecureRemoteCert = xecureRemoteCert; + } + + /** + * xecure2 protocol related + */ + public String getXecure2ConfigPath() { + return xecure2ConfigPath; + } + + public void setXecure2ConfigPath(String xecure2ConfigPath) { + this.xecure2ConfigPath = xecure2ConfigPath; + } + + public String getXecure2SmIp() { + return xecure2SmIp; + } + + public void setXecure2SmIp(String xecure2SmIp) { + this.xecure2SmIp = xecure2SmIp; + } + + public int getXecure2SmPort() { + return xecure2SmPort; + } + + public void setXecure2SmPort(int xecure2SmPort) { + this.xecure2SmPort = xecure2SmPort; + } + + /** + * xecure2 Envelop protocol related + */ + public String getEnvelopPassword() { + return envelopPassword; + } + + public void setEnvelopPassword(String envelopPassword) { + this.envelopPassword = envelopPassword; + } + + public String getEnvelopSigncertPath() { + return envelopSigncertPath; + } + + public void setEnvelopSigncertPath(String envelopSigncertPath) { + this.envelopSigncertPath = envelopSigncertPath; + } + + public String getEnvelopSignkeyPath() { + return envelopSignkeyPath; + } + + public void setEnvelopSignkeyPath(String envelopSignkeyPath) { + this.envelopSignkeyPath = envelopSignkeyPath; + } + + /** + * xecure3 protocol related 20100901 JGY + */ + public String getXecure3CertStore() { + return xecure3CertStore; + } + + public void setXecure3CertStore(String xecure3CertStore) { + this.xecure3CertStore = xecure3CertStore; + } + + public String getXecure3ServerCert() { + return xecure3ServerCert; + } + + public void setXecure3ServerCert(String xecure3ServerCert) { + this.xecure3ServerCert = xecure3ServerCert; + } + + public String getXecure3ClientCert() { + return xecure3ClientCert; + } + + public void setXecure3ClientCert(String xecure3ClientCert) { + this.xecure3ClientCert = xecure3ClientCert; + } + + public String getXecure3CertKey() { + return xecure3CertKey; + } + + public void setXecure3CertKey(String xecure3CertKey) { + this.xecure3CertKey = xecure3CertKey; + } + + public String getXecure3CertPassword() { + return xecure3CertPassword; + } + + public void setXecure3CertPassword(String xecure3CertPassword) { + this.xecure3CertPassword = xecure3CertPassword; + } + /** + * xecureconnect3 epb + */ + public String getXc3epbPassword() { + return xc3epbPassword; + } + + public void setXc3epbPassword(String xc3epbPassword) { + this.xc3epbPassword = xc3epbPassword; + } + + public String getXc3epbConfigPath() { + return xc3epbConfigPath; + } + + public void setXc3epbConfigPath(String xc3epbConfigPath) { + this.xc3epbConfigPath = xc3epbConfigPath; + } + + /** + * inisafe_payload protocol related 20100515 JGY + */ + public String getInisafeIdPassword() { + return inisafeIdPassword; + } + + public void setInisafeIdPassword(String inisafeIdPassword) { + this.inisafeIdPassword = inisafeIdPassword; + } + + /** + * TCSEED protocol related 20101213 JGY + */ + public String getTcseedKeyStore() { + return tcseedKeyStore; + } + + public void setTcseedKeyStore(String tcseedKeyStore) { + this.tcseedKeyStore = tcseedKeyStore; + } + + /** + * variable header protocol related 20121030 KwonSeHwan + */ + + public int getRecvHeaderLength() { + return recvHeaderLength; + } + + public void setRecvHeaderLength(int recvHeaderLength) { + this.recvHeaderLength = recvHeaderLength; + } + + public int getSendHeaderLength() { + return sendHeaderLength; + } + + public void setSendHeaderLength(int sendHeaderLength) { + this.sendHeaderLength = sendHeaderLength; + } + + public String getSingleSession() { + return singleSession; + } + + public void setSingleSession(String singleSession) { + this.singleSession = singleSession; + } + + public String getBlockIpList() { + return blockIpList; + } + + public void setBlockIpList(String blockIpList) { + this.blockIpList = blockIpList; + } + + public String getL4SkipIpList() { + return l4SkipIpList; + } + + public void setL4SkipIpList(String l4SkipIpList) { + this.l4SkipIpList = l4SkipIpList; + } + + public String getDelimiter() { + return delimiter; + } + + public void setDelimiter(String delimiter) { + this.delimiter = delimiter; + } + + public String getLoginSend() { + return loginSend; + } + + public void setLoginSend(String loginSend) { + this.loginSend = loginSend; + } + + public String getLoginRecv() { + return loginRecv; + } + + public void setLoginRecv(String loginRecv) { + this.loginRecv = loginRecv; + } + + public String getBindType() { + return bindType; + } + + public void setBindType(String bindType) { + this.bindType = bindType; + } + + public int getLlFieldLengthAlpha() { + return llFieldLengthAlpha; + } + + public void setLlFieldLengthAlpha(int llFieldLengthAlpha) { + this.llFieldLengthAlpha = llFieldLengthAlpha; + } + + public String getInicisKeyPath() { + return inicisKeyPath; + } + + public void setInicisKeyPath(String inicisKeyPath) { + this.inicisKeyPath = inicisKeyPath; + } + + public String getInicisKeyPass() { + return inicisKeyPass; + } + + public void setInicisKeyPass(String inicisKeyPass) { + this.inicisKeyPass = inicisKeyPass; + } + + public String getAppendHead() { + return appendHead; + } + + public void setAppendHead(String appendHead) { + this.appendHead = appendHead; + } + + public String getAppendTail() { + return appendTail; + } + + public void setAppendTail(String appendTail) { + this.appendTail = appendTail; + } + + public String getDataControlRule() { + return dataControlRule; + } + + public void setDataControlRule(String dataControlRule) { + this.dataControlRule = dataControlRule; + } + + // for 싱글어댑터 + public String getPrimaryInstId() { + return primaryInstId; + } + + // for 싱글어댑터 + public void setPrimaryInstId(String primaryInstId) { + this.primaryInstId = primaryInstId; + } + + public String getDynamicOffsetPattern() { + return dynamicOffsetPattern; + } + + public void setDynamicOffsetPattern(String dynamicOffsetPattern) { + this.dynamicOffsetPattern = dynamicOffsetPattern; + } + + public String getDataAddRule() { + return dataAddRule; + } + + public void setDataAddRule(String dataAddRule) { + this.dataAddRule = dataAddRule; + } + + public String getDataRemoveRule() { + return dataRemoveRule; + } + + public void setDataRemoveRule(String dataRemoveRule) { + this.dataRemoveRule = dataRemoveRule; + } + + public void setKeepAlive(String keepAlive) { + this.keepAlive = keepAlive; + } + + public String getKeepAlive() { + return keepAlive; + } + + public boolean isKeepAlive() { + return "Y".equals(keepAlive); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/config/SocketAdapterFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketAdapterFactory.java new file mode 100644 index 0000000..d09855f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketAdapterFactory.java @@ -0,0 +1,1305 @@ +package com.eactive.eai.adapter.socket2.config; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.admin.AdminServer; +import com.eactive.eai.adapter.socket2.protocol.append.AppendClient; +import com.eactive.eai.adapter.socket2.protocol.append.AppendServer; +import com.eactive.eai.adapter.socket2.protocol.cert.CertClient; +import com.eactive.eai.adapter.socket2.protocol.cert.CertServer; +import com.eactive.eai.adapter.socket2.protocol.cisco.CiscoClient; +import com.eactive.eai.adapter.socket2.protocol.cisco.CiscoServer; +import com.eactive.eai.adapter.socket2.protocol.delimiter.DelimiterClient; +import com.eactive.eai.adapter.socket2.protocol.delimiter.DelimiterServer; +import com.eactive.eai.adapter.socket2.protocol.dynamicoffset.DynamicOffsetClient; +import com.eactive.eai.adapter.socket2.protocol.dynamicoffset.DynamicOffsetServer; +import com.eactive.eai.adapter.socket2.protocol.echo.EchoClient; +import com.eactive.eai.adapter.socket2.protocol.echo.EchoServer; +import com.eactive.eai.adapter.socket2.protocol.envelop.EnvelopClient; +import com.eactive.eai.adapter.socket2.protocol.envelop.EnvelopServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.FixedHeaderClient; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.FixedHeaderServer; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.FixedPayloadClient; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.FixedPayloadServer; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServer; +import com.eactive.eai.adapter.socket2.protocol.inicis.InicisClient; +import com.eactive.eai.adapter.socket2.protocol.inicis.InicisServer; +import com.eactive.eai.adapter.socket2.protocol.inisafe.InisafeClient; +import com.eactive.eai.adapter.socket2.protocol.inisafe.InisafeServer; +import com.eactive.eai.adapter.socket2.protocol.inisafe2020.Inisafe2020Client; +import com.eactive.eai.adapter.socket2.protocol.inisafe2020.Inisafe2020Server; +import com.eactive.eai.adapter.socket2.protocol.inisafenatn.InisafeNatnPayloadClient; +import com.eactive.eai.adapter.socket2.protocol.inisafenatn.InisafeNatnPayloadServer; +import com.eactive.eai.adapter.socket2.protocol.inisafepayload.InisafePayloadClient; +import com.eactive.eai.adapter.socket2.protocol.inisafepayload.InisafePayloadServer; +import com.eactive.eai.adapter.socket2.protocol.law.LawClient; +import com.eactive.eai.adapter.socket2.protocol.law.LawServer; +import com.eactive.eai.adapter.socket2.protocol.login.BindClient; +import com.eactive.eai.adapter.socket2.protocol.login.LazyClient; +import com.eactive.eai.adapter.socket2.protocol.login.LoginClient; +import com.eactive.eai.adapter.socket2.protocol.proxy.ProxyServer; +import com.eactive.eai.adapter.socket2.protocol.tcseed.TcseedClient; +import com.eactive.eai.adapter.socket2.protocol.tcseed.TcseedServer; +import com.eactive.eai.adapter.socket2.protocol.udp.UdpClient; +import com.eactive.eai.adapter.socket2.protocol.udp.UdpServer; +import com.eactive.eai.adapter.socket2.protocol.variableheader.VariableHeaderClient; +import com.eactive.eai.adapter.socket2.protocol.variableheader.VariableHeaderServer; +import com.eactive.eai.adapter.socket2.protocol.xc3epb.Xc3EpbClient; +import com.eactive.eai.adapter.socket2.protocol.xc3epb.Xc3EpbServer; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureClient; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureServer; +import com.eactive.eai.adapter.socket2.protocol.xecure2.Xecure2Client; +import com.eactive.eai.adapter.socket2.protocol.xecure2.Xecure2Server; +import com.eactive.eai.adapter.socket2.protocol.xecure3.Xecure3Client; +import com.eactive.eai.adapter.socket2.protocol.xecure3.Xecure3Server; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.NullControl; + +import java.util.Properties; + +public class SocketAdapterFactory { + private static Logger logger = SocketLoggerManager.getInstance().getLogger(); +// private static Logger errLogger = SocketLoggerManager.getInstance().getErrLogger(); + + private enum SocketType { + SERVER, CLIENT, ADMIN, UNKNOWN; + + public static SocketType getValue(String value) { + try { + return valueOf(value.toUpperCase()); + } catch (Exception e) { + return UNKNOWN; + } + } + } + + private enum Protocol { + ADMIN, + CERT, + CISCO, + ECHO, + EGSEED, + ENVELOP, + FIXED_LENGTH_HEADER, + FIXED_LENGTH_PAYLOAD, + VARIABLE_LENGTH_HEADER, + INISAFE, + INISAFE_2020, + INISAFE_NATN, + INISAFE_PAYLOAD, + HTTP, + PROXY, + TCSEED, + UDP_FIXED_LENGTH_HEADER, + UDP_FIXED_LENGTH_PAYLOAD, + XECURE, + XECURE2, + XECURE3, + LOGIN, + LAZY, + BIND, + LAW, + DELIMITER, + INICIS, + APPEND, + XC3EPB, + DYNAMIC_OFFSET, + UNKNOWN; + + public static Protocol getValue(String value) { + try { + return valueOf(value.toUpperCase()); + } catch (Exception e) { + return UNKNOWN; + } + } + } + +// private static boolean isDrMode = false; +// static { +// if("Y".equals(System.getProperty(Keys.DR_MODE, "N").toUpperCase())) { +// isDrMode = true; +// } +// } + + public SocketAdapterFactory() { + super(); + } + + public static ISocketAdapter createSocketAdapter(SocketAdapterContext context) throws EAIException { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | create socket adapter ... "); + } + + try { +// String adapterGroupName = context.getAdapterGroupName(); +// String adapterName = context.getAdapterName(); + + ISocketAdapter adapter = null; + + switch(SocketType.getValue(context.getSocketType())) { + case ADMIN: + if(Protocol.getValue(context.getProtocol()) == Protocol.ADMIN) { + context.setSocketType("SERVER"); + } + else { + throw new EAIException("unknown ADMIN protocol : " + context.getProtocol()); + } + break; + case SERVER: + switch(Protocol.getValue(context.getProtocol())) { + case ADMIN: + adapter = new AdminServer(context); + break; + case CERT: + adapter = new CertServer(context); + break; + case CISCO: + if (Env.isWindows()) { // for test + adapter = new CiscoServer(context); + break; + } else { + throw new EAIException(context.getAdapterName() + " | 'CISCO' Protocol does not support 'SERVER' socket type."); + } + case ECHO: + adapter = new EchoServer(context); + break; + case ENVELOP: // 20100423 JGY + adapter = new EnvelopServer(context); + break; + case FIXED_LENGTH_HEADER: + adapter = new FixedHeaderServer(context); + break; + case FIXED_LENGTH_PAYLOAD: + adapter = new FixedPayloadServer(context); + break; + case VARIABLE_LENGTH_HEADER: //20121030 KWON SE HWAN + adapter = new VariableHeaderServer(context); + break; + case INISAFE: // 한국은행 신한은망 + adapter = new InisafeServer(context); + break; + case INISAFE_2020: // 한국은행 신한은망 NEW Version + adapter = new Inisafe2020Server(context); + break; + case INISAFE_NATN: // 한국은행 국고망 + adapter = new InisafeNatnPayloadServer(context); + break; + case INISAFE_PAYLOAD: // 20100510 JGY // 정책금융공사 + adapter = new InisafePayloadServer(context); + break; + case HTTP: + adapter = new HttpServer(context); + break; + case PROXY: + adapter = new ProxyServer(context); + break; + case TCSEED: // 20101213 JGY + adapter = new TcseedServer(context); + break; + case UDP_FIXED_LENGTH_HEADER: + case UDP_FIXED_LENGTH_PAYLOAD: + adapter = new UdpServer(context); + break; + case XECURE: + adapter = new XecureServer(context); + break; + case XECURE2: + adapter = new Xecure2Server(context); + break; + case XECURE3: // 20100901 JGY + adapter = new Xecure3Server(context); + break; + case LAW: + adapter = new LawServer(context); + break; + case DELIMITER: + adapter = new DelimiterServer(context); + break; + case INICIS: + adapter = new InicisServer(context); + break; + case APPEND: + adapter = new AppendServer(context); + break; + case XC3EPB: + adapter = new Xc3EpbServer(context); + break; + case DYNAMIC_OFFSET: + adapter = new DynamicOffsetServer(context); + break; + case UNKNOWN: + default: + throw new EAIException("unknown protocol : " + context.getProtocol()); + } + break; + case CLIENT: + switch(Protocol.getValue(context.getProtocol())) { + case ADMIN: + case CERT: + if (Env.isWindows()) { // for test + adapter = new CertClient(context); + break; + } else { + throw new EAIException(context.getAdapterName() + " | 'CERT' Protocol does not support 'CLIENT' socket type."); + } + case CISCO: + adapter = new CiscoClient(context); + break; + case ECHO: + adapter = new EchoClient(context); + break; + case ENVELOP: + adapter = new EnvelopClient(context); + break; + case FIXED_LENGTH_HEADER: + adapter = new FixedHeaderClient(context); + break; + case FIXED_LENGTH_PAYLOAD: + adapter = new FixedPayloadClient(context); + break; + case VARIABLE_LENGTH_HEADER: + adapter = new VariableHeaderClient(context); + break; + case INISAFE: // 한국은행 신한은망 + adapter = new InisafeClient(context); + break; + case INISAFE_2020: // 한국은행 신한은망 New Version + adapter = new Inisafe2020Client(context); + break; + case INISAFE_NATN: // 한국은행 국고망 + adapter = new InisafeNatnPayloadClient(context); + break; + case INISAFE_PAYLOAD: // 정책금융공사 + adapter = new InisafePayloadClient(context); + break; + case HTTP: + case PROXY: + throw new EAIException(context.getAdapterName() + " | '" + context.getProtocol() + "' Protocol does not support 'CLIENT' socket type."); + case TCSEED: + adapter = new TcseedClient(context); + break; + case UDP_FIXED_LENGTH_HEADER: + case UDP_FIXED_LENGTH_PAYLOAD: + adapter = new UdpClient(context); + break; + case XECURE: + adapter = new XecureClient(context); + break; + case XECURE2: + adapter = new Xecure2Client(context); + break; + case XECURE3: + adapter = new Xecure3Client(context); + break; + case LOGIN: + adapter = new LoginClient(context); + break; + case LAZY: + adapter = new LazyClient(context); + break; + case BIND: + adapter = new BindClient(context); + break; + case LAW: + adapter = new LawClient(context); + break; + case DELIMITER: + adapter = new DelimiterClient(context); + break; + case INICIS: + adapter = new InicisClient(context); + break; + case APPEND: + adapter = new AppendClient(context); + break; + case XC3EPB: + adapter = new Xc3EpbClient(context); + break; + case DYNAMIC_OFFSET: + adapter = new DynamicOffsetClient(context); + break; + case UNKNOWN: + default: + throw new EAIException("unknown protocol : " + context.getProtocol()); + } + break; + case UNKNOWN: + default: + throw new EAIException("unknown socket type : " + context.getSocketType()); + } + + SocketAdapterManager.getInstance().addAdapter(adapter); + + return adapter; + } catch (EAIException e) { + throw e; + } catch (Exception e) { + throw new EAIException(e); + } + } + + // START A SOCKET ADAPTER CONFIGURATION + public static ISocketAdapter createSocketAdapter(AdapterVO config) throws Exception { + return createSocketAdapter(createContext(config)); + } + + public static SocketAdapterContext createContext(AdapterVO config) throws Exception { + SocketAdapterContext context = new SocketAdapterContext(); + context.setAdapterGroupName(config.getAdapterGroupName()); + context.setAdapterName(config.getName()); + + //PropManager manager = PropManager.getInstance(); + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties prop = manager.getProperties(config.getPropGroupName()); +// String errMsg = null; + + /** + * protocol + */ + if (!"".equals(prop.getProperty(Constants.PROTOCOL, "").trim())) { + context.setProtocol(prop.getProperty(Constants.PROTOCOL, context.getProtocol()).trim()); + if (!context.getProtocol().matches("(FIXED_LENGTH_HEADER|FIXED_LENGTH_PAYLOAD|VARIABLE_LENGTH_HEADER|CISCO|CERT|INISAFE|INISAFE_2020|INISAFE_NATN|INISAFE_PAYLOAD|EGSEED|TCSEED|ADMIN|HTTP|OBJECT|UDP_FIXED_LENGTH_HEADER|UDP_FIXED_LENGTH_PAYLOAD|XECURE|XECURE2|XECURE3|ENVELOP|LOGIN|LAZY|BIND|APPEND|DELIMITER|INICIS|XC3EPB|DYNAMIC_OFFSET|)")) { + throw new Exception(context.getAdapterName() + " | protocol must be one of (FIXED_LENGTH_HEADER|FIXED_LENGTH_PAYLOAD|VARIABLE_LENGTH_HEADER|CISCO|CERT|INISAFE|INISAFE_2020|INISAFE_NATN|INISAFE_PAYLOAD|EGSEED|TCSEED|ADMIN|HTTP|OBJECT|UDP_FIXED_LENGTH_HEADER|UDP_FIXED_LENGTH_PAYLOAD|XECURE|XECURE2|XECURE3|ENVELOP|LOGIN|LAZY|BIND|APPEND|DELIMITER|INICIS|XC3EPB|DYNAMIC_OFFSET|), but - '" + context.getProtocol() + "'"); + } + } else { + // for backward compatibility + if ("CISCO".equals(prop.getProperty(Constants.LL_FIELD_TYPE))) { + context.setProtocol("CISCO"); + } + logger.warn(context.getAdapterName() + " | 'protocol' is not specified. use default : " + context.getProtocol()); + } + + /** + * adapter.group.name + */ + if (prop.getProperty(Constants.ADAPTER_GROUP_NAME) == null) { + throw new Exception(context.getAdapterName() + " | adapter group name is null"); + } + + /** + * bound.usage + */ + if (!"".equals(prop.getProperty(Constants.BOUND_USAGE, "").trim())) { + context.setBoundUsage(prop.getProperty(Constants.BOUND_USAGE, context.getBoundUsage()).trim()); + if ("INBOUND,OUTBOUND,IOBOUND".indexOf(context.getBoundUsage()) < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.BOUND_USAGE + " must be one of [INBOUND|OUTBOUND|IOBOUND], but - '" + context.getBoundUsage() + "'"); + } + } + + /** + * socket.type + */ + if (!"".equals(prop.getProperty(Constants.SOCKET_TYPE, "").trim())) { + if ("ADMIN".equals(context.getSocketType())) + context.setSocketType("SERVER"); + + context.setSocketType(prop.getProperty(Constants.SOCKET_TYPE, context.getSocketType()).trim()); + if ("SERVER,CLIENT".indexOf(context.getSocketType()) < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.SOCKET_TYPE + " must be one of [SERVER|CLIENT], but - '" + context.getSocketType() + "'"); + } + } + + /** + * permanent + */ + if (!"".equals(prop.getProperty(Constants.PERMANENT, "").trim())) { + context.setPermanent(prop.getProperty(Constants.PERMANENT, context.getPermanent()).trim()); + if (context.getPermanent() == null || !context.getPermanent().matches("[Y|N]")) { + throw new Exception(context.getAdapterName() + " | " + Constants.PERMANENT + " must be one of [Y|N], but - '" + context.getPermanent() + "'"); + } + } + + /** + * blocking + */ + if (!"".equals(prop.getProperty(Constants.BLOCKING, "").trim())) { + context.setBlocking(prop.getProperty(Constants.BLOCKING, context.getBlocking()).trim()); + if (context.getBlocking() == null || !context.getBlocking().matches("[Y|N]")) { + throw new Exception(context.getAdapterName() + " | " + Constants.BLOCKING + " must be one of [Y|N], but - '" + context.getBlocking() + "'"); + } + } + + /** + * host.name | port.number + */ + context.setHostName(prop.getProperty(Constants.HOST_NAME, context.getHostName()).trim()); + + context.setPortNumber(Integer.parseInt(prop.getProperty(Constants.PORT_NUMBER, Integer + .toString(context.getPortNumber())).trim())); + + /** + * local.host.name | local.port.number (CLIENT type || PROXY protocol) + */ + if (context.getSocketType().equals(SocketAdapterContext.CLIENT_SOCKET)) { + if (!"".equals(prop.getProperty(Constants.LOCAL_PORT_NUMBER, "").trim())) { + try { + context.setLocalPortNumber(Integer.parseInt(prop.getProperty(Constants.LOCAL_PORT_NUMBER, Integer.toString(context.getLocalPortNumber())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.LOCAL_PORT_NUMBER + " | " + e.getMessage()); + } + } + + if (!"".equals(prop.getProperty(Constants.LOCAL_HOST_NAME, "").trim())) { + context.setLocalHostName(prop.getProperty(Constants.LOCAL_HOST_NAME, context.getLocalHostName()).trim()); + } + } + + /** + * max.connection + */ + if (!"".equals(prop.getProperty(Constants.MAX_CONNECTION, "").trim())) { + try { + context.setMaxConnection(Integer.parseInt(prop.getProperty(Constants.MAX_CONNECTION, Integer.toString(context.getMaxConnection())).trim())); + if (context.getSocketType().equals(SocketAdapterContext.CLIENT_SOCKET) && context.getMaxConnection() < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.MAX_CONNECTION + "(" + context.getMaxConnection() + ") < 0"); + } + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.MAX_CONNECTION + " | " + e.getMessage()); + } + } else { + if (context.isServer()) { + context.setMaxConnection(0); + } + } + + /** + * connection.limit.per.ip + */ + if (!"".equals(prop.getProperty(Constants.CONN_LIMIT_PER_IP, "").trim())) { + try { + context.setConnLimitPerIp(Integer.parseInt(prop.getProperty(Constants.CONN_LIMIT_PER_IP, Integer.toString(context.getConnLimitPerIp())).trim())); + if (context.getConnLimitPerIp() < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.CONN_LIMIT_PER_IP + " must be > 0, but - '" + context.getConnLimitPerIp() + "'"); + } + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.CONN_LIMIT_PER_IP + " | " + e.getMessage()); + } + } + + /** + * max.thread + */ + if (!"".equals(prop.getProperty(Constants.MAX_THREAD, "").trim())) { + try { + context.setMaxThread(Integer.parseInt(prop.getProperty(Constants.MAX_THREAD, Integer.toString(context.getMaxThread())).trim())); + if (context.getMaxThread() < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.MAX_THREAD + " must be > 0, but - '" + context.getMaxThread() + "'"); + } + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.MAX_THREAD + " | " + e.getMessage()); + } + // for backward compatibility - old socket + } else if (!"".equals(prop.getProperty("max.session", "").trim())) { + logger.warn(context.getAdapterName() + " | old socket property | change property name 'max.session' -> '" + Constants.MAX_THREAD + "'"); + try { + context.setMaxThread(Integer.parseInt(prop.getProperty("max.session", Integer.toString(context.getMaxThread())).trim())); + if (context.getMaxThread() < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.MAX_THREAD + " must be > 0, but - '" + context.getMaxThread() + "'"); + } + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.MAX_THREAD + " | " + e.getMessage()); + } + } + + /** + * timeout + */ + if (!"".equals(prop.getProperty(Constants.TIMEOUT, "").trim())) { + try { + context.setTimeout(Integer.parseInt(prop.getProperty(Constants.TIMEOUT, Integer.toString(context.getTimeout())).trim())); + if (context.getTimeout() < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.TIMEOUT + " must be > 0, but - '" + context.getTimeout() + "'"); + } + + if (context.getTimeout() > 600) { + logger.warn(context.getAdapterName() + " | timeout is to big '" + context.getTimeout() + "' -> timeout is reset to 600 (sec)"); + context.setTimeout(600); + } + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.TIMEOUT + " | " + e.getMessage()); + } + } + + + /** + * idle timeout + */ + if (!"".equals(prop.getProperty(Constants.IDLE_TIMEOUT, "").trim())) { + try { + context.setIdleTimeout(Integer.parseInt(prop.getProperty(Constants.IDLE_TIMEOUT, Integer.toString(context.getIdleTimeout())).trim())); + // idle.timeout 을 설정하지 않을 경우, 0으로 처리되므로 동일하게 체크하도록 수정함 + // 다만, L4에 의해 비정상 종료되는 경우가 발생할 수 있으므로 유의해서 사용해야 함 + if (context.getIdleTimeout() == 0) { + logger.warn(context.getAdapterName() + " | idle.timeout =" + context.getIdleTimeout() + ", session will not close"); + } + else { + if (context.getIdleTimeout() < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.IDLE_TIMEOUT + " must be > 0, but - '" + context.getIdleTimeout() + "'"); + } + + if (context.getIdleTimeout() <= context.getTimeout()) { + throw new Exception(context.getAdapterName() + " | idle.timeout (" + context.getIdleTimeout() + " sec) must be greater than timeout(" + context.getTimeout() + " sec)"); + } + } + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.IDLE_TIMEOUT + " | " + e.getMessage()); + } + } + + /** + * response.type + */ + if (!"".equals(prop.getProperty(Constants.RESPONSE_TYPE, "").trim())) { + context.setResponseType(prop.getProperty(Constants.RESPONSE_TYPE, context.getResponseType()).trim()); + if ("SYNC,ASYN".indexOf(context.getResponseType()) < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.RESPONSE_TYPE + " must be one of (SYNC|ASYN), but - '" + context.getResponseType() + "'"); + } + } + + /** + * socket.reuse + */ + if (!"".equals(prop.getProperty(Constants.SOCKET_REUSE, "").trim())) { + context.setSocketReuse(prop.getProperty(Constants.SOCKET_REUSE, context.getSocketReuse()).trim()); + if ("Y,N".indexOf(context.getSocketReuse()) < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.SOCKET_REUSE + " must be one of [Y|N], but - '" + context.getSocketReuse() + "'"); + } + } + + /** + * ack.support + */ + if (!"".equals(prop.getProperty(Constants.ACK_SUPPORT, "").trim())) { + context.setAckSupport(prop.getProperty(Constants.ACK_SUPPORT, context.getAckSupport()).trim()); + if ("Y,N".indexOf(context.getAckSupport()) < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.ACK_SUPPORT + " must be one of [Y|N], but - '" + context.getAckSupport() + "'"); + } + } + + /** + * acl + */ + if (!"".equals(prop.getProperty(Constants.ACL_LIST, "").trim())) { + context.setAclList(prop.getProperty(Constants.ACL_LIST , context.getAclList()).trim()); + } + + /** + * validation.rule + */ + if (!"".equals(prop.getProperty(Constants.VALIDATION_RULE, "").trim())) { + context.setValidationRule(prop.getProperty(Constants.VALIDATION_RULE, context.getValidationRule()).trim()); + } + + /** + * datacontrol.rule + */ + if (!"".equals(prop.getProperty(Constants.DATACONTROL_RULE, ""))) { + context.setDataControlRule(prop.getProperty(Constants.DATACONTROL_RULE, context.getDataControlRule())); + } + + /** + * business.work.class.code + */ + context.setBwkClsCd(prop.getProperty(Constants.WORK_CLASS_CODE, context.getBwkClsCd()).trim()); + + /** + * trace.level + */ + if (!"".equals(prop.getProperty(Constants.TRACE_LEVEL, "").trim())) { + try { + context.setTraceLevel(Integer.parseInt(prop.getProperty(Constants.TRACE_LEVEL, Integer + .toString(context.getTraceLevel())).trim())); + if ("0,1,2,3".indexOf(Integer.toString(context.getTraceLevel())) < 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.TRACE_LEVEL + " must be one of [0|1|2|3], but - '" + context.getTraceLevel() + "'"); + } + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.TRACE_LEVEL + " | " + e.getMessage()); + } + } + + /** + * description + */ + context.setDescription(prop.getProperty(Constants.DESCRIPTION, context.getDescription()).trim()); + + + /** + * polling + * - polling.use : Y|N + * - polling.role : SEDNER|RECEIVER + * - polling.oneway : Y|N + * - polling.timeout : SENDER (default:client) + * - polling.request : SENDER (default:client) + * - polling.response.pattern : SENDER (default:client) + * - polling.request.pattern : RECEIVER (default:server) + * - polling.replacement : RECEIVER (default:server) + */ + + /** + * polling.use + */ + if (!"".equals(prop.getProperty(Constants.POLLING_USE, "").trim())) { + context.setPollingUse(prop.getProperty(Constants.POLLING_USE, context.getPollingUse()).trim()); + if (!context.getPollingUse().matches("[Y|N]")) { + throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_USE + " must be one of [Y|N], but - '" + context.getPollingUse() + "'"); + } + } + + if (context.isPollingUse()) { + /** + * polling.role + */ + // JGY 20100510 + String pollingRole = prop.getProperty(Constants.POLLING_ROLE, "").trim(); + if ("".equals(pollingRole)) { + if (context.isClient()) { + context.setPollingRole("SENDER"); + } else { + context.setPollingRole("RECEIVER"); + } + } else { +// if (!context.getPollingRole().matches("(SENDER|RECEIVER)")) { + if (!pollingRole.matches("(SENDER|RECEIVER)")) { + throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_ROLE + " must be one of (SENDER|RECEIVER), but -> '" + pollingRole + "'"); + } + context.setPollingRole(prop.getProperty(Constants.POLLING_ROLE, context.getPollingRole()).trim()); + } + + /** + * polling.oneway + */ + if (!"".equals(prop.getProperty(Constants.POLLING_ONEWAY, "").trim())) { + context.setPollingOneway(prop.getProperty(Constants.POLLING_ONEWAY, context.getPollingOneway()).trim()); + } + + /** + * polling.timeout + */ + if (!"".equals(prop.getProperty(Constants.POLLING_TIMEOUT, "").trim())) { + try { + context.setPollingTimeout(Integer.parseInt(prop.getProperty(Constants.POLLING_TIMEOUT, Integer.toString(context.getPollingTimeout())).trim())); + if (context.getPollingTimeout() <= 0) { + throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_TIMEOUT + " must be > 0, but - '" + context.getPollingTimeout() + "'"); + } + if (context.getPollingTimeout() <= context.getTimeout()) { + throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_TIMEOUT + " must be > timeout(" + context.getTimeout() + ")"); + } + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.POLLING_TIMEOUT + " | " + e.getMessage(), e); + } + } + + /** + * polling.request + */ + if (!"".equals( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REQUEST, ""))) ) { + context.setPollingRequest( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REQUEST, context.getPollingRequest())) ); + } + + /** + * polling.request.pattern + */ + if (!"".equals( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REQUEST_PATTERN, ""))) ) { + context.setPollingRequestPattern( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REQUEST_PATTERN, context.getPollingRequestPattern())) ); + } + + /** + * polling.replacement + */ + if (!"".equals( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REPLACEMENT, ""))) ) { + context.setPollingReplacement ( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_REPLACEMENT, context.getPollingReplacement())) ); + } + + /** + * polling.response.pattern + */ + if (!"".equals( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_RESPONSE_PATTERN, ""))) ) { + context.setPollingResponsePattern( NullControl.trimSpace2(prop.getProperty(Constants.POLLING_RESPONSE_PATTERN, context.getPollingResponsePattern())) ); + } + } + + + /**KSH + * init.msg.use + */ + if (!"".equals(prop.getProperty(Constants.INIT_MSG_USE, "").trim())) { + context.setInitMsgUse(prop.getProperty(Constants.INIT_MSG_USE, context.getInitMsgUse()).trim()); + if (!context.getInitMsgUse().matches("[Y|N]")) { + throw new Exception(context.getAdapterName() + " | " + Constants.INIT_MSG_USE + " must be one of [Y|N], but - '" + context.getInitMsgUse() + "'"); + } + } + + if (context.isInitMsgUse()) { + /** + * init.msg.role + */ + // KSH + String initMsgRole = prop.getProperty(Constants.INIT_MSG_ROLE, "").trim(); + if ("".equals(initMsgRole)) { + if (context.isClient()) { + context.setInitMsgRole("SENDER"); + } else { + context.setInitMsgRole("RECEIVER"); + } + } else { + if (!initMsgRole.matches("(SENDER|RECEIVER)")) { + throw new Exception(context.getAdapterName() + " | " + Constants.INIT_MSG_ROLE + " must be one of (SENDER|RECEIVER), but -> '" + initMsgRole + "'"); + } + context.setInitMsgRole(prop.getProperty(Constants.INIT_MSG_ROLE, context.getInitMsgRole()).trim()); + } + + /** + * init.msg.request + */ + if (!"".equals(prop.getProperty(Constants.INIT_MSG_REQUEST, "").trim())) { + context.setInitMsgRequest(prop.getProperty(Constants.INIT_MSG_REQUEST, context.getInitMsgRequest()).trim()); + } + + /** + * init.msg.request.pattern + */ + if (!"".equals(prop.getProperty(Constants.INIT_MSG_REQUEST_PATTERN, "").trim())) { + context.setInitMsgRequestPattern(prop.getProperty(Constants.INIT_MSG_REQUEST_PATTERN, context.getInitMsgRequestPattern()).trim()); + } + + /** + * init.msg.replacement + */ + if (!"".equals(prop.getProperty(Constants.INIT_MSG_REPLACEMENT, "").trim())) { + context.setInitMsgReplacement(prop.getProperty(Constants.INIT_MSG_REPLACEMENT, context.getInitMsgReplacement()).trim()); + } + + /** + * init.msg.response.pattern + */ + if (!"".equals(prop.getProperty(Constants.INIT_MSG_RESPONSE_PATTERN, "").trim())) { + context.setInitMsgResponsePattern(prop.getProperty(Constants.INIT_MSG_RESPONSE_PATTERN, context.getInitMsgResponsePattern()).trim()); + } + } + + + /** + * FIXED_LENGTH_HEADER, UDP_FIXED_LENGTH_HEADER, XECURE, XECURE2, XECURE3, EGSEED, ENVELOP protocol only + * VARIABLE_LENGTH_HEADER add 2012.10.30 Kwon Se Hwan + * - ll.field.type + * - ll.field.offset + * - ll.field.length + * - ll.field.include + * - ll.include + */ + if ("FIXED_LENGTH_HEADER".equals(context.getProtocol()) + || "VARIABLE_LENGTH_HEADER".equals(context.getProtocol()) + || "UDP_FIXED_LENGTH_HEADER".equals(context.getProtocol()) + || "EGSEED".equals(context.getProtocol()) + || "TCSEED".equals(context.getProtocol()) + || "ENVELOP".equals(context.getProtocol()) + || "XECURE".equals(context.getProtocol()) + || "XECURE2".equals(context.getProtocol()) + || "XECURE3".equals(context.getProtocol()) + || "LOGIN".equals(context.getProtocol()) + || "LAZY".equals(context.getProtocol()) + || "BIND".equals(context.getProtocol()) + || "APPEND".equals(context.getProtocol()) + || "INICIS".equals(context.getProtocol()) + || "XC3EPB".equals(context.getProtocol()) + || "DYNAMIC_OFFSET".equals(context.getProtocol()) + ) { + + if (!"".equals(prop.getProperty(Constants.LL_FIELD_TYPE, "").trim())) { + context.setLlFieldType(prop.getProperty(Constants.LL_FIELD_TYPE, context.getLlFieldType()).trim()); + if (!context.getLlFieldType().matches("(BIN|CHAR|NONE)")) { + throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_TYPE + " must be one of (BIN|CHAR|NONE), but - '" + context.getLlFieldType() + "'"); + } + } else if ("XECURE".equals(context.getProtocol())) { + context.setLlFieldType("CHAR"); + } + + /** + * ll.field.offset + */ + if (!"".equals(prop.getProperty(Constants.LL_FIELD_OFFSET, "").trim())) { + try { + context.setLlFieldOffset(Integer.parseInt(prop.getProperty(Constants.LL_FIELD_OFFSET, + Integer.toString(context.getLlFieldOffset())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_OFFSET + " | " + e.getMessage()); + } + } else if ("XECURE".equals(context.getProtocol())) { + context.setLlFieldOffset(0); + } + + /** + * ll.field.length + */ + if (!"".equals(prop.getProperty(Constants.LL_LENGTH_ADJUST, "").trim())) { + try { + context.setLlLenAdjust(Integer.parseInt(prop.getProperty(Constants.LL_LENGTH_ADJUST, + Integer.toString(context.getLlFieldLength())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.LL_LENGTH_ADJUST + " | " + e.getMessage()); + } + } + + /** + * ll.field.length + */ + if (!"".equals(prop.getProperty(Constants.LL_FIELD_LENGTH, "").trim())) { + try { + context.setLlFieldLength(Integer.parseInt(prop.getProperty(Constants.LL_FIELD_LENGTH, + Integer.toString(context.getLlFieldLength())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_LENGTH + " | " + e.getMessage()); + } + } else if ("XECURE".equals(context.getProtocol())) { + context.setLlFieldLength(7); + } + + /** + * ll.field.include + */ + if (!"".equals(prop.getProperty(Constants.LL_FIELD_INCLUDE, "").trim())) { + context.setLlFieldInclude(prop.getProperty(Constants.LL_FIELD_INCLUDE, + context.getLlFieldInclude()).trim()); + if (!context.getLlFieldInclude().matches("[Y|N]")) { + throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_INCLUDE + " must be one of [Y|N], but - '" + context.getLlFieldInclude() + "'"); + } + } else if ("XECURE".equals(context.getProtocol())) { + context.setLlFieldInclude("N"); + } + + /** + * ll.offset.exclude + */ + if (!"".equals(prop.getProperty(Constants.LL_OFFSET_EXCLUDE, "").trim())) { + context.setLlOffsetExclude(prop.getProperty(Constants.LL_OFFSET_EXCLUDE, + context.getLlOffsetExclude()).trim()); + if (!context.getLlOffsetExclude().matches("[Y|N]")) { + throw new Exception(context.getAdapterName() + " | " + Constants.LL_OFFSET_EXCLUDE + " must be one of [Y|N], but - '" + context.getLlOffsetExclude() + "'"); + } + } else if ("XECURE".equals(context.getProtocol())) { + context.setLlOffsetExclude("N"); + } + + /** + * ll.include + */ + if (!"".equals(prop.getProperty(Constants.LL_INCLUDE, "").trim())) { + context.setLlInclude(prop.getProperty(Constants.LL_INCLUDE, + context.getLlInclude()).trim()); + if (!context.getLlFieldInclude().matches("[Y|N]")) { + throw new Exception(context.getAdapterName() + " | " + Constants.LL_INCLUDE + " must be one of [Y|N], but - '" + context.getLlInclude() + "'"); + } + } else if ("XECURE".equals(context.getProtocol())) { + context.setLlInclude("Y"); + } + + + /** + * recv.header.length 2012.10.30 Kwon Se Hwan + */ + if (!"".equals(prop.getProperty(Constants.RECV_HEADER_LENGTH, "").trim())) { + try { + context.setRecvHeaderLength(Integer.parseInt(prop.getProperty(Constants.RECV_HEADER_LENGTH, + Integer.toString(context.getRecvHeaderLength())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.RECV_HEADER_LENGTH + " | " + e.getMessage()); + } + } + + /** + * send.header.length 2012.10.30 Kwon Se Hwan + */ + if (!"".equals(prop.getProperty(Constants.SEND_HEADER_LENGTH, "").trim())) { + try { + context.setSendHeaderLength(Integer.parseInt(prop.getProperty(Constants.SEND_HEADER_LENGTH, + Integer.toString(context.getSendHeaderLength())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.SEND_HEADER_LENGTH + " | " + e.getMessage()); + } + } + + } + + + /** + * FIXED_LENGTH_PAYLOAD, UDP_FIXED_LENGTH_PAYLOAD, INISAFE_PAYLOAD protocol only + * - send.payload.length + * - recv.payload.length + */ + if ("FIXED_LENGTH_PAYLOAD".equals(context.getProtocol()) + || "INISAFE_PAYLOAD".equals(context.getProtocol()) // 20100510 JGY + || "UDP_FIXED_LENGTH_PAYLOAD".equals(context.getProtocol())) { + /** + * send.payload.length + */ + if (!"".equals(prop.getProperty(Constants.SEND_PAYLOAD_LENGTH, "").trim())) { + try { + context.setSendPayloadLength(Integer.parseInt(prop.getProperty(Constants.SEND_PAYLOAD_LENGTH, + Integer.toString(context.getSendPayloadLength())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.SEND_PAYLOAD_LENGTH + " | " + e.getMessage()); + } + } + /** + * recv.payload.length + */ + if (!"".equals(prop.getProperty(Constants.RECV_PAYLOAD_LENGTH, "").trim())) { + try { + context.setRecvPayloadLength(Integer.parseInt(prop.getProperty(Constants.RECV_PAYLOAD_LENGTH, + Integer.toString(context.getRecvPayloadLength())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.RECV_PAYLOAD_LENGTH + " | " + e.getMessage()); + } + } + } + + + /** + * SSL + * - ssl.use + * - ssl.cert.store + * - ssl.cert.password + */ + if (!"".equals(prop.getProperty(Constants.SSL_USE, "").trim())) { + context.setSslUse(prop.getProperty(Constants.SSL_USE, context.getSslUse()).trim()); + /* + if (!context.getSslUse().matches("[Y|N]")) { + throw new Exception(context.getAdapterName() + " | " + Constants.SSL_USE + " must be one of [Y|N], but - '" + context.getSslUse() + "'"); + } + */ + + context.setSslCertStore(prop.getProperty(Constants.SSL_CERT_STORE, context.getSslCertStore()).trim()); + + context.setSslCertPassword(prop.getProperty(Constants.SSL_CERT_PASSWORD, context.getSslCertPassword()).trim()); + } + + /** + * INISAFE, INISAFE_NATN protocol only + */ + if ( "INISAFE".equals(context.getProtocol()) || "INISAFE_2020".equals(context.getProtocol())) { + context.setInisafeConfigPath(prop.getProperty(Constants.INISAFE_CONFIG_PATH, + context.getInisafeConfigPath()).trim()); + + context.setInisafeRelatedAdapterGroups(prop.getProperty(Constants.INISAFE_RELATED_ADAPTER_GROUPS, + context.getInisafeRelatedAdapterGroups()).trim()); + + if (!"".equals(prop.getProperty(Constants.INISAFE_START_MESSAGE, "").trim())) { + context.setInisafeStartMessage(prop.getProperty(Constants.INISAFE_START_MESSAGE, + context.getInisafeStartMessage()).trim()); + } + + if (!"".equals(prop.getProperty(Constants.INISAFE_STOP_MESSAGE, "").trim())) { + context.setInisafeStopMessage(prop.getProperty(Constants.INISAFE_STOP_MESSAGE, + context.getInisafeStopMessage()).trim()); + } + } + else if ( "INISAFE_NATN".equals(context.getProtocol()) ) { + context.setInisafeConfigPath(prop.getProperty(Constants.INISAFE_CONFIG_PATH, + context.getInisafeConfigPath()).trim()); + + context.setInisafeRelatedAdapterGroups(prop.getProperty(Constants.INISAFE_RELATED_ADAPTER_GROUPS, + context.getInisafeRelatedAdapterGroups()).trim()); + + if (!"".equals(prop.getProperty(Constants.INISAFE_START_MESSAGE, "").trim())) { + context.setInisafeStartMessage(prop.getProperty(Constants.INISAFE_START_MESSAGE, + context.getInisafeStartMessage()).trim()); + } + + if (!"".equals(prop.getProperty(Constants.INISAFE_STOP_MESSAGE, "").trim())) { + context.setInisafeStopMessage(prop.getProperty(Constants.INISAFE_STOP_MESSAGE, + context.getInisafeStopMessage()).trim()); + } + + /** + * send.payload.length + */ + if (!"".equals(prop.getProperty(Constants.SEND_PAYLOAD_LENGTH, "").trim())) { + try { + context.setSendPayloadLength(Integer.parseInt(prop.getProperty(Constants.SEND_PAYLOAD_LENGTH, + Integer.toString(context.getSendPayloadLength())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.SEND_PAYLOAD_LENGTH + " | " + e.getMessage()); + } + } + else { + context.setSendPayloadLength(460); + } + /** + * recv.payload.length + */ + if (!"".equals(prop.getProperty(Constants.RECV_PAYLOAD_LENGTH, "").trim())) { + try { + context.setRecvPayloadLength(Integer.parseInt(prop.getProperty(Constants.RECV_PAYLOAD_LENGTH, + Integer.toString(context.getRecvPayloadLength())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.RECV_PAYLOAD_LENGTH + " | " + e.getMessage()); + } + } + else { + context.setRecvPayloadLength(460); + } + + /** + * ll.field.length + */ + if (!"".equals(prop.getProperty(Constants.LL_FIELD_LENGTH, "").trim())) { + try { + context.setLlFieldLength(Integer.parseInt(prop.getProperty(Constants.LL_FIELD_LENGTH, + Integer.toString(context.getLlFieldLength())).trim())); + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.LL_FIELD_LENGTH + " | " + e.getMessage()); + } + } else { + context.setLlFieldLength(0); + } + } + + /** + * INISAFE_PAYLOAD protocol only - 20100510 JGY + */ + if ("INISAFE_PAYLOAD".equals(context.getProtocol())) { + context.setInisafeConfigPath(prop.getProperty(Constants.INISAFE_CONFIG_PATH, + context.getInisafeConfigPath()).trim()); + + context.setInisafeIdPassword(prop.getProperty(Constants.INISAFE_ID_PASSWORD, + context.getInisafeIdPassword()).trim()); + } + + /** + * sms.running.time + */ + if (!"".equals(prop.getProperty(Constants.SMS_RUNNING_TIME, "").trim())) { + context.setSmsRunningTime(prop.getProperty(Constants.SMS_RUNNING_TIME , context.getSmsRunningTime()).trim()); + } + + /** + * XECURE protocol only + * - xecure.type + * - xecure.config.path + * - xecure.remote.cert + */ + + if ("XECURE".equals(context.getProtocol())) { + context.setXecureType(prop.getProperty(Constants.XECURE_TYPE, context.getXecureType())); + if (!context.getXecureType().matches("(BASIC|FIXED|WELCOME|ENVELOPE|FIXEDHEADER)")) { + throw new Exception(context.getAdapterName() + " | " + Constants.XECURE_TYPE + " must be one of (BASIC|FIXED|WELCOME|ENVELOPE|FIXEDHEADER), but - '" + context.getXecureType() + "'"); + } + + context.setXecureConfigPath(prop.getProperty(Constants.XECURE_CONFIG_PATH, + context.getXecureConfigPath()).trim()); + + context.setXecureRemoteCert(prop.getProperty(Constants.XECURE_REMOTE_CERT, + context.getXecureRemoteCert()).trim()); + } + + /** + * XECURE2 protocole only + * - xecure2.config.path + * - xecure2.sm.ip + * - xecure2.sm.port + */ + if ("XECURE2".equals(context.getProtocol())) { + if (!"".equals(prop.getProperty(Constants.XECURE2_CONFIG_PATH, "").trim())) { + context.setXecure2ConfigPath(prop.getProperty(Constants.XECURE2_CONFIG_PATH, + context.getXecure2ConfigPath()).trim()); + } + + if (!"".equals(prop.getProperty(Constants.XECURE2_SM_IP, "").trim())) { + context.setXecure2SmIp(prop.getProperty(Constants.XECURE2_SM_IP, + context.getXecure2SmIp()).trim()); + } + + try { + if (!"".equals(prop.getProperty(Constants.XECURE2_SM_PORT, "").trim())) { + context.setXecure2SmPort(Integer.parseInt(prop.getProperty(Constants.XECURE2_SM_PORT, + Integer.toString(context.getXecure2SmPort())).trim())); + } + } catch (NumberFormatException e) { + throw new Exception(context.getAdapterName() + " | " + Constants.XECURE2_SM_PORT + " | " + e.getMessage()); + } + + // use CISCO interface only + if (!"".equals(prop.getProperty(Constants.XECURE_TYPE, "").trim())) { + context.setXecureType(prop.getProperty(Constants.XECURE_TYPE, context.getXecureType())); + } + } + + /** + * XECURE3 protocol only + * - xecure3.type + * - xecure3.config.path + * - xecure3.remote.cert + */ + + if ("XECURE3".equals(context.getProtocol())) { + context.setXecureType(prop.getProperty(Constants.XECURE_TYPE, context.getXecureType())); + if (!context.getXecureType().matches("(ENVELOPE)")) { + throw new Exception(context.getAdapterName() + " | " + Constants.XECURE_TYPE + " must be one of (ENVELOPE), but - '" + context.getXecureType() + "'"); + } + + if (!"".equals(prop.getProperty(Constants.XECURE3_CERT_STORE, "").trim())) { + context.setXecure3CertStore(prop.getProperty(Constants.XECURE3_CERT_STORE, + context.getXecure3CertStore()).trim()); + } + + if (!"".equals(prop.getProperty(Constants.XECURE3_SERVER_CERT, "").trim())) { + context.setXecure3ServerCert(prop.getProperty(Constants.XECURE3_SERVER_CERT, + context.getXecure3ServerCert()).trim()); + } + + if (!"".equals(prop.getProperty(Constants.XECURE3_CLIENT_CERT, "").trim())) { + context.setXecure3ClientCert(prop.getProperty(Constants.XECURE3_CLIENT_CERT, + context.getXecure3ClientCert()).trim()); + } + + if (!"".equals(prop.getProperty(Constants.XECURE3_CERT_KEY, "").trim())) { + context.setXecure3CertKey(prop.getProperty(Constants.XECURE3_CERT_KEY, + context.getXecure3CertKey()).trim()); + } + + if (!"".equals(prop.getProperty(Constants.XECURE3_CERT_PASSWORD, "").trim())) { + context.setXecure3CertPassword(prop.getProperty(Constants.XECURE3_CERT_PASSWORD, + context.getXecure3CertPassword()).trim()); + } + } + /** + * XC3EPB protocol only + * - xc3epb.password + * - xc3epb.config.path + */ + + if ("XC3EPB".equals(context.getProtocol())) { + + if (!"".equals(prop.getProperty(Constants.XC3EPB_PASSWORD, "").trim())) { + context.setXc3epbPassword(prop.getProperty(Constants.XC3EPB_PASSWORD, + context.getXc3epbPassword()).trim()); + } + if (!"".equals(prop.getProperty(Constants.XC3EPB_CONFIG_PATH, "").trim())) { + context.setXc3epbConfigPath(prop.getProperty(Constants.XC3EPB_CONFIG_PATH, + context.getXc3epbConfigPath()).trim()); + } + } + + // 20100423 JGY + if ("ENVELOP".equals(context.getProtocol())) { + if (!"".equals(prop.getProperty(Constants.ENVELOP_SIGNCERT_PATH, "").trim())) { + context.setEnvelopSigncertPath(prop.getProperty(Constants.ENVELOP_SIGNCERT_PATH, + context.getEnvelopSigncertPath()).trim()); + } + + if (!"".equals(prop.getProperty(Constants.ENVELOP_SIGNKEY_PATH, "").trim())) { + context.setEnvelopSignkeyPath(prop.getProperty(Constants.ENVELOP_SIGNKEY_PATH, + context.getEnvelopSignkeyPath()).trim()); + } + + if (!"".equals(prop.getProperty(Constants.ENVELOP_PASSWORD, "").trim())) { + context.setEnvelopPassword(prop.getProperty(Constants.ENVELOP_PASSWORD, + context.getEnvelopPassword()).trim()); + } + } + + /** + * TCSEED protocol only - 20101213 JGY + */ + if ("TCSEED".equals(context.getProtocol())) { + context.setTcseedKeyStore(prop.getProperty(Constants.TCSEED_KEY_STORE, + context.getTcseedKeyStore()).trim()); + + } + /** + * INICIS protocol only + */ + + if ("INICIS".equals(context.getProtocol())) { + context.setInicisKeyPath(prop.getProperty(Constants.INICIS_KEY_PATH, + context.getInicisKeyPath())); + context.setInicisKeyPass(prop.getProperty(Constants.INICIS_KEY_PASS, + context.getInicisKeyPass())); + } + /** + * DELIMITER protocol only + */ + + if ("DELIMITER".equals(context.getProtocol())) { + context.setDelimiter(prop.getProperty(Constants.DELIMITER, + context.getDelimiter())); + } + + if (( "LOGIN".equals(context.getProtocol()) + ||"BIND".equals(context.getProtocol()) + ||"LAZY".equals(context.getProtocol()) ) + && context.isClient()) { + context.setLoginSend(prop.getProperty(Constants.LOGIN_SEND, + context.getLoginSend())); + context.setLoginRecv(prop.getProperty(Constants.LOGIN_RECV, + context.getLoginRecv())); + context.setLlFieldLengthAlpha(Integer.parseInt(prop.getProperty(Constants.LL_FIELD_LENGTH_ALPHA, + Integer.toString(context.getLlFieldLengthAlpha())))); + } + if ("BIND".equals(context.getProtocol()) && context.isClient()) { + context.setBindType(prop.getProperty(Constants.BIND_TYPE, + context.getBindType())); + } + if ("APPEND".equals(context.getProtocol())){ + context.setAppendHead(prop.getProperty(Constants.APPEND_HEAD, + context.getAppendHead())); + context.setAppendTail(prop.getProperty(Constants.APPEND_TAIL, + context.getAppendTail())); + } + + /** + * block.ip.list + */ + if (!"".equals(prop.getProperty(Constants.BLOCK_IP_LIST,"")) && context.isServer()) { + context.setBlockIpList(prop.getProperty(Constants.BLOCK_IP_LIST,"")); + } + /** + * l4.skip.ip.list + */ + if (!"".equals(prop.getProperty(Constants.L4_SKIP_IP_LIST,"")) && context.isServer()) { + context.setL4SkipIpList(prop.getProperty(Constants.L4_SKIP_IP_LIST,"")); + } + + /** + * SingleSession + */ + if (!"".equals(prop.getProperty(Constants.IS_SINGLE_SESSION, ""))) { + context.setSingleSession(prop.getProperty(Constants.IS_SINGLE_SESSION, context.getSingleSession())); + if (context.getSingleSession() == null || !context.getSingleSession().matches("[Y|N]")) { + throw new Exception(context.getAdapterName() + " | " + Constants.IS_SINGLE_SESSION + " must be one of [Y|N], but - '" + context.getSingleSession() + "'"); + } + } + + /** + * SingleSession Primary + */ + if(!"".equals(prop.getProperty(Constants.SINGLE_PRIMARY_INST, ""))) { + context.setPrimaryInstId( prop.getProperty(Constants.SINGLE_PRIMARY_INST, context.getPrimaryInstId())); + } + if ("DYNAMIC_OFFSET".equals(context.getProtocol())){ + if(!"".equals(prop.getProperty(Constants.DYNAMIC_OFFSET_PATTERN, ""))) { + context.setDynamicOffsetPattern( prop.getProperty(Constants.DYNAMIC_OFFSET_PATTERN, context.getDynamicOffsetPattern())); + } + if(!"".equals(prop.getProperty(Constants.DATA_ADD_RULE, ""))) { + context.setDataAddRule( prop.getProperty(Constants.DATA_ADD_RULE, context.getDataAddRule())); + } + if(!"".equals(prop.getProperty(Constants.DATA_REMOVE_RULE, ""))) { + context.setDataRemoveRule( prop.getProperty(Constants.DATA_REMOVE_RULE, context.getDataRemoveRule())); + } + context.setLlInclude("Y"); + } + + /** + * keep.alive + */ + if (!"".equals(prop.getProperty(Constants.KEEP_ALIVE,"N"))) { + context.setKeepAlive(prop.getProperty(Constants.KEEP_ALIVE,"N")); + } + + return context; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/config/SocketAdapterManager.java b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketAdapterManager.java new file mode 100644 index 0000000..ef1b7fa --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketAdapterManager.java @@ -0,0 +1,485 @@ +/* + * Created on 2005. 2. 26. + */ +package com.eactive.eai.adapter.socket2.config; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoSession; + +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +/** + * + */ +public class SocketAdapterManager implements Lifecycle { + private Logger logger = SocketLoggerManager.getInstance().getLogger(); + private Logger errLogger = SocketLoggerManager.getInstance().getErrLogger(); + + public static final long CONNECTION_CHECK_CYCLE = 60 * 1000L; // every 60 sec. + public static final long RECOVERY_CHECK_CYCLE = 10 * 1000L; // every 20 sec. + // 10분간 미상용시 Connection Close; 0으로 설정시 강제적으로 미사용 소켓을 CLOSE하지 않음.... + public static final long UNUSED_CONNECTION_TIMEOUT = 0L; // 10 * 60 * 1000L; + + private static final SocketAdapterManager instance = new SocketAdapterManager(); + private SocketAdapterFactory socketAdapterFactory; + + private ConcurrentHashMap> adapterGroups; + Random random = new Random(); + + private boolean started; + + public static SocketAdapterManager getInstance() { + return instance; + } + + private SocketAdapterManager() { + adapterGroups = new ConcurrentHashMap<>(); + + socketAdapterFactory = new SocketAdapterFactory(); + started = false; + logger.debug(socketAdapterFactory.toString() +" started = " + started); + } + + + public boolean isStarted() { + // 자동 생성된 메소드 스텁 + return false; + } + + public void start() throws LifecycleException { + // 자동 생성된 메소드 스텁 + + } + + public void stop() { + for (Enumeration> e = adapterGroups.elements(); e.hasMoreElements(); ) { + ConcurrentHashMap group = e.nextElement(); + for (Enumeration ee = group.elements(); ee.hasMoreElements(); ) { + ISocketAdapter adapter = ee.nextElement(); + try { + SimpleFuture future = adapter.stop(); + future.join(); + } catch(Exception ex) { + logger.error(adapter.getContext().getAdapterName() + " | " + ex.getMessage(), ex); + errLogger.error(adapter.getContext().getAdapterName() + " | " + ex.getMessage(), ex); + } + } + } + } + + public ConcurrentMap> getSocketAdapterGroups() { + return adapterGroups; + } + + public ISocketAdapter[] getSocketAdapters(String adapterGroupName) { + ConcurrentHashMap adapters0 = adapterGroups.get(adapterGroupName); + if (adapters0 == null) + return null; + ISocketAdapter[] adapters = new ISocketAdapter[adapters0.size()]; + int i = 0; + for (Enumeration e = adapters0.elements(); e.hasMoreElements(); ) { + adapters[i++] = e.nextElement(); + } + return adapters; + } + + public ISocketAdapter getSocketAdapter(String adapterGroupName, String adapterName) { + ConcurrentHashMap adapters = adapterGroups.get(adapterGroupName); + if (adapters == null) + return null; + + if (adapterName != null) { + return adapters.get(adapterName); + } else { + return adapters.elements().nextElement(); + } + } + + public ISocketAdapter getOutboundSocketAdapter(String adapterGroupName, String adapterName) { + ConcurrentHashMap adapters = adapterGroups.get(adapterGroupName); + if (adapters == null) + return null; + + if (adapterName != null) { + return adapters.get(adapterName); + } else { + // select random + Vector started = new Vector<>(); + for (Iterator iter = adapters.values().iterator(); iter.hasNext();) { + ISocketAdapter adapter = iter.next(); + if (adapter.getState() == ISocketAdapter.State.STARTED + && !"INBOUND".equals(adapter.getContext().getBoundUsage()) + && ("N".equals(adapter.getContext().getPermanent()) || adapter.getSessionPool().size() > 0) + ) // concern Non-Permanent pool size 0 + started.add(adapter); + } + Object[] array = started.toArray(); + if (array == null || array.length <= 0) { + return null; + } + else if(array.length > 1) { + int index = random.nextInt(array.length); + return (ISocketAdapter) array[index]; + } + else { + return (ISocketAdapter) array[0]; + } + } + } + + public ISocketAdapter getSocketAdapter(String adapterFullName) { + String adapterGroupName = adapterFullName; + String adapterName = null; + if (adapterFullName.indexOf('.') != -1) { + adapterGroupName = adapterFullName.substring(0, adapterFullName.indexOf('.')); + adapterName = adapterFullName.substring(adapterFullName.indexOf('.')+1); + } + + ConcurrentHashMap adapters = adapterGroups.get(adapterGroupName); + if (adapters == null) + return null; + + if (adapterName != null) { + return adapters.get(adapterName); + } else { + // select random + Vector started = new Vector<>(); + for (Iterator iter = adapters.values().iterator(); iter.hasNext();) { + ISocketAdapter adapter = iter.next(); + if (adapter.getState() == ISocketAdapter.State.STARTED + && adapter.getSessionPool().size() > 0) { + started.add(adapter); + } + } + Object[] array = started.toArray(); + if (array == null || array.length <= 0) { + return null; + } + else if(array.length > 1) { + int index = random.nextInt(array.length); + return (ISocketAdapter) array[index]; + } + else { + return (ISocketAdapter) array[0]; + } + } + } + + /** + * get adapter context + */ + public SocketAdapterContext getContext(String adapterName) { + ISocketAdapter adapter = getSocketAdapter(adapterName); + if (adapter != null) + return adapter.getContext(); + return null; + } + + /** + * Adapter Name별 Socket Adapter starting... + */ + public String start(String adapterGroupName, String adapterName) { + ISocketAdapter adapter = getSocketAdapter(adapterGroupName, adapterName); + if (adapter == null) + return adapterGroupName + "." + adapterName + " | SocketAdapter Manager - cannot start - socket adapter does not exists."; + + try { + adapter.start().join(60000L); + } catch(Exception e) { + return ExceptionStackTrace.dump(e); + } + + return adapterGroupName + "." + adapterName + " | SocketAdapterManager - adapter started"; + } + + + public String stop(String adapterGroupName, String adapterName) { +// StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = getSocketAdapter(adapterGroupName, adapterName); + if (adapter == null) + return adapterGroupName + "." + adapterName + " | SocketAdapterManager - socket adapter does not exists."; + + try { + adapter.stop().join(); + } catch(Exception e) { + return ExceptionStackTrace.dump(e); + } + + return adapterGroupName + "." + adapterName + " | SocketAdapterManager - adapter stopped"; + } + + + public void stop(AdapterVO vo) throws Exception { + stop(vo.getAdapterGroupName(), vo.getName()); + } + + public void addAdapter(ISocketAdapter adapter) throws Exception { + ConcurrentHashMap adapters = adapterGroups.get(adapter.getContext().getAdapterGroupName()); + if (adapters == null) { + adapterGroups.put(adapter.getContext().getAdapterGroupName(), new ConcurrentHashMap()); + } else { + if (adapters.get(adapter.getContext().getAdapterName()) != null) { + logger.warn(adapter.getContext().getAdapterName() + " | SocketAdapterManager - socket adapter already exist -> replace [" + adapter.getContext().getAdapterGroupName() + ", " + adapter.getContext().getAdapterName() + "]"); + try { + ((ISocketAdapter) adapters.get(adapter.getContext().getAdapterName())).stop().join(); + } catch(Exception e) { + logger.warn(adapter.getContext().getAdapterName() + " | old adapter stop error.", e); + //adapter.addRecentError(adapter.getContext().getAdapterName() + " | old adapter stop error.", e); + } finally { + // sleep 1 second to avoid BindException + try { + Thread.sleep(1000L); + } catch(Exception e) { + logger.warn(adapter.getContext().getAdapterName() + " | sleep error.", e); + } + } + //throw new Exception(adapter.getContext().getAdapterName() + " | SocketAdapterManager | start error : Socket adapter aready exist [" + adapter.getContext().getAdapterGroupName() + ", " + adapter.getContext().getAdapterName() + "]"); + } + } + adapterGroups.get(adapter.getContext().getAdapterGroupName()).put(adapter.getContext().getAdapterName(), adapter); + } + + + public synchronized String disconnect(String remoteIP, String remotePort) { + return null; + } + + public String toString() { + return toString(false); + } + + public String toString(boolean verbose) { + StringBuilder sb = new StringBuilder(); + //sb.append("SocketAdater Info (AdpaterGroup > Adapter > Session)\n"); + sb.append("---------------------------------------------------------------------------------------------------------------------\n"); + + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = e.nextElement(); + ConcurrentHashMap adapters = adapterGroups.get(adapterGroupName); + sb.append("ⓖ AdapterGroup : " + adapterGroupName); + //sb.append(", " + adapterGroups); + sb.append("\n"); + for (Enumeration ee = adapters.elements() ; ee.hasMoreElements() ;) { + ISocketAdapter adapter = ee.nextElement(); + sb.append(" ⓐ Adapter : "); + sb.append(adapter.getContext().getAdapterName()); + sb.append(", " + adapter.getState().name()); + sb.append(", " + adapter.getContext().getProtocol()); + sb.append(", " + adapter.getContext().getBoundUsage()); + sb.append("-" + adapter.getContext().getSocketType()); + if (adapter.getContext().isClient()) { + sb.append(" (" + adapter.getContext().getLocalHostName() + ":" + adapter.getContext().getLocalPortNumber()); + sb.append("->"); + sb.append("/" + adapter.getContext().getHostName() + ":" + adapter.getContext().getPortNumber() + ")"); + } else { + sb.append(" (" + adapter.getContext().getHostName() + ":" + adapter.getContext().getPortNumber()); + sb.append("<-)"); + } + if(adapter.getContext().isSync()) { + sb.append(", SYNC"); + } else { + sb.append(", ASYN"); + } + if ("Y".equals(adapter.getContext().getAckSupport())) { + sb.append(", ACK"); + } else { + sb.append(", NO_ACK"); + } + if(adapter.getContext().isPermanent()) { + sb.append(", PERMANENT"); + } else { + sb.append(", NON_PERM"); + } + sb.append(", " + adapter.getContext().getMaxConnection()); + sb.append(", " + adapter.getContext().getMaxThread()); + + if ("FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "ADMIN".equals(adapter.getContext().getProtocol())) { + sb.append(", " + adapter.getContext().getLlFieldType()); + sb.append(":" + adapter.getContext().getLlFieldOffset()); + sb.append(":" + adapter.getContext().getLlFieldLength()); + sb.append(":" + adapter.getContext().getLlFieldInclude()); + sb.append(":" + adapter.getContext().getLlInclude()); + } + + if ("VARIABLE_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "ADMIN".equals(adapter.getContext().getProtocol())) { + sb.append(", " + adapter.getContext().getLlFieldType()); + sb.append(":" + adapter.getContext().getLlFieldOffset()); + sb.append(":" + adapter.getContext().getLlFieldLength()); + sb.append(":" + adapter.getContext().getLlFieldInclude()); + sb.append(":" + adapter.getContext().getLlInclude()); + sb.append(":" + adapter.getContext().getRecvHeaderLength()); + sb.append(":" + adapter.getContext().getSendHeaderLength()); + } + + + if (adapter.getContext().isClient() &&adapter.getContext().isPollingUse()) { + sb.append(" ("); + sb.append("POLLING, "); + sb.append(", " + adapter.getContext().getPollingTimeout()); + sb.append(", " + adapter.getContext().getPollingRequest()); + sb.append(")"); + } + + //KSH + if (adapter.getContext().isClient() &&adapter.getContext().isInitMsgUse()) { + sb.append(" ("); + sb.append("INIT_MSG, "); + sb.append(", " + adapter.getContext().getInitMsgRequest()); + sb.append(")"); + } + + sb.append(", pool:" + adapter.getSessionPool().remaining() + "/" + adapter.getSessionPool().peekSize()); + sb.append(", recv:" + adapter.getMessageRecv()); + sb.append(", send:" + adapter.getMessageSend()); + sb.append(", error:" + adapter.getRecentErrorCount()); + + if ("XECURE".equals(adapter.getContext().getProtocol())) { + sb.append(", ("); + sb.append(adapter.getContext().getXecureType()); + //sb.append(", " + adapter.getContext().getXecureTmode()); + //sb.append(", " + adapter.getContext().getXecureEncodeMode()); + //sb.append(", " + adapter.getContext().getXecurePassword()); + sb.append(", " + adapter.getContext().getXecureConfigPath()); + sb.append(", " + adapter.getContext().getXecureRemoteCert()); + sb.append(")"); + } + +// if (verbose && false) { +// sb.append(", " + adapter.getContext().getDescription()); +// } + + sb.append("\n"); +// if (verbose && false) { +// sb.append(adapter.getContext() + "\n"); +// } + for (Iterator iii = adapter.getSessionPool().iterator() ; iii.hasNext(); ) { + IoSession session = iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :"); + //sb.append(" [" + session.getTrafficMask() + "]"); + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", " + TimeUtil.formatDate(session.getCreationTime())); + //sb.append(" start:" + DatetimeUtil.getCurrentDateDash(session.getCreationTime()) + sb.append(", recv:" + session.getReadMessages()); + //sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + //sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + + if (adapter.getSessionPool().checkedOut() > 0) { + sb.append(" -----------------------------------------------------------------------------------------------\n"); + } + + for (Iterator iii = adapter.getSessionPool().checkedOutIterator() ; iii.hasNext(); ) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :"); + //sb.append(" [" + session.getTrafficMask() + "]"); + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", " + TimeUtil.formatDate(session.getCreationTime())); + //sb.append(" start:" + DatetimeUtil.getCurrentDateDash(session.getCreationTime()) + sb.append(", recv:" + session.getReadMessages()); + //sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + //sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + } + } + sb.append("---------------------------------------------------------------------------------------------------------------------\n"); + //sb.append(queue.toString()); + return sb.toString(); + } + + public void addLifecycleListener(LifecycleListener listener) { + if(logger.isDebug()) logger.debug("addLifecycleListener : " + listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return new LifecycleListener[0]; + } + + public void removeLifecycleListener(LifecycleListener listener) { + if(logger.isDebug()) logger.debug("removeLifecycleListener : " + listener); + } + + public List searchAdapterGroupName(String searchType,String searchValue){ + List adapterGroupNames = new ArrayList<>(); + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = e.nextElement(); + ConcurrentHashMap adapters = adapterGroups.get(adapterGroupName); + + for (Enumeration ee = adapters.elements() ; ee.hasMoreElements() ;) { + ISocketAdapter adapter = ee.nextElement(); + + String value = null; + if ("PROTOCOL".equals(searchType)){ + value = adapter.getContext().getProtocol(); + }else if ("PORTNUMBER".equals(searchType)){ + value = String.valueOf(adapter.getContext().getPortNumber()); + }else if ("HOSTNAME".equals(searchType)){ + value = adapter.getContext().getHostName(); + } + + if (value != null && value.equals(searchValue)){ + adapterGroupNames.add(adapterGroupName); + break; + } + } + } + + return adapterGroupNames; + } + /** + * 일자전환 관련 + * - ATM socket 어댑터를 끊기 위해서 생성 + * + */ + public void sessionCloseAll(String adapterGroupName){ + ConcurrentHashMap adapters0 = adapterGroups.get(adapterGroupName); + if (adapters0 == null) + return ; + int i = 0; + for (Enumeration e = adapters0.elements(); e.hasMoreElements(); ) { + ISocketAdapter socket = e.nextElement(); + socket.getSessionPool().shutdown(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/config/SocketLogger.java b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketLogger.java new file mode 100644 index 0000000..e1918db --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketLogger.java @@ -0,0 +1,12 @@ +package com.eactive.eai.adapter.socket2.config; +//package com.eactive.eai.adapter.socket2.config; +// +//import com.eactive.eai.common.util.Logger; +// +//public class SocketLogger { +// +// public static final int DEFAULT = 0; // WARNING, ERROR, FATAL인 경우 에러로깅 +// public static final int INFO = 1; // INFO 수준의 LOGGING을 수행한다. +// public static final int DEBUG = 2; // DEBUG 수준의 송수신전문 및 에러 메인처리내용의 모든수준의 로깅을 수행한다. +// +//} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/config/SocketLoggerManager.java b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketLoggerManager.java new file mode 100644 index 0000000..777c718 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/config/SocketLoggerManager.java @@ -0,0 +1,134 @@ +/* + * Created on 2005. 2. 26. + */ +package com.eactive.eai.adapter.socket2.config; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +import java.util.HashMap; +import java.util.Properties; + + +/** + * @author janet + */ +public class SocketLoggerManager { + private static SocketLoggerManager instance = new SocketLoggerManager(); + + private HashMap pool = new HashMap() ; // KEY - adapterGroupName, VALUE - logger + private String eaiServer; + public static String DEFAULT_LOGGER_NAME = "NET"; + public static String ERROR_LOGGER_NAME = "ERRORNET"; + + public SocketLoggerManager() { + eaiServer = EAIServerManager.getInstance().getLocalServerName(); + if (eaiServer == null) + eaiServer = ""; + } + + public static SocketLoggerManager getInstance() { + return instance; + } + + public void stop() { + this.removeAll(); + } + + public void removeAll() { + pool.clear(); + } + + // Socket Adapter Group Name별 Logger생성 및 관리... + public void start(String adapterGroupName) { + this.addLogger(adapterGroupName); + } + + public synchronized void addLogger(String adapterGroupName) { + String loggerName = this.getLoggerName( adapterGroupName ); + Object o = pool.get( loggerName ); + if ( o == null ) { + synchronized ( pool ) { + o = pool.get( loggerName ); + if ( o == null ) { + Logger logger = Logger.getLogger( loggerName ); +// boolean isNull = (logger == null ); + pool.put( loggerName, logger ); + } + } + } + } + + private String getLoggerName(String adapterGroupName) { + StringBuffer sb = new StringBuffer(); + sb.append("FileLogger{").append( adapterGroupName ).append("}_").append( this.eaiServer ); + + return sb.toString(); + } + + private String getLoggerBase(String adapterGroupName) { + StringBuffer strBuff = new StringBuffer(); + strBuff.append("FileLogger{").append( adapterGroupName ).append("}"); + + return strBuff.toString(); + } + + public void removeLogger(String adapterGroupName) { + pool.remove( this.getLoggerName( adapterGroupName )); + } + + public void stop(String adapterGroupName) { + // adapterGroupName의 session stop & clear + this.removeLogger( adapterGroupName ); + } + + public Logger getLogger( String adapterGroupName ) { + return getLoggerGroup( adapterGroupName ); + } + + public Logger getErrLogger() { + return getLoggerGroup( ERROR_LOGGER_NAME ); + } + + public Logger getLoggerGroup( String adapterGroupName ) { + + Logger logger = (Logger) pool.get( this.getLoggerName( adapterGroupName ) ); + if ( logger == null ) { + if ( DEFAULT_LOGGER_NAME.equals( adapterGroupName ) ) { + this.addLogger( adapterGroupName ); + logger = (Logger) pool.get( this.getLoggerName( adapterGroupName ) ); + } else { + //PropManager pmanager = PropManager.getInstance(); + AdapterPropManager pmanager = AdapterPropManager.getInstance(); + Properties loggerInfo= null; + + try { + loggerInfo = pmanager.getProperties( getLoggerBase(adapterGroupName) ); + } catch(Exception e) { + loggerInfo = null; + } + + if ( loggerInfo == null ) { + logger = getLogger(); + } else { + this.addLogger( adapterGroupName ); + logger = (Logger) pool.get( this.getLoggerName( adapterGroupName ) ); + } + } + } + return logger; + } + + public Logger getLogger() { + //return Logger.getLogger( Logger.LOGGER_ADAPTER ); + Logger logger = (Logger) pool.get( this.getLoggerName( this.DEFAULT_LOGGER_NAME ) ); + if ( logger == null ) { + this.addLogger( DEFAULT_LOGGER_NAME ); + logger = (Logger) pool.get( this.getLoggerName( DEFAULT_LOGGER_NAME ) ); + } + + return logger; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/acl/AclFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/acl/AclFilter.java new file mode 100644 index 0000000..57f7df0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/acl/AclFilter.java @@ -0,0 +1,83 @@ +package com.eactive.eai.adapter.socket2.filter.acl; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.util.IpUtil; + +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class AclFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + private final Set aclList = new HashSet(); + + public AclFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + + String[] allowList = context.getAclList().split(","); + for (int i=0; i= context.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | AclFilter | deny connection - [" + session.toString() + "]"); + } + + session.close(); + } + + private boolean isAllowed(IoSession session) { + SocketAddress remoteAddress = session.getRemoteAddress(); + + if (remoteAddress instanceof InetSocketAddress) { + byte[] remoteAddr = ((InetSocketAddress) remoteAddress).getAddress().getAddress(); + String remoteIp = ""; + for (int i=0; i 0) { + remoteIp += "."; + } + remoteIp += remoteAddr[i]&0xFF; + } + return IpUtil.isMatchIp(String.join(",", aclList), remoteIp); + } + + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/acl/BlockIpFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/acl/BlockIpFilter.java new file mode 100644 index 0000000..65cb0d0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/acl/BlockIpFilter.java @@ -0,0 +1,82 @@ +package com.eactive.eai.adapter.socket2.filter.acl; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.util.IpUtil; + +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class BlockIpFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + private final Set blockIpList = new HashSet(); + + public BlockIpFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + + String[] blockList = context.getBlockIpList().split(","); + for (int i=0; i= context.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | BlockIpFilter | "+context.getBlockIpList()+" | deny connection - [" + session.toString() + "]"); + } + session.close(); + } + + private boolean isBlocked(IoSession session) { + SocketAddress remoteAddress = session.getRemoteAddress(); + + if (remoteAddress instanceof InetSocketAddress) { + byte[] remoteAddr = ((InetSocketAddress) remoteAddress).getAddress().getAddress(); + String remoteIp = ""; + for (int i=0; i 0) { + remoteIp += "."; + } + remoteIp += remoteAddr[i]&0xFF; + } + return IpUtil.isMatchIp(String.join(",", blockIpList), remoteIp); + } + + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/acl/L4SkipIpFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/acl/L4SkipIpFilter.java new file mode 100644 index 0000000..be9526b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/acl/L4SkipIpFilter.java @@ -0,0 +1,93 @@ +package com.eactive.eai.adapter.socket2.filter.acl; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class L4SkipIpFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + private final Set l4SkipIpList = new HashSet(); + + public L4SkipIpFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + + String[] l4SkipList = context.getL4SkipIpList().split(","); + for (int i=0; i= context.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | L4SkipFilter | "+context.getL4SkipIpList()+" | deny connection - [" + session.toString() + "]"); + } +// session.close(); + } + + private boolean isSkiped(IoSession session) { + SocketAddress remoteAddress = session.getRemoteAddress(); + + if (remoteAddress instanceof InetSocketAddress) { + for (String allow : l4SkipIpList) { + byte[] remoteAddr = ((InetSocketAddress) remoteAddress).getAddress().getAddress(); + String remoteIp = ""; + for (int i=0; i 0) { + remoteIp += "."; + } + remoteIp += remoteAddr[i]&0xFF; + } + + if (allow.indexOf('*') == -1) { + if (allow.equals(remoteIp)) { + return true; + } + } else { + String allowRegexp = allow.replaceAll("\\*", "[0-9]+"); + Matcher matcher = Pattern.compile(allowRegexp, Pattern.CASE_INSENSITIVE).matcher(remoteIp); + if (matcher.matches()) { + return true; + } + } + } + } + + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/datacontrol/DataControlFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/datacontrol/DataControlFilter.java new file mode 100644 index 0000000..d16d06d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/datacontrol/DataControlFilter.java @@ -0,0 +1,117 @@ +package com.eactive.eai.adapter.socket2.filter.datacontrol; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.StringUtil; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class DataControlFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + public DataControlFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + ByteMessage mm = null ; + + /** + * datacontrol.rule + */ + if (!"".equals(context.getDataControlRule())) { + Matcher matcher = Pattern.compile("\\[([ ]*[0-9]+)[ ]*,([ ]*[0-9]+)[ ]*\\][ ]*=[ ]*(.+)").matcher(context.getDataControlRule().trim()); + if (matcher.find()) { + int offset = Integer.parseInt(matcher.group(1).trim()); + int length = Integer.parseInt(matcher.group(2).trim()); + String re = matcher.group(3).trim(); + + + mm = (new ByteMessage()) + .append(m.getBytes(0, offset)) + .append(m.getBytes(offset + length)); + + + } else { + throw new Exception(context.getAdapterName() + " | datacontrol.rule format is invalid : " + context.getDataControlRule()); + } + } + + /** + * next filter + */ + nextFilter.messageReceived(session, mm); + } + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteBuffer) { + m = new ByteMessage((ByteBuffer) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + ByteMessage mm = null ; + + /** + * datacontrol.rule + */ + if (!"".equals(context.getDataControlRule())) { + Matcher matcher = Pattern.compile("\\[([ ]*[0-9]+)[ ]*,([ ]*[0-9]+)[ ]*\\][ ]*=[ ]*(.+)").matcher(context.getDataControlRule().trim()); + if (matcher.find()) { + int offset = Integer.parseInt(matcher.group(1).trim()); + int length = Integer.parseInt(matcher.group(2).trim()); + String re = matcher.group(3).trim(); + if (re != null && length != re.length()){ + re = StringUtil.stringFormat(re, false, ' ', length); + } + if (re != null){ + byte[] org = m.getBytes(offset,length); + + if (re.equals(new String(org))){ + //TODO JUN 같은 값이면 추가 안하는 걸로 했는데 바꿔야 할듯 + mm = m; + }else{ + mm = (new ByteMessage()) + .append(m.getBytes(0, offset)) + .append(re.getBytes()) + .append(m.getBytes(offset)); + } + } + } else { + throw new Exception(context.getAdapterName() + " | datacontrol.rule format is invalid : " + context.getDataControlRule()); + } + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(mm, writeRequest.getFuture(), writeRequest.getDestination())); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/executor/BlockingThreadPoolExecutor.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/executor/BlockingThreadPoolExecutor.java new file mode 100644 index 0000000..4c9af64 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/executor/BlockingThreadPoolExecutor.java @@ -0,0 +1,36 @@ +package com.eactive.eai.adapter.socket2.filter.executor; + +import java.util.concurrent.*; + + + +public class BlockingThreadPoolExecutor extends ThreadPoolExecutor { + private Semaphore semaphore; + + public BlockingThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, + TimeUnit unit, BlockingQueue workQueue) { + super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue); + this.semaphore = new Semaphore(maximumPoolSize); + } + + @Override + public void execute(final Runnable task) { + try { + semaphore.acquire(); + super.execute(new Runnable() { + public void run() { + try { + task.run(); + } finally { + semaphore.release(); + } + } + }); + } catch (InterruptedException e) { + throw new RuntimeException(e.getMessage(), e); + } catch(RejectedExecutionException e) { + semaphore.release(); + throw e; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/executor/BoundedExecutorFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/executor/BoundedExecutorFilter.java new file mode 100644 index 0000000..a244b76 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/executor/BoundedExecutorFilter.java @@ -0,0 +1,318 @@ +package com.eactive.eai.adapter.socket2.filter.executor; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; + +import edu.emory.mathcs.backport.java.util.concurrent.Executor; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; +import org.apache.mina.util.ByteBufferUtil; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.Semaphore; +import java.util.concurrent.TimeUnit; + + +public class BoundedExecutorFilter extends IoFilterAdapter { + private final Logger logger ; + private final Executor executor; + private final Semaphore semaphore; + private ISocketAdapter adapter; + private SocketAdapterContext context; + + + // ---------------------------------------------------------------------- + // added by bmchae + // ---------------------------------------------------------------------- + public BoundedExecutorFilter(ISocketAdapter adapter, Executor executor) { + this.executor = executor; + + //------------------------------------------------------- + // 2009.05.12 + // Connect retry Error + // Outbound의 MaxThread 는 10으로 고정되고 + // connection이 20일 경우 + // 상대편의 Socket Server 가 재기동 되었을 경우 + // retry 수행시 + // this.semaphore 가 20 이 되므로 문제가 발생함 + //------------------------------------------------------- +// this.semaphore = new Semaphore(adapter.getContext().getMaxThread() + 10); + if(adapter.getContext().getMaxThread() > adapter.getContext().getMaxConnection()) { + this.semaphore = new Semaphore(adapter.getContext().getMaxThread() + 10); + } + else { + this.semaphore = new Semaphore(adapter.getContext().getMaxConnection() + 10); + } + this.adapter = adapter; + this.context = adapter.getContext(); + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + } + + /** + * Returns the underlying {@link Executor} instance this filter uses. + */ + public Executor getExecutor() { + return executor; + } + + private void fireEvent(NextFilter nextFilter, IoSession session, EventType type, Object data) { + Event event = new Event(type, nextFilter, data); + final SessionBuffer sessionBuffer = SessionBuffer.getSessionBuffer(session); + + synchronized (sessionBuffer.eventQueue) { + sessionBuffer.eventQueue.add(event); + } + + if (sessionBuffer.processingCompleted) { + sessionBuffer.processingCompleted = false; + if (logger.isDebugEnabled()) { + logger.debug("Launching thread for " + session.getRemoteAddress()); + } + + if (Thread.currentThread().getName().contains("IoProcessor")||Thread.currentThread().getName().contains("DatagramAcceptor")) { + try { + if (semaphore.tryAcquire(context.getTimeout(), TimeUnit.SECONDS)) { + executor.execute(new Runnable() { + public void run() { + try { + (new ProcessEventsRunnable(context, sessionBuffer)).run(); + } finally { + semaphore.release(); + } + } + }); + } else { + throw new RuntimeException("timeout (" + context.getTimeout() + ") occurred when allocate thread"); + } + } catch(InterruptedException e) { + throw new RuntimeException("thread interrupted when acquire semaphore", e); + } catch(RejectedExecutionException e) { + semaphore.release(); + throw new RuntimeException("cannot allocate thread -> increase thread pool size (max.threads)", e); + } + } else { + (new ProcessEventsRunnable(context, sessionBuffer)).run(); + } + } else { //if (type==EventType.CLOSED || type==EventType.EXCEPTION) { + //-------------------------------------------------------------- + // added by bmchae + // client && sync && non-permanent 일 경우 CLOSED/EXCEPTION event 무시 + //-------------------------------------------------------------- + if (context.isClient() + && context.isSync() + && !context.isPermanent() + //&& context.isBlocking() + && (type.equals(EventType.CLOSED) + || (type.equals(EventType.EXCEPTION) && data instanceof java.io.IOException))) { + return; + } + + if (Thread.currentThread().getName().contains("IoProcessor")||Thread.currentThread().getName().contains("DatagramAcceptor")) { + try { + if (semaphore.tryAcquire(context.getTimeout(), TimeUnit.SECONDS)) { + executor.execute(new Runnable() { + public void run() { + try { + (new ProcessEventsRunnable(context, sessionBuffer)).run(); + } finally { + semaphore.release(); + } + } + }); + } else { + throw new RuntimeException("timeout (" + context.getTimeout() + ") occurred when allocate thread"); + } + } catch(InterruptedException e) { + throw new RuntimeException("thread interrupted when acquire semaphore", e); + } catch(RejectedExecutionException e) { + semaphore.release(); + throw new RuntimeException("cannot allocate thread -> increase thread pool size (max.threads)", e); + } + } else { + (new ProcessEventsRunnable(context, sessionBuffer)).run(); + } + } + } + + private static class SessionBuffer { + private static final String KEY = SessionBuffer.class.getName() + ".KEY"; + + private static SessionBuffer getSessionBuffer(IoSession session) { + synchronized (session) { + SessionBuffer sessionBuffer = (SessionBuffer) session.getAttribute(KEY); + if (sessionBuffer == null) { + sessionBuffer = new SessionBuffer(session); + session.setAttribute(KEY, sessionBuffer); + } + return sessionBuffer; + } + } + + private final IoSession session; + + private final List eventQueue = new ArrayList(); + + private boolean processingCompleted = true; + + private SessionBuffer(IoSession session) { + this.session = session; + } + } + + protected static class EventType { + public static final EventType OPENED = new EventType("OPENED"); + public static final EventType CLOSED = new EventType("CLOSED"); + public static final EventType READ = new EventType("READ"); + public static final EventType WRITTEN = new EventType("WRITTEN"); + public static final EventType RECEIVED = new EventType("RECEIVED"); + public static final EventType SENT = new EventType("SENT"); + public static final EventType IDLE = new EventType("IDLE"); + public static final EventType EXCEPTION = new EventType("EXCEPTION"); + + private final String value; + + private EventType(String value) { + this.value = value; + } + + public String toString() { + return value; + } + } + + protected static class Event { + private final EventType type; + + private final NextFilter nextFilter; + + private final Object data; + + Event(EventType type, NextFilter nextFilter, Object data) { + this.type = type; + this.nextFilter = nextFilter; + this.data = data; + } + + public Object getData() { + return data; + } + + public NextFilter getNextFilter() { + return nextFilter; + } + + public EventType getType() { + return type; + } + } + + public void sessionCreated(NextFilter nextFilter, IoSession session) { + nextFilter.sessionCreated(session); + } + + public void sessionOpened(NextFilter nextFilter, IoSession session) { + fireEvent(nextFilter, session, EventType.OPENED, null); + } + + public void sessionClosed(NextFilter nextFilter, IoSession session) { + fireEvent(nextFilter, session, EventType.CLOSED, null); + } + + public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) { + fireEvent(nextFilter, session, EventType.IDLE, status); + } + + public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) { + fireEvent(nextFilter, session, EventType.EXCEPTION, cause); + } + + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) { + ByteBufferUtil.acquireIfPossible(message); + fireEvent(nextFilter, session, EventType.RECEIVED, message); + } + + public void messageSent(NextFilter nextFilter, IoSession session, Object message) { + ByteBufferUtil.acquireIfPossible(message); + fireEvent(nextFilter, session, EventType.SENT, message); + } + + protected void processEvent(NextFilter nextFilter, IoSession session, EventType type, + Object data) { + //---------------------------------------------------------------------- + // added by bmchae + //---------------------------------------------------------------------- + adapter.getThreadMap().put(Thread.currentThread().getName(), Thread.currentThread()); + try { + if (type.equals(EventType.RECEIVED)) { + nextFilter.messageReceived(session, data); + ByteBufferUtil.releaseIfPossible(data); + } else if (type.equals(EventType.SENT)) { + nextFilter.messageSent(session, data); + ByteBufferUtil.releaseIfPossible(data); + } else if (type.equals(EventType.EXCEPTION)) { + nextFilter.exceptionCaught(session, (Throwable) data); + } else if (type.equals(EventType.IDLE)) { + nextFilter.sessionIdle(session, (IdleStatus) data); + } else if (type.equals(EventType.OPENED)) { + nextFilter.sessionOpened(session); + } else if (type.equals(EventType.CLOSED)) { + nextFilter.sessionClosed(session); + } + } finally { + adapter.getThreadMap().remove(Thread.currentThread().getName()); + } + } + + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) { + nextFilter.filterWrite(session, writeRequest); + } + + public void filterClose(NextFilter nextFilter, IoSession session) throws Exception { + nextFilter.filterClose(session); + } + + private class ProcessEventsRunnable implements Runnable { + private final SessionBuffer sessionBuffer; + private SocketAdapterContext context; + + ProcessEventsRunnable(SocketAdapterContext context, SessionBuffer sessionBuffer) { + this.context = context; + this.sessionBuffer = sessionBuffer; + } + + public void run() { + //------------------------------------------------------------------ + // added by bmchae + //------------------------------------------------------------------ + if (Thread.currentThread().getName().startsWith("pool-") && context != null) { + Thread.currentThread().setName(context.getAdapterName() + "-" + Thread.currentThread().getName()); + } + + while (!Thread.currentThread().isInterrupted()) { + Event event; + + synchronized (sessionBuffer.eventQueue) { + if (sessionBuffer.eventQueue.isEmpty()) { + sessionBuffer.processingCompleted = true; + break; + } + + event = (Event) sessionBuffer.eventQueue.remove(0); + } + + processEvent(event.getNextFilter(), sessionBuffer.session, event.getType(), event + .getData()); + } + + if (logger.isDebugEnabled()) { + logger.debug("Exiting since queue is empty for " + + sessionBuffer.session.getRemoteAddress()); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/executor/ExecutorFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/executor/ExecutorFilter.java new file mode 100644 index 0000000..a8829bc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/executor/ExecutorFilter.java @@ -0,0 +1,299 @@ +package com.eactive.eai.adapter.socket2.filter.executor; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import edu.emory.mathcs.backport.java.util.concurrent.Executor; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; +import org.apache.mina.util.ByteBufferUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.RejectedExecutionException; + + +public class ExecutorFilter extends IoFilterAdapter { + private final Logger logger = LoggerFactory.getLogger(getClass()); + private final Executor executor; + private ISocketAdapter adapter; + private SocketAdapterContext context; + + /** + * Creates a new instace with the default thread pool implementation ( + * + * new ThreadPoolExecutor(16, 16, 60, TimeUnit.SECONDS, new LinkedBlockingQueue() ) + * ). + */ + /* + public ExecutorFilter() { + this(new ThreadPoolExecutor(16, 16, 60, TimeUnit.SECONDS, new LinkedBlockingQueue())); + } + */ + + /** + * Creates a new instance with the specified executor. + */ + /* + public ExecutorFilter(Executor executor) { + if (executor == null) { + throw new NullPointerException("executor"); + } + + this.executor = executor; + } + */ + + /** + * Creates a new instance with the specified executor. + */ + // ---------------------------------------------------------------------- + // added by bmchae + // ---------------------------------------------------------------------- + public ExecutorFilter(ISocketAdapter adapter, Executor executor) { + this.executor = executor; + this.adapter = adapter; + this.context = adapter.getContext(); + } + + /** + * Returns the underlying {@link Executor} instance this filter uses. + */ + public Executor getExecutor() { + return executor; + } + + private void fireEvent(NextFilter nextFilter, IoSession session, EventType type, Object data) { + Event event = new Event(type, nextFilter, data); + SessionBuffer buf = SessionBuffer.getSessionBuffer(session); + + synchronized (buf.eventQueue) { + buf.eventQueue.add(event); + if (buf.processingCompleted) { + buf.processingCompleted = false; + if (logger.isDebugEnabled()) { + logger.debug("Launching thread for " + session.getRemoteAddress()); + } + + try { + executor.execute(new ProcessEventsRunnable(context, buf)); + } catch(RejectedExecutionException e) { + throw new RuntimeException("cannot allocate thread -> increase thread pool size (max.threads)", e); + } + } else { //if (type==EventType.CLOSED || type==EventType.EXCEPTION) { + //-------------------------------------------------------------- + // added by bmchae + //-------------------------------------------------------------- + //-------------------------------------------------------------- + // client && sync && non-permanent 일 경우 CLOSED/EXCEPTION event 무시 + //-------------------------------------------------------------- + +// StringBuffer sb = new StringBuffer(); +// sb.append("EventQueue=["); +// for (Iterator iter = buf.eventQueue.iterator(); iter.hasNext();) { +// Event ev = (Event) iter.next(); +// sb.append(ev.getType().toString() + ","); +// } +// sb.append("]"); +// adapter.addRecentError(context.getAdapterName() + " | " +sb.toString()); +// logger.info(context.getAdapterName() + " | " +sb.toString()); +// System.out.println("######################### " + type + " | " + data); + + if (context.isClient() + && context.isSync() + && !context.isPermanent() + //&& context.isBlocking() + && (type.equals(EventType.CLOSED) + || (type.equals(EventType.EXCEPTION) && data instanceof java.io.IOException))) { + return; + } + + try { + executor.execute(new ProcessEventsRunnable(context, buf)); + } catch(RejectedExecutionException e) { + throw new RuntimeException("cannot allocate thread -> increase thread pool size (max.threads)", e); + } + } + } + } + + private static class SessionBuffer { + private static final String KEY = SessionBuffer.class.getName() + ".KEY"; + + private static SessionBuffer getSessionBuffer(IoSession session) { + synchronized (session) { + SessionBuffer buf = (SessionBuffer) session.getAttribute(KEY); + if (buf == null) { + buf = new SessionBuffer(session); + session.setAttribute(KEY, buf); + } + return buf; + } + } + + private final IoSession session; + + private final List eventQueue = new ArrayList(); + + private boolean processingCompleted = true; + + private SessionBuffer(IoSession session) { + this.session = session; + } + } + + protected static class EventType { + public static final EventType OPENED = new EventType("OPENED"); + public static final EventType CLOSED = new EventType("CLOSED"); + public static final EventType READ = new EventType("READ"); + public static final EventType WRITTEN = new EventType("WRITTEN"); + public static final EventType RECEIVED = new EventType("RECEIVED"); + public static final EventType SENT = new EventType("SENT"); + public static final EventType IDLE = new EventType("IDLE"); + public static final EventType EXCEPTION = new EventType("EXCEPTION"); + + private final String value; + + private EventType(String value) { + this.value = value; + } + + public String toString() { + return value; + } + } + + protected static class Event { + private final EventType type; + + private final NextFilter nextFilter; + + private final Object data; + + Event(EventType type, NextFilter nextFilter, Object data) { + this.type = type; + this.nextFilter = nextFilter; + this.data = data; + } + + public Object getData() { + return data; + } + + public NextFilter getNextFilter() { + return nextFilter; + } + + public EventType getType() { + return type; + } + } + + public void sessionCreated(NextFilter nextFilter, IoSession session) { + nextFilter.sessionCreated(session); + } + + public void sessionOpened(NextFilter nextFilter, IoSession session) { + fireEvent(nextFilter, session, EventType.OPENED, null); + } + + public void sessionClosed(NextFilter nextFilter, IoSession session) { + fireEvent(nextFilter, session, EventType.CLOSED, null); + } + + public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) { + fireEvent(nextFilter, session, EventType.IDLE, status); + } + + public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) { + fireEvent(nextFilter, session, EventType.EXCEPTION, cause); + } + + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) { + ByteBufferUtil.acquireIfPossible(message); + fireEvent(nextFilter, session, EventType.RECEIVED, message); + } + + public void messageSent(NextFilter nextFilter, IoSession session, Object message) { + ByteBufferUtil.acquireIfPossible(message); + fireEvent(nextFilter, session, EventType.SENT, message); + } + + protected void processEvent(NextFilter nextFilter, IoSession session, EventType type, + Object data) { + //---------------------------------------------------------------------- + // added by bmchae + //---------------------------------------------------------------------- + adapter.getThreadMap().put(Thread.currentThread().getName(), Thread.currentThread()); + try { + if (type.equals(EventType.RECEIVED)) { + nextFilter.messageReceived(session, data); + ByteBufferUtil.releaseIfPossible(data); + } else if (type.equals(EventType.SENT)) { + nextFilter.messageSent(session, data); + ByteBufferUtil.releaseIfPossible(data); + } else if (type.equals(EventType.EXCEPTION)) { + nextFilter.exceptionCaught(session, (Throwable) data); + } else if (type.equals(EventType.IDLE)) { + nextFilter.sessionIdle(session, (IdleStatus) data); + } else if (type.equals(EventType.OPENED)) { + nextFilter.sessionOpened(session); + } else if (type.equals(EventType.CLOSED)) { + nextFilter.sessionClosed(session); + } + } finally { + adapter.getThreadMap().remove(Thread.currentThread().getName()); + } + } + + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) { + nextFilter.filterWrite(session, writeRequest); + } + + public void filterClose(NextFilter nextFilter, IoSession session) throws Exception { + nextFilter.filterClose(session); + } + + private class ProcessEventsRunnable implements Runnable { + private final SessionBuffer buffer; + private SocketAdapterContext context; + + ProcessEventsRunnable(SocketAdapterContext context, SessionBuffer buffer) { + this.context = context; + this.buffer = buffer; + } + + public void run() { + //------------------------------------------------------------------ + // added by bmchae + //------------------------------------------------------------------ + if (Thread.currentThread().getName().startsWith("pool-") && context != null) { + Thread.currentThread().setName( + context.getAdapterName() + "-" + Thread.currentThread().getName()); + } + + while (true) { + Event event; + + synchronized (buffer.eventQueue) { + if (buffer.eventQueue.isEmpty()) { + buffer.processingCompleted = true; + break; + } + + event = (Event) buffer.eventQueue.remove(0); + } + + processEvent(event.getNextFilter(), buffer.session, event.getType(), event + .getData()); + } + + if (logger.isDebugEnabled()) { + logger.debug("Exiting since queue is empty for " + + buffer.session.getRemoteAddress()); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/flowcontrol/FlowControlFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/flowcontrol/FlowControlFilter.java new file mode 100644 index 0000000..e7b1490 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/flowcontrol/FlowControlFilter.java @@ -0,0 +1,18 @@ +package com.eactive.eai.adapter.socket2.filter.flowcontrol; + +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + + +/** + * TODO : snmp 와 연동... + */ +public class FlowControlFilter extends IoFilterAdapter { + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + // Some logic here... + nextFilter.messageReceived(session, message); + // Some other logic here... + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/flowcontrol/ReadThrottleFilterBuilder.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/flowcontrol/ReadThrottleFilterBuilder.java new file mode 100644 index 0000000..d0df5c7 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/flowcontrol/ReadThrottleFilterBuilder.java @@ -0,0 +1,119 @@ +package com.eactive.eai.adapter.socket2.filter.flowcontrol; + +import com.eactive.eai.adapter.socket2.filter.executor.BoundedExecutorFilter; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import org.apache.mina.common.DefaultIoFilterChainBuilder; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoFilterChain.Entry; +import org.apache.mina.common.IoSession; + +import java.util.Iterator; +import java.util.List; + + +/** + * IoFilterChain chain = config.getFilterChain(); + * ReadThrottleFilterBuilder filter = new ReadThrottleFilterBuilder(); + * filter.attach(chain); + */ + +public class ReadThrottleFilterBuilder { + public static final String COUNTER = ReadThrottleFilterBuilder.class.getName() + ".counter"; + + public static final String SUSPENDED_READS = ReadThrottleFilterBuilder.class.getName() + ".suspendedReads"; + + private volatile int maximumConnectionBufferSize = 100; // 1024 * 1024; // 1mb + + public void setMaximumConnectionBufferSize(int maximumConnectionBufferSize) { + this.maximumConnectionBufferSize = maximumConnectionBufferSize; + } + + public void attach(IoFilterChain chain) { + String name = getThreadPoolFilterEntryName(chain.getAll()); + + chain.addBefore(name, getClass().getName() + ".add", new Add()); + chain.addAfter(name, getClass().getName() + ".release", new Release()); + } + + public void attach(DefaultIoFilterChainBuilder builder) { + String name = getThreadPoolFilterEntryName(builder.getAll()); + + builder.addBefore(name, getClass().getName() + ".add", new Add()); + builder.addAfter(name, getClass().getName() + ".release", new Release()); + } + + private String getThreadPoolFilterEntryName(List entries) { + Iterator i = entries.iterator(); + + while (i.hasNext()) { + Entry entry = i.next(); + + if (entry.getFilter().getClass().isAssignableFrom(BoundedExecutorFilter.class)) { + return entry.getName(); + } + } + + throw new IllegalStateException("Chain does not contain a ExecutorFilter"); + } + + private void add(IoSession session, int size) { + synchronized (session) { + int counter = getCounter(session); + counter = counter + size; + session.setAttribute(COUNTER, new Integer(counter)); + + if (counter >= maximumConnectionBufferSize && session.getTrafficMask().isReadable()) { +//System.out.println("----- session -> suspendRead() : "); + session.suspendRead(); + session.setAttribute(SUSPENDED_READS); + } + } + } + + private void release(IoSession session, int size) { + synchronized (session) { + int counter = Math.max(0, getCounter(session) - size); + session.setAttribute(COUNTER, new Integer(counter)); + + if (counter < maximumConnectionBufferSize && isSuspendedReads(session)) { +//System.out.println("+++++ session -> resumeRead() : "); + session.resumeRead(); + session.removeAttribute(SUSPENDED_READS); + } + + } + } + + private boolean isSuspendedReads(IoSession session) { + Boolean flag = (Boolean) session.getAttribute(SUSPENDED_READS); + return null != flag && flag.booleanValue(); + } + + private int getCounter(IoSession session) { + Integer i = (Integer) session.getAttribute(COUNTER); + return null == i ? 0 : i.intValue(); + } + + private class Add extends IoFilterAdapter { + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) + throws Exception { + if (message instanceof ByteMessage) { + add(session, ((ByteMessage) message).size()); + } + + nextFilter.messageReceived(session, message); + } + } + + private class Release extends IoFilterAdapter { + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) + throws Exception { + if (message instanceof ByteMessage) { + release(session, ((ByteMessage) message).size()); + } + + nextFilter.messageReceived(session, message); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/initmsgshake/InitMsgFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/initmsgshake/InitMsgFilter.java new file mode 100644 index 0000000..b2d9485 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/initmsgshake/InitMsgFilter.java @@ -0,0 +1,167 @@ +package com.eactive.eai.adapter.socket2.filter.initmsgshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.ExecutorService; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class InitMsgFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + + private static final String FILTER_STATE_KEY = InitMsgFilter.class.getName() + ".STATE"; + private static class FilterState { + SimpleFuture initMsgResponseFuture = new SimpleFuture(); + } + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + protected ExecutorService executor; + private static String endHandshake="N"; + + public InitMsgFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + nextFilter.sessionCreated(session); + } + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState != null && filterState.initMsgResponseFuture != null) { + filterState.initMsgResponseFuture.set(new Exception("session closed by peer")); + } + endHandshake="N"; + nextFilter.sessionClosed(session); + } + + @Override + public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState != null && filterState.initMsgResponseFuture != null) { + filterState.initMsgResponseFuture.set(cause); + } + endHandshake="N"; + nextFilter.exceptionCaught(session, cause); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + if (context.isInitMsgSender() && context.isPermanent() && context.isInitMsgUse()){ + sendInitMsgRequest(session); + } + endHandshake="N"; + nextFilter.sessionOpened(session); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { +// FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (endHandshake.equals("N") ){ + endHandshake = "Y"; + } else { + nextFilter.messageReceived(session, message); + } + } + + private void sendInitMsgRequest(IoSession session) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + final byte[] initMsgRequest = getInitMsgRequestFormatted(); + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentSend(session, "InitMsgFilter | session idle -> initMsg request - " + + CommonLib.hexDump(initMsgRequest, true, context)); + logger.debug(context.getAdapterName() + " | InitMsgFilter | session idle -> initMsg request - " + + CommonLib.hexDump(initMsgRequest, true, context)); + } + IoSession sess = adapter.getSessionPool().acquire(session); + try { + if (filterState.initMsgResponseFuture == null) { + filterState.initMsgResponseFuture = new SimpleFuture(); + } + final IoSession s = session; +// final FilterState hState = filterState; + if (Thread.currentThread().getName().startsWith("pool-")) { + Thread.currentThread().setName(context.getAdapterName() + "-InitMsgFilter-" + Thread.currentThread().getName()); + } + internalSendMessage(s, initMsgRequest); + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | InitMsgFilter | error when send INIT_MSG request - " + e.getMessage(), e); + logger.warn(context.getAdapterName() + " | InitMsgFilter | error when send INIT_MSG request - " + e.getMessage()); + } finally { + if (sess != null) { + adapter.getSessionPool().release(sess); + } + } + } + + protected void internalSendMessage(IoSession session, Object message) throws Exception { + ByteMessage m = null; + + if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else { + throw new Exception("Unknown data format"); + } +// WriteFuture future = session.write(message); + session.write(message); + } + + protected byte[] getInitMsgRequestFormatted() { + String message = context.getInitMsgRequest(); + //Polling ·ÎÁ÷ ¼öÁ¤ 2017.05 KSH + String str[] = message.split("%d"); + String endMsg = ""; + for(int i=0; i= context.TRACE_LEVEL_TRACE && !"HTTP".equals(context.getProtocol())) { + logger.debug(context.getAdapterName() + " | ConnectionLimitFilter | session created : " + session); + } + */ + //Session 오픈 이전에 message를 수신하지 않도록 한다. + session.suspendRead(); + + SessionPool sessionPool = adapter.getSessionPool(); + + /** + * max connection 제한 + */ + synchronized(this) { + if (context.getMaxConnection() > 0) { + /** + * TODO : 아래 원인을 다시 한번 체크해 볼 것 + * clear invalid ('CLOSING') connections - avoid bug + */ + for (Iterator iter = sessionPool.iterator(); iter.hasNext(); ) { + IoSession s = (IoSession) iter.next(); + if (s != null && s.isClosing()) { + s.close(); + sessionPool.remove(s); + } + } + + /** + * curr connections >= max.connection 이라면, 아래 2가지 중 한 작업 + */ + if (sessionPool.size() >= context.getMaxConnection()) { + /** + * [1] close existing 'YOUNGEST' connections + */ + if (context.getCloseExistingConnection()) { + if (sessionPool.size() > 0) { + IoSession victim = sessionPool.acquireYoungest(); + + if (victim != null) { + StringBuffer sb = new StringBuffer(); + sb.append(context.getAdapterName() + " | ConnectionLimitFilter | "); + sb.append("max connection(" + context.getMaxConnection() + ") exceeded "); + sb.append("-> remove 'YOUNGEST' victim connection in pool - [" + victim.toString() + "]"); + sb.append(", put new connection in pool - [" + session + "]"); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_INFO) { + logger.info(sb.toString()); + } + + adapter.addRecentErrorOnly(sb.toString() + "\n" + dumpSessionPool()); + + victim.close(); + sessionPool.remove(victim); + } else { + sessionPool.shutdown(); + } + } + /** + * [2] close new connections + */ + } else { + StringBuffer sb = new StringBuffer(); + sb.append(context.getAdapterName() + " | ConnectionLimitFilter | "); + sb.append("max connection(" + sessionPool.size() + "/" + context.getMaxConnection() + ") exceeded "); + sb.append("-> close 'new' session - [" + session.toString() + "]"); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_INFO) { + logger.info(sb.toString()); + } + + adapter.addRecentErrorOnly(sb.toString() + "\n" + dumpSessionPool()); + + sessionPool.remove(session); + session.close(); + + return; + } + } + } + } + + /** + * remote ip 당 connection 갯수 제한 (SERVER only) + */ + synchronized (this) { + if (context.isServer() && context.getConnLimitPerIp() > 0) { + String remoteIp = ((InetSocketAddress) session.getRemoteAddress()).getHostName(); + Integer remotePort = ((InetSocketAddress) session.getRemoteAddress()).getPort(); + + if (ipLimitTable.get(remoteIp) == null) { + ipLimitTable.put(remoteIp, new ConcurrentHashMap()); + } + + /** + * TODO : 아래 원인을 다시 한번 체크해 볼 것 + * clear invalid ('CLOSING') connections - avoid bug + */ + ConcurrentHashMap map = (ConcurrentHashMap) ipLimitTable.get(remoteIp); + for (Iterator iter = map.values().iterator(); iter.hasNext(); ) { + IoSession s = (IoSession) iter.next(); + if (s != null && s.isClosing()) { + s.close(); + map.remove(((InetSocketAddress) s.getRemoteAddress()).getPort()); + } + } + + if (((ConcurrentHashMap) ipLimitTable.get(remoteIp)).size() < context.getConnLimitPerIp()) { + ((ConcurrentHashMap) ipLimitTable.get(remoteIp)).put(remotePort, session); + } else { + /** + * [1] close existing 'OLDEST' connections + * 2009.09.10 권세환대리 요청 + * negative(-) 옵션을 준 상태에서 세션이 Full 상태 일때, 가장 오래 된 세션을 끊고 새로운 세션을 연결한다. + */ + if (context.getCloseExistingConnectionPerIpLimit()) { + if (sessionPool.size() > 0) { + IoSession victim = sessionPool.acquire(); + + if (victim != null) { + Integer victimPort = ((InetSocketAddress) victim.getRemoteAddress()).getPort(); + + StringBuffer sb = new StringBuffer(); + sb.append(context.getAdapterName() + " | ConnectionLimitFilter | "); + sb.append("connection.limit.per.ip(" + context.getConnLimitPerIp() + ") exceeded "); + sb.append("-> remove 'OLDEST' victim connection in pool - [" + victim.toString() + "]"); + sb.append(", put new connection in pool - [" + session + "]"); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_INFO) { + logger.info(sb.toString()); + } + + adapter.addRecentErrorOnly(sb.toString() + "\n" + dumpSessionPool()); + + victim.close(); + sessionPool.remove(victim); + + ((ConcurrentHashMap) ipLimitTable.get(remoteIp)).remove(victimPort); + ((ConcurrentHashMap) ipLimitTable.get(remoteIp)).put(remotePort, session); + } else { + sessionPool.shutdown(); + } + } + } + /** + * [2] close new connections + */ + else { + StringBuffer sb = new StringBuffer(); + sb.append(context.getAdapterName() + " | ConnectionLimitFilter | "); + sb.append("session created. : but connection.limit.per.ip(" + context.getConnLimitPerIp() + ") exceeded "); + sb.append("-> close 'new' session. (" + session + ")"); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_INFO) { + logger.info(sb.toString()); + } + + adapter.addRecentErrorOnly(sb.toString() + "\n" + + dumpSessionPool() + + dumpIpLimitTable()); + + sessionPool.remove(session); + session.close(); + + return; + } + } + } + } + + //Connection Limit 를 체크한후 Message 를 Read 한다. + session.resumeRead(); + + nextFilter.sessionOpened(session); + } + + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { + /* + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE && !"HTTP".equals(context.getProtocol())) { + logger.debug(context.getAdapterName() + " | ConnectionLimitFilter | session closed : " + session); + } + */ + + /** + * remote ip 당 connection 갯수 제한 (SERVER only) + */ + synchronized (this) { + if (context.isServer() && context.getConnLimitPerIp() > 0) { + String remoteIp = ((InetSocketAddress) session.getRemoteAddress()).getHostName(); + Integer remotePort = ((InetSocketAddress) session.getRemoteAddress()).getPort(); + + if (ipLimitTable.get(remoteIp) == null) { + ipLimitTable.put(remoteIp, new ConcurrentHashMap()); + } + + ((ConcurrentHashMap) ipLimitTable.get(remoteIp)).remove(remotePort); + } + } + + nextFilter.sessionClosed(session); + } + + + private String dumpSessionPool() { + StringBuffer sb = new StringBuffer(); + sb.append("SessionPool Dump : "); + sb.append("\n"); + for (Iterator i = adapter.getSessionPool().iterator() ; i.hasNext(); ) { + IoSession session = (IoSession) i.next(); + sb.append(" " + sessionInfo(session) + "\n"); + } + sb.append(""); + + sb.append(""); + for (Iterator i = adapter.getSessionPool().checkedOutIterator() ; i.hasNext(); ) { + IoSession session = (IoSession) i.next(); + sb.append(" " + sessionInfo(session) + "\n"); + } + sb.append(""); + + return sb.toString(); + } + + + private String dumpIpLimitTable() { + StringBuffer sb = new StringBuffer(); + sb.append("IpLimitTable Dump : "); + sb.append("\n"); + for (Iterator iter = ipLimitTable.keySet().iterator() ; iter.hasNext(); ) { + String ip = iter.next(); + ConcurrentHashMap map = (ConcurrentHashMap) ipLimitTable.get(ip); + sb.append(String.format(" * %s (%d)\n", ip, map.size())); + for (Iterator iter2 = map.values().iterator() ; iter2.hasNext(); ) { + IoSession session = (IoSession) iter2.next(); + sb.append(" " + sessionInfo(session) + "\n"); + } + } + sb.append(""); + return sb.toString(); + } + + + private String sessionInfo(IoSession session) { + StringBuffer sb = new StringBuffer(); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :");; + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime())); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/polling/HexPollingFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/polling/HexPollingFilter.java new file mode 100644 index 0000000..8e83c53 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/polling/HexPollingFilter.java @@ -0,0 +1,295 @@ +package com.eactive.eai.adapter.socket2.filter.polling; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class HexPollingFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + + private static final String FILTER_STATE_KEY = HexPollingFilter.class.getName() + ".STATE"; + + private static class FilterState { + SimpleFuture pollingResponseFuture = new SimpleFuture(); + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + protected ExecutorService executor; + + + public HexPollingFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + this.executor = Executors.newCachedThreadPool(); + ((ThreadPoolExecutor) this.executor).setKeepAliveTime(1L, TimeUnit.SECONDS); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + //SimpleFuture handshakeFuture = new SimpleFuture(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState != null && filterState.pollingResponseFuture != null) { + filterState.pollingResponseFuture.set(new Exception("session closed by peer")); + } + + nextFilter.sessionClosed(session); + } + + + @Override + public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception { + if (context.isPollingSender() && context.isPermanent() && context.isPollingUse() + && System.currentTimeMillis()-session.getLastIoTime() > (context.getTimeout() + 1) * 1000L + && System.currentTimeMillis()-session.getLastIoTime() < (context.getPollingTimeout() + 10) * 1000L) { + sendPollingRequest(session); + } else { + nextFilter.sessionIdle(session, status); + } + } + + + @Override + public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState != null && filterState.pollingResponseFuture != null) { + filterState.pollingResponseFuture.set(cause); + } + nextFilter.exceptionCaught(session, cause); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + ByteMessage m = (ByteMessage) message; + + if (recvPolling(session, m, filterState)) { + if (filterState.pollingResponseFuture == null) { + filterState.pollingResponseFuture = new SimpleFuture(); + } + filterState.pollingResponseFuture.set(m); + } else { + nextFilter.messageReceived(session, message); + } + } + + + private void sendPollingRequest(IoSession session) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + /** + * send polling request + */ + final byte[] pollingRequest = getPollingRequestFormatted(); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentSend(session, "HexPollingFilter | session idle -> polling request - " + + CommonLib.hexDump(pollingRequest, true, context)); + logger.debug(context.getAdapterName() + " | HexPollingFilter | session idle -> polling request - " + + CommonLib.hexDump(pollingRequest, true, context)); + } + + IoSession sess = adapter.getSessionPool().acquire(session); + + try { + if (filterState.pollingResponseFuture == null) { + filterState.pollingResponseFuture = new SimpleFuture(); + } + + final IoSession s = sess; + final FilterState hState = filterState; + + FutureTask futureTask = new FutureTask(new Callable() { + public byte[] call() { + if (Thread.currentThread().getName().startsWith("pool-")) { + Thread.currentThread().setName(context.getAdapterName() + "-HexPollingFilter-" + Thread.currentThread().getName()); + } + + try { + internalSendMessage(s, pollingRequest); + + /** + * oneway 이면 기다리지 않는다. + */ + if (adapter.getContext().isPollingOneway()) { + return null; + } + + if (hState.pollingResponseFuture != null) { + Object result = hState.pollingResponseFuture.join(context.getTimeout() * 1000L); + if (result instanceof ByteMessage) { + return ((ByteMessage) result).getBytes(); + } else { + throw new Exception("error when wait polling response", (Throwable) result); + } + } else { + throw new Exception("future result(poll message response) is null"); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | " + e.getMessage(), e); + logger.warn(context.getAdapterName() + " | " + e.getMessage()); + return null; + } + } + }); + + executor.execute(futureTask); + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | HexPollingFilter | error when send POLLING request - " + e.getMessage(), e); + logger.warn(context.getAdapterName() + " | HexPollingFilter | error when send POLLING request - " + e.getMessage()); + } finally { + if (sess != null) { + adapter.getSessionPool().release(sess); + } + } + } + + + private boolean recvPolling(IoSession session, ByteMessage m, FilterState filterState) throws Exception { + ByteMessage om = m; + + if ("Y".equals(context.getLlInclude())) { + m = (new ByteMessage()) + .append(m.getBytes(0, context.getLlFieldOffset())) + .append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + } + + if (context.isPollingReceiver() && m.getString().matches(getHexToStr(context.getPollingRequestPattern()))) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, "HexPollingFilter | polling request - " + om.hexDump()); + logger.debug(context.getAdapterName() + " | HexPollingFilter | polling request - " + om.hexDump()); + } + + /** + * oneway 일 경우, polling 응답을 보내지 않는다 + */ + if (context.isPollingOneway()) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, "HexPollingFilter | oneway polling - skip sending polling response"); + logger.debug(context.getAdapterName() + " | HexPollingFilter | oneway polling - skip sending polling response"); + } + return true; + } + + try { + byte[] response = m.getString().replaceAll(getHexToStr(context.getPollingRequestPattern()), + getHexToStr(context.getPollingReplacement())).getBytes(); + + if ("Y".equals(context.getLlInclude())) { + byte[] ll = new byte[context.getLlFieldLength()]; + ByteMessage rm = new ByteMessage(response); + ByteMessage mm = (new ByteMessage()) + .append(rm.getBytes(0, context.getLlFieldOffset())) + .append(ll) + .append(rm.getBytes(context.getLlFieldOffset())); + response = mm.getBytes(); + } + + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentSend(session, "HexPollingFilter | polling response - " + CommonLib.hexDump(response, true, context)); + logger.debug(context.getAdapterName() + " | HexPollingFilter | polling response - " + CommonLib.hexDump(response, true, context)); + } + + internalSendMessage(session, response); + } catch (Exception e) { + throw e; + } + + return true; + } else if (context.isPollingSender() && m.getString().matches(getHexToStr(context.getPollingResponsePattern()))) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, "HexPollingFilter | polling response - " + om.hexDump()); + logger.debug(context.getAdapterName() + " | HexPollingFilter | polling response - " + om.hexDump()); + } + + return true; + } + + return false; + } + + + protected void internalSendMessage(IoSession session, Object message) throws Exception { + ByteMessage m = null; + + if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else { + throw new Exception("Unknown data format"); + } +// WriteFuture future = session.write(message); + session.write(message); + //future.join(context.getTimeout() * 1000L); + + } + + + protected byte[] getPollingRequestFormatted() { + String message = getHexToStr(context.getPollingRequest()); + Matcher matcher = Pattern.compile("%d\\{([a-zA-Z \\-]+)\\}").matcher(getHexToStr(context.getPollingRequest())); + if (matcher.find()) { + String datePattern = matcher.group(1); + DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(datePattern); + message = getHexToStr(context.getPollingRequest()).replaceAll("%d\\{([a-zA-Z \\-]+)\\}", dateFormat.format(ZonedDateTime.now())); + } + + if ("Y".equals(context.getLlInclude())) { + byte[] ll = new byte[context.getLlFieldLength()]; + ByteMessage mm = (new ByteMessage()) + .append(message.substring(0, context.getLlFieldOffset())) + .append(ll) + .append(message.substring(context.getLlFieldOffset())); + return mm.getBytes(); + } else { + return message.getBytes(); + } + } + protected String getHexToStr(String str){ + ByteMessage data = new ByteMessage(); + while(str.indexOf("0x") != -1) { + data.append(str.substring(0, str.indexOf("0x"))); + String hex = str.substring(str.indexOf("0x"), str.indexOf("0x")+4); + data.append((byte) Integer.parseInt(hex.substring(2), 16)); + str = str.substring(str.indexOf("0x")+4); + } + data.append(str); + return data.getString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/polling/KFTCPollingFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/polling/KFTCPollingFilter.java new file mode 100644 index 0000000..e0284ee --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/polling/KFTCPollingFilter.java @@ -0,0 +1,322 @@ +package com.eactive.eai.adapter.socket2.filter.polling; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.concurrent.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class KFTCPollingFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + + private static final String FILTER_STATE_KEY = KFTCPollingFilter.class.getName() + ".STATE"; + private static final int offset =0; //context.getLlFieldOffset() 을 offset 으로 변경 + private static class FilterState { + SimpleFuture pollingResponseFuture = new SimpleFuture(); + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + protected ExecutorService executor; + + + public KFTCPollingFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + this.executor = Executors.newCachedThreadPool(); + ((ThreadPoolExecutor) this.executor).setKeepAliveTime(1L, TimeUnit.SECONDS); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + //SimpleFuture handshakeFuture = new SimpleFuture(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState != null && filterState.pollingResponseFuture != null) { + filterState.pollingResponseFuture.set(new Exception("session closed by peer")); + } + + nextFilter.sessionClosed(session); + } + + + @Override + public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception { + int responseTimeout = 0; + + if (session.containsAttribute("responseTimeout")){ + responseTimeout = (Integer)session.getAttribute("responseTimeout"); + } +// if (context.isPollingSender() && context.isPermanent() && context.isPollingUse() +// && System.currentTimeMillis()-session.getLastIoTime() > (context.getTimeout() + 1) * 1000L +// && System.currentTimeMillis()-session.getLastIoTime() < (context.getPollingTimeout() + 10) * 1000L) { +// sendPollingRequest(session); +// } else { +// nextFilter.sessionIdle(session, status); +// } + if (responseTimeout > 0){ + nextFilter.sessionIdle(session, status); + }else{//원래로직 + if (context.isPollingSender() && context.isPermanent() && context.isPollingUse() + && System.currentTimeMillis()-session.getLastIoTime() > (context.getTimeout() + 1) * 1000L + && System.currentTimeMillis()-session.getLastIoTime() < (context.getPollingTimeout() + 10) * 1000L) { + sendPollingRequest(session); + } else { + nextFilter.sessionIdle(session, status); + } + } + + } + + + @Override + public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState != null && filterState.pollingResponseFuture != null) { + filterState.pollingResponseFuture.set(cause); + } + nextFilter.exceptionCaught(session, cause); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + ByteMessage m = (ByteMessage) message; + + if (recvPolling(session, m, filterState)) { + if (filterState.pollingResponseFuture == null) { + filterState.pollingResponseFuture = new SimpleFuture(); + } + filterState.pollingResponseFuture.set(m); + } else { + nextFilter.messageReceived(session, message); + } + } + + + private void sendPollingRequest(IoSession session) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + /** + * send polling request + */ + final byte[] pollingRequest = getPollingRequestFormatted(); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentSend(session, "KFTCPollingFilter | session idle -> polling request - " + + CommonLib.hexDump(pollingRequest, true, context)); + logger.debug(context.getAdapterName() + " | KFTCPollingFilter | session idle -> polling request - " + + CommonLib.hexDump(pollingRequest, true, context)); + } + + IoSession sess = adapter.getSessionPool().acquire(session); + + try { + if (filterState.pollingResponseFuture == null) { + filterState.pollingResponseFuture = new SimpleFuture(); + } + + final IoSession s = sess; + final FilterState hState = filterState; + + FutureTask futureTask = new FutureTask(new Callable() { + public byte[] call() { + if (Thread.currentThread().getName().startsWith("pool-")) { + Thread.currentThread().setName(context.getAdapterName() + "-KFTCPollingFilter-" + Thread.currentThread().getName()); + } + + try { + internalSendMessage(s, pollingRequest); + + /** + * oneway 이면 기다리지 않는다. + */ + if (adapter.getContext().isPollingOneway()) { + return null; + } + + if (hState.pollingResponseFuture != null) { + Object result = hState.pollingResponseFuture.join(context.getTimeout() * 1000L); + if (result instanceof ByteMessage) { + return ((ByteMessage) result).getBytes(); + } else { + throw new Exception("error when wait polling response", (Throwable) result); + } + } else { + throw new Exception("future result(poll message response) is null"); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | " + e.getMessage(), e); + logger.warn(context.getAdapterName() + " | " + e.getMessage()); + return null; + } + } + }); + + executor.execute(futureTask); + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | KFTCPollingFilter | error when send POLLING request - " + e.getMessage(), e); + logger.warn(context.getAdapterName() + " | KFTCPollingFilter | error when send POLLING request - " + e.getMessage()); + } finally { + if (sess != null) { + adapter.getSessionPool().release(sess); + } + } + } + + + private boolean recvPolling(IoSession session, ByteMessage m, FilterState filterState) throws Exception { + ByteMessage om = m; + + if ("Y".equals(context.getLlInclude())) { + m = (new ByteMessage()) + .append(m.getBytes(0, offset)) + .append(m.getBytes(offset + context.getLlFieldLength())); + } + + if (context.isPollingReceiver() && m.getString().matches(context.getPollingRequestPattern())) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, "KFTCPollingFilter | polling request - " + om.hexDump()); + logger.debug(context.getAdapterName() + " | KFTCPollingFilter | polling request - " + om.hexDump()); + } + + /** + * oneway 일 경우, polling 응답을 보내지 않는다 + */ + if (context.isPollingOneway()) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, "KFTCPollingFilter | oneway polling - skip sending polling response"); + logger.debug(context.getAdapterName() + " | KFTCPollingFilter | oneway polling - skip sending polling response"); + } + return true; + } + + try { + byte[] response = m.getString().replaceAll(context.getPollingRequestPattern(), + context.getPollingReplacement()).getBytes(); + + if ("Y".equals(context.getLlInclude())) { + byte[] ll = new byte[context.getLlFieldLength()]; + ll = padding(ll,(byte)0x30); + ByteMessage rm = new ByteMessage(response); + ByteMessage mm = (new ByteMessage()) + .append(rm.getBytes(0, offset)) + .append(ll) + .append(rm.getBytes(offset)); + response = mm.getBytes(); + } + + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentSend(session, "KFTCPollingFilter | polling response - " + CommonLib.hexDump(response, true, context)); + logger.debug(context.getAdapterName() + " | KFTCPollingFilter | polling response - " + CommonLib.hexDump(response, true, context)); + } + + internalSendMessage(session, response); + } catch (Exception e) { + throw e; + } + + return true; + } else if (context.isPollingSender() && m.getString().matches(context.getPollingResponsePattern())) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, "KFTCPollingFilter | polling response - " + om.hexDump()); + logger.debug(context.getAdapterName() + " | KFTCPollingFilter | polling response - " + om.hexDump()); + } + + return true; + } + + return false; + } + + + protected void internalSendMessage(IoSession session, Object message) throws Exception { + ByteMessage m = null; + + if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else { + throw new Exception("Unknown data format"); + } + +// WriteFuture future = session.write(message); + session.write(message); + //future.join(context.getTimeout() * 1000L); + } + + + protected byte[] getPollingRequestFormatted() { + String message = context.getPollingRequest(); + //Polling 로직 수정 2017.05 KSH + String str[] = message.split("%d"); + String endMsg = ""; + for(int i=0; i (context.getTimeout() + 1) * 1000L +// && System.currentTimeMillis()-session.getLastIoTime() < (context.getPollingTimeout() + 10) * 1000L) { +// sendPollingRequest(session); +// } else { +// nextFilter.sessionIdle(session, status); +// } + if (responseTimeout > 0){ + nextFilter.sessionIdle(session, status); + }else{//원래로직 + if (context.isPollingSender() && context.isPermanent() && context.isPollingUse() + && System.currentTimeMillis()-session.getLastIoTime() > (context.getTimeout() + 1) * 1000L + && System.currentTimeMillis()-session.getLastIoTime() < (context.getPollingTimeout() + 10) * 1000L) { + sendPollingRequest(session); + } else { + nextFilter.sessionIdle(session, status); + } + } + + } + + + @Override + public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState != null && filterState.pollingResponseFuture != null) { + filterState.pollingResponseFuture.set(cause); + } + nextFilter.exceptionCaught(session, cause); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + ByteMessage m = (ByteMessage) message; + + if (recvPolling(session, m, filterState)) { + if (filterState.pollingResponseFuture == null) { + filterState.pollingResponseFuture = new SimpleFuture(); + } + filterState.pollingResponseFuture.set(m); + } else { + nextFilter.messageReceived(session, message); + } + } + + + private void sendPollingRequest(IoSession session) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + /** + * send polling request + */ + final byte[] pollingRequest = getPollingRequestFormatted(); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentSend(session, "PollingFilter | session idle -> polling request - " + + CommonLib.hexDump(pollingRequest, true, context)); + logger.debug(context.getAdapterName() + " | PollingFilter | session idle -> polling request - " + + CommonLib.hexDump(pollingRequest, true, context)); + } + + IoSession sess = adapter.getSessionPool().acquire(session); + + try { + if (filterState.pollingResponseFuture == null) { + filterState.pollingResponseFuture = new SimpleFuture(); + } + + final IoSession s = sess; + final FilterState hState = filterState; + + FutureTask futureTask = new FutureTask(new Callable() { + public byte[] call() { + if (Thread.currentThread().getName().startsWith("pool-")) { + Thread.currentThread().setName(context.getAdapterName() + "-PollingFilter-" + Thread.currentThread().getName()); + } + + try { + internalSendMessage(s, pollingRequest); + + /** + * oneway 이면 기다리지 않는다. + */ + if (adapter.getContext().isPollingOneway()) { + return null; + } + + if (hState.pollingResponseFuture != null) { + Object result = hState.pollingResponseFuture.join(context.getTimeout() * 1000L); + if (result instanceof ByteMessage) { + return ((ByteMessage) result).getBytes(); + } else { + throw new Exception("error when wait polling response", (Throwable) result); + } + } else { + throw new Exception("future result(poll message response) is null"); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | " + e.getMessage(), e); + logger.warn(context.getAdapterName() + " | " + e.getMessage()); + return null; + } + } + }); + + executor.execute(futureTask); + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | PollingFilter | error when send POLLING request - " + e.getMessage(), e); + logger.warn(context.getAdapterName() + " | PollingFilter | error when send POLLING request - " + e.getMessage()); + } finally { + if (sess != null) { + adapter.getSessionPool().release(sess); + } + } + } + + + private boolean recvPolling(IoSession session, ByteMessage m, FilterState filterState) throws Exception { + ByteMessage om = m; + + if ("Y".equals(context.getLlInclude())) { + m = (new ByteMessage()) + .append(m.getBytes(0, context.getLlFieldOffset())) + .append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + } + + if (context.isPollingReceiver() && m.getString().matches(context.getPollingRequestPattern())) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, "PollingFilter | polling request - " + om.hexDump()); + logger.debug(context.getAdapterName() + " | PollingFilter | polling request - " + om.hexDump()); + } + + /** + * oneway 일 경우, polling 응답을 보내지 않는다 + */ + if (context.isPollingOneway()) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, "PollingFilter | oneway polling - skip sending polling response"); + logger.debug(context.getAdapterName() + " | PollingFilter | oneway polling - skip sending polling response"); + } + return true; + } + + try { + byte[] response = m.getString().replaceAll(context.getPollingRequestPattern(), + context.getPollingReplacement()).getBytes(); + + if ("Y".equals(context.getLlInclude())) { + byte[] ll = new byte[context.getLlFieldLength()]; + ByteMessage rm = new ByteMessage(response); + ByteMessage mm = (new ByteMessage()) + .append(rm.getBytes(0, context.getLlFieldOffset())) + .append(ll) + .append(rm.getBytes(context.getLlFieldOffset())); + response = mm.getBytes(); + } + + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentSend(session, "PollingFilter | polling response - " + CommonLib.hexDump(response, true, context)); + logger.debug(context.getAdapterName() + " | PollingFilter | polling response - " + CommonLib.hexDump(response, true, context)); + } + + internalSendMessage(session, response); + } catch (Exception e) { + throw e; + } + + return true; + } else if (context.isPollingSender() && m.getString().matches(context.getPollingResponsePattern())) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, "PollingFilter | polling response - " + om.hexDump()); + logger.debug(context.getAdapterName() + " | PollingFilter | polling response - " + om.hexDump()); + } + + return true; + } + + return false; + } + + + protected void internalSendMessage(IoSession session, Object message) throws Exception { + ByteMessage m = null; + + if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else { + throw new Exception("Unknown data format"); + } + +// WriteFuture future = session.write(message); + session.write(message); + //future.join(context.getTimeout() * 1000L); + } + + + protected byte[] getPollingRequestFormatted() { + String message = context.getPollingRequest(); + //Polling 로직 수정 2017.05 KSH + String str[] = message.split("%d"); + String endMsg = ""; + for(int i=0; i= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | create SSLContext - " + (isServer ? "SERVER" : "CLIENT")); + } + + SSLContext sslContext = null; + if (isServer) { + if (serverSslContext == null) { + synchronized (SSLContextFactory.class) { + if (serverSslContext == null) { + try { + serverSslContext = createServerSSLContext(context); + } catch (Exception ioe) { + throw new GeneralSecurityException("Can't create Server SSLContext:" + ioe); + } + } + } + } + sslContext = serverSslContext; + } else { + if (clientSslContext == null) { + synchronized (SSLContextFactory.class) { + if (clientSslContext == null) { + clientSslContext = createClientSSLContext(context); + } + } + } + sslContext = clientSslContext; + } + return sslContext; + } + + + private static SSLContext createServerSSLContext(SocketAdapterContext context) throws GeneralSecurityException, IOException { + // Create keystore + KeyStore ks = KeyStore.getInstance("JKS"); + InputStream in = null; + try { + in = SSLContextFactory.class.getResourceAsStream(context.getSslCertStore()); + if (in == null) { + throw new GeneralSecurityException("ssl cert store does not exist - " + context.getSslCertStore()); + } + ks.load(in, context.getSslCertPassword().toCharArray()); + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException ignored) { + } + } + } + + // Set up key manager factory to use our key store + KeyManagerFactory kmf = KeyManagerFactory.getInstance(KEY_MANAGER_FACTORY_ALGORITHM); + kmf.init(ks, context.getSslCertPassword().toCharArray()); + + // Initialize the SSLContext to work with our key managers. + SSLContext sslContext = SSLContext.getInstance(PROTOCOL); + sslContext.init(kmf.getKeyManagers(), TrustManagerFactory.X509_MANAGERS, null); + + return sslContext; + } + + + private static SSLContext createClientSSLContext(SocketAdapterContext context) throws GeneralSecurityException { + SSLContext sslContext = SSLContext.getInstance(PROTOCOL); + sslContext.init(null, TrustManagerFactory.X509_MANAGERS, null); + //SSLSocket sslSocket = (SSLSocket) sslContext.getSocketFactory().createSocket(); + //sslSocket.startHandshake(); + return sslContext; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/SSLServerSocketFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/SSLServerSocketFactory.java new file mode 100644 index 0000000..e03d1af --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/SSLServerSocketFactory.java @@ -0,0 +1,68 @@ +package com.eactive.eai.adapter.socket2.filter.ssl; +//package com.eactive.eai.adapter.socket2.protocol.ssl; +// +//import java.io.IOException; +//import java.net.InetAddress; +//import java.net.ServerSocket; +//import java.security.GeneralSecurityException; +// +//import javax.net.ServerSocketFactory; +// +//import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +//import com.eactive.eai.common.util.Logger; +// +// +//public class SSLServerSocketFactory extends javax.net.ServerSocketFactory { +// static final protected Logger logger = SocketLoggerManager.getInstance().getLogger(); +// static final protected Logger errLogger = SocketLoggerManager.getInstance().getErrLogger(); +// +// private static boolean sslEnabled = false; +// private static javax.net.ServerSocketFactory sslFactory = null; +// private static ServerSocketFactory factory = null; +// +// public SSLServerSocketFactory() { +// super(); +// } +// +// public ServerSocket createServerSocket(int port) throws IOException { +// return new ServerSocket(port); +// } +// +// public ServerSocket createServerSocket(int port, int backlog) throws IOException { +// return new ServerSocket(port, backlog); +// } +// +// public ServerSocket createServerSocket(int port, int backlog, InetAddress ifAddress) +// throws IOException { +// return new ServerSocket(port, backlog, ifAddress); +// } +// +// public static javax.net.ServerSocketFactory getServerSocketFactory() throws IOException { +// if (isSslEnabled()) { +// if (sslFactory == null) { +// try { +// sslFactory = SSLContextFactory.createSSLContext(true).getServerSocketFactory(); +// } catch (GeneralSecurityException e) { +// IOException ioe = new IOException("could not create SSL socket"); +// ioe.initCause(e); +// throw ioe; +// } +// } +// return sslFactory; +// } else { +// if (factory == null) { +// factory = new SSLServerSocketFactory(); +// } +// return factory; +// } +// +// } +// +// public static boolean isSslEnabled() { +// return sslEnabled; +// } +// +// public static void setSslEnabled(boolean newSslEnabled) { +// sslEnabled = newSslEnabled; +// } +//} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/SSLSocketFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/SSLSocketFactory.java new file mode 100644 index 0000000..20bd147 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/SSLSocketFactory.java @@ -0,0 +1,88 @@ +package com.eactive.eai.adapter.socket2.filter.ssl; +//package com.eactive.eai.adapter.socket2.protocol.ssl; +// +//import java.io.IOException; +//import java.net.InetAddress; +//import java.net.Socket; +//import java.net.UnknownHostException; +//import java.security.GeneralSecurityException; +// +//import javax.net.SocketFactory; +// +//import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +//import com.eactive.eai.common.util.Logger; +// +// +//public class SSLSocketFactory extends SocketFactory { +// static final protected Logger logger = SocketLoggerManager.getInstance().getLogger(); +// static final protected Logger errLogger = SocketLoggerManager.getInstance().getErrLogger(); +// +// private static boolean sslEnabled = false; +// private static javax.net.ssl.SSLSocketFactory sslFactory = null; +// private static javax.net.SocketFactory factory = null; +// +// public SSLSocketFactory() { +// super(); +// } +// +// public Socket createSocket(String arg1, int arg2) throws IOException, UnknownHostException { +// if (isSslEnabled()) { +// return getSSLFactory().createSocket(arg1, arg2); +// } else { +// return new Socket(arg1, arg2); +// } +// } +// +// public Socket createSocket(String arg1, int arg2, InetAddress arg3, int arg4) throws IOException, UnknownHostException { +// if (isSslEnabled()) { +// return getSSLFactory().createSocket(arg1, arg2, arg3, arg4); +// } else { +// return new Socket(arg1, arg2, arg3, arg4); +// } +// } +// +// public Socket createSocket(InetAddress arg1, int arg2) throws IOException { +// if (isSslEnabled()) { +// return getSSLFactory().createSocket(arg1, arg2); +// } else { +// return new Socket(arg1, arg2); +// } +// } +// +// public Socket createSocket(InetAddress arg1, int arg2, InetAddress arg3, int arg4) throws IOException { +// System.out.println("-SSLSocketFactory.createSocket()"); +// +// if (isSslEnabled()) { +// return getSSLFactory().createSocket(arg1, arg2, arg3, arg4); +// } else { +// return new Socket(arg1, arg2, arg3, arg4); +// } +// } +// +// public static javax.net.SocketFactory getSocketFactory() { +// if (factory == null) { +// factory = new SSLSocketFactory(); +// } +// return factory; +// } +// +// private javax.net.ssl.SSLSocketFactory getSSLFactory() throws IOException { +// if (sslFactory == null) { +// try { +// sslFactory = SSLContextFactory.createSSLContext(false).getSocketFactory(); +// } catch (GeneralSecurityException e) { +// throw new RuntimeException("could not create SSL socket", e); +// } +// } +// return sslFactory; +// } +// +// public static boolean isSslEnabled() { +// return sslEnabled; +// } +// +// public static void setSslEnabled(boolean newSslEnabled) { +// sslEnabled = newSslEnabled; +// } +// +//} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/TrustManagerFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/TrustManagerFactory.java new file mode 100644 index 0000000..5398dbf --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/TrustManagerFactory.java @@ -0,0 +1,48 @@ +package com.eactive.eai.adapter.socket2.filter.ssl; + +import javax.net.ssl.ManagerFactoryParameters; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactorySpi; +import javax.net.ssl.X509TrustManager; +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + + + +class TrustManagerFactory extends TrustManagerFactorySpi { + + static final X509TrustManager X509 = new X509TrustManager() { + public void checkClientTrusted(X509Certificate[] x509Certificates, + String s) throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] x509Certificates, + String s) throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[0]; + } + }; + + static final TrustManager[] X509_MANAGERS = new TrustManager[] { X509 }; + + public TrustManagerFactory() { + } + + protected TrustManager[] engineGetTrustManagers() { + return X509_MANAGERS; + } + + protected void engineInit(KeyStore keystore) throws KeyStoreException { + // noop + } + + protected void engineInit(ManagerFactoryParameters managerFactoryParameters) + throws InvalidAlgorithmParameterException { + // noop + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/bogus.cert b/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/bogus.cert new file mode 100644 index 0000000..d34502d Binary files /dev/null and b/src/main/java/com/eactive/eai/adapter/socket2/filter/ssl/bogus.cert differ diff --git a/src/main/java/com/eactive/eai/adapter/socket2/filter/validation/ValidationFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/filter/validation/ValidationFilter.java new file mode 100644 index 0000000..c3c6963 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/filter/validation/ValidationFilter.java @@ -0,0 +1,63 @@ +package com.eactive.eai.adapter.socket2.filter.validation; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class ValidationFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + public ValidationFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + /* + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | ValidationFilter | messageReceived()"); + } + */ + + ByteMessage m = (ByteMessage) message; + + /** + * validation.rule + */ + if (!"".equals(context.getValidationRule())) { + Matcher matcher = Pattern.compile("\\[([ ]*[0-9]+)[ ]*,([ ]*[0-9]+)[ ]*\\][ ]*=[ ]*(.+)").matcher(context.getValidationRule().trim()); + if (matcher.find()) { + int offset = Integer.parseInt(matcher.group(1).trim()); + int length = Integer.parseInt(matcher.group(2).trim()); + String re = matcher.group(3).trim(); + + if (!new String(m.getBytes(offset, length)).matches(re)) { + throw new Exception(context.getAdapterName() + " | data is invalid - validation.rule : " + context.getValidationRule() + " " + m.hexDump()); + } + } else { + throw new Exception(context.getAdapterName() + " | validation.rule format is invalid : " + context.getValidationRule()); + } + } + + /** + * next filter + */ + nextFilter.messageReceived(session, message); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/ByteMessage.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/ByteMessage.java new file mode 100644 index 0000000..a20964c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/ByteMessage.java @@ -0,0 +1,143 @@ +package com.eactive.eai.adapter.socket2.protocol; + +import org.apache.mina.common.ByteBuffer; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; + +public class ByteMessage { + protected byte[] value; + + public ByteMessage() { + this.value = new byte[0]; + } + + public ByteMessage(byte[] value) { + this.value = value; + } + + public ByteMessage(String value) { + this.value = value.getBytes(); + } + + public ByteMessage(ByteBuffer buffer) { + this.setByteBuffer(buffer); + } + + public byte getByte(int offset) { + return this.value[offset]; + } + + public byte[] getBytes() { + return value; + } + + public byte[] getBytes(int offset, int length) throws EAIException { + if (size() - offset - length < 0) { + throw new EAIException("ByteMessage | cannot make negative array size bytes" + + "| size=" + size() + ", offset=" + offset + ", length=" + length + " - " + CommonLib.hexDump(this.value)); + } + + byte[] bytes = new byte[length]; + System.arraycopy(value, offset, bytes, 0, length); + return bytes; + } + + public byte[] getBytes(int offset) { + if (size() - offset < 0) { + throw new RuntimeException("ByteMessage | cannot make negative array size bytes" + + "| size=" + size() + ", offset=" + offset + " - " + CommonLib.hexDump(this.value)); + } + + byte[] bytes = new byte[size()-offset]; + System.arraycopy(value, offset, bytes, 0, size()-offset); + return bytes; + } + + public ByteMessage exclude(int offset, int length) throws EAIException { + byte[] messageWithoutLl = new byte[size() - length]; + System.arraycopy(getBytes(0, offset), 0, messageWithoutLl, 0, offset); + System.arraycopy(getBytes(offset + length), 0, messageWithoutLl, offset+length, size()-length-offset); + return new ByteMessage(messageWithoutLl); + } + + public ByteMessage append(byte b) { + byte[] sum = new byte[size() + 1]; + System.arraycopy(this.value, 0, sum, 0, size()); + sum[size()] = b; + this.value = sum; + return this; + } + + public ByteMessage append(byte[] bytes) { + byte[] sum = new byte[size() + bytes.length]; + System.arraycopy(this.value, 0, sum, 0, size()); + System.arraycopy(bytes, 0, sum, size(), bytes.length); + this.value = sum; + return this; + } + + public ByteMessage append(String str) { + return append(str.getBytes()); + } + + public ByteMessage padding(int length, byte b) throws EAIException { + if (length >= size()) { + byte[] sum = new byte[length]; + System.arraycopy(this.value, 0, sum, 0, size()); + for (int i=0; i retryThreads; + protected SessionPool sessionPool; + + protected long messageSend = 0; + protected long messageRecv = 0; + private boolean isXCInclude = false;//XecuserConnect 모듈 유무 판단. + + protected ProtocolHandler(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + + this.sessionPool = new SessionPool(adapter, context); + //XecuserConnect 모듈 유무 판단. + try { + Class clazz = Class.forName("com.sf.xc3.XCException"); + isXCInclude = true; + logger.warn("XCException include"); + } catch (Throwable e) { + logger.error("XCException not include"); + } + } + + public void start() throws Exception { + this.retryThreads = new ArrayList<>(); + } + + public void stop() throws Exception { + for (Iterator iter = (new ArrayList(retryThreads)).iterator(); iter.hasNext(); ) { + try { + iter.next().interrupt(); + } catch(ConcurrentModificationException e) { + logger.debug("stop ConcurrentModificationException"); + } + } + } + + @Override + public void sessionCreated(IoSession session) throws Exception { + super.sessionCreated(session); + + synchronized(lockObj) { + HandlerState handlerState = (HandlerState) session.getAttribute(HANDLER_STATE_KEY); + if (handlerState == null) { + handlerState = new HandlerState(); + session.setAttribute(HANDLER_STATE_KEY, handlerState); + setSessionState(session, handlerState.state.toString()); + + SimpleFuture handshakeFuture = new SimpleFuture(); + session.setAttribute(HANDSHAKE_FUTURE, handshakeFuture); + } + } + } + + @Override + public void sessionOpened(IoSession session) throws Exception { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE && !"HTTP".equals(context.getProtocol())) { + logger.debug(context.getAdapterName() + " | session opened : " + session); + } + + // DEFAULT : false + if(session.getTransportType() == TransportType.SOCKET + && context.isKeepAlive()) { + ((SocketSessionConfig)session.getConfig()).setKeepAlive(true); + } + + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + session.setWriteTimeout(context.getTimeout()); + + HandlerState handlerState = (HandlerState) session.getAttribute(HANDLER_STATE_KEY); + if (handlerState == null) { + handlerState = new HandlerState(); + handlerState.state = State.STATE_MESSAGE_WAIT_REQUEST; + session.setAttribute(HANDLER_STATE_KEY, handlerState); + } + + synchronized(lockObj) { + sessionPool.release(session); + + if (!context.isPermanent()) { + SimpleFuture handshakeFuture = (SimpleFuture) session.getAttribute(HANDSHAKE_FUTURE); + if (handshakeFuture != null) { + handshakeFuture.set(Boolean.TRUE); + } + } + + adapter.setAdapterStatus(true); + } + if("Y".equals(context.getSingleSession())){ + logger.debug(context.getAdapterName() + " | session opened : SingleSession - " + session); + SingleSessionManager.getInstance().sessionOpen(context.getAdapterGroupName(), session); + } + } + + @Override + public void sessionIdle(IoSession session, IdleStatus status) { + HandlerState handlerState = (HandlerState) session.getAttribute(HANDLER_STATE_KEY); + + StringBuilder sb = new StringBuilder(); + sb.append("idle:" + TimeUtil.elapsedTime(session.getLastIoTime())); + if (System.currentTimeMillis()-session.getLastIoTime() < (context.getTimeout() + 1) * 1000L) { + sb.append(", timeout:" + context.getTimeout()); + sb.append(", protocol:" + context.getProtocol()); + if (handlerState != null) { + sb.append(", state:" + handlerState.state.toString()); + } + sb.append("/" + session.getAttribute(SESSION_STATE)); + sb.append("/" + session.getAttribute(CODEC_STATE)); + sb.append(", " + session.getAttribute(CODEC_STATE_BUFFER)); + + logger.error(context.getAdapterName() + " | transaction timeout -> disconnecting (" + session + ") " + sb.toString()); + adapter.addRecentError(context.getAdapterName() + " | transaction timeout -> disconnecting (" + session + ") " + sb.toString()); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA005"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA005"); + } else { + /** + * idle.timeout이 0 이면 connection을 끊지 않는다. + */ + if (context.getIdleTimeout() == 0) { + return; + } + + adapter.addRecentErrorOnly(context.getAdapterName() + " | session idle -> disconnecting (" + session + ") " + sb.toString()); + logger.info(context.getAdapterName() + " | session idle -> disconnecting (" + session + ") " + sb.toString()); + } + + // disconnect an idle client + sessionPool.remove(session); + session.close(); + } + + @Override + public void sessionClosed(IoSession session) throws Exception { + try { + /** + * logging + */ + if (context.isPermanent() && context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + /** + * ignore L4 connection close event + */ + if (session.getWrittenMessages()==0 && session.getReadMessages()==0 + && System.currentTimeMillis() - session.getCreationTime() < 1000) { + // ignore - skip logging + } else { + adapter.addRecentError(context.getAdapterName() + " | session closed (" + session + ")"); + } + } + + if (context.isPermanent() && context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE && !"HTTP".equals(context.getProtocol())) { + logger.debug(context.getAdapterName() + " | session closed (" + session + ")" + ""); + } + + HandlerState handlerState = (HandlerState) session.getAttribute(HANDLER_STATE_KEY); + if (handlerState != null + && handlerState.responseFuture != null + && (context.isServer() || context.isPermanent())) { + handlerState.responseFuture.set(new Exception("session closed by peer (" + session + ")")); + } + + ConnectFuture connectFuture = (ConnectFuture) session.getAttribute("connectFuture"); + if (connectFuture != null) { + connectFuture.setException(new Exception("inbound session is closed by peer (" + session + ")")); + } + + if (!context.isPermanent()) { + return; + } + + if (adapter.getState() == ISocketAdapter.State.STOPPING || adapter.getState() == ISocketAdapter.State.STOPPED) { + return; + } + } finally { + try { + if("Y".equals(context.getSingleSession())){ + SingleSessionManager.getInstance().sessionClose(context.getAdapterGroupName(), session); + } + + sessionPool.remove(session); + session.close(); + + if (sessionPool.size() <= 0 && context.isPermanent()) { + adapter.setAdapterStatus(false); + } + } catch(Exception e) { + logger.error(context.getAdapterName() + " | " + e.getMessage(), e); + } + } + + if (adapter instanceof SocketAdapterClient + && context.isPermanent() + && adapter.getState() == ISocketAdapter.State.STARTED + && adapter.getSessionPool().size() < adapter.getContext().getMaxConnection() + && !("INISAFE".equals(context.getProtocol()) + || "INISAFE_2020".equals(context.getProtocol()) + || "INISAFE_NATN".equals(context.getProtocol()) + )) { + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | session closed -> try to connect after 10 seconds ..."); + } + + while (!Thread.currentThread().isInterrupted()) { + if (adapter.getState() != ISocketAdapter.State.STARTED) { + break; + } + + // 싱글어댑터 - Start --------------------------------------------------------------------------------------------------------------------- + boolean retry = true; + + // 싱글어댑터 session 종료 시 재연결 처리 + if (context.getSingleSession().equals("Y")) { + String primaryInst = context.getPrimaryInstId(); + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String localServerName = eaiServerManager.getLocalServerName(); + String adapterGroupName = context.getAdapterGroupName(); + + if (localServerName.equals(primaryInst)) { // CASE : Primary 서버 + SessionVO sessionVO = SessionManager.getInstance().getConnectionStatus(adapterGroupName); + + if(sessionVO != null) { // Secondary 서버가 연결하고 있음 + retry = false; + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + "| SingleSession Validation Exist [" +sessionVO.getLoginInstId()+"]"); + } + + } else { // Secondary 서버가 연결하지 않고 있으므로 연결 시도함. + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + "| SingleSession Validation Connection empty -> retry to connect after 10 secs"); + } + } + } else { // CASE : Secondary 서버 + boolean isAlive = HealthCheckManager.getInstance().getServerStatus(primaryInst); // Primay서버 상태 확인 + + if (isAlive) { // Primary 서버 살아있으면 재연결 시도 안함 + retry = false; + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) + logger.debug(context.getAdapterName() + "| SingleSession Validation Exist [" +primaryInst+"]"); + } else { + SessionManager.getInstance().removeConnectionInfo(adapterGroupName); + } + } + + } + + if(!retry) { + try { + Thread.sleep(10 * 1000L); + } catch (InterruptedException e) { + logger.error(context.getAdapterName() + " | " + e.getMessage(), e); + } + continue; + } + // 싱글어댑터 - End --------------------------------------------------------------------------------------------------------------------- + /** + * FDS - connectOne 시도 후, 바로 connection이 끊어지는 경우 + * ExecutorFilter에서 Thread 생성이 계속 늘어나는 현상을 방지 + * connection retry thread 개수를 max.connection 개수에 맞춘다. + */ + synchronized(retryThreads) { + if (sessionPool.size() + retryThreads.size() >= context.getMaxConnection()) { + break; + } + retryThreads.add(Thread.currentThread()); + } + + try { + try { + Thread.sleep(10000L); + } catch(InterruptedException ee) { + break; + } catch(Exception ee) { + logger.error(context.getAdapterName() + " | " + ee.getMessage(), ee); + } + +// if (adapter.getState() != ISocketAdapter.State.STARTED) { +// break; +// } + + try { + if (adapter.connectOne() != null) { + break; + } + } catch(Throwable t) { + logger.debug(context.getAdapterName() + " | session closed -> fail to reconnect -> retry after 10 seconds. caused by " + t.toString()); + } + } finally { + synchronized(retryThreads) { + retryThreads.remove(Thread.currentThread()); + } + } + } + } + } + + @Override + public void exceptionCaught(IoSession session, Throwable cause) { + if (cause instanceof IOException) { + logger.warn(context.getAdapterName() + " | " + cause.getMessage() + " (" + session + ")"); + String cMsg = cause.getMessage(); + if( (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) && context.isPermanent() + && (cMsg != null && cMsg.indexOf("reset by peer") != -1) ) { + adapter.addRecentError(context.getAdapterName() + " | " + cMsg + " (" + session + ")", cause); + } + + } else if (isXCInclude && cause instanceof com.sf.xc3.XCException) { + logger.warn(context.getAdapterName() + " | session exception caught (" + session + ") - " + cause.getMessage()); + } else { + String errorMsg = context.getAdapterName() + " | session exception caught (" + session + ")"; + logger.error(errorMsg, cause); + adapter.addRecentError(errorMsg, cause); + errLogger.error(errorMsg, cause); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA001"); + } + + HandlerState handlerState = (HandlerState) session.getAttribute(HANDLER_STATE_KEY); + if (handlerState != null && handlerState.responseFuture != null + && cause instanceof IOException + && (context.isServer() || context.isPermanent())) { + handlerState.responseFuture.set(cause); + } + + // close the connection on exceptional situation + // TODO : 위의 sessionClosed() 메쏘드가 불려져서 pool에서 제거되는지 확인 + sessionPool.remove(session); + session.close(); + } + + public SocketAdapterContext getContext() { + return context; + } + + public SessionPool getSessionPool() { + return sessionPool; + } + + /** + * message received + */ + @Override + public void messageReceived(final IoSession session, Object message) throws Exception { + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG && !"HTTP".equals(context.getProtocol())) { + logger.debug(context.getAdapterName() + " (" + session + ") | " + message); + } + + HandlerState handlerState = (HandlerState) session.getAttribute(HANDLER_STATE_KEY); + if (handlerState == null) { + handlerState = new HandlerState(); + handlerState.state = State.STATE_MESSAGE_WAIT_REQUEST; + session.setAttribute(HANDLER_STATE_KEY, handlerState); + } + + incMessageRecv(); + + ByteMessage m = (ByteMessage) message; + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + adapter.addRecentRecv(session, CommonLib.hexDump(m.getBytes(), true, context)); + } + + switch (handlerState.state) { + case STATE_MESSAGE_WAIT_RESPONSE: + if (handlerState.responseFuture != null) { + handlerState.responseFuture.set(m); + } + if (context.isPermanent() && (!session.isConnected() || session.isClosing())) { + throw new IOException("session is not connected (" + session + ")"); + } + break; + + case STATE_MESSAGE_WAIT_REQUEST: + try { + sessionPool.acquire(session); + + byte[] r = null; + if (message instanceof ByteMessage) { + r = ((ByteMessage) message).getBytes(); + } else { + throw new Exception("unknown message type : " + message.getClass().getName()); + } + + if ("OUTBOUND".equals(context.getBoundUsage())) { + throw new Exception("'OUTBOUND" + (context.isSync() ? "" : ", ASYN") + "' adapter cannot process request : " + CommonLib.hexDump(r, true, context)); + } + + final byte[] request = r; + @SuppressWarnings("unchecked") + final FutureTask futureTask = new FutureTask(new Callable() { + ExecutionContext executionContext = ExecutionContext.getInstance(); + + public byte[] call() throws Exception { + try { + if (Thread.currentThread().getName().startsWith("pool-")) { + Thread.currentThread().setName(context.getAdapterName() + "-Worker-" + Thread.currentThread().getName()); + } + executionContext.set("session", session); + return processRequest(session, request); + } finally { + executionContext.remove("session"); + } + } + }); + + try { + futureTask.run(); + } catch(Exception e) { + throw new RuntimeException("error when process request", e); + } + + if (context.isPermanent() && (!session.isConnected() || session.isClosing())) { + throw new IOException("session is not connected (" + session + ")"); + } + + /** + * if SYNC -> send result to sender + */ + if (context.isSync()) { + try { + byte[] response = (byte[]) futureTask.get(context.getTimeout(), TimeUnit.SECONDS); + + if (response == null) { + throw new EAIException("cannot send NULL response message (framework returned) - check if target adapter is ASYNC"); + } else if (response.length == 0) { + throw new EAIException("cannot send ZERO-size response message (framework returned) - check if target adapter is ASYNC"); + } else { + try { + internalSendMessage(session, new ByteMessage(response)); + } catch(Exception e) { + throw new EAIException("(SYNC) cannot send response message", e); + } + } + } catch (ExecutionException e) { + Throwable cause = e.getCause(); + if (cause instanceof Exception) + throw (Exception) cause; + else + throw new Exception(cause.getMessage()); + } catch (InterruptedException e) { + throw new TimeoutException("(future) cannot recv message. timeout=" + context.getTimeout()); + } catch(TimeoutException e) { + throw new TimeoutException("(future) cannot send message. timeout=" + context.getTimeout()); + } + } + } finally { + try { + releaseSession(session); + } catch(Exception e) { + logger.warn("releaseSession error", e); + } + } + + break; + } + } + + protected byte[] processRequest(IoSession session, byte[] request) throws Exception { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | (before) process request : " + CommonLib.hexDump(request, true, context)); + } + + try { + Properties prop = new Properties(); + byte[] response = null; + + //for GW + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(context.getAdapterGroupName()); + +// if (context.getBoundUsage().equals(context.IOBOUND_SOCKET)) { + if (StringUtils.isNotBlank(adptGrpVO.getSameSessionYn()) && "1".equals(adptGrpVO.getSameSessionYn()) + && context.getBoundUsage().equals(context.IOBOUND_SOCKET)) { + String sessionId = String.valueOf(session.hashCode()); + prop.setProperty("SESSION_ID", sessionId); + GWSessionManager.getInstance().sessionIn(sessionId, session); + } + + if (context.getRequestProcessor() != null) { + response = context.getRequestProcessor().handle(request); + } else if (!"".equals(context.getScript().trim())) { + String filename = context.getScript(); + if (filename.endsWith(".groovy")) { + Groovy groovy = new Groovy(filename, + context.getAdapterGroupName() + "." + context.getAdapterName()); + response = groovy.run(request); + } else { + response = FileUtil.readFile(filename); + } + } else if (Env.isEcho() || context.getDescription().startsWith("ECHO")) { + response = request; + } else if (!Env.isStandalone()) { + + String encode = null; + try { + RequestDispatcher dispatcher = RequestDispatcher + .getRequestDispatcher(context.getAdapterGroupName()); + Object responseObject = dispatcher.handle(context.getAdapterName(), request, prop); + if (responseObject == null) { + response = null; + } else if (responseObject instanceof byte[]) { + response = (byte[]) responseObject; + } else if (responseObject instanceof String) { + // TODO : 정상작동여부를 확인해야 함. + encode = prop.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN, "euc-kr"); + response = ((String) responseObject).getBytes(encode); + } else { + throw new Exception("RECEAIAHA001"); + } + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | (after) process request : " + + CommonLib.hexDump(response, true, context)); + } + + return response; + } catch (Throwable t) { + logger.error(t); + byte[] errorResponse = ("[RECEAIONA001] " + context.getAdapterName() + + " | cannot process request - " + t.getMessage()).getBytes(encode); + internalSendMessage(session, new ByteMessage(errorResponse)); + throw t; + } + } else { + throw new Exception("no rule to handle request"); + } + + return response; + } catch (Throwable t) { + logger.error(context.getAdapterName() + " | cannot process request " + CommonLib.hexDump(request, true, context), t); + adapter.addRecentError(context.getAdapterName() + " | cannot process request " + CommonLib.hexDump(request, true, context), t); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA010"); + + HandlerState handlerState = (HandlerState) session.getAttribute(HANDLER_STATE_KEY); + if (handlerState != null && handlerState.responseFuture != null) { + handlerState.responseFuture.set(t); + } + throw new EAIException(t); + } + } + + protected void internalSendMessage(IoSession session, Object message) throws Exception { + if(!session.isConnected()) { + throw new EAIException("cannot send message - session is not connected (" + session + ")"); + } + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | " + getHexDump(message)); + adapter.addRecentSend(session, getHexDump(message)); + } + + WriteFuture future = session.write(message); + if (adapter instanceof TcpAdapterClient || adapter instanceof TcpAdapterServer) { + future.join(context.getTimeout() * 1000L); + } + + incMessageSend(); + } + + public Object sendMessage(IoSession reservedSession, Object message) throws EAIException { + return sendMessage(reservedSession, message, context.getTimeout()); + } + public Object sendMessage(IoSession reservedSession, Object message, int responseTimeout) throws EAIException { + switch(adapter.getState()) { + case STARTING: + case STARTED: + break; + default: + adapter.addRecentError(context.getAdapterName() + " | cannot send message. adapter state is " + adapter.getState().name()); + throw new EAIException(context.getAdapterName() + " | cannot send message. adapter state is " + adapter.getState().name()); + } + + IoSession session = null; + + try { + if (reservedSession == null) { + session = acquireSession(); + } else { + session = reservedSession; + } + + HandlerState handlerState = (HandlerState) session.getAttribute(HANDLER_STATE_KEY); + handlerState.responseFuture = new SimpleFuture(); + if (context.isSync()) { + handlerState.state = State.STATE_MESSAGE_WAIT_RESPONSE; + } + + internalSendMessage(session, message); + + if(!session.isConnected() && (context.isServer() || context.isPermanent())) { + String logMessage = context.getDescription() + "(" + context.getAdapterName() + ") | (server||permanent) SEND 후, 세션 연결 끊김 (" + session + ")"; + logger.error(logMessage); + throw new EAIException(logMessage); + } + + if (context.isSync()) { + try { + session.setAttribute("responseTimeout",responseTimeout); + session.setIdleTime(IdleStatus.BOTH_IDLE, responseTimeout); + + Object result = handlerState.responseFuture.join(responseTimeout * 1000L); + session.removeAttribute("responseTimeout"); + + if (result instanceof TimeoutException) { + throw new EAITimeoutException("timeout(" + responseTimeout + "), cannot receive result message"); + } else if (result instanceof Throwable) { + throw new EAIException("send/recv(SYNC) faild - " + ((Exception) result).getMessage(), (Throwable) result); + } else { + ByteMessage m = (ByteMessage) result; + if (m.size() >= 7 && new String(m.getBytes(0,7)).startsWith("[RECEAI")) + throw new EAIException(m.getString()); + return m.getBytes(); + } + } finally { + handlerState.state = State.STATE_MESSAGE_WAIT_REQUEST; + } + } else { + return null; + } + } catch(EAITimeoutException e) { + sessionPool.remove(session); + if(session != null) session.close(); + String errorMessage = context.getAdapterName() + " | send(/recv) EAITimeoutException - " + e.getMessage(); + adapter.addRecentError(errorMessage, e); + throw new EAITimeoutException(errorMessage, e); + } catch(EAIException e) { + sessionPool.remove(session); + if(session != null) session.close(); + String errorMessage = context.getAdapterName() + " | send(/recv) EAIException - " + e.getMessage(); + adapter.addRecentError(errorMessage, e); + throw new EAIException(errorMessage, e); + } catch(TimeoutException e) { + sessionPool.remove(session); + if(session != null) session.close(); + String errorMessage = context.getAdapterName() + " | send(/recv) TimeoutException - " + e.getMessage(); + adapter.addRecentError(errorMessage, e); + throw new EAITimeoutException(errorMessage, e); + } catch(Throwable e) { + sessionPool.remove(session); + if(session != null) session.close(); + String errorMessage = context.getAdapterName() + " | send(/recv) Throwable - " + e.getMessage(); + adapter.addRecentError(errorMessage, e); + throw new EAIException(errorMessage, e); + } finally { + if (reservedSession == null) { + releaseSession(session); + } + } + } + + + public IoSession acquireSession() throws EAIException { + IoSession session = null; + + if (context.isClient() && !context.isPermanent()) { + session = adapter.connectOne(); + + if (session == null) { + String errorMsg = context.getAdapterName() + + " | cannot connect -> " + context.getHostName() + "/" + context.getPortNumber(); + logger.error(errorMsg); + adapter.addRecentError(errorMsg); + if (TimeUtil.isSMSRunningTime(context.getSmsRunningTime())) + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA014"); + throw new EAIConnectException(errorMsg); + } + + SimpleFuture handshakeFuture = (SimpleFuture) session.getAttribute(HANDSHAKE_FUTURE); + if (handshakeFuture != null) { + try { + Object result = handshakeFuture.join(context.getTimeout() * 1000L); + if (result instanceof Exception) { + throw new EAIConnectException(context.getAdapterName() + " | cannot connect error", (Exception) result); + } + } catch(EAITimeoutException e) { + throw new EAIConnectException(context.getAdapterName() + " | handshake faild due to timeout", e); + } + } + } else { + /** + * client && pool size = 0 일 경우, 10ms만 기다린다. + */ + long timeout = context.getTimeout() * 1000L; + if (adapter.getState()==ISocketAdapter.State.STARTED && sessionPool.size()<1) { + timeout = 10L; + } + + session = sessionPool.acquire(timeout); + + if (session == null) { + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA015"); + throw new EAINoAvailableConnectionException("cannot get session(=connection) from SessionPool[size=" + sessionPool.size() + ", remaining=" + sessionPool.remaining() + "]"); + } + } + + return session; + } + + public void releaseSession(IoSession session) { + if (session == null) { + return; + } + + if (context.isClient() && !context.isPermanent()) { + sessionPool.remove(session); + session.close(); + } else { + if (session.isClosing()) { + sessionPool.remove(session); + } else { + sessionPool.release(session); + } + } + } + + public Object sendBatch(Object message) throws Exception { + return null; + /* + if (context.getSocketListener() != null) { + return ((SocketListener) context.getSocketListener()).messageReceived(request); + } + */ + } + + public long getMessageSend() { + return messageSend; + } + + public long getMessageRecv() { + return messageRecv; + } + + public synchronized void incMessageSend() { + messageSend++; + } + + public synchronized void incMessageRecv() { + messageRecv++; + } + + public void clearStats() { + messageSend = 0; + messageRecv = 0; + } + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + + protected String getHexDump(Object message) { + if (message == null) { + return ""; + } else if (message instanceof byte[]) { + message = new ByteMessage((byte[]) message); + return ((ByteMessage) message).hexDump(); + } else if (message instanceof String) { + message = new ByteMessage((String) message); + return ((ByteMessage) message).hexDump(); + } else { + return message.toString(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/SessionPool.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/SessionPool.java new file mode 100644 index 0000000..fb07d8b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/SessionPool.java @@ -0,0 +1,250 @@ +package com.eactive.eai.adapter.socket2.protocol; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoSession; + +import java.net.InetSocketAddress; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + + +public class SessionPool { + private Logger logger = SocketLoggerManager.getInstance().getLogger(); + + private ISocketAdapter adapter; + private SocketAdapterContext context; + private List pool; + private List checkedOut; + + public SessionPool(ISocketAdapter adapter, SocketAdapterContext context) { + this.adapter = adapter; + this.context = context; + this.pool = new CopyOnWriteArrayList<>(); + this.checkedOut = new CopyOnWriteArrayList<>(); + } + + public synchronized IoSession acquire(IoSession session) { + if (pool.remove(session)) { + if (!checkedOut.contains(session)) { + checkedOut.add(session); + } + return session; + } + + return null; + } + + public synchronized IoSession acquire() { + return acquire(context.getTimeout() * 1000L, true); + } + + public synchronized IoSession acquireYoungest() { + return acquire(context.getTimeout() * 1000L, false); + } + + public synchronized IoSession acquire(long timeout) { + return acquire(timeout, true); + } + + private synchronized IoSession acquire(long timeout, boolean pickOld) { + long startTime = System.currentTimeMillis(); + IoSession session; + + while ((session = internalAcquire(timeout, pickOld)) == null) { + try { + /** + * timeout의 1/10 만큼만 기다린다. + */ + wait(timeout/10L); + } catch (InterruptedException e) { + break; + } + + if ((System.currentTimeMillis() - startTime) >= timeout) { + // Timeout has expired + break; + } + } + + + if (session != null) { + checkedOut.add(session); + } + + return session; + } + + private IoSession internalAcquire(long timeout, boolean pickOld) { + IoSession session = null; + + if (!pool.isEmpty()) { + // pick the first Connection in the vector to get round-robin usage + if (pickOld) { + session = pool.remove(0); + } else { + session = pool.remove(pool.size()-1); + } + + try { + // ## + if (session == null || !session.isConnected()) { + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | remove bad connection from IoSessionPool."); + } + + // Try again recursively + session = acquire(timeout, pickOld); + } + } catch (Exception e) { + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | remove bad connection from IoSessionPool."); + } + + // Try again recursively + session = acquire(timeout, pickOld); + } + } + + return session; + } + + public synchronized void release(IoSession session) { + if ((session != null) && session.isConnected()) { + if (pool.contains(session)) { + //throw new RuntimeException(context.getAdapterName() + " | cannot put session into session pool. session already exists in pool (" + session + ")"); + return; + } + pool.add(session); + checkedOut.remove(session); + notifyAll(); + } + } + + public void remove(IoSession session) { + pool.remove(session); + checkedOut.remove(session); + } + public void remove(int localPort, int remotePort){ + for (Iterator iii = pool.iterator() ; iii.hasNext(); ) { + IoSession session = iii.next(); + + if(session == null) return; + + InetSocketAddress local =(InetSocketAddress)session.getLocalAddress(); + InetSocketAddress remote =(InetSocketAddress)session.getRemoteAddress(); + + if (remote != null && local.getPort() == localPort && remote.getPort() == remotePort ){ + pool.remove(session); + try{ + session.close(); + }catch(Exception e){ + logger.error(e); + } + break; + } + } + + } + public void sessionValidate(){ + for (Iterator iii = pool.iterator() ; iii.hasNext(); ) { + IoSession session = iii.next(); + if (session!=null && !session.isConnected()){ + pool.remove(session); + try{ + session.close(); + }catch(Exception e){ + logger.error(e); + } + } + } + + } + + public synchronized int size() { + return checkedOut.size() + pool.size(); + } + + public int peekSize() { + return checkedOut.size() + pool.size(); + } + + public int checkedOut() { + return checkedOut.size(); + } + + public int remaining() { + return pool.size(); + } + + public Iterator iterator() { + return pool.iterator(); + } + + public Iterator checkedOutIterator() { + return checkedOut.iterator(); + } + + public void shutdown() { + int count = 0; + while (size() > 0 && count++ < 10) { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | session pool shutdown - try count : " + count); + } + + for(IoSession session : checkedOut) { + try { + if (session != null) { + if (session.isConnected() && !session.isClosing()) { + session.close().join(); + } + checkedOut.remove(session); + } + } catch(Exception e) { + checkedOut.remove(session); + logger.error(context.getAdapterName() + " | " + e.getMessage(), e); + adapter.addRecentError(context.getAdapterName() + " | " + ExceptionStackTrace.dump(e)); + } + } + + IoSession session = null; + while (pool.size() > 0) { + try { + session = acquire(1000L, true); + if (session != null) { + if (session.isConnected() && !session.isClosing()) { + session.close().join(); + } + pool.remove(session); + } + } catch(Exception e) { + pool.remove(session); + logger.error(context.getAdapterName() + " | " + e.getMessage(), e); + adapter.addRecentError(context.getAdapterName() + " | " + ExceptionStackTrace.dump(e)); + } + } + + try { + Thread.sleep(100L); + } catch(Exception e) { + logger.error(context.getAdapterName() + " | session pool sleep error.", e); + } + } + + if (count >= 100) { + logger.error(context.getAdapterName() + " | session pool shutdown failed - garbage connection left"); + adapter.addRecentError(context.getAdapterName() + " | session pool shutdown failed - garbage connection left"); + } + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[SessionPool of " + context.getAdapterName()); + sb.append(" | pool:" + pool.size()); + sb.append(" | checkedout:" + checkedOut.size() + "]"); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/SocketAdapter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/SocketAdapter.java new file mode 100644 index 0000000..91543cc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/SocketAdapter.java @@ -0,0 +1,250 @@ +package com.eactive.eai.adapter.socket2.protocol; + +import java.util.Date; +import java.util.Hashtable; +import java.util.Map; + +import org.apache.mina.common.IoSession; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.EAIConnectException; +import com.eactive.eai.adapter.socket2.common.CircularQueue; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.common.util.Logger; + +import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService; +import edu.emory.mathcs.backport.java.util.concurrent.Executors; +import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor; +import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit; + +public abstract class SocketAdapter implements ISocketAdapter { + static final int MAX_LOG_MESSAGE_SIZE = 100000; + + protected final Logger logger; + protected final Logger errLogger; + + protected State state = State.STOPPED; + + protected SocketAdapterContext context; + protected ProtocolHandler handler; + protected ExecutorService executor; + protected Hashtable threadMap = new Hashtable<>(); + + protected static CircularQueue globalErrorQueue = new CircularQueue(10); + protected CircularQueue recentErrorQueue = new CircularQueue(10); + protected CircularQueue recentSendRecvQueue = new CircularQueue(10); + + protected Date uptime; + + protected void startExecutor() { + this.executor = Executors.newCachedThreadPool(); + ((ThreadPoolExecutor) this.executor).setKeepAliveTime(1L, TimeUnit.SECONDS); + } + + protected SocketAdapter(SocketAdapterContext context) { + this.context = context; + startExecutor(); + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + + this.uptime = new Date(); + } + + public SocketAdapterContext getContext() { + return context; + } + + public void setTraceLevel(int traceLevel) { + context.setTraceLevel(traceLevel); + } + + public boolean connect() throws Exception { + throw new UnsupportedOperationException(); + } + + public IoSession connectOne() throws EAIConnectException { + throw new UnsupportedOperationException(); + } + + public SessionPool getSessionPool() { + return handler.getSessionPool(); + } + + public Map getThreadMap() { + return threadMap; + } + + public long getMessageSend() { + return handler.getMessageSend(); + } + + public long getMessageRecv() { + return handler.getMessageRecv(); + } + + public void incMessageSend() { + handler.incMessageSend(); + } + + public void incMessageRecv() { + handler.incMessageRecv(); + } + + public State getState() { + return this.state; + } + + public void setState(State state) { + this.state = state; + } + + public int getRecentErrorCount() { + return recentErrorQueue.getRecordCount(); + } + + public String[] getRecentErrors() { + return recentErrorQueue.getRecords(); + } + + public static String[] getGlobalErrors() { + return globalErrorQueue.getRecords(); + } + + public void addRecentError(String message) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE/10) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE/10); + recentErrorQueue.addRecord(message); + globalErrorQueue.addRecord(message); + } + + public void addRecentError(String message, Throwable t) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE/10) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE/10); + recentErrorQueue.addRecord(message + "\n" + ExceptionStackTrace.dump(t)); + globalErrorQueue.addRecord(message + "\n" + ExceptionStackTrace.dump(t)); + } + + public void addRecentErrorOnly(String message) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE/10) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE/10); + recentErrorQueue.addRecord(message); + //globalErrorQueue.addRecord(message); + } + + public void addRecentErrorOnly(String message, Throwable t) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE/10) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE/10); + recentErrorQueue.addRecord(message + "\n" + ExceptionStackTrace.dump(t)); + //globalErrorQueue.addRecord(message + "\n" + ExceptionStackTrace.dump(t)); + } + + public void addRecentLog(String message) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE); + recentSendRecvQueue.addRecord(message); + } + + public void addRecentSend(IoSession session, String message) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE); + recentSendRecvQueue.addRecord(" " + (session==null ? "" : "(" + session + ") - ") + message); + } + + public void addRecentRecv(IoSession session, String message) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE); + recentSendRecvQueue.addRecord(" " + (session==null ? "" : "(" + session + ") - ") + message); + } + + public void addRecentSendTrace(IoSession session, String message) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE); + recentSendRecvQueue.addRecord(" " + (session==null ? "" : "(" + session + ") - ") + message + ""); + } + + public void addRecentRecvTrace(IoSession session, String message) { + if (message == null) + return; + if (message.length() > MAX_LOG_MESSAGE_SIZE) + message = message.substring(0, MAX_LOG_MESSAGE_SIZE); + recentSendRecvQueue.addRecord(" " + (session==null ? "" : "(" + session + ") - ") + message + ""); + } + + public String[] getRecentSendRecv() { + return recentSendRecvQueue.getRecords(); + } + + public void clearStat() { + recentErrorQueue.clear(); + recentSendRecvQueue.clear(); + handler.clearStats(); + } + + public void resumeRead() { + } + + public void resumeWrite() { + } + + public void suspendRead() { + } + + public void suspendWrite() { + } + + public Object sendMessage(Object message) throws EAIException { + return handler.sendMessage(null, message); + } + + public Object sendMessage(Object message, int responseTimeout) throws EAIException { + return handler.sendMessage(null, message, responseTimeout); + } + + public Object sendMessage(IoSession reservedSession, Object message) throws EAIException { + return handler.sendMessage(reservedSession, message); + } + + public IoSession acquireSession() throws Exception { + return handler.acquireSession(); + } + + public void releaseSession(IoSession session) { + handler.releaseSession(session); + } + + public void setAdapterStatus(boolean status) { + AdapterVO vo = getContext().getAdapterVO(); + if (vo != null) { + vo.setStatus(status); + } + } + + public Date getUptime() { + return uptime; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | sessionPool size : " + handler.getSessionPool().size()); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/SocketAdapterClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/SocketAdapterClient.java new file mode 100644 index 0000000..2bb4eb9 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/SocketAdapterClient.java @@ -0,0 +1,413 @@ +package com.eactive.eai.adapter.socket2.protocol; + +import java.net.InetSocketAddress; +import java.util.concurrent.TimeoutException; + +import javax.net.ssl.SSLContext; + +import org.apache.mina.common.ConnectFuture; +import org.apache.mina.common.IoSession; +import org.apache.mina.common.ThreadModel; +import org.apache.mina.common.support.BaseIoConnector; +import org.apache.mina.common.support.BaseIoConnectorConfig; +import org.apache.mina.filter.SSLFilter; +import org.apache.mina.util.NewThreadExecutor; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.EAIConnectException; +import com.eactive.eai.adapter.socket2.common.ExecutionContext; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.filter.datacontrol.DataControlFilter; +import com.eactive.eai.adapter.socket2.filter.executor.BoundedExecutorFilter; +import com.eactive.eai.adapter.socket2.filter.initmsgshake.InitMsgFilter; +import com.eactive.eai.adapter.socket2.filter.polling.PollingFilter; +import com.eactive.eai.adapter.socket2.filter.ssl.SSLContextFactory; +import com.eactive.eai.adapter.socket2.filter.validation.ValidationFilter; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.session.SessionManager; +import com.eactive.eai.common.session.SessionVO; +import com.eactive.eai.util.HealthCheckManager; + +import edu.emory.mathcs.backport.java.util.concurrent.Executor; +import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor; + + +public abstract class SocketAdapterClient extends SocketAdapter { + protected Executor ioProcessExecutor; + protected BaseIoConnector connector; + protected BaseIoConnectorConfig config; + private Thread launcher = null; + + protected SocketAdapterClient(SocketAdapterContext context) throws Exception { + super(context); + + if (context.getMaxConnection() == 0) { + context.setMaxConnection(1); + } + + /** + * Configure the service. + */ + config = createConnectorConfig(); + + config.setConnectTimeout(context.getTimeout()); + config.setThreadModel(ThreadModel.MANUAL); + + /** + * filters + */ + config.getFilterChain().addFirst("threadPool", new BoundedExecutorFilter(this, executor)); + //config.getFilterChain().addLast("logger", new LoggingFilter()); + + if ("Y".equals(context.getSslUse())) { + SSLContext sslContext = SSLContextFactory.createSSLContext(context); + SSLFilter sslFilter = new SSLFilter(sslContext); + sslFilter.setUseClientMode(true); + config.getFilterChain().addLast("ssl", sslFilter); + } + + //KSH + if (context.isInitMsgUse()) { + config.getFilterChain().addLast("initMsg", new InitMsgFilter(this)); + } + + if (context.isPollingUse()) { + config.getFilterChain().addLast("polling", new PollingFilter(this)); + } + + + if (!"".equals(context.getValidationRule().trim())) { + config.getFilterChain().addLast("validation", new ValidationFilter(this)); + } + if (!"".equals(context.getDataControlRule().trim())) { + config.getFilterChain().addLast("datacontrol", new DataControlFilter(this)); + } + } + + public SimpleFuture start() throws Exception { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | start client socket adapter."); + } + + switch(getState()) { + case STARTED: + throw new Exception(context.getAdapterName() + " | socket adapter already started. - " + getState().name()); + case STARTING: + throw new Exception(context.getAdapterName() + " | socket adapter already starting... - " + getState().name()); + case STOPPING: + throw new Exception(context.getAdapterName() + " | socket adapter shutdown progressing. - " + getState().name()); + default: + break; + } + + /** + * start protocol handler + */ + handler.start(); + + /** + * io process executor + */ + ioProcessExecutor = new NewThreadExecutor(); + + /** + * determine ioProcessor count + */ + int ioProcessorCount1 = 1 + Runtime.getRuntime().availableProcessors(); + int ioProcessorCount2 = 1 + (context.getMaxThread() / 10); + int ioProcessorCount = ioProcessorCount1 < ioProcessorCount2 ? ioProcessorCount1 : ioProcessorCount2; + + /** + * create connector + */ + connector = createConnector(ioProcessorCount, ioProcessExecutor); + + setState(State.STARTING); + + final SimpleFuture future = new SimpleFuture(); +// final ISocketAdapter adapter = this; + + if (!context.isPermanent()) { + setAdapterStatus(true); + setState(State.STARTED); + future.set(Boolean.TRUE); + return future; + } + + Runnable runnable = new Runnable() { + public void run() { + boolean retry = true; + while(true) { + try { + if(getState() == State.STARTED + || getState() == State.STOPPING + || getState() == State.STOPPED) { + logger.warn("Exit Launcher - " + context.getAdapterName() + "-Terminator"); + return; + } + + retry = true; + if(context.getSingleSession().equals("Y")) { + String adapterGroupoName = context.getAdapterGroupName(); + SessionVO sessionVo = SessionManager.getInstance().getConnectionStatus(adapterGroupoName); + + // 싱글어댑터 - Start --------------------------------------------------------------------------------------------------------------------- + String primaryInst = context.getPrimaryInstId(); + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String localServerName = eaiServerManager.getLocalServerName(); + + if ( localServerName.equals(primaryInst)) { // CASE : Primary 서버 + SessionVO sessionVO = SessionManager.getInstance().getConnectionStatus(adapterGroupoName); + + if (sessionVO != null) { + if(localServerName.equals(sessionVO.getLoginInstId())) { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + "| SingleSession Validation, local server exist [" +sessionVO.getLoginInstId()+"], remove cache -> retry to connect after 10 secs"); + } + SessionManager.getInstance().removeConnectionInfo(adapterGroupoName); + } + else {// Secondary 서버가 연결하고 있음 + retry = false; + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + "| SingleSession Validation, Secondary server exist [" +sessionVO.getLoginInstId()+"]"); + } + } + } else { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + "| SingleSession Validation, Connection empty -> retry to connect after 10 secs"); + } + + } + } else { // CASE : Secondary 서버 + boolean isAlive = HealthCheckManager.getInstance().getServerStatus(primaryInst); + + if (isAlive) { // Primary 서버 살아있으면 재연결 시도 안함 + retry = false; + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) + logger.debug(context.getAdapterName() + "| SingleSession Validation, Primary server exist [" +primaryInst+"]"); + } else { + SessionManager.getInstance().removeConnectionInfo(adapterGroupoName); + } + + SessionVO svo = SessionManager.getInstance().getConnectionInfo(adapterGroupoName); + + if (svo != null) { + String connectedInst = svo.getLoginInstId(); + if(connectedInst.equals(localServerName)) + SessionManager.getInstance().removeConnectionInfo(adapterGroupoName); + } + } + // 싱글어댑터 - End --------------------------------------------------------------------------------------------------------------------- + + + if(sessionVo != null) { + retry = false; + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | SingleSession Validation Exist ["+sessionVo.getLoginInstId() +"] -> retry to connect after 10 seconds..."); + } + } + else { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | SingleSession Validation Connection Empty -> retry to connect after 10 seconds..."); + } + } + } + + if(retry) { + boolean result = connect(); + + if (result && getSessionPool().size() > 0) { + setAdapterStatus(true); + context.setStarted(true); + setState(State.STARTED); + future.set(Boolean.TRUE); + break; + } else { + setAdapterStatus(false); + context.setStarted(false); + future.set(Boolean.FALSE); + getSessionPool().shutdown(); + } + } + } catch(Throwable t) { + setAdapterStatus(false); + context.setStarted(false); + future.set(t); + getSessionPool().shutdown(); + } + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG + && retry && logger.isDebug()) { + logger.debug(context.getAdapterName() + " | failed to connect -> retry to connect after 10 seconds..."); + } + + try { + Thread.sleep(10000L); + } catch(InterruptedException e) { + if(logger.isDebug()) { + logger.debug(context.getAdapterName() + " sleep error - " + e.getMessage()); + } + } + } + } + }; + //executor.execute(runnable); + launcher = new Thread(runnable); + launcher.setName(context.getAdapterName() + "-Launcher"); + launcher.start(); + + return future; + } + + public SimpleFuture stop() throws Exception { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | stop client socket adapter."); + } + + switch(getState()) { + case STOPPING: + case STOPPED: + logger.warn(context.getAdapterName() + " | socket adapter already " + getState().name()); + final SimpleFuture future = new SimpleFuture(); + future.set(Boolean.TRUE); + return future; + default: + break; + } + + return doStop(); + } + + public SimpleFuture stopForcely() throws Exception { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | stop client socket adapter forcely."); + } + return doStop(); + } + + private SimpleFuture doStop() throws Exception { + setState(State.STOPPING); + context.setStarted(false); + + final SimpleFuture future = new SimpleFuture(); + + Runnable runnable = new Runnable() { + public void run() { + try { + handler.stop(); + getSessionPool().shutdown(); + setAdapterStatus(false); + setState(State.STOPPED); +// List list = ioProcessExecutor.shutdownNow(); +// for (Iterator iter = list.iterator(); iter.hasNext(); ) { +// ((Thread) iter.next()).interrupt(); +// } + future.set(Boolean.TRUE); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | socket adapter stopped."); + } + } catch(Exception e) { + logger.error(context.getAdapterName() + " | socket adapter stop process failed.", e); + addRecentError(context.getAdapterName() + " | socket adapter stop process failed.", e); + future.set(e); + } + } + }; + //executor.execute(runnable); + Thread t = new Thread(runnable); + t.setName(context.getAdapterName() + "-Terminator"); + t.start(); + + return future; + } + + @Override + public boolean connect() throws Exception { + for (int i = 0; i < context.getMaxConnection(); i++) { + IoSession session = connectOne(); + if (session == null) { + setState(State.STOPPED); + context.setStarted(false); + throw new Exception(context.getAdapterName() + " | failed to establish connection ... "); + } + } + return true; + } + + @Override + public IoSession connectOne() throws EAIConnectException { + InetSocketAddress remoteAddress = new InetSocketAddress(context.getHostName(), context.getPortNumber()); + InetSocketAddress localAddress = null; + + if (context.getLocalPortNumber() > 0 || context.getLocalHostName().trim().length() > 0) { + localAddress = new InetSocketAddress(context.getLocalHostName(), context.getLocalPortNumber()); + } + + IoSession session = null; + + try { + ConnectFuture future = connector.connect( + remoteAddress, + localAddress, + handler, + config); + + /** + * inbound connection 이 끊어졌을 경우, + * outbound connection 시도 작업을 중단한다. + */ + ExecutionContext executionContext = ExecutionContext.getInstance(); + IoSession sess = (IoSession) executionContext.get("session"); + if (sess != null) { + sess.setAttribute("connectFuture", future); + } + + boolean success = future.join(context.getTimeout() * 1000L); + if (success) { + session = future.getSession(); + if(!session.isConnected()) { + throw new EAIException("session closed by peer (" + session + ")"); + } + return session; + } else { + throw new TimeoutException("connect timeout '" + context.getTimeout() + "' sec"); + } + } catch (Exception e) { + if (session != null && session.isConnected()) { + try { + getSessionPool().remove(session); + session.close().join(); + } catch(Exception ee) { + logger.warn(context.getAdapterName() +" session close error"); + } + } + String errorMessage = context.getAdapterName() + + " | cannot connect - " + context.getHostName() + "/" + context.getPortNumber(); + logger.error(errorMessage, e); + + if (getState() != State.STARTING) { + addRecentError(errorMessage, e); + } else { + addRecentErrorOnly(errorMessage, e); + } + + try { + if (TimeUtil.isSMSRunningTime(context.getSmsRunningTime())) + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA014"); + } catch(Throwable t) { + logger.debug("[EAIDEBUG] SMS logging Error occured. but ignore this. - " + t.toString()); + } + + context.setStarted(false); + + throw new EAIConnectException("cannot connect - " + context.getHostName() + "/" + context.getPortNumber(), e); + } + } + + abstract protected BaseIoConnectorConfig createConnectorConfig(); + abstract protected BaseIoConnector createConnector(int ioProcessorCount, Executor ioProcessExecutor); +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/SocketAdapterServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/SocketAdapterServer.java new file mode 100644 index 0000000..33054fc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/SocketAdapterServer.java @@ -0,0 +1,224 @@ +package com.eactive.eai.adapter.socket2.protocol; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.filter.acl.AclFilter; +import com.eactive.eai.adapter.socket2.filter.acl.BlockIpFilter; +import com.eactive.eai.adapter.socket2.filter.acl.L4SkipIpFilter; +import com.eactive.eai.adapter.socket2.filter.datacontrol.DataControlFilter; +import com.eactive.eai.adapter.socket2.filter.executor.BoundedExecutorFilter; +import com.eactive.eai.adapter.socket2.filter.initmsgshake.InitMsgFilter; +import com.eactive.eai.adapter.socket2.filter.limit.ConnectionLimitFilter; +import com.eactive.eai.adapter.socket2.filter.polling.PollingFilter; +import com.eactive.eai.adapter.socket2.filter.ssl.SSLContextFactory; +import com.eactive.eai.adapter.socket2.filter.validation.ValidationFilter; +import edu.emory.mathcs.backport.java.util.concurrent.Executor; +import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService; +import edu.emory.mathcs.backport.java.util.concurrent.Executors; +import edu.emory.mathcs.backport.java.util.concurrent.ThreadPoolExecutor; + +import org.apache.mina.common.ThreadModel; +import org.apache.mina.common.support.BaseIoAcceptor; +import org.apache.mina.common.support.BaseIoAcceptorConfig; +import org.apache.mina.filter.SSLFilter; + +import javax.net.ssl.SSLContext; +import java.net.InetSocketAddress; +import java.util.Iterator; +import java.util.List; + + +public abstract class SocketAdapterServer extends SocketAdapter { + protected ExecutorService ioProcessExecutor; + protected BaseIoAcceptor acceptor; + protected BaseIoAcceptorConfig config; + + protected SocketAdapterServer(SocketAdapterContext context) throws Exception { + super(context); + + config = createAcceptorConfig(); + + config.setThreadModel(ThreadModel.MANUAL); + + /** + * filters + */ + config.getFilterChain().addFirst("threadPool", new BoundedExecutorFilter(this, executor)); + //config.getFilterChain().addLast("logger", new LoggingFilter()); + + if (!"".equals(context.getL4SkipIpList().trim())) { + config.getFilterChain().addLast("l4SkipIp", new L4SkipIpFilter(this)); + } + if (!"".equals(context.getBlockIpList().trim())) { + config.getFilterChain().addLast("blockIp", new BlockIpFilter(this)); + } + // polling response 후 LIMIT Filter에 걸리는 경우가 있어 ACL, LIMIT Filter를 앞에 둠 + if (!"".equals(context.getAclList().trim())) { + config.getFilterChain().addLast("acl", new AclFilter(this)); + } + + if (context.getMaxConnection() > 0 || context.getConnLimitPerIp() > 0) { + config.getFilterChain().addLast("limit", new ConnectionLimitFilter(this)); + } + + if ("Y".equals(context.getSslUse())) { + SSLContext sslContext = SSLContextFactory.createSSLContext(context); + SSLFilter sslFilter = new SSLFilter(sslContext); + config.getFilterChain().addLast("ssl", sslFilter); + } + + if (context.isInitMsgUse()) { + config.getFilterChain().addLast("initMsg", new InitMsgFilter(this)); + } + + if (context.isPollingUse()) { + config.getFilterChain().addLast("polling", new PollingFilter(this)); + } + + if (!"".equals(context.getValidationRule().trim())) { + config.getFilterChain().addLast("validation", new ValidationFilter(this)); + } + if (!"".equals(context.getDataControlRule().trim())) { + config.getFilterChain().addLast("datacontrol", new DataControlFilter(this)); + } + } + + public SimpleFuture start() throws Exception { + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | start server socket adapter."); + } + + switch(getState()) { + case STARTED: + throw new Exception(context.getAdapterName() + " | socket adapter already started - " + getState().name()); + case STARTING: + throw new Exception(context.getAdapterName() + " | socket adapter booting process already started - " + getState().name()); + case STOPPING: + throw new Exception(context.getAdapterName() + " | socket adapter shutdown progressing - " + getState().name()); + default: + break; + } + + /** + * start protocol handler + */ + handler.start(); + + /** + * ioProcessorExecutor + */ + ioProcessExecutor = Executors.newCachedThreadPool(); + + /** + * determine ioProcessor count + */ + int ioProcessorCount1 = 1 + Runtime.getRuntime().availableProcessors(); + int ioProcessorCount2 = 1 + (context.getMaxThread() / 10); + int ioProcessorCount = ioProcessorCount1 < ioProcessorCount2 ? ioProcessorCount1 : ioProcessorCount2; + + /** + * create acceptor + */ + acceptor = createAcceptor(ioProcessorCount, ioProcessExecutor); + + setState(State.STARTING); + SimpleFuture future = new SimpleFuture(); + + /** + * bind + */ + try { + acceptor.bind(new InetSocketAddress(context.getPortNumber()), handler, config); + if (!context.isPermanent()) { + setAdapterStatus(true); + } + setState(State.STARTED); + context.setStarted(true); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | socket adapter listening on port " + context.getPortNumber()); + } + + future.set(Boolean.TRUE); + + return future; + } catch(Exception e) { + logger.error(context.getAdapterName() + " | " + e.getMessage(), e); + addRecentError(context.getAdapterName() + " | " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA013"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA013"); + setAdapterStatus(false); + context.setStarted(false); + setState(State.STOPPED); + future.set(Boolean.FALSE); + return future; + } + } + + public SimpleFuture stop() throws Exception { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | stop server socket adapter."); + } + + switch(getState()) { + case STOPPING: + case STOPPED: + throw new Exception(context.getAdapterName() + " | socket adapter already " + getState().name()); + default: + break; + } + + return doStop(); + } + + public SimpleFuture stopForcely() throws Exception { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | stop server socket adapter forcely."); + } + + return doStop(); + } + + private SimpleFuture doStop() throws Exception { + setState(State.STOPPING); + context.setStarted(false); + + final SimpleFuture future = new SimpleFuture(); + + Runnable runnable = new Runnable() { + public void run() { + try { + acceptor.unbindAll(); + handler.stop(); + getSessionPool().shutdown(); + setAdapterStatus(false); + setState(State.STOPPED); + List list = ioProcessExecutor.shutdownNow(); + for (Iterator iter = list.iterator(); iter.hasNext(); ) { + ((Thread) iter.next()).interrupt(); + } + future.set(Boolean.TRUE); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | socket adapter stopped."); + } + } catch(Exception e) { + logger.error(context.getAdapterName() + " | socket adapter stop process failed.", e); + addRecentError(context.getAdapterName() + " | socket adapter stop process failed.", e); + future.set(e); + } + } + }; + + //executor.execute(runnable); + Thread t = new Thread(runnable); + t.setName(context.getAdapterName() + "-Terminator"); + t.start(); + + return future; + } + + protected abstract BaseIoAcceptorConfig createAcceptorConfig(); + protected abstract BaseIoAcceptor createAcceptor(int ioProcessorCount, Executor ioProcessExecutor); +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/TcpAdapterClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/TcpAdapterClient.java new file mode 100644 index 0000000..2df8cb5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/TcpAdapterClient.java @@ -0,0 +1,25 @@ +package com.eactive.eai.adapter.socket2.protocol; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import edu.emory.mathcs.backport.java.util.concurrent.Executor; +import org.apache.mina.common.support.BaseIoConnector; +import org.apache.mina.common.support.BaseIoConnectorConfig; +import org.apache.mina.transport.socket.nio.SocketConnector; +import org.apache.mina.transport.socket.nio.SocketConnectorConfig; + + +public abstract class TcpAdapterClient extends SocketAdapterClient { + protected TcpAdapterClient(SocketAdapterContext context) throws Exception { + super(context); + } + + protected BaseIoConnectorConfig createConnectorConfig() { + return new SocketConnectorConfig(); + } + + protected BaseIoConnector createConnector(int ioProcessorCount, Executor ioProcessExecutor) { + SocketConnector connector = new SocketConnector(ioProcessorCount, ioProcessExecutor, this); + connector.setWorkerTimeout(1); + return connector; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/TcpAdapterServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/TcpAdapterServer.java new file mode 100644 index 0000000..c56be74 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/TcpAdapterServer.java @@ -0,0 +1,30 @@ +package com.eactive.eai.adapter.socket2.protocol; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import edu.emory.mathcs.backport.java.util.concurrent.Executor; +import org.apache.mina.common.support.BaseIoAcceptor; +import org.apache.mina.common.support.BaseIoAcceptorConfig; +import org.apache.mina.transport.socket.nio.SocketAcceptor; +import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; + + +abstract public class TcpAdapterServer extends SocketAdapterServer { + public TcpAdapterServer(SocketAdapterContext context) throws Exception { + super(context); + } + + protected BaseIoAcceptorConfig createAcceptorConfig() { + SocketAcceptorConfig config = new SocketAcceptorConfig(); + + //config.getSessionConfig().setSoLinger(0); + + // to reuse TIME_WAIT state port + config.setReuseAddress("Y".equals(context.getSocketReuse()) ? true : false); + + return config; + } + + protected BaseIoAcceptor createAcceptor(int ioProcessorCount, Executor ioProcessExecutor) { + return new SocketAcceptor(ioProcessorCount, ioProcessExecutor, this); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/UdpAdapterClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/UdpAdapterClient.java new file mode 100644 index 0000000..6e4645f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/UdpAdapterClient.java @@ -0,0 +1,28 @@ +package com.eactive.eai.adapter.socket2.protocol; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import edu.emory.mathcs.backport.java.util.concurrent.Executor; +import org.apache.mina.common.support.BaseIoConnector; +import org.apache.mina.common.support.BaseIoConnectorConfig; +import org.apache.mina.transport.socket.nio.DatagramConnector; +import org.apache.mina.transport.socket.nio.DatagramConnectorConfig; +import org.apache.mina.transport.socket.nio.support.DatagramConnectorDelegate; + + +public abstract class UdpAdapterClient extends SocketAdapterClient { + protected UdpAdapterClient(SocketAdapterContext context) throws Exception { + super(context); + } + + protected BaseIoConnectorConfig createConnectorConfig() { + DatagramConnectorConfig config = new DatagramConnectorConfig(); + //config.setSessionRecycler(new ExpiringSessionRecycler(24 * 60 * 60)); + return config; + } + + protected BaseIoConnector createConnector(int ioProcessorCount, Executor ioProcessExecutor) { + DatagramConnector dc = new DatagramConnector(); + DatagramConnectorDelegate connector = new DatagramConnectorDelegate(dc, ioProcessExecutor, this); + return connector; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/UdpAdapterServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/UdpAdapterServer.java new file mode 100644 index 0000000..bf1932a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/UdpAdapterServer.java @@ -0,0 +1,29 @@ +package com.eactive.eai.adapter.socket2.protocol; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import edu.emory.mathcs.backport.java.util.concurrent.Executor; +import org.apache.mina.common.support.BaseIoAcceptor; +import org.apache.mina.common.support.BaseIoAcceptorConfig; +import org.apache.mina.transport.socket.nio.DatagramAcceptor; +import org.apache.mina.transport.socket.nio.DatagramAcceptorConfig; +import org.apache.mina.transport.socket.nio.support.DatagramAcceptorDelegate; + + +public abstract class UdpAdapterServer extends SocketAdapterServer { + protected UdpAdapterServer(SocketAdapterContext context) throws Exception { + super(context); + } + + protected BaseIoAcceptorConfig createAcceptorConfig() { + DatagramAcceptorConfig config = new DatagramAcceptorConfig(); + config.setDisconnectOnUnbind(true); + //config.setSessionRecycler(new ExpiringSessionRecycler(24 * 60 * 60 )); + return config; + } + + protected BaseIoAcceptor createAcceptor(int ioProcessorCount, Executor ioProcessExecutor) { + DatagramAcceptor da = new DatagramAcceptor(); + DatagramAcceptorDelegate acceptor = new DatagramAcceptorDelegate(da, ioProcessExecutor, this); + return acceptor; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/adapter_properties.txt b/src/main/java/com/eactive/eai/adapter/socket2/protocol/adapter_properties.txt new file mode 100644 index 0000000..7b26e4b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/adapter_properties.txt @@ -0,0 +1,140 @@ + basic + fixed + welcome + envelope ++--------------------------------------------------------------------------------------------------------------------------------------------+ +|protocol |HTTP |FIXED_H_L|UDP_F_H_L|FIXED_P_L|UDP_F_P_L|CISCO |XECURE |INISAFE |CERT |EGSEED |XECURE2 | +|--------------------------------------------------------------------------------------------------------------------------------------------| +|protocol |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|permanent |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|blocking | |0 |0 | | | | | | | | | +|adapter.group.name |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|adapter.name |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|bound.usage |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|host.name |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|port.number |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|(c)local.host.name |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|(c)local.port.number |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|socket.type |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|ack.support | |0 | | | | | | | | | | +|response.type |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|business.work.class.code |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|(s)connection.limit.per.ip |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|(s)acl.list |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|max.connection |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|max.thread |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|(s)socket.reuse |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|timeout |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|idle.timeout |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|validation.rule |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|trace.level |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|description |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|(c)sms.running.time |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 |0 | +|----------------------------------------------------------------------------------------------------------------------------------|---------| +|polling.use | |0 | | | | | | | | | | +|polling.role | |0 | | | | | | | | | | +|polling.oneway | |0 | | | | | | | | | | +|(S)polling.timeout | |0 | | | | | | | | | | +|(S)polling.request | |0 | | | | | | | | | | +|(R)polling.request.pattern | |0 | | | | | | | | | | +|(R)polling.replacement | |0 | | | | | | | | | | +|(S)polling.response.pattern | |0 | | | | | | | | | | +|----------------------------------------------------------------------------------------------------------------------------------|---------| +|ll.field.type | |0 |0 | | | |0 | | |0 |0 | +|ll.field.length | |0 |0 | | | |0 | | |0 |0 | +|ll.field.offset | |0 |0 | | | |0 | | |0 |0 | +|ll.field.include | |0 |0 | | | |0 | | |0 |0 | +|ll.offset.exclude | |0 |0 | | | |0 | | |0 |0 | +|ll.include | |0 |0 | | | |0 | | |0 |0 | +|----------------------------------------------------------------------------------------------------------------------------------|---------| +|send.payload.length | | | |0 |0 | | | | | | | +|recv.payload.length | | | |0 |0 | | | | | | | +|----------------------------------------------------------------------------------------------------------------------------------|---------| +|xecure.type | | | | | | |0 | | | | | +|xecure.config.path | | | | | | |0 | | | | | +|(cfg)xecure.local.cert | | | | | | |0 | | | | | +|(cfg)xecure.local.key | | | | | | |0 | | | | | +|(cfg)xecure.local.password | | | | | | |0 | | | | | +|xecure.remote.cert | | | | | | |0 | | | | | +|----------------------------------------------------------------------------------------------------------------------------------|---------| +|inisafe.config.path | | | | | | | |0 | | | | +|inisafe.related.adapter.groups| | | | | | | |0 | | | | +|inisafe.start.message | | | | | | | |0 | | | | +|inisafe.stop.message | | | | | | | |0 | | | | +|----------------------------------------------------------------------------------------------------------------------------------|---------| +|ssl.use | | | | | | | | | | | | +|ssl.cert.store | | | | | | | | | | | | +|ssl.cert.password | | | | | | | | | | | | ++----------------------------------------------------------------------------------------------------------------------------------+---------+ +|(cfg)xecure2.config.path | | | | | | | | | | |0 | +|xecure2.sm.ip | | | | | | | | | | |0 | +|xecure2.sm.port | | | | | | | | | | |0 | ++----------------------------------------------------------------------------------------------------------------------------------+---------+ + (c)client (s)server (cfg)config file (S) sender (R) receiver + + + + + ++--------------------------------------------------------------------------------------------------------------+ +|protocol | 접속 통신규약을 정하는 항목 | +|permanent | 거래시 마다 접속을 유지할지 끊을지 판단하는 항목 | +|blocking | 소켓 접속시 Blocking 모드로 할지 Non-Blocking모드를 할지 판단하는 항목 | +| | | +|adapter.group.name | 아답터의 그룹명 | +|bound.usage | 나가는 거래인지 들어오는거래인지 판단하는 항목 | +|host.name | 바인딩 되는 아이피 | +|port.number | 바인딩 되는 포트 | +|local.host.name | 로컬에 바인딩 되는 아이피 | +|local.port.number | 로컬에 바인딩 되는 포트 | +|socket.type | 서버인지 클라이언트인지 판단하는 항목 | +|ack.support | 응답을 받을지 판단하는 항목 | +|response.type | 응답방법(동기/비동기) | +|business.work.class.code | 업무를 구분하기위한 코드 | +|connection.limit.per.ip | 아이피당 접속을 제한하는 항목 | +|max.connection | 최대 접속 갯수를 제한하는 항목 | +|max.thread | 거래 처리시 최대 쓰레드 갯수를 제한하는 항목 | +|socket.reuse | 서버 소켓일경우 이전 소켓을 무시하고 재사용하는 항목 | +|timeout | 거래시 데이타가 안들어올경우 타임아웃 항목 | +|idle.timeout | 접속후 데이타를 안보내거나 안받을 경우 타이아웃 항목 | +|validation.rule | 거래가 들어올경우 룰에 안맞는건 error처리 | +|trace.level | 거래로그 레벨 | +|description | 설명 | +|sms.running.time | sms 발송시간, value = [BUSINESS_DAY | ALL_WEEK],%d{HHmmss},%d{HHmmss} | +|--------------------------------------------------------------------------------------------------------------| +|polling.use | 폴링 사용유무 | +|polling.timeout | 폴링 타임아웃 | +|polling.request | 폴링 요청 | +|polling.request.pattern | 폴링 요청 패턴 | +|polling.replacement | 폴링 요청을 응답으로 바꾸는 패턴 | +|polling.response.pattern | 폴링 응답 패턴 | +|--------------------------------------------------------------------------------------------------------------| +|ll.field.type | LL 필드의 Type(CHAR/BIN) | +|ll.field.length | LL 필드의 길이 | +|ll.field.offset | LL 필드의 시작위치 | +|ll.field.include | LL 필드 포함 길이여부 | +|ll.offset.exclude | LL 필드의 시작위치 포함여부 | +|ll.include | LL 필드를 포함에서 넘길지 여부 | +|--------------------------------------------------------------------------------------------------------------| +|payload.length | 거래시 특정 길이로 LL을 셋팅하고 송수신 | +|--------------------------------------------------------------------------------------------------------------| +|xecure.type | Xecure Connect Type(WELCOME/ENVELOPE/BASIC) | +|xecure.config.path | Xecure Connect 환경파일 위치 | +|(cfg)xecure.local.cert | Xecure Connect 인증서 파일명 | +|(cfg)xecure.local.key | Xecure Connect 키 파일명 | +|(cfg)xecure.local.password | Xecure Connect 패스워드 | +|xecure.remote.cert | Xecure Connect 원격지 인증서 파일명 | +|--------------------------------------------------------------------------------------------------------------| +|inisafe.config.path | INI Safe 환경파일 위치 | +|inisafe.related.adapter.groups| INI Safe와 관련된 아답터 그룹 (신한은망용) | +|inisafe.start.message | INI Safe와 관련된 아답터 시작 메시지 (신한은망용) | +|inisafe.stop.message | INI Safe와 관련되 아답터 종료 메시지 (신한은망용) | +|--------------------------------------------------------------------------------------------------------------| +|ssl.use | SSL 사용여부 | +|ssl.cert.store | SSL 인증서 | +|ssl.cert.password | SSL 패스워드 | +|--------------------------------------------------------------------------------------------------------------| +|(cfg)xecure2.config.path | Xecure Connect Session Manager Type Protocol config file path | +|xecure2.sm.ip | Session Manager Listen IP | +|xecure2.sm.port | Session Manager Listen PORT | ++--------------------------------------------------------------------------------------------------------------+ diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/AdminHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/AdminHandler.java new file mode 100644 index 0000000..16ed82f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/AdminHandler.java @@ -0,0 +1,368 @@ +package com.eactive.eai.adapter.socket2.protocol.admin; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import org.apache.commons.cli.BasicParser; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.Options; +import org.apache.mina.common.IoSession; + +import java.util.Enumeration; +import java.util.concurrent.ConcurrentHashMap; + +public class AdminHandler extends ProtocolHandler { +// private static final String HANDLER_STATE_KEY = AdminHandler.class.getName() + ".STATE"; + SocketAdapterManager manager = SocketAdapterManager.getInstance(); + + private enum State { + STATE_HANDSHAKE, + STATE_MESSAGE; + } + + private static class HandlerState { + State state = State.STATE_HANDSHAKE; + } + + AdminParser parser; + + + public AdminHandler(ISocketAdapter adapter) { + super(adapter); + + this.parser = new AdminParser(); + } + +// private void initState(IoSession session) { +// HandlerState handlerState = (HandlerState) session.getAttribute(HANDLER_STATE_KEY); +// +// if (handlerState == null) { +// handlerState = new HandlerState(); +// // NO_ACK Protocol +// if ("N".equals(context.getAckSupport())) { +// handlerState.state = State.STATE_MESSAGE; +// setSessionState(session, handlerState.state.toString()); +// +// if (context.isPermanent()) { +// sessionPool.release(session); +// } else { +// SimpleFuture handshakeFuture = (SimpleFuture) session.getAttribute(HANDSHAKE_FUTURE); +// handshakeFuture.set(Boolean.TRUE); +// } +// adapter.setAdapterStatus(true); +// } +// session.setAttribute(HANDLER_STATE_KEY, handlerState); +// } +// } + + + @Override + protected byte[] processRequest(IoSession session, byte[] request) { + String result = processCommand(new String(request)); + if(result == null) { + return "".getBytes(); + } + else { + return result.getBytes(); + } + } + + private enum Command { + HELP, // help + CC, CD, // change context + LIST, LS, // list status + START, // start + STOP, // stop + //GET, // get + SET, // set + DISCONNECT, // distconnect + QUIT, EXIT, BYE, // quit + UNKNOWN; + + public static Command getValue(String value) { + try { + return valueOf(value.toUpperCase()); + } catch (Exception e) { + return UNKNOWN; + } + } + } + + private enum Option { + CONNECTION, + SESSION, + TRACE, + CONFIG, + UNKNOWN; + + public static Option getValue(String value) { + try { + return valueOf(value.toUpperCase()); + } catch (Exception e) { + return UNKNOWN; + } + } + } + + public String processCommand(String command) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | execute command : " + command); + } + + //String commands = "stop,start,get,set,disconnect"; + //String options = "connection,session,trace,config"; + //String inCmd = command; + + if (command == null || command.equals("")) { + return ""; + } + + // Parse the program arguments + CommandLine line = null; + try { + line = parser.parse(command); + } catch(Exception e) { + logger.error(context.getAdapterName() + " | " + e.getMessage(), e); + adapter.addRecentError(context.getAdapterName() + " | " + e.getMessage(), e); + return "[AdminHandler] " + e.getMessage(); + } + + // Set the appropriate variables based on supplied options + boolean verbose = false; + boolean help = false; + + if (line.hasOption('h')) { + help = true; + } + + if (line.hasOption('v')) { + verbose = true; + } + + String[] args = line.getArgs(); + String arg0 = args[0].toLowerCase(); + + switch (Command.getValue(arg0)) { + case HELP: + return help(); + + case CD: + case CC: + return cc(args); + + case LS: + case LIST: + return ls(args, verbose); + + case START: + return start(args); + + case STOP: + return stop(args); + + case DISCONNECT: + return disconnect(args, command); + +// case GET: +// if (args.length < 3) { +// return "args.length < 3"; +// } +// +// switch (Option.getValue(args[1].toLowerCase())) { +// case CONNECTION: +// if (args[2].equalsIgnoreCase("all")) { +// return manager.getConnectionInfo(null); +// } else if (args[2].equalsIgnoreCase("summary")) { +// return manager.getConnectionSummary(); +// } else { +// return manager.getConnectionInfo(args[2]); +// } +// case CONFIG: +// SocketAdapterContext ctx = manager.getContext(args[2]); +// if (ctx == null) { +// return CommonLib.getMessage("cannot get context"); +// } else { +// return manager.getContext(args[2]).toString(); +// } +// case SESSION: +// if (args[2].equalsIgnoreCase("all")) { +// return manager.getSessionInfo(null); +// } else { +// return manager.getSessionInfo(args[2]); +// } +// case UNKNOWN: +// default: +// return "Invalid Option : " + command; +// } +// + case SET: + if (args.length < 4) { + return CommonLib.getMessage("args.length < 4"); + } + + // Connections + int newCount = 0; + try { + newCount = Integer.parseInt(args[3]); + } catch (Exception e) { + return e.getMessage(); + } + + switch (Option.getValue(args[1].toLowerCase())) { +// case CONNECTION: +// return manager.adjustConnection(args[2], newCount); +// case SESSION: +// try { +// return manager.adjustThread(args[2], newCount); +// } catch (Exception e) { +// return e.getMessage(); +// } + case TRACE: + SocketAdapterContext ctx = manager.getContext(args[2]); + if (newCount < 0 || newCount > 2) { + return "count is invalid"; + } + if (ctx == null) { + return "context is null"; + } + ctx.setTraceLevel(newCount); + String newLevel = ""; + + switch(newCount) { + case 0: + newLevel = "0(ERROR)"; + break; + case 1: + newLevel = "1(INFO)"; + break; + default: + newLevel = "2(DEBUG)"; + } + + return "change trace level to " + newLevel; + case UNKNOWN: + default: + return "Invalid Option : " + command; + } + + case QUIT: + case EXIT: + case BYE: + return "EXIT"; + case UNKNOWN: + default: + return " Unknown Command : " + command + ". Type 'help'"; + } + } + + private String help() { + StringBuilder sb = new StringBuilder(); + sb.append("\n help\n"); + sb.append(" -------------------------------------------------------------------\n"); + sb.append(" help - 도움말\n"); + sb.append(" list|ls|stat|st| - List properties, Status\n"); + sb.append(" cd|cc [AdapterGroup].[Adapter] - Change Context\n"); + sb.append(" start - Start socket adapter\n"); + sb.append(" stop - Stop socket adapter\n"); + sb.append(" disconnect - Disconnect session\n"); + sb.append(" set - Modify socket adapter property\n"); + return sb.toString(); + } + + private String cc(String[] args) { + if (args.length < 2) { + return " usage : cc|cd [adapter group].[adapter]"; + } + + ISocketAdapter adapter = manager.getSocketAdapter(args[1]); + if (adapter != null) + return args[1]; + else + return " ERROR - context (adapter group, adapter) does not exist : " + args[1]; + } + + private String ls(String[] args, boolean verbose) { + StringBuilder sb = new StringBuilder(); + sb.append("\n"); + sb.append(String.format(" %-30s %-10s %-10s %10s %10s %10s %10s\n", + "adapter", + "protocol", + "state", + "pool", + "recv", + "send", + "error")); + sb.append(" -----------------------------------------------------------------------------------------------------------\n"); + String prev = ""; + + ConcurrentHashMap> adapterGroups = (ConcurrentHashMap)manager.getSocketAdapterGroups(); + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = (String) e.nextElement(); + ConcurrentHashMap adapters = adapterGroups.get(adapterGroupName); + //sb.append(adapterGroupName + "\n"); + for (Enumeration ee = adapters.elements() ; ee.hasMoreElements() ;) { + ISocketAdapter adapter = ee.nextElement(); + if (!prev.equals(adapterGroupName)) { + sb.append(String.format(" %-31s %s\n", + adapterGroupName, + "---------------------------------------------------------------------------")); + } + sb.append(String.format(" .%-30s %-10s %-10s %10d %10d %10d %10d\n", + adapter.getContext().getAdapterName(), + adapter.getContext().getProtocol().length() > 5 ? adapter.getContext().getProtocol().substring(0,5) : adapter.getContext().getProtocol(), + adapter.getState().name(), + adapter.getSessionPool().peekSize(), + adapter.getMessageRecv(), + adapter.getMessageSend(), + adapter.getRecentErrorCount())); + prev = adapterGroupName; + } + } + + return sb.toString(); + } + + private String start(String[] args) { + if (args.length < 3) { + return " usage : start [adapter group] [adapter]"; + } + + return manager.start(args[1], args[2]); + } + + private String stop(String[] args) { + if (args.length < 3) { + return " usage : stop [adapter group] [adapter]"; + } + + manager.stop(); + return "stopped"; + } + + private String disconnect(String[] args, String command) { + if (args.length < 3) { + return "args.length < 3"; + } + return manager.disconnect(args[1].toLowerCase(), args[2]); + } +} + +class AdminParser { + CommandLineParser parser; + Options options; + + public AdminParser() { + parser = new BasicParser(); + options = new Options(); + options.addOption("h", "help", false, "Print this usage information"); + options.addOption("v", "verbose", false, "Print out VERBOSE information"); + //options.addOption("f", "file", true, "File to save program output to"); + } + + public CommandLine parse(String cmd) throws Exception { + return parser.parse(options, cmd.split("\\s")); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/AdminServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/AdminServer.java new file mode 100644 index 0000000..52f6b7a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/AdminServer.java @@ -0,0 +1,27 @@ +package com.eactive.eai.adapter.socket2.protocol.admin; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class AdminServer extends TcpAdapterServer { + public AdminServer(SocketAdapterContext context) throws Exception { + super(context); + + context.setLlFieldType("BIN"); + context.setLlFieldOffset(0); + context.setLlFieldLength(2); + context.setLlFieldInclude("N"); + context.setLlInclude("N"); + + this.handler = new AdminHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + } + + public Object sendMessage(Object message) throws EAIException { + throw new EAIException("[Admin Server] not supported function"); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminHandler.java new file mode 100644 index 0000000..590feb2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminHandler.java @@ -0,0 +1,34 @@ +package com.eactive.eai.adapter.socket2.protocol.admin; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import org.apache.mina.common.IoSession; + +public class TelnetAdminHandler extends ProtocolHandler { + public TelnetAdminHandler(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(IoSession session) { + session.write("WELCOME"); + session.write("cmd> " + (byte) 0xF8); + } + + @Override + public void messageReceived(IoSession session, Object message) throws Exception { + String msg = message.toString().trim(); + System.out.println(" " + msg); + + if ("quit".equals(msg) || "exit".equals(msg)) { + session.write("bye......"); + sessionPool.remove(session); + session.close(); + return; + } + + session.write(msg); + session.write("\r\ncmd> "); + session.write((byte) 0x22); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminServer.java new file mode 100644 index 0000000..df0216e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetAdminServer.java @@ -0,0 +1,23 @@ +package com.eactive.eai.adapter.socket2.protocol.admin; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import org.apache.mina.filter.codec.ProtocolCodecFilter; +import org.apache.mina.filter.codec.textline.TextLineCodecFactory; +import org.apache.mina.transport.socket.nio.SocketSessionConfig; + +import java.nio.charset.Charset; + + +public class TelnetAdminServer extends TcpAdapterServer { + public TelnetAdminServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new TelnetAdminHandler(this); + + SocketSessionConfig sessionConfig = (SocketSessionConfig) config.getSessionConfig(); + sessionConfig.setTcpNoDelay(true); + sessionConfig.setKeepAlive(true); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new TextLineCodecFactory(Charset.forName("UTF-8")))); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetTextLineCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetTextLineCodecFactory.java new file mode 100644 index 0000000..8ba76be --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/admin/TelnetTextLineCodecFactory.java @@ -0,0 +1,89 @@ +package com.eactive.eai.adapter.socket2.protocol.admin; + +import org.apache.mina.common.BufferDataException; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.textline.LineDelimiter; +import org.apache.mina.filter.codec.textline.TextLineDecoder; +import org.apache.mina.filter.codec.textline.TextLineEncoder; + +import java.nio.charset.Charset; + +public class TelnetTextLineCodecFactory implements ProtocolCodecFactory { + private final TextLineEncoder encoder; + + private final TextLineDecoder decoder; + + /** + * Creates a new instance with the current default {@link Charset}. + */ + public TelnetTextLineCodecFactory() { + this(Charset.defaultCharset()); + } + + /** + * Creates a new instance with the specified {@link Charset}. + */ + public TelnetTextLineCodecFactory(Charset charset) { + encoder = new TextLineEncoder(charset, LineDelimiter.UNIX); + decoder = new TextLineDecoder(charset, LineDelimiter.AUTO); + } + + public ProtocolEncoder getEncoder() { + return encoder; + } + + public ProtocolDecoder getDecoder() { + return decoder; + } + + /** + * Returns the allowed maximum size of the encoded line. + * If the size of the encoded line exceeds this value, the encoder + * will throw a {@link IllegalArgumentException}. The default value + * is {@link Integer#MAX_VALUE}. + *

+ * This method does the same job with {@link TextLineEncoder#getMaxLineLength()}. + */ + public int getEncoderMaxLineLength() { + return encoder.getMaxLineLength(); + } + + /** + * Sets the allowed maximum size of the encoded line. + * If the size of the encoded line exceeds this value, the encoder + * will throw a {@link IllegalArgumentException}. The default value + * is {@link Integer#MAX_VALUE}. + *

+ * This method does the same job with {@link TextLineEncoder#setMaxLineLength(int)}. + */ + public void setEncoderMaxLineLength(int maxLineLength) { + encoder.setMaxLineLength(maxLineLength); + } + + /** + * Returns the allowed maximum size of the line to be decoded. + * If the size of the line to be decoded exceeds this value, the + * decoder will throw a {@link BufferDataException}. The default + * value is 1024 (1KB). + *

+ * This method does the same job with {@link TextLineDecoder#getMaxLineLength()}. + */ + public int getDecoderMaxLineLength() { + return decoder.getMaxLineLength(); + } + + /** + * Sets the allowed maximum size of the line to be decoded. + * If the size of the line to be decoded exceeds this value, the + * decoder will throw a {@link BufferDataException}. The default + * value is 1024 (1KB). + *

+ * This method does the same job with {@link TextLineDecoder#setMaxLineLength(int)}. + */ + public void setDecoderMaxLineLength(int maxLineLength) { + decoder.setMaxLineLength(maxLineLength); + } +} + diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/AppendClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/AppendClient.java new file mode 100644 index 0000000..ab21a9b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/AppendClient.java @@ -0,0 +1,18 @@ +package com.eactive.eai.adapter.socket2.protocol.append; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.append.codec.AppendCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class AppendClient extends TcpAdapterClient { + + public AppendClient(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new AppendHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new AppendCodecFactory(this))); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/AppendHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/AppendHandler.java new file mode 100644 index 0000000..c595d39 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/AppendHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.append; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class AppendHandler extends ProtocolHandler { + public AppendHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/AppendServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/AppendServer.java new file mode 100644 index 0000000..da8f3d5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/AppendServer.java @@ -0,0 +1,18 @@ +package com.eactive.eai.adapter.socket2.protocol.append; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.append.codec.AppendCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class AppendServer extends TcpAdapterServer { + + public AppendServer(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new AppendHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new AppendCodecFactory(this))); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/codec/AppendCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/codec/AppendCodecFactory.java new file mode 100644 index 0000000..cca6009 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/codec/AppendCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.append.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class AppendCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public AppendCodecFactory(ISocketAdapter adapter) { + encoder = new AppendEncoder(adapter); + decoder = new AppendDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/codec/AppendDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/codec/AppendDecoder.java new file mode 100644 index 0000000..f6ec9e2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/codec/AppendDecoder.java @@ -0,0 +1,310 @@ +package com.eactive.eai.adapter.socket2.protocol.append.codec; + +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; + +public class AppendDecoder extends ProtocolDecoderAdapter { + protected final Logger logger; + protected final Logger errLogger; + + private static final String errorCode = "RECEAINNA008"; + + public static final int MAX_PAYLOAD_SIZE = 25 * 1024 * 1024; // 25MB + + private static final String DECODER_STATE_KEY = AppendDecoder.class.getName() + ".STATE"; + + private enum State { + STATE_HEADER_READ, STATE_PAYLOAD_READ; + } + + private static class CodecState { + State state = State.STATE_HEADER_READ; + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public AppendDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @SuppressWarnings("static-access") + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + + + if (codecState == null) { + String line = context.getAppendHead(); + ByteMessage head = new ByteMessage(); + while(line.indexOf("0x") != -1) { + head.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + head.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + head.append(line); + + line = context.getAppendTail(); + + ByteMessage tail = new ByteMessage(); + while(line.indexOf("0x") != -1) { + tail.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + tail.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + tail.append(line); + session.setAttribute("head",head); + session.setAttribute("tail",tail); + + codecState = new CodecState(); + codecState.buffer.limit(context.getLlFieldOffset() + context.getLlFieldLength() + head.size() ); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + ByteMessage head = (ByteMessage)session.getAttribute("head"); + ByteMessage tail = (ByteMessage)session.getAttribute("tail"); + if (head == null) head = new ByteMessage(); + if (tail == null) tail = new ByteMessage(); + + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + StringBuilder sb = new StringBuilder(); + sb.append("FixedHeaderDecoder"); + if (codecState.state == State.STATE_PAYLOAD_READ) { + sb.append("(" + codecState.payloadSize + ")"); + } + sb.append(" | decode : " + CommonLib.hexDump(in, context)); + logger.debug(sb.toString()); + adapter.addRecentRecvTrace(session, sb.toString()); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + /** + * payload size < 0 인 경우 + */ + if (codecState.payloadSize < 0) { + throw new EAIException(errorCode, context.getAdapterName() + + " (" + context.getLlFieldType() + "," + context.getLlFieldOffset() + "," + context.getLlFieldLength() + + ") | when read header, ll length field is invalid | " + CommonLib.hexDump(codecState.buffer, context)); + /** + * payload size == 0 인 경우 + */ + } else if (codecState.payloadSize == 0) { + if (context.isSync()) { + throw new Exception(" payload size 0 (ping). 'SYNC' response type socket does not support ping(size 0) message."); + } + + //codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_INFO ) { + logger.info(context.getAdapterName() + " | payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + } + + /** + * header 값을 읽은 후 buffer의 position을 이동해 준다. + * 이 작업을 안해주면 무한루프에 빠질 수 있다. + * 예) 법원 공탁금 (_LAW_IN_SOC_AsS{...}) + */ + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + break; + } + /** + * ll.include = 'Y' - LL을 포함해서 넘긴다. + */ + if ("Y".equals(context.getLlInclude())) { + try { + codecState.buffer.position(context.getLlFieldOffset() + context.getLlFieldLength()+ head.size()) + .limit(codecState.payloadSize + context.getLlFieldLength()+ head.size() +tail.size()); + } catch(IllegalArgumentException e) { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); + sb.append("offset=" + context.getLlFieldOffset() + context.getLlFieldLength()); + sb.append(", limit=" + codecState.payloadSize + context.getLlFieldLength()); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + /** + * ll.include = 'N' - LL을 제외하고 넘긴다. + */ + } else { + try { + codecState.buffer.position(context.getLlFieldOffset()).limit(codecState.payloadSize); + } catch(IllegalArgumentException e) { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); + sb.append("offset=" + context.getLlFieldOffset()); + sb.append(", limit=" + codecState.payloadSize); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + } + + /** + * offset + ll 을 읽었고, 더 이상 읽을 것(payload)이 없는 경우 + * - ll.length value = ll.offset + ll.field.length + */ + if (codecState.buffer.position() == codecState.buffer.limit()) { + byte[] bytes = new byte[codecState.buffer.limit()-head.size()-tail.size()]; + byte[] tails = new byte[tail.size()]; + codecState.buffer.position(head.size()); + codecState.buffer.get(bytes); + codecState.buffer.get(tails); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength() + head.size()); + + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + + break; + } + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()-head.size()-tail.size()]; + byte[] tails = new byte[tail.size()]; + codecState.buffer.position(head.size()); + codecState.buffer.get(bytes); + codecState.buffer.get(tails); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength() + head.size()); + + //by short11 + //polling.role 이 Server 가 sender일 경우 오류가 있었음 + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + + break; + default : + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + ByteMessage head = (ByteMessage)session.getAttribute("head"); +// ByteMessage tail = (ByteMessage)session.getAttribute("tail"); + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + if ("BIN".equals(context.getLlFieldType())) { + codecState.payloadSize = 0; + for (int i=0; i MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + MAX_PAYLOAD_SIZE + ") exceeded : " + + codecState.payloadSize + " | " + + CommonLib.hexDump(codecState.buffer, context)); + } + + /** + * ll.field.include = 'Y' - 헤더 길이를 빼 준다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + codecState.payloadSize = codecState.payloadSize - context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 더해서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + codecState.payloadSize = codecState.payloadSize + context.getLlFieldOffset(); + } + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/codec/AppendEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/codec/AppendEncoder.java new file mode 100644 index 0000000..0b770a8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/append/codec/AppendEncoder.java @@ -0,0 +1,155 @@ +package com.eactive.eai.adapter.socket2.protocol.append.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class AppendEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public AppendEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + /** + * head size 및 value + */ + + String line = context.getAppendHead(); + ByteMessage head = new ByteMessage(); + while(line.indexOf("0x") != -1) { + head.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + head.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + head.append(line); + + /** + * tail size 및 value + */ + line = context.getAppendTail(); + + ByteMessage tail = new ByteMessage(); + while(line.indexOf("0x") != -1) { + tail.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + tail.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + tail.append(line); + + + + /** + * ll.include = 'Y' - 통째로 보낸다. + */ + if ("Y".equals(context.getLlInclude())) { + ByteBuffer buffer = ByteBuffer.allocate(m.size() - context.getLlFieldLength()); + buffer.put(m.getBytes(0, context.getLlFieldOffset())); + buffer.put(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + buffer.flip(); + m.setByteBuffer(buffer); + } + + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate(context.getLlFieldLength() + length + head.size()+ tail.size()).limit(context.getLlFieldLength() + length+ head.size()+ tail.size()); + + /** + * ll.field.include = 'Y' - header 길이 포함하여 ll 을 계산한다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + length = length + context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 빼서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + length = length - context.getLlFieldOffset(); + } + + /** + * [1] head 추가 + */ + + buffer.put(head.getBytes()); + /** + * [2] before-payload + */ + buffer.put(m.getBytes(0, context.getLlFieldOffset())); + + /** + * [3] write header + */ + if ("BIN".equals(context.getLlFieldType())) { + int tmpLength = length; + byte[] header = new byte[context.getLlFieldLength()]; + for (int i = context.getLlFieldLength()-1; i>=0; i--) { + header[i] = (byte) (tmpLength % 256); + tmpLength = tmpLength / 256; + } + buffer.put(header); + } else { // "CHAR" + String lenStr = CommonLib.getFormatString(length, context.getLlFieldLength()); + buffer.put(lenStr.getBytes()); + } + /** + * [4] after-payload + */ + buffer.put(m.getBytes(context.getLlFieldOffset(), m.getBytes().length - context.getLlFieldOffset())); + + + /** + * [5]tail 추가 + */ + buffer.put(tail.getBytes()); + + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | FixedHeaderEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "FixedHeaderEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + out.flush(); + } + + public void dispose(IoSession session) throws Exception { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/CertClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/CertClient.java new file mode 100644 index 0000000..548bfaf --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/CertClient.java @@ -0,0 +1,19 @@ +package com.eactive.eai.adapter.socket2.protocol.cert; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.cert.codec.CertCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.cert.handshake.CertClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class CertClient extends TcpAdapterClient { + + public CertClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new CertHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new CertCodecFactory(this))); + config.getFilterChain().addAfter("codec", "cert", new CertClientFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/CertHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/CertHandler.java new file mode 100644 index 0000000..09d350b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/CertHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.cert; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class CertHandler extends ProtocolHandler { + public CertHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/CertServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/CertServer.java new file mode 100644 index 0000000..464066f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/CertServer.java @@ -0,0 +1,17 @@ +package com.eactive.eai.adapter.socket2.protocol.cert; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.cert.codec.CertCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.cert.handshake.CertServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class CertServer extends TcpAdapterServer { + public CertServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new CertHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new CertCodecFactory(this))); + config.getFilterChain().addAfter("codec", "cert", new CertServerFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertCodecFactory.java new file mode 100644 index 0000000..3f19d96 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertCodecFactory.java @@ -0,0 +1,25 @@ +package com.eactive.eai.adapter.socket2.protocol.cert.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class CertCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + + public CertCodecFactory(ISocketAdapter adapter) { + encoder = new CertEncoder(adapter); + decoder = new CertDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertConstants.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertConstants.java new file mode 100644 index 0000000..6f904e4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertConstants.java @@ -0,0 +1,8 @@ +package com.eactive.eai.adapter.socket2.protocol.cert.codec; + +public class CertConstants { + public static final String CODEC_KEY = "UNRELAIBLE_CODEC_KEY"; + private CertConstants() { + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertDecoder.java new file mode 100644 index 0000000..fc1b193 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertDecoder.java @@ -0,0 +1,147 @@ +package com.eactive.eai.adapter.socket2.protocol.cert.codec; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.adapter.socket2.protocol.cert.message.CertMessage; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + + +public class CertDecoder extends ProtocolDecoderAdapter { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + private enum State { + STATE_LL_READ, + STATE_PAYLOAD_READ + } + + public static class CodecState { + State state = State.STATE_LL_READ; + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + } + + public CertDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) + throws Exception { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | CertDecoder | decode : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "CertDecoder | decode : " + CommonLib.hexDump(in, context)); + } + + CodecState codecState = (CodecState) session.getAttribute(CertConstants.CODEC_KEY); + + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(CertMessage.LL_LENGTH); + session.setAttribute(CertConstants.CODEC_KEY, codecState); + } + + while (in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_LL_READ: + if (readHeader(codecState, in)) { + codecState.buffer.position(CertMessage.LL_LENGTH).limit(CertMessage.LL_LENGTH + codecState.payloadSize); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.get(bytes); + + CertMessage message = new CertMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(CertMessage.LL_LENGTH); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_LL_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + default : + } + } + } + + private boolean readHeader(CodecState codecState, ByteBuffer in) throws Exception { + /* + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | read header : " + CommonLib.hexDump(in)); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while (codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.buffer.flip(); + + try { + byte[] header = new byte[CertMessage.LL_LENGTH]; + codecState.buffer.get(header); + codecState.payloadSize = Integer.parseInt(new String(header)); + } catch (NumberFormatException e) { + throw new EAIException("RECEAINNA008", context.getAdapterName() + " | when read header, number format is invalid - " + e.getMessage() + " | " + CommonLib.hexDump(codecState.buffer, context)); + } + + return true; + } + + private boolean readPayload(CodecState codecState, ByteBuffer in) throws Exception { + /* + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | read payload : " + CommonLib.hexDump(in)); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while (codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.buffer.flip(); + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertEncoder.java new file mode 100644 index 0000000..49b819e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/codec/CertEncoder.java @@ -0,0 +1,95 @@ +package com.eactive.eai.adapter.socket2.protocol.cert.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.cert.codec.CertDecoder.CodecState; +import com.eactive.eai.adapter.socket2.protocol.cert.message.CertMessage; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class CertEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public CertEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + /* + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | decode : " + message); + } + */ + + CodecState codecState = (CodecState) session.getAttribute(CertConstants.CODEC_KEY); + + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(CertMessage.LL_LENGTH); + session.setAttribute(CertConstants.CODEC_KEY, codecState); + } + + CertMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof CertMessage) { + m = (CertMessage) message; + } else if (message instanceof ByteMessage) { + m = new CertMessage(((ByteMessage) message).getBytes()); + } else if (message instanceof String) { + m = new CertMessage((String) message); + } else if (message instanceof byte[]) { + m = new CertMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + ByteBuffer buffer = ByteBuffer.allocate(CertMessage.COMMON_HEADER_LENGTH + CertMessage.INDIVIDUAL_HEADER_LENGTH + m.getBytes().length); + //buf.setAutoExpand(true); // Enable auto-expand for easier encoding + + // write header +// String ll = CommonLib.getFormatString(m.getBytes().length, CertMessage.LL_LENGTH); +// buffer.put(ll.getBytes()); // tatal message length + // tatal message length - left padding '0' + //buffer.put(StringUtils.leftPad(String.valueOf(m.getValue().length + Constants.HEADER_LENGTH + Constants.TAIL_LENGTH), 7, '0').getBytes()); + + // 암호화 타입 (0:plain 1:DES 2:Plll Connect) + //buffer.put(codecState.securityType); + // 판매점 아이디 (16 Byte 고정으로 앞 또는 뒤를 공백문자로 채운다) + //buffer.put(StringUtils.leftPad("1111", 16, ' ').getBytes()); + + // write header + buffer.put(m.getHeader()); + + //write payload + buffer.put(m.getBytes()); + + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | CertEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "CertEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + public void dispose(IoSession session) throws Exception { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/handshake/CertClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/handshake/CertClientFilter.java new file mode 100644 index 0000000..63984ef --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/handshake/CertClientFilter.java @@ -0,0 +1,75 @@ +package com.eactive.eai.adapter.socket2.protocol.cert.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.cert.message.CertMessage; +import org.apache.mina.common.IoSession; + + +public class CertClientFilter extends CertFilter { + public CertClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { +// FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + CertMessage mm = new CertMessage(); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | CertClientFilter | challenge : " + mm.hexDump()); + } +// IoFuture future = session.write(mm.getBytes()); + session.write(mm.getBytes()); + //future.join(context.getTimeout() * 1000L); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { + case STATE_CHALLENGE: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | CertClientFilter | challenge : " + m.hexDump()); + } + CertMessage mm = new CertMessage(); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | CertClientFilter | auth : " + mm.hexDump()); + } +// IoFuture future = session.write(mm.getBytes()); + session.write(mm.getBytes()); + //future.join(context.getTimeout() * 1000L); + + filterState.state = State.STATE_AUTH; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_AUTH: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | CertClientFilter | auth : " + m.hexDump()); + } + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + break; + + case STATE_MESSAGE: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | CertClientFilter | : " + m.hexDump()); + } + nextFilter.messageReceived(session, message); + break; + + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/handshake/CertFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/handshake/CertFilter.java new file mode 100644 index 0000000..3ecce80 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/handshake/CertFilter.java @@ -0,0 +1,65 @@ +package com.eactive.eai.adapter.socket2.protocol.cert.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + + +public abstract class CertFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + + public static final String FILTER_STATE_KEY = CertFilter.class.getName() + ".STATE"; + public static final String SESSION_STATE = "SESSION_STATE"; + + public enum State { + STATE_CHALLENGE, + STATE_AUTH, + STATE_MESSAGE; + } + + public static class FilterState { + public State state = State.STATE_CHALLENGE; + byte[] key; // token? + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected CertFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + if (parent.contains(CertFilter.class)) { + throw new IllegalStateException("A filter chain cannot contain more than one CertFilter."); + } + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/handshake/CertServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/handshake/CertServerFilter.java new file mode 100644 index 0000000..d854037 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/handshake/CertServerFilter.java @@ -0,0 +1,63 @@ +package com.eactive.eai.adapter.socket2.protocol.cert.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.cert.message.CertMessage; +import org.apache.mina.common.IoFuture; +import org.apache.mina.common.IoSession; + + +public class CertServerFilter extends CertFilter { + public CertServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + CertMessage m = (CertMessage) message; + + switch (filterState.state) { + case STATE_CHALLENGE: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | CertServerFilter | challenge : " + m.hexDump()); + } + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | CertServerFilter | challenge : " + m.hexDump()); + } + IoFuture future = session.write(m.getBytes()); + //future.join(context.getTimeout() * 1000L); + + filterState.state = State.STATE_AUTH; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_AUTH: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | CertServerFilter | auth : " + m.hexDump()); + } + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | CertServerFilter | auth : " + m.hexDump()); + } + future = session.write(m.getBytes()); //filterState.key); + //future.join(context.getTimeout() * 1000L); + + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + break; + + case STATE_MESSAGE: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | CertServerFilter | : " + m.hexDump()); + } + + nextFilter.messageReceived(session, message); + break; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/message/CertMessage.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/message/CertMessage.java new file mode 100644 index 0000000..7736f42 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cert/message/CertMessage.java @@ -0,0 +1,49 @@ +package com.eactive.eai.adapter.socket2.protocol.cert.message; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; + +public class CertMessage extends ByteMessage { + public static final int LL_LENGTH = 9; + public static final int COMMON_HEADER_LENGTH = 223; + public static final int INDIVIDUAL_HEADER_LENGTH = 235; + + byte[] header; + + public CertMessage() { + this(new byte[0]); + } + + public CertMessage(String body) { + this(body.getBytes()); + } + + public CertMessage(byte[] body) { + this(new byte[COMMON_HEADER_LENGTH + INDIVIDUAL_HEADER_LENGTH], body); + } + + public CertMessage(byte[] header, byte[] body) { + this.header = header; + this.value = body; + String ll = CommonLib.getFormatString(COMMON_HEADER_LENGTH - LL_LENGTH + INDIVIDUAL_HEADER_LENGTH + body.length, LL_LENGTH); + System.arraycopy(ll.getBytes(), 0, header, 0, LL_LENGTH); + } + + public byte[] getHeader() { + return header; + } + + @Override + public String hexDump() { + return CommonLib.hexDump(value); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("CertMessage - ["); + sb.append(new String(value)); + sb.append("]"); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/CiscoClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/CiscoClient.java new file mode 100644 index 0000000..d66f170 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/CiscoClient.java @@ -0,0 +1,44 @@ +package com.eactive.eai.adapter.socket2.protocol.cisco; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.cisco.codec.CiscoCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class CiscoClient extends TcpAdapterClient { + + public CiscoClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new CiscoHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new CiscoCodecFactory(this))); + + /** + * TODO : snmp 와 연동하여 아래 작업 할 것 flow control filter + */ + //config.getFilterChain().addLast("flowControl", new FlowControlFilter()); + + /* + ReadThrottleFilterBuilder filter = new ReadThrottleFilterBuilder(); + filter.attach(config.getFilterChain()); + */ + + + /** + * flow control filter (apache mina version 1.9.x) + */ + /* + * config.getFilterChain().addLast("executor", new ExecutorFilter(executor)); + * ReadThrottleFilterBuilder flowControlFilter = new ReadThrottleFilterBuilder(); + * flowControlFilter.setMaximumConnectionBufferSize(1024*1024); // 1MB + * flowControlFilter.attach(config.getFilterChain()); + */ + + /** + * flow control filter (apache mina version 2.x) + */ + /* + * config.getFilterChain().addLast("flowControl", new ReadThrottleFilter()); + * config.getFilterChain().addLast("flowControl", new WriteThrottleFilter()); + */ + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/CiscoHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/CiscoHandler.java new file mode 100644 index 0000000..2400124 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/CiscoHandler.java @@ -0,0 +1,11 @@ +package com.eactive.eai.adapter.socket2.protocol.cisco; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class CiscoHandler extends ProtocolHandler { + + public CiscoHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/CiscoServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/CiscoServer.java new file mode 100644 index 0000000..71cec81 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/CiscoServer.java @@ -0,0 +1,44 @@ +package com.eactive.eai.adapter.socket2.protocol.cisco; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.cisco.codec.CiscoCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class CiscoServer extends TcpAdapterServer { + public CiscoServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new CiscoHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new CiscoCodecFactory(this))); + + /** + * TODO : snmp 와 연동하여 아래 작업 할 것 flow control filter + */ + //config.getFilterChain().addLast("flowControl", new FlowControlFilter()); + + /* + ReadThrottleFilterBuilder filter = new ReadThrottleFilterBuilder(); + filter.attach(config.getFilterChain()); + */ + + + /** + * flow control filter (apache mina version 1.9.x) + */ + /* + * config.getFilterChain().addLast("executor", new ExecutorFilter(executor)); + * ReadThrottleFilterBuilder flowControlFilter = new ReadThrottleFilterBuilder(); + * flowControlFilter.setMaximumConnectionBufferSize(1024*1024); // 1MB + * flowControlFilter.attach(config.getFilterChain()); + */ + + /** + * flow control filter (apache mina version 2.x) + */ + /* + * config.getFilterChain().addLast("flowControl", new ReadThrottleFilter()); + * config.getFilterChain().addLast("flowControl", new WriteThrottleFilter()); + */ + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoCodecFactory.java new file mode 100644 index 0000000..f39b807 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.cisco.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class CiscoCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public CiscoCodecFactory(ISocketAdapter adapter) { + encoder = new CiscoEncoder(adapter); + decoder = new CiscoDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoConstants.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoConstants.java new file mode 100644 index 0000000..bedcec6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoConstants.java @@ -0,0 +1,9 @@ +package com.eactive.eai.adapter.socket2.protocol.cisco.codec; + +public class CiscoConstants { + public static final int CISCO_PACKET_SIZE = 1024; + //public static final long RECONNECT_INTERVAL = 1000; + private CiscoConstants() { + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoDecoder.java new file mode 100644 index 0000000..1b529fc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoDecoder.java @@ -0,0 +1,154 @@ +package com.eactive.eai.adapter.socket2.protocol.cisco.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +public class CiscoDecoder extends ProtocolDecoderAdapter { + protected final Logger logger; + protected final Logger errLogger; + + private static final String DECODER_STATE_KEY = CiscoDecoder.class.getName() + ".STATE"; + + private enum State { + STATE_HEADER_READ, + STATE_PAYLOAD_READ; + } + + private static class CodecState { + State state = State.STATE_HEADER_READ; + ByteBuffer partBuffer = ByteBuffer.allocate(CiscoConstants.CISCO_PACKET_SIZE); + ByteBuffer wholeBuffer = ByteBuffer.allocate(CiscoConstants.CISCO_PACKET_SIZE).setAutoExpand(true); + int payloadSize; + boolean last; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public CiscoDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) + throws Exception { + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | CiscoDecoder | decode : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "CiscoDecoder | decode : " + CommonLib.hexDump(in, context)); + } + + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + + if (codecState == null) { + codecState = new CodecState(); + codecState.partBuffer.limit(6); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch(codecState.state) { + case STATE_HEADER_READ : + // try to read first image + if (readHeader(session, codecState, in)) { + codecState.partBuffer.position(0).limit(codecState.payloadSize); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ : + if (readPayload(session, codecState, in)) { + codecState.wholeBuffer.put(codecState.partBuffer); + if (codecState.last) { + byte[] bytes = new byte[codecState.wholeBuffer.position()]; + codecState.wholeBuffer.position(0); + codecState.wholeBuffer.get(bytes); + ByteMessage m = new ByteMessage(bytes); + out.write(m); + + codecState.wholeBuffer.position(0).limit(6); + codecState.last = false; + } + codecState.partBuffer.position(0).limit(6); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + } + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read header : " + CommonLib.hexDump(in)); + } + */ + + if (codecState.partBuffer.remaining() > in.remaining()) { + codecState.partBuffer.put(in); + return false; + } + + while(codecState.partBuffer.hasRemaining()) { + codecState.partBuffer.put(in.get()); + } + + if ((codecState.partBuffer.get(0) & 0xD7) == 0 + || codecState.partBuffer.get(1) != 0x4A + || codecState.partBuffer.get(5) != 0x00) { + throw new Exception(context.getAdapterName() + " | magic number is wrong."); + } + + codecState.payloadSize = ((int) ((codecState.partBuffer.get(2)) & 0xFF) * 256) + + ((int) ((codecState.partBuffer.get(3)) & 0xFF)); + codecState.last = codecState.partBuffer.get(4) == 0x00; + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read payload : " + CommonLib.hexDump(in)); + } + */ + + if (codecState.partBuffer.remaining() > in.remaining()) { + codecState.partBuffer.put(in); + return false; + } + + while(codecState.partBuffer.hasRemaining()) { + codecState.partBuffer.put(in.get()); + } + + codecState.partBuffer.flip(); + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoEncoder.java new file mode 100644 index 0000000..a7240a8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/cisco/codec/CiscoEncoder.java @@ -0,0 +1,91 @@ +package com.eactive.eai.adapter.socket2.protocol.cisco.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class CiscoEncoder implements ProtocolEncoder { + final protected Logger logger; + final protected Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public CiscoEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) + throws Exception { + + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + ByteBuffer buffer = ByteBuffer.allocate(6); + buffer.setAutoExpand(true); // Enable auto-expand for easier encoding + + int toSendLen = 0; + int sentLen = 0; + + while (true) { + if (m.getBytes().length - sentLen <= CiscoConstants.CISCO_PACKET_SIZE) { + toSendLen = m.getBytes().length - sentLen; + } else { + toSendLen = CiscoConstants.CISCO_PACKET_SIZE; + } + + buffer.put((byte) 0xD7); + buffer.put((byte) 0x4A); + buffer.put((byte) (toSendLen/256)); + buffer.put((byte) (toSendLen%256)); + buffer.put((byte) (sentLen + toSendLen >= m.getBytes().length ? 0x00 : 0x01)); + buffer.put((byte) 0x00); + + byte[] payload = new byte[toSendLen]; + System.arraycopy(m.getBytes(), sentLen, payload, 0, toSendLen); + buffer.put(payload); + + sentLen += toSendLen; + + if( sentLen >= m.getBytes().length) { + break; + } + //continue; + } + + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | CiscoEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "CiscoEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + + buffer.flip(); + out.write(buffer); + } + + public void dispose(IoSession session) throws Exception { + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/DelimiterClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/DelimiterClient.java new file mode 100644 index 0000000..ca68c61 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/DelimiterClient.java @@ -0,0 +1,15 @@ +package com.eactive.eai.adapter.socket2.protocol.delimiter; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.delimiter.codec.DelimiterCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class DelimiterClient extends TcpAdapterClient { + public DelimiterClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new DelimiterHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new DelimiterCodecFactory(this))); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/DelimiterHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/DelimiterHandler.java new file mode 100644 index 0000000..54b277a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/DelimiterHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.delimiter; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class DelimiterHandler extends ProtocolHandler { + public DelimiterHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/DelimiterServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/DelimiterServer.java new file mode 100644 index 0000000..0424f93 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/DelimiterServer.java @@ -0,0 +1,16 @@ +package com.eactive.eai.adapter.socket2.protocol.delimiter; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.delimiter.codec.DelimiterCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class DelimiterServer extends TcpAdapterServer { + public DelimiterServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new DelimiterHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new DelimiterCodecFactory(this))); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/codec/DelimiterCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/codec/DelimiterCodecFactory.java new file mode 100644 index 0000000..86a51f4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/codec/DelimiterCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.delimiter.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class DelimiterCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public DelimiterCodecFactory(ISocketAdapter adapter) { + encoder = new DelimiterEncoder(adapter); + decoder = new DelimiterDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/codec/DelimiterDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/codec/DelimiterDecoder.java new file mode 100644 index 0000000..51cf432 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/codec/DelimiterDecoder.java @@ -0,0 +1,174 @@ +package com.eactive.eai.adapter.socket2.protocol.delimiter.codec; + + +import java.util.Arrays; + +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.HexUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; + +public class DelimiterDecoder extends ProtocolDecoderAdapter { + protected final Logger logger; + protected final Logger errLogger; + + public static final int MAX_PAYLOAD_SIZE = 25 * 1024 * 1024; // 25MB + + private static final String DECODER_STATE_KEY = DelimiterDecoder.class.getName() + ".STATE"; + + private enum State { + STATE_HEADER_READ, STATE_PAYLOAD_READ; + } + + private static class CodecState { + State state = State.STATE_HEADER_READ; + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public DelimiterDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @SuppressWarnings("static-access") + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + byte[] delimiter = HexUtil.string2Hex(context.getDelimiter()); + codecState.buffer.limit(delimiter.length); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + StringBuilder sb = new StringBuilder(); + sb.append("DelimiterDecoder"); + if (codecState.state == State.STATE_PAYLOAD_READ) { + sb.append("(" + codecState.payloadSize + ")"); + } + sb.append(" | decode : " + CommonLib.hexDump(in, context)); + logger.debug(sb.toString()); + adapter.addRecentRecvTrace(session, sb.toString()); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + /** + * payload size < 0 인 경우 + */ + if (codecState.payloadSize < 0) { + throw new EAIException("RECEAINNA008", context.getAdapterName() + + " (" + context.getLlFieldType() + "," + context.getLlFieldOffset() + "," + context.getLlFieldLength() + + ") | when read header, ll length field is invalid | " + CommonLib.hexDump(codecState.buffer, context)); + } + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + byte[] delimiter = HexUtil.string2Hex(context.getDelimiter()); + + codecState.buffer.position(0).limit(delimiter.length); + + //by short11 + //polling.role 이 Server 가 sender일 경우 오류가 있었음 + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + default : + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.payloadSize = 0; + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + byte[] delimiter = HexUtil.string2Hex(context.getDelimiter()); + + if (delimiter.length >1 ){ + ByteMessage dst = new ByteMessage(); + int position = codecState.buffer.position(); + for(int i=delimiter.length-1;i >0;i--){ + dst.append(codecState.buffer.position(position-i).get()); + } + while(in.hasRemaining()){ + byte b = in.get(); + dst.append(b); + if (Arrays.equals(dst.getBytes(), delimiter)){ + codecState.buffer.put(b); + int lposition = codecState.buffer.position(); + codecState.buffer.limit(lposition - delimiter.length); + return true; + }else{ + codecState.buffer.put(b); + } + dst =dst.exclude(0, 1); + } + }else{ + while(in.hasRemaining()){ + byte b = in.get(); + if (b == delimiter[0]){ + return true; + }else{ + codecState.buffer.put(b); + } + } + } + return false; + + } + + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/codec/DelimiterEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/codec/DelimiterEncoder.java new file mode 100644 index 0000000..1492703 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/delimiter/codec/DelimiterEncoder.java @@ -0,0 +1,69 @@ +package com.eactive.eai.adapter.socket2.protocol.delimiter.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.HexUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class DelimiterEncoder implements ProtocolEncoder { + final protected Logger logger; + final protected Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public DelimiterEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + byte[] delimiter = HexUtil.string2Hex(context.getDelimiter()); + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate( length + delimiter.length ).limit( length + delimiter.length ); + buffer.put(m.getBytes()); + buffer.put(delimiter); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | DelimiterEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "DelimiterEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + out.flush(); + } + + public void dispose(IoSession session) throws Exception { + } + + + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesClientFilter.java new file mode 100644 index 0000000..e19e3b6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesClientFilter.java @@ -0,0 +1,66 @@ +package com.eactive.eai.adapter.socket2.protocol.des.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + +import javax.crypto.spec.SecretKeySpec; + + +public class DesClientFilter extends DesFilter { + public DesClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + // empty + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { + case STATE_HANDSHAKE: + /** + * read secret key + */ + /* + ByteArrayInputStream bis = new ByteArrayInputStream(m.getBytes()); + ObjectInputStream ois = new ObjectInputStream(bis); + filterState.secretKey = (SecretKey) ois.readObject(); + ois.close(); + */ + filterState.secretKey = new SecretKeySpec(m.getBytes(), "DES"); + + /** + * change state + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + nextFilter.sessionOpened(session); + break; + + case STATE_MESSAGE: + DesCodec des = new DesCodec(filterState.secretKey); + byte[] decrypted = des.decrypt(m.getBytes()); + m = new ByteMessage(decrypted); + + ///* + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | DesClientFilter | after decrypt : " + m.hexDump()); + } + //*/ + + nextFilter.messageReceived(session, m); + break; + + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesCodec.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesCodec.java new file mode 100644 index 0000000..0a05b72 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesCodec.java @@ -0,0 +1,64 @@ +package com.eactive.eai.adapter.socket2.protocol.des.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.common.util.Logger; + +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.SecretKey; + +public class DesCodec { + Cipher ecipher; + Cipher dcipher; + private Logger logger = SocketLoggerManager.getInstance().getLogger(); + private static final String DES_CIPER = "DES"; + public DesCodec(SecretKey key) { + try { + ecipher = Cipher.getInstance(DES_CIPER); + dcipher = Cipher.getInstance(DES_CIPER); + ecipher.init(Cipher.ENCRYPT_MODE, key); + dcipher.init(Cipher.DECRYPT_MODE, key); + } catch (javax.crypto.NoSuchPaddingException e) { + logger.info("NoSuchPaddingException"+ e.toString()); + } catch (java.security.NoSuchAlgorithmException e) { + logger.info("NoSuchAlgorithmException"+ e.toString()); + } catch (java.security.InvalidKeyException e) { + logger.info("InvalidKeyException"+ e.toString()); + } + } + + public byte[] encrypt(byte[] utf8) { + try { + // Encode the string into bytes using utf-8 + //byte[] utf8 = str.getBytes("UTF8"); + // Encrypt +// byte[] enc = ecipher.doFinal(utf8); + // Encode bytes to base64 to get a string + //return new sun.misc.BASE64Encoder().encode(enc); + return ecipher.doFinal(utf8); + } catch (javax.crypto.BadPaddingException e) { + logger.info("BadPaddingException - "+ e.toString()); + } catch (IllegalBlockSizeException e) { + logger.info("IllegalBlockSizeException - "+ e.toString()); + } + return null; + } + + public byte[] decrypt(byte[] dec) { + try { + // Decode base64 to get bytes + //byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str); + + // Decrypt +// byte[] utf8 = dcipher.doFinal(dec); + // Decode using utf-8 +// return new String(utf8, "UTF8"); + return dcipher.doFinal(dec); + } catch (javax.crypto.BadPaddingException e) { + logger.info("BadPaddingException - "+ e.toString()); + } catch (IllegalBlockSizeException e) { + logger.info("IllegalBlockSizeException - "+ e.toString()); + } + return null; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesFilter.java new file mode 100644 index 0000000..89226c6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesFilter.java @@ -0,0 +1,108 @@ +package com.eactive.eai.adapter.socket2.protocol.des.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + +import javax.crypto.SecretKey; + + +public abstract class DesFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + + private static final String NEXT_FILTER = DesFilter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = DesFilter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + + protected enum State { + STATE_HANDSHAKE, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = State.STATE_HANDSHAKE; + public SecretKey secretKey = null; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected DesFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + if (parent.contains(DesFilter.class)) { + throw new IllegalStateException("A filter chain cannot contain more than one DesFilter."); + } + + IoSession session = parent.getSession(); + session.setAttribute(NEXT_FILTER, nextFilter); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + if (filterState.state == State.STATE_MESSAGE) { + ///* + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | DesFilter | filterWrite() " + m.hexDump()); + } + //*/ + + //key = KeyGenerator.getInstance("DES").generateKey(); + DesCodec des = new DesCodec(filterState.secretKey); + byte[] encrypted = des.encrypt(m.getBytes()); + m = new ByteMessage(encrypted); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | DesFilter | filterWrite() - after encrypt - " + m.hexDump()); + } + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesServerFilter.java new file mode 100644 index 0000000..2c27a61 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/des/handshake/DesServerFilter.java @@ -0,0 +1,70 @@ +package com.eactive.eai.adapter.socket2.protocol.des.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + +import javax.crypto.KeyGenerator; + + +public class DesServerFilter extends DesFilter { + public DesServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + /** + * create secret key + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + filterState.secretKey = KeyGenerator.getInstance("DES").generateKey(); + + /** + * send secret key + */ + /* + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos); + oos.writeObject(filterState.secretKey); + oos.close(); + WriteFuture future = session.write(new ByteMessage(bos.toByteArray())); + //future.join(context.getTimeout() * 60L); + */ + byte[] keyBytes = filterState.secretKey.getEncoded(); +// WriteFuture future = session.write(new ByteMessage(keyBytes)); + session.write(new ByteMessage(keyBytes)); + /** + * change state + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * next filter + */ + nextFilter.sessionOpened(session); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | DesServerFilter | messageReceived() " + m.hexDump()); + } + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + DesCodec des = new DesCodec(filterState.secretKey); + byte[] decrypted = des.decrypt(m.getBytes()); + m = new ByteMessage(decrypted); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | DesServerFilter | messageReceived() - after decrypt - " + m.hexDump()); + } + + /** + * next filter + */ + nextFilter.messageReceived(session, m); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/DynamicOffsetClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/DynamicOffsetClient.java new file mode 100644 index 0000000..15e229f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/DynamicOffsetClient.java @@ -0,0 +1,39 @@ +package com.eactive.eai.adapter.socket2.protocol.dynamicoffset; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.filter.polling.KFTCPollingFilter; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.dynamicoffset.codec.DynamicOffsetCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.ack.AckClientFilter; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.ChunkCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class DynamicOffsetClient extends TcpAdapterClient { + public DynamicOffsetClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new DynamicOffsetHandler(this); + + if ("NONE".equals(context.getLlFieldType())) { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new ChunkCodecFactory(this))); + } else { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new DynamicOffsetCodecFactory(this))); + } + + if ("Y".equals(context.getAckSupport())) { + config.getFilterChain().addAfter("codec", "ack", new AckClientFilter(this)); + } + + if (context.isPollingUse()) { + config.getFilterChain().addAfter("polling", "kftcPolling", new KFTCPollingFilter(this)); + config.getFilterChain().remove("polling"); + } + + } + + @Override + public Object sendMessage(Object message) throws EAIException { + return super.sendMessage(message); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/DynamicOffsetHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/DynamicOffsetHandler.java new file mode 100644 index 0000000..b8e2455 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/DynamicOffsetHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.dynamicoffset; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class DynamicOffsetHandler extends ProtocolHandler { + public DynamicOffsetHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/DynamicOffsetServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/DynamicOffsetServer.java new file mode 100644 index 0000000..736c7c2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/DynamicOffsetServer.java @@ -0,0 +1,32 @@ +package com.eactive.eai.adapter.socket2.protocol.dynamicoffset; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.filter.polling.KFTCPollingFilter; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.dynamicoffset.codec.DynamicOffsetCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.ack.AckServerFilter; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.ChunkCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class DynamicOffsetServer extends TcpAdapterServer { + public DynamicOffsetServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new DynamicOffsetHandler(this); + + if ("NONE".equals(context.getLlFieldType())) { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new ChunkCodecFactory(this))); + } else { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new DynamicOffsetCodecFactory(this))); + } + + if ("Y".equals(context.getAckSupport())) { + config.getFilterChain().addAfter("codec", "ack", new AckServerFilter(this)); + } + if (context.isPollingUse()) { + config.getFilterChain().addAfter("polling", "kftcPolling", new KFTCPollingFilter(this)); + config.getFilterChain().remove("polling"); + } + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/codec/DynamicOffsetCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/codec/DynamicOffsetCodecFactory.java new file mode 100644 index 0000000..9fba649 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/codec/DynamicOffsetCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.dynamicoffset.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class DynamicOffsetCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public DynamicOffsetCodecFactory(ISocketAdapter adapter) { + encoder = new DynamicOffsetEncoder(adapter); + decoder = new DynamicOffsetDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/codec/DynamicOffsetDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/codec/DynamicOffsetDecoder.java new file mode 100644 index 0000000..4711962 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/codec/DynamicOffsetDecoder.java @@ -0,0 +1,355 @@ +package com.eactive.eai.adapter.socket2.protocol.dynamicoffset.codec; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.util.ByteCharSequence; + +public class DynamicOffsetDecoder extends ProtocolDecoderAdapter { + protected final Logger logger; + protected final Logger errLogger; + + int hdrLength = 0;//패턴때문에 보정필요 + public static final int MAX_PAYLOAD_SIZE = 25 * 1024 * 1024; // 25MB + + private static final String ERROR_CODE = "RECEAINNA008"; + + private static final String DECODER_STATE_KEY = DynamicOffsetDecoder.class.getName() + ".STATE"; + + private enum State { + STATE_HEADER_READ, STATE_PAYLOAD_READ; + } + + private static class CodecState { + State state = State.STATE_HEADER_READ; + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + int offsetSize; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public DynamicOffsetDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @SuppressWarnings("static-access") + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(context.getLlFieldOffset() + context.getLlFieldLength() + hdrLength); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + StringBuilder sb = new StringBuilder(); + sb.append("DynamicOffsetDecoder"); + //sb.append(codecState.state); + if (codecState.state == State.STATE_PAYLOAD_READ) { + sb.append("(" + codecState.payloadSize + ")"); + } + sb.append(" | decode : " + CommonLib.hexDump(in, context)); + logger.debug(sb.toString()); + adapter.addRecentRecvTrace(session, sb.toString()); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + + /** + * payload size < 0 인 경우 + */ + if (codecState.payloadSize < 0) { + throw new EAIException(ERROR_CODE, context.getAdapterName() + +// " (" + context.getLlFieldType() + "," + context.getLlFieldOffset() + "," + context.getLlFieldLength() + + " (" + context.getLlFieldType() + "," + codecState.offsetSize + "," + context.getLlFieldLength() + + ") | when read header, ll length field is invalid | " + CommonLib.hexDump(codecState.buffer, context)); + /** + * payload size == 0 인 경우 + */ + } else if (codecState.payloadSize == 0) { + if (context.isSync()) { + throw new Exception(" payload size 0 (ping). 'SYNC' response type socket does not support ping(size 0) message."); + } + + //codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_INFO ) { + logger.info(context.getAdapterName() + " | payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + } + + /** + * header 값을 읽은 후 buffer의 position을 이동해 준다. + * 이 작업을 안해주면 무한루프에 빠질 수 있다. + * 예) 법원 공탁금 (_LAW_IN_SOC_AsS{...}) + */ + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength());//초기화 + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + break; + } + + /** + * ll.include = 'Y' - LL을 포함해서 넘긴다. + */ + if ("Y".equals(context.getLlInclude())) { + try { + codecState.buffer.position(context.getLlFieldOffset() + context.getLlFieldLength()) + .limit(codecState.payloadSize + context.getLlFieldLength()); +// if (codecState.offsetSize == context.getLlFieldOffset()){ //일반전문 +// codecState.buffer.position(codecState.offsetSize + context.getLlFieldLength() ) +// .limit(codecState.payloadSize + context.getLlFieldLength()); +// }else{//폴링전문 +// codecState.buffer.position(codecState.offsetSize +context.getLlFieldOffset() + context.getLlFieldLength() ) +// .limit(codecState.payloadSize + context.getLlFieldLength()); +// } + } catch(IllegalArgumentException e) { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); +// sb.append("offset=" + context.getLlFieldOffset() + context.getLlFieldLength()); + sb.append("offset=" + codecState.offsetSize + context.getLlFieldLength()); + sb.append(", limit=" + codecState.payloadSize + context.getLlFieldLength()); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA007"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + /** + * ll.include = 'N' - LL을 제외하고 넘긴다. + */ + } else { + try { + codecState.buffer.position(context.getLlFieldOffset()).limit(codecState.payloadSize); +// if (codecState.offsetSize == context.getLlFieldOffset()){ //일반전문 +// codecState.buffer.position(codecState.offsetSize).limit(codecState.payloadSize); +// }else{ +// codecState.buffer.position(codecState.offsetSize + context.getLlFieldOffset()).limit(codecState.payloadSize); +// } + } catch(IllegalArgumentException e) { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); +// sb.append("offset=" + context.getLlFieldOffset()); + sb.append("offset=" + codecState.offsetSize); + sb.append(", limit=" + codecState.payloadSize); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + } + + /** + * offset + ll 을 읽었고, 더 이상 읽을 것(payload)이 없는 경우 + * - ll.length value = ll.offset + ll.field.length + */ + if (codecState.buffer.position() == codecState.buffer.limit()) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength());//초기화 + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + break; + } + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); +// ByteMessage message = new ByteMessage(bytes); + ByteMessage message = null; + if (codecState.offsetSize == context.getLlFieldOffset()){ + message = removeData(new ByteMessage(bytes)); + }else{ + message = new ByteMessage(bytes); + } + + out.write(message); + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength());//limit 초기화 + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read header : " + in); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + //offsetSize 를 가져온다. + codecState.offsetSize = getPatternOffset(codecState); + if ("CHAR".equals(context.getLlFieldType())) { + codecState.buffer.flip(); + try { + byte[] header = new byte[context.getLlFieldLength()]; + for (int i=0; i MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + MAX_PAYLOAD_SIZE + ") exceeded : " + + codecState.payloadSize + " | " + + CommonLib.hexDump(codecState.buffer, context)); + } + + /** + * ll.field.include = 'Y' - 헤더 길이를 빼 준다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + codecState.payloadSize = codecState.payloadSize - context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 더해서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { +// codecState.payloadSize = codecState.payloadSize + context.getLlFieldOffset(); + codecState.payloadSize = codecState.payloadSize + codecState.offsetSize; + } + + /** + * ll.length.adjust = 200 - 공통부 header 길이를 더한다. (한은망 평문 테스트용) + */ + if (context.getLlLenAdjust() != 0) { + codecState.payloadSize = codecState.payloadSize + context.getLlLenAdjust(); + } + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read payload : " + in); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } + private int getPatternOffset(CodecState codecState){ + int offset = 0; + + byte[] data = new byte[codecState.buffer.limit()]; + codecState.buffer.flip(); + codecState.buffer.get(data); + + String dynamicOffsetPattern = context.getDynamicOffsetPattern().trim(); + Matcher matcher = Pattern.compile(dynamicOffsetPattern).matcher(new ByteCharSequence(data)); + if(matcher.find()){ + offset = matcher.start(); + }else{ + offset = context.getLlFieldOffset(); + } + return offset; + } + private ByteMessage removeData(ByteMessage m) throws Exception{ + ByteMessage mm = null ; + + /** + * removedata.rule + */ + if (!"".equals(context.getDataRemoveRule())) { + Matcher matcher = Pattern.compile("\\[([ ]*[0-9]+)[ ]*,([ ]*[0-9]+)[ ]*\\][ ]*").matcher(context.getDataRemoveRule().trim()); + + if (matcher.find()) { + int offset = Integer.parseInt(matcher.group(1).trim()); + int length = Integer.parseInt(matcher.group(2).trim()); + mm = (new ByteMessage()) + .append(m.getBytes(0, offset)) + .append(m.getBytes(offset + length)); + } + else { + throw new Exception(context.getAdapterName() + " | data.remove.rule format is invalid : " + context.getDataRemoveRule()); + } + } + return mm; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/codec/DynamicOffsetEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/codec/DynamicOffsetEncoder.java new file mode 100644 index 0000000..d687926 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/dynamicoffset/codec/DynamicOffsetEncoder.java @@ -0,0 +1,175 @@ +package com.eactive.eai.adapter.socket2.protocol.dynamicoffset.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.util.ByteCharSequence; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class DynamicOffsetEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public DynamicOffsetEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + int offset = getPatternOffset(m.getBytes()); + if (offset == context.getLlFieldOffset()){ + m = addData(m); + } + + if(m == null) { + throw new Exception("ByteMessage cannot NULL."); + } + /** + * ll.include = 'Y' - 통째로 보낸다. + */ + if ("Y".equals(context.getLlInclude())) { + ByteBuffer buffer = ByteBuffer.allocate(m.size() - context.getLlFieldLength()); +// buffer.put(m.getBytes(0, context.getLlFieldOffset())); +// buffer.put(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + buffer.put(m.getBytes(0, offset)); + buffer.put(m.getBytes(offset + context.getLlFieldLength())); + buffer.flip(); + m.setByteBuffer(buffer); + } + + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate(context.getLlFieldLength() + length).limit(context.getLlFieldLength() + length); + + /** + * ll.field.include = 'Y' - header 길이 포함하여 ll 을 계산한다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + length = length + context.getLlFieldLength(); + } + + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 빼서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { +// length = length - context.getLlFieldOffset(); + length = length - offset; + } + + /** + * ll.length.adjust = 200 - 공통부 header 길이를 더한다. (한은망 평문 테스트용) + */ + if (context.getLlLenAdjust() != 0) { + length = length + context.getLlLenAdjust(); + } + + + /** + * [1] before-payload + */ +// buffer.put(m.getBytes(0, context.getLlFieldOffset())); + buffer.put(m.getBytes(0, offset)); + + /** + * [2] write header + */ + if ("CHAR".equals(context.getLlFieldType())) { + String lenStr = CommonLib.getFormatString(length, context.getLlFieldLength()); + buffer.put(lenStr.getBytes()); + } + + /** + * [3] after-payload + */ +// buffer.put(m.getBytes(context.getLlFieldOffset(), m.getBytes().length - context.getLlFieldOffset())); + buffer.put(m.getBytes(offset, m.getBytes().length - offset)); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | FixedHeaderEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "FixedHeaderEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + out.flush(); + } + + public void dispose(IoSession session) throws Exception { + // empty + } + private int getPatternOffset(byte[] data){ + int offset = 0; + + String dynamicOffsetPattern = context.getDynamicOffsetPattern().trim(); + Matcher matcher = Pattern.compile(dynamicOffsetPattern).matcher(new ByteCharSequence(data)); + if(matcher.find()){ + offset = matcher.start(); + }else{ + offset = context.getLlFieldOffset(); + } + return offset; + } + private ByteMessage addData(ByteMessage m) throws Exception{ + ByteMessage mm = null ; + + /** + * adddata.rule + */ + if (!"".equals(context.getDataAddRule())) { + Matcher matcher = Pattern.compile("\\[([ ]*[0-9]+)[ ]*,([ ]*[0-9]+)[ ]*\\][ ]*=[ ]*(.+)").matcher(context.getDataAddRule().trim()); + if (matcher.find()) { + int offset = Integer.parseInt(matcher.group(1).trim()); + int length = Integer.parseInt(matcher.group(2).trim()); + String re = matcher.group(3).trim(); + if (re != null && length != re.length()){ + re = StringUtil.stringFormat(re, false, ' ', length); + } + if (re != null){ + mm = (new ByteMessage()) + .append(m.getBytes(0, offset)) + .append(re.getBytes()) + .append(m.getBytes(offset)); + + } + } else { + throw new Exception(context.getAdapterName() + " | data.add.rule format is invalid : " + context.getDataAddRule()); + } + } + return mm; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/echo/EchoClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/echo/EchoClient.java new file mode 100644 index 0000000..50c681a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/echo/EchoClient.java @@ -0,0 +1,12 @@ +package com.eactive.eai.adapter.socket2.protocol.echo; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; + + +public class EchoClient extends TcpAdapterClient { + public EchoClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new EchoProtocolHandler(this); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/echo/EchoProtocolHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/echo/EchoProtocolHandler.java new file mode 100644 index 0000000..2ef423f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/echo/EchoProtocolHandler.java @@ -0,0 +1,63 @@ +package com.eactive.eai.adapter.socket2.protocol.echo; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; + + +public class EchoProtocolHandler extends ProtocolHandler { + public EchoProtocolHandler(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void messageReceived(IoSession session, Object message) throws Exception { + if (!(message instanceof ByteBuffer)) { + return; + } + + ByteBuffer rb = (ByteBuffer) message; + + synchronized(this) { + messageRecv++; + } + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | : " + CommonLib.hexDump(rb, context)); + } + + if (!context.isSync()) { + return; + } + + ByteBuffer wb = ByteBuffer.allocate(rb.remaining()); + wb.put(rb); + wb.flip(); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | : " + CommonLib.hexDump(wb, context)); + } + + session.write(wb).join(); + + synchronized(this) { + messageSend++; + } + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + if (message instanceof byte[]) { + logger.debug(context.getAdapterName() + " | " + CommonLib.hexDump((byte[]) message, true, context)); + adapter.addRecentSend(session, CommonLib.hexDump((byte[]) message, true, context )); + } else if (message instanceof String) { + logger.debug(context.getAdapterName() + " | " + CommonLib.hexDump(((String) message).getBytes(), true, context)); + adapter.addRecentSend(session, message.toString()); + } else { + logger.debug(context.getAdapterName() + " | " + message); + adapter.addRecentSend(session, message.toString()); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/echo/EchoServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/echo/EchoServer.java new file mode 100644 index 0000000..6b41f2c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/echo/EchoServer.java @@ -0,0 +1,12 @@ +package com.eactive.eai.adapter.socket2.protocol.echo; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; + +public class EchoServer extends TcpAdapterServer { + + public EchoServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new EchoProtocolHandler(this); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/EnvelopClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/EnvelopClient.java new file mode 100644 index 0000000..e2d1e07 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/EnvelopClient.java @@ -0,0 +1,18 @@ +package com.eactive.eai.adapter.socket2.protocol.envelop; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.envelop.handshake.EnvelopClientFilter; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class EnvelopClient extends TcpAdapterClient { + + public EnvelopClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new EnvelopHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "envelop-client", new EnvelopClientFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/EnvelopHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/EnvelopHandler.java new file mode 100644 index 0000000..ba5739e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/EnvelopHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.envelop; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class EnvelopHandler extends ProtocolHandler { + public EnvelopHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/EnvelopServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/EnvelopServer.java new file mode 100644 index 0000000..1fa8bb0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/EnvelopServer.java @@ -0,0 +1,18 @@ +package com.eactive.eai.adapter.socket2.protocol.envelop; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.envelop.handshake.EnvelopServerFilter; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class EnvelopServer extends TcpAdapterServer { + public EnvelopServer(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new EnvelopHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "ENVELOP.SERVER", new EnvelopServerFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/handshake/EnvelopClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/handshake/EnvelopClientFilter.java new file mode 100644 index 0000000..68ddd1e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/handshake/EnvelopClientFilter.java @@ -0,0 +1,171 @@ +package com.eactive.eai.adapter.socket2.protocol.envelop.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import com.sf.xc.XCException; +import com.sf.xc.XCUtil; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + + +public class EnvelopClientFilter extends IoFilterAdapter { + + protected final Logger logger; + protected final Logger errLogger; + + private static final String NEXT_FILTER = EnvelopClientFilter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = EnvelopClientFilter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + + protected enum State { + STATE_HANDSHAKE, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = State.STATE_MESSAGE; //State.STATE_HANDSHAKE; + public byte[] userKey = new byte[16]; + public int[] roundKey = new int[32]; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + public EnvelopClientFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + if (parent.contains(EnvelopClientFilter.class)) { + throw new IllegalStateException("A filter chain cannot contain more than one DesFilter."); + } + + IoSession session = parent.getSession(); + session.setAttribute(NEXT_FILTER, nextFilter); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + /** + * EnvelopClient init + */ + try { + byte[] cert = XCUtil.readFile("modules/envelop/cert/signCert.der"); +// XCE2EClient client = new XCE2EClient(cert); + +// session.setAttribute("ENVELOP.CLIENT", client); + } catch(Exception e) { + logger.warn("ENVELOP.CLIENT set error", e); + } + + nextFilter.sessionOpened(session); + + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | Envelop init error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | Envelop init error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | Envelop init error - " + e.getMessage(), e); + + try { + adapter.getSessionPool().remove(session); + session.close(); + } catch(Exception ignor) { + logger.warn("session.close error", e); + } + + throw new Exception(context.getAdapterName() + " | Envelop init error - " + e.getMessage()); + } + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { + case STATE_MESSAGE: + /** + * decrypt + */ +// byte[] decrypted = EnvelopCodec.e2eClientDecrypt(m.getBytes(), session); +// if (decrypted == null || decrypted.length == 0) { +// throw new Exception("received message is invalid - check if message is encrypted : " + m.hexDump()); +// } +// m.setBytes(decrypted); + + /** + * next filter + */ + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m.hexDump()); + } + } + + @SuppressWarnings("static-access") + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = null; + + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | EnvelopFilter | " + filterState.state.toString() + " | " + m.hexDump()); + } + + try { + +// m = EnvelopCodec.e2eClientEncrypt(m.getBytes(), session); + + } catch(Exception xce) { + adapter.addRecentError(context.getAdapterName() + " | envelop error - " + xce.getMessage(), xce); + logger.error(context.getAdapterName() + " | envelop error - " + xce.getMessage(), xce); + errLogger.error(context.getAdapterName() + " | envelop error - " + xce.getMessage(), xce); + throw new XCException(context.getAdapterName() + " | envelop error - " + xce.getMessage()); + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/handshake/EnvelopCodec.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/handshake/EnvelopCodec.java new file mode 100644 index 0000000..5c8eab3 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/handshake/EnvelopCodec.java @@ -0,0 +1,32 @@ +package com.eactive.eai.adapter.socket2.protocol.envelop.handshake;//package com.eactive.eai.adapter.socket2.protocol.envelop.handshake; +// +//import org.apache.mina.common.IoSession; +// +//import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +//import com.sf.xc.XCE2EClient; +//import com.sf.xc.XCE2EServer; +// +//public class EnvelopCodec { +// public static ByteMessage e2eServerEncrypt(byte[] bytes, IoSession session) throws Exception { +// +// XCE2EServer server = (XCE2EServer) session.getAttribute("ENVELOP.SERVER"); +// return (new ByteMessage(server.encryptServer(bytes))); +// } +// +// public static byte[] e2eServerDecrypt(byte[] bytes, IoSession session) throws Exception { +// +// XCE2EServer server = (XCE2EServer) session.getAttribute("ENVELOP.SERVER"); +// return (server.decryptServer(bytes)); +// } +// public static ByteMessage e2eClientEncrypt(byte[] bytes, IoSession session) throws Exception { +// +// XCE2EClient client = (XCE2EClient) session.getAttribute("ENVELOP.CLIENT"); +// return (new ByteMessage(client.encryptClient(bytes))); +// } +// +// public static byte[] e2eClientDecrypt(byte[] bytes, IoSession session) throws Exception { +// +// XCE2EClient client = (XCE2EClient) session.getAttribute("ENVELOP.CLIENT"); +// return (client.decryptClient(bytes)); +// } +//} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/handshake/EnvelopServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/handshake/EnvelopServerFilter.java new file mode 100644 index 0000000..88d6cda --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/envelop/handshake/EnvelopServerFilter.java @@ -0,0 +1,192 @@ +package com.eactive.eai.adapter.socket2.protocol.envelop.handshake; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import com.sf.xc.XCException; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + + +public class EnvelopServerFilter extends IoFilterAdapter { + + protected final Logger logger; + protected final Logger errLogger; + + private static final String NEXT_FILTER = EnvelopServerFilter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = EnvelopServerFilter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + + protected enum State { + STATE_HANDSHAKE, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = State.STATE_MESSAGE; //State.STATE_HANDSHAKE; + public byte[] userKey = new byte[16]; + public int[] roundKey = new int[32]; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + public EnvelopServerFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + if (parent.contains(EnvelopServerFilter.class)) { + throw new IllegalStateException("A filter chain cannot contain more than one DesFilter."); + } + + IoSession session = parent.getSession(); + session.setAttribute(NEXT_FILTER, nextFilter); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + /** + * EnvelopServer init + */ +// XCE2EServer server = new XCE2EServer(context.getEnvelopSigncertPath(),context.getEnvelopSignkeyPath(),context.getEnvelopPassword()); +// +// session.setAttribute("ENVELOP.SERVER", server); +// +// nextFilter.sessionOpened(session); + + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | Envelop init error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | Envelop init error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | Envelop init error - " + e.getMessage(), e); + + try { + adapter.getSessionPool().remove(session); + session.close(); + } catch(Exception ignor) { + logger.warn(context.getAdapterName() + " session close errir ", e); + } + + throw new Exception(context.getAdapterName() + " | Envelop init error - " + e.getMessage()); + } + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { + case STATE_MESSAGE: + /** + * decrypt + */ +// byte[] decrypted = EnvelopCodec.e2eServerDecrypt(m.getBytes(), session); +// if (decrypted == null || decrypted.length == 0) { +// throw new Exception("received message is invalid - check if message is encrypted : " + m.hexDump()); +// } +// m.setBytes(decrypted); + + /** + * next filter + */ + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m.hexDump()); + } + } + + @SuppressWarnings("static-access") + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = null; + + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | EnvelopFilter | " + filterState.state.toString() + " | " + m.hexDump()); + } + + try { + /** + * check polling message - skip polling + */ + if (!context.isPollingUse() || !isPollingPattern(m)) { + + filterState.state = State.STATE_MESSAGE; + session.setAttribute(FILTER_STATE_KEY, filterState); + + /** + * encrypt + */ +// m = EnvelopCodec.e2eServerEncrypt(m.getBytes(), session); + + } + + } catch(Exception xce) { + adapter.addRecentError(context.getAdapterName() + " | envelop error - " + xce.getMessage(), xce); + logger.error(context.getAdapterName() + " | envelop error - " + xce.getMessage(), xce); + errLogger.error(context.getAdapterName() + " | envelop error - " + xce.getMessage(), xce); + throw new XCException(context.getAdapterName() + " | envelop error - " + xce.getMessage()); + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + private boolean isPollingPattern(ByteMessage m) throws EAIException { + ByteMessage bm = m; + if ("Y".equals(context.getLlInclude())) { + bm = (new ByteMessage()) + .append(m.getBytes(0, context.getLlFieldOffset())) + .append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + } + + if ((context.isPollingReceiver() && bm.getString().matches(context.getPollingResponsePattern())) + || (context.isPollingSender() && bm.getString().matches(context.getPollingRequestPattern()))) + return true; + + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderBlockingHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderBlockingHandler.java new file mode 100644 index 0000000..2897a51 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderBlockingHandler.java @@ -0,0 +1,256 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.SocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderDecoder; +import com.eactive.eai.common.util.Logger; + +import java.io.*; +import java.net.Socket; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class FixedHeaderBlockingHandler { + @SuppressWarnings("static-access") + static public byte[] sendMessage(SocketAdapter adapter, Object request) throws Exception { + SocketAdapterContext context = adapter.getContext(); + Logger logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + + byte[] m = null; + if (request instanceof byte[]) { + m = (byte[]) request; + } else if (request instanceof String) { + m = ((String) request).getBytes(); + } + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | " + CommonLib.hexDump(m, true, context)); + adapter.addRecentSend(null, CommonLib.hexDump(m, true, context)); + } + + Socket socket = null; + InputStream is = null; + OutputStream os = null; + + // System.out.println(Thread.currentThread().getName() + + // " ### before get | semaphore + " + + // context.getMaxConnSemaphore().availablePermits()); + boolean success = context.getMaxConnSemaphore().tryAcquire(context.getTimeout(), + TimeUnit.SECONDS); + if (!success) { + throw new TimeoutException("connot get max conn semaphore - " + + context.getMaxConnection()); + } + + try { + socket = new Socket(context.getHostName(), context.getPortNumber()); + socket.setSoTimeout(context.getTimeout() * 1000); + is = new BufferedInputStream(socket.getInputStream()); + os = new BufferedOutputStream(socket.getOutputStream()); + os.write(encode(context, m)); + os.flush(); + adapter.incMessageSend(); + + byte[] response = decode(context, m, socket, is); + adapter.incMessageRecv(); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | " + CommonLib.hexDump(response, true, context)); + adapter.addRecentRecv(null, CommonLib.hexDump(response, true, context)); + } + + return response; + } finally { + if (is != null) + try { + is.close(); + } catch (Exception e) { + } + if (os != null) + try { + os.close(); + } catch (Exception e) { + } + if (socket != null) + try { + socket.close(); + } catch (Exception e) { + } + context.getMaxConnSemaphore().release(); + // System.out.println(Thread.currentThread().getName() + + // " ### after release | semaphore - " + + // context.getMaxConnSemaphore().availablePermits()); + } + } + + @SuppressWarnings("static-access") + static private byte[] encode(SocketAdapterContext context, byte[] request) throws Exception { + Logger logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + + ByteMessage m = new ByteMessage(request); + ByteMessage result = new ByteMessage(); + + /** + * ll.include = 'Y' - 통째로 보낸다. + */ + if ("Y".equals(context.getLlInclude())) { + ByteMessage temp = new ByteMessage(); + temp.append(m.getBytes(0, context.getLlFieldOffset())); + temp.append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + m = temp; + } + + int length = m.size(); + + /** + * ll.field.include = 'Y' - header 길이 포함하여 ll 을 계산한다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + length = length + context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 빼서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + length = length - context.getLlFieldOffset(); + } + + /** + * [1] before-payload + */ + result.append(m.getBytes(0, context.getLlFieldOffset())); + + /** + * [2] write header + */ + byte[] header = null; + if ("BIN".equals(context.getLlFieldType())) { + int tmpLength = length; + header = new byte[context.getLlFieldLength()]; + for (int i = context.getLlFieldLength() - 1; i >= 0; i--) { + header[i] = (byte) (tmpLength % 256); + tmpLength = tmpLength / 256; + } + } else { // "CHAR" + String lenStr = CommonLib.getFormatString(length, context.getLlFieldLength()); + header = lenStr.getBytes(); + } + result.append(header); + + /** + * [3] after-payload + */ + result.append(m.getBytes(context.getLlFieldOffset(), m.getBytes().length + - context.getLlFieldOffset())); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | FixedHeaderEncoder(Blocking) | encode : " + + result.hexDump()); + } + return result.getBytes(); + } + + @SuppressWarnings("static-access") + static private byte[] decode(SocketAdapterContext context, byte[] request, Socket socket, + InputStream is) throws Exception { + Logger logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + + ByteMessage result = new ByteMessage(); + + byte[] offsetPlusHeader = new byte[context.getLlFieldOffset() + context.getLlFieldLength()]; + int read = is.read(offsetPlusHeader); + if (read == -1) { + throw new IOException("socket is closed by peer - " + + socket.getLocalAddress().getHostName() + ":" + socket.getLocalPort() + "->" + + context.getHostName() + ":" + socket.getPort()); + } + + int payloadSize = 0; + if ("BIN".equals(context.getLlFieldType())) { + for (int i = 0; i < context.getLlFieldLength(); i++) { + payloadSize += ((int) offsetPlusHeader[context.getLlFieldOffset() + i] & 0xFF) + * Math.pow(256, context.getLlFieldLength() - i - 1); + } + } else { + try { + byte[] header = new byte[context.getLlFieldLength()]; + for (int i = 0; i < context.getLlFieldLength(); i++) { + header[i] = offsetPlusHeader[context.getLlFieldOffset() + i]; + } + payloadSize = Integer.parseInt(new String(header)); + } catch (NumberFormatException e) { +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA008"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA008"); + throw new EAIException("RECEAINNA008", context.getAdapterName() + " (" + + context.getLlFieldType() + "," + context.getLlFieldOffset() + "," + + context.getLlFieldLength() + + ") | when read header, number format is invalid - " + e.getMessage() + + " | " + CommonLib.hexDump(offsetPlusHeader, true, context)); + } + } + + if (payloadSize > FixedHeaderDecoder.MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + FixedHeaderDecoder.MAX_PAYLOAD_SIZE + + ") exceeded : " + payloadSize); + } + + /** + * ll.field.include = 'Y' - 헤더 길이를 빼 준다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + payloadSize = payloadSize - context.getLlFieldLength(); // - + // context. + // getLlFieldOffset + // (); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 더해서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + payloadSize = payloadSize + context.getLlFieldOffset(); + } + + /** + * ll.field.include = 'Y' - 헤더 길이를 빼 준다. + */ + if ("Y".equals(context.getLlInclude())) { + result.append(offsetPlusHeader); + } else { + result.append((new ByteMessage(offsetPlusHeader)).getBytes(0, context + .getLlFieldOffset())); + } + + byte[] remaining = readPayload(is, payloadSize - context.getLlFieldOffset()); + result.append(remaining); + + ByteMessage full = (new ByteMessage(offsetPlusHeader)).append(remaining); + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | FixedHeaderDecoder(Blocking) | decode : " + + full.hexDump()); + } + + return result.getBytes(); + } + + private static byte[] readPayload(InputStream in, int total) throws Exception { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + int amt = 0; + byte[] buf = new byte[2048]; + while (amt < total) { + int n = in.read(buf, 0, total-amt<2048 ? total-amt : 2048); + if (n == -1) { + break; + } + amt += n; + bos.write(buf, 0, n); + } + bos.flush(); + return bos.toByteArray(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderClient.java new file mode 100644 index 0000000..5160bb2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderClient.java @@ -0,0 +1,43 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.ack.AckClientFilter; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.ChunkCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class FixedHeaderClient extends TcpAdapterClient { + public FixedHeaderClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new FixedHeaderHandler(this); + + if ("NONE".equals(context.getLlFieldType())) { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new ChunkCodecFactory(this))); + } else { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + } + + if ("Y".equals(context.getAckSupport())) { + config.getFilterChain().addAfter("codec", "ack", new AckClientFilter(this)); + } + } + + public Object sendMessage(Object message) throws EAIException { + if (context.isClient() + && "FIXED_LENGTH_HEADER".equals(context.getProtocol()) + && context.isSync() + && !context.isPermanent() + && context.isBlocking()) { + try { + return FixedHeaderBlockingHandler.sendMessage(this, message); + } catch(Exception e) { + throw new EAIException(e); + } + } else { + return super.sendMessage(message); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderHandler.java new file mode 100644 index 0000000..45b96cd --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class FixedHeaderHandler extends ProtocolHandler { + public FixedHeaderHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderServer.java new file mode 100644 index 0000000..e4aa47e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/FixedHeaderServer.java @@ -0,0 +1,26 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.ack.AckServerFilter; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.ChunkCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class FixedHeaderServer extends TcpAdapterServer { + public FixedHeaderServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new FixedHeaderHandler(this); + + if ("NONE".equals(context.getLlFieldType())) { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new ChunkCodecFactory(this))); + } else { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + } + + if ("Y".equals(context.getAckSupport())) { + config.getFilterChain().addAfter("codec", "ack", new AckServerFilter(this)); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/ack/AckClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/ack/AckClientFilter.java new file mode 100644 index 0000000..ff29588 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/ack/AckClientFilter.java @@ -0,0 +1,81 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader.ack; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + + +public class AckClientFilter extends AckFilter { + public AckClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + +// WriteFuture future = session.write(new ByteMessage(context.getResponseType())); + session.write(new ByteMessage(context.getResponseType())); + //future.join(context.getTimeout() * 1000L); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | AckClientFilter | " + context.getResponseType()); + } + + filterState.state = State.STATE_HANDSHAKE_CLIENT_WAIT_HELLO_ACK; + setSessionState(session, filterState.state.toString()); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { + case STATE_HANDSHAKE_CLIENT_WAIT_HELLO_ACK: + if (!"ACK".equals(m.getString())) { + throw new Exception("expected 'ACK' when handshaking, but received : " + m.getString()); + } + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | AckClientFilter | HELLO ACK : " + m.hexDump()); + } + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + break; + + case STATE_WAIT_ACK: + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | AckClientFilter | ACK : " + m); + } + if (!"ACK".equals(m.getString())) { + throw new Exception("expected 'ACK', but encounterred : " + m.getString()); + } + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_SEND_ACK: + case STATE_MESSAGE: + ///* + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | AckClientFilter | : " + m.hexDump()); + } + //*/ + sendAckMessage(session); + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + nextFilter.messageReceived(session, message); + break; + + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/ack/AckFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/ack/AckFilter.java new file mode 100644 index 0000000..02cf795 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/ack/AckFilter.java @@ -0,0 +1,104 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader.ack; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + + +abstract public class AckFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + + protected static final String FILTER_STATE_KEY = AckFilter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + + protected static enum State { + STATE_HANDSHAKE_SERVER_WAIT_HELLO, + STATE_HANDSHAKE_CLIENT_WAIT_HELLO_ACK, + STATE_WAIT_ACK, + STATE_SEND_ACK, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = null; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + public AckFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + if (parent.contains(AckFilter.class)) { + throw new IllegalStateException("A filter chain cannot contain more than one AckFilter."); + } + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + } + + @Override + public void messageSent(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + ByteMessage m = null; + + if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else { + throw new Exception("Unknown data format"); + } + + if (filterState.state == State.STATE_MESSAGE && m.size() != 3 && !"ACK".equals(m.getString())) { + filterState.state = State.STATE_WAIT_ACK; + setSessionState(session, filterState.state.toString()); + } + } + + protected void sendAckMessage(IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | ACK "); + } + + filterState.state = State.STATE_SEND_ACK; + setSessionState(session, filterState.state.toString()); + +// WriteFuture future = session.write("ACK"); + session.write("ACK"); + //future.join(context.getTimeout() * 1000L); + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/ack/AckServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/ack/AckServerFilter.java new file mode 100644 index 0000000..0af7977 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/ack/AckServerFilter.java @@ -0,0 +1,81 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader.ack; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + + +public class AckServerFilter extends AckFilter { + public AckServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + filterState.state = State.STATE_HANDSHAKE_SERVER_WAIT_HELLO; + setSessionState(session, filterState.state.toString()); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { + case STATE_HANDSHAKE_SERVER_WAIT_HELLO: + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | AckServerFilter | HELLO : " + m); + } + if (m.getString().equals(context.getResponseType())) { + sendAckMessage(session); + } else { +// WriteFuture future = session.write(new ByteMessage("NACK PROTOCOL VIOLATION")); + session.write(new ByteMessage("NACK PROTOCOL VIOLATION")); + //future.join(context.getTimeout() * 1000L); + adapter.getSessionPool().remove(session); + session.close(); + throw new Exception("invalid handshake message. close connection"); + } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_WAIT_ACK: + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | AckServerFilter | ACK : " + m); + } + if (!"ACK".equals(m.getString())) { + throw new Exception("expected 'ACK', but encounterred : " + m.getString()); + } + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_SEND_ACK: + case STATE_MESSAGE: + ///* + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | AckServerFilter | : " + m.hexDump()); + } + //*/ + sendAckMessage(session); + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + nextFilter.messageReceived(session, message); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/ChunkCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/ChunkCodecFactory.java new file mode 100644 index 0000000..e28d82b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/ChunkCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class ChunkCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public ChunkCodecFactory(ISocketAdapter adapter) { + encoder = new ChunkEncoder(adapter); + decoder = new ChunkDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/ChunkDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/ChunkDecoder.java new file mode 100644 index 0000000..0758ab9 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/ChunkDecoder.java @@ -0,0 +1,76 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +public class ChunkDecoder extends ProtocolDecoderAdapter { + final protected Logger logger; + final protected Logger errLogger; + + public static final int MAX_PAYLOAD_SIZE = 25 * 1024 * 1024; // 25MB + + private static final String DECODER_STATE_KEY = ChunkDecoder.class.getName() + ".STATE"; + + private static class CodecState { + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + //int payloadSize; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public ChunkDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | ChunkDecoder | decode : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "ChunkDecoder | decode : " + CommonLib.hexDump(in, context)); + } + + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(context.getRecvPayloadLength()); + //codecState.payloadSize = context.getPayloadLength(); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + codecState.buffer.limit(in.position()); + codecState.buffer.put(in); + + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/ChunkEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/ChunkEncoder.java new file mode 100644 index 0000000..371b8e5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/ChunkEncoder.java @@ -0,0 +1,63 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class ChunkEncoder implements ProtocolEncoder { + final protected Logger logger; + final protected Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public ChunkEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + ByteBuffer buffer = ByteBuffer.allocate(m.size()).limit(m.size()); + buffer.put(m.getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | ChunkEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "ChunkEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + public void dispose(IoSession session) throws Exception { + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/FixedHeaderCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/FixedHeaderCodecFactory.java new file mode 100644 index 0000000..4a89e28 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/FixedHeaderCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class FixedHeaderCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public FixedHeaderCodecFactory(ISocketAdapter adapter) { + encoder = new FixedHeaderEncoder(adapter); + decoder = new FixedHeaderDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/FixedHeaderDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/FixedHeaderDecoder.java new file mode 100644 index 0000000..029490c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/FixedHeaderDecoder.java @@ -0,0 +1,287 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader.codec; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +public class FixedHeaderDecoder extends ProtocolDecoderAdapter { + final protected Logger logger; + final protected Logger errLogger; + + public static final int MAX_PAYLOAD_SIZE = 25 * 1024 * 1024; // 25MB + + private static final String DECODER_STATE_KEY = FixedHeaderDecoder.class.getName() + ".STATE"; + + private static enum State { + STATE_HEADER_READ, STATE_PAYLOAD_READ; + } + + private static class CodecState { + State state = State.STATE_HEADER_READ; + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public FixedHeaderDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @SuppressWarnings("static-access") + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(context.getLlFieldOffset() + context.getLlFieldLength()); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + StringBuffer sb = new StringBuffer(); + sb.append("FixedHeaderDecoder"); + //sb.append(codecState.state); + if (codecState.state == State.STATE_PAYLOAD_READ) { + sb.append("(" + codecState.payloadSize + ")"); + } + sb.append(" | decode : " + CommonLib.hexDump(in, context)); + logger.debug(sb.toString()); + adapter.addRecentRecvTrace(session, sb.toString()); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + /** + * payload size < 0 인 경우 + */ + if (codecState.payloadSize < 0) { + throw new EAIException("RECEAINNA008", context.getAdapterName() + + " (" + context.getLlFieldType() + "," + context.getLlFieldOffset() + "," + context.getLlFieldLength() + + ") | when read header, ll length field is invalid | " + CommonLib.hexDump(codecState.buffer, context)); + /** + * payload size == 0 인 경우 + */ + } else if (codecState.payloadSize == 0) { + if (context.isSync()) { + throw new Exception(" payload size 0 (ping). 'SYNC' response type socket does not support ping(size 0) message."); + } + + //codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_INFO ) { + logger.info(context.getAdapterName() + " | payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + } + + /** + * header 값을 읽은 후 buffer의 position을 이동해 준다. + * 이 작업을 안해주면 무한루프에 빠질 수 있다. + * 예) 법원 공탁금 (_LAW_IN_SOC_AsS{...}) + */ + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + break; + } + + /** + * ll.include = 'Y' - LL을 포함해서 넘긴다. + */ + if ("Y".equals(context.getLlInclude())) { + try { + codecState.buffer.position(context.getLlFieldOffset() + context.getLlFieldLength()) + .limit(codecState.payloadSize + context.getLlFieldLength()); + } catch(IllegalArgumentException e) { + StringBuffer sb = new StringBuffer(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); + sb.append("offset=" + context.getLlFieldOffset() + context.getLlFieldLength()); + sb.append(", limit=" + codecState.payloadSize + context.getLlFieldLength()); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA007"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + /** + * ll.include = 'N' - LL을 제외하고 넘긴다. + */ + } else { + try { + codecState.buffer.position(context.getLlFieldOffset()).limit(codecState.payloadSize); + } catch(IllegalArgumentException e) { + StringBuffer sb = new StringBuffer(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); + sb.append("offset=" + context.getLlFieldOffset()); + sb.append(", limit=" + codecState.payloadSize); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + } + + /** + * offset + ll 을 읽었고, 더 이상 읽을 것(payload)이 없는 경우 + * - ll.length value = ll.offset + ll.field.length + */ + if (codecState.buffer.position() == codecState.buffer.limit()) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + break; + } + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read header : " + in); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + if ("BIN".equals(context.getLlFieldType())) { + codecState.payloadSize = 0; + for (int i=0; i MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + MAX_PAYLOAD_SIZE + ") exceeded : " + + codecState.payloadSize + " | " + + CommonLib.hexDump(codecState.buffer, context)); + } + + /** + * ll.field.include = 'Y' - 헤더 길이를 빼 준다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + codecState.payloadSize = codecState.payloadSize - context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 더해서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + codecState.payloadSize = codecState.payloadSize + context.getLlFieldOffset(); + } + + /** + * ll.length.adjust = 200 - 공통부 header 길이를 더한다. (한은망 평문 테스트용) + */ + if (context.getLlLenAdjust() != 0) { + codecState.payloadSize = codecState.payloadSize + context.getLlLenAdjust(); + } + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read payload : " + in); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/FixedHeaderEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/FixedHeaderEncoder.java new file mode 100644 index 0000000..d618be0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedheader/codec/FixedHeaderEncoder.java @@ -0,0 +1,123 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedheader.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class FixedHeaderEncoder implements ProtocolEncoder { + final protected Logger logger; + final protected Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public FixedHeaderEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + /** + * ll.include = 'Y' - 통째로 보낸다. + */ + if ("Y".equals(context.getLlInclude())) { + ByteBuffer buffer = ByteBuffer.allocate(m.size() - context.getLlFieldLength()); + buffer.put(m.getBytes(0, context.getLlFieldOffset())); + buffer.put(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + buffer.flip(); + m.setByteBuffer(buffer); + } + + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate(context.getLlFieldLength() + length).limit(context.getLlFieldLength() + length); + + /** + * ll.field.include = 'Y' - header 길이 포함하여 ll 을 계산한다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + length = length + context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 빼서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + length = length - context.getLlFieldOffset(); + } + + /** + * ll.length.adjust = 200 - 공통부 header 길이를 더한다. (한은망 평문 테스트용) + */ + if (context.getLlLenAdjust() != 0) { + length = length + context.getLlLenAdjust(); + } + /** + * [1] before-payload + */ + buffer.put(m.getBytes(0, context.getLlFieldOffset())); + + /** + * [2] write header + */ + if ("BIN".equals(context.getLlFieldType())) { + int tmpLength = length; + byte[] header = new byte[context.getLlFieldLength()]; + for (int i = context.getLlFieldLength()-1; i>=0; i--) { + header[i] = (byte) (tmpLength % 256); + tmpLength = tmpLength / 256; + } + buffer.put(header); + } else { // "CHAR" + String lenStr = CommonLib.getFormatString(length, context.getLlFieldLength()); + buffer.put(lenStr.getBytes()); + } + + /** + * [3] after-payload + */ + buffer.put(m.getBytes(context.getLlFieldOffset(), m.getBytes().length - context.getLlFieldOffset())); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + String dump = CommonLib.hexDump(buffer, context); + if(logger.isDebugEnabled()) { + logger.debug(context.getAdapterName() + " | FixedHeaderEncoder | encode : " + dump); + } + adapter.addRecentSendTrace(session, "FixedHeaderEncoder | encode : " + dump); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + out.flush(); + } + + public void dispose(IoSession session) throws Exception { + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/FixedPayloadClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/FixedPayloadClient.java new file mode 100644 index 0000000..a0cfa27 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/FixedPayloadClient.java @@ -0,0 +1,27 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedpayload; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.codec.FixedPayloadCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.handshake.IgnoreFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class FixedPayloadClient extends TcpAdapterClient { + public FixedPayloadClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new FixedPayloadHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedPayloadCodecFactory(this))); + + /** + * ignore PING(ACK) message + */ + config.getFilterChain().addAfter("codec", "ignore", new IgnoreFilter(this)); + } + + @Override + public Object sendMessage(Object message) throws EAIException { + return super.sendMessage(message); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/FixedPayloadHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/FixedPayloadHandler.java new file mode 100644 index 0000000..1f37452 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/FixedPayloadHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedpayload; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class FixedPayloadHandler extends ProtocolHandler { + public FixedPayloadHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/FixedPayloadServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/FixedPayloadServer.java new file mode 100644 index 0000000..2fbdc55 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/FixedPayloadServer.java @@ -0,0 +1,21 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedpayload; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.codec.FixedPayloadCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.handshake.IgnoreFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class FixedPayloadServer extends TcpAdapterServer { + public FixedPayloadServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new FixedPayloadHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedPayloadCodecFactory(this))); + + /** + * ignore PING(ACK) message + */ + config.getFilterChain().addAfter("codec", "ignore", new IgnoreFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/codec/FixedPayloadCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/codec/FixedPayloadCodecFactory.java new file mode 100644 index 0000000..59bdcb6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/codec/FixedPayloadCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedpayload.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class FixedPayloadCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public FixedPayloadCodecFactory(ISocketAdapter adapter) { + encoder = new FixedPayloadEncoder(adapter); + decoder = new FixedPayloadDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/codec/FixedPayloadDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/codec/FixedPayloadDecoder.java new file mode 100644 index 0000000..7d59d4f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/codec/FixedPayloadDecoder.java @@ -0,0 +1,157 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedpayload.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +public class FixedPayloadDecoder extends ProtocolDecoderAdapter { + final protected Logger logger; + final protected Logger errLogger; + + public static final int MAX_PAYLOAD_SIZE = 25 * 1024 * 1024; // 25MB + + private static final String DECODER_STATE_KEY = FixedPayloadDecoder.class.getName() + ".STATE"; + private static final String N_DECODER_STATE_KEY = "N" + FixedPayloadDecoder.class.getName() + ".STATE"; + + private static class CodecState { + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + boolean beforeFirst = true; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public FixedPayloadDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | FixedPayloadDecoder | decode : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "FixedPayloadDecoder | decode : " + CommonLib.hexDump(in, context)); + } + + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + + if ( (codecState == null) && (context.getRecvPayloadLength() > 0) ) { + codecState = new CodecState(); + codecState.buffer.limit(context.getRecvPayloadLength()); + //codecState.payloadSize = context.getPayloadLength(); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + /** + * undefined recvPayloadLength; it must negative value + */ + if (context.getRecvPayloadLength() < 0) { + codecState = (CodecState) session.getAttribute(N_DECODER_STATE_KEY); + + if (codecState == null) { + codecState = new CodecState(); + } + + if (codecState.beforeFirst) { + byte[] hdr = new byte[49]; + in.position(0); + in.get(hdr); + ByteMessage bm = new ByteMessage(hdr); + String trCd = new String(bm.getBytes(3, 6)); + int cnt = Integer.parseInt(new String(bm.getBytes(47, 2))); + + int recvPayloadLength = 49; + if ("210905".equals(trCd) || "611204".equals(trCd)) { // 증권수탁배치|펀드원장정보 + recvPayloadLength = 49 + (1200 + 8) * cnt; +// context.setRecvPayloadLength(recvPayloadLength); + codecState.buffer.limit(recvPayloadLength); + } else if ("611202".equals(trCd)) { + recvPayloadLength = 49 + (1100 + 8) * cnt; +// context.setRecvPayloadLength(recvPayloadLength); + codecState.buffer.limit(recvPayloadLength); + } else { // 개시 및 종료 전문 등이 올수 있슴, Transaction Code 관계없이 49bytes +// context.setRecvPayloadLength(49); + codecState.buffer.limit(recvPayloadLength); + } + + in.position(0); + codecState.payloadSize = recvPayloadLength; + session.setAttribute(N_DECODER_STATE_KEY, codecState); + } + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + if (context.getRecvPayloadLength() < 0) { + codecState.buffer.position(0).limit(codecState.payloadSize); + } else { + codecState.buffer.position(0).limit(context.getRecvPayloadLength()); + } + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + } + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /** + * send size 만큼 와도 message를 생성해서 넘긴다. + * SA 또는 SN 으로 시작하는 PING(ACK) 전문이 올 수 있다고 한다. + * concern undefined payload length; negative value + */ + if ((context.getSendPayloadLength() > 0) + && (context.getSendPayloadLength() < context.getRecvPayloadLength())) { + + if (codecState.buffer.position() + in.remaining() == context.getSendPayloadLength()) { + codecState.buffer.limit(context.getSendPayloadLength()); + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + return true; + } + } + + /** + * 읽으려는 size 만큼 아직 data가 오지 못했다. + */ + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + codecState.beforeFirst = false; + return false; + } + + /** + * 읽으려는 size 에 도달했다. + */ + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + codecState.beforeFirst = true; + } + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/codec/FixedPayloadEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/codec/FixedPayloadEncoder.java new file mode 100644 index 0000000..1631813 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/codec/FixedPayloadEncoder.java @@ -0,0 +1,70 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedpayload.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class FixedPayloadEncoder implements ProtocolEncoder { + final protected Logger logger; + final protected Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public FixedPayloadEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + int length = context.getSendPayloadLength(); + + /** + * undefined sendPayloadLength; it must negative value + */ + if (length < 0) + length = m.size(); + + ByteBuffer buffer = ByteBuffer.allocate(length).limit(length); + buffer.put(m.padding(length, (byte) 0x00).getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | FixedPayloadEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "FixedPayloadEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + public void dispose(IoSession session) throws Exception { + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/handshake/IgnoreFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/handshake/IgnoreFilter.java new file mode 100644 index 0000000..caa7e7d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/fixedpayload/handshake/IgnoreFilter.java @@ -0,0 +1,53 @@ +package com.eactive.eai.adapter.socket2.protocol.fixedpayload.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + + +public class IgnoreFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + + public IgnoreFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + //KB Case - CMBS_OU_NET_SyC{KOREA} adapter group의 경우 만 적용 + ByteMessage m = (ByteMessage) message; + + if ( (m.size() >= 2) && (m.getByte(0) == 'S') && (m.getByte(1) == 'A') + && "CMBS_OU_NET_SyC{KOREA}".equals(context.getAdapterGroupName()) ) { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | IgnoreFilter - ignore : " + m.hexDump()); + adapter.addRecentRecvTrace(session, "IgnoreFilter - ignore : " + m.hexDump()); + } + return; + } + + // 증권투자수탁 HEADER Check, it must start 'N' + if ( (context.getRecvPayloadLength() < 0) && (m.getByte(0) != 'N') ) { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | IgnoreFilter - ignore, HEADER must start 'N' : " + m.hexDump()); + adapter.addRecentRecvTrace(session, "IgnoreFilter - ignore, HEADER must start 'N' : " + m.hexDump()); + } + return; + } + + nextFilter.messageReceived(session, message); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/HttpHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/HttpHandler.java new file mode 100644 index 0000000..6db6d04 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/HttpHandler.java @@ -0,0 +1,117 @@ +package com.eactive.eai.adapter.socket2.protocol.http; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.util.SessionLog; + +import java.util.Hashtable; + +public class HttpHandler extends ProtocolHandler { + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_"); + + static String[] servletList = { + "adapters", "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdaptersServlet", + "adaptersJson", "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdaptersJsonServlet", + "adapter", "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdapterServlet", + "adapterJson", "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdapterJsonServlet", + "adapterInternal", "com.eactive.eai.adapter.socket2.protocol.http.servlet.AdapterInternalServlet", + "check", "com.eactive.eai.adapter.socket2.protocol.http.servlet.CheckServlet", + "thread", "com.eactive.eai.adapter.socket2.protocol.http.servlet.ThreadServlet", + "memory", "com.eactive.eai.adapter.socket2.protocol.http.servlet.MemoryServlet", + "error", "com.eactive.eai.adapter.socket2.protocol.http.servlet.ErrorServlet", + "file", "com.eactive.eai.adapter.socket2.protocol.http.servlet.FileServlet", + "prop", "com.eactive.eai.adapter.socket2.protocol.http.servlet.PropServlet", + "groovy", "com.eactive.eai.adapter.socket2.protocol.http.servlet.GroovyServlet", + "transformer", "com.eactive.eai.transformer.servlet.TransformerServlet", + "message", "com.eactive.eai.transformer.servlet.LayoutServlet", + "layout", "com.eactive.eai.transformer.servlet.LayoutServlet", + "transform", "com.eactive.eai.transformer.servlet.TransformServlet", + "function", "com.eactive.eai.transformer.servlet.FunctionServlet", + "service", "com.eactive.eai.transformer.servlet.ServiceServlet", + "bizkey", "com.eactive.eai.transformer.servlet.BizKeyServlet", + "control", "com.eactive.eai.adapter.socket2.protocol.http.servlet.ControlServlet", + "http", "com.eactive.eai.adapter.http.servlet.HttpAdapterLogServlet", + "zombies", "com.eactive.eai.adapter.socket2.protocol.http.servlet.ZombieAdaptersServlet", + "token", "com.openbanking.eai.common.token.servlet.AccessTokenServlet", + "rolling", "com.eactive.kakao.rolling.servlet.RollingServlet" + }; + + Hashtable map = new Hashtable(); + + + public HttpHandler(ISocketAdapter adapter) { + super(adapter); + + for (int i=0; i= context.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | audit - " + session + " - " + request.getURI()); + } + + /** + * sevlet + */ + try { + String servletName = "error"; + if (!"".equals(request.getContext())) { + servletName = request.getContext(); + } + if (servletName.indexOf('/') != -1) { + servletName = servletName.substring(0, servletName.indexOf('/')); + } + + HttpServlet servlet = (HttpServlet) map.get(servletName); + if (servlet == null) { + if (!servletName.endsWith(".ico")) + logger.warn("404 - > " + servletName); + response.setResponseCode(404); + } else { + servlet.service(request, response); + } + } catch(Exception e) { + response.appendBody("

");
+        	response.appendBody(ExceptionStackTrace.dump(e));
+        	response.appendBody("
"); + } + + session.write(response).join(); + } + + @Override + public void sessionIdle(IoSession session, IdleStatus status) { + SessionLog.info(session, context.getAdapterName() + " | session idle -> disconnect"); + sessionPool.remove(session); + session.close(); + } + + @Override + public void exceptionCaught(IoSession session, Throwable cause) { + sessionPool.remove(session); + session.close(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/HttpServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/HttpServer.java new file mode 100644 index 0000000..8b94843 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/HttpServer.java @@ -0,0 +1,15 @@ +package com.eactive.eai.adapter.socket2.protocol.http; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class HttpServer extends TcpAdapterServer { + public HttpServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new HttpHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new HttpProtocolCodecFactory(context))); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/HttpServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/HttpServlet.java new file mode 100644 index 0000000..9cf5336 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/HttpServlet.java @@ -0,0 +1,13 @@ +package com.eactive.eai.adapter.socket2.protocol.http; + +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; + +abstract public class HttpServlet { + + public void service(HttpRequest request, HttpResponse response) throws Exception { + doService(request, response); + } + + abstract protected void doService(HttpRequest request, HttpResponse response) throws Exception; +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/Server.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/Server.java new file mode 100644 index 0000000..d093d96 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/Server.java @@ -0,0 +1,51 @@ +package com.eactive.eai.adapter.socket2.protocol.http; + +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpProtocolCodecFactory; +import org.apache.mina.common.IoAcceptor; +import org.apache.mina.filter.LoggingFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; +import org.apache.mina.transport.socket.nio.SocketAcceptor; +import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; + +import java.net.InetSocketAddress; + + +public class Server { + /** Default HTTP port */ + private static final int DEFAULT_PORT = 8080; + + /** Tile server revision number */ + public static final String VERSION_STRING = ""; + + public static void main(String[] args) { + int port = DEFAULT_PORT; + + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-port")) { + port = Integer.parseInt(args[i + 1]); + } + } + + try { + // Create an acceptor + IoAcceptor acceptor = new SocketAcceptor(); + + // Create a service configuration + SocketAcceptorConfig cfg = new SocketAcceptorConfig(); + cfg.setReuseAddress(true); + cfg.getFilterChain().addLast( + "protocolFilter", + new ProtocolCodecFilter( + new HttpProtocolCodecFactory(null))); + cfg.getFilterChain().addLast("logger", new LoggingFilter()); + + acceptor + .bind(new InetSocketAddress(port), new ServerHandler(), cfg); + + System.out.println("Server now listening on port " + port); + } catch (Exception ex) { +// ex.printStackTrace(); + System.out.println("Error" + ex.toString()); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/ServerHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/ServerHandler.java new file mode 100644 index 0000000..8fb9b74 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/ServerHandler.java @@ -0,0 +1,40 @@ +package com.eactive.eai.adapter.socket2.protocol.http; + +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoHandlerAdapter; +import org.apache.mina.common.IoSession; +import org.apache.mina.util.SessionLog; + + +public class ServerHandler extends IoHandlerAdapter { + @Override + public void sessionOpened(IoSession session) { + // set idle time to 60 seconds + session.setIdleTime(IdleStatus.BOTH_IDLE, 60); + } + + @Override + public void messageReceived(IoSession session, Object message) { + // Check that we can service the request context + HttpResponse response = new HttpResponse(); + response.setContentType("text/plain"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody("CONNECTED"); + + if (response != null) { + session.write(response).join(); + } + } + + @Override + public void sessionIdle(IoSession session, IdleStatus status) { + SessionLog.info(session, "Disconnecting the idle."); + session.close(); + } + + @Override + public void exceptionCaught(IoSession session, Throwable cause) { + session.close(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpProtocolCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpProtocolCodecFactory.java new file mode 100644 index 0000000..7c2ebf7 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpProtocolCodecFactory.java @@ -0,0 +1,12 @@ +package com.eactive.eai.adapter.socket2.protocol.http.codec; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import org.apache.mina.filter.codec.demux.DemuxingProtocolCodecFactory; + + +public class HttpProtocolCodecFactory extends DemuxingProtocolCodecFactory { + public HttpProtocolCodecFactory(SocketAdapterContext context) { + super.register(HttpRequestDecoder.class); + super.register(HttpResponseEncoder.class); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpRequest.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpRequest.java new file mode 100644 index 0000000..d43ca66 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpRequest.java @@ -0,0 +1,77 @@ +package com.eactive.eai.adapter.socket2.protocol.http.codec; + +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.mina.common.IoSession; + + +public class HttpRequest { + private Map headers = null; + private IoSession session = null; + + public void setHeaders(Map headers) { + this.headers = headers; + } + + public Map getHeaders() { + return headers; + } + + public String getURI() { + String[] uris = (String[]) headers.get("URI"); + return uris == null ? "" : uris[0]; + } + + public String getContext() { + String[] context = (String[]) headers.get("Context"); + return context == null ? "" : context[0]; + } + + public String getParameter(String name) { + String[] param = (String[]) headers.get("@".concat(name)); + return param == null ? "" : param[0]; + } + + public String[] getParameters(String name) { + String[] param = (String[]) headers.get("@".concat(name)); + return param == null ? new String[] {} : param; + } + + public String[] getHeader(String name) { + return (String[]) headers.get(name); + } + + public void setSession(IoSession session) { + this.session = session; + } + + public IoSession getSession() { + return session; + } + + public String toString() { + StringBuilder str = new StringBuilder(); + + Iterator it = headers.entrySet().iterator(); + while (it.hasNext()) { + Entry e = (Entry) it.next(); + str.append(e.getKey() + " : " + + arrayToString((String[]) e.getValue(), ',') + "\n"); + } + return str.toString(); + } + + public static String arrayToString(String[] s, char sep) { + if (s == null || s.length == 0) + return ""; + StringBuilder buf = new StringBuilder(); + for (int i = 0; i < s.length; i++) { + if (i > 0) + buf.append(sep); + buf.append(s[i]); + } + return buf.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpRequestDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpRequestDecoder.java new file mode 100644 index 0000000..da6fc1b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpRequestDecoder.java @@ -0,0 +1,212 @@ +package com.eactive.eai.adapter.socket2.protocol.http.codec; + +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; +import org.apache.mina.filter.codec.demux.MessageDecoderAdapter; +import org.apache.mina.filter.codec.demux.MessageDecoderResult; +import org.apache.mina.util.CharsetUtil; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.CharsetDecoder; +import java.util.HashMap; +import java.util.Map; + +/** + * A {@link org.apache.mina.filter.codec.demux.MessageDecoder} that decodes {@link HttpRequest}. + * + * @author The Apache Directory Project (mina-dev@directory.apache.org) + * @version + */ +public class HttpRequestDecoder extends MessageDecoderAdapter { + private static final byte[] CONTENT_LENGTH = "Content-Length:".getBytes(); + + //private CharsetDecoder decoder = Charset.defaultCharset().newDecoder(); + + private CharsetDecoder decoder = CharsetUtil.getDefaultCharset().newDecoder(); + + protected final com.eactive.eai.common.util.Logger logger; + + public HttpRequestDecoder() { + logger = SocketLoggerManager.getInstance().getLogger(); + } + + public MessageDecoderResult decodable(IoSession session, ByteBuffer in) { + // Return NEED_DATA if the whole header is not read yet. + try { + return messageComplete(in) ? MessageDecoderResult.OK + : MessageDecoderResult.NEED_DATA; + } catch (Exception ex) { + logger.debug(ex.toString()); + } + + return MessageDecoderResult.NOT_OK; + } + + public MessageDecoderResult decode(IoSession session, ByteBuffer in, + ProtocolDecoderOutput out) throws Exception { + // Try to decode body + HttpRequest m = decodeBody(in); + + // Return NEED_DATA if the body is not fully read. + if (m == null) + return MessageDecoderResult.NEED_DATA; + + m.setSession(session); + out.write(m); + return MessageDecoderResult.OK; + } + + private boolean messageComplete(ByteBuffer in) throws Exception { + int last = in.remaining() - 1; + if (in.remaining() < 4) + return false; + + // to speed up things we check if the Http request is a GET or POST + if (in.get(0) == (byte) 'G' && in.get(1) == (byte) 'E' + && in.get(2) == (byte) 'T') { + // Http GET request therefore the last 4 bytes should be 0x0D 0x0A 0x0D 0x0A + return (in.get(last) == (byte) 0x0A + && in.get(last - 1) == (byte) 0x0D + && in.get(last - 2) == (byte) 0x0A && in.get(last - 3) == (byte) 0x0D); + } else if (in.get(0) == (byte) 'P' && in.get(1) == (byte) 'O' + && in.get(2) == (byte) 'S' && in.get(3) == (byte) 'T') { + // Http POST request + // first the position of the 0x0D 0x0A 0x0D 0x0A bytes + int eoh = -1; + for (int i = last; i > 2; i--) { + if (in.get(i) == (byte) 0x0A && in.get(i - 1) == (byte) 0x0D + && in.get(i - 2) == (byte) 0x0A + && in.get(i - 3) == (byte) 0x0D) { + eoh = i + 1; + break; + } + } + if (eoh == -1) + return false; + for (int i = 0; i < last; i++) { + boolean found = false; + for (int j = 0; j < CONTENT_LENGTH.length; j++) { + if (in.get(i + j) != CONTENT_LENGTH[j]) { + found = false; + break; + } + found = true; + } + if (found) { + // retrieve value from this position till next 0x0D 0x0A + StringBuilder contentLength = new StringBuilder(); + for (int j = i + CONTENT_LENGTH.length; j < last; j++) { + if (in.get(j) == 0x0D) + break; + contentLength.append(new String( + new byte[] { in.get(j) })); + } + // if content-length worth of data has been received then the message is complete + return (Integer.parseInt(contentLength.toString().trim()) + + eoh == in.remaining()); + } + } + } + + // the message is not complete and we need more data + return false; + } + + private HttpRequest decodeBody(ByteBuffer in) { + HttpRequest request = new HttpRequest(); + try { + request.setHeaders(parseRequest(new StringReader(in + .getString(decoder)))); + return request; + } catch (CharacterCodingException ex) { + logger.debug(ex.toString()); + } + + return null; + } + + private Map parseRequest(Reader is) { + Map map = new HashMap<>(); + BufferedReader rdr = new BufferedReader(is); + + try { + // Get request URL. + String line = rdr.readLine(); + String[] url = line == null?new String[0]:line.split(" "); + if (url.length < 3) + return map; + + map.put("URI", new String[] { line }); + if(url[0] != null) map.put("Method", new String[] { url[0].toUpperCase() }); + if(url[1] != null) map.put("Context", new String[] { url[1].substring(1) }); + if(url[2] != null) map.put("Protocol", new String[] { url[2] }); + // Read header + while ((line = rdr.readLine()) != null && line.length() > 0) { + String[] tokens = line.split(": "); + map.put(tokens[0], new String[] { tokens[1] }); + } + + // If method 'POST' then read Content-Length worth of data + if (url[0].equalsIgnoreCase("POST")) { + int len = Integer.parseInt(map.get("Content-Length")[0]); + if(len >= 0) { + char[] buf = new char[len]; + if (rdr.read(buf) == len) { + line = String.copyValueOf(buf); + //System.out.println(line); + } + } + } else if (url[0].equalsIgnoreCase("GET")) { + int idx = url[1].indexOf('?'); + if (idx != -1) { + map.put("Context", + new String[] { url[1].substring(1, idx) }); + line = url[1].substring(idx + 1); + } else { + line = null; + } + } + + if (line != null) { + String[] match = line.split("\\&"); + for (int i = 0; i < match.length; i++) { + String[] params = new String[1]; + String[] tokens = match[i].split("="); + switch (tokens.length) { + case 0: + map.put("@".concat(match[i]), new String[] {}); + break; + case 1: + map.put("@".concat(tokens[0]), new String[] {}); + break; + default: + String name = "@".concat(tokens[0]); + if (map.containsKey(name)) { + params = map.get(name); + if(params != null) { + String[] tmp = new String[params.length + 1]; + for (int j = 0; j < params.length; j++) + tmp[j] = params[j]; + params = tmp; + } + } + if(params != null) { + params[params.length - 1] = tokens[1].trim(); + map.put(name, params); + } + } + } + } + } catch (IOException ex) { + logger.debug(ex.toString()); + } + + return map; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponse.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponse.java new file mode 100644 index 0000000..84362ed --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponse.java @@ -0,0 +1,83 @@ +package com.eactive.eai.adapter.socket2.protocol.http.codec; + +import com.eactive.eai.adapter.socket2.protocol.http.Server; +import org.apache.mina.common.ByteBuffer; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; +import java.util.Map; + + +public class HttpResponse { + /** HTTP response codes */ + public static final int HTTP_STATUS_SUCCESS = 200; + + public static final int HTTP_STATUS_NOT_FOUND = 404; + + /** Map */ + private Map headers = new HashMap(); + + /** Storage for body of HTTP response. */ + private ByteArrayOutputStream body = new ByteArrayOutputStream(1024); + + private int responseCode = HTTP_STATUS_SUCCESS; + + public HttpResponse() { + headers.put("Server", "HttpServer (" + Server.VERSION_STRING + ')'); + headers.put("Cache-Control", "private"); + headers.put("Content-Type", "text/html; charset='UTF-8'"); + headers.put("Connection", "keep-alive"); + headers.put("Keep-Alive", "200"); + headers.put("Date", DateTimeFormatter.ofPattern( + "EEE, dd MMM yyyy HH:mm:ss zzz").format(ZonedDateTime.now())); + headers.put("Last-Modified", DateTimeFormatter.ofPattern( + "EEE, dd MMM yyyy HH:mm:ss zzz").format(ZonedDateTime.now())); + } + + public Map getHeaders() { + return headers; + } + + public void addHeader(String key, String value) { + headers.put(key, value); + } + + public void setContentType(String contentType) { + headers.put("Content-Type", contentType); + } + + public void setResponseCode(int responseCode) { + this.responseCode = responseCode; + } + + public int getResponseCode() { + return this.responseCode; + } + + public void appendBody(byte[] b) { + try { + body.write(b); + } catch (IOException ex) { + System.out.println("appendBody error"); + } + } + + public void appendBody(String s) { + try { + body.write(s.getBytes()); + } catch (IOException ex) { + System.out.println("appendBody string error"); + } + } + + public ByteBuffer getBody() { + return ByteBuffer.wrap(body.toByteArray()); + } + + public int getBodyLength() { + return body.size(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponseEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponseEncoder.java new file mode 100644 index 0000000..8132f2a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/codec/HttpResponseEncoder.java @@ -0,0 +1,78 @@ +package com.eactive.eai.adapter.socket2.protocol.http.codec; + +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; +import org.apache.mina.filter.codec.demux.MessageEncoder; +import org.apache.mina.util.CharsetUtil; + +import java.nio.charset.CharacterCodingException; +import java.nio.charset.CharsetEncoder; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map.Entry; +import java.util.Set; + +public class HttpResponseEncoder implements MessageEncoder { + private static final Set> TYPES; + + static { + Set> types = new HashSet>(); + types.add(HttpResponse.class); + TYPES = Collections.unmodifiableSet(types); + } + + private static final byte[] CRLF = new byte[] { 0x0D, 0x0A }; + + public HttpResponseEncoder() { + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) + throws Exception { + HttpResponse msg = (HttpResponse) message; + ByteBuffer buf = ByteBuffer.allocate(256); + // Enable auto-expand for easier encoding + buf.setAutoExpand(true); + + try { + // output all headers except the content length + //CharsetEncoder encoder = Charset.defaultCharset().newEncoder(); + CharsetEncoder encoder = CharsetUtil.getDefaultCharset().newEncoder(); + buf.putString("HTTP/1.1 ", encoder); + buf.putString(String.valueOf(msg.getResponseCode()), encoder); + switch (msg.getResponseCode()) { + case HttpResponse.HTTP_STATUS_SUCCESS: + buf.putString(" OK", encoder); + break; + case HttpResponse.HTTP_STATUS_NOT_FOUND: + buf.putString(" Not Found", encoder); + break; + } + buf.put(CRLF); + for (Iterator it = msg.getHeaders().entrySet().iterator(); it.hasNext();) { + Entry entry = (Entry) it.next(); + buf.putString((String) entry.getKey(), encoder); + buf.putString(": ", encoder); + buf.putString((String) entry.getValue(), encoder); + buf.put(CRLF); + } + // now the content length is the body length + buf.putString("Content-Length: ", encoder); + buf.putString(String.valueOf(msg.getBodyLength()), encoder); + buf.put(CRLF); + buf.put(CRLF); + // add body + buf.put(msg.getBody()); + } catch (CharacterCodingException ex) { + out.flush(); + } + + buf.flip(); + out.write(buf); + } + + public Set> getMessageTypes() { + return TYPES; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdapterInternalServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdapterInternalServlet.java new file mode 100644 index 0000000..09d3861 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdapterInternalServlet.java @@ -0,0 +1,927 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoSession; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Iterator; + +public class AdapterInternalServlet extends HttpServlet { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String command = request.getContext(); + if (command.lastIndexOf('/') == -1) { + command = ""; + } else { + command = command.substring(command.indexOf('/') + 1); + } + + String result = ""; + + try { + if (command == null || "".equals(command) || "show".equals(command)) { + result = show(request.getParameter("adapter")); + } else if (command.startsWith("traceLevel")) { + result = traceLevel(request.getParameter("adapter"), Integer.parseInt(request.getParameter("level"))); + } else if (command.startsWith("clear")) { + result = clear(request.getParameter("adapter")); + } else if (command.startsWith("start")) { + String adapterName = request.getParameter("adapter"); + logger.fatal("HttpAdapter | " + adapterName + " | start - " + request.getSession()); + result = start(adapterName); + } else if (command.startsWith("stopforcely")) { + String adapterName = request.getParameter("adapter"); + logger.fatal("HttpAdapter | " + adapterName + " | stop - " + request.getSession()); + result = stop(adapterName, true); + } else if (command.startsWith("stop")) { + String adapterName = request.getParameter("adapter"); + logger.fatal("HttpAdapter | " + adapterName + " | stop - " + request.getSession()); + result = stop(adapterName, false); + } else if (command.startsWith("error")) { + result = error(request.getParameter("adapter")); + } else if (command.startsWith("sendRecv")) { + result = sendRecv(request.getParameter("adapter")); + } else if (command.startsWith("removeSession")) { + result = removeSession(request.getParameter("adapter"), request.getParameter("localPort"), + request.getParameter("remotePort")); + } else if (command.startsWith("sessionValidate")) { + result = sessionValidate(request.getParameter("adapter")); + } else { + response.setResponseCode(404); + return; + } + } catch (Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html;charset=utf-8;"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + private String show(String adapterName) throws Exception { + StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + sb.append(adapterName); + + if (adapter == null) { + sb.append(" Not found adapter (" + adapterName + ")"); + return sb.toString(); + } + /** + * status + */ + if ("STARTED".equals(adapter.getState().name())) { + sb.append(" (" + adapter.getState().name() + ")"); + } else { + sb.append(" (" + adapter.getState().name() + ")"); + } + + sb.append(" uptime:" + TimeUtil.formatDate(adapter.getUptime().getTime())); + sb.append(", pool:" + adapter.getSessionPool().remaining() + "/" + (adapter.getSessionPool().peekSize())); + sb.append(", recv:" + adapter.getMessageRecv()); + sb.append(", send:" + adapter.getMessageSend()); + if (adapter.getRecentErrorCount() > 0) { + sb.append(", "); + sb.append(""); + sb.append("error:" + adapter.getRecentErrorCount()); + sb.append(""); + } else { + sb.append(", error:" + adapter.getRecentErrorCount()); + } + + // sb.append(", (clear)"); + + // sb.append(" (start"); + // sb.append("|stop)"); + + if (adapter.getContext().getDescription() != null && !"".equals(adapter.getContext().getDescription().trim())) { + sb.append("\n " + adapter.getContext().getDescription() + "\n"); + } + + sb.append("\n\n"); + + /** + * common info + */ + sb.append(String.format("%4s %-30s : %s\n", "", "host.name", adapter.getContext().getHostName())); + sb.append(String.format("%4s %-30s : %s\n", "", "port.number", adapter.getContext().getPortNumber())); + sb.append(String.format("%4s %-30s : %s\n", "", "local.host.name", adapter.getContext().getLocalHostName())); + sb.append( + String.format("%4s %-30s : %s\n", "", "local.port.number", adapter.getContext().getLocalPortNumber())); + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "protocol", adapter.getContext().getProtocol())); + sb.append(String.format("%4s %-30s : %s\n", "", "bound.usage", adapter.getContext().getBoundUsage())); + sb.append(String.format("%4s %-30s : %s\n", "", "socket.type", adapter.getContext().getSocketType())); + sb.append(String.format("%4s %-30s : %s\n", "", "response.type", adapter.getContext().getResponseType())); + sb.append(String.format("%4s %-30s : %s\n", "", "ack.support", adapter.getContext().getAckSupport())); + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "permanent", adapter.getContext().getPermanent())); + sb.append(String.format("%4s %-30s : %s\n", "", "blocking(NIO, BIO)", adapter.getContext().getBlocking())); + sb.append(String.format("%4s %-30s : %s (sec)\n", "", "timeout", adapter.getContext().getTimeout())); + sb.append(String.format("%4s %-30s : %s (sec)\n", "", "idle.timeout", adapter.getContext().getIdleTimeout())); + sb.append(String.format("%4s %-30s : %s\n", "", "socket.reuse", adapter.getContext().getSocketReuse())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "business.work.class.code", + adapter.getContext().getBwkClsCd())); + sb.append(String.format("%4s %-30s : %s\n", "", "max.connection", + (adapter.getContext().getCloseExistingConnection() ? "-" : "") + + adapter.getContext().getMaxConnection())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "connection.limit.per.ip", + adapter.getContext().getConnLimitPerIp())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "max.thread", adapter.getContext().getMaxThread())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "validation.rule", adapter.getContext().getValidationRule())); + sb.append( + String.format("%4s %-30s : %s\n\n", "", "datacontrol.rule", adapter.getContext().getDataControlRule())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "acl.list", adapter.getContext().getAclList())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "block.ip.list", adapter.getContext().getBlockIpList())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "l4.skip.ip.list", adapter.getContext().getL4SkipIpList())); + + sb.append( + String.format("%4s %-30s : %s\n\n", "", "is.single.session", adapter.getContext().getSingleSession())); + + int traceLevel = adapter.getContext().getTraceLevel(); + sb.append(String.format("%4s %-30s : %s \n", "", "trace.level", adapter.getContext().getTraceLevel())); +// switch(traceLevel) { +// case 0: +// sb.append(String.format("%4s %-30s : %s %s %s %s\n", "", "trace.level", +// "0(DEFAULT)", +// "1", +// "2", +// "3")); +// break; +// case 1: +// sb.append(String.format("%4s %-30s : %s %s %s %s\n", "", "trace.level", +// "0", +// "1(INFO)", +// "2", +// "3")); +// break; +// case 2: +// sb.append(String.format("%4s %-30s : %s %s %s %s\n", "", "trace.level", +// "0", +// "1", +// "2(DEBUG)", +// "3")); +// break; +// case 3: +// sb.append(String.format("%4s %-30s : %s %s %s %s\n", "", "trace.level", +// "0", +// "1", +// "2", +// "3(TRACE)")); +// break; +// } + + if (adapter.getContext().isPollingUse()) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.use", adapter.getContext().getPollingUse())); + if ("".equals(adapter.getContext().getPollingRole().trim())) { + if (adapter.getContext().isPollingSender()) + sb.append(String.format("%4s %-30s : %s\n", "", "polling.role", "SENDER (client)")); + else + sb.append(String.format("%4s %-30s : %s\n", "", "polling.role", "RECEIVER (server)")); + } else { + sb.append(String.format("%4s %-30s : %s\n", "", "polling.role", adapter.getContext().getPollingRole())); + } + sb.append(String.format("%4s %-30s : %s\n", "", "polling.oneway", adapter.getContext().getPollingOneway())); + + if (adapter.getContext().isPollingReceiver()) { + sb.append(""); + } + sb.append( + String.format("%4s %-30s : %s\n", "", "polling.timeout", adapter.getContext().getPollingTimeout())); + sb.append( + String.format("%4s %-30s : %s\n", "", "polling.request", adapter.getContext().getPollingRequest())); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.response.pattern", + adapter.getContext().getPollingResponsePattern())); + if (adapter.getContext().isPollingReceiver()) { + sb.append(""); + } + + if (adapter.getContext().isPollingSender()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "polling.request.pattern", + adapter.getContext().getPollingRequestPattern())); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.replacement", + adapter.getContext().getPollingReplacement())); + if (adapter.getContext().isPollingSender()) { + sb.append(""); + } + + sb.append("\n"); + } + + // KSH + if (adapter.getContext().isInitMsgUse()) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.use", adapter.getContext().getInitMsgUse())); + if ("".equals(adapter.getContext().getInitMsgRole().trim())) { + if (adapter.getContext().isInitMsgSender()) + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.role", "SENDER (client)")); + else + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.role", "RECEIVER (server)")); + } else { + sb.append( + String.format("%4s %-30s : %s\n", "", "init.msg.role", adapter.getContext().getInitMsgRole())); + } + + if (adapter.getContext().isInitMsgReceiver()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.request", + adapter.getContext().getInitMsgRequest())); + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.response.pattern", + adapter.getContext().getInitMsgResponsePattern())); + if (adapter.getContext().isInitMsgReceiver()) { + sb.append(""); + } + + if (adapter.getContext().isInitMsgSender()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.request.pattern", + adapter.getContext().getInitMsgRequestPattern())); + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.replacement", + adapter.getContext().getInitMsgReplacement())); + if (adapter.getContext().isInitMsgSender()) { + sb.append(""); + } + + sb.append("\n"); + } + + /** + * ll info (fixed length header) + */ + if ("FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "UDP_FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "EGSEED".equals(adapter.getContext().getProtocol()) + || "TCSEED".equals(adapter.getContext().getProtocol()) // 20101213 JGY + || "ENVELOP".equals(adapter.getContext().getProtocol()) + || "XECURE".equals(adapter.getContext().getProtocol()) + || "XECURE2".equals(adapter.getContext().getProtocol()) + || "XECURE3".equals(adapter.getContext().getProtocol()) + || "XC3EPB".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.type", adapter.getContext().getLlFieldType())); + sb.append( + String.format("%4s %-30s : %s\n", "", "ll.field.offset", adapter.getContext().getLlFieldOffset())); + sb.append( + String.format("%4s %-30s : %s\n", "", "ll.field.length", adapter.getContext().getLlFieldLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.include", + adapter.getContext().getLlFieldInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.offset.exclude", + adapter.getContext().getLlOffsetExclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.include", adapter.getContext().getLlInclude())); + } + + /** + * ll info (variable length payload) 20130719 KSH + */ + if ("VARIABLE_LENGTH_HEADER".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.type", adapter.getContext().getLlFieldType())); + sb.append( + String.format("%4s %-30s : %s\n", "", "ll.field.offset", adapter.getContext().getLlFieldOffset())); + sb.append( + String.format("%4s %-30s : %s\n", "", "ll.field.length", adapter.getContext().getLlFieldLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.include", + adapter.getContext().getLlFieldInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.offset.exclude", + adapter.getContext().getLlOffsetExclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.include", adapter.getContext().getLlInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "send.header.length", + adapter.getContext().getSendHeaderLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "recv.header.length", + adapter.getContext().getRecvHeaderLength())); + } + + /** + * ll info (fixed length payload) + */ + if ("FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol()) + || "INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol()) // 20100515 JGY + || "UDP_FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "send.payload.length", + adapter.getContext().getSendPayloadLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "recv.payload.length", + adapter.getContext().getRecvPayloadLength())); + } + + /** + * xecure + */ + if ("XECURE".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.type", adapter.getContext().getXecureType())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.config.path", + adapter.getContext().getXecureConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.remote.cert", + adapter.getContext().getXecureRemoteCert())); + } + + /** + * xecure2 + */ + if ("XECURE2".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure2.config.path", + adapter.getContext().getXecure2ConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure2.sm.ip", adapter.getContext().getXecure2SmIp())); + sb.append( + String.format("%4s %-30s : %s\n", "", "xecure2.sm.port", adapter.getContext().getXecure2SmPort())); + // use CISCO interface only + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.type", adapter.getContext().getXecureType())); + } + + /** + * xecure3 20100901 JGY + */ + if ("XECURE3".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.cert.store", + adapter.getContext().getXecure3CertStore())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.server.cert", + adapter.getContext().getXecure3ServerCert())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.client.cert", + adapter.getContext().getXecure3ClientCert())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.cert.key", + adapter.getContext().getXecure3CertKey())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.cert.password", + adapter.getContext().getXecure3CertPassword())); + } + + /** + * xc3epb 20210929 + */ + if ("XC3EPB".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append( + String.format("%4s %-30s : %s\n", "", "xc3epb.password", adapter.getContext().getXc3epbPassword())); + sb.append(String.format("%4s %-30s : %s\n", "", "xc3epb.config.path", + adapter.getContext().getXc3epbConfigPath())); + } + + /** + * inisafe inisafe_payload 20100515 JGY + */ + if ("INISAFE".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", + adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.related.adapter.groups", + adapter.getContext().getInisafeRelatedAdapterGroups())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.start.message", + adapter.getContext().getInisafeStartMessage())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.stop.message", + adapter.getContext().getInisafeStopMessage())); + } else if ("INISAFE_2020".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", + adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.related.adapter.groups", + adapter.getContext().getInisafeRelatedAdapterGroups())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.start.message", + adapter.getContext().getInisafeStartMessage())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.stop.message", + adapter.getContext().getInisafeStopMessage())); + } else if ("INISAFE_NATN".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", + adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.related.adapter.groups", + adapter.getContext().getInisafeRelatedAdapterGroups())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.start.message", + adapter.getContext().getInisafeStartMessage())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.stop.message", + adapter.getContext().getInisafeStopMessage())); + } else if ("INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", + adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.id.password", + adapter.getContext().getInisafeIdPassword())); + } + + /** + * ENVELOP : JGY 20100423 + */ + if ("ENVELOP".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "envelop.signcert.path", + adapter.getContext().getEnvelopSigncertPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "envelop.signkey.path", + adapter.getContext().getEnvelopSignkeyPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "envelop.password", + adapter.getContext().getEnvelopPassword())); + } + + /** + * TCSEED : JGY 20101213 + */ + if ("TCSEED".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "tcseed.key.store", + adapter.getContext().getTcseedKeyStore())); + } + + if ("DYNAMIC_OFFSET".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.type", adapter.getContext().getLlFieldType())); + sb.append( + String.format("%4s %-30s : %s\n", "", "ll.field.offset", adapter.getContext().getLlFieldOffset())); + sb.append( + String.format("%4s %-30s : %s\n", "", "ll.field.length", adapter.getContext().getLlFieldLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.include", + adapter.getContext().getLlFieldInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.offset.exclude", + adapter.getContext().getLlOffsetExclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.include", adapter.getContext().getLlInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "dynamic.offset.pattern", + adapter.getContext().getDynamicOffsetPattern())); + sb.append(String.format("%4s %-30s : %s\n", "", "data.add.rule", adapter.getContext().getDataAddRule())); + sb.append(String.format("%4s %-30s : %s\n", "", "data.remove.rule", + adapter.getContext().getDataRemoveRule())); + } + + /** + * script + */ + if (!"".equals(adapter.getContext().getScript().trim())) { + sb.append("\n"); + // sb.append(String.format("%4s %-30s : %s\n", "", "script", "" + adapter.getContext().getScript() + + // "")); + } + + sb.append("\n"); + + /** + * session list + */ + sb.append("\nsession pool (remaining)\n"); + sb.append(""); + for (Iterator iii = adapter.getSessionPool().iterator(); iii.hasNext();) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :"); + ; + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + sb.append(""); + + if (adapter.getSessionPool().checkedOut() > 0) { + sb.append("session pool (checked out)\n"); + } + + sb.append(""); + for (Iterator iii = adapter.getSessionPool().checkedOutIterator(); iii.hasNext();) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :"); + ; + // sb.append(" [" + session.getTrafficMask() + "]"); + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + sb.append(""); + sb.append("\n"); + + /** + * netstat + */ + try { + String[] cmd; + if (Env.isWindows()) { + cmd = new String[] { "cmd.exe", "/c", "netstat -an | findstr " + adapter.getContext().getPortNumber() }; + } else { + cmd = new String[] { "sh", "-c", + "netstat -an | grep -E 'tcp|udp' | grep " + adapter.getContext().getPortNumber() }; + } + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec(cmd); + + StreamForNetstat netstat1 = new StreamForNetstat(process.getInputStream(), adapter); + StreamForNetstat netstat2 = new StreamForNetstat(process.getErrorStream(), adapter); + netstat1.start(); + netstat2.start(); + while (true) { + if (!netstat1.isAlive() && !netstat2.isAlive()) { // 두개의 스레드가 정지할면 프로세스 종료때까지 기다린다. + process.waitFor(); + sb.append(netstat1.getData()); + break; + } + } + } catch (Exception e) { + logger.error("Error", e); + } + + /** + * lsof && ps + */ + if (!Env.isWindows()) { + try { + String[] cmd = new String[] { "sh", "-c", + "lsof -iTCP" + + ("*".equals(adapter.getContext().getHostName()) ? "" + : "@" + adapter.getContext().getHostName()) + + ":" + adapter.getContext().getPortNumber() + + // " | grep " + adapter.getContext().getHostName() + + " | grep -E '\\([A-Z0-9_]+\\)$'" }; + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec(cmd); + + StreamForLsof lsof1 = new StreamForLsof(process.getInputStream()); + StreamForLsof lsof2 = new StreamForLsof(process.getErrorStream()); + lsof1.start(); + lsof2.start(); + while (true) { + if (!lsof1.isAlive() && !lsof2.isAlive()) { // 두개의 스레드가 정지할면 프로세스 종료때까지 기다린다. + process.waitFor(); + sb.append(lsof1.getData()); + break; + } + } + +// Process process = new ProcessBuilder(cmd).start(); +// InputStream is = process.getInputStream(); +// InputStreamReader isr = new InputStreamReader(is); +// BufferedReader br = new BufferedReader(isr); +// int result = process.waitFor(); +// +// sb.append("\nlsof"); +// sb.append("\n"); +// String line = ""; +// while ((line = br.readLine()) != null) { +// String[] cols = line.trim().split("[ ]+"); +// String separator = Env.isWindows() ? ":" : "."; +// sb.append(" " + line + "\n"); +// } +// sb.append(""); +// sb.append("\n"); + } catch (Exception e) { + logger.error("Error", e); + } + } + + /** + * threads info + */ + sb.append("\nthreads"); + sb.append("\n"); + ThreadGroup it = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[it.activeCount()]; + it.enumerate(threads); + + sb.append(""); + for (int i = 0; i < threads.length; i++) { + try { + if ((threads[i] != null && threads[i].getName() != null + && threads[i].getName() + .startsWith(adapterName.substring(adapterName.lastIndexOf('.') + 1) + "-")) + || (adapter.getThreadMap().get(threads[i]) != null)) { + sb.append(""); + sb.append(ThreadDumpUtil.getStackTrace(threads[i])); + sb.append(""); + } + } catch (Exception e) { + logger.error("Error", e); + } + } + sb.append("
"); + sb.append("
"); + sb.append("\n"); + + return "
" + sb.toString() + "
"; + } + + private String traceLevel(String adapterName, int level) throws Exception { +// StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter != null) + adapter.getContext().setTraceLevel(level); + return show(adapterName); + } + + private String clear(String adapterName) throws Exception { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + adapter.clearStat(); + return adapterName + " | statistics cleared successfully."; + } + + private String start(String adapterName) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + SimpleFuture future = adapter.start(); + Object result = future.join(60000L); + if (result instanceof Throwable) { + return "
" + ExceptionStackTrace.dump((Throwable) result) + "
"; + } + return adapterName + " | adapter successfully started"; + } else { + ISocketAdapter[] adapters = manager.getSocketAdapters(adapterName); + if (adapters == null) + throw new Exception("adapter group '" + adapterName + "' does not exist"); + for (int i = 0; i < adapters.length; i++) { + SimpleFuture future = adapters[i].start(); + Object result = future.join(60000L); + if (result instanceof Throwable) { + return "
" + ExceptionStackTrace.dump((Throwable) result) + "
"; + } + } + return adapterName + " | adapter group successfully started"; + } + } + + private String stop(String adapterName, boolean isForce) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + return adapterName + " | adapter does not exist"; + try { + SimpleFuture future = null; + if (isForce) { + future = adapter.stopForcely(); + } else { + future = adapter.stop(); + } + Object result = future.join(); + if (result instanceof Throwable) { + return "
" + ExceptionStackTrace.dump((Throwable) result) + "
"; + } + return adapterName + " | adapter successfully stopped"; + } catch (Exception e) { + return e.getMessage(); + } + } else { + ISocketAdapter[] adapters = manager.getSocketAdapters(adapterName); + if (adapters == null) + throw new Exception(adapterName + " | adapter group does not exist"); + for (int i = 0; i < adapters.length; i++) { + SimpleFuture future = null; + if (isForce) { + future = adapters[i].stopForcely(); + } else { + future = adapters[i].stop(); + } + Object result = future.join(); + if (result instanceof Throwable) { + return "
" + ExceptionStackTrace.dump((Throwable) result) + "
"; + } + } + return adapterName + " | adapter group successfully stopped"; + } + } + + final static String SCRIPT = " \n"; + + private String error(String adapterName) throws Exception { + StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception(adapterName + " - adapter does not exist"); + + String[] errors = adapter.getRecentErrors(); + + sb.append(SCRIPT); + sb.append("adapter = " + adapterName + "
"); + sb.append("\n"); + for (int i = errors.length - 1; i >= 0; i--) { + sb.append( + "
"); + sb.append("
");
+			sb.append(unescape(errors[i]));
+			sb.append("
"); + sb.append("
"); + sb.append("
"); + } + return sb.toString(); + + } + + private String sendRecv(String adapterName) throws Exception { + StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception(adapterName + " - adapter does not exist"); + + String[] msgs = adapter.getRecentSendRecv(); + + sb.append(SCRIPT); + sb.append("adapter = " + adapterName + "
"); + sb.append("\n"); + sb.append("
");
+		for (int i = msgs.length - 1; i >= 0; i--) {
+			sb.append(
+					"
"); + sb.append("
");
+			sb.append(unescape(msgs[i]));
+			sb.append("\n\n");
+			sb.append("
"); + sb.append("
"); + sb.append("
"); + } + sb.append("
\n"); + return sb.toString(); + } + + private String removeSession(String adapterName, String localPort, String remotePort) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + adapter.getSessionPool().remove(Integer.parseInt(localPort), Integer.parseInt(remotePort)); + return adapterName + " | adapter session remove local(" + localPort + ") remote(" + remotePort + ")"; + } + return "fail"; + } + + private String sessionValidate(String adapterName) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + adapter.getSessionPool().sessionValidate(); + return adapterName + " | adapter session validate"; + } + return "fail"; + } + + private String unescape(String string) { + string = string.replace("", "(b)").replace("", "(/b)"); + string = string.replaceAll("", "(a$1)").replace("", "(/a)"); + string = string.replaceAll("", "(font color='$1')").replace("", + "(/font)"); + string = string.replace(">", ">").replace("<", "<"); + string = string.replace("(b)", "").replace("(/b)", ""); + string = string.replaceAll("\\(a( href=\\'[a-zA-Z0-9_/]+\\')\\)", "").replace("(/a)", ""); + string = string.replaceAll("\\(font color='([a-zA-Z0-9# ]+)'\\)", "").replace("(/font)", + ""); + return string; + } + + class StreamForNetstat extends Thread { + InputStream is; + StringBuffer sb; + ISocketAdapter adapter; + + public StreamForNetstat(InputStream is, ISocketAdapter adapter) { + this.adapter = adapter; + this.is = is; + sb = new StringBuffer(); + } + + public void run() { + try { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + sb.append("\nnetstat"); + sb.append("\n"); + String line; + while ((line = br.readLine()) != null) { + if (!line.trim().toUpperCase().startsWith("TCP") && !line.trim().toUpperCase().startsWith("UDP")) + continue; + String[] cols = line.trim().split("[ ]+"); + String separator = Env.isWindows() ? ":" : "."; + if (Env.isWindows()) { + if (adapter.getContext().isServer()) { + if (!cols[1].endsWith(separator + adapter.getContext().getPortNumber())) { + continue; + } + } else { + if (!cols[2].equals(adapter.getContext().getHostName() + separator + + adapter.getContext().getPortNumber())) { + continue; + } + } + } else { + if (adapter.getContext().isServer()) { + if (!cols[3].endsWith(separator + adapter.getContext().getPortNumber())) { + continue; + } + } else { + if (!cols[4].equals(adapter.getContext().getHostName() + separator + + adapter.getContext().getPortNumber())) { + continue; + } + } + } + sb.append(" " + line + "\n"); + } + sb.append(""); + sb.append("\n"); + + } catch (IOException ioe) { + logger.error("StreamForNetstat", ioe); + } + } + + public String getData() { + return sb.toString(); + } + } + + class StreamForLsof extends Thread { + InputStream is; + StringBuffer sb; + + public StreamForLsof(InputStream is) { + this.is = is; + sb = new StringBuffer(); + } + + public void run() { + try { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + sb.append("\nlsof"); + sb.append("\n"); + String line = ""; + while ((line = br.readLine()) != null) { +// String[] cols = line.trim().split("[ ]+"); +// String separator = Env.isWindows() ? ":" : "."; + sb.append(" " + line + "\n"); + } + sb.append(""); + sb.append("\n"); + + } catch (IOException ioe) { + logger.error("StreamForLsof", ioe); + } + } + + public String getData() { + return sb.toString(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdapterJsonServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdapterJsonServlet.java new file mode 100644 index 0000000..dec4476 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdapterJsonServlet.java @@ -0,0 +1,773 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoSession; +import org.json.simple.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.Iterator; + +public class AdapterJsonServlet extends HttpServlet { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String command = request.getContext(); + if (command.lastIndexOf('/') == -1) { + command = ""; + } else { + command = command.substring(command.indexOf('/')+1); + } + + String result = ""; + + try { + if (command == null || "".equals(command) || "show".equals(command)) { + result = show(request.getParameter("adapter")); + } else if (command.startsWith("traceLevel")) { + result = traceLevel(request.getParameter("adapter"), Integer.parseInt(request.getParameter("level"))); + } else if (command.startsWith("clear")) { + result = clear(request.getParameter("adapter")); + } else if (command.startsWith("start")) { + String adapterName = request.getParameter("adapter"); + logger.fatal("HttpAdapter | " + adapterName + " | start - " + request.getSession()); + result = start(adapterName); + } else if (command.startsWith("stopforcely")) { + String adapterName = request.getParameter("adapter"); + logger.fatal("HttpAdapter | " + adapterName + " | stop - " + request.getSession()); + result = stop(adapterName, true); + } else if (command.startsWith("stop")) { + String adapterName = request.getParameter("adapter"); + logger.fatal("HttpAdapter | " + adapterName + " | stop - " + request.getSession()); + result = stop(adapterName, false); + } else if (command.startsWith("error")) { + result = error(request.getParameter("adapter")); + } else if (command.startsWith("sendRecv")) { + result = sendRecv(request.getParameter("adapter")); + } else if (command.startsWith("removeSession")) { + result = removeSession(request.getParameter("adapter"),request.getParameter("localPort"),request.getParameter("remotePort")); + } else if (command.startsWith("sessionValidate")) { + result = sessionValidate(request.getParameter("adapter")); + } else { + response.setResponseCode(404); + return; + } + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html;charset=utf-8;"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + private String show(String adapterName) throws Exception { + StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + + HashMap detail = new HashMap(); + detail.put("adapterName", adapterName); + + if(adapter == null) { + JSONObject json = new JSONObject(); + json.putAll(detail); + return json.toJSONString(); + } + detail.put("state", adapter.getState().name()); + detail.put("uptime" , TimeUtil.formatDate(adapter.getUptime().getTime())); + detail.put("pool" , adapter.getSessionPool().remaining() + "/" + (adapter.getSessionPool().peekSize())); + detail.put("recv", adapter.getMessageRecv()); + detail.put("send", adapter.getMessageSend()); + detail.put("error", adapter.getRecentErrorCount()); + detail.put("trace.level", adapter.getContext().getTraceLevel()); + + + if (adapter.getContext().getDescription() != null && !"".equals(adapter.getContext().getDescription().trim())) { + sb.append("\n " + adapter.getContext().getDescription() + "\n"); + } + + sb.append("\n\n"); + + /** + * common info + */ + sb.append(String.format("%4s %-30s : %s\n", "", "host.name", adapter.getContext().getHostName())); + sb.append(String.format("%4s %-30s : %s\n", "", "port.number", adapter.getContext().getPortNumber())); + sb.append(String.format("%4s %-30s : %s\n", "", "local.host.name", adapter.getContext().getLocalHostName())); + sb.append(String.format("%4s %-30s : %s\n", "", "local.port.number", adapter.getContext().getLocalPortNumber())); + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "protocol", adapter.getContext().getProtocol())); + sb.append(String.format("%4s %-30s : %s\n", "", "bound.usage", adapter.getContext().getBoundUsage())); + sb.append(String.format("%4s %-30s : %s\n", "", "socket.type", adapter.getContext().getSocketType())); + sb.append(String.format("%4s %-30s : %s\n", "", "response.type", adapter.getContext().getResponseType())); + sb.append(String.format("%4s %-30s : %s\n", "", "ack.support", adapter.getContext().getAckSupport())); + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "permanent", adapter.getContext().getPermanent())); + sb.append(String.format("%4s %-30s : %s\n", "", "blocking(NIO, BIO)", adapter.getContext().getBlocking())); + sb.append(String.format("%4s %-30s : %s (sec)\n", "", "timeout", adapter.getContext().getTimeout())); + sb.append(String.format("%4s %-30s : %s (sec)\n", "", "idle.timeout", adapter.getContext().getIdleTimeout())); + sb.append(String.format("%4s %-30s : %s\n", "", "socket.reuse", adapter.getContext().getSocketReuse())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "business.work.class.code", adapter.getContext().getBwkClsCd())); + sb.append(String.format("%4s %-30s : %s\n", "", "max.connection", (adapter.getContext().getCloseExistingConnection() ? "-" : "") + adapter.getContext().getMaxConnection())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "connection.limit.per.ip", adapter.getContext().getConnLimitPerIp())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "max.thread", adapter.getContext().getMaxThread())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "validation.rule", adapter.getContext().getValidationRule())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "acl.list", adapter.getContext().getAclList())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "block.ip.list", adapter.getContext().getBlockIpList())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "l4.skip.ip.list", adapter.getContext().getL4SkipIpList())); + + sb.append(String.format("%4s %-30s : %s\n\n", "", "is.single.session", adapter.getContext().getSingleSession())); + + + + if (adapter.getContext().isPollingUse()) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.use", adapter.getContext().getPollingUse())); + if ("".equals(adapter.getContext().getPollingRole().trim())) { + if (adapter.getContext().isPollingSender()) + sb.append(String.format("%4s %-30s : %s\n", "", "polling.role", "SENDER (client)")); + else + sb.append(String.format("%4s %-30s : %s\n", "", "polling.role", "RECEIVER (server)")); + } else { + sb.append(String.format("%4s %-30s : %s\n", "", "polling.role", adapter.getContext().getPollingRole())); + } + sb.append(String.format("%4s %-30s : %s\n", "", "polling.oneway", adapter.getContext().getPollingOneway())); + + if (adapter.getContext().isPollingReceiver()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "polling.timeout", adapter.getContext().getPollingTimeout())); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.request", adapter.getContext().getPollingRequest())); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.response.pattern", adapter.getContext().getPollingResponsePattern())); + if (adapter.getContext().isPollingReceiver()) { + sb.append(""); + } + + if (adapter.getContext().isPollingSender()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "polling.request.pattern", adapter.getContext().getPollingRequestPattern())); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.replacement", adapter.getContext().getPollingReplacement())); + if (adapter.getContext().isPollingSender()) { + sb.append(""); + } + + sb.append("\n"); + } + + //KSH + if (adapter.getContext().isInitMsgUse()) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.use", adapter.getContext().getInitMsgUse())); + if ("".equals(adapter.getContext().getInitMsgRole().trim())) { + if (adapter.getContext().isInitMsgSender()) + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.role", "SENDER (client)")); + else + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.role", "RECEIVER (server)")); + } else { + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.role", adapter.getContext().getInitMsgRole())); + } + + if (adapter.getContext().isInitMsgReceiver()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.request", adapter.getContext().getInitMsgRequest())); + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.response.pattern", adapter.getContext().getInitMsgResponsePattern())); + if (adapter.getContext().isInitMsgReceiver()) { + sb.append(""); + } + + if (adapter.getContext().isInitMsgSender()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.request.pattern", adapter.getContext().getInitMsgRequestPattern())); + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.replacement", adapter.getContext().getInitMsgReplacement())); + if (adapter.getContext().isInitMsgSender()) { + sb.append(""); + } + + sb.append("\n"); + } + + /** + * ll info (fixed length header) + */ + if ("FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "UDP_FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "EGSEED".equals(adapter.getContext().getProtocol()) + || "TCSEED".equals(adapter.getContext().getProtocol()) //20101213 JGY + || "ENVELOP".equals(adapter.getContext().getProtocol()) + || "XECURE".equals(adapter.getContext().getProtocol()) + || "XECURE2".equals(adapter.getContext().getProtocol()) + || "XECURE3".equals(adapter.getContext().getProtocol()) + || "XC3EPB".equals(adapter.getContext().getProtocol()) + ) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.type", adapter.getContext().getLlFieldType())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.offset", adapter.getContext().getLlFieldOffset())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.length", adapter.getContext().getLlFieldLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.include", adapter.getContext().getLlFieldInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.offset.exclude", adapter.getContext().getLlOffsetExclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.include", adapter.getContext().getLlInclude())); + } + + /** + * ll info (variable length payload) 20130719 KSH + */ + if ("VARIABLE_LENGTH_HEADER".equals(adapter.getContext().getProtocol())){ + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.type", adapter.getContext().getLlFieldType())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.offset", adapter.getContext().getLlFieldOffset())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.length", adapter.getContext().getLlFieldLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.include", adapter.getContext().getLlFieldInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.offset.exclude", adapter.getContext().getLlOffsetExclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.include", adapter.getContext().getLlInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "send.header.length", adapter.getContext().getSendHeaderLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "recv.header.length", adapter.getContext().getRecvHeaderLength())); + } + + + /** + * ll info (fixed length payload) + */ + if ("FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol()) + || "INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol()) // 20100515 JGY + || "UDP_FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "send.payload.length", adapter.getContext().getSendPayloadLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "recv.payload.length", adapter.getContext().getRecvPayloadLength())); + } + + /** + * xecure + */ + if ("XECURE".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.type", adapter.getContext().getXecureType())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.config.path", adapter.getContext().getXecureConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.remote.cert", adapter.getContext().getXecureRemoteCert())); + } + + /** + * xecure2 + */ + if ("XECURE2".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure2.config.path", adapter.getContext().getXecure2ConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure2.sm.ip", adapter.getContext().getXecure2SmIp())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure2.sm.port", adapter.getContext().getXecure2SmPort())); + // use CISCO interface only + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.type", adapter.getContext().getXecureType())); + } + + /** + * xecure3 20100901 JGY + */ + if ("XECURE3".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.cert.store", adapter.getContext().getXecure3CertStore())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.server.cert", adapter.getContext().getXecure3ServerCert())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.client.cert", adapter.getContext().getXecure3ClientCert())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.cert.key", adapter.getContext().getXecure3CertKey())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.cert.password", adapter.getContext().getXecure3CertPassword())); + } + + /** + * xc3epb 20210929 + */ + if ("XC3EPB".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xc3epb.password", adapter.getContext().getXc3epbPassword())); + sb.append(String.format("%4s %-30s : %s\n", "", "xc3epb.config.path", adapter.getContext().getXc3epbConfigPath())); + } + + /** + * inisafe + * inisafe_payload 20100515 JGY + */ + if ("INISAFE".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.related.adapter.groups", adapter.getContext().getInisafeRelatedAdapterGroups())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.start.message", adapter.getContext().getInisafeStartMessage())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.stop.message", adapter.getContext().getInisafeStopMessage())); + } + else if ("INISAFE_2020".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.related.adapter.groups", adapter.getContext().getInisafeRelatedAdapterGroups())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.start.message", adapter.getContext().getInisafeStartMessage())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.stop.message", adapter.getContext().getInisafeStopMessage())); + } + else if ("INISAFE_NATN".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.related.adapter.groups", adapter.getContext().getInisafeRelatedAdapterGroups())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.start.message", adapter.getContext().getInisafeStartMessage())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.stop.message", adapter.getContext().getInisafeStopMessage())); + } + else if ("INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.id.password", adapter.getContext().getInisafeIdPassword())); + } + + /** + * ENVELOP : JGY 20100423 + */ + if ("ENVELOP".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "envelop.signcert.path", adapter.getContext().getEnvelopSigncertPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "envelop.signkey.path", adapter.getContext().getEnvelopSignkeyPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "envelop.password", adapter.getContext().getEnvelopPassword())); + } + + /** + * TCSEED : JGY 20101213 + */ + if ("TCSEED".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "tcseed.key.store", adapter.getContext().getTcseedKeyStore())); + } + + /** + * script + */ + if (!"".equals(adapter.getContext().getScript().trim())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "script", "" + adapter.getContext().getScript() + "")); + } + + sb.append("\n"); + + /** + * session list + */ + sb.append("\nsession pool (remaining)\n"); + for (Iterator iii = adapter.getSessionPool().iterator() ; iii.hasNext(); ) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :");; + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + + if (adapter.getSessionPool().checkedOut() > 0) { + sb.append("session pool (checked out)\n"); + } + + for (Iterator iii = adapter.getSessionPool().checkedOutIterator() ; iii.hasNext(); ) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :");; + //sb.append(" [" + session.getTrafficMask() + "]"); + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + sb.append("\n"); + + /** + * netstat + */ + try { + String[] cmd; + if (Env.isWindows()) { + cmd = new String[] {"cmd.exe", "/c", "netstat -an | findstr " + adapter.getContext().getPortNumber()}; + } else { + cmd = new String[] {"sh", "-c", "netstat -an | grep -E 'tcp|udp' | grep " + adapter.getContext().getPortNumber()}; + } + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec(cmd); + + StreamForNetstat netstat1 = new StreamForNetstat(process.getInputStream(),adapter); + StreamForNetstat netstat2 = new StreamForNetstat(process.getErrorStream(),adapter); + netstat1.start(); + netstat2.start(); + while (true) { + if (!netstat1.isAlive() && !netstat2.isAlive()) { //두개의 스레드가 정지할면 프로세스 종료때까지 기다린다. + process.waitFor(); + sb.append(netstat1.getData()); + break; + } + } + + } catch(Exception e) { + logger.error("Error", e) ; + } + + /** + * lsof && ps + */ + if (!Env.isWindows()) { + try { + String[] cmd = new String[] {"sh", "-c", "lsof -iTCP" + + ("*".equals(adapter.getContext().getHostName()) ? "" : "@" + adapter.getContext().getHostName()) + + ":" + adapter.getContext().getPortNumber() + + //" | grep " + adapter.getContext().getHostName() + + " | grep -E '\\([A-Z0-9_]+\\)$'" }; + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec(cmd); + + StreamForLsof lsof1 = new StreamForLsof(process.getInputStream()); + StreamForLsof lsof2 = new StreamForLsof(process.getErrorStream()); + lsof1.start(); + lsof2.start(); + while (true) { + if (!lsof1.isAlive() && !lsof2.isAlive()) { //두개의 스레드가 정지할면 프로세스 종료때까지 기다린다. + process.waitFor(); + sb.append(lsof1.getData()); + break; + } + } + + + } catch(Exception e) { + logger.error("Error", e) ; + } + } + + + /** + * threads info + */ + sb.append("\nthreads"); + ThreadGroup it = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[it.activeCount()] ; + it.enumerate(threads); + + sb.append(""); + for (int i=0; i"); + sb.append(ThreadDumpUtil.getStackTrace(threads[i])); + sb.append(""); + } + } catch(Exception e) { + logger.error("Error", e) ; + } + } + sb.append("
"); + sb.append("\n"); + + detail.put("data", sb.toString()); + + JSONObject json = new JSONObject(); + json.putAll(detail); + + return json.toJSONString(); + } + + private String traceLevel(String adapterName, int level) throws Exception { +// StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if(adapter != null) adapter.getContext().setTraceLevel(level); + return show(adapterName); + } + + private String clear(String adapterName) throws Exception { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + adapter.clearStat(); + return adapterName + " | statistics cleared successfully."; + } + + private String start(String adapterName) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + SimpleFuture future = adapter.start(); + Object result = future.join(60000L); + if (result instanceof Throwable) { + return "
" + ExceptionStackTrace.dump((Throwable) result) + "
"; + } + return adapterName + " | adapter successfully started"; + } else { + ISocketAdapter[] adapters = manager.getSocketAdapters(adapterName); + if (adapters == null) + throw new Exception("adapter group '" + adapterName + "' does not exist"); + for (int i=0; i" + ExceptionStackTrace.dump((Throwable) result) + ""; + } + } + return adapterName + " | adapter group successfully started"; + } + } + + private String stop(String adapterName, boolean isForce) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + return adapterName + " | adapter does not exist"; + try { + SimpleFuture future = null; + if (isForce) { + future = adapter.stopForcely(); + } else { + future = adapter.stop(); + } + Object result = future.join(); + if (result instanceof Throwable) { + return "
" + ExceptionStackTrace.dump((Throwable) result) + "
"; + } + return adapterName + " | adapter successfully stopped"; + } catch(Exception e) { + return e.getMessage(); + } + } else { + ISocketAdapter[] adapters = manager.getSocketAdapters(adapterName); + if (adapters == null) + throw new Exception(adapterName + " | adapter group does not exist"); + for (int i=0; i" + ExceptionStackTrace.dump((Throwable) result) + ""; + } + } + return adapterName + " | adapter group successfully stopped"; + } + } + + final static String SCRIPT = + " \n"; + + private String error(String adapterName) throws Exception { + StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception(adapterName + " - adapter does not exist"); + + String[] errors = adapter.getRecentErrors(); + + sb.append(SCRIPT); + sb.append("adapter = " + adapterName + "
"); + sb.append("\n"); + for (int i=errors.length-1; i>=0; i--) { + sb.append("
"); + sb.append("
");
+    		sb.append(unescape(errors[i]));
+    	   	sb.append("
"); + sb.append("
"); + sb.append("
"); + } + return sb.toString(); + + } + + private String sendRecv(String adapterName) throws Exception { + StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception(adapterName + " - adapter does not exist"); + + String[] msgs = adapter.getRecentSendRecv(); + + sb.append(SCRIPT); + sb.append("adapter = " + adapterName + "
"); + sb.append("\n"); + sb.append("
");
+    	for (int i=msgs.length-1; i>=0; i--) {
+    		sb.append("
"); + sb.append("
");
+    	   	sb.append(unescape(msgs[i]));
+    	   	sb.append("\n\n");
+    	   	sb.append("
"); + sb.append("
"); + sb.append("
"); + } + sb.append("
\n"); + return sb.toString(); + } + private String removeSession(String adapterName, String localPort, String remotePort) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + adapter.getSessionPool().remove(Integer.parseInt(localPort), Integer.parseInt(remotePort)); + return adapterName + " | adapter session remove local("+localPort+") remote("+remotePort+")"; + } + return "fail"; + } + private String sessionValidate(String adapterName) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + adapter.getSessionPool().sessionValidate(); + return adapterName + " | adapter session validate"; + } + return "fail"; + } + + private String unescape(String string) { + string = string.replace("", "(b)").replace("", "(/b)"); + string = string.replaceAll("", "(a$1)").replace("", "(/a)"); + string = string.replaceAll("", "(font color='$1')").replace("", "(/font)"); + string = string.replace(">", ">").replace("<", "<"); + string = string.replace("(b)", "").replace("(/b)", ""); + string = string.replaceAll("\\(a( href=\\'[a-zA-Z0-9_/]+\\')\\)", "").replace("(/a)", ""); + string = string.replaceAll("\\(font color='([a-zA-Z0-9# ]+)'\\)", "").replace("(/font)", ""); + return string; + } + class StreamForNetstat extends Thread + { + InputStream is; + StringBuffer sb ; + ISocketAdapter adapter; + public StreamForNetstat(InputStream is,ISocketAdapter adapter) { + this.adapter = adapter; + this.is = is; + sb = new StringBuffer(); + } + + public void run() + { + try { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + sb.append("\nnetstat"); + sb.append("\n"); + String line; + while ((line = br.readLine()) != null) { + if (!line.trim().toUpperCase().startsWith("TCP") && !line.trim().toUpperCase().startsWith("UDP")) + continue; + String[] cols = line.trim().split("[ ]+"); + String separator = Env.isWindows() ? ":" : "."; + if (Env.isWindows()) { + if (adapter.getContext().isServer()) { + if(!cols[1].endsWith(separator + adapter.getContext().getPortNumber())) { + continue; + } + } else { + if(!cols[2].equals(adapter.getContext().getHostName() + separator + adapter.getContext().getPortNumber())) { + continue; + } + } + } else { + if (adapter.getContext().isServer()) { + if(!cols[3].endsWith(separator + adapter.getContext().getPortNumber())) { + continue; + } + } else { + if(!cols[4].equals(adapter.getContext().getHostName() + separator + adapter.getContext().getPortNumber())) { + continue; + } + } + } + sb.append(" " + line + "\n"); + } + sb.append(""); + sb.append("\n"); + + } catch (IOException ioe) { + logger.error("StreamForNetstat", ioe); + } + } + public String getData(){ + return sb.toString(); + } + } + class StreamForLsof extends Thread + { + InputStream is; + StringBuffer sb ; + public StreamForLsof(InputStream is) { + this.is = is; + sb = new StringBuffer(); + } + + public void run() + { + try { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + sb.append("\nlsof"); + sb.append("\n"); + String line = ""; + while ((line = br.readLine()) != null) { +// String[] cols = line.trim().split("[ ]+"); +// String separator = Env.isWindows() ? ":" : "."; + sb.append(" " + line + "\n"); + } + sb.append(""); + sb.append("\n"); + + } catch (IOException ioe) { + logger.error("StreamForLsof", ioe); + } + } + public String getData(){ + return sb.toString(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdapterServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdapterServlet.java new file mode 100644 index 0000000..b10c835 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdapterServlet.java @@ -0,0 +1,845 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoSession; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Iterator; + +public class AdapterServlet extends HttpServlet { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String command = request.getContext(); + if (command.lastIndexOf('/') == -1) { + command = ""; + } else { + command = command.substring(command.indexOf('/')+1); + } + + String result = ""; + + try { + if (command == null || "".equals(command) || "show".equals(command)) { + result = show(request.getParameter("adapter")); + } else if (command.startsWith("traceLevel")) { + result = traceLevel(request.getParameter("adapter"), Integer.parseInt(request.getParameter("level"))); + } else if (command.startsWith("clear")) { + result = clear(request.getParameter("adapter")); + } else if (command.startsWith("start")) { + String adapterName = request.getParameter("adapter"); + logger.fatal("HttpAdapter | " + adapterName + " | start - " + request.getSession()); + result = start(adapterName); + } else if (command.startsWith("stopforcely")) { + String adapterName = request.getParameter("adapter"); + logger.fatal("HttpAdapter | " + adapterName + " | stop - " + request.getSession()); + result = stop(adapterName, true); + } else if (command.startsWith("stop")) { + String adapterName = request.getParameter("adapter"); + logger.fatal("HttpAdapter | " + adapterName + " | stop - " + request.getSession()); + result = stop(adapterName, false); + } else if (command.startsWith("error")) { + result = error(request.getParameter("adapter")); + } else if (command.startsWith("sendRecv")) { + result = sendRecv(request.getParameter("adapter")); + } else if (command.startsWith("removeSession")) { + result = removeSession(request.getParameter("adapter"),request.getParameter("localPort"),request.getParameter("remotePort")); + } else if (command.startsWith("sessionValidate")) { + result = sessionValidate(request.getParameter("adapter")); + } else { + response.setResponseCode(404); + return; + } + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html;charset=utf-8;"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + private String show(String adapterName) throws Exception { + StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + sb.append(adapterName); + + if(adapter == null) { + sb.append(" Not found adapter (" + adapterName + ")"); + return sb.toString(); + } + /** + * status + */ + if ("STARTED".equals(adapter.getState().name())) { + sb.append(" (" + adapter.getState().name() + ")"); + } else { + sb.append(" (" + adapter.getState().name() + ")"); + } + + sb.append(" uptime:" + TimeUtil.formatDate(adapter.getUptime().getTime())); + sb.append(", pool:" + adapter.getSessionPool().remaining() + "/" + (adapter.getSessionPool().peekSize())); + sb.append(", recv:" + "" + adapter.getMessageRecv() + ""); + sb.append(", send:" + "" + adapter.getMessageSend() + ""); + if (adapter.getRecentErrorCount() > 0) { + sb.append(", "); + sb.append(""); + sb.append("error:" + adapter.getRecentErrorCount()); + sb.append(""); + } else { + sb.append(", error:" + adapter.getRecentErrorCount()); + } + + sb.append(", (clear)"); + + sb.append(" (start"); + sb.append("|stop)"); + + if (adapter.getContext().getDescription() != null && !"".equals(adapter.getContext().getDescription().trim())) { + sb.append("\n " + adapter.getContext().getDescription() + "\n"); + } + + sb.append("\n\n"); + + /** + * common info + */ + sb.append(String.format("%4s %-30s : %s\n", "", "host.name", adapter.getContext().getHostName())); + sb.append(String.format("%4s %-30s : %s\n", "", "port.number", adapter.getContext().getPortNumber())); + sb.append(String.format("%4s %-30s : %s\n", "", "local.host.name", adapter.getContext().getLocalHostName())); + sb.append(String.format("%4s %-30s : %s\n", "", "local.port.number", adapter.getContext().getLocalPortNumber())); + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "protocol", adapter.getContext().getProtocol())); + sb.append(String.format("%4s %-30s : %s\n", "", "bound.usage", adapter.getContext().getBoundUsage())); + sb.append(String.format("%4s %-30s : %s\n", "", "socket.type", adapter.getContext().getSocketType())); + sb.append(String.format("%4s %-30s : %s\n", "", "response.type", adapter.getContext().getResponseType())); + sb.append(String.format("%4s %-30s : %s\n", "", "ack.support", adapter.getContext().getAckSupport())); + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "permanent", adapter.getContext().getPermanent())); + sb.append(String.format("%4s %-30s : %s\n", "", "blocking(NIO, BIO)", adapter.getContext().getBlocking())); + sb.append(String.format("%4s %-30s : %s (sec)\n", "", "timeout", adapter.getContext().getTimeout())); + sb.append(String.format("%4s %-30s : %s (sec)\n", "", "idle.timeout", adapter.getContext().getIdleTimeout())); + sb.append(String.format("%4s %-30s : %s\n", "", "socket.reuse", adapter.getContext().getSocketReuse())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "business.work.class.code", adapter.getContext().getBwkClsCd())); + sb.append(String.format("%4s %-30s : %s\n", "", "max.connection", (adapter.getContext().getCloseExistingConnection() ? "-" : "") + adapter.getContext().getMaxConnection())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "connection.limit.per.ip", adapter.getContext().getConnLimitPerIp())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "max.thread", adapter.getContext().getMaxThread())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "validation.rule", adapter.getContext().getValidationRule())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "datacontrol.rule", adapter.getContext().getDataControlRule())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "acl.list", adapter.getContext().getAclList())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "block.ip.list", adapter.getContext().getBlockIpList())); + sb.append(String.format("%4s %-30s : %s\n\n", "", "l4.skip.ip.list", adapter.getContext().getL4SkipIpList())); + + sb.append(String.format("%4s %-30s : %s\n\n", "", "is.single.session", adapter.getContext().getSingleSession())); + + int traceLevel = adapter.getContext().getTraceLevel(); + switch(traceLevel) { + case 0: + sb.append(String.format("%4s %-30s : %s %s %s %s\n", "", "trace.level", + "0(DEFAULT)", + "1", + "2", + "3")); + break; + case 1: + sb.append(String.format("%4s %-30s : %s %s %s %s\n", "", "trace.level", + "0", + "1(INFO)", + "2", + "3")); + break; + case 2: + sb.append(String.format("%4s %-30s : %s %s %s %s\n", "", "trace.level", + "0", + "1", + "2(DEBUG)", + "3")); + break; + case 3: + sb.append(String.format("%4s %-30s : %s %s %s %s\n", "", "trace.level", + "0", + "1", + "2", + "3(TRACE)")); + break; + } + + if (adapter.getContext().isPollingUse()) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.use", adapter.getContext().getPollingUse())); + if ("".equals(adapter.getContext().getPollingRole().trim())) { + if (adapter.getContext().isPollingSender()) + sb.append(String.format("%4s %-30s : %s\n", "", "polling.role", "SENDER (client)")); + else + sb.append(String.format("%4s %-30s : %s\n", "", "polling.role", "RECEIVER (server)")); + } else { + sb.append(String.format("%4s %-30s : %s\n", "", "polling.role", adapter.getContext().getPollingRole())); + } + sb.append(String.format("%4s %-30s : %s\n", "", "polling.oneway", adapter.getContext().getPollingOneway())); + + if (adapter.getContext().isPollingReceiver()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "polling.timeout", adapter.getContext().getPollingTimeout())); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.request", adapter.getContext().getPollingRequest())); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.response.pattern", adapter.getContext().getPollingResponsePattern())); + if (adapter.getContext().isPollingReceiver()) { + sb.append(""); + } + + if (adapter.getContext().isPollingSender()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "polling.request.pattern", adapter.getContext().getPollingRequestPattern())); + sb.append(String.format("%4s %-30s : %s\n", "", "polling.replacement", adapter.getContext().getPollingReplacement())); + if (adapter.getContext().isPollingSender()) { + sb.append(""); + } + + sb.append("\n"); + } + + //KSH + if (adapter.getContext().isInitMsgUse()) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.use", adapter.getContext().getInitMsgUse())); + if ("".equals(adapter.getContext().getInitMsgRole().trim())) { + if (adapter.getContext().isInitMsgSender()) + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.role", "SENDER (client)")); + else + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.role", "RECEIVER (server)")); + } else { + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.role", adapter.getContext().getInitMsgRole())); + } + + if (adapter.getContext().isInitMsgReceiver()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.request", adapter.getContext().getInitMsgRequest())); + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.response.pattern", adapter.getContext().getInitMsgResponsePattern())); + if (adapter.getContext().isInitMsgReceiver()) { + sb.append(""); + } + + if (adapter.getContext().isInitMsgSender()) { + sb.append(""); + } + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.request.pattern", adapter.getContext().getInitMsgRequestPattern())); + sb.append(String.format("%4s %-30s : %s\n", "", "init.msg.replacement", adapter.getContext().getInitMsgReplacement())); + if (adapter.getContext().isInitMsgSender()) { + sb.append(""); + } + + sb.append("\n"); + } + + /** + * ll info (fixed length header) + */ + if ("FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "UDP_FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "EGSEED".equals(adapter.getContext().getProtocol()) + || "TCSEED".equals(adapter.getContext().getProtocol()) //20101213 JGY + || "ENVELOP".equals(adapter.getContext().getProtocol()) + || "XECURE".equals(adapter.getContext().getProtocol()) + || "XECURE2".equals(adapter.getContext().getProtocol()) + || "XECURE3".equals(adapter.getContext().getProtocol()) + || "XC3EPB".equals(adapter.getContext().getProtocol()) + ) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.type", adapter.getContext().getLlFieldType())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.offset", adapter.getContext().getLlFieldOffset())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.length", adapter.getContext().getLlFieldLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.include", adapter.getContext().getLlFieldInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.offset.exclude", adapter.getContext().getLlOffsetExclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.include", adapter.getContext().getLlInclude())); + } + + /** + * ll info (variable length payload) 20130719 KSH + */ + if ("VARIABLE_LENGTH_HEADER".equals(adapter.getContext().getProtocol())){ + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.type", adapter.getContext().getLlFieldType())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.offset", adapter.getContext().getLlFieldOffset())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.length", adapter.getContext().getLlFieldLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.include", adapter.getContext().getLlFieldInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.offset.exclude", adapter.getContext().getLlOffsetExclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.include", adapter.getContext().getLlInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "send.header.length", adapter.getContext().getSendHeaderLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "recv.header.length", adapter.getContext().getRecvHeaderLength())); + } + + + /** + * ll info (fixed length payload) + */ + if ("FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol()) + || "INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol()) // 20100515 JGY + || "UDP_FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "send.payload.length", adapter.getContext().getSendPayloadLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "recv.payload.length", adapter.getContext().getRecvPayloadLength())); + } + + /** + * xecure + */ + if ("XECURE".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.type", adapter.getContext().getXecureType())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.config.path", adapter.getContext().getXecureConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.remote.cert", adapter.getContext().getXecureRemoteCert())); + } + + /** + * xecure2 + */ + if ("XECURE2".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure2.config.path", adapter.getContext().getXecure2ConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure2.sm.ip", adapter.getContext().getXecure2SmIp())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure2.sm.port", adapter.getContext().getXecure2SmPort())); + // use CISCO interface only + sb.append(String.format("%4s %-30s : %s\n", "", "xecure.type", adapter.getContext().getXecureType())); + } + + /** + * xecure3 20100901 JGY + */ + if ("XECURE3".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.cert.store", adapter.getContext().getXecure3CertStore())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.server.cert", adapter.getContext().getXecure3ServerCert())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.client.cert", adapter.getContext().getXecure3ClientCert())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.cert.key", adapter.getContext().getXecure3CertKey())); + sb.append(String.format("%4s %-30s : %s\n", "", "xecure3.cert.password", adapter.getContext().getXecure3CertPassword())); + } + + /** + * xc3epb 20210929 + */ + if ("XC3EPB".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "xc3epb.password", adapter.getContext().getXc3epbPassword())); + sb.append(String.format("%4s %-30s : %s\n", "", "xc3epb.config.path", adapter.getContext().getXc3epbConfigPath())); + } + + /** + * inisafe + * inisafe_payload 20100515 JGY + */ + if ("INISAFE".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.related.adapter.groups", adapter.getContext().getInisafeRelatedAdapterGroups())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.start.message", adapter.getContext().getInisafeStartMessage())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.stop.message", adapter.getContext().getInisafeStopMessage())); + } + else if ("INISAFE_2020".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.related.adapter.groups", adapter.getContext().getInisafeRelatedAdapterGroups())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.start.message", adapter.getContext().getInisafeStartMessage())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.stop.message", adapter.getContext().getInisafeStopMessage())); + } + else if ("INISAFE_NATN".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.related.adapter.groups", adapter.getContext().getInisafeRelatedAdapterGroups())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.start.message", adapter.getContext().getInisafeStartMessage())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.stop.message", adapter.getContext().getInisafeStopMessage())); + } + else if ("INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.config.path", adapter.getContext().getInisafeConfigPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "inisafe.id.password", adapter.getContext().getInisafeIdPassword())); + } + + /** + * ENVELOP : JGY 20100423 + */ + if ("ENVELOP".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "envelop.signcert.path", adapter.getContext().getEnvelopSigncertPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "envelop.signkey.path", adapter.getContext().getEnvelopSignkeyPath())); + sb.append(String.format("%4s %-30s : %s\n", "", "envelop.password", adapter.getContext().getEnvelopPassword())); + } + + /** + * TCSEED : JGY 20101213 + */ + if ("TCSEED".equals(adapter.getContext().getProtocol())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "tcseed.key.store", adapter.getContext().getTcseedKeyStore())); + } + + if ("DYNAMIC_OFFSET".equals(adapter.getContext().getProtocol()) ) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.type", adapter.getContext().getLlFieldType())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.offset", adapter.getContext().getLlFieldOffset())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.length", adapter.getContext().getLlFieldLength())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.field.include", adapter.getContext().getLlFieldInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.offset.exclude", adapter.getContext().getLlOffsetExclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "ll.include", adapter.getContext().getLlInclude())); + sb.append(String.format("%4s %-30s : %s\n", "", "dynamic.offset.pattern", adapter.getContext().getDynamicOffsetPattern())); + sb.append(String.format("%4s %-30s : %s\n", "", "data.add.rule", adapter.getContext().getDataAddRule())); + sb.append(String.format("%4s %-30s : %s\n", "", "data.remove.rule", adapter.getContext().getDataRemoveRule())); + } + + /** + * script + */ + if (!"".equals(adapter.getContext().getScript().trim())) { + sb.append("\n"); + sb.append(String.format("%4s %-30s : %s\n", "", "script", "" + adapter.getContext().getScript() + "")); + } + + sb.append("\n"); + + /** + * session list + */ + sb.append("\nsession pool (remaining)\n"); + sb.append(""); + for (Iterator iii = adapter.getSessionPool().iterator() ; iii.hasNext(); ) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :");; + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + sb.append(""); + + if (adapter.getSessionPool().checkedOut() > 0) { + sb.append("session pool (checked out)\n"); + } + + sb.append(""); + for (Iterator iii = adapter.getSessionPool().checkedOutIterator() ; iii.hasNext(); ) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :");; + //sb.append(" [" + session.getTrafficMask() + "]"); + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + sb.append(""); + sb.append("\n"); + + /** + * netstat + */ + try { + String[] cmd; + if (Env.isWindows()) { + cmd = new String[] {"cmd.exe", "/c", "netstat -an | findstr " + adapter.getContext().getPortNumber()}; + } else { + cmd = new String[] {"sh", "-c", "netstat -an | grep -E 'tcp|udp' | grep " + adapter.getContext().getPortNumber()}; + } + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec(cmd); + + StreamForNetstat netstat1 = new StreamForNetstat(process.getInputStream(),adapter); + StreamForNetstat netstat2 = new StreamForNetstat(process.getErrorStream(),adapter); + netstat1.start(); + netstat2.start(); + while (true) { + if (!netstat1.isAlive() && !netstat2.isAlive()) { //두개의 스레드가 정지할면 프로세스 종료때까지 기다린다. + process.waitFor(); + sb.append(netstat1.getData()); + break; + } + } + } catch(Exception e) { + logger.error("Error", e) ; + } + + /** + * lsof && ps + */ + if (!Env.isWindows()) { + try { + String[] cmd = new String[] {"sh", "-c", "lsof -iTCP" + + ("*".equals(adapter.getContext().getHostName()) ? "" : "@" + adapter.getContext().getHostName()) + + ":" + adapter.getContext().getPortNumber() + + //" | grep " + adapter.getContext().getHostName() + + " | grep -E '\\([A-Z0-9_]+\\)$'" }; + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec(cmd); + + StreamForLsof lsof1 = new StreamForLsof(process.getInputStream()); + StreamForLsof lsof2 = new StreamForLsof(process.getErrorStream()); + lsof1.start(); + lsof2.start(); + while (true) { + if (!lsof1.isAlive() && !lsof2.isAlive()) { //두개의 스레드가 정지할면 프로세스 종료때까지 기다린다. + process.waitFor(); + sb.append(lsof1.getData()); + break; + } + } + +// Process process = new ProcessBuilder(cmd).start(); +// InputStream is = process.getInputStream(); +// InputStreamReader isr = new InputStreamReader(is); +// BufferedReader br = new BufferedReader(isr); +// int result = process.waitFor(); +// +// sb.append("\nlsof"); +// sb.append("\n"); +// String line = ""; +// while ((line = br.readLine()) != null) { +// String[] cols = line.trim().split("[ ]+"); +// String separator = Env.isWindows() ? ":" : "."; +// sb.append(" " + line + "\n"); +// } +// sb.append(""); +// sb.append("\n"); + } catch(Exception e) { + logger.error("Error", e) ; + } + } + + + /** + * threads info + */ + sb.append("\nthreads"); + sb.append("\n"); + ThreadGroup it = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[it.activeCount()] ; + it.enumerate(threads); + + sb.append(""); + for (int i=0; i"); + sb.append(ThreadDumpUtil.getStackTrace(threads[i])); + sb.append(""); + } + } catch(Exception e) { + logger.error("Error", e) ; + } + } + sb.append("
"); + sb.append("
"); + sb.append("\n"); + + return "
" + sb.toString() + "
"; + } + + private String traceLevel(String adapterName, int level) throws Exception { +// StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if(adapter != null) adapter.getContext().setTraceLevel(level); + return show(adapterName); + } + + private String clear(String adapterName) throws Exception { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + adapter.clearStat(); + return adapterName + " | statistics cleared successfully."; + } + + private String start(String adapterName) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + SimpleFuture future = adapter.start(); + Object result = future.join(60000L); + if (result instanceof Throwable) { + return "
" + ExceptionStackTrace.dump((Throwable) result) + "
"; + } + return adapterName + " | adapter successfully started"; + } else { + ISocketAdapter[] adapters = manager.getSocketAdapters(adapterName); + if (adapters == null) + throw new Exception("adapter group '" + adapterName + "' does not exist"); + for (int i=0; i" + ExceptionStackTrace.dump((Throwable) result) + ""; + } + } + return adapterName + " | adapter group successfully started"; + } + } + + private String stop(String adapterName, boolean isForce) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + return adapterName + " | adapter does not exist"; + try { + SimpleFuture future = null; + if (isForce) { + future = adapter.stopForcely(); + } else { + future = adapter.stop(); + } + Object result = future.join(); + if (result instanceof Throwable) { + return "
" + ExceptionStackTrace.dump((Throwable) result) + "
"; + } + return adapterName + " | adapter successfully stopped"; + } catch(Exception e) { + return e.getMessage(); + } + } else { + ISocketAdapter[] adapters = manager.getSocketAdapters(adapterName); + if (adapters == null) + throw new Exception(adapterName + " | adapter group does not exist"); + for (int i=0; i" + ExceptionStackTrace.dump((Throwable) result) + ""; + } + } + return adapterName + " | adapter group successfully stopped"; + } + } + + final static String SCRIPT = + " \n"; + + private String error(String adapterName) throws Exception { + StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception(adapterName + " - adapter does not exist"); + + String[] errors = adapter.getRecentErrors(); + + sb.append(SCRIPT); + sb.append("adapter = " + adapterName + "
"); + sb.append("\n"); + for (int i=errors.length-1; i>=0; i--) { + sb.append("
"); + sb.append("
");
+    		sb.append(unescape(errors[i]));
+    	   	sb.append("
"); + sb.append("
"); + sb.append("
"); + } + return sb.toString(); + + } + + private String sendRecv(String adapterName) throws Exception { + StringBuffer sb = new StringBuffer(); + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception(adapterName + " - adapter does not exist"); + + String[] msgs = adapter.getRecentSendRecv(); + + sb.append(SCRIPT); + sb.append("adapter = " + adapterName + "
"); + sb.append("\n"); + sb.append("
");
+    	for (int i=msgs.length-1; i>=0; i--) {
+    		sb.append("
"); + sb.append("
");
+    	   	sb.append(unescape(msgs[i]));
+    	   	sb.append("\n\n");
+    	   	sb.append("
"); + sb.append("
"); + sb.append("
"); + } + sb.append("
\n"); + return sb.toString(); + } + private String removeSession(String adapterName, String localPort, String remotePort) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + adapter.getSessionPool().remove(Integer.parseInt(localPort), Integer.parseInt(remotePort)); + return adapterName + " | adapter session remove local("+localPort+") remote("+remotePort+")"; + } + return "fail"; + } + private String sessionValidate(String adapterName) throws Exception { + if (adapterName.indexOf('.') != -1) { + ISocketAdapter adapter = manager.getSocketAdapter(adapterName); + if (adapter == null) + throw new Exception("adapter does not exist"); + adapter.getSessionPool().sessionValidate(); + return adapterName + " | adapter session validate"; + } + return "fail"; + } + + private String unescape(String string) { + string = string.replace("", "(b)").replace("", "(/b)"); + string = string.replaceAll("", "(a$1)").replace("", "(/a)"); + string = string.replaceAll("", "(font color='$1')").replace("", "(/font)"); + string = string.replace(">", ">").replace("<", "<"); + string = string.replace("(b)", "").replace("(/b)", ""); + string = string.replaceAll("\\(a( href=\\'[a-zA-Z0-9_/]+\\')\\)", "").replace("(/a)", ""); + string = string.replaceAll("\\(font color='([a-zA-Z0-9# ]+)'\\)", "").replace("(/font)", ""); + return string; + } + class StreamForNetstat extends Thread + { + InputStream is; + StringBuffer sb ; + ISocketAdapter adapter; + public StreamForNetstat(InputStream is,ISocketAdapter adapter) { + this.adapter = adapter; + this.is = is; + sb = new StringBuffer(); + } + + public void run() + { + try { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + sb.append("\nnetstat"); + sb.append("\n"); + String line; + while ((line = br.readLine()) != null) { + if (!line.trim().toUpperCase().startsWith("TCP") && !line.trim().toUpperCase().startsWith("UDP")) + continue; + String[] cols = line.trim().split("[ ]+"); + String separator = Env.isWindows() ? ":" : "."; + if (Env.isWindows()) { + if (adapter.getContext().isServer()) { + if(!cols[1].endsWith(separator + adapter.getContext().getPortNumber())) { + continue; + } + } else { + if(!cols[2].equals(adapter.getContext().getHostName() + separator + adapter.getContext().getPortNumber())) { + continue; + } + } + } else { + if (adapter.getContext().isServer()) { + if(!cols[3].endsWith(separator + adapter.getContext().getPortNumber())) { + continue; + } + } else { + if(!cols[4].equals(adapter.getContext().getHostName() + separator + adapter.getContext().getPortNumber())) { + continue; + } + } + } + sb.append(" " + line + "\n"); + } + sb.append(""); + sb.append("\n"); + + } catch (IOException ioe) { + logger.error("StreamForNetstat", ioe); + } + } + public String getData(){ + return sb.toString(); + } + } + class StreamForLsof extends Thread + { + InputStream is; + StringBuffer sb ; + public StreamForLsof(InputStream is) { + this.is = is; + sb = new StringBuffer(); + } + + public void run() + { + try { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + sb.append("\nlsof"); + sb.append("\n"); + String line = ""; + while ((line = br.readLine()) != null) { +// String[] cols = line.trim().split("[ ]+"); +// String separator = Env.isWindows() ? ":" : "."; + sb.append(" " + line + "\n"); + } + sb.append(""); + sb.append("\n"); + + } catch (IOException ioe) { + logger.error("StreamForLsof", ioe); + } + } + public String getData(){ + return sb.toString(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdaptersJsonServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdaptersJsonServlet.java new file mode 100644 index 0000000..d5c53e0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdaptersJsonServlet.java @@ -0,0 +1,364 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoSession; +import org.json.simple.JSONArray; + +import java.net.URLDecoder; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; + +public class AdaptersJsonServlet extends HttpServlet { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String filter = request.getContext(); + filter = filter.substring(filter.indexOf('/')+1); + if ("adaptersJson".equals(filter)) { + filter = null; + } + + String result = ""; + try { + result = list(filter); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + if (!"".equals(request.getParameter("refresh"))) { + response.appendBody("\n\n"); + } + + response.setContentType("text/html;charset=utf-8;"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + private String list(String filter) { +// boolean verbose = false; + //StringBuffer sb = new StringBuffer(); + try{ + filter = URLDecoder.decode(filter,"UTF-8"); + }catch(Exception e){ + if(filter != null) filter = filter.trim(); + } + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) SocketAdapterManager.getInstance().getSocketAdapterGroups(); + List list = new ArrayList(); + String prevAdapterGroupName = ""; + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = (String) e.nextElement(); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + + for (Enumeration ee = adapters.elements() ; ee.hasMoreElements() ;) { + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + if (filter != null && adapter.getContext().getAdapterName().toLowerCase().indexOf(filter.toLowerCase()) == -1 + && adapter.getContext().getProtocol().toLowerCase().indexOf(filter.toLowerCase()) == -1 + && String.valueOf(adapter.getContext().getPortNumber()).toLowerCase().indexOf(filter.toLowerCase()) == -1 + && adapter.getContext().getDescription().indexOf(filter.toLowerCase()) == -1) + continue; + + HashMap row = new HashMap(); + row.put("adapterGroupName", adapterGroupName); + row.put("adapterName", adapter.getContext().getAdapterName()); + row.put("state", adapter.getState().name()); + if (Env.isWindows()) { + row.put("status", ""); + }else{ + row.put("status", getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName())); + + } + row.put("uptime", TimeUtil.formatDate(adapter.getUptime().getTime())); + if (adapter.getSessionPool() != null) { + row.put("pool", adapter.getSessionPool().remaining() + "/" + (adapter.getSessionPool().peekSize())); + } + row.put("recv", adapter.getMessageRecv()); + row.put("send", adapter.getMessageSend()); + + row.put("error", adapter.getRecentErrorCount()); + + row.put("trace", adapter.getContext().getTraceLevel()); + + + StringBuffer sb = new StringBuffer(); + sb.append(adapter.getContext().getProtocol()); + sb.append(", " + adapter.getContext().getBoundUsage() ); + sb.append(", " + adapter.getContext().getSocketType() ); + if (adapter.getContext().isClient()) { + sb.append(" (" + adapter.getContext().getLocalHostName() + ":" + adapter.getContext().getLocalPortNumber()); + sb.append("->"); + sb.append("/" + adapter.getContext().getHostName() + ":" + adapter.getContext().getPortNumber() + ")"); + } else { + sb.append(" (" + adapter.getContext().getHostName() + ":" + adapter.getContext().getPortNumber()); + sb.append("<-)"); + } + if(adapter.getContext().isSync()) { + sb.append(", SYNC"); + } else { + sb.append(", ASYN"); + } + if ("Y".equals(adapter.getContext().getAckSupport())) { + sb.append(", ACK"); + } else { + sb.append(", NO_ACK"); + } + if(adapter.getContext().isPermanent()) { + sb.append(", PERMANENT"); + } else { + sb.append(", NON_PERM"); + } + if(adapter.getContext().isBlocking()) { + sb.append(", BIO"); + } else { + sb.append(", NIO"); + } + sb.append(", max_conn:" + (adapter.getContext().getCloseExistingConnection() ? "-" : "") + adapter.getContext().getMaxConnection()); + sb.append(", limit_per_ip:" + adapter.getContext().getConnLimitPerIp()); + sb.append(", max_thread:" + adapter.getContext().getMaxThread()); + +// switch(adapter.getContext().getTraceLevel()) { +// case 0: +// sb.append(", 0(DEFAULT)"); +// break; +// case 1: +// sb.append(", 1(INFO)"); +// break; +// case 2: +// sb.append(", 2(DEBUG)"); +// break; +// case 3: +// sb.append(", 3(TRACE)"); +// break; +// } + + if (adapter.getContext().isPollingUse()) { + sb.append("\n("); + sb.append("POLLING"); + sb.append(", " + adapter.getContext().getPollingRole()); + if (adapter.getContext().isPollingOneway()) { + sb.append(", oneway"); + } + sb.append(", " + adapter.getContext().getPollingTimeout()); +// sb.append(", " + adapter.getContext().getPollingRequest()); +// sb.append(", " + adapter.getContext().getPollingRequestPattern()); +// sb.append(", " + adapter.getContext().getPollingReplacement()); +// sb.append(", " + adapter.getContext().getPollingResponsePattern()); + sb.append(")"); + } + //KSH + if (adapter.getContext().isInitMsgUse()) { + sb.append("\n("); + sb.append("INIT_MSG"); + sb.append(", " + adapter.getContext().getInitMsgRole()); + sb.append(")"); + } + + if ("FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "UDP_FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "VARIABLE_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) //20130719 KSH + || "EGSEED".equals(adapter.getContext().getProtocol()) + || "TCSEED".equals(adapter.getContext().getProtocol()) //20101213 JGY + || "ENVELOP".equals(adapter.getContext().getProtocol()) + || "XECURE".equals(adapter.getContext().getProtocol()) + || "XECURE2".equals(adapter.getContext().getProtocol()) + || "XECURE3".equals(adapter.getContext().getProtocol()) + || "XC3EPB".equals(adapter.getContext().getProtocol()) + ) { + sb.append("\n("); + sb.append("type=" + adapter.getContext().getLlFieldType()); + sb.append(", offset=" + adapter.getContext().getLlFieldOffset()); + sb.append(", length=" + adapter.getContext().getLlFieldLength()); + sb.append(", ll.field.include=" + adapter.getContext().getLlFieldInclude()); + sb.append(", ll.offset.exclude=" + adapter.getContext().getLlOffsetExclude()); + sb.append(", ll.include=" + adapter.getContext().getLlInclude()); + sb.append(")"); + } + + if ("VARIABLE_LENGTH_HEADER".equals(adapter.getContext().getProtocol())) { // 20130719 KSH + sb.append("\n("); + sb.append("send.header.length="); + sb.append(adapter.getContext().getSendHeaderLength()); + sb.append(", recv.header.length="); + sb.append(adapter.getContext().getRecvHeaderLength()); + sb.append(")"); + } + + if ("FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol()) + || "INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol()) // 20100515 JGY + || "UDP_FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n("); + sb.append("send.payload.length="); + sb.append(adapter.getContext().getSendPayloadLength()); + sb.append(", recv.payload.length="); + sb.append(adapter.getContext().getRecvPayloadLength()); + sb.append(")"); + } + + if ("XECURE".equals(adapter.getContext().getProtocol()) + || "XECURE3".equals(adapter.getContext().getProtocol())) { + sb.append("\n("); + sb.append(adapter.getContext().getXecureType()); + sb.append(", " + adapter.getContext().getXecureConfigPath()); + sb.append(", " + adapter.getContext().getXecureRemoteCert()); + sb.append(")"); + } + if ("XC3EPB".equals(adapter.getContext().getProtocol())) { + sb.append("\n("); + sb.append("XC3EPB"); + sb.append(", " + adapter.getContext().getXc3epbPassword()); + sb.append(", " + adapter.getContext().getXc3epbConfigPath()); + sb.append(")"); + } + + if ("INISAFE".equals(adapter.getContext().getProtocol())) { + sb.append("\n("); + sb.append("INISAFE"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeRelatedAdapterGroups()); + sb.append(", " + adapter.getContext().getInisafeStartMessage()); + sb.append(", " + adapter.getContext().getInisafeStopMessage()); + sb.append(")"); + } + + if ("INISAFE_2020".equals(adapter.getContext().getProtocol())) { + sb.append("\n("); + sb.append("INISAFE_2020"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeRelatedAdapterGroups()); + sb.append(", " + adapter.getContext().getInisafeStartMessage()); + sb.append(", " + adapter.getContext().getInisafeStopMessage()); + sb.append(")"); + } + + if ("INISAFE_NATN".equals(adapter.getContext().getProtocol())) { + sb.append("\n("); + sb.append("INISAFE_NATN"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeRelatedAdapterGroups()); + sb.append(", " + adapter.getContext().getInisafeStartMessage()); + sb.append(", " + adapter.getContext().getInisafeStopMessage()); + sb.append(")"); + } + + // JGY 20100515 + if ("INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n("); + sb.append("INISAFE_PAYLOAD"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeIdPassword()); + sb.append(")"); + } + + // JGY 20100423 + if ("ENVELOP".equals(adapter.getContext().getProtocol())) { + sb.append("\n("); + sb.append("ENVELOP"); + sb.append(", " + adapter.getContext().getEnvelopSigncertPath()); + sb.append(", " + adapter.getContext().getEnvelopSignkeyPath()); + sb.append(", " + adapter.getContext().getEnvelopPassword()); + sb.append(")"); + } + + // JGY 20101213 + if ("TCSEED".equals(adapter.getContext().getProtocol())) { + sb.append("\n("); + sb.append("TCSEED"); + sb.append(", " + adapter.getContext().getTcseedKeyStore());; + sb.append(")"); + } + + if (adapter.getContext().getDescription() != null && !"".equals(adapter.getContext().getDescription().trim())) { + sb.append("\n(" + adapter.getContext().getDescription() + ")"); + } + + + row.put("data", sb.toString()); + + ArrayList normal = new ArrayList(); + StringBuffer sessionsb = null; + for (Iterator iii = adapter.getSessionPool().iterator() ; iii.hasNext(); ) { + sessionsb = new StringBuffer(); + IoSession session = (IoSession) iii.next(); + if (!session.isConnected()) + sessionsb.append("●"); + else if (session.isClosing()) + sessionsb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sessionsb.append("⊙"); + else + sessionsb.append("○"); + sessionsb.append(" Session :");; + if (session.isClosing()) + sessionsb.append(" [CLOSING]"); + if (!session.isConnected()) + sessionsb.append(" [NOT CONNECTED]"); + sessionsb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sessionsb.append(", recv:" + session.getReadMessages()); + sessionsb.append("(" + session.getReadBytes() + ")"); + sessionsb.append(", send:" + session.getWrittenMessages()); + sessionsb.append("(" + session.getWrittenBytes() + ")"); + sessionsb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sessionsb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) ); + normal.add(sessionsb.toString()); + } + ArrayList delay = new ArrayList(); + for (Iterator iii = adapter.getSessionPool().checkedOutIterator() ; iii.hasNext(); ) { + sessionsb = new StringBuffer(); + IoSession session = (IoSession) iii.next(); + if (!session.isConnected()) + sessionsb.append("●"); + else if (session.isClosing()) + sessionsb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sessionsb.append("⊙"); + else + sessionsb.append("○"); + sessionsb.append(" Session :");; + if (session.isClosing()) + sessionsb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sessionsb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sessionsb.append(", recv:" + session.getReadMessages()); + sessionsb.append("(" + session.getReadBytes() + ")"); + sessionsb.append(", send:" + session.getWrittenMessages()); + sessionsb.append("(" + session.getWrittenBytes() + ")"); + sessionsb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sessionsb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + delay.add(sessionsb.toString()); + } + row.put("normal", normal); + row.put("delay", delay); + list.add(row); + prevAdapterGroupName = adapterGroupName; + } + } + JSONArray array = new JSONArray(); + array.addAll(list); + return array.toJSONString(); + } + +// private String prop() { +// return ""; +// } + + protected boolean getAdapterStatus(String adapterGroupName, String adapterName) { + AdapterManager manager = AdapterManager.getInstance(); + AdapterVO vo = manager.getAdapterVO(adapterGroupName, adapterName); + if (vo != null) { + return vo.isStatus(); + } + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdaptersServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdaptersServlet.java new file mode 100644 index 0000000..78db6b0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/AdaptersServlet.java @@ -0,0 +1,387 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoSession; + +import java.net.URLDecoder; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; + +public class AdaptersServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String filter = request.getContext(); + filter = filter.substring(filter.indexOf('/')+1); + if ("adapters".equals(filter)) { + filter = null; + } + + String result = ""; + try { + result = list(filter); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + if (!"".equals(request.getParameter("refresh"))) { + response.appendBody("\n\n"); + } + + response.setContentType("text/html;charset=utf-8;"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + private String list(String filter) { +// boolean verbose = false; + StringBuffer sb = new StringBuffer(); + try{ + filter = URLDecoder.decode(filter,"UTF-8"); + }catch(Exception e){ + if(filter != null) filter = filter.trim(); + } + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) SocketAdapterManager.getInstance().getSocketAdapterGroups(); + + String prevAdapterGroupName = ""; + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = (String) e.nextElement(); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + + for (Enumeration ee = adapters.elements() ; ee.hasMoreElements() ;) { + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + if (filter != null && adapter.getContext().getAdapterName().toLowerCase().indexOf(filter.toLowerCase()) == -1 + && adapter.getContext().getProtocol().toLowerCase().indexOf(filter.toLowerCase()) == -1 + && String.valueOf(adapter.getContext().getPortNumber()).toLowerCase().indexOf(filter.toLowerCase()) == -1 + && adapter.getContext().getDescription().indexOf(filter.toLowerCase()) == -1) + continue; + + if (!adapterGroupName.equals(prevAdapterGroupName)) { + sb.append("ⓖ " + adapterGroupName); + sb.append("\n"); + } + + sb.append(" ⓐ "); + sb.append(adapter.getContext().getAdapterName()); + sb.append(""); + + sb.append(" ("); + if ("STARTED".equals(adapter.getState().name())) { + sb.append(adapter.getState().name()); + } else { + sb.append("" + adapter.getState().name() + ""); + } + if (!Env.isWindows()) { + sb.append(", " + getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName())); + } + sb.append(")"); + + sb.append(" uptime:" + TimeUtil.formatDate(adapter.getUptime().getTime())); + if (adapter.getSessionPool() != null) { + sb.append(", pool:" + adapter.getSessionPool().remaining() + "/" + (adapter.getSessionPool().peekSize())); + } + sb.append(", recv:" + "" + adapter.getMessageRecv() + ""); + sb.append(", send:" + "" + adapter.getMessageSend() + ""); + if (adapter.getRecentErrorCount() > 0) { + sb.append(", "); + sb.append(""); + sb.append("error:" + adapter.getRecentErrorCount()); + sb.append(""); + } else { + sb.append(", error:" + adapter.getRecentErrorCount()); + } + + sb.append(" (start"); + sb.append("|stop)"); +// sb.append(" sessionValidate"); + + sb.append("\n "); + sb.append(""); + sb.append(""); + sb.append(adapter.getContext().getProtocol()); + sb.append(""); + sb.append(", " + adapter.getContext().getBoundUsage() + ""); + sb.append(", " + adapter.getContext().getSocketType() + ""); + if (adapter.getContext().isClient()) { + sb.append(" (" + adapter.getContext().getLocalHostName() + ":" + adapter.getContext().getLocalPortNumber()); + sb.append("->"); + sb.append("/" + adapter.getContext().getHostName() + ":" + adapter.getContext().getPortNumber() + ")"); + } else { + sb.append(" (" + adapter.getContext().getHostName() + ":" + adapter.getContext().getPortNumber()); + sb.append("<-)"); + } + if(adapter.getContext().isSync()) { + sb.append(", SYNC"); + } else { + sb.append(", ASYN"); + } + if ("Y".equals(adapter.getContext().getAckSupport())) { + sb.append(", ACK"); + } else { + sb.append(", NO_ACK"); + } + if(adapter.getContext().isPermanent()) { + sb.append(", PERMANENT"); + } else { + sb.append(", NON_PERM"); + } + if(adapter.getContext().isBlocking()) { + sb.append(", BIO"); + } else { + sb.append(", NIO"); + } + sb.append(", max_conn:" + (adapter.getContext().getCloseExistingConnection() ? "-" : "") + adapter.getContext().getMaxConnection()); + sb.append(", limit_per_ip:" + adapter.getContext().getConnLimitPerIp()); + sb.append(", max_thread:" + adapter.getContext().getMaxThread()); + + switch(adapter.getContext().getTraceLevel()) { + case 0: + sb.append(", 0(DEFAULT)"); + break; + case 1: + sb.append(", 1(INFO)"); + break; + case 2: + sb.append(", 2(DEBUG)"); + break; + case 3: + sb.append(", 3(TRACE)"); + break; + } + + if (adapter.getContext().isPollingUse()) { + sb.append("\n ("); + sb.append("POLLING"); + sb.append(", " + adapter.getContext().getPollingRole()); + if (adapter.getContext().isPollingOneway()) { + sb.append(", oneway"); + } + sb.append(", " + adapter.getContext().getPollingTimeout()); +// sb.append(", " + adapter.getContext().getPollingRequest()); +// sb.append(", " + adapter.getContext().getPollingRequestPattern()); +// sb.append(", " + adapter.getContext().getPollingReplacement()); +// sb.append(", " + adapter.getContext().getPollingResponsePattern()); + sb.append(")"); + } + //KSH + if (adapter.getContext().isInitMsgUse()) { + sb.append("\n ("); + sb.append("INIT_MSG"); + sb.append(", " + adapter.getContext().getInitMsgRole()); + sb.append(")"); + } + + if ("FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "UDP_FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "VARIABLE_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) //20130719 KSH + || "EGSEED".equals(adapter.getContext().getProtocol()) + || "TCSEED".equals(adapter.getContext().getProtocol()) //20101213 JGY + || "ENVELOP".equals(adapter.getContext().getProtocol()) + || "XECURE".equals(adapter.getContext().getProtocol()) + || "XECURE2".equals(adapter.getContext().getProtocol()) + || "XECURE3".equals(adapter.getContext().getProtocol()) + || "XC3EPB".equals(adapter.getContext().getProtocol()) + ) { + sb.append("\n ("); + sb.append("type=" + adapter.getContext().getLlFieldType()); + sb.append(", offset=" + adapter.getContext().getLlFieldOffset()); + sb.append(", length=" + adapter.getContext().getLlFieldLength()); + sb.append(", ll.field.include=" + adapter.getContext().getLlFieldInclude()); + sb.append(", ll.offset.exclude=" + adapter.getContext().getLlOffsetExclude()); + sb.append(", ll.include=" + adapter.getContext().getLlInclude()); + sb.append(")"); + } + + if ("VARIABLE_LENGTH_HEADER".equals(adapter.getContext().getProtocol())) { // 20130719 KSH + sb.append("\n ("); + sb.append("send.header.length="); + sb.append(adapter.getContext().getSendHeaderLength()); + sb.append(", recv.header.length="); + sb.append(adapter.getContext().getRecvHeaderLength()); + sb.append(")"); + } + + if ("FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol()) + || "INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol()) // 20100515 JGY + || "UDP_FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("send.payload.length="); + sb.append(adapter.getContext().getSendPayloadLength()); + sb.append(", recv.payload.length="); + sb.append(adapter.getContext().getRecvPayloadLength()); + sb.append(")"); + } + + if ("XECURE".equals(adapter.getContext().getProtocol()) + || "XECURE3".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append(""); + sb.append(adapter.getContext().getXecureType()); + sb.append(""); + sb.append(", " + adapter.getContext().getXecureConfigPath()); + sb.append(", " + adapter.getContext().getXecureRemoteCert()); + sb.append(")"); + } + if ("XC3EPB".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("XC3EPB"); + sb.append(", " + adapter.getContext().getXc3epbPassword()); + sb.append(", " + adapter.getContext().getXc3epbConfigPath()); + sb.append(")"); + } + if ("INISAFE".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("INISAFE"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeRelatedAdapterGroups()); + sb.append(", " + adapter.getContext().getInisafeStartMessage()); + sb.append(", " + adapter.getContext().getInisafeStopMessage()); + sb.append(")"); + } + + if ("INISAFE_2020".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("INISAFE_2020"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeRelatedAdapterGroups()); + sb.append(", " + adapter.getContext().getInisafeStartMessage()); + sb.append(", " + adapter.getContext().getInisafeStopMessage()); + sb.append(")"); + } + + if ("INISAFE_NATN".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("INISAFE_NATN"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeRelatedAdapterGroups()); + sb.append(", " + adapter.getContext().getInisafeStartMessage()); + sb.append(", " + adapter.getContext().getInisafeStopMessage()); + sb.append(")"); + } + + // JGY 20100515 + if ("INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("INISAFE_PAYLOAD"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeIdPassword()); + sb.append(")"); + } + + // JGY 20100423 + if ("ENVELOP".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("ENVELOP"); + sb.append(", " + adapter.getContext().getEnvelopSigncertPath()); + sb.append(", " + adapter.getContext().getEnvelopSignkeyPath()); + sb.append(", " + adapter.getContext().getEnvelopPassword()); + sb.append(")"); + } + + // JGY 20101213 + if ("TCSEED".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("TCSEED"); + sb.append(", " + adapter.getContext().getTcseedKeyStore());; + sb.append(")"); + } + + if (adapter.getContext().getDescription() != null && !"".equals(adapter.getContext().getDescription().trim())) { + sb.append("\n (" + adapter.getContext().getDescription() + ")"); + } + + sb.append(""); + + sb.append("\n"); + for (Iterator iii = adapter.getSessionPool().iterator() ; iii.hasNext(); ) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :");; + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) ); + +// InetSocketAddress local =(InetSocketAddress)session.getLocalAddress(); +// InetSocketAddress remote =(InetSocketAddress)session.getRemoteAddress(); +// sb.append(", remove session" ); + sb.append("\n"); + } + sb.append(""); + + sb.append("\n"); + for (Iterator iii = adapter.getSessionPool().checkedOutIterator() ; iii.hasNext(); ) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :");; + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + sb.append(""); + sb.append("\n"); + + prevAdapterGroupName = adapterGroupName; + } + } + + return "
" + sb.toString() + "
"; + } + +// private String prop() { +// return ""; +// } + + protected boolean getAdapterStatus(String adapterGroupName, String adapterName) { + AdapterManager manager = AdapterManager.getInstance(); + AdapterVO vo = manager.getAdapterVO(adapterGroupName, adapterName); + if (vo != null) { + return vo.isStatus(); + } + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/CheckServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/CheckServlet.java new file mode 100644 index 0000000..f0490b4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/CheckServlet.java @@ -0,0 +1,201 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.*; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import org.dom4j.Document; +import org.dom4j.DocumentHelper; +import org.dom4j.Element; + +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketTimeoutException; +import java.net.URL; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.ConcurrentHashMap; + +public class CheckServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String option = request.getContext(); + if (option.lastIndexOf('/') == -1) { + option = ""; + } else { + option = option.substring(option.indexOf('/')+1); + } + + String result = show("full".equals(option)); + + response.setContentType("text/xml"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody("\n"); + response.appendBody(result); //.getBytes("UTF-8")); + } + + private String show(boolean checkConnect) throws Exception { + Document document = DocumentHelper.createDocument(); + Element root = document.addElement("adapters"); + + /** + * [1] Socket Adapter + */ + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) SocketAdapterManager.getInstance().getSocketAdapterGroups(); + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = (String) e.nextElement(); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + + for (Enumeration ee = adapters.elements() ; ee.hasMoreElements() ;) { + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + Element adapterNode = root.addElement("adapter"); + adapterNode.addElement("name").addText(adapter.getContext().getAdapterName()); + adapterNode.addElement("type").addText("socket"); + adapterNode.addElement("group").addText(adapterGroupName); + adapterNode.addElement("desc").addText(adapter.getContext().getDescription()); + + /** + * status + */ + String cause = ""; + if (adapter.getContext().isServer()) { + if (adapter.getState() == ISocketAdapter.State.STARTED) { + if (adapter.getContext().isPermanent()) { + if (adapter.getSessionPool().peekSize() > 0) { + adapterNode.addElement("status").addText("O"); + } else { + adapterNode.addElement("status").addText("X"); + cause = "SERVER/PERMANENT - no established session"; + } + } else { + adapterNode.addElement("status").addText("O"); + } + } else { + adapterNode.addElement("status").addText("X"); + cause = "SERVER - adapter not started, adapter status = " + adapter.getState().name(); + } + } else { + if (adapter.getState() == ISocketAdapter.State.STARTED) { + if (adapter.getContext().isPermanent()) { + if (adapter.getSessionPool().peekSize() > 0) { + adapterNode.addElement("status").addText("O"); + } else { + adapterNode.addElement("status").addText("X"); + cause = "CLIENT/PERMANENT - no established session"; + } + } else { + try { + checkRemote(adapter.getContext().getHostName(), adapter.getContext().getPortNumber(), checkConnect); + adapterNode.addElement("status").addText("O"); + } catch(Exception ex) { + adapterNode.addElement("status").addText("X"); + cause = "CLIENT/NON-PERM - cannot connect remote server - " + ex.getMessage(); + } + } + } else { + if ("INISAFE".equals(adapter.getContext().getProtocol())) { + adapterNode.addElement("status").addText("O"); + } + else if ("INISAFE_2020".equals(adapter.getContext().getProtocol())) { + adapterNode.addElement("status").addText("O"); + } + else if ("INISAFE_NATN".equals(adapter.getContext().getProtocol())) { + adapterNode.addElement("status").addText("O"); + } + else { + adapterNode.addElement("status").addText("X"); + cause = "CLIENT - adapter not started, adapter status = " + adapter.getState().name(); + } + } + } + + adapterNode.addElement("cause").addText(cause); + } + } + + /** + * [2] Http Adapter + */ + List groups = AdapterManager.getInstance().getAllAdapterGroupNames(); + for (Iterator iter = groups.iterator(); iter.hasNext();) { + String groupName = (String) iter.next(); + AdapterGroupVO groupVO = AdapterManager.getInstance().getAdapterGroupVO(groupName); + + if (!"HTT".equals(groupVO.getType()) + && !"HQS".equals(groupVO.getType()) + && !"HXC".equals(groupVO.getType())) { + continue; + } + + for (Iterator iter2 = groupVO.getAdapters() ; iter2.hasNext() ;) { + AdapterVO adapterVO = (AdapterVO) iter2.next(); + //PropGroupVO propGroupVO = PropManager.getInstance().getPropGroupVO(adapterVO.getPropGroupName()); + AdapterPropGroupVO propGroupVO = AdapterPropManager.getInstance().getAdapterPropGroupVO(adapterVO.getPropGroupName()); + Element adapterNode = root.addElement("adapter"); + adapterNode.addElement("name").addText(adapterVO.getName()); + adapterNode.addElement("type").addText("http"); + adapterNode.addElement("group").addText(groupName); + adapterNode.addElement("desc").addText(adapterVO.getDescription()); + + //adapterNode.addElement("status").addText(adapterVO.getListenerClass()); + //adapterNode.addElement("cause").addText(adapterVO.getPropGroupName()); + + /** + * status + */ + String cause = ""; + if ("I".equals(groupVO.getGubun())) { + if (adapterVO.isStatus()) { + adapterNode.addElement("status").addText("O"); + } else { + adapterNode.addElement("status").addText("X"); + } + } else { + if (adapterVO.isStatus()) { + String urlString = propGroupVO.getProperty("URL"); + try { + URL url = new URL(urlString); + checkRemote(url.getHost(), url.getPort(), checkConnect); + adapterNode.addElement("status").addText("O"); + } catch(SocketTimeoutException ex) { + adapterNode.addElement("status").addText("X"); + cause = "CLIENT - cannot connect remote server - " + urlString; + } catch(Exception ex) { + adapterNode.addElement("status").addText("X"); + cause = ex.getMessage(); + } + } else { + adapterNode.addElement("status").addText("X"); + } + } + + adapterNode.addElement("cause").addText(cause); + } + } + + return root.asXML(); + } + + private boolean checkRemote(String host, int port, boolean checkConnect) throws Exception { + if (!checkConnect) { + return true; + } + + Socket socket = null; + try { + socket = new Socket(); + socket.connect(new InetSocketAddress(host, port), 2000); + return true; + } finally { + if (socket != null) + try { socket.close(); } catch(Exception e) {} + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ControlServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ControlServlet.java new file mode 100644 index 0000000..c649476 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ControlServlet.java @@ -0,0 +1,197 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URLDecoder; + +public class ControlServlet extends HttpServlet { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String command = request.getContext(); + if (command.lastIndexOf('/') == -1) { + command = ""; + } else { + command = command.substring(command.indexOf('/')+1); + } + String result = ""; + try { + if (command == null || "".equals(command) || "list".equals(command)) { + result += list(request.getParameter("adapter")); + } else if (command.startsWith("start")) { + result += start(request.getParameter("adapter")); + } else if (command.startsWith("stop")) { + result += stop(request.getParameter("adapter")); + } else if (command.startsWith("free")) { + result += free(request.getParameter("adapter")); + } else { + response.setResponseCode(404); + return; + } + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } +// if (!"".equals(request.getParameter("refresh"))) { +// response.appendBody("\n\n"); +// } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + + } + + private String list(String filter) { +// boolean verbose = false; +// StringBuffer sb = new StringBuffer(); + try{ + filter = URLDecoder.decode(filter,"UTF-8"); + }catch(Exception e){ + filter = null; + } + if (filter == null){ + return cmd(" ps -ef | grep tcp "); + }else{ + return cmd(" ps -ef | grep tcp | grep "+filter); + } + } + private String free(String filter) { +// boolean verbose = false; +// StringBuffer sb = new StringBuffer(); + try{ + filter = URLDecoder.decode(filter,"UTF-8"); + }catch(Exception e){ + filter = null; + } + if (filter == null){ + return ""; + }else{ + return cmd(filter); + } + } + private String start(String filter) { +// boolean verbose = false; +// StringBuffer sb = new StringBuffer(); + try{ + filter = URLDecoder.decode(filter,"UTF-8"); + }catch(Exception e){ + filter = null; + } + if (filter == null){ + return ""; + }else{ + return cmd(" devstart "+filter); + } + } + private String stop(String filter) { +// boolean verbose = false; +// StringBuffer sb = new StringBuffer(); + try{ + filter = URLDecoder.decode(filter,"UTF-8"); + }catch(Exception e){ + filter = null; + } + if (filter == null){ + return ""; + }else{ + return cmd(" devstop "+filter); + } + } + + private String cmd(String command){ + + StringBuffer sb = new StringBuffer(); + try { + String[] cmd = new String[] {"sh", "-c", command}; + Runtime runtime = Runtime.getRuntime(); + Process process = runtime.exec(cmd); + +// Process process = new ProcessBuilder(cmd).start(); + + StreamGobbler gb1 = new StreamGobbler(process.getInputStream()); + StreamGobbler gb2 = new StreamGobbler(process.getErrorStream()); + gb1.start(); + gb2.start(); + + while (true) { + if (!gb1.isAlive() && !gb2.isAlive()) { //두개의 스레드가 정지할면 프로세스 종료때까지 기다린다. + process.waitFor(); + sb.append(gb1.getData()); + break; + } + } + +// InputStream is = process.getInputStream(); +// InputStreamReader isr = new InputStreamReader(is); +// BufferedReader br = new BufferedReader(isr); +// int result = process.waitFor(); +// sb.append(""); +// String line; +// while ((line = br.readLine()) != null) { +// sb.append(""); +// sb.append( line + "\n"); +// sb.append(""); +// } +// sb.append(""); + } catch(Exception e) { + // ignore + sb.append("cmd failed"); + } + return sb.toString(); + } +// private String prop() { +// return ""; +// } + + protected boolean getAdapterStatus(String adapterGroupName, String adapterName) { + AdapterManager manager = AdapterManager.getInstance(); + AdapterVO vo = manager.getAdapterVO(adapterGroupName, adapterName); + if (vo != null) { + return vo.isStatus(); + } + return false; + } + class StreamGobbler extends Thread + { + InputStream is; + StringBuffer sb ; + public StreamGobbler(InputStream is) { + this.is = is; + sb = new StringBuffer(); + } + + public void run() + { + try { + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + sb.append(""); + String line; + while ((line = br.readLine()) != null) { + sb.append(""); + sb.append( line + "\n"); + sb.append(""); + } + sb.append(""); + } catch (IOException ioe) { + logger.info("run error - "+ ioe.toString()); + } + } + public String getData(){ + return sb.toString(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ErrorServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ErrorServlet.java new file mode 100644 index 0000000..311610d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ErrorServlet.java @@ -0,0 +1,83 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.SocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; + +public class ErrorServlet extends HttpServlet { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + static String uptime = TimeUtil.formatDate(System.currentTimeMillis()); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String filter = request.getContext(); + filter = filter.substring(filter.indexOf('/')+1); + if ("error".equals(filter)) { + filter = null; + } + + String result = ""; + + try { + result = error(filter); + } catch(Throwable e) { + result = ExceptionStackTrace.dump(e); + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody("uptime : " + uptime + ""); + response.appendBody("

"); + response.appendBody("socket adapters  "); + response.appendBody("socket zombies  | "); + response.appendBody("http adapters  | "); +// response.appendBody("socket adapters error  | "); + //2020.03.04 링크추가요청반영 + response.appendBody("layout  "); + response.appendBody("transform  "); + response.appendBody("transformer/error  "); + response.appendBody("
"); + response.appendBody(result); + } + + final static String SCRIPT = + " \n"; + + private String error(String filter) throws Exception { + StringBuffer sb = new StringBuffer(); + String[] errors = SocketAdapter.getGlobalErrors(); + + sb.append(SCRIPT); + sb.append("

socket adapter global errors

"); + for (int i=errors.length-1; i>=0; i--) { + if (filter != null && errors[i].toLowerCase().indexOf(filter.toLowerCase()) == -1) { + continue; + } + + sb.append("
"); + sb.append("
");
+    		sb.append(errors[i].replace(">", ">").replace("<", "<"));
+    	   	sb.append("
"); + sb.append("
"); + sb.append("
"); + } + return sb.toString(); + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/FileServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/FileServlet.java new file mode 100644 index 0000000..fcc9f3f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/FileServlet.java @@ -0,0 +1,62 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import java.io.BufferedReader; +import java.io.FileReader; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; + +public class FileServlet extends HttpServlet { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String fname = request.getContext(); + fname = fname.substring(fname.indexOf('/')+1); + if ("file".equals(fname)) { + fname = null; + } + + String result = ""; + try { + result = fread(fname); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + + } + + private String fread(String fname) throws Exception { + StringBuilder sb = new StringBuilder(); + BufferedReader in = new BufferedReader(new FileReader(fname)); + try { + sb.append("
");
+	        String line;
+	        while ((line = in.readLine()) != null) {
+	            sb.append(line + "\n");
+	        }
+	        sb.append("
"); + } + catch(Exception e) { + logger.error(e); + } + finally { + try { + if(in != null) in.close(); + } + catch(Exception e) { + logger.error(e); + } + } + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/GroovyServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/GroovyServlet.java new file mode 100644 index 0000000..93dd245 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/GroovyServlet.java @@ -0,0 +1,56 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import groovy.lang.Binding; +import groovy.lang.GroovyShell; + +public class GroovyServlet extends HttpServlet { + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String method = request.getHeader("Method")[0]; + if ("GET".equals(method)) { + doGet(request, response); + } else { + doPost(request, response); + } + } + + protected void doGet(HttpRequest request, HttpResponse response) throws Exception { + StringBuilder sb = new StringBuilder(); + + sb.append("
"); + sb.append(""); + sb.append(""); + sb.append("
"); + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(sb.toString()); + } + + protected void doPost(HttpRequest request, HttpResponse response) throws Exception { +// System.out.println(request.getParameter("")); + + StringBuilder sb = new StringBuilder(); + + Binding binding = new Binding(); + binding.setVariable("request", request); + binding.setVariable("response", request); + GroovyShell shell = new GroovyShell(binding); + + shell.evaluate(request.getParameter("")); + //return (byte[]) binding.getVariable("response"); + + sb.append(request); + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(sb.toString()); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/MemoryServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/MemoryServlet.java new file mode 100644 index 0000000..8e1a331 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/MemoryServlet.java @@ -0,0 +1,37 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; + +import java.text.DecimalFormat; + +public class MemoryServlet extends HttpServlet { + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody("
");
+		response.appendBody(memoryStat());
+		response.appendBody("
"); + } + + private String memoryStat() throws Exception { + Runtime rt = Runtime.getRuntime(); + long total = rt.totalMemory(); + long free = rt.freeMemory(); + long max = rt.maxMemory(); + + DecimalFormat df = new DecimalFormat("###,###,###");; + + StringBuilder sb = new StringBuilder(); + sb.append(String.format("total : %15s B\n", df.format(total))); + sb.append(String.format(" used : %15s B\n", df.format(total-free))); + sb.append(String.format(" free : %15s B\n", df.format(free))); + sb.append(String.format(" max : %15s B\n", df.format(max))); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/PropServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/PropServlet.java new file mode 100644 index 0000000..964bab2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/PropServlet.java @@ -0,0 +1,73 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; + +public class PropServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String fname = request.getContext(); + fname = fname.substring(fname.indexOf('/')+1); + if ("file".equals(fname)) { + fname = null; + } + + String result = ""; + try { + result = fread(fname); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + + } + + private String fread(String fname) throws Exception { + StringBuilder sb = new StringBuilder(); + URL url = ISocketAdapter.class.getResource("adapter_properties.txt"); + sb.append("
");
+		if(url == null) {
+			sb.append("url is null");
+		}
+		else {
+	        BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
+	        
+	        String line;
+	        
+	        try {
+		        while ((line = in.readLine()) != null) {
+		            sb.append(line + "\n");
+		        }
+	        }
+	        catch(Exception e) {
+	        	logger.error("fread error", e);
+	        }
+		    finally {
+		    	try {
+		    		if(in != null) in.close();
+		    	}
+		    	catch(Exception e) {
+		    		logger.warn(e.toString());
+		    	}
+		    }
+		}
+		
+        sb.append("
"); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ThreadDumpUtil.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ThreadDumpUtil.java new file mode 100644 index 0000000..0aa0972 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ThreadDumpUtil.java @@ -0,0 +1,153 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import java.util.Arrays; +import java.util.Hashtable; + + +public class ThreadDumpUtil { + @SuppressWarnings("deprecation") + public static void kill(String threadName) { + ThreadGroup it = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[it.activeCount()] ; + it.enumerate(threads); + for (int i=0; i

"); + + Thread[] threads = new Thread[it.activeCount()] ; + //sb.append("thread count : " + it.activeCount() + "

"); + it.enumerate(threads); + sb.append(""); + + String[] threadNames = new String[threads.length]; + for (int i=0; i"); + //sb.append(getStackTrace(threads[i])); + sb.append(getStackTrace(thread)); + sb.append(""); + } + filterThreadCount++; + } + sb.append("
"); + + StringBuilder sbb = new StringBuilder(); + sbb.append("thread count : " + filterThreadCount + " / " + it.activeCount() + "


"); + sbb.append(sb); + return sbb.toString(); + } + + static public String getStackTrace(Thread thread) { + StringBuilder sb = new StringBuilder(); + sb.append("■ \"" + thread.getName() + "\" "); + sb.append("prio=" + thread.getPriority() + " "); + sb.append(thread.isDaemon() ? "daemon " : " "); + + StackTraceElement stack[] = thread.getStackTrace(); + + if (stack==null || stack.length<1) + return sb.toString(); + + if (stack[0].getMethodName().equals("wait")) + sb.append("wait "); + else if (stack[0].getMethodName().equals("sleep")) + sb.append("sleep "); + else + sb.append("running or blocked "); + + //sb.append(" (kill)"); + sb.append("\n"); + + for (int i=0; iat "); + else + sb.append(" at "); + sb.append(className + "." + methodName); + sb.append("(" + filename + ":" + (isNativeMethod ? "native" : String.valueOf(line)) + ")"); + if (className.startsWith("java") + || className.startsWith("org.") + || className.startsWith("sun.") + || className.startsWith("com.sun.") + || className.startsWith("edu.emory.")) + sb.append(""); + sb.append("\n"); + } + + if (stack[0].getMethodName().equals("wait")) + return "

" + sb.toString() + "
"; + else if (stack[0].getMethodName().equals("sleep")) + return "
" + sb.toString() + "
"; + else + return "
" + sb.toString() + "
"; + } + + +// static public String dump() { +// StringBuffer sb = new StringBuffer(); +// ThreadGroup it = Thread.currentThread().getThreadGroup(); +// sb.append("[group] " + it.getName() + "\n"); +// Thread[] threads = new Thread[it.activeCount()] ; +// sb.append("active count : "+it.activeCount() + "\n"); +// it.enumerate(threads); +// +// //---------------------------------------------------------------------- +// ///* +// String[] threadNames = new String[threads.length]; +// for (int i=0; i" + ThreadDumpUtil.dump(filter) + ""); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ZombieAdaptersServlet.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ZombieAdaptersServlet.java new file mode 100644 index 0000000..7161fd5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/http/servlet/ZombieAdaptersServlet.java @@ -0,0 +1,402 @@ +package com.eactive.eai.adapter.socket2.protocol.http.servlet; + +import java.net.URLDecoder; +import java.time.LocalDateTime; +import java.time.OffsetDateTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.time.temporal.ChronoField; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.mina.common.IoSession; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; + +public class ZombieAdaptersServlet extends HttpServlet { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String filter = request.getContext(); + filter = filter.substring(filter.indexOf('/')+1); + if ("zombies".equals(filter)) { + filter = null; + } + + String result = ""; + try { + result = list(filter); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + if (!"".equals(request.getParameter("refresh"))) { + response.appendBody("\n\n"); + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + public static String getDate(String flagDate, int time) throws Exception { + ZonedDateTime nowDateTime = ZonedDateTime.now(); + DateTimeFormatter fmt = new DateTimeFormatterBuilder() + .appendPattern("MM-dd HH:mm:ss") + .parseDefaulting(ChronoField.YEAR,Long.parseLong(DateTimeFormatter.ofPattern("yyyy").format(nowDateTime))) + .toFormatter(); + + LocalDateTime ldt = LocalDateTime.parse(flagDate,fmt).plusMinutes(time); + ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault()); + return fmt.format(zdt); + } + public static long getParseDate(String flagDate) throws Exception { + ZonedDateTime nowDateTime = ZonedDateTime.now(); + DateTimeFormatter fmt = new DateTimeFormatterBuilder() + .appendPattern("MM-dd HH:mm:ss") + .parseDefaulting(ChronoField.YEAR,Long.parseLong(DateTimeFormatter.ofPattern("yyyy").format(nowDateTime))) + .toFormatter(); + + LocalDateTime ldt = LocalDateTime.parse(flagDate,fmt); + return ldt.toInstant(OffsetDateTime.now().getOffset()).toEpochMilli(); + } + + private String list(String filter) throws Exception { +// boolean verbose = false; + StringBuilder sb = new StringBuilder(); + try{ + filter = URLDecoder.decode(filter,"UTF-8"); + }catch(Exception e){ + logger.warn("URLDecoder.decode error", e); + } + ConcurrentHashMap adapterGroups = (ConcurrentHashMap) SocketAdapterManager.getInstance().getSocketAdapterGroups(); + + String prevAdapterGroupName = ""; + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = (String) e.nextElement(); + ConcurrentHashMap adapters = (ConcurrentHashMap) adapterGroups.get(adapterGroupName); + + for (Enumeration ee = adapters.elements() ; ee.hasMoreElements() ;) { + ISocketAdapter adapter = (ISocketAdapter) ee.nextElement(); + if(adapter == null) continue; + if (filter != null && adapter.getContext().getAdapterName().toLowerCase().indexOf(filter.toLowerCase()) == -1 + && adapter.getContext().getProtocol().toLowerCase().indexOf(filter.toLowerCase()) == -1 + && String.valueOf(adapter.getContext().getPortNumber()).toLowerCase().indexOf(filter.toLowerCase()) == -1 + && adapter.getContext().getDescription().indexOf(filter.toLowerCase()) == -1) + continue; + + ISocketAdapter adapter_imsi = manager.getSocketAdapter(adapterGroupName + "." + adapter.getContext().getAdapterName()); + + if (adapter_imsi != null){ + if((adapter.getRecentErrorCount() < 3)|| ("CLIENT".equals((adapter_imsi.getContext().getSocketType())))){ + continue; + } + String currentTime = DateTimeFormatter.ofPattern("MM-dd HH:mm:ss").format(ZonedDateTime.now()); + String flagTime = getDate(currentTime,-10); + String[] errors = adapter_imsi.getRecentErrors(); + String errMsg = errors[errors.length-1]; + String errTime = errMsg.substring(1,15); + long errDate = getParseDate(errTime); + long flagDate = getParseDate(flagTime); + + //10분 이내 에러난 것과, connection.limit.per.ip 에러가 아닌건 모두다 pass + if (errDate-flagDate < 0 || errMsg.indexOf("limit") < 0){ + continue; + } + } + + if (!adapterGroupName.equals(prevAdapterGroupName)) { + sb.append("ⓖ " + adapterGroupName); + sb.append("\n"); + } + + sb.append(" ⓐ "); + sb.append(adapter.getContext().getAdapterName()); + sb.append(""); + + sb.append(" ("); + if ("STARTED".equals(adapter.getState().name())) { + sb.append(adapter.getState().name()); + } else { + sb.append("" + adapter.getState().name() + ""); + } + if (!Env.isWindows()) { + sb.append(", " + getAdapterStatus(adapterGroupName, adapter.getContext().getAdapterName())); + } + sb.append(")"); + + sb.append(" uptime:" + TimeUtil.formatDate(adapter.getUptime().getTime())); + if (adapter.getSessionPool() != null) { + sb.append(", pool:" + adapter.getSessionPool().remaining() + "/" + (adapter.getSessionPool().peekSize())); + } + sb.append(", recv:" + "" + adapter.getMessageRecv() + ""); + sb.append(", send:" + "" + adapter.getMessageSend() + ""); + if (adapter.getRecentErrorCount() > 0) { + sb.append(", "); + sb.append(""); + sb.append("error:" + adapter.getRecentErrorCount()); + sb.append(""); + } else { + sb.append(", error:" + adapter.getRecentErrorCount()); + } + + sb.append(" (start"); + sb.append("|stop)"); + + sb.append("\n "); + sb.append(""); + sb.append(""); + sb.append(adapter.getContext().getProtocol()); + sb.append(""); + sb.append(", " + adapter.getContext().getBoundUsage() + ""); + sb.append(", " + adapter.getContext().getSocketType() + ""); + if (adapter.getContext().isClient()) { + sb.append(" (" + adapter.getContext().getLocalHostName() + ":" + adapter.getContext().getLocalPortNumber()); + sb.append("->"); + sb.append("/" + adapter.getContext().getHostName() + ":" + adapter.getContext().getPortNumber() + ")"); + } else { + sb.append(" (" + adapter.getContext().getHostName() + ":" + adapter.getContext().getPortNumber()); + sb.append("<-)"); + } + if(adapter.getContext().isSync()) { + sb.append(", SYNC"); + } else { + sb.append(", ASYN"); + } + if ("Y".equals(adapter.getContext().getAckSupport())) { + sb.append(", ACK"); + } else { + sb.append(", NO_ACK"); + } + if(adapter.getContext().isPermanent()) { + sb.append(", PERMANENT"); + } else { + sb.append(", NON_PERM"); + } + if(adapter.getContext().isBlocking()) { + sb.append(", BIO"); + } else { + sb.append(", NIO"); + } + sb.append(", max_conn:" + (adapter.getContext().getCloseExistingConnection() ? "-" : "") + adapter.getContext().getMaxConnection()); + sb.append(", limit_per_ip:" + adapter.getContext().getConnLimitPerIp()); + sb.append(", max_thread:" + adapter.getContext().getMaxThread()); + + switch(adapter.getContext().getTraceLevel()) { + case 0: + sb.append(", 0(DEFAULT)"); + break; + case 1: + sb.append(", 1(INFO)"); + break; + case 2: + sb.append(", 2(DEBUG)"); + break; + case 3: + sb.append(", 3(TRACE)"); + break; + default : + } + + if (adapter.getContext().isPollingUse()) { + sb.append("\n ("); + sb.append("POLLING"); + sb.append(", " + adapter.getContext().getPollingRole()); + if (adapter.getContext().isPollingOneway()) { + sb.append(", oneway"); + } + sb.append(", " + adapter.getContext().getPollingTimeout()); +// sb.append(", " + adapter.getContext().getPollingRequest()); +// sb.append(", " + adapter.getContext().getPollingRequestPattern()); +// sb.append(", " + adapter.getContext().getPollingReplacement()); +// sb.append(", " + adapter.getContext().getPollingResponsePattern()); + sb.append(")"); + } + + if ("FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "UDP_FIXED_LENGTH_HEADER".equals(adapter.getContext().getProtocol()) + || "EGSEED".equals(adapter.getContext().getProtocol()) + || "TCSEED".equals(adapter.getContext().getProtocol()) //20101213 JGY + || "ENVELOP".equals(adapter.getContext().getProtocol()) + || "XECURE".equals(adapter.getContext().getProtocol()) + || "XECURE2".equals(adapter.getContext().getProtocol()) + || "XECURE3".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("type=" + adapter.getContext().getLlFieldType()); + sb.append(", offset=" + adapter.getContext().getLlFieldOffset()); + sb.append(", length=" + adapter.getContext().getLlFieldLength()); + sb.append(", ll.field.include=" + adapter.getContext().getLlFieldInclude()); + sb.append(", ll.offset.exclude=" + adapter.getContext().getLlOffsetExclude()); + sb.append(", ll.include=" + adapter.getContext().getLlInclude()); + sb.append(")"); + } + + if ("FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol()) + || "INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol()) // 20100515 JGY + || "UDP_FIXED_LENGTH_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("send.payload.length="); + sb.append(adapter.getContext().getSendPayloadLength()); + sb.append(", recv.payload.length="); + sb.append(adapter.getContext().getRecvPayloadLength()); + sb.append(")"); + } + + if ("XECURE".equals(adapter.getContext().getProtocol()) + || "XECURE3".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append(""); + sb.append(adapter.getContext().getXecureType()); + sb.append(""); + sb.append(", " + adapter.getContext().getXecureConfigPath()); + sb.append(", " + adapter.getContext().getXecureRemoteCert()); + sb.append(")"); + } + + if ("INISAFE".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("INISAFE"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeRelatedAdapterGroups()); + sb.append(", " + adapter.getContext().getInisafeStartMessage()); + sb.append(", " + adapter.getContext().getInisafeStopMessage()); + sb.append(")"); + } + else if ("INISAFE_2020".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("INISAFE_2020"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeRelatedAdapterGroups()); + sb.append(", " + adapter.getContext().getInisafeStartMessage()); + sb.append(", " + adapter.getContext().getInisafeStopMessage()); + sb.append(")"); + } + + if ("INISAFE_NATN".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("INISAFE_NATN"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeRelatedAdapterGroups()); + sb.append(", " + adapter.getContext().getInisafeStartMessage()); + sb.append(", " + adapter.getContext().getInisafeStopMessage()); + sb.append(")"); + } + + // JGY 20100515 + if ("INISAFE_PAYLOAD".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("INISAFE_PAYLOAD"); + sb.append(", " + adapter.getContext().getInisafeConfigPath()); + sb.append(", " + adapter.getContext().getInisafeIdPassword()); + sb.append(")"); + } + + // JGY 20100423 + if ("ENVELOP".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("ENVELOP"); + sb.append(", " + adapter.getContext().getEnvelopSigncertPath()); + sb.append(", " + adapter.getContext().getEnvelopSignkeyPath()); + sb.append(", " + adapter.getContext().getEnvelopPassword()); + sb.append(")"); + } + + // JGY 20101213 + if ("TCSEED".equals(adapter.getContext().getProtocol())) { + sb.append("\n ("); + sb.append("TCSEED"); + sb.append(", " + adapter.getContext().getTcseedKeyStore()); + sb.append(")"); + } + + if (adapter.getContext().getDescription() != null && !"".equals(adapter.getContext().getDescription().trim())) { + sb.append("\n (" + adapter.getContext().getDescription() + ")"); + } + + sb.append(""); + + sb.append("\n"); + for (Iterator iii = adapter.getSessionPool().iterator() ; iii.hasNext(); ) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :"); + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + sb.append(""); + + sb.append("\n"); + for (Iterator iii = adapter.getSessionPool().checkedOutIterator() ; iii.hasNext(); ) { + IoSession session = (IoSession) iii.next(); + sb.append(" "); + if (!session.isConnected()) + sb.append("●"); + else if (session.isClosing()) + sb.append("◐"); + else if (System.currentTimeMillis() - session.getLastIoTime() < 1000L) + sb.append("⊙"); + else + sb.append("○"); + sb.append(" Session :"); + if (session.isClosing()) + sb.append(" [CLOSING]"); + if (!session.isConnected()) + sb.append(" [NOT CONNECTED]"); + sb.append(" " + session.getLocalAddress() + (adapter.getContext().isClient() ? "->" : "<-") + session.getRemoteAddress()); + sb.append(", recv:" + session.getReadMessages()); + sb.append("(" + session.getReadBytes() + ")"); + sb.append(", send:" + session.getWrittenMessages()); + sb.append("(" + session.getWrittenBytes() + ")"); + sb.append(", created:" + TimeUtil.formatDate(session.getCreationTime())); + sb.append(", idle:" + TimeUtil.elapsedTime(session.getLastIoTime()) + "\n"); + } + sb.append(""); + sb.append("\n"); + + prevAdapterGroupName = adapterGroupName; + } + } + + return "
" + sb.toString() + "
"; + } + + protected boolean getAdapterStatus(String adapterGroupName, String adapterName) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterVO vo = adapterManager.getAdapterVO(adapterGroupName, adapterName); + if (vo != null) { + return vo.isStatus(); + } + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/InicisClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/InicisClient.java new file mode 100644 index 0000000..3b4fa1f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/InicisClient.java @@ -0,0 +1,12 @@ +package com.eactive.eai.adapter.socket2.protocol.inicis; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; + +public class InicisClient extends TcpAdapterClient{ + + public InicisClient(SocketAdapterContext context) throws Exception { + super(context); + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/InicisHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/InicisHandler.java new file mode 100644 index 0000000..2d422d2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/InicisHandler.java @@ -0,0 +1,14 @@ +package com.eactive.eai.adapter.socket2.protocol.inicis; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class InicisHandler extends ProtocolHandler{ + + public InicisHandler(ISocketAdapter adapter) { + super(adapter); + + } + + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/InicisServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/InicisServer.java new file mode 100644 index 0000000..b68249c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/InicisServer.java @@ -0,0 +1,22 @@ +package com.eactive.eai.adapter.socket2.protocol.inicis; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.inicis.handshake.InicisServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class InicisServer extends TcpAdapterServer{ + + public InicisServer(SocketAdapterContext context) throws Exception { + super(context); + + + this.handler = new InicisHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "inicis", new InicisServerFilter(this)); + } + + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/handshake/InicisCodec.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/handshake/InicisCodec.java new file mode 100644 index 0000000..12f0e5a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/handshake/InicisCodec.java @@ -0,0 +1,90 @@ +package com.eactive.eai.adapter.socket2.protocol.inicis.handshake; + +import kr.co.extrus.exafe.ie2e.ExafeiE2E; + +public class InicisCodec { + + private static InicisCodec instance; + + private static ExafeiE2E ie2e; + + private InicisCodec() { + + } + + public static synchronized InicisCodec getInstance(String keyPath, String keyPass) throws Exception { + if(instance==null) { + + instance = new InicisCodec(); + + String E2E_KEYFILE = ""; + String E2E_CERTFILE = ""; + String E2E_CODE = ""; + + try { + + E2E_KEYFILE = keyPath + "/key.pem"; + E2E_CERTFILE = keyPath + "/cert.pem"; + E2E_CODE = keyPass; + + // 암호화 모듈 초기화 - 한번만 수행 + ie2e = new ExafeiE2E(); + ie2e.InitCert(E2E_KEYFILE, E2E_CERTFILE, E2E_CODE); + + } catch (Exception e) { + throw new Exception("InicisCodec | Exafei 초기화 에러: " + e.getMessage() + ", keyPath|keyPass: " + keyPath + "|" + keyPass + + ", E2E_KEYFILE|E2E_CERTFILE|E2E_CODE: " + E2E_KEYFILE + "|" + E2E_CERTFILE + "|" + E2E_CODE); + } + } + return instance; + } + + public byte[] decrypt(byte[] bytes) throws Exception { + + byte[] decrypted = null; + + try { + decrypted = ie2e.Decryption(new String(bytes)).getBytes(); + } catch (Exception e) { + throw new Exception("InicisCodec | Exafei 복호화 에러: " + e.getMessage()); + } + + return decrypted; + } + + public static byte[] encrypt(byte[] bytes) { + + return bytes; + } + + + +// public static void main(String[] args){ +// +// ExafeiE2E ie2e; +// String E2E_KEYFILE = "/"; +// String E2E_CERTFILE = "/"; +// String E2E_CODE = "/"; +// +// ie2e = new ExafeiE2E(); +// byte[] input_data = "00000274RD8160 T20120719095522banktpg 1DK 0 00990007 ^|BT|^CRYPTO=Y,GSID= ,FIELD_SIZE=592,DEC_LEN=11,PW_LEN=15,PAD= ,ALIGN=L,ENC_DATA=rn3f7p6cqgN5jJo9aRjbhQ==,ENVELOP_DATA=MIIBQQYJKoZIhvcNAQcDoIIBMjCCAS4CAQAxgeswgegCAQAwUTBEMQswCQYDVQQGEwJLUjEPMA0GA1UECBMGSmVvbmp1MQ8wDQYDVQQKEwZKQkJhbmsxEzARBgNVBAMUCkUyRV9TZXJ2ZXICCQCq5nr6/7/EOzANBgkqhkiG9w0BAQEFAASBgCssAOhR2yRUxjwUhIgBWoROnfkBMrGZOyYgcOafwnGwYG429ZoXC3iwtqwHlq2X5JlT84JB39U36mUHJH2rq/PYS/yEQWgoaYyHO/bvE/DtAIJW2SBztGuPMIn6spDQAoyka4ZUQyEi2zn9MxauV/Iz5F2F8K1N3ZOKr67nTjNmMDsGCSqGSIb3DQEHATAcBggqgxqMmkQBBAQQLi5FeGFmZUUyRS4uISEuLoAQrn3f7p6cqgN5jJo9aRjbhQ==^|BT|^".getBytes(); +// byte[] result = null; +// +// // 암호화 모듈 초기화 - 한번만 수행 +// try { +// ie2e.InitCert(E2E_KEYFILE, E2E_CERTFILE, E2E_CODE); +// } catch (Exception e) { +// System.out.println("InicisServerFilter | Exafei 초기화 에러."); +// } +// +// try { +// result = InicisCodec.decrypt(input_data, ie2e); +// } catch (Exception e) { +// +// e.printStackTrace(); +// } +// +// System.out.println("decrypt : " + CommonLib.hexDump(result)); +// +// } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/handshake/InicisFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/handshake/InicisFilter.java new file mode 100644 index 0000000..8579267 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/handshake/InicisFilter.java @@ -0,0 +1,97 @@ +package com.eactive.eai.adapter.socket2.protocol.inicis.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + +public class InicisFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + + private static final String NEXT_FILTER = InicisFilter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = InicisFilter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + + protected enum State { + STATE_HANDSHAKE, + STATE_MESSAGE; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected static class FilterState { + public State state = State.STATE_MESSAGE; + public byte[] userKey = new byte[16]; + public int[] roundKey = new int[32]; + } + + public InicisFilter(ISocketAdapter adapter) { + + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + + if (parent.contains(InicisFilter.class)) { + throw new IllegalStateException("A filter chain cannot contain more than one DesFilter."); + } + + IoSession session = parent.getSession(); + session.setAttribute(NEXT_FILTER, nextFilter); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + if (filterState.state == State.STATE_MESSAGE) { + byte[] encrypted = InicisCodec.encrypt(m.getBytes()); + m = new ByteMessage(encrypted); + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/handshake/InicisServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/handshake/InicisServerFilter.java new file mode 100644 index 0000000..56e35a5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inicis/handshake/InicisServerFilter.java @@ -0,0 +1,43 @@ +package com.eactive.eai.adapter.socket2.protocol.inicis.handshake; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + +public class InicisServerFilter extends InicisFilter{ + + public InicisServerFilter(ISocketAdapter adapter) { + + super(adapter); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { + case STATE_MESSAGE: + /** + * decrypt + */ + byte[] decrypted = InicisCodec.getInstance(context.getInicisKeyPath(),context.getInicisKeyPass()).decrypt(m.getBytes()); + if (decrypted == null || decrypted.length == 0) { + throw new Exception("received message is invalid - check if message is encrypted : " + m.hexDump()); + } + m.setBytes(decrypted); + + /** + * next filter + */ + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m.hexDump()); + } + } +} + + diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeClient.java new file mode 100644 index 0000000..a742e8f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeClient.java @@ -0,0 +1,39 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe; + +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.inisafe.codec.InisafeCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.inisafe.handshake.InisafeClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class InisafeClient extends TcpAdapterClient { + boolean isBooting = true; + + public InisafeClient(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new InisafeClientHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new InisafeCodecFactory(this))); + config.getFilterChain().addAfter("codec", "inisafe.codec", new InisafeClientFilter(this)); + } + + @Override + public SimpleFuture start() throws Exception { + if (isBooting && !Env.isTest()) { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | inisafe client protocol - skip start process when booting ..."); + } + isBooting = false; + + SimpleFuture future = new SimpleFuture(); + future.set(Boolean.TRUE); + return future; + } else { + return super.start(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeClientHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeClientHandler.java new file mode 100644 index 0000000..5de40db --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeClientHandler.java @@ -0,0 +1,40 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class InisafeClientHandler extends InisafeHandler { + public InisafeClientHandler(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(IoSession session) throws Exception { + super.sessionOpened(session); + } + + @Override + public void sessionClosed(IoSession session) throws Exception { + super.sessionClosed(session); + /** + * client-server pair 로 작업한다. + */ + doSessionClosed(session); + } + + protected String messageReplace (String str){ + Matcher matcher = Pattern.compile("%d\\{([a-zA-Z \\-]+)\\}").matcher(str); + + while (matcher.find()) { + String datePattern = matcher.group(1); + DateFormat dateFormat = new SimpleDateFormat(datePattern); + str = str.replaceFirst("%d\\{([a-zA-Z \\-]+)\\}", dateFormat.format(System.currentTimeMillis())); + } + return str; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeErrorMessage.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeErrorMessage.java new file mode 100644 index 0000000..6cc2bc8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeErrorMessage.java @@ -0,0 +1,26 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe; + +import java.util.Hashtable; + +public class InisafeErrorMessage { + static Hashtable hash = new Hashtable<>(); + + static { + hash.put("-1910", "ERR_POLICY_RESERVED_CN | 이미 등록되어 있은 CN 입니다."); + } + + private InisafeErrorMessage() { + + } + public static String getErrorMessage(String key) { + String value = hash.get(key); + if (value == null) { + return "Unknown Error."; + } + return value; + } + + public static String getErrorMessage(int key) { + return getErrorMessage(String.valueOf(key)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeHandler.java new file mode 100644 index 0000000..a4ba40e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/InisafeHandler.java @@ -0,0 +1,37 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import org.apache.mina.common.IoSession; + + +public class InisafeHandler extends ProtocolHandler { + public InisafeHandler(ISocketAdapter adapter) { + super(adapter); + } + + protected void doSessionClosed (IoSession session) throws Exception { + /** + * client-server pair (in same adapter group) + */ + + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + for (int i=0; i= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | InisafeDecoder | decode : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "InisafeDecoder | decode : " + CommonLib.hexDump(in, context)); + } + + boolean isHandshakeState = false; + FilterState filterState = (FilterState) session.getAttribute(InisafeFilter.FILTER_STATE_KEY); + if (filterState != null && filterState.state != InisafeFilter.State.STATE_MESSAGE) { + isHandshakeState = true; + } + + if (isHandshakeState) { + decodeHandshake(session, in, out); + } else { + decodeMessage(session, in, out); + } + } + + private void decodeHandshake(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(InisafeConstants.COMMON_PART_LENGTH); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + codecState.buffer.position(200).limit(200+codecState.payloadSize); + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] individualLL = new byte[4]; + codecState.buffer.position(200).get(individualLL); + int individualLength = Integer.parseInt(new String(individualLL)); + byte[] bytes = new byte[individualLength-4]; + codecState.buffer.position(204).get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(200); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private void decodeMessage(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(InisafeConstants.COMMON_PART_LENGTH); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + /** + * payload size°¡ 0ÀÎ °æ¿ì + */ + if (codecState.payloadSize == 0) { + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0).get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(InisafeConstants.COMMON_PART_LENGTH); + } else { + codecState.buffer.position(200).limit(codecState.payloadSize+200); + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0).get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(InisafeConstants.COMMON_PART_LENGTH); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.buffer.flip(); + try { + byte[] commonLL = new byte[5]; + codecState.buffer.position(0).get(commonLL); + codecState.payloadSize = Integer.parseInt(new String(commonLL)); + codecState.buffer.position(0); + } catch (NumberFormatException e) { +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA008"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA008"); + throw new EAIException("RECEAINNA008", context.getAdapterName() + + "when read header, number format is invalid - " + + e.getMessage() + " | " + CommonLib.hexDump(codecState.buffer, context)); + } + + if (codecState.payloadSize > MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + MAX_PAYLOAD_SIZE + ") exceeded : " + codecState.payloadSize); + } + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/codec/InisafeEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/codec/InisafeEncoder.java new file mode 100644 index 0000000..8ef2257 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/codec/InisafeEncoder.java @@ -0,0 +1,164 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.inisafe.handshake.InisafeFilter; +import com.eactive.eai.adapter.socket2.protocol.inisafe.handshake.InisafeFilter.FilterState; +import com.eactive.eai.common.util.Logger; +import org.apache.commons.lang3.StringUtils; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class InisafeEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public InisafeEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + boolean isHandshakeState = false; + FilterState filterState = (FilterState) session.getAttribute(InisafeFilter.FILTER_STATE_KEY); + if (filterState != null && filterState.state != InisafeFilter.State.STATE_MESSAGE) { + isHandshakeState = true; + } + + if (isHandshakeState) { + encodeHandshake(session, m, out); + } else { + encodeMessage(session, m, out); + } + } + + + private void encodeHandshake(IoSession session, ByteMessage m, ProtocolEncoderOutput out) throws Exception { + int length = m.size(); + int totalLength = InisafeConstants.COMMON_PART_LENGTH + length; + + ByteBuffer buffer = ByteBuffer.allocate(totalLength).limit(totalLength); + + /** + * [1] common ll + */ + String commonLL = CommonLib.getFormatString(totalLength-InisafeConstants.COMMON_PART_LENGTH, InisafeConstants.COMMON_LL_LENGTH); + buffer.put(commonLL.getBytes()); // 1 전문송신 Byte 수 5 N * 비고 1) 참조 + + /** + * [2] common rest + */ + buffer.put(getTransactionType(session)); // 2 거래구분코드 9 AN * 비고 2) 참조 + buffer.put("BOK".getBytes()); // 3 System ID 3 A * BOK (단, 증권예탁결제원간 거래는 DVP) + buffer.put("0000".getBytes()); // 4 전문종별 코드 4 N * 비고 3) 참조 + buffer.put("YYYYMMDD".getBytes()); // 5 영업일자 8 N * YYYYMMDD + buffer.put(" ".getBytes()); // 6 STATUS 4 N * 비고 4) 참조 + buffer.put("0000".getBytes()); // 7 응답코드 4 AN * <별첨1> 참조 + buffer.put("00000000000000000000".getBytes()); // 8 전문관리번호 20 N * 비고 5) 참조 + buffer.put("YYYYMMDDhhmmss".getBytes()); // 9 전문전송시간 14 N * YYYYMMDDhhmmss + buffer.put("00000000000000000000".getBytes()); // 10 참조번호 20 N B 비고 6) 참조 + buffer.put("1051".getBytes()); // 11 송신기관 4 N * <별첨3> 참조, 비고 7)참조 + buffer.put("1016".getBytes()); // 12 수신기관 4 N * <별첨3> 참조, 비고 8)참조 + buffer.put("N".getBytes()); // 13 암호화 여부 1 A * Y/N + buffer.put("001".getBytes()); // 14 전송횟수 3 N * 전송한 횟수 * 최초전송번호 : 1 + buffer.put(StringUtils.leftPad("", 65).getBytes()); // 15 공란 65 A * Space + buffer.put(" ".getBytes()); // 16 참가기관 ID 16 AN SR 한국은행에 등록된 ID + buffer.put(" ".getBytes()); // 17 참가기관 비밀번호 16 AN SR 참가기관의 비밀번호 + + /** + * [3] individual part + */ + buffer.put(m.getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | InisafeEncoder | encode (handshake) : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "InisafeEncoder | encode (handshake) : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + + private byte[] getTransactionType(IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(InisafeFilter.FILTER_STATE_KEY); + if (filterState == null) { + throw new Exception("session does not have filter state"); + } + + switch (filterState.state) { + case STATE_INIT : + if (adapter.getContext().isClient()) { + return "000000001".getBytes(); + } else { + return "000000002".getBytes(); + } + case STATE_UPDATE : + if (adapter.getContext().isClient()) { + return "000000003".getBytes(); + } else { + return "000000004".getBytes(); + } + case STATE_FINAL : + return "000000005".getBytes(); + default : + throw new Exception("invalid state"); + } + } + + private void encodeMessage(IoSession session, ByteMessage m, ProtocolEncoderOutput out) throws Exception { + /** + * copy byte[] to buffer + */ + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate(length).limit(length); + buffer.put(m.getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | InisafeEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "InisafeEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + + public void dispose(IoSession session) throws Exception { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/handshake/InisafeClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/handshake/InisafeClientFilter.java new file mode 100644 index 0000000..d07282d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/handshake/InisafeClientFilter.java @@ -0,0 +1,189 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.initech.inisafenet.HandShakeManager_RSA; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; + + +public class InisafeClientFilter extends InisafeFilter { + public InisafeClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + HandShakeManager_RSA inisafeSession = new HandShakeManager_RSA(); + inisafeSession.TEST_MODE = false; + session.setAttribute(INISAFE_SESSION_KEY, inisafeSession); + + process(nextFilter, session, null); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + HandShakeManager_RSA inisafeSession = (HandShakeManager_RSA) session.getAttribute(INISAFE_SESSION_KEY); + + /** + * State machine + */ + ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_INIT: + /* + * handshake timeout 설정함 + * timeout 에서 5초 전 설정 + */ + if (context.getTimeout() <= 5 ) { + throw new Exception("invalid timeout("+context.getTimeout()+") value . set timeout must be 5 or more. "); + } + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout() - 5); + /** + * change state to INIT + */ + filterState.state = State.STATE_INIT; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + + /** + * create INIT key + */ + byte[] initKey = inisafeSession.initHandShakeClient(null); + String initIndividualLL = CommonLib.getFormatString(initKey.length+4, 4); + //byte[] paddedInitKey = StringUtils.rightPad(new String(initKey), 92).getBytes(); + + buffer = ByteBuffer.allocate(4+initKey.length).limit(4+initKey.length); + buffer.put(initIndividualLL.getBytes()); + buffer.put(initKey); + + byte[] initIndividualBytes = new byte[4+initKey.length]; + buffer.position(0).get(initIndividualBytes); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_INIT"); + } + session.write(initIndividualBytes); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_UPDATE; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_UPDATE: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_INIT response"); + } + if(message == null) throw new Exception("Message is NULL"); + /** + * send UPDATE + */ + byte[] updateKey = inisafeSession.updateHandShakeClient(message.getBytes()); + String updateIndividualLL = CommonLib.getFormatString(updateKey.length+4, 4); + //byte[] paddedUpdateKey = StringUtils.rightPad(new String(updateKey), 268).getBytes(); + + buffer = ByteBuffer.allocate(4+updateKey.length).limit(4+updateKey.length); + buffer.put(updateIndividualLL.getBytes()); + buffer.put(updateKey); + + byte[] updateIndividualBytes = new byte[4+updateKey.length]; + buffer.position(0).get(updateIndividualBytes); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_UPDATE"); + } + session.write(updateIndividualBytes); + + /** + * change state to FINAL + */ + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_UPDATE response"); + } + if(message == null) throw new Exception("Message is NULL"); + /** + * send FINAL + */ + byte[] finalKey = inisafeSession.finalHandShakeClient(message.getBytes()); + String finalIndividualLL = CommonLib.getFormatString(finalKey.length+4, 4); + //byte[] paddedFinalKey = StringUtils.rightPad(new String(finalKey), 92).getBytes(); + + buffer = ByteBuffer.allocate(4+finalKey.length).limit(4+finalKey.length); + buffer.put(finalIndividualLL.getBytes()); + buffer.put(finalKey); + + byte[] finalIndividualBytes = new byte[4+finalKey.length]; + buffer.position(0).get(finalIndividualBytes); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_FINAL"); + } + session.write(finalIndividualBytes); + + /** + * change state + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * finish handshake + */ + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog(context.getAdapterName() + " | InisafeClientFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | InisafeClientFilter | handshake finished ..."); + } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + + break; + + case STATE_MESSAGE: + if(message == null) throw new Exception("Message is NULL"); + validateMessage(message); + message = decrypt(message, session); + nextFilter.messageReceived(session, message); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + nextFilter.filterClose(session); + + adapter.getSessionPool().remove(session); + session.close(); + throw new Exception(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/handshake/InisafeFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/handshake/InisafeFilter.java new file mode 100644 index 0000000..c7de204 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/handshake/InisafeFilter.java @@ -0,0 +1,209 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import com.initech.inisafenet.HandShakeManager_RSA; +import com.initech.provider.crypto.InitechProvider; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + + +abstract public class InisafeFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + private final Object lockObj = new Object(); +// private static final String NEXT_FILTER = InisafeFilter.class.getName() + ".NextFilter"; + public static final String FILTER_STATE_KEY = InisafeFilter.class.getName() + ".STATE"; + + public static final String SESSION_STATE = "SESSION_STATE"; + public static final String INISAFE_SESSION_KEY = "INISAFE_SESSION_KEY"; + + public enum State { + STATE_START, + STATE_INIT, + STATE_UPDATE, + STATE_FINAL, + STATE_MESSAGE; + } + + public static class FilterState { + public State state = null; + public byte[] key; // token? + + public FilterState() {} + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected byte[] cert; + protected byte[] key; + protected String password; + protected byte[] remoteCert; + + static { + new InitechProvider(); + } + + public InisafeFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + synchronized(lockObj) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_INIT; + session.setAttribute(FILTER_STATE_KEY, filterState); + //setSessionState(session, filterState.state.toString()); + } + } + + // handshake future + session.setAttribute(ProtocolHandler.HANDSHAKE_FUTURE, new SimpleFuture()); + } + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { +// HandShakeManager_RSA inisafeSession = (HandShakeManager_RSA) session.getAttribute(INISAFE_SESSION_KEY); +// inisafeSession.close(); + + nextFilter.sessionClosed(session); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteBuffer) { + m = new ByteMessage((ByteBuffer) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + /** + * encrypt + */ + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); +// HandShakeManager_RSA inisafeSession = (HandShakeManager_RSA) session.getAttribute(INISAFE_SESSION_KEY); + + switch (filterState.state) { + case STATE_MESSAGE: + validateMessage(m); +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + m = encrypt(m, session); + break; + + default: + break; + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new Exception(context.getAdapterName() + " | initech error - " + e.getMessage()); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + @Override + public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState.state != State.STATE_MESSAGE){ + StringBuffer sb = new StringBuffer(); + sb.append("idle:" + TimeUtil.elapsedTime(session.getLastIoTime())); + sb.append(", handshake timeout:" + (context.getTimeout() -5)); + sb.append(", protocol:" + context.getProtocol()); + if (filterState != null) { + sb.append(", state:" + filterState.state.toString()); + } + sb.append("/" + session.getAttribute(SESSION_STATE)); + logger.error(context.getAdapterName() + " | handshake timeout -> disconnecting (" + session + ") " + sb.toString()); + adapter.addRecentError(context.getAdapterName() + " | handshake timeout -> disconnecting (" + session + ") " + sb.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + adapter.getSessionPool().remove(session); + session.close(); + + + }else{ + nextFilter.sessionIdle(session, status); + } + } + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } + + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + + + protected void validateMessage(ByteMessage m) throws Exception { + if (m.size() < 200) { + throw new Exception("cannot send message - message size < 200 - " + m.hexDump()); + } + + String ll = new String(m.getBytes(0, 5)); + if (!ll.matches("[0-9]{5}")) { + throw new Exception("ll field (0-5) of message is not number - " + m.hexDump()); + } + } + + + protected ByteMessage encrypt(ByteMessage m, IoSession session) throws Exception { + /** + * 암호화 여부 체크 + */ + if ('Y' != m.getByte(99)) + return m; + + HandShakeManager_RSA inisafeSession = (HandShakeManager_RSA) session.getAttribute(INISAFE_SESSION_KEY); + byte[] encryptPart = inisafeSession.i_encrypt(m.getBytes(200-16-16)); + ByteMessage encrypted = new ByteMessage(m.getBytes(0, 200-16-16)).append(encryptPart); + + return encrypted; + } + + protected ByteMessage decrypt(ByteMessage m, IoSession session) throws Exception { + /** + * 암호화 여부 체크 + */ + if ('Y' != m.getByte(99)) + return m; + + HandShakeManager_RSA inisafeSession = (HandShakeManager_RSA) session.getAttribute(INISAFE_SESSION_KEY); + byte[] decryptPart = inisafeSession.i_decrypt(m.getBytes(200-16-16)); + ByteMessage decrypted = new ByteMessage(m.getBytes(0, 200-16-16)).append(decryptPart); + + return decrypted; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/handshake/InisafeServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/handshake/InisafeServerFilter.java new file mode 100644 index 0000000..f6fd7c3 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe/handshake/InisafeServerFilter.java @@ -0,0 +1,207 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.initech.inisafenet.HandShakeManager_RSA; +import com.initech.inisafenet.exception.INISAFENetException; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; + + +public class InisafeServerFilter extends InisafeFilter { + public InisafeServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + HandShakeManager_RSA inisafeSession = new HandShakeManager_RSA(context.getInisafeConfigPath()); + session.setAttribute(INISAFE_SESSION_KEY, inisafeSession); + } catch(INISAFENetException e) { + throw e; + } + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + //validateMessage(m); + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + HandShakeManager_RSA inisafeSession = null; + + try { + /** + * get filter state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + /** + * check inisafe session + */ + inisafeSession = (HandShakeManager_RSA) session.getAttribute(INISAFE_SESSION_KEY); + if (inisafeSession == null) { + throw new Exception("inisafe session is not established"); + } + + /** + * state machine + */ + ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_INIT: + /* + * handshake timeout 설정함 + * timeout 에서 5초 전 설정 + */ + if (context.getTimeout() <= 5 ) { + throw new Exception("invalid timeout("+context.getTimeout()+") value . set timeout must be 5 or more. "); + } + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_INIT"); + } + + /** + * send INIT response + */ + byte[] initKey = inisafeSession.initHandShake(message.getBytes()); + String initIndividualLL = CommonLib.getFormatString(initKey.length+4, 4); + //byte[] paddedInitKey = StringUtils.rightPad(new String(initKey), 1792).getBytes(); + + buffer = ByteBuffer.allocate(4+initKey.length).limit(4+initKey.length); + buffer.put(initIndividualLL.getBytes()); + buffer.put(initKey); + + byte[] initIndividualBytes = new byte[4+initKey.length]; + buffer.position(0).get(initIndividualBytes); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_INIT response"); + } + session.write(initIndividualBytes); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_UPDATE; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_UPDATE: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_UPDATE"); + } + + /** + * send UPDATE response + */ + byte[] updateKey = inisafeSession.updateHandShake(message.getBytes()); + String updateIndividualLL = CommonLib.getFormatString(updateKey.length+4, 4); + //byte[] paddedUpdateKey = StringUtils.rightPad(new String(updateKey), 108).getBytes(); + + buffer = ByteBuffer.allocate(4+updateKey.length).limit(4+updateKey.length); + buffer.put(updateIndividualLL.getBytes()); + buffer.put(updateKey); + + byte[] updateIndividualBytes = new byte[4+updateKey.length]; + buffer.position(0).get(updateIndividualBytes); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_UPDATE response"); + } + session.write(updateIndividualBytes); + + /** + * change state to FINAL + */ + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_FINAL"); + } + + // 20200409 ASIS 에는 없던 TOBE 추가로직을 삽입함 + //------------------------------------------------------------------- + int result = inisafeSession.finalHandShake(message.getBytes()); + + if (result !=1){ + throw new Exception(" invalid message during handshake .. : " + message); + } + //------------------------------------------------------------------- + /** + * change state to MESSAGE + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * start client pair socket adapter (in same socket adapter group) + */ + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + if(adapters == null) return; + for (int i=0; i= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog("InisafeServerFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | InisafeServerFilter | handshake finished ..."); + } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + //nextFilter.messageReceived(session, new ByteMessage("STARTED")); + + break; + + case STATE_MESSAGE: + validateMessage(message); + message = decrypt(message, session); + nextFilter.messageReceived(session, message); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + + adapter.getSessionPool().remove(session); + session.close(); + + throw new Exception(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/Inisafe2020Client.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/Inisafe2020Client.java new file mode 100644 index 0000000..8edd086 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/Inisafe2020Client.java @@ -0,0 +1,38 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe2020; + +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.inisafe2020.codec.InisafeCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.inisafe2020.handshake.InisafeClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class Inisafe2020Client extends TcpAdapterClient { + boolean isBooting = true; + + public Inisafe2020Client(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new InisafeClientHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new InisafeCodecFactory(this))); + config.getFilterChain().addAfter("codec", "inisafe.codec", new InisafeClientFilter(this)); + } + + public SimpleFuture start() throws Exception { + if (isBooting && !Env.isTest()) { + if (context.getTraceLevel() >= context.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | inisafe client protocol - skip start process when booting ..."); + } + isBooting = false; + + SimpleFuture future = new SimpleFuture(); + future.set(Boolean.TRUE); + return future; + } else { + return super.start(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/Inisafe2020Server.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/Inisafe2020Server.java new file mode 100644 index 0000000..0f72bea --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/Inisafe2020Server.java @@ -0,0 +1,19 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe2020; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.inisafe2020.codec.InisafeCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.inisafe2020.handshake.InisafeServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class Inisafe2020Server extends TcpAdapterServer { + public Inisafe2020Server(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new InisafeServerHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new InisafeCodecFactory(this))); + config.getFilterChain().addAfter("codec", "inisafe.codec", new InisafeServerFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/InisafeClientHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/InisafeClientHandler.java new file mode 100644 index 0000000..817de66 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/InisafeClientHandler.java @@ -0,0 +1,38 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe2020; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class InisafeClientHandler extends InisafeHandler { + public InisafeClientHandler(ISocketAdapter adapter) { + super(adapter); + } + + public void sessionOpened(IoSession session) throws Exception { + super.sessionOpened(session); + } + + public void sessionClosed(IoSession session) throws Exception { + super.sessionClosed(session); + /** + * client-server pair 로 작업한다. + */ + doSessionClosed(session); + } + + protected String messageReplace (String str){ + Matcher matcher = Pattern.compile("%d\\{([a-zA-Z \\-]+)\\}").matcher(str); + + while (matcher.find()) { + String datePattern = matcher.group(1); + DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(datePattern); + str = str.replaceFirst("%d\\{([a-zA-Z \\-]+)\\}", dateFormat.format(ZonedDateTime.now())); + } + return str; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/InisafeErrorMessage.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/InisafeErrorMessage.java new file mode 100644 index 0000000..b310ee2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/InisafeErrorMessage.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe2020; + +import java.util.Hashtable; + + +public class InisafeErrorMessage { + static Hashtable hash = new Hashtable(); + + static { + hash.put("-1910", "ERR_POLICY_RESERVED_CN | 이미 등록되어 있은 CN 입니다."); + } + + static public String getErrorMessage(String key) { + String value = hash.get(key); + if (value == null) { + return "Unknown Error."; + } + return value; + } + + static public String getErrorMessage(int key) { + return getErrorMessage(String.valueOf(key)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/InisafeHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/InisafeHandler.java new file mode 100644 index 0000000..8f8e22c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/InisafeHandler.java @@ -0,0 +1,38 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe2020; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import org.apache.mina.common.IoSession; + + +public class InisafeHandler extends ProtocolHandler { + public InisafeHandler(ISocketAdapter adapter) { + super(adapter); + } + + protected void doSessionClosed (IoSession session) throws Exception { + /** + * client-server pair (in same adapter group) + */ + + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + if(adapters == null) return; + for (int i=0; i= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | InisafeDecoder | decode : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "InisafeDecoder | decode : " + CommonLib.hexDump(in, context)); + } + + boolean isHandshakeState = false; + FilterState filterState = (FilterState) session.getAttribute(InisafeFilter.FILTER_STATE_KEY); + if (filterState != null && filterState.state != InisafeFilter.State.STATE_MESSAGE) { + isHandshakeState = true; + } + + if (isHandshakeState) { + decodeHandshake(session, in, out); + } else { + decodeMessage(session, in, out); + } + } + + private void decodeHandshake(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(InisafeConstants.COMMON_PART_LENGTH); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + codecState.buffer.position(200).limit(200+codecState.payloadSize); + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] individualLL = new byte[4]; + codecState.buffer.position(200).get(individualLL); + int individualLength = Integer.parseInt(new String(individualLL)); + byte[] bytes = new byte[individualLength-4]; + codecState.buffer.position(204).get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(200); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private void decodeMessage(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(InisafeConstants.COMMON_PART_LENGTH); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + /** + * payload size°¡ 0ÀÎ °æ¿ì + */ + if (codecState.payloadSize == 0) { + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0).get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(InisafeConstants.COMMON_PART_LENGTH); + } else { + codecState.buffer.position(200).limit(codecState.payloadSize+200); + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0).get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(InisafeConstants.COMMON_PART_LENGTH); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.buffer.flip(); + try { + byte[] commonLL = new byte[5]; + codecState.buffer.position(0).get(commonLL); + codecState.payloadSize = Integer.parseInt(new String(commonLL)); + codecState.buffer.position(0); + } catch (NumberFormatException e) { +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA008"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA008"); + throw new EAIException("RECEAINNA008", context.getAdapterName() + + "when read header, number format is invalid - " + + e.getMessage() + " | " + CommonLib.hexDump(codecState.buffer, context)); + } + + if (codecState.payloadSize > MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + MAX_PAYLOAD_SIZE + ") exceeded : " + codecState.payloadSize); + } + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/codec/InisafeEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/codec/InisafeEncoder.java new file mode 100644 index 0000000..584948b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/codec/InisafeEncoder.java @@ -0,0 +1,164 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe2020.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.inisafe2020.handshake.InisafeFilter; +import com.eactive.eai.adapter.socket2.protocol.inisafe2020.handshake.InisafeFilter.FilterState; +import com.eactive.eai.common.util.Logger; +import org.apache.commons.lang3.StringUtils; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class InisafeEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public InisafeEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + boolean isHandshakeState = false; + FilterState filterState = (FilterState) session.getAttribute(InisafeFilter.FILTER_STATE_KEY); + if (filterState != null && filterState.state != InisafeFilter.State.STATE_MESSAGE) { + isHandshakeState = true; + } + + if (isHandshakeState) { + encodeHandshake(session, m, out); + } else { + encodeMessage(session, m, out); + } + } + + + private void encodeHandshake(IoSession session, ByteMessage m, ProtocolEncoderOutput out) throws Exception { + int length = m.size(); + int totalLength = InisafeConstants.COMMON_PART_LENGTH + length; + + ByteBuffer buffer = ByteBuffer.allocate(totalLength).limit(totalLength); + + /** + * [1] common ll + */ + String commonLL = CommonLib.getFormatString(totalLength-InisafeConstants.COMMON_PART_LENGTH, InisafeConstants.COMMON_LL_LENGTH); + buffer.put(commonLL.getBytes()); // 1 전문송신 Byte 수 5 N * 비고 1) 참조 + + /** + * [2] common rest + */ + buffer.put(getTransactionType(session)); // 2 거래구분코드 9 AN * 비고 2) 참조 + buffer.put("BOK".getBytes()); // 3 System ID 3 A * BOK (단, 증권예탁결제원간 거래는 DVP) + buffer.put("0000".getBytes()); // 4 전문종별 코드 4 N * 비고 3) 참조 + buffer.put("YYYYMMDD".getBytes()); // 5 영업일자 8 N * YYYYMMDD + buffer.put(" ".getBytes()); // 6 STATUS 4 N * 비고 4) 참조 + buffer.put("0000".getBytes()); // 7 응답코드 4 AN * <별첨1> 참조 + buffer.put("00000000000000000000".getBytes()); // 8 전문관리번호 20 N * 비고 5) 참조 + buffer.put("YYYYMMDDhhmmss".getBytes()); // 9 전문전송시간 14 N * YYYYMMDDhhmmss + buffer.put("00000000000000000000".getBytes()); // 10 참조번호 20 N B 비고 6) 참조 + buffer.put("1051".getBytes()); // 11 송신기관 4 N * <별첨3> 참조, 비고 7)참조 + buffer.put("1016".getBytes()); // 12 수신기관 4 N * <별첨3> 참조, 비고 8)참조 + buffer.put("N".getBytes()); // 13 암호화 여부 1 A * Y/N + buffer.put("001".getBytes()); // 14 전송횟수 3 N * 전송한 횟수 * 최초전송번호 : 1 + buffer.put(StringUtils.leftPad("", 65).getBytes()); // 15 공란 65 A * Space + buffer.put(" ".getBytes()); // 16 참가기관 ID 16 AN SR 한국은행에 등록된 ID + buffer.put(" ".getBytes()); // 17 참가기관 비밀번호 16 AN SR 참가기관의 비밀번호 + + /** + * [3] individual part + */ + buffer.put(m.getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | InisafeEncoder | encode (handshake) : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "InisafeEncoder | encode (handshake) : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + + private byte[] getTransactionType(IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(InisafeFilter.FILTER_STATE_KEY); + if (filterState == null) { + throw new Exception("session does not have filter state"); + } + + switch (filterState.state) { + case STATE_INIT : + if (adapter.getContext().isClient()) { + return "000000001".getBytes(); + } else { + return "000000002".getBytes(); + } + case STATE_UPDATE : + if (adapter.getContext().isClient()) { + return "000000003".getBytes(); + } else { + return "000000004".getBytes(); + } + case STATE_FINAL : + return "000000005".getBytes(); + default : + throw new Exception("invalid state"); + } + } + + private void encodeMessage(IoSession session, ByteMessage m, ProtocolEncoderOutput out) throws Exception { + /** + * copy byte[] to buffer + */ + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate(length).limit(length); + buffer.put(m.getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | InisafeEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "InisafeEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + + public void dispose(IoSession session) throws Exception { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/handshake/InisafeClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/handshake/InisafeClientFilter.java new file mode 100644 index 0000000..5226dda --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/handshake/InisafeClientFilter.java @@ -0,0 +1,187 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe2020.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.initech.inisafenet.HandShakeManager; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; + + +public class InisafeClientFilter extends InisafeFilter { + public InisafeClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + HandShakeManager inisafeSession = new HandShakeManager(context.getInisafeConfigPath()); +// inisafeSession.TEST_MODE = false; + session.setAttribute(INISAFE_SESSION_KEY, inisafeSession); + + process(nextFilter, session, null); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + + /** + * State machine + */ + ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_INIT: + /* + * handshake timeout 설정함 + * timeout 에서 5초 전 설정 + */ + if (context.getTimeout() <= 5 ) { + throw new Exception("invalid timeout("+context.getTimeout()+") value . set timeout must be 5 or more. "); + } + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout() - 5); + /** + * change state to INIT + */ + filterState.state = State.STATE_INIT; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + + /** + * create INIT key + */ + byte[] initKey = inisafeSession.initHandShakeClient(null); + String initIndividualLL = CommonLib.getFormatString(initKey.length+4, 4); + //byte[] paddedInitKey = StringUtils.rightPad(new String(initKey), 92).getBytes(); + + buffer = ByteBuffer.allocate(4+initKey.length).limit(4+initKey.length); + buffer.put(initIndividualLL.getBytes()); + buffer.put(initKey); + + byte[] initIndividualBytes = new byte[4+initKey.length]; + buffer.position(0).get(initIndividualBytes); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_INIT"); + } + session.write(initIndividualBytes); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_UPDATE; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_UPDATE: + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_INIT response"); + } + + /** + * send UPDATE + */ + byte[] updateKey = inisafeSession.updateHandShakeClient(message.getBytes()); + String updateIndividualLL = CommonLib.getFormatString(updateKey.length+4, 4); + //byte[] paddedUpdateKey = StringUtils.rightPad(new String(updateKey), 268).getBytes(); + + buffer = ByteBuffer.allocate(4+updateKey.length).limit(4+updateKey.length); + buffer.put(updateIndividualLL.getBytes()); + buffer.put(updateKey); + + byte[] updateIndividualBytes = new byte[4+updateKey.length]; + buffer.position(0).get(updateIndividualBytes); + + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_UPDATE"); + } + session.write(updateIndividualBytes); + + /** + * change state to FINAL + */ + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_UPDATE response"); + } + + /** + * send FINAL + */ + byte[] finalKey = inisafeSession.finalHandShakeClient(message.getBytes()); + String finalIndividualLL = CommonLib.getFormatString(finalKey.length+4, 4); + //byte[] paddedFinalKey = StringUtils.rightPad(new String(finalKey), 92).getBytes(); + + buffer = ByteBuffer.allocate(4+finalKey.length).limit(4+finalKey.length); + buffer.put(finalIndividualLL.getBytes()); + buffer.put(finalKey); + + byte[] finalIndividualBytes = new byte[4+finalKey.length]; + buffer.position(0).get(finalIndividualBytes); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeClientFilter | KEY_FINAL"); + } + session.write(finalIndividualBytes); + + /** + * change state + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * finish handshake + */ + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog(context.getAdapterName() + " | InisafeClientFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | InisafeClientFilter | handshake finished ..."); + } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + + break; + + case STATE_MESSAGE: + validateMessage(message); + message = decrypt(message, session); + nextFilter.messageReceived(session, message); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + nextFilter.filterClose(session); + + adapter.getSessionPool().remove(session); + session.close(); + throw new Exception(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/handshake/InisafeFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/handshake/InisafeFilter.java new file mode 100644 index 0000000..5665406 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/handshake/InisafeFilter.java @@ -0,0 +1,210 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe2020.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import com.initech.inisafenet.HandShakeManager; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + + +abstract public class InisafeFilter extends IoFilterAdapter { + final protected Logger logger; + final protected Logger errLogger; + +// private static final String NEXT_FILTER = InisafeFilter.class.getName() + ".NextFilter"; + public static final String FILTER_STATE_KEY = InisafeFilter.class.getName() + ".STATE"; + + public static final String SESSION_STATE = "SESSION_STATE"; + public static final String INISAFE_SESSION_KEY = "INISAFE_SESSION_KEY"; + public static final byte[] INITIAL_VECTOR = "INISAFE NETWORK.".getBytes(); + + public static enum State { + STATE_START, + STATE_INIT, + STATE_UPDATE, + STATE_FINAL, + STATE_MESSAGE; + } + + public static class FilterState { + public State state = null; + public byte[] key; // token? + + public FilterState() {} + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected byte[] cert; + protected byte[] key; + protected String password; + protected byte[] remoteCert; + +// static { +// new InitechProvider(); +// } + + public InisafeFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + synchronized(session) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_INIT; + session.setAttribute(FILTER_STATE_KEY, filterState); + //setSessionState(session, filterState.state.toString()); + } + } + + // handshake future + session.setAttribute(ProtocolHandler.HANDSHAKE_FUTURE, new SimpleFuture()); + } + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { +// HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); +// inisafeSession.close(); + + nextFilter.sessionClosed(session); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteBuffer) { + m = new ByteMessage((ByteBuffer) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + /** + * encrypt + */ + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); +// HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + + switch (filterState.state) { + case STATE_MESSAGE: + validateMessage(m); +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + m = encrypt(m, session); + break; + + default: + break; + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new Exception(context.getAdapterName() + " | initech error - " + e.getMessage()); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + @Override + public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState.state != State.STATE_MESSAGE){ + StringBuffer sb = new StringBuffer(); + sb.append("idle:" + TimeUtil.elapsedTime(session.getLastIoTime())); + sb.append(", handshake timeout:" + (context.getTimeout() -5)); + sb.append(", protocol:" + context.getProtocol()); + if (filterState != null) { + sb.append(", state:" + filterState.state.toString()); + } + sb.append("/" + session.getAttribute(SESSION_STATE)); + logger.error(context.getAdapterName() + " | handshake timeout -> disconnecting (" + session + ") " + sb.toString()); + adapter.addRecentError(context.getAdapterName() + " | handshake timeout -> disconnecting (" + session + ") " + sb.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + adapter.getSessionPool().remove(session); + session.close(); + + + }else{ + nextFilter.sessionIdle(session, status); + } + } + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } + + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + + + protected void validateMessage(ByteMessage m) throws Exception { + if (m.size() < 200) { + throw new Exception("cannot send message - message size < 200 - " + m.hexDump()); + } + + String ll = new String(m.getBytes(0, 5)); + if (!ll.matches("[0-9]{5}")) { + throw new Exception("ll field (0-5) of message is not number - " + m.hexDump()); + } + } + + + protected ByteMessage encrypt(ByteMessage m, IoSession session) throws Exception { + /** + * 암호화 여부 체크 + */ + if ('Y' != m.getByte(99)) + return m; + + HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + byte[] encryptPart = inisafeSession.encrypt(m.getBytes(200-16-16)); + ByteMessage encrypted = new ByteMessage(m.getBytes(0, 200-16-16)).append(encryptPart); + + return encrypted; + } + + protected ByteMessage decrypt(ByteMessage m, IoSession session) throws Exception { + /** + * 암호화 여부 체크 + */ + if (m == null || 'Y' != m.getByte(99)) + return m; + + HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + byte[] decryptPart = inisafeSession.decrypt(m.getBytes(200-16-16)); + ByteMessage decrypted = new ByteMessage(m.getBytes(0, 200-16-16)).append(decryptPart); + + return decrypted; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/handshake/InisafeServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/handshake/InisafeServerFilter.java new file mode 100644 index 0000000..bd7cba2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafe2020/handshake/InisafeServerFilter.java @@ -0,0 +1,203 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafe2020.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.initech.inisafenet.HandShakeManager; +import com.initech.inisafenet.exception.INISAFENetException; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; + + +public class InisafeServerFilter extends InisafeFilter { + public InisafeServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + HandShakeManager inisafeSession = new HandShakeManager(context.getInisafeConfigPath()); + session.setAttribute(INISAFE_SESSION_KEY, inisafeSession); + } catch(INISAFENetException e) { + throw e; + } + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + //validateMessage(m); + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + HandShakeManager inisafeSession = null; + + try { + /** + * get filter state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + /** + * check inisafe session + */ + inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + if (inisafeSession == null) { + throw new Exception("inisafe session is not established"); + } + + /** + * state machine + */ + ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_INIT: + /* + * handshake timeout 설정함 + * timeout 에서 5초 전 설정 + */ + if (context.getTimeout() <= 5 ) { + throw new Exception("invalid timeout("+context.getTimeout()+") value . set timeout must be 5 or more. "); + } + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_INIT"); + } + + /** + * send INIT response + */ + byte[] initKey = inisafeSession.initHandShake(message.getBytes()); + String initIndividualLL = CommonLib.getFormatString(initKey.length+4, 4); + //byte[] paddedInitKey = StringUtils.rightPad(new String(initKey), 1792).getBytes(); + + buffer = ByteBuffer.allocate(4+initKey.length).limit(4+initKey.length); + buffer.put(initIndividualLL.getBytes()); + buffer.put(initKey); + + byte[] initIndividualBytes = new byte[4+initKey.length]; + buffer.position(0).get(initIndividualBytes); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_INIT response"); + } + session.write(initIndividualBytes); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_UPDATE; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_UPDATE: + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_UPDATE"); + } + + /** + * send UPDATE response + */ + byte[] updateKey = inisafeSession.updateHandShake(message.getBytes()); + String updateIndividualLL = CommonLib.getFormatString(updateKey.length+4, 4); + //byte[] paddedUpdateKey = StringUtils.rightPad(new String(updateKey), 108).getBytes(); + + buffer = ByteBuffer.allocate(4+updateKey.length).limit(4+updateKey.length); + buffer.put(updateIndividualLL.getBytes()); + buffer.put(updateKey); + + byte[] updateIndividualBytes = new byte[4+updateKey.length]; + buffer.position(0).get(updateIndividualBytes); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_UPDATE response"); + } + session.write(updateIndividualBytes); + + /** + * change state to FINAL + */ + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeServerFilter | KEY_FINAL"); + } + int result = inisafeSession.finalHandShake(message.getBytes()); + + if (result !=1){ + throw new Exception(" invalid message during handshake .. : " + message); + } + + /** + * change state to MESSAGE + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * start client pair socket adapter (in same socket adapter group) + */ + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + if(adapters == null) return; + for (int i=0; i= context.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog("InisafeServerFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | InisafeServerFilter | handshake finished ..."); + } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + //nextFilter.messageReceived(session, new ByteMessage("STARTED")); + + break; + + case STATE_MESSAGE: + validateMessage(message); + message = decrypt(message, session); + nextFilter.messageReceived(session, message); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + + adapter.getSessionPool().remove(session); + session.close(); + + throw new Exception(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnErrorMessage.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnErrorMessage.java new file mode 100644 index 0000000..db2832e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnErrorMessage.java @@ -0,0 +1,27 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafenatn; + +import java.util.Hashtable; + + +public class InisafeNatnErrorMessage { + static Hashtable hash = new Hashtable<>(); + + static { + hash.put("-1910", "ERR_POLICY_RESERVED_CN | 이미 등록되어 있은 CN 입니다."); + } + + private InisafeNatnErrorMessage() { + + } + public static String getErrorMessage(String key) { + String value = hash.get(key); + if (value == null) { + return "Unknown Error."; + } + return value; + } + + public static String getErrorMessage(int key) { + return getErrorMessage(String.valueOf(key)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnPayloadClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnPayloadClient.java new file mode 100644 index 0000000..cecdd74 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnPayloadClient.java @@ -0,0 +1,39 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafenatn; + +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.inisafenatn.codec.InisafeNatnPayloadCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.inisafenatn.handshake.InisafeNatnPayloadClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class InisafeNatnPayloadClient extends TcpAdapterClient { + boolean isBooting = true; + + public InisafeNatnPayloadClient(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new InisafeNatnPayloadClientHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new InisafeNatnPayloadCodecFactory(this))); + config.getFilterChain().addAfter("codec", "inisafe.codec", new InisafeNatnPayloadClientFilter(this)); + } + + @Override + public SimpleFuture start() throws Exception { + if (isBooting && !Env.isTest()) { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | InisafeNatnPayloadClient protocol - skip start process when booting ..."); + } + isBooting = false; + + SimpleFuture future = new SimpleFuture(); + future.set(Boolean.TRUE); + return future; + } else { + return super.start(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnPayloadClientHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnPayloadClientHandler.java new file mode 100644 index 0000000..00d016e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnPayloadClientHandler.java @@ -0,0 +1,40 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafenatn; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class InisafeNatnPayloadClientHandler extends InisafeNatnPayloadHandler { + public InisafeNatnPayloadClientHandler(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(IoSession session) throws Exception { + super.sessionOpened(session); + } + + @Override + public void sessionClosed(IoSession session) throws Exception { + super.sessionClosed(session); + /** + * client-server pair 로 작업한다. + */ + doSessionClosed(session); + } + + protected String messageReplace (String str){ + Matcher matcher = Pattern.compile("%d\\{([a-zA-Z \\-]+)\\}").matcher(str); + + while (matcher.find()) { + String datePattern = matcher.group(1); + DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern(datePattern); + str = str.replaceFirst("%d\\{([a-zA-Z \\-]+)\\}", dateFormat.format(ZonedDateTime.now())); + } + return str; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnPayloadHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnPayloadHandler.java new file mode 100644 index 0000000..bc94ddb --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/InisafeNatnPayloadHandler.java @@ -0,0 +1,38 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafenatn; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import org.apache.mina.common.IoSession; + + +public class InisafeNatnPayloadHandler extends ProtocolHandler { + public InisafeNatnPayloadHandler(ISocketAdapter adapter) { + super(adapter); + } + + protected void doSessionClosed (IoSession session) throws Exception { + /** + * client-server pair (in same adapter group) + */ + + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + if(adapters == null) return; + for (int i=0; i= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | InisafeNatnPayloadDecoder | handshake : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "InisafeNatnPayloadDecoder | handshake : " + CommonLib.hexDump(in, context)); + } + + CodecState codecState = (CodecState) session.getAttribute(H_DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(InisafeNatnPayloadConstants.COMMON_LENGTH); // LL Field 길이값(4): 전체전문 - LL필드길이 + session.setAttribute(H_DECODER_STATE_KEY, codecState); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { //length 읽은 이후? + //데이터 읽기 + codecState.buffer.position(InisafeNatnPayloadConstants.COMMON_LENGTH).limit(4+codecState.payloadSize); + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + //암호화 부분 : (length) + 암호회 + byte[] individualLL = new byte[4]; + codecState.buffer.position(InisafeNatnPayloadConstants.COMMON_LENGTH).get(individualLL); + int individualLength = Integer.parseInt(new String(individualLL)); + byte[] bytes = new byte[individualLength-4]; + codecState.buffer.position(InisafeNatnPayloadConstants.COMMON_LENGTH+4).get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(InisafeNatnPayloadConstants.COMMON_LENGTH); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + default : + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private void decodeMessage(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | InisafeNatnPayloadDecoder | decode : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "InisafeNatnPayloadDecoder | decode : " + CommonLib.hexDump(in, context)); + } + + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + + int ll = context.getLlFieldLength(); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(ll + context.getRecvPayloadLength()); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit() - ll]; + codecState.buffer.position(ll); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(ll + context.getRecvPayloadLength()); + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + } + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.buffer.flip(); + try { + byte[] commonLL = new byte[4]; + codecState.buffer.position(0).get(commonLL); + codecState.payloadSize = Integer.parseInt(new String(commonLL)); //전문 전체 크기 + codecState.buffer.position(0); + } catch (NumberFormatException e) { +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA008"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA008"); + throw new EAIException("RECEAINNA008", context.getAdapterName() + + "when read header, number format is invalid - " + + e.getMessage() + " | " + CommonLib.hexDump(codecState.buffer, context)); + } + + if (codecState.payloadSize > MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + MAX_PAYLOAD_SIZE + ") exceeded : " + codecState.payloadSize); + } + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/codec/InisafeNatnPayloadEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/codec/InisafeNatnPayloadEncoder.java new file mode 100644 index 0000000..c00e8dd --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/codec/InisafeNatnPayloadEncoder.java @@ -0,0 +1,177 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafenatn.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.inisafenatn.handshake.InisafeNatnPayloadFilter; +import com.eactive.eai.adapter.socket2.protocol.inisafenatn.handshake.InisafeNatnPayloadFilter.FilterState; +import com.eactive.eai.common.util.Logger; +import org.apache.commons.lang3.StringUtils; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class InisafeNatnPayloadEncoder implements ProtocolEncoder { + final protected Logger logger; + final protected Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public InisafeNatnPayloadEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + boolean isHandshakeState = false; + FilterState filterState = (FilterState) session.getAttribute(InisafeNatnPayloadFilter.FILTER_STATE_KEY); + if (filterState != null && filterState.state != InisafeNatnPayloadFilter.State.STATE_MESSAGE) { + isHandshakeState = true; + } + + if (isHandshakeState) { + encodeHandshake(session, m, out); + } else { + encodeMessage(session, m, out); + } + } + + + private void encodeHandshake(IoSession session, ByteMessage m, ProtocolEncoderOutput out) throws Exception { + int length = m.size(); + int totalLength = InisafeNatnPayloadConstants.COMMON_LENGTH + length; + + ByteBuffer buffer = ByteBuffer.allocate(totalLength).limit(totalLength); + + /** + * [1] common ll + */ + String commonLL = CommonLib.getFormatString(totalLength-InisafeNatnPayloadConstants.COMMON_LL_LENGTH, InisafeNatnPayloadConstants.COMMON_LL_LENGTH); + buffer.put(commonLL.getBytes()); // 1 전문송신 Byte 수 4 N * 비고 1) 참조 + + /** + * [2] common rest + */ + buffer.put(getTransactionType(session)); // 2 거래구분코드 9 A + buffer.put("00".getBytes()); // 3 업무코드 2 A * Space + buffer.put("00".getBytes()); // 4 거래종류코드 2 A * Space + buffer.put(" ".getBytes()); // 5 요청응답구분코드 1 A * Space + buffer.put(" ".getBytes()); // 6 송신기관코드 3 A * Space + buffer.put(" ".getBytes()); // 7 수신기관코드 3 A * Space + buffer.put(" ".getBytes()); // 8 거래일자 8 N * Space + buffer.put(" ".getBytes()); // 9 거래시각 6 N * Space + buffer.put(" ".getBytes()); // 10 전문관리번호 7 N * Space + buffer.put(" ".getBytes()); // 11 처리기관코드 3 N * Space + buffer.put(" ".getBytes()); // 12 처리결과코드 4 A * Space + buffer.put(" ".getBytes()); // 13 코드변환구분 1 A * Space + buffer.put(StringUtils.leftPad("", 61).getBytes()); // 14 공란1 61 A * Space + buffer.put(StringUtils.leftPad("", 20).getBytes()); // 15 사용자ID 20 A * Space + buffer.put(" ".getBytes()); // 16 Password 8 A * Space + + /** + * [3] individual part + */ + buffer.put(m.getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | InisafeNatnPayloadEncoder | encode (handshake) : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "InisafeNatnPayloadEncoder | encode (handshake) : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + + private byte[] getTransactionType(IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(InisafeNatnPayloadFilter.FILTER_STATE_KEY); + if (filterState == null) { + throw new Exception("session does not have filter state"); + } + + switch (filterState.state) { + case STATE_INIT : + if (adapter.getContext().isClient()) { + return "000000001".getBytes(); + } else { + return "000000002".getBytes(); + } + case STATE_UPDATE : + if (adapter.getContext().isClient()) { + return "000000003".getBytes(); + } else { + return "000000004".getBytes(); + } + case STATE_FINAL : + return "000000005".getBytes(); + default : + throw new Exception("invalid state"); + } + } + + private void encodeMessage(IoSession session, ByteMessage m, ProtocolEncoderOutput out) throws Exception { + /** + * copy byte[] to buffer + */ + int length = m.size(); + //ByteBuffer buffer = ByteBuffer.allocate(length).limit(length); + ByteBuffer buffer = ByteBuffer.allocate(context.getLlFieldLength() + length).limit(context.getLlFieldLength() + length); + + /** + * ll.include = 'Y' - 길이필드 붙이기 + * BOK - payload 사이즈 ll필드를 붙이는 기관이 존재 + */ +// if ("Y".equals(context.getLlInclude())) { +// String lenStr = CommonLib.getFormatString(context.getSendPayloadLength(), context.getLlFieldLength()); +// buffer.put(lenStr.getBytes()); +// } + if(context.getLlFieldLength() > 0){ + String lenStr = CommonLib.getFormatString(context.getSendPayloadLength(), context.getLlFieldLength()); + buffer.put(lenStr.getBytes()); + } + + buffer.put(m.getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | InisafeEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "InisafeEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + + public void dispose(IoSession session) throws Exception { + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/handshake/InisafeNatnPayloadClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/handshake/InisafeNatnPayloadClientFilter.java new file mode 100644 index 0000000..a143352 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/handshake/InisafeNatnPayloadClientFilter.java @@ -0,0 +1,189 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafenatn.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.initech.inisafenet.HandShakeManager; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; + + +public class InisafeNatnPayloadClientFilter extends InisafeNatnPayloadFilter { + public InisafeNatnPayloadClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + HandShakeManager inisafeSession = new HandShakeManager(context.getInisafeConfigPath()); +// inisafeSession.TEST_MODE = false; + session.setAttribute(INISAFE_SESSION_KEY, inisafeSession); + + process(nextFilter, session, null); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + + /** + * State machine + */ + ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_INIT: + /* + * handshake timeout 설정함 + * timeout 에서 5초 전 설정 + */ + if (context.getTimeout() <= 5 ) { + throw new Exception("invalid timeout("+context.getTimeout()+") value . set timeout must be 5 or more. "); + } + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout() - 5); + /** + * change state to INIT + */ + filterState.state = State.STATE_INIT; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + + /** + * create INIT key + */ + byte[] initKey = inisafeSession.initHandShakeClient(null); + String initIndividualLL = CommonLib.getFormatString(initKey.length+4, 4); + //byte[] paddedInitKey = StringUtils.rightPad(new String(initKey), 92).getBytes(); + + buffer = ByteBuffer.allocate(4+initKey.length).limit(4+initKey.length); + buffer.put(initIndividualLL.getBytes()); + buffer.put(initKey); + + byte[] initIndividualBytes = new byte[4+initKey.length]; + buffer.position(0).get(initIndividualBytes); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafeNatnClientFilter | KEY_INIT"); + } + session.write(initIndividualBytes); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_UPDATE; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_UPDATE: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafeNatnClientFilter | KEY_INIT response"); + } + if(message == null) throw new Exception("Message is NULL"); + /** + * send UPDATE + */ + byte[] updateKey = inisafeSession.updateHandShakeClient(message.getBytes()); + String updateIndividualLL = CommonLib.getFormatString(updateKey.length+4, 4); + //byte[] paddedUpdateKey = StringUtils.rightPad(new String(updateKey), 268).getBytes(); + + buffer = ByteBuffer.allocate(4+updateKey.length).limit(4+updateKey.length); + buffer.put(updateIndividualLL.getBytes()); + buffer.put(updateKey); + + byte[] updateIndividualBytes = new byte[4+updateKey.length]; + buffer.position(0).get(updateIndividualBytes); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafeNatnClientFilter | KEY_UPDATE"); + } + session.write(updateIndividualBytes); + + /** + * change state to FINAL + */ + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeNatnClientFilter | KEY_UPDATE response"); + } + if(message == null) throw new Exception("Message is NULL"); + /** + * send FINAL + */ + byte[] finalKey = inisafeSession.finalHandShakeClient(message.getBytes()); + String finalIndividualLL = CommonLib.getFormatString(finalKey.length+4, 4); + //byte[] paddedFinalKey = StringUtils.rightPad(new String(finalKey), 92).getBytes(); + + buffer = ByteBuffer.allocate(4+finalKey.length).limit(4+finalKey.length); + buffer.put(finalIndividualLL.getBytes()); + buffer.put(finalKey); + + byte[] finalIndividualBytes = new byte[4+finalKey.length]; + buffer.position(0).get(finalIndividualBytes); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeNatnClientFilter | KEY_FINAL"); + } + session.write(finalIndividualBytes); + + /** + * change state + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * finish handshake + */ + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog(context.getAdapterName() + " | InisafeNatnClientFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | InisafeNatnClientFilter | handshake finished ..."); + } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + + break; + + case STATE_MESSAGE: + if(message == null) throw new Exception("Message is NULL"); + //validateMessage(message); + message = decrypt(message, session); + nextFilter.messageReceived(session, message); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + nextFilter.filterClose(session); + + adapter.getSessionPool().remove(session); + session.close(); + throw new Exception(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/handshake/InisafeNatnPayloadFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/handshake/InisafeNatnPayloadFilter.java new file mode 100644 index 0000000..9442c02 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/handshake/InisafeNatnPayloadFilter.java @@ -0,0 +1,209 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafenatn.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.common.TimeUtil; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.adapter.socket2.protocol.inisafenatn.codec.InisafeNatnPayloadConstants; +import com.eactive.eai.common.util.Logger; +import com.initech.inisafenet.HandShakeManager; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + + +public abstract class InisafeNatnPayloadFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + private final Object lockObj = new Object(); +// private static final String NEXT_FILTER = InisafeNatnPayloadFilter.class.getName() + ".NextFilter"; + public static final String FILTER_STATE_KEY = InisafeNatnPayloadFilter.class.getName() + ".STATE"; + + public static final String SESSION_STATE = "SESSION_STATE"; + public static final String INISAFE_SESSION_KEY = "INISAFE_SESSION_KEY"; + public static final byte[] INITIAL_VECTOR = "INISAFE NETWORK.".getBytes(); + + public enum State { + STATE_START, + STATE_INIT, + STATE_UPDATE, + STATE_FINAL, + STATE_MESSAGE; + } + + public static class FilterState { + public State state = null; + public byte[] key; // token? + + public FilterState() {} + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected byte[] cert; + protected byte[] key; + protected String password; + protected byte[] remoteCert; + +/* static { + new InitechProvider(); + }*/ + + public InisafeNatnPayloadFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + synchronized(lockObj) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_INIT; + session.setAttribute(FILTER_STATE_KEY, filterState); + //setSessionState(session, filterState.state.toString()); + } + } + + // handshake future + session.setAttribute(ProtocolHandler.HANDSHAKE_FUTURE, new SimpleFuture()); + } + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { +// HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); +// inisafeSession.close(); + + nextFilter.sessionClosed(session); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteBuffer) { + m = new ByteMessage((ByteBuffer) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + /** + * encrypt + */ + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); +// HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + + switch (filterState.state) { + case STATE_MESSAGE: + //validateMessage(m); +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + m = encrypt(m, session); + break; + + default: + break; + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new Exception(context.getAdapterName() + " | initech error - " + e.getMessage()); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + @Override + public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if(filterState == null) { + logger.error(context.getAdapterName() + " | filterState is NULL"); + } + else { + if (filterState.state != State.STATE_MESSAGE){ + StringBuilder sb = new StringBuilder(); + sb.append("idle:" + TimeUtil.elapsedTime(session.getLastIoTime())); + sb.append(", handshake timeout:" + (context.getTimeout() -5)); + sb.append(", protocol:" + context.getProtocol()); + sb.append(", state:" + filterState.state.toString()); + sb.append("/" + session.getAttribute(SESSION_STATE)); + logger.error(context.getAdapterName() + " | handshake timeout -> disconnecting (" + session + ") " + sb.toString()); + adapter.addRecentError(context.getAdapterName() + " | handshake timeout -> disconnecting (" + session + ") " + sb.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + adapter.getSessionPool().remove(session); + session.close(); + }else{ + nextFilter.sessionIdle(session, status); + } + } + } + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } + + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + + + protected void validateMessage(ByteMessage m) throws Exception { + if (m.size() < 200) { + throw new Exception("cannot send message - message size < 200 - " + m.hexDump()); + } + + String ll = new String(m.getBytes(0, 5)); + if (!ll.matches("[0-9]{5}")) { + throw new Exception("ll field (0-5) of message is not number - " + m.hexDump()); + } + } + + + protected ByteMessage encrypt(ByteMessage m, IoSession session) throws Exception { + + HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + int llLen = 0; + +// if ("Y".equals(context.getLlInclude())) { +// llLen = 4; +// } + + byte[] encryptPart = inisafeSession.encrypt(m.getBytes(InisafeNatnPayloadConstants.UN_ENC_LENGTH+llLen)); + return new ByteMessage(m.getBytes(0, InisafeNatnPayloadConstants.UN_ENC_LENGTH)).append(encryptPart); + } + + protected ByteMessage decrypt(ByteMessage m, IoSession session) throws Exception { + + HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + + int llLen = 0; +// if ("Y".equals(context.getLlInclude())) { +// llLen = 4; +// } + byte[] decryptPart = inisafeSession.decrypt(m.getBytes(InisafeNatnPayloadConstants.UN_ENC_LENGTH+llLen)); + return new ByteMessage(m.getBytes(0, InisafeNatnPayloadConstants.UN_ENC_LENGTH)).append(decryptPart); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/handshake/InisafeNatnPayloadServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/handshake/InisafeNatnPayloadServerFilter.java new file mode 100644 index 0000000..8226d02 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafenatn/handshake/InisafeNatnPayloadServerFilter.java @@ -0,0 +1,205 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafenatn.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.initech.inisafenet.HandShakeManager; +import com.initech.inisafenet.exception.INISAFENetException; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; + + +public class InisafeNatnPayloadServerFilter extends InisafeNatnPayloadFilter { + public InisafeNatnPayloadServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + //KeyStorageManager ksm = new KeyStorageManager(null); + HandShakeManager inisafeSession = new HandShakeManager(context.getInisafeConfigPath()); + session.setAttribute(INISAFE_SESSION_KEY, inisafeSession); + } catch(INISAFENetException e) { + throw e; + } + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + //validateMessage(m); + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + HandShakeManager inisafeSession = null; + + try { + /** + * get filter state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + /** + * check inisafe session + */ + inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + if (inisafeSession == null) { + throw new Exception("inisafe session is not established"); + } + + /** + * state machine + */ + ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_INIT: + /* + * handshake timeout 설정함 + * timeout 에서 5초 전 설정 + */ + if (context.getTimeout() <= 5 ) { + throw new Exception("invalid timeout("+context.getTimeout()+") value . set timeout must be 5 or more. "); + } + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeNatnPayloadServerFilter | KEY_INIT"); + } + + /** + * send INIT response + */ + byte[] initKey = inisafeSession.initHandShake(message.getBytes()); + String initIndividualLL = CommonLib.getFormatString(initKey.length+4, 4); + //byte[] paddedInitKey = StringUtils.rightPad(new String(initKey), 1792).getBytes(); + + buffer = ByteBuffer.allocate(4+initKey.length).limit(4+initKey.length); + buffer.put(initIndividualLL.getBytes()); + buffer.put(initKey); + + byte[] initIndividualBytes = new byte[4+initKey.length]; + buffer.position(0).get(initIndividualBytes); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeNatnPayloadServerFilter | KEY_INIT response"); + } + session.write(initIndividualBytes); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_UPDATE; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_UPDATE: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeNatnPayloadServerFilter | KEY_UPDATE"); + } + + /** + * send UPDATE response + */ + byte[] updateKey = inisafeSession.updateHandShake(message.getBytes()); + String updateIndividualLL = CommonLib.getFormatString(updateKey.length+4, 4); + //byte[] paddedUpdateKey = StringUtils.rightPad(new String(updateKey), 108).getBytes(); + + buffer = ByteBuffer.allocate(4+updateKey.length).limit(4+updateKey.length); + buffer.put(updateIndividualLL.getBytes()); + buffer.put(updateKey); + + byte[] updateIndividualBytes = new byte[4+updateKey.length]; + buffer.position(0).get(updateIndividualBytes); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeNatnPayloadServerFilter | KEY_UPDATE response"); + } + session.write(updateIndividualBytes); + + /** + * change state to FINAL + */ + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafeNatnPayloadServerFilter | KEY_FINAL"); + } + int result = inisafeSession.finalHandShake(message.getBytes()); + + if (result !=1){ + throw new Exception(" invalid message during handshake .. : " + message); + } + + + /** + * change state to MESSAGE + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * start client pair socket adapter (in same socket adapter group) + */ + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + for (int i=0; i= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog("InisafeNatnPayloadServerFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | InisafeNatnPayloadServerFilter | handshake finished ..."); + } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + //nextFilter.messageReceived(session, new ByteMessage("STARTED")); + + break; + + case STATE_MESSAGE: + //validateMessage(message); + message = decrypt(message, session); + nextFilter.messageReceived(session, message); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + + adapter.getSessionPool().remove(session); + session.close(); + + throw new Exception(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadClient.java new file mode 100644 index 0000000..9044afa --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadClient.java @@ -0,0 +1,21 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafepayload; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.inisafepayload.codec.InisafePayloadCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.inisafepayload.handshake.InisafePayloadClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class InisafePayloadClient extends TcpAdapterClient { + boolean isBooting = true; + + public InisafePayloadClient(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new InisafePayloadClientHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new InisafePayloadCodecFactory(this))); + config.getFilterChain().addAfter("codec", "inisafe_kofc.codec", new InisafePayloadClientFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadClientHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadClientHandler.java new file mode 100644 index 0000000..72dd6a5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadClientHandler.java @@ -0,0 +1,9 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafepayload; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + +public class InisafePayloadClientHandler extends InisafePayloadHandler { + public InisafePayloadClientHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadHandler.java new file mode 100644 index 0000000..2b4f67b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadHandler.java @@ -0,0 +1,11 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafepayload; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + + +public class InisafePayloadHandler extends ProtocolHandler { + public InisafePayloadHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadServer.java new file mode 100644 index 0000000..1f45a8e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadServer.java @@ -0,0 +1,19 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafepayload; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.inisafepayload.codec.InisafePayloadCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.inisafepayload.handshake.InisafePayloadServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class InisafePayloadServer extends TcpAdapterServer { + public InisafePayloadServer(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new InisafePayloadServerHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new InisafePayloadCodecFactory(this))); + config.getFilterChain().addAfter("codec", "inisafe_kofc.codec", new InisafePayloadServerFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadServerHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadServerHandler.java new file mode 100644 index 0000000..28c27b5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/InisafePayloadServerHandler.java @@ -0,0 +1,38 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafepayload; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + +import java.net.InetSocketAddress; + + +public class InisafePayloadServerHandler extends InisafePayloadHandler { + public InisafePayloadServerHandler(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(IoSession session) throws Exception { + super.sessionOpened(session); + } + + @Override + public void sessionClosed(IoSession session) throws Exception { + super.sessionClosed(session); + + /** + * L4 에 오는 polling (check) connection 이면 무시한다. + */ + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + if(adapters == null) return; + for (int i=0; i= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | InisafePayloadDecoder | decode : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "InisafePayloadDecoder | decode : " + CommonLib.hexDump(in, context)); + } + + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + + if ( (codecState == null) && (context.getRecvPayloadLength() > 0) ) { + codecState = new CodecState(); + codecState.buffer.limit(context.getRecvPayloadLength()); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(context.getRecvPayloadLength()); + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + } + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /** + * 읽으려는 size 만큼 아직 data가 오지 못함 + */ + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + /** + * 읽으려는 size 에 도달 + */ + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/codec/InisafePayloadEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/codec/InisafePayloadEncoder.java new file mode 100644 index 0000000..f296008 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/codec/InisafePayloadEncoder.java @@ -0,0 +1,67 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafepayload.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class InisafePayloadEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public InisafePayloadEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + /** + * copy byte[] to buffer + */ + int length = context.getSendPayloadLength(); + ByteBuffer buffer = ByteBuffer.allocate(length).limit(length); + buffer.put(m.getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | InisafePayloadEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "InisafePayloadEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + public void dispose(IoSession session) throws Exception { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/handshake/InisafePayloadClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/handshake/InisafePayloadClientFilter.java new file mode 100644 index 0000000..c1c4665 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/handshake/InisafePayloadClientFilter.java @@ -0,0 +1,321 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafepayload.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.initech.inisafenet.HandShakeManager; +import com.initech.inisafenet.exception.INISAFENetException; +import com.initech.inisafenet.util.INISAFENetCryptoUtil; +import java.util.Arrays; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; + + +public class InisafePayloadClientFilter extends InisafePayloadFilter { + public InisafePayloadClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + HandShakeManager inisafeSession = new HandShakeManager(context.getInisafeConfigPath()); + session.setAttribute(INISAFE_SESSION_KEY, inisafeSession); + } catch(INISAFENetException e) { + throw e; + } + process(nextFilter, session, null); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + try { + + HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + + /** + * State machine + */ + ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_INIT: + /** + * change state to INIT + */ + filterState.state = State.STATE_INIT; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + + /** + * create INIT key + */ + byte[] initKey = inisafeSession.initHandShakeClient(null); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(Arrays.toString(initKey) + " | InisafePayloadClientFilter | initKey Value"); + } + buffer = ByteBuffer.allocate(context.getSendPayloadLength()).limit(context.getSendPayloadLength()); + + buffer.put(initKey); + while(buffer.hasRemaining()){ + buffer.put(" ".getBytes()); + } + buffer.position(0); + + logger.debug(buffer + " | InisafePayloadClientFilter | Buffer Value"); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | KEY_INIT"); + } + session.write(buffer); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_UPDATE; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_UPDATE: + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | KEY_INIT response"); + } + + /** + * send UPDATE + * null Padding + */ + + if(message == null) { + throw new Exception("receive message is null"); + } + + byte[] updateKey = inisafeSession.updateHandShakeClient(message.getBytes(0,1496)); + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(Arrays.toString(updateKey) + " | InisafePayloadClientFilter | Update Value"); + } + + /** + * 기관요청에 의해 UpdateHandshake 시 ID-PASSWORD 자리를 스페이스 32바이트 송신 + */ + String idpw32 = " "; + buffer = ByteBuffer.allocate(context.getSendPayloadLength()).limit(context.getSendPayloadLength()); + buffer.put(updateKey); + while(buffer.hasRemaining()){ + buffer.put(" ".getBytes()); + } + buffer.position(384); + buffer.put(idpw32.getBytes()); + buffer.position(0); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(buffer + " | InisafePayloadClientFilter | Buffer Value"); + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | KEY_UPDATE"); + } + session.write(buffer); + + /** + * change state to FINAL + */ + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | KEY_UPDATE response"); + } + + /** + * send FINAL + * null Padding + */ + if(message == null) { + throw new Exception("message is null"); + } + byte[] finalKey = inisafeSession.finalHandShakeClient(message.getBytes(0,116)); + + buffer = ByteBuffer.allocate(context.getSendPayloadLength()).limit(context.getSendPayloadLength()); + buffer.put(finalKey); + while(buffer.hasRemaining()){ + buffer.put(" ".getBytes()); + } + /** + * 20100515 JGY + * 금융기관인증정보생성 : 은행코드(3) + ID(8) + Password(20) + */ + String tmp = context.getInisafeIdPassword(); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | tmp : " + tmp.toString()); + } + ByteMessage id_pw = new ByteMessage(inisafeSession.i_encrypt(tmp.getBytes())); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | id_pw : " + id_pw.toString()); + } + + buffer.position(96); + buffer.put(id_pw.getBytes()); + buffer.position(0); + + session.write(buffer); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog(context.getAdapterName() + " | InisafePayloadClientFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | KEY_FINAL" + CommonLib.hexDump(buffer, context)); + } + + /** + * change state + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + + break; + + case STATE_MESSAGE: + + if(message == null) { + throw new Exception("receive message is null"); + } + byte[] bm = message.getBytes(0, message.size()-48); + byte[] verify = message.getBytes(message.size()-48, 20); + + /** + * 메시지 HASH + */ + INISAFENetCryptoUtil cryptoUtil = new INISAFENetCryptoUtil(); + byte[] hashBuf = cryptoUtil.getDigest(bm, "SHA1"); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | hashBuf" + CommonLib.hexDump(hashBuf, true, context)); + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | verify" + CommonLib.hexDump(verify, true, context)); + } + + String verifyString = new String(verify); + String hashBufString = new String(hashBuf); + + if(!hashBufString.equals(verifyString)) { + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog(context.getAdapterName() + " | InisafePayloadClientFilter | Integrity Verification Fail"); + logger.debug(context.getAdapterName() + " | InisafePayloadClientFilter | Integrity Verification Fail"); + } + nextFilter.filterClose(session); + adapter.getSessionPool().remove(session); + session.close(); + throw new Exception(context.getAdapterName() + " | initech error - "); + + } else { + + /** + * 메시지 복호화 + */ + byte[] dBuf = inisafeSession. i_decrypt(bm); + + /** + * 암호화 처리된 업무 전문의 맨 끝 16 Byte를 + * 다음 업무 전문의 암/복호 처리를 위한 보조 암호키로 사용할 수 있도록 이니셜벡터 처리 + */ + byte[] iv = new byte[16]; + System.arraycopy(message.getBytes(), bm.length - 16, iv, 0, 16); + inisafeSession.setIV(iv); + + /** + * 폴링전문 처리 + * 온라인 : 0100P 00409299999910000000일자(14}000 N P + * 일 괄 : 0023KoFC-OLB_POLLINGTESTREQ + */ + byte[] eBuf = new byte[7]; + System.arraycopy(dBuf, 20, eBuf, 0, 7); + + String eBufString = new String(eBuf); + + if ("9999910".equals(eBufString) || "TESTREP".equals(eBufString)) { + + adapter.addRecentRecv(session, "PollingFilter | polling request - " + CommonLib.hexDump(dBuf, true, context)); + break; + + } else if ("9999900".equals(eBufString)) { + + byte[] p2Buf = new byte[21]; + byte[] p4Buf = new byte[79]; + + System.arraycopy(dBuf, 4, p2Buf, 0, 21); + System.arraycopy(dBuf, 26, p4Buf, 0, 79); + ByteMessage polling = new ByteMessage("0100".getBytes()).append(p2Buf).append("1".getBytes()).append(p4Buf); + adapter.addRecentSend(session, "PollingFilter | polling response - " + polling.hexDump()); + + session.write(polling); + + break; + + } else if ("TESTREQ".equals(eBufString)) { + + ByteMessage polling = new ByteMessage("0023KoFC-OLB_POLLINGTESTREP".getBytes()); + adapter.addRecentSend(session, "PollingFilter | polling response - " + polling.hexDump()); + + session.write(polling); + + break; + } + + /** + * 메시지 길이 파싱 + */ + byte[] byteRecvLL = new byte[4]; + System.arraycopy(dBuf, 0, byteRecvLL, 0, 4); + + int intRecvLL = Integer.parseInt(new String(byteRecvLL)); + + /** + * 메시지 길이만큼만 업무 프로세스로 송신 + */ + buffer = ByteBuffer.allocate(intRecvLL+4).limit(intRecvLL+4); + byte[] byteRecvBuf = new byte[intRecvLL+4]; + System.arraycopy(dBuf, 0, byteRecvBuf, 0, intRecvLL+4); + buffer.put(byteRecvBuf); + buffer.position(0); + + message = new ByteMessage(buffer); + + } + + nextFilter.messageReceived(session, message); + + break; + + default: + throw new Exception(" invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + adapter.getSessionPool().remove(session); + session.close(); + + throw new Exception(context.getAdapterName() + " | inisafe error - " + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/handshake/InisafePayloadFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/handshake/InisafePayloadFilter.java new file mode 100644 index 0000000..75d3fd6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/handshake/InisafePayloadFilter.java @@ -0,0 +1,178 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafepayload.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import com.initech.inisafenet.HandShakeManager; +import com.initech.inisafenet.util.INISAFENetCryptoUtil; +import com.initech.provider.crypto.InitechProvider; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + + +public abstract class InisafePayloadFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + + public static final String FILTER_STATE_KEY = InisafePayloadFilter.class.getName() + ".STATE"; + + public static final String SESSION_STATE = "SESSION_STATE"; + public static final String INISAFE_SESSION_KEY = "INISAFE_SESSION_KEY"; + + public enum State { + STATE_START, + STATE_INIT, + STATE_UPDATE, + STATE_FINAL, + STATE_MESSAGE; + } + + public static class FilterState { + public State state = null; + public byte[] key; // token? + + public FilterState() {} + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected byte[] cert; + protected byte[] key; + protected String password; + protected byte[] remoteCert; + + static { + new InitechProvider(); + } + + protected InisafePayloadFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + synchronized(session) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_INIT; + session.setAttribute(FILTER_STATE_KEY, filterState); + } + } + + // handshake future + session.setAttribute(ProtocolHandler.HANDSHAKE_FUTURE, new SimpleFuture()); + } + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { +// HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + + nextFilter.sessionClosed(session); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + ByteBuffer buffer = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteBuffer) { + m = new ByteMessage((ByteBuffer) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + /** + * encrypt + */ + try { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + HandShakeManager inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + + switch (filterState.state) { + case STATE_MESSAGE: + + buffer = ByteBuffer.allocate(context.getSendPayloadLength()).limit(context.getSendPayloadLength()); + + /** + * 업무전문을 무조건 4047 바이트화 (데이터 + Null) + */ + byte[] encBuffer = new byte[4047]; + System.arraycopy(m.getBytes(), 0, encBuffer, 0, m.getBytes().length); + + /** + * 4047 바이트를 암호화하면 4048 바이트 리턴 + */ + byte[] mBuffer = new byte[4048]; + mBuffer = inisafeSession.i_encrypt(encBuffer); + buffer.put(mBuffer); + + + /** + * 업무전문의 암호화를 위한 보조 암호키로 사용(데이터 마지막부터 16바이트) + */ + byte[] iv = new byte[16]; + System.arraycopy(mBuffer, mBuffer.length - 16, iv, 0, 16); + inisafeSession.setIV(iv); + + + /** + * 암호검증용 Hash 값 (20바이트) + */ + INISAFENetCryptoUtil cryptoUtil = new INISAFENetCryptoUtil(); + byte[] hashBuf = cryptoUtil.getDigest(mBuffer, "SHA1"); + buffer.position(4048); + buffer.put(hashBuf); + buffer.position(0); + /** + * 4K 데이터 송신을 위한 버퍼이동 + */ + m = new ByteMessage(buffer); + logger.debug(context.getAdapterName() + " | InisafePayloadFilter | m : " + m.hexDump()); + + + break; + + default: + break; + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new Exception(context.getAdapterName() + " | initech error - " + e.getMessage()); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } + + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/handshake/InisafePayloadServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/handshake/InisafePayloadServerFilter.java new file mode 100644 index 0000000..ed00db7 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/inisafepayload/handshake/InisafePayloadServerFilter.java @@ -0,0 +1,246 @@ +package com.eactive.eai.adapter.socket2.protocol.inisafepayload.handshake; + +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.initech.inisafenet.HandShakeManager; +import com.initech.inisafenet.exception.INISAFENetException; +import com.initech.inisafenet.util.INISAFENetCryptoUtil; +import java.util.Arrays; + + +public class InisafePayloadServerFilter extends InisafePayloadFilter { + public InisafePayloadServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + HandShakeManager inisafeSession = new HandShakeManager(context.getInisafeConfigPath()); + session.setAttribute(INISAFE_SESSION_KEY, inisafeSession); + } catch(INISAFENetException e) { + throw e; + } + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + HandShakeManager inisafeSession = null; + + try { + /** + * get filter state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + /** + * check inisafe session + */ + inisafeSession = (HandShakeManager) session.getAttribute(INISAFE_SESSION_KEY); + if (inisafeSession == null) { + throw new Exception("inisafe session is not established"); + } + + /** + * state machine + */ + ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_INIT: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | KEY_INIT"); + } + + /** + * send INIT response + */ + byte[] initKey = inisafeSession.initHandShake(message.getBytes()); + + buffer = ByteBuffer.allocate(context.getRecvPayloadLength()).limit(context.getRecvPayloadLength()); + + buffer.put(initKey); + buffer.position(0); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | KEY_INIT response"); + } + + session.write(buffer); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_UPDATE; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_UPDATE: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | KEY_UPDATE"); + } + + /** + * send UPDATE response + * LL 데이터 전송 테스트 JGY + */ + // LL 생성 + // String updateLL = CommonLib.getFormatString(updateKey.length, 4); + // LL 파싱 + // int intUpdateLL = Integer.parseInt(new String(message.getBytes(4000,4))); + // byte[] updateKey = inisafeSession.updateHandShake(message.getBytes(0, intUpdateLL)); + + byte[] idpw32 = message.getBytes(384, 32); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | id_pw : " + Arrays.toString(idpw32)); + } + + byte[] updateKey = inisafeSession.updateHandShake(message.getBytes()); + + /** + * ByteBuffer 타입의 buffer가 버퍼 초기화가 될 수 없어 객체 신규생성 + */ + byte[] updateKeyBuffer = new byte[context.getRecvPayloadLength()]; + + System.arraycopy(updateKey, 0, updateKeyBuffer, 0, updateKey.length); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | KEY_UPDATE response"); + } + session.write(updateKeyBuffer); + + /** + * change state to FINAL + */ + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + + inisafeSession.finalHandShake(message.getBytes(0,96)); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | KEY_FINAL"); + } + + /** + * Client 에서 ID/Password를 송신하면 서버에서 복호화 후 검증 테스트 + */ + byte[] id_pw = message.getBytes(384, 32); + id_pw = inisafeSession.i_decrypt(id_pw); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | id_pw : " + Arrays.toString(id_pw)); + } + + /** + * change state to MESSAGE + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * handshake finished + */ + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog("InisafePayloadServerFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | handshake finished ..."); + } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + + break; + + case STATE_MESSAGE: + + byte[] bm = new byte[4048]; + bm = message.getBytes(0, message.size()-48); + byte[] verify = message.getBytes(message.size()-48, 20); + + /** + * 메시지 HASH + */ + INISAFENetCryptoUtil cryptoUtil = new INISAFENetCryptoUtil(); + byte[] hashBuf = cryptoUtil.getDigest(bm, "SHA1"); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | bm : " + CommonLib.hexDump(bm, true, context)); + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | hashBuf : " + CommonLib.hexDump(hashBuf, true, context)); + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | verify : " + CommonLib.hexDump(verify, true, context)); + } + +// if(!hashBuf.equals(verify)) { + if(!Arrays.equals(hashBuf, verify)) { + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog(context.getAdapterName() + " | InisafePayloadServerFilter | Integrity Verification Fail"); + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | Integrity Verification Fail"); + } + nextFilter.filterClose(session); + adapter.getSessionPool().remove(session); + session.close(); + throw new Exception(context.getAdapterName() + " | initech error - "); + + } else { + + buffer = ByteBuffer.allocate(context.getSendPayloadLength()).limit(context.getSendPayloadLength()); + + /** + * 암호화 처리된 업무 전문의 맨 끝 16 Byte를 + * 다음 업무 전문의 암/복호 처리를 위한 보조 암호키로 사용할 수 있도록 이니셜벡터 처리 + */ + byte[] iv = new byte[16]; + System.arraycopy(bm, 4048 - 16, iv, 0, 16); + inisafeSession.setIV(iv); + + /** + * 메시지 복호화 + */ + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | Before decrypt" + CommonLib.hexDump(bm, true, context)); + buffer.put(inisafeSession.i_decrypt(bm)); + buffer.position(0); + + message = new ByteMessage(buffer); + logger.debug(context.getAdapterName() + " | InisafePayloadServerFilter | After decrypt" + message.hexDump()); + + } + + nextFilter.messageReceived(session, message); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + + adapter.getSessionPool().remove(session); + session.close(); + + throw new Exception(context.getAdapterName() + " | initech error - " + e.getMessage(), e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/LawClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/LawClient.java new file mode 100644 index 0000000..3964513 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/LawClient.java @@ -0,0 +1,15 @@ +package com.eactive.eai.adapter.socket2.protocol.law; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.law.codec.LawSendCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class LawClient extends TcpAdapterClient { + public LawClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new LawHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new LawSendCodecFactory(this))); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/LawHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/LawHandler.java new file mode 100644 index 0000000..5bcfac4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/LawHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.law; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class LawHandler extends ProtocolHandler { + public LawHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/LawServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/LawServer.java new file mode 100644 index 0000000..9f580bd --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/LawServer.java @@ -0,0 +1,16 @@ +package com.eactive.eai.adapter.socket2.protocol.law; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.law.codec.LawRecvCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class LawServer extends TcpAdapterServer { + public LawServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new LawHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new LawRecvCodecFactory(this))); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawConstants.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawConstants.java new file mode 100644 index 0000000..31a6a02 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawConstants.java @@ -0,0 +1,14 @@ +package com.eactive.eai.adapter.socket2.protocol.law.codec; + +public class LawConstants { + public static final byte EOF = (byte)0x1F;//^_ + public static final byte EOG = (byte)0x1D;//^] + public static final byte EOD = (byte)0x1C;//^\ + public static final int LL_FIELD_OFFSET_LENGTH = 1; + public static final int LL_FIELD_LENGTH = 10; + public static final int COMMON_LENGTH = 30; + + private LawConstants() { + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawRecvCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawRecvCodecFactory.java new file mode 100644 index 0000000..729c9cf --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawRecvCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.law.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class LawRecvCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public LawRecvCodecFactory(ISocketAdapter adapter) { + encoder = new LawRecvEncoder(adapter); + decoder = new LawRecvDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawRecvDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawRecvDecoder.java new file mode 100644 index 0000000..04c1e0d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawRecvDecoder.java @@ -0,0 +1,146 @@ +package com.eactive.eai.adapter.socket2.protocol.law.codec; + +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; + +public class LawRecvDecoder extends ProtocolDecoderAdapter { + protected final Logger logger; + protected final Logger errLogger; + + public static final int MAX_PAYLOAD_SIZE = 25 * 1024 * 1024; // 25MB + + private static final String DECODER_STATE_KEY = LawRecvDecoder.class.getName() + ".STATE"; + + private enum State { + STATE_HEADER_READ, STATE_PAYLOAD_READ; + } + + private static class CodecState { + State state = State.STATE_HEADER_READ; + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public LawRecvDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @SuppressWarnings("static-access") + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(LawConstants.COMMON_LENGTH); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + StringBuilder sb = new StringBuilder(); + sb.append("LawRecvDecoder"); + if (codecState.state == State.STATE_PAYLOAD_READ) { + sb.append("(" + codecState.payloadSize + ")"); + } + sb.append(" | decode : " + CommonLib.hexDump(in, context)); + logger.debug(sb.toString()); + adapter.addRecentRecvTrace(session, sb.toString()); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + /** + * payload size < 0 인 경우 + */ + if (codecState.payloadSize < 0) { + throw new EAIException("RECEAINNA008", context.getAdapterName() + + " (" + context.getLlFieldType() + "," + context.getLlFieldOffset() + "," + context.getLlFieldLength() + + ") | when read header, ll length field is invalid | " + CommonLib.hexDump(codecState.buffer, context)); + } + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(LawConstants.COMMON_LENGTH); + + //by short11 + //polling.role 이 Server 가 sender일 경우 오류가 있었음 + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.payloadSize = 0; + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + while(in.hasRemaining()){ + byte b = in.get(); + if (b == LawConstants.EOD){ + codecState.buffer.put(b); + return true; + }else{ + codecState.buffer.put(b); + } + } + return false; + + } + + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawRecvEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawRecvEncoder.java new file mode 100644 index 0000000..27ac098 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawRecvEncoder.java @@ -0,0 +1,89 @@ +package com.eactive.eai.adapter.socket2.protocol.law.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class LawRecvEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public LawRecvEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + if(true){ + ByteBuffer lBuffer = ByteBuffer.allocate(m.size() - LawConstants.LL_FIELD_LENGTH); + lBuffer.put(m.getBytes(0, LawConstants.LL_FIELD_OFFSET_LENGTH)); + lBuffer.put(m.getBytes(LawConstants.LL_FIELD_OFFSET_LENGTH + LawConstants.LL_FIELD_LENGTH)); + lBuffer.flip(); + m.setByteBuffer(lBuffer); + } + + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate( LawConstants.LL_FIELD_LENGTH+length ).limit( LawConstants.LL_FIELD_LENGTH+length ); + + length =length + LawConstants.LL_FIELD_LENGTH; + /** + * [1] before-payload + */ + buffer.put(m.getBytes( 0, LawConstants.LL_FIELD_OFFSET_LENGTH)); + /** + * [2] write header + */ + String lenStr = CommonLib.getFormatString(length, LawConstants.LL_FIELD_LENGTH); + buffer.put(lenStr.getBytes()); + + + /** + * [3] after-payload + */ + buffer.put(m.getBytes(LawConstants.LL_FIELD_OFFSET_LENGTH, m.getBytes().length - LawConstants.LL_FIELD_OFFSET_LENGTH )); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | LawRecvEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "LawRecvEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + out.flush(); + } + + public void dispose(IoSession session) throws Exception { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawSendCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawSendCodecFactory.java new file mode 100644 index 0000000..24d27f9 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawSendCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.law.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class LawSendCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public LawSendCodecFactory(ISocketAdapter adapter) { + encoder = new LawSendEncoder(adapter); + decoder = new LawRecvDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawSendDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawSendDecoder.java new file mode 100644 index 0000000..996d022 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawSendDecoder.java @@ -0,0 +1,247 @@ +package com.eactive.eai.adapter.socket2.protocol.law.codec; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +public class LawSendDecoder extends ProtocolDecoderAdapter { + protected final Logger logger; + protected final Logger errLogger; + + public static final int MAX_PAYLOAD_SIZE = 25 * 1024 * 1024; // 25MB + + private static final String DECODER_STATE_KEY = LawSendDecoder.class.getName() + ".STATE"; + + private enum State { + STATE_HEADER_READ, STATE_PAYLOAD_READ; + } + + private static class CodecState { + State state = State.STATE_HEADER_READ; + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public LawSendDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @SuppressWarnings("static-access") + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(LawConstants.LL_FIELD_OFFSET_LENGTH + LawConstants.LL_FIELD_LENGTH); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + StringBuilder sb = new StringBuilder(); + sb.append("LawSendDecoder"); + if (codecState.state == State.STATE_PAYLOAD_READ) { + sb.append("(" + codecState.payloadSize + ")"); + } + sb.append(" | decode : " + CommonLib.hexDump(in, context)); + logger.debug(sb.toString()); + adapter.addRecentRecvTrace(session, sb.toString()); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + /** + * payload size < 0 인 경우 + */ + if (codecState.payloadSize < 0) { + throw new EAIException("RECEAINNA008", context.getAdapterName() + + " (" + context.getLlFieldType() + "," + LawConstants.LL_FIELD_OFFSET_LENGTH + "," + LawConstants.LL_FIELD_LENGTH + + ") | when read header, ll length field is invalid | " + CommonLib.hexDump(codecState.buffer, context)); + /** + * payload size == 0 인 경우 + */ + } else if (codecState.payloadSize == 0) { + if (context.isSync()) { + throw new Exception(" payload size 0 (ping). 'SYNC' response type socket does not support ping(size 0) message."); + } + + //codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_INFO ) { + logger.info(context.getAdapterName() + " | payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + } + + /** + * header 값을 읽은 후 buffer의 position을 이동해 준다. + * 이 작업을 안해주면 무한루프에 빠질 수 있다. + * 예) 법원 공탁금 (_LAW_IN_SOC_AsS{...}) + */ + codecState.buffer.position(0).limit(LawConstants.LL_FIELD_OFFSET_LENGTH + LawConstants.LL_FIELD_LENGTH); + + //by short11 + //polling.role 이 Server 가 sender일 경우 오류가 있었음 + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + + break; + } + + /** + * ll.include = 'Y' - LL을 포함해서 넘긴다. + */ + try { + codecState.buffer.position(LawConstants.LL_FIELD_OFFSET_LENGTH + LawConstants.LL_FIELD_LENGTH) + .limit(codecState.payloadSize + LawConstants.LL_FIELD_LENGTH); + } catch(IllegalArgumentException e) { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); + sb.append("offset=" + LawConstants.LL_FIELD_OFFSET_LENGTH + LawConstants.LL_FIELD_LENGTH); + sb.append(", limit=" + codecState.payloadSize + LawConstants.LL_FIELD_LENGTH); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + + /** + * offset + ll 을 읽었고, 더 이상 읽을 것(payload)이 없는 경우 + * - ll.length value = ll.offset + ll.field.length + */ + if (codecState.buffer.position() == codecState.buffer.limit()) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + codecState.buffer.position(0).limit(LawConstants.LL_FIELD_OFFSET_LENGTH + LawConstants.LL_FIELD_LENGTH); + + + + //by short11 + //polling.role 이 Server 가 sender일 경우 오류가 있었음 + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + + break; + } + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(LawConstants.LL_FIELD_OFFSET_LENGTH + LawConstants.LL_FIELD_LENGTH); + + //by short11 + //polling.role 이 Server 가 sender일 경우 오류가 있었음 + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + codecState.payloadSize = 0; + + byte[] header = new byte[LawConstants.LL_FIELD_LENGTH]; + for (int i=0; i MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + MAX_PAYLOAD_SIZE + ") exceeded : " + + codecState.payloadSize + " | " + + CommonLib.hexDump(codecState.buffer, context)); + } + /** + * ll.field.include = 'Y' - 헤더 길이를 빼 준다. + */ + if (true) { + codecState.payloadSize = codecState.payloadSize - LawConstants.LL_FIELD_LENGTH; + } + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } + + private int getInt(byte[] header) throws Exception{ + String h = new String(header); + String len = h.replaceAll(" ", ""); + return Integer.parseInt(len); + } + + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawSendEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawSendEncoder.java new file mode 100644 index 0000000..d92f117 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/law/codec/LawSendEncoder.java @@ -0,0 +1,69 @@ +package com.eactive.eai.adapter.socket2.protocol.law.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class LawSendEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public LawSendEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate( length ).limit( length ); + + /** + * [1] payload + */ + buffer.put(m.getBytes()); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | LawSendEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "LawSendEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + out.flush(); + } + + public void dispose(IoSession session) throws Exception { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/BindClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/BindClient.java new file mode 100644 index 0000000..e2cc88a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/BindClient.java @@ -0,0 +1,20 @@ +package com.eactive.eai.adapter.socket2.protocol.login; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.login.codec.BindCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.login.handshake.BindClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class BindClient extends TcpAdapterClient { + boolean isForceStop = true; + + public BindClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new BindHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new BindCodecFactory(this))); + config.getFilterChain().addAfter("codec", "bind.codec", new BindClientFilter(this)); + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/BindHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/BindHandler.java new file mode 100644 index 0000000..26e6235 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/BindHandler.java @@ -0,0 +1,30 @@ +package com.eactive.eai.adapter.socket2.protocol.login; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import org.apache.mina.common.IoSession; + + +public class BindHandler extends ProtocolHandler { + public BindHandler(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(IoSession session) throws Exception { + super.sessionOpened(session); + + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + if(adapters == null) return; + for (int i=0; i= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | lazy client protocol - skip start process when booting ..."); + } + isBooting = false; + + SimpleFuture future = new SimpleFuture(); + future.set(Boolean.FALSE); + return future; + } else { + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_INFO) { + logger.info(context.getAdapterName() + " | client protocol - start process when booting ..."); + } + return super.start(); + } + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/LazyHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/LazyHandler.java new file mode 100644 index 0000000..63de65b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/LazyHandler.java @@ -0,0 +1,32 @@ +package com.eactive.eai.adapter.socket2.protocol.login; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import org.apache.mina.common.IoSession; + + +public class LazyHandler extends ProtocolHandler { + public LazyHandler(ISocketAdapter adapter) { + super(adapter); + } + @Override + public void sessionClosed(IoSession session) throws Exception { + super.sessionClosed(session); + } + + @Override + public void sessionOpened(IoSession session) throws Exception { + + super.sessionOpened(session); + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + if(adapters == null) return; + for (int i=0; i= context.TRACE_LEVEL_TRACE ) { + StringBuilder sb = new StringBuilder(); + sb.append("FixedHeaderDecoder"); + //sb.append(codecState.state); + if (codecState.state == State.STATE_PAYLOAD_READ) { + sb.append("(" + codecState.payloadSize + ")"); + } + sb.append(" | decode : " + CommonLib.hexDump(in, context)); + logger.debug(sb.toString()); + adapter.addRecentRecvTrace(session, sb.toString()); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + /** + * payload size < 0 인 경우 + */ + if (codecState.payloadSize < 0) { + throw new EAIException("RECEAINNA008", context.getAdapterName() + + " (" + context.getLlFieldType() + "," + context.getLlFieldOffset() + "," + context.getLlFieldLength() + + ") | when read header, ll length field is invalid | " + CommonLib.hexDump(codecState.buffer, context)); + /** + * payload size == 0 인 경우 + */ + } else if (codecState.payloadSize == 0) { + if (context.isSync()) { + throw new Exception(" payload size 0 (ping). 'SYNC' response type socket does not support ping(size 0) message."); + } + + //codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_INFO ) { + logger.info(context.getAdapterName() + " | payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + } + + /** + * header 값을 읽은 후 buffer의 position을 이동해 준다. + * 이 작업을 안해주면 무한루프에 빠질 수 있다. + * 예) 법원 공탁금 (_LAW_IN_SOC_AsS{...}) + */ + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + + //by short11 + //polling.role 이 Server 가 sender일 경우 오류가 있었음 + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } +// if (context.isClient() && context.isPermanent() && context.isPollingUse()) { +// session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); +// } else { +// session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); +// } + + break; + } + + /** + * ll.include = 'Y' - LL을 포함해서 넘긴다. + */ + if ("Y".equals(context.getLlInclude())) { + try { + codecState.buffer.position(context.getLlFieldOffset() + context.getLlFieldLength()) + .limit(codecState.payloadSize + context.getLlFieldLength()); + } catch(IllegalArgumentException e) { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); + sb.append("offset=" + context.getLlFieldOffset() + context.getLlFieldLength()); + sb.append(", limit=" + codecState.payloadSize + context.getLlFieldLength()); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA007"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + /** + * ll.include = 'N' - LL을 제외하고 넘긴다. + */ + } else { + try { + codecState.buffer.position(context.getLlFieldOffset()).limit(codecState.payloadSize); + } catch(IllegalArgumentException e) { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); + sb.append("offset=" + context.getLlFieldOffset()); + sb.append(", limit=" + codecState.payloadSize); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + } + + /** + * offset + ll 을 읽었고, 더 이상 읽을 것(payload)이 없는 경우 + * - ll.length value = ll.offset + ll.field.length + */ + if (codecState.buffer.position() == codecState.buffer.limit()) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + + + + //by short11 + //polling.role 이 Server 가 sender일 경우 오류가 있었음 + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + +// if (context.isClient() && context.isPermanent() && context.isPollingUse()) { +// session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); +// } else { +// session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); +// } + + break; + } + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + + //by short11 + //polling.role 이 Server 가 sender일 경우 오류가 있었음 + if (context.isPollingUse() && context.isPollingSender() && context.isPermanent()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + }else{ + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + +// if (context.isClient() && context.isPermanent() && context.isPollingUse()) { +// session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); +// } else { +// session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); +// } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read header : " + in); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + if ("BIN".equals(context.getLlFieldType())) { + codecState.payloadSize = 0; + for (int i=0; i MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + MAX_PAYLOAD_SIZE + ") exceeded : " + + codecState.payloadSize + " | " + + CommonLib.hexDump(codecState.buffer, context)); + } + + /** + * ll.field.include = 'Y' - 헤더 길이를 빼 준다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + codecState.payloadSize = codecState.payloadSize - context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 더해서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + codecState.payloadSize = codecState.payloadSize + context.getLlFieldOffset(); + } + //길이 계산 로직에 추가하면 됨 + if (context.getLlFieldLengthAlpha() != 0 ){ + codecState.payloadSize = codecState.payloadSize - context.getLlFieldLengthAlpha(); + } + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read payload : " + in); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } + + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/codec/BindEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/codec/BindEncoder.java new file mode 100644 index 0000000..0022193 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/codec/BindEncoder.java @@ -0,0 +1,121 @@ +package com.eactive.eai.adapter.socket2.protocol.login.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class BindEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public BindEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + /** + * ll.include = 'Y' - 통째로 보낸다. + */ + if ("Y".equals(context.getLlInclude())) { + ByteBuffer buffer = ByteBuffer.allocate(m.size() - context.getLlFieldLength()); + buffer.put(m.getBytes(0, context.getLlFieldOffset())); + buffer.put(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + buffer.flip(); + m.setByteBuffer(buffer); + } + + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate(context.getLlFieldLength() + length).limit(context.getLlFieldLength() + length); + + /** + * ll.field.include = 'Y' - header 길이 포함하여 ll 을 계산한다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + length = length + context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 빼서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + length = length - context.getLlFieldOffset(); + } + //길이 계산 로직에 추가하면 됨 + if (context.getLlFieldLengthAlpha() != 0 ){ + length = length + context.getLlFieldLengthAlpha(); + } + + /////////////////////////////////////// + + /** + * [1] before-payload + */ + buffer.put(m.getBytes(0, context.getLlFieldOffset())); + + /** + * [2] write header + */ + if ("BIN".equals(context.getLlFieldType())) { + int tmpLength = length; + byte[] header = new byte[context.getLlFieldLength()]; + for (int i = context.getLlFieldLength()-1; i>=0; i--) { + header[i] = (byte) (tmpLength % 256); + tmpLength = tmpLength / 256; + } + buffer.put(header); + } else { // "CHAR" + String lenStr = CommonLib.getFormatString(length, context.getLlFieldLength()); + buffer.put(lenStr.getBytes()); + } + + /** + * [3] after-payload + */ + buffer.put(m.getBytes(context.getLlFieldOffset(), m.getBytes().length - context.getLlFieldOffset())); + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | BindEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "BindEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + out.flush(); + } + + public void dispose(IoSession session) throws Exception { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/BindClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/BindClientFilter.java new file mode 100644 index 0000000..1955954 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/BindClientFilter.java @@ -0,0 +1,181 @@ +package com.eactive.eai.adapter.socket2.protocol.login.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + + +public class BindClientFilter extends BindFilter { + public BindClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + process(nextFilter, session, null); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + /** + * State machine + */ +// ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_BIND_SEND: + + +// session.getRemoteAddress() + + /** + * change state to SEND + */ + filterState.state = State.STATE_BIND_SEND; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + + /** + * create send data + */ + + ByteMessage data = new ByteMessage(); + String line = context.getLoginSend(); + while(line.indexOf("0x") != -1) { + data.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + data.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + data.append(line); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | LoginClientFilter | LOGIN_SEND" + CommonLib.hexDump(data.getBytes(), true, context)); + } + session.write(data.getBytes()); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_BIND_RECV; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_BIND_RECV: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | LoginClientFilter | LOGIN_RECV response"); + } + + if(message == null) { + throw new Exception("LOGIN_RECV message is null"); + } + /** + * get ip port + */ + int offset = 12; + byte[] firstIp = message.getBytes(offset, 16); offset = offset + 16; + byte[] firstTPort = message.getBytes(offset, 4); offset = offset + 4; + byte[] firstRPort = message.getBytes(offset, 4); offset = offset + 4; + byte[] secondIp = message.getBytes(offset, 16); offset = offset + 16; + byte[] secondTPort = message.getBytes(offset, 4); offset = offset + 4; + byte[] secondRPort = message.getBytes(offset, 4); +// byte[] result = message.getBytes(offset, 4);offset = offset + 4; + + + String[] sIp = {new String(firstIp),new String(secondIp)}; + int[] iTport = {0,0}; + int[] iRport = {0,0}; + for (int i=0; i<4; i++) { + iTport[0] += ((int) firstTPort[i] & 0xFF) * Math.pow(256, 4-i-1); + iRport[0] += ((int) firstRPort[i] & 0xFF) * Math.pow(256, 4-i-1); + iTport[1] += ((int) secondTPort[i] & 0xFF) * Math.pow(256, 4-i-1); + iRport[1] += ((int) secondRPort[i] & 0xFF) * Math.pow(256, 4-i-1); + } + logger.debug("firstIp = "+sIp[0]); + logger.debug("tport = "+iTport[0]); + logger.debug("rport = "+iRport[0]); + logger.debug("secondIp = "+sIp[1]); + logger.debug("tport = "+iTport[1]); + logger.debug("rport = "+iRport[1]); + + + /** + * change state + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * finish handshake + */ + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog(context.getAdapterName() + " | LoginClientFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | LoginClientFilter | handshake finished ..."); + } + /** + * start lazy pair socket adapter (in same socket adapter group) + */ + int index = 0; + ISocketAdapter[] adapters = SocketAdapterManager.getInstance().getSocketAdapters(adapter.getContext().getAdapterGroupName()); + if(adapters == null) return; + for (int i=0; i invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | login error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | login error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | login error - " + e.getMessage(), e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new Exception(context.getAdapterName() + " | login error - " + e.getMessage(), e); + } + } + + + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/BindFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/BindFilter.java new file mode 100644 index 0000000..b4df85c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/BindFilter.java @@ -0,0 +1,123 @@ +package com.eactive.eai.adapter.socket2.protocol.login.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + + +abstract public class BindFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + +// private static final String NEXT_FILTER = BindFilter.class.getName() + ".NextFilter"; + public static final String FILTER_STATE_KEY = BindFilter.class.getName() + ".STATE"; + + public static final String SESSION_STATE = "SESSION_STATE"; + + public enum State { + STATE_START, + STATE_BIND_SEND, + STATE_BIND_RECV, + STATE_MESSAGE; + } + + public static class FilterState { + public State state = null; + public byte[] key; // token? + + public FilterState() {} + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected byte[] cert; + protected byte[] key; + protected String password; + protected byte[] remoteCert; + + protected BindFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + synchronized(session) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_BIND_SEND; + session.setAttribute(FILTER_STATE_KEY, filterState); + } + nextFilter.sessionCreated(session); + } + + // handshake future +// session.setAttribute(ProtocolHandler.HANDSHAKE_FUTURE, new SimpleFuture()); + } + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { + nextFilter.sessionClosed(session); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteBuffer) { + m = new ByteMessage((ByteBuffer) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + switch (filterState.state) { + case STATE_MESSAGE: +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + break; + + default: + break; + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | bind error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | bind error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | bind error - " + e.getMessage(), e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new Exception(context.getAdapterName() + " | bind error - " + e.getMessage()); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } + + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/LoginClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/LoginClientFilter.java new file mode 100644 index 0000000..a76c939 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/LoginClientFilter.java @@ -0,0 +1,141 @@ +package com.eactive.eai.adapter.socket2.protocol.login.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + + +public class LoginClientFilter extends LoginFilter { + public LoginClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + process(nextFilter, session, null); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + process(nextFilter, session, m); + } + + protected void process(NextFilter nextFilter, IoSession session, ByteMessage message) throws Exception { + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + /** + * State machine + */ +// ByteBuffer buffer = null; + + switch (filterState.state) { + case STATE_LOGIN_SEND: + + +// session.getRemoteAddress() + + /** + * change state to SEND + */ + filterState.state = State.STATE_LOGIN_SEND; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + + /** + * create send data + */ + ByteMessage data = getHexToByte(context.getLoginSend()); + + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | LoginClientFilter | LOGIN_SEND" + CommonLib.hexDump(data.getBytes(), true, context)); + } + session.write(data.getBytes()); + + /** + * change state to UPDATE + */ + filterState.state = State.STATE_LOGIN_RECV; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_LOGIN_RECV: + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | LoginClientFilter | LOGIN_RECV response"); + } + /** + * recv data comp + */ + byte[] recv = null; + + if(message == null) { + session.close(); + throw new Exception(" invalid message during handshake .. : " + message); + } + else { + recv = message.getBytes(); + } + + + ByteMessage loginRecv = getHexToByte(context.getLoginRecv()); + + if (!new String(recv).startsWith(loginRecv.getString()) ){ + session.close(); + throw new Exception(" invalid message during handshake .. : " + message); + } + + /** + * change state + */ + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + /** + * finish handshake + */ + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + adapter.addRecentLog(context.getAdapterName() + " | LoginClientFilter | handshake finished ..."); + logger.debug(context.getAdapterName() + " | LoginClientFilter | handshake finished ..."); + } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + + break; + + case STATE_MESSAGE: + nextFilter.messageReceived(session, message); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + message); + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | login error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | login error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | login error - " + e.getMessage(), e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new Exception(context.getAdapterName() + " | login error - " + e.getMessage(), e); + } + } + + private ByteMessage getHexToByte(String line){ + ByteMessage data = new ByteMessage(); + while(line.indexOf("0x") != -1) { + data.append(line.substring(0, line.indexOf("0x"))); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x")+4); + data.append((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x")+4); + } + data.append(line); + return data; + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/LoginFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/LoginFilter.java new file mode 100644 index 0000000..ec88024 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/login/handshake/LoginFilter.java @@ -0,0 +1,122 @@ +package com.eactive.eai.adapter.socket2.protocol.login.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + + +abstract public class LoginFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + +// private static final String NEXT_FILTER = LoginFilter.class.getName() + ".NextFilter"; + public static final String FILTER_STATE_KEY = LoginFilter.class.getName() + ".STATE"; + + public static final String SESSION_STATE = "SESSION_STATE"; + + public enum State { + STATE_START, + STATE_LOGIN_SEND, + STATE_LOGIN_RECV, + STATE_MESSAGE; + } + + public static class FilterState { + public State state = null; + public byte[] key; // token? + + public FilterState() {} + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected byte[] cert; + protected byte[] key; + protected String password; + protected byte[] remoteCert; + + protected LoginFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + synchronized(session) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_LOGIN_SEND; + session.setAttribute(FILTER_STATE_KEY, filterState); + } + } + + // handshake future +// session.setAttribute(ProtocolHandler.HANDSHAKE_FUTURE, new SimpleFuture()); + } + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { + nextFilter.sessionClosed(session); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteBuffer) { + m = new ByteMessage((ByteBuffer) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + switch (filterState.state) { + case STATE_MESSAGE: +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + break; + + default: + break; + } + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | sms error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | sms error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | sms error - " + e.getMessage(), e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new Exception(context.getAdapterName() + " | sms error - " + e.getMessage()); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } + + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/ObjectClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/ObjectClient.java new file mode 100644 index 0000000..54e8756 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/ObjectClient.java @@ -0,0 +1,22 @@ +package com.eactive.eai.adapter.socket2.protocol.object; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.object.codec.ObjectSerializationCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class ObjectClient extends TcpAdapterClient { + public ObjectClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new ObjectHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory(this))); + } + + @Override + public Object sendMessage(Object message) throws EAIException { + return super.sendMessage(message); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/ObjectHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/ObjectHandler.java new file mode 100644 index 0000000..8c6e50d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/ObjectHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.object; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class ObjectHandler extends ProtocolHandler { + public ObjectHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/ObjectServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/ObjectServer.java new file mode 100644 index 0000000..a795bdb --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/ObjectServer.java @@ -0,0 +1,16 @@ +package com.eactive.eai.adapter.socket2.protocol.object; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.object.codec.ObjectSerializationCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class ObjectServer extends TcpAdapterServer { + public ObjectServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new ObjectHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new ObjectSerializationCodecFactory(this))); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/codec/ObjectSerializationCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/codec/ObjectSerializationCodecFactory.java new file mode 100644 index 0000000..234d424 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/codec/ObjectSerializationCodecFactory.java @@ -0,0 +1,86 @@ +package com.eactive.eai.adapter.socket2.protocol.object.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.BufferDataException; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + + +public class ObjectSerializationCodecFactory implements ProtocolCodecFactory { + private final ObjectSerializationEncoder encoder; + + private final ObjectSerializationDecoder decoder; + + /** + * Creates a new instance with the {@link ClassLoader} of + * the current thread. + */ + public ObjectSerializationCodecFactory(ISocketAdapter adapter) { + this(Thread.currentThread().getContextClassLoader()); + } + + /** + * Creates a new instance with the specified {@link ClassLoader}. + */ + public ObjectSerializationCodecFactory(ClassLoader classLoader) { + encoder = new ObjectSerializationEncoder(); + decoder = new ObjectSerializationDecoder(classLoader); + } + + public ProtocolEncoder getEncoder() { + return encoder; + } + + public ProtocolDecoder getDecoder() { + return decoder; + } + + /** + * Returns the allowed maximum size of the encoded object. + * If the size of the encoded object exceeds this value, the encoder + * will throw a {@link IllegalArgumentException}. The default value + * is {@link Integer#MAX_VALUE}. + *

+ * This method does the same job with {@link ObjectSerializationEncoder#getMaxObjectSize()}. + */ + public int getEncoderMaxObjectSize() { + return encoder.getMaxObjectSize(); + } + + /** + * Sets the allowed maximum size of the encoded object. + * If the size of the encoded object exceeds this value, the encoder + * will throw a {@link IllegalArgumentException}. The default value + * is {@link Integer#MAX_VALUE}. + *

+ * This method does the same job with {@link ObjectSerializationEncoder#setMaxObjectSize(int)}. + */ + public void setEncoderMaxObjectSize(int maxObjectSize) { + encoder.setMaxObjectSize(maxObjectSize); + } + + /** + * Returns the allowed maximum size of the object to be decoded. + * If the size of the object to be decoded exceeds this value, the + * decoder will throw a {@link BufferDataException}. The default + * value is 1048576 (1MB). + *

+ * This method does the same job with {@link ObjectSerializationDecoder#getMaxObjectSize()}. + */ + public int getDecoderMaxObjectSize() { + return decoder.getMaxObjectSize(); + } + + /** + * Sets the allowed maximum size of the object to be decoded. + * If the size of the object to be decoded exceeds this value, the + * decoder will throw a {@link BufferDataException}. The default + * value is 1048576 (1MB). + *

+ * This method does the same job with {@link ObjectSerializationDecoder#setMaxObjectSize(int)}. + */ + public void setDecoderMaxObjectSize(int maxObjectSize) { + decoder.setMaxObjectSize(maxObjectSize); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/codec/ObjectSerializationDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/codec/ObjectSerializationDecoder.java new file mode 100644 index 0000000..6bab305 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/codec/ObjectSerializationDecoder.java @@ -0,0 +1,63 @@ +package com.eactive.eai.adapter.socket2.protocol.object.codec; + +import org.apache.mina.common.BufferDataException; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.CumulativeProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +public class ObjectSerializationDecoder extends CumulativeProtocolDecoder { + private final ClassLoader classLoader; + + private int maxObjectSize = 1048576; // 1MB + + /** + * Creates a new instance with the {@link ClassLoader} of the current + * thread. + */ + public ObjectSerializationDecoder() { + this(Thread.currentThread().getContextClassLoader()); + } + + /** + * Creates a new instance with the specified {@link ClassLoader}. + */ + public ObjectSerializationDecoder(ClassLoader classLoader) { + if (classLoader == null) { + throw new NullPointerException("classLoader"); + } + this.classLoader = classLoader; + } + + /** + * Returns the allowed maximum size of the object to be decoded. If the size + * of the object to be decoded exceeds this value, this decoder will throw a + * {@link BufferDataException}. The default value is 1048576 (1MB). + */ + public int getMaxObjectSize() { + return maxObjectSize; + } + + /** + * Sets the allowed maximum size of the object to be decoded. If the size of + * the object to be decoded exceeds this value, this decoder will throw a + * {@link BufferDataException}. The default value is 1048576 (1MB). + */ + public void setMaxObjectSize(int maxObjectSize) { + if (maxObjectSize <= 0) { + throw new IllegalArgumentException("maxObjectSize: " + maxObjectSize); + } + + this.maxObjectSize = maxObjectSize; + } + + protected boolean doDecode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) + throws Exception { + if (!in.prefixedDataAvailable(4, maxObjectSize)) { + return false; + } + + out.write(in.getObject(classLoader)); + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/codec/ObjectSerializationEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/codec/ObjectSerializationEncoder.java new file mode 100644 index 0000000..3fae22a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/object/codec/ObjectSerializationEncoder.java @@ -0,0 +1,65 @@ +package com.eactive.eai.adapter.socket2.protocol.object.codec; + +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoderAdapter; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +import java.io.NotSerializableException; +import java.io.Serializable; + +public class ObjectSerializationEncoder extends ProtocolEncoderAdapter { + private int maxObjectSize = Integer.MAX_VALUE; // 2GB + + /** + * Creates a new instance. + */ + public ObjectSerializationEncoder() { + // empty + } + + /** + * Returns the allowed maximum size of the encoded object. If the size of + * the encoded object exceeds this value, this encoder will throw a + * {@link IllegalArgumentException}. The default value is + * {@link Integer#MAX_VALUE}. + */ + public int getMaxObjectSize() { + return maxObjectSize; + } + + /** + * Sets the allowed maximum size of the encoded object. If the size of the + * encoded object exceeds this value, this encoder will throw a + * {@link IllegalArgumentException}. The default value is + * {@link Integer#MAX_VALUE}. + */ + public void setMaxObjectSize(int maxObjectSize) { + if (maxObjectSize <= 0) { + throw new IllegalArgumentException("maxObjectSize: " + maxObjectSize); + } + + this.maxObjectSize = maxObjectSize; + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) + throws Exception { + if (!(message instanceof Serializable)) { + throw new NotSerializableException(); + } + + ByteBuffer buf = ByteBuffer.allocate(64); + buf.setAutoExpand(true); + buf.putObject(message); + + int objectSize = buf.position() - 4; + if (objectSize > maxObjectSize) { + buf.release(); + throw new IllegalArgumentException("The encoded object is too big: " + objectSize + + " (> " + maxObjectSize + ')'); + } + + buf.flip(); + out.write(buf); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/proxy/AbstractProxyHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/proxy/AbstractProxyHandler.java new file mode 100644 index 0000000..5c4ba26 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/proxy/AbstractProxyHandler.java @@ -0,0 +1,73 @@ +package com.eactive.eai.adapter.socket2.protocol.proxy; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import org.apache.mina.common.IoSession; +import org.apache.mina.common.TrafficMask; + +import java.net.InetSocketAddress; +import java.net.SocketAddress; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public abstract class AbstractProxyHandler extends ProtocolHandler { +// private static Charset CHARSET = Charset.forName("iso8859-1"); + private final Set l4SkipIpList = new HashSet<>(); + private final Set blockIpList = new HashSet<>(); + + protected AbstractProxyHandler(ISocketAdapter adapter) { + super(adapter); + + String[] l4SkipList = context.getL4SkipIpList().split(","); + for (int i=0; i list) { + SocketAddress remoteAddress = session.getRemoteAddress(); + + if (remoteAddress instanceof InetSocketAddress) { + for (String allow : list) { + byte[] remoteAddr = ((InetSocketAddress) remoteAddress).getAddress().getAddress(); + String remoteIp = ""; + for (int i=0; i 0) { + remoteIp += "."; + } + remoteIp += remoteAddr[i]&0xFF; + } + + if (allow.indexOf('*') == -1) { + if (allow.equals(remoteIp)) { + return true; + } + } else { + String allowRegexp = allow.replaceAll("\\*", "[0-9]+"); + Matcher matcher = Pattern.compile(allowRegexp, Pattern.CASE_INSENSITIVE).matcher(remoteIp); + if (matcher.matches()) { + return true; + } + } + } + } + + return false; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/proxy/ClientToProxyHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/proxy/ClientToProxyHandler.java new file mode 100644 index 0000000..b4f655c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/proxy/ClientToProxyHandler.java @@ -0,0 +1,104 @@ +package com.eactive.eai.adapter.socket2.protocol.proxy; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.SessionPool; +import org.apache.mina.common.*; +import org.apache.mina.transport.socket.nio.SocketConnector; + +import java.net.InetSocketAddress; + + +public class ClientToProxyHandler extends AbstractProxyHandler { + private final ServerToProxyHandler connectorHandler; + private final IoConnector connector; + private final InetSocketAddress[] addresses; + + public ClientToProxyHandler(ISocketAdapter adapter) { + super(adapter); + + + this.connectorHandler = new ServerToProxyHandler(adapter); + this.connector = new SocketConnector(); + // Set connect timeout. + ((IoConnectorConfig) connector.getDefaultConfig()).setConnectTimeout(30); + ((IoConnectorConfig) connector.getDefaultConfig()).setThreadModel(ThreadModel.MANUAL); // 2014.07.07 + + String[] hosts = context.getLocalHostName().split(";"); + this.addresses = new InetSocketAddress[hosts.length]; + for (int i=0; i hash = new Hashtable(); + + static { + hash.put("-1910", "ERR_POLICY_RESERVED_CN | 이미 등록되어 있은 CN 입니다."); + } + + static public String getErrorMessage(String key) { + String value = hash.get(key); + if (value == null) { + return "Unknown Error."; + } + return value; + } + + static public String getErrorMessage(int key) { + return getErrorMessage(String.valueOf(key)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/SeedHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/SeedHandler.java new file mode 100644 index 0000000..66b52a4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/SeedHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.seed; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class SeedHandler extends ProtocolHandler { + public SeedHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/SeedServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/SeedServer.java new file mode 100644 index 0000000..b8e47af --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/SeedServer.java @@ -0,0 +1,19 @@ +package com.eactive.eai.adapter.socket2.protocol.seed; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.seed.handshake.SeedServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class SeedServer extends TcpAdapterServer { + public SeedServer(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new SeedHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "seed", new SeedServerFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedClientFilter.java new file mode 100644 index 0000000..7af3aa9 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedClientFilter.java @@ -0,0 +1,60 @@ +package com.eactive.eai.adapter.socket2.protocol.seed.handshake; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + + +public class SeedClientFilter extends SeedFilter { + public SeedClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + +// @Override +// public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { +// process(nextFilter, session, null); +// } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + process(nextFilter, session, message); + } + + + private void process(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { +// case STATE_HANDSHAKE: +// /** +// * create user key & round key +// */ +// filterState.userKey = m.getBytes(); +// //SeedCodec.SeedEncRoundKey(filterState.roundKey, filterState.userKey); +// +// /** +// * change state +// */ +// filterState.state = State.STATE_MESSAGE; +// setSessionState(session, filterState.state.toString()); +// nextFilter.sessionOpened(session); +// break; + + case STATE_MESSAGE: + byte[] decrypted = SeedCodec.decrypt(m.getBytes()); + m.setBytes(decrypted); + +// if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { +// logger.debug(context.getAdapterName() + " | SeedClientFilter | after decrypt : " + m.hexDump()); +// } + + nextFilter.messageReceived(session, m); + break; + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedCodec.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedCodec.java new file mode 100644 index 0000000..a28dddd --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedCodec.java @@ -0,0 +1,533 @@ +package com.eactive.eai.adapter.socket2.protocol.seed.handshake; + +/******************************************************************************* + * Made : 2006. 7.18. Update : 2006.11.24 FILE : seedx_test.java + * + * DESCRIPTION: Core routines for the enhanced SEED + * + *******************************************************************************/ + +public class SeedCodec { + private static int SS0[] = { + 0x2989a1a8, 0x05858184, 0x16c6d2d4, 0x13c3d3d0, 0x14445054, 0x1d0d111c, 0x2c8ca0ac, 0x25052124, + 0x1d4d515c, 0x03434340, 0x18081018, 0x1e0e121c, 0x11415150, 0x3cccf0fc, 0x0acac2c8, 0x23436360, + 0x28082028, 0x04444044, 0x20002020, 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, 0x08c8c0c8, 0x17071314, + 0x2585a1a4, 0x0f8f838c, 0x03030300, 0x3b4b7378, 0x3b8bb3b8, 0x13031310, 0x12c2d2d0, 0x2ecee2ec, + 0x30407070, 0x0c8c808c, 0x3f0f333c, 0x2888a0a8, 0x32023230, 0x1dcdd1dc, 0x36c6f2f4, 0x34447074, + 0x2ccce0ec, 0x15859194, 0x0b0b0308, 0x17475354, 0x1c4c505c, 0x1b4b5358, 0x3d8db1bc, 0x01010100, + 0x24042024, 0x1c0c101c, 0x33437370, 0x18889098, 0x10001010, 0x0cccc0cc, 0x32c2f2f0, 0x19c9d1d8, + 0x2c0c202c, 0x27c7e3e4, 0x32427270, 0x03838380, 0x1b8b9398, 0x11c1d1d0, 0x06868284, 0x09c9c1c8, + 0x20406060, 0x10405050, 0x2383a3a0, 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, 0x1e8e929c, 0x0f4f434c, + 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, 0x38487078, 0x2686a2a4, 0x12021210, 0x2f8fa3ac, 0x15c5d1d4, + 0x21416160, 0x03c3c3c0, 0x3484b0b4, 0x01414140, 0x12425250, 0x3d4d717c, 0x0d8d818c, 0x08080008, + 0x1f0f131c, 0x19899198, 0x00000000, 0x19091118, 0x04040004, 0x13435350, 0x37c7f3f4, 0x21c1e1e0, + 0x3dcdf1fc, 0x36467274, 0x2f0f232c, 0x27072324, 0x3080b0b0, 0x0b8b8388, 0x0e0e020c, 0x2b8ba3a8, + 0x2282a2a0, 0x2e4e626c, 0x13839390, 0x0d4d414c, 0x29496168, 0x3c4c707c, 0x09090108, 0x0a0a0208, + 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, 0x05c5c1c4, 0x07878384, 0x14041014, 0x3ecef2fc, 0x24446064, + 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, 0x1a0a1218, 0x06060204, 0x21012120, 0x2b4b6368, 0x26466264, + 0x02020200, 0x35c5f1f4, 0x12829290, 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, 0x3e4e727c, 0x10c0d0d0, + 0x3a4a7278, 0x07474344, 0x16869294, 0x25c5e1e4, 0x26062224, 0x00808080, 0x2d8da1ac, 0x1fcfd3dc, + 0x2181a1a0, 0x30003030, 0x37073334, 0x2e8ea2ac, 0x36063234, 0x15051114, 0x22022220, 0x38083038, + 0x34c4f0f4, 0x2787a3a4, 0x05454144, 0x0c4c404c, 0x01818180, 0x29c9e1e8, 0x04848084, 0x17879394, + 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, 0x3c0c303c, 0x31417170, 0x11011110, 0x07c7c3c4, 0x09898188, + 0x35457174, 0x3bcbf3f8, 0x1acad2d8, 0x38c8f0f8, 0x14849094, 0x19495158, 0x02828280, 0x04c4c0c4, + 0x3fcff3fc, 0x09494148, 0x39093138, 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, 0x17c7d3d4, 0x3888b0b8, + 0x0f0f030c, 0x0e8e828c, 0x02424240, 0x23032320, 0x11819190, 0x2c4c606c, 0x1bcbd3d8, 0x2484a0a4, + 0x34043034, 0x31c1f1f0, 0x08484048, 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, 0x2d0d212c, 0x00404040, + 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, 0x0e4e424c, 0x15455154, + 0x3b0b3338, 0x1cccd0dc, 0x28486068, 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, 0x0a4a4248, 0x16465254, + 0x37477374, 0x2080a0a0, 0x2dcde1ec, 0x06464244, 0x3585b1b4, 0x2b0b2328, 0x25456164, 0x3acaf2f8, + 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, 0x26c6e2e4, 0x3282b2b0, + 0x31013130, 0x2acae2e8, 0x2d4d616c, 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, 0x0dcdc1cc, 0x08888088, + 0x16061214, 0x3a0a3238, 0x18485058, 0x14c4d0d4, 0x22426260, 0x29092128, 0x07070304, 0x33033330, + 0x28c8e0e8, 0x1b0b1318, 0x05050104, 0x39497178, 0x10809090, 0x2a4a6268, 0x2a0a2228, 0x1a8a9298 + }; + + private static int SS1[] = { + 0x38380830, 0xe828c8e0, 0x2c2d0d21, 0xa42686a2, 0xcc0fcfc3, 0xdc1eced2, 0xb03383b3, 0xb83888b0, + 0xac2f8fa3, 0x60204060, 0x54154551, 0xc407c7c3, 0x44044440, 0x6c2f4f63, 0x682b4b63, 0x581b4b53, + 0xc003c3c3, 0x60224262, 0x30330333, 0xb43585b1, 0x28290921, 0xa02080a0, 0xe022c2e2, 0xa42787a3, + 0xd013c3d3, 0x90118191, 0x10110111, 0x04060602, 0x1c1c0c10, 0xbc3c8cb0, 0x34360632, 0x480b4b43, + 0xec2fcfe3, 0x88088880, 0x6c2c4c60, 0xa82888a0, 0x14170713, 0xc404c4c0, 0x14160612, 0xf434c4f0, + 0xc002c2c2, 0x44054541, 0xe021c1e1, 0xd416c6d2, 0x3c3f0f33, 0x3c3d0d31, 0x8c0e8e82, 0x98188890, + 0x28280820, 0x4c0e4e42, 0xf436c6f2, 0x3c3e0e32, 0xa42585a1, 0xf839c9f1, 0x0c0d0d01, 0xdc1fcfd3, + 0xd818c8d0, 0x282b0b23, 0x64264662, 0x783a4a72, 0x24270723, 0x2c2f0f23, 0xf031c1f1, 0x70324272, + 0x40024242, 0xd414c4d0, 0x40014141, 0xc000c0c0, 0x70334373, 0x64274763, 0xac2c8ca0, 0x880b8b83, + 0xf437c7f3, 0xac2d8da1, 0x80008080, 0x1c1f0f13, 0xc80acac2, 0x2c2c0c20, 0xa82a8aa2, 0x34340430, + 0xd012c2d2, 0x080b0b03, 0xec2ecee2, 0xe829c9e1, 0x5c1d4d51, 0x94148490, 0x18180810, 0xf838c8f0, + 0x54174753, 0xac2e8ea2, 0x08080800, 0xc405c5c1, 0x10130313, 0xcc0dcdc1, 0x84068682, 0xb83989b1, + 0xfc3fcff3, 0x7c3d4d71, 0xc001c1c1, 0x30310131, 0xf435c5f1, 0x880a8a82, 0x682a4a62, 0xb03181b1, + 0xd011c1d1, 0x20200020, 0xd417c7d3, 0x00020202, 0x20220222, 0x04040400, 0x68284860, 0x70314171, + 0x04070703, 0xd81bcbd3, 0x9c1d8d91, 0x98198991, 0x60214161, 0xbc3e8eb2, 0xe426c6e2, 0x58194951, + 0xdc1dcdd1, 0x50114151, 0x90108090, 0xdc1cccd0, 0x981a8a92, 0xa02383a3, 0xa82b8ba3, 0xd010c0d0, + 0x80018181, 0x0c0f0f03, 0x44074743, 0x181a0a12, 0xe023c3e3, 0xec2ccce0, 0x8c0d8d81, 0xbc3f8fb3, + 0x94168692, 0x783b4b73, 0x5c1c4c50, 0xa02282a2, 0xa02181a1, 0x60234363, 0x20230323, 0x4c0d4d41, + 0xc808c8c0, 0x9c1e8e92, 0x9c1c8c90, 0x383a0a32, 0x0c0c0c00, 0x2c2e0e22, 0xb83a8ab2, 0x6c2e4e62, + 0x9c1f8f93, 0x581a4a52, 0xf032c2f2, 0x90128292, 0xf033c3f3, 0x48094941, 0x78384870, 0xcc0cccc0, + 0x14150511, 0xf83bcbf3, 0x70304070, 0x74354571, 0x7c3f4f73, 0x34350531, 0x10100010, 0x00030303, + 0x64244460, 0x6c2d4d61, 0xc406c6c2, 0x74344470, 0xd415c5d1, 0xb43484b0, 0xe82acae2, 0x08090901, + 0x74364672, 0x18190911, 0xfc3ecef2, 0x40004040, 0x10120212, 0xe020c0e0, 0xbc3d8db1, 0x04050501, + 0xf83acaf2, 0x00010101, 0xf030c0f0, 0x282a0a22, 0x5c1e4e52, 0xa82989a1, 0x54164652, 0x40034343, + 0x84058581, 0x14140410, 0x88098981, 0x981b8b93, 0xb03080b0, 0xe425c5e1, 0x48084840, 0x78394971, + 0x94178793, 0xfc3cccf0, 0x1c1e0e12, 0x80028282, 0x20210121, 0x8c0c8c80, 0x181b0b13, 0x5c1f4f53, + 0x74374773, 0x54144450, 0xb03282b2, 0x1c1d0d11, 0x24250521, 0x4c0f4f43, 0x00000000, 0x44064642, + 0xec2dcde1, 0x58184850, 0x50124252, 0xe82bcbe3, 0x7c3e4e72, 0xd81acad2, 0xc809c9c1, 0xfc3dcdf1, + 0x30300030, 0x94158591, 0x64254561, 0x3c3c0c30, 0xb43686b2, 0xe424c4e0, 0xb83b8bb3, 0x7c3c4c70, + 0x0c0e0e02, 0x50104050, 0x38390931, 0x24260622, 0x30320232, 0x84048480, 0x68294961, 0x90138393, + 0x34370733, 0xe427c7e3, 0x24240420, 0xa42484a0, 0xc80bcbc3, 0x50134353, 0x080a0a02, 0x84078783, + 0xd819c9d1, 0x4c0c4c40, 0x80038383, 0x8c0f8f83, 0xcc0ecec2, 0x383b0b33, 0x480a4a42, 0xb43787b3 + }; + + private static int SS2[] = { + 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, 0xa0ac2c8c, 0x21242505, + 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, 0xc2c80aca, 0x63602343, + 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, 0xc0c808c8, 0x13141707, + 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, 0xd2d012c2, 0xe2ec2ece, + 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, 0xf2f436c6, 0x70743444, + 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, 0xb1bc3d8d, 0x01000101, + 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, 0xf2f032c2, 0xd1d819c9, + 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, 0x82840686, 0xc1c809c9, + 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, 0x929c1e8e, 0x434c0f4f, + 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, 0xa3ac2f8f, 0xd1d415c5, + 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, 0x818c0d8d, 0x00080808, + 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, 0xf3f437c7, 0xe1e021c1, + 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, 0x020c0e0e, 0xa3a82b8b, + 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, 0x01080909, 0x02080a0a, + 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, 0xf2fc3ece, 0x60642444, + 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, 0x63682b4b, 0x62642646, + 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, 0x727c3e4e, 0xd0d010c0, + 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, 0xa1ac2d8d, 0xd3dc1fcf, + 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, 0x22202202, 0x30383808, + 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, 0x80840484, 0x93941787, + 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, 0xc3c407c7, 0x81880989, + 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, 0x82800282, 0xc0c404c4, + 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, 0xd3d417c7, 0xb0b83888, + 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, 0xd3d81bcb, 0xa0a42484, + 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, 0x212c2d0d, 0x40400040, + 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, 0x424c0e4e, 0x51541545, + 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, 0x42480a4a, 0x52541646, + 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, 0x61642545, 0xf2f83aca, + 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, 0xe2e426c6, 0xb2b03282, + 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, 0xc1cc0dcd, 0x80880888, + 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, 0x03040707, 0x33303303, + 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, 0x22282a0a, 0x92981a8a + }; + + private static int SS3[] = { + 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838, + 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, + 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427, + 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b, + 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, + 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818, + 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f, + 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, + 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b, + 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434, + 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, + 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839, + 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031, + 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, 0x02222022, 0x04000404, 0x48606828, 0x41717031, + 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819, + 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010, + 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, + 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d, + 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e, + 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, + 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003, + 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809, + 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, + 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003, + 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839, + 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, + 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406, + 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d, + 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, + 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, 0x02323032, 0x84808404, 0x49616829, 0x83939013, + 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407, + 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437 + }; + + + private static int[] KC = { + 0x9e3779b9, 0x3c6ef373, 0x78dde6e6, 0xf1bbcdcc, 0xe3779b99, 0xc6ef3733, 0x8dde6e67, 0x1bbcdccf, + 0x3779b99e, 0x6ef3733c, 0xdde6e678, 0xbbcdccf1, 0x779b99e3, 0xef3733c6, 0xde6e678d, 0xbcdccf1b + }; + + /* 시스템의 Endian을 정의 */ + private static Boolean LITTLE = true; +// private static Boolean BIG = false; + /* C의 Define 대신 사용 */ + + /* System의 Endian에 따라 선택적으로 사용 */ + private static Boolean ENDIAN = LITTLE; // Intel 80x86, DEC VAX, DEC PDP-11 + //private static Bool ENDIAN = BIG; // IBM370, Motorola 68000, Pyramid (대부분의 RISC 기반) + + /* 초기 환경 변수 */ + private static int NoRounds = 16; +// private int NoRoundKeys = 32; //(NoRounds*2) +// private int SeedBlockSize = 16; // in bytes +// private int SeedBlockLen = 128; // in bits + + /* Encryption/Decryption */ + private static int GetB0(int A){ return (int)(0x000000ff&(A) ); }; + private static int GetB1(int A){ return (int)(0x000000ff&((A)>>>8)); }; + private static int GetB2(int A){ return (int)(0x000000ff&((A)>>>16)); }; + private static int GetB3(int A){ return (int)(0x000000ff&((A)>>>24)); }; + private static void EndianChange(int dws[]) { dws[0] = (dws[0]>>>24) | (dws[0]<<24) | ((dws[0]<<8)&0x00ff0000)|((dws[0]>>>8)&0x0000ff00); }; + private static int EndianChange(int dws) { return (dws>>>24) | (dws<<24) | ((dws<<8)&0x00ff0000)|((dws>>>8)&0x0000ff00); }; + + private SeedCodec() { + + } + + /* Round Function */ + private static void SeedRound(int L0[], int L1[], int R0[], int R1[], int K[]) + { + int T0, T1; + long T00=0, T11=0; + T0 = R0[0] ^ K[0]; + T1 = R1[0] ^ K[1]; + T1 ^= T0; + + T00 = (T0<0) ? (long)(T0 & 0x7fffffff)|(long)(0x80000000) : (long)(T0); + T1 = SS0[GetB0(T1)] ^ SS1[GetB1(T1)] ^ SS2[GetB2(T1)] ^ SS3[GetB3(T1)]; + T11 = (T1<0) ? (long)(T1 & 0x7fffffff)|(long)(0x80000000) : (long)(T1); + T00 += T11; + T0 = SS0[GetB0((int)T00)] ^ SS1[GetB1((int)T00)] ^ SS2[GetB2((int)T00)] ^ SS3[GetB3((int)T00)]; + T00 = (T0<0) ? (long)(T0 & 0x7fffffff)|(long)(0x80000000) : (long)(T0); + T11 += T00; + T1 = SS0[GetB0((int)T11)] ^ SS1[GetB1((int)T11)] ^ SS2[GetB2((int)T11)] ^ SS3[GetB3((int)T11)]; + T11 = (T1<0) ? (long)(T1 & 0x7fffffff)|(long)(0x80000000) : (long)(T1); + T00 += T11; + L0[0] ^= (int)T00; L1[0] ^= (int)T11; // return L0, L1 + }; + + /* Encrypt */ + public static void SeedEncrypt(byte pbData[], int pdwRoundKey[], byte outData[]) + { + int L0[] = new int[1]; int L1[] = new int[1]; + int R0[] = new int[1]; int R1[] = new int[1]; + L0[0] = 0x0; L1[0] = 0x0; R0[0] = 0x0; R1[0] = 0x0; + int K[] = new int[2]; + int nCount = 0; + + L0[0] = ((int)pbData[0]&0x000000ff); + L0[0] = ((L0[0])<<8)^((int)pbData[1]&0x000000ff); + L0[0] = ((L0[0])<<8)^((int)pbData[2]&0x000000ff); + L0[0] = ((L0[0])<<8)^((int)pbData[3]&0x000000ff); + + L1[0] = ((int)pbData[4]&0x000000ff); + L1[0] = ((L1[0])<<8)^((int)pbData[5]&0x000000ff); + L1[0] = ((L1[0])<<8)^((int)pbData[6]&0x000000ff); + L1[0] = ((L1[0])<<8)^((int)pbData[7]&0x000000ff); + + R0[0] = ((int)pbData[8]&0x000000ff); + R0[0] = ((R0[0])<<8)^((int)pbData[9]&0x000000ff); + R0[0] = ((R0[0])<<8)^((int)pbData[10]&0x000000ff); + R0[0] = ((R0[0])<<8)^((int)pbData[11]&0x000000ff); + + R1[0] = ((int)pbData[12]&0x000000ff); + R1[0] = ((R1[0])<<8)^((int)pbData[13]&0x000000ff); + R1[0] = ((R1[0])<<8)^((int)pbData[14]&0x000000ff); + R1[0] = ((R1[0])<<8)^((int)pbData[15]&0x000000ff); + + + if (!ENDIAN) {EndianChange(L0); EndianChange(L1); EndianChange(R0); EndianChange(R1);}; + + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(L0, L1, R0, R1, K); /* 1 */ + + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(R0, R1, L0, L1, K); /* 2 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(L0, L1, R0, R1, K); /* 3 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(R0, R1, L0, L1, K); /* 4 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(L0, L1, R0, R1, K); /* 5 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(R0, R1, L0, L1, K); /* 6 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(L0, L1, R0, R1, K); /* 7 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(R0, R1, L0, L1, K); /* 8 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(L0, L1, R0, R1, K); /* 9 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(R0, R1, L0, L1, K); /* 10 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(L0, L1, R0, R1, K); /* 11 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(R0, R1, L0, L1, K); /* 12 */ + + if (NoRounds == 16) + { + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(L0, L1, R0, R1, K); /* 13 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(R0, R1, L0, L1, K); /* 14 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(L0, L1, R0, R1, K); /* 15 */ + K[0] = pdwRoundKey[nCount++]; K[1] = pdwRoundKey[nCount++]; + SeedRound(R0, R1, L0, L1, K); /* 16 */ + } + + if (!ENDIAN) {EndianChange(L0); EndianChange(L1); EndianChange(R0); EndianChange(R1);}; + + for (int i=0; i<4; i++) + { + outData[i ] = (byte)(((R0[0])>>>(8*(3-i)))&0xff); + outData[4+i ] = (byte)(((R1[0])>>>(8*(3-i)))&0xff); + outData[8+i ] = (byte)(((L0[0])>>>(8*(3-i)))&0xff); + outData[12+i] = (byte)(((L1[0])>>>(8*(3-i)))&0xff); + } + } + + /* Decrypt */ + /* same as encrypt, except that round keys are applied in reverse order. */ + public static void SeedDecrypt(byte pbData[], int pdwRoundKey[], byte outData[]) + { + int L0[] = new int[1]; int L1[] = new int[1]; + int R0[] = new int[1]; int R1[] = new int[1]; + int K[] = new int[2]; + L0[0] = 0x0; L1[0] = 0x0; R0[0] = 0x0; R1[0] = 0x0; + int nCount = 31; + + L0[0] = ((int)pbData[0]&0x000000ff); + L0[0] = ((L0[0])<<8)^((int)pbData[1]&0x000000ff); + L0[0] = ((L0[0])<<8)^((int)pbData[2]&0x000000ff); + L0[0] = ((L0[0])<<8)^((int)pbData[3]&0x000000ff); + + L1[0] = ((int)pbData[4]&0x000000ff); + L1[0] = ((L1[0])<<8)^((int)pbData[5]&0x000000ff); + L1[0] = ((L1[0])<<8)^((int)pbData[6]&0x000000ff); + L1[0] = ((L1[0])<<8)^((int)pbData[7]&0x000000ff); + + R0[0] = ((int)pbData[8]&0x000000ff); + R0[0] = ((R0[0])<<8)^((int)pbData[9]&0x000000ff); + R0[0] = ((R0[0])<<8)^((int)pbData[10]&0x000000ff); + R0[0] = ((R0[0])<<8)^((int)pbData[11]&0x000000ff); + + R1[0] = ((int)pbData[12]&0x000000ff); + R1[0] = ((R1[0])<<8)^((int)pbData[13]&0x000000ff); + R1[0] = ((R1[0])<<8)^((int)pbData[14]&0x000000ff); + R1[0] = ((R1[0])<<8)^((int)pbData[15]&0x000000ff); + + + if (!ENDIAN) {EndianChange(L0); EndianChange(L1); EndianChange(R0); EndianChange(R1);}; + + if (NoRounds == 16) + { + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(L0, L1, R0, R1, K); /* 1 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(R0, R1, L0, L1, K); /* 2 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(L0, L1, R0, R1, K); /* 3 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(R0, R1, L0, L1, K); /* 4 */ + } + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(L0, L1, R0, R1, K); /* 5 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(R0, R1, L0, L1, K); /* 6 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(L0, L1, R0, R1, K); /* 7 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(R0, R1, L0, L1, K); /* 8 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(L0, L1, R0, R1, K); /* 9 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(R0, R1, L0, L1, K); /* 10 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(L0, L1, R0, R1, K); /* 11 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(R0, R1, L0, L1, K); /* 12 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(L0, L1, R0, R1, K); /* 13 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(R0, R1, L0, L1, K); /* 14 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount--]; + SeedRound(L0, L1, R0, R1, K); /* 15 */ + K[1] = pdwRoundKey[nCount--]; K[0] = pdwRoundKey[nCount]; + SeedRound(R0, R1, L0, L1, K); /* 16 */ + + if (!ENDIAN) {EndianChange(L0); EndianChange(L1); EndianChange(R0); EndianChange(R1);}; + + + + for (int i=0; i<4; i++) + { + outData[i ] = (byte)(((R0[0])>>>(8*(3-i)))&0xff); + outData[4+i ] = (byte)(((R1[0])>>>(8*(3-i)))&0xff); + outData[8+i ] = (byte)(((L0[0])>>>(8*(3-i)))&0xff); + outData[12+i] = (byte)(((L1[0])>>>(8*(3-i)))&0xff); + } + } + + private static void EncRoundKeyUpdate0(int K[], int A[], int B[], int C[], int D[], int Z) + { + int T0; + int T00, T11; + T0 = A[0]; + A[0] = (A[0]>>>8) ^ (B[0]<<24); + B[0] = (B[0]>>>8) ^ (T0<<24); + T00 = (int)A[0] + (int)C[0] - (int)KC[Z]; + T11 = (int)B[0] + (int)KC[Z] - (int)D[0]; + K[0] = SS0[GetB0((int)T00)] ^ SS1[GetB1((int)T00)] ^ SS2[GetB2((int)T00)] ^ SS3[GetB3((int)T00)]; + K[1] = SS0[GetB0((int)T11)] ^ SS1[GetB1((int)T11)] ^ SS2[GetB2((int)T11)] ^ SS3[GetB3((int)T11)]; + } + + private static void EncRoundKeyUpdate1(int K[], int A[], int B[], int C[], int D[], int Z) + { + int T0; + int T00, T11; + T0 = C[0]; + C[0] = (C[0]<<8) ^ (D[0]>>>24); + D[0] = (D[0]<<8) ^ (T0>>>24); + T00 = (int)A[0] + (int)C[0] - (int)KC[Z]; + T11 = (int)B[0] + (int)KC[Z] - (int)D[0]; + K[0] = SS0[GetB0((int)T00)] ^ SS1[GetB1((int)T00)] ^ SS2[GetB2((int)T00)] ^ SS3[GetB3((int)T00)]; + K[1] = SS0[GetB0((int)T11)] ^ SS1[GetB1((int)T11)] ^ SS2[GetB2((int)T11)] ^ SS3[GetB3((int)T11)]; + } + + public static void SeedEncRoundKey(int pdwRoundKey[], byte pbUserKey[]) + { + int A[] = new int[1]; + int B[] = new int[1]; + int C[] = new int[1]; + int D[] = new int[1]; + int K[] = new int[2]; + int T0, T1; + int nCount = 2; + + A[0] = ((int)pbUserKey[0]&0x000000ff); + A[0] = (A[0]<<8)^((int)pbUserKey[1]&0x000000ff); + A[0] = (A[0]<<8)^((int)pbUserKey[2]&0x000000ff); + A[0] = (A[0]<<8)^((int)pbUserKey[3]&0x000000ff); + + B[0] = ((int)pbUserKey[4]&0x000000ff); + B[0] = (B[0]<<8)^((int)pbUserKey[5]&0x000000ff); + B[0] = (B[0]<<8)^((int)pbUserKey[6]&0x000000ff); + B[0] = (B[0]<<8)^((int)pbUserKey[7]&0x000000ff); + + C[0] = ((int)pbUserKey[8]&0x000000ff); + C[0] = (C[0]<<8)^((int)pbUserKey[9]&0x000000ff); + C[0] = (C[0]<<8)^((int)pbUserKey[10]&0x000000ff); + C[0] = (C[0]<<8)^((int)pbUserKey[11]&0x000000ff); + + D[0] = ((int)pbUserKey[12]&0x000000ff); + D[0] = (D[0]<<8)^((int)pbUserKey[13]&0x000000ff); + D[0] = (D[0]<<8)^((int)pbUserKey[14]&0x000000ff); + D[0] = (D[0]<<8)^((int)pbUserKey[15]&0x000000ff); + + if (!ENDIAN) {A[0]=EndianChange(A[0]); B[0]=EndianChange(B[0]); C[0]=EndianChange(C[0]); D[0]=EndianChange(D[0]);}; + + T0 = (int)A[0] + (int)C[0] - (int)KC[0]; + T1 = (int)B[0] - (int)D[0] + (int)KC[0]; + + pdwRoundKey[0] = SS0[GetB0((int)T0)] ^ SS1[GetB1((int)T0)] ^ SS2[GetB2((int)T0)] ^ SS3[GetB3((int)T0)]; + pdwRoundKey[1] = SS0[GetB0((int)T1)] ^ SS1[GetB1((int)T1)] ^ SS2[GetB2((int)T1)] ^ SS3[GetB3((int)T1)]; + + EncRoundKeyUpdate0(K, A, B, C, D, 1 ); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate1(K, A, B, C, D, 2 ); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate0(K, A, B, C, D, 3 ); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate1(K, A, B, C, D, 4 ); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate0(K, A, B, C, D, 5 ); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate1(K, A, B, C, D, 6 ); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate0(K, A, B, C, D, 7 ); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate1(K, A, B, C, D, 8 ); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate0(K, A, B, C, D, 9 ); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate1(K, A, B, C, D, 10); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate0(K, A, B, C, D, 11); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + if (NoRounds == 16) + { + EncRoundKeyUpdate1(K, A, B, C, D, 12); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate0(K, A, B, C, D, 13); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate1(K, A, B, C, D, 14); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + + EncRoundKeyUpdate0(K, A, B, C, D, 15); + pdwRoundKey[nCount++] = K[0]; pdwRoundKey[nCount++] = K[1]; + } + } + + + public static byte[] encrypt(byte[] bytes) { + return bytes; + } + + + public static byte[] decrypt(byte[] bytes) { + return bytes; + } + + +// public static void main(String[] args) throws Exception { +// int pdwRoundKey[] = new int[32]; +// byte pbUserKey[] = {(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, +// (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00}; +// byte pbData[] = {(byte)0x00, (byte)0x01, (byte)0x02, (byte)0x03, (byte)0x04, (byte)0x05, (byte)0x06, (byte)0x07, +// (byte)0x08, (byte)0x09, (byte)0x0A, (byte)0x0B, (byte)0x0C, (byte)0x0D, (byte)0x0E, (byte)0x0F}; +// +// byte pbCipher[] = new byte[16]; +// byte pbPlain[] = new byte[16]; +// +// System.out.print("[ Test SEED reference code ]" + "\n"); +// System.out.print("\n\n"); +// +// pbData = "1234567890123456".getBytes(); +// +// /** +// * round key +// */ +// SeedEncRoundKey(pdwRoundKey, pbUserKey); +// +// /** +// * encrypt +// */ +// SeedEncrypt(pbData, pdwRoundKey, pbCipher); +// +// System.out.println("[ Test Encrypt mode ] ##################################"); +// System.out.println("Key : " + CommonLib.hexDump(pbUserKey)); +// System.out.println("Plaintext : " + CommonLib.hexDump(pbData)); +// System.out.println("Ciphertext : " + CommonLib.hexDump(pbCipher)); +// +// /** +// * decrypt +// */ +// SeedDecrypt(pbCipher, pdwRoundKey, pbPlain); +// +// System.out.println("[ Test Decrypt mode ] ##################################"); +// System.out.println("Key : " + CommonLib.hexDump(pbUserKey)); +// System.out.println("Ciphertext : " + CommonLib.hexDump(pbCipher)); +// System.out.println("Plaintext : " + CommonLib.hexDump(pbPlain)); +// } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedFilter.java new file mode 100644 index 0000000..69d63dc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedFilter.java @@ -0,0 +1,95 @@ +package com.eactive.eai.adapter.socket2.protocol.seed.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + + +public abstract class SeedFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + + private static final String NEXT_FILTER = SeedFilter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = SeedFilter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + + protected enum State { + STATE_HANDSHAKE, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = State.STATE_MESSAGE; //State.STATE_HANDSHAKE; + public byte[] userKey = new byte[16]; + public int[] roundKey = new int[32]; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected SeedFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + if (parent.contains(SeedFilter.class)) { + throw new IllegalStateException("A filter chain cannot contain more than one DesFilter."); + } + + IoSession session = parent.getSession(); + session.setAttribute(NEXT_FILTER, nextFilter); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + if (filterState.state == State.STATE_MESSAGE) { + byte[] encrypted = SeedCodec.encrypt(m.getBytes()); + m = new ByteMessage(encrypted); + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedServerFilter.java new file mode 100644 index 0000000..4fc76ac --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/seed/handshake/SeedServerFilter.java @@ -0,0 +1,69 @@ +package com.eactive.eai.adapter.socket2.protocol.seed.handshake; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + + +public class SeedServerFilter extends SeedFilter { + public SeedServerFilter(ISocketAdapter adapter) { + super(adapter); + } + +// @Override +// public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { +// process(nextFilter, session, new ByteMessage("123")); +// } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + process(nextFilter, session, message); + } + + + private void process(NextFilter nextFilter, IoSession session, Object message) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { +// case STATE_HANDSHAKE: +// /** +// * create user key & round key +// */ +// filterState.userKey = m.getBytes(); +// //EgeedCodec.SeedEncRoundKey(filterState.roundKey, filterState.userKey); +// session.write(m.getBytes()); +// +// /** +// * change state +// */ +// filterState.state = State.STATE_MESSAGE; +// setSessionState(session, filterState.state.toString()); +// +// nextFilter.sessionOpened(session); +// break; + + case STATE_MESSAGE: +// if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { +// logger.debug(context.getAdapterName() + " | SeedServerFilter | messageReceived() " + m.hexDump()); +// } + + byte[] decrypted = SeedCodec.decrypt(m.getBytes()); + m.setBytes(decrypted); + +// if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { +// logger.debug(context.getAdapterName() + " | SeedServerFilter | messageReceived() - after decrypt - " + m.hexDump()); +// } + + /** + * next filter + */ + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/SnmpAdapter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/SnmpAdapter.java new file mode 100644 index 0000000..b423cb0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/SnmpAdapter.java @@ -0,0 +1,33 @@ +package com.eactive.eai.adapter.socket2.protocol.snmp; + +import com.eactive.eai.adapter.socket2.protocol.snmp.codec.SnmpCodecFactory; +import edu.emory.mathcs.backport.java.util.concurrent.Executors; +import org.apache.mina.common.DefaultIoFilterChainBuilder; +import org.apache.mina.filter.LoggingFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; +import org.apache.mina.filter.executor.ExecutorFilter; +import org.apache.mina.transport.socket.nio.DatagramAcceptor; + +import java.net.InetSocketAddress; + + +public class SnmpAdapter { + public SnmpAdapter() throws Exception { + DatagramAcceptor acceptor = new DatagramAcceptor(Executors.newCachedThreadPool()); + + DefaultIoFilterChainBuilder chain = acceptor.getFilterChain(); + chain.addLast("logger", new LoggingFilter()); + chain.addLast("executor", new ExecutorFilter(Executors.newCachedThreadPool())); + chain.addLast("codec", new ProtocolCodecFilter(new SnmpCodecFactory())); + +// DatagramAcceptorConfig config = (DatagramAcceptorConfig) acceptor.getDefaultConfig(); + //config.setReuseAddress(true); + + acceptor.bind(new InetSocketAddress(161), new SnmpHandler()); + acceptor.bind(new InetSocketAddress(162), new SnmpHandler()); + } + + public static void main(String[] args) throws Exception { + new SnmpAdapter(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/SnmpHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/SnmpHandler.java new file mode 100644 index 0000000..f6e5cfb --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/SnmpHandler.java @@ -0,0 +1,41 @@ +package com.eactive.eai.adapter.socket2.protocol.snmp; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoHandlerAdapter; +import org.apache.mina.common.IoSession; + + +public class SnmpHandler extends IoHandlerAdapter { + public SnmpHandler(ISocketAdapter adapter) { + //super(adapter); + } + + public SnmpHandler() { + } + + @Override + public void sessionOpened(IoSession session) throws Exception { +// System.out.println("SnmpHandler | session opened."); + } + + @Override + public void sessionClosed(IoSession session) throws Exception { +// System.out.println("SnmpHandler | session closed."); + session.close(); + } + + @Override + public void messageReceived(IoSession session, Object message) throws Exception { +// System.out.println("SnmpHandler | message received. - "); + } + + @Override + public void messageSent(IoSession session, Object message) throws Exception { +// System.out.println("SnmpHandler | message sent."); + } + + @Override + public void exceptionCaught(IoSession session, Throwable cause) throws Exception { +// System.out.println("SnmpHandler | exception caught."); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/SnmpRequest.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/SnmpRequest.java new file mode 100644 index 0000000..156be1a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/SnmpRequest.java @@ -0,0 +1,1281 @@ +/*_############################################################################ + _## + _## SNMP4J - SnmpRequest.java + _## + _## Copyright (C) 2003-2008 Frank Fock and Jochen Katz (SNMP4J.org) + _## + _## 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 + _## + _## http://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. + _## + _##########################################################################*/ + +package com.eactive.eai.adapter.socket2.protocol.snmp; + +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.common.util.Logger; +import org.snmp4j.*; +import org.snmp4j.asn1.BER; +import org.snmp4j.event.ResponseEvent; +import org.snmp4j.log.JavaLogFactory; +import org.snmp4j.log.LogFactory; +import org.snmp4j.log.LogLevel; +import org.snmp4j.mp.*; +import org.snmp4j.security.*; +import org.snmp4j.smi.*; +import org.snmp4j.transport.AbstractTransportMapping; +import org.snmp4j.transport.DefaultTcpTransportMapping; +import org.snmp4j.transport.DefaultUdpTransportMapping; +import org.snmp4j.util.*; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; +import java.util.Vector; + +/** + * The SnmpRequest application is an example implementation of most of the + * SNMP4J features. It can be used to send SNMP requests to a target or to + * listen for traps/notifications and inform requests. + * + * @author Frank Fock + * @version 1.9 + */ +public class SnmpRequest implements CommandResponder, PDUFactory { + + // initialize Java logging + static { + LogFactory.setLogFactory(new JavaLogFactory()); + BER.setCheckSequenceLength(false); + } + + public static final int DEFAULT = 0; + public static final int WALK = 1; + public static final int LISTEN = 2; + public static final int TABLE = 3; + public static final int CVS_TABLE = 4; + public static final int TIME_BASED_CVS_TABLE = 5; + public static final int SNAPSHOT_CREATION = 6; + public static final int SNAPSHOT_DUMP = 7; + + Target target; + Address address; + OID authProtocol; + OID privProtocol; + OctetString privPassphrase; + OctetString authPassphrase; + OctetString community = new OctetString("public"); + OctetString authoritativeEngineID; + OctetString contextEngineID; + OctetString contextName = new OctetString(); + OctetString securityName = new OctetString(); + OctetString localEngineID = new OctetString(MPv3.createLocalEngineID()); + + TimeTicks sysUpTime = new TimeTicks(0); + OID trapOID = SnmpConstants.coldStart; + + PDUv1 v1TrapPDU = new PDUv1(); + + int version = SnmpConstants.version3; + int engineBootCount = 0; + int retries = 1; + int timeout = 1000; + int pduType = PDU.GETNEXT; + int maxRepetitions = 10; + int nonRepeaters = 0; + int maxSizeResponsePDU = 65535; + Vector vbs = new Vector(); + File snapshotFile; + + protected int operation = DEFAULT; + + int numDispatcherThreads = 2; + + boolean useDenseTableOperation = false; + + // table options + OID lowerBoundIndex, upperBoundIndex; + private static Logger logger = SocketLoggerManager.getInstance().getLogger(); + public SnmpRequest(String[] args) { + // Set the default counter listener to return proper USM and MP error + // counters. + CounterSupport.getInstance().addCounterListener(new DefaultCounterListener()); + + vbs.add(new VariableBinding(new OID("1.3.6"))); + int paramStart = parseArgs(args); + if (paramStart >= args.length) { + printUsage(); + System.exit(1); + } else if (operation != SNAPSHOT_DUMP) { + checkOptions(); + address = getAddress(args[paramStart++]); + Vector vbs = getVariableBindings(args, paramStart); + checkTrapVariables(vbs); + if (vbs.size() > 0) { + this.vbs = vbs; + } + } + } + + public int getPduType() { + return pduType; + } + + public int getVersion() { + return version; + } + + public Vector getVbs() { + return vbs; + } + + public boolean isUseDenseTableOperation() { + return useDenseTableOperation; + } + + public OID getUpperBoundIndex() { + return upperBoundIndex; + } + + public OID getTrapOID() { + return trapOID; + } + + public int getTimeout() { + return timeout; + } + + public Target getTarget() { + return target; + } + + public TimeTicks getSysUpTime() { + return sysUpTime; + } + + public OctetString getSecurityName() { + return securityName; + } + + public int getRetries() { + return retries; + } + + public OID getPrivProtocol() { + return privProtocol; + } + + public OctetString getPrivPassphrase() { + return privPassphrase; + } + + public int getOperation() { + return operation; + } + + public int getNumDispatcherThreads() { + return numDispatcherThreads; + } + + public int getNonRepeaters() { + return nonRepeaters; + } + + public int getMaxRepetitions() { + return maxRepetitions; + } + + public OID getLowerBoundIndex() { + return lowerBoundIndex; + } + + public OctetString getContextName() { + return contextName; + } + + public OctetString getContextEngineID() { + return contextEngineID; + } + + public OctetString getCommunity() { + return community; + } + + public OctetString getAuthoritativeEngineID() { + return authoritativeEngineID; + } + + public OID getAuthProtocol() { + return authProtocol; + } + + public OctetString getAuthPassphrase() { + return authPassphrase; + } + + public Address getAddress() { + return address; + } + + private void checkOptions() { + if ((operation == WALK) && ((pduType != PDU.GETBULK) && (pduType != PDU.GETNEXT))) { + throw new IllegalArgumentException("Walk operation is not supported for PDU type: " + + PDU.getTypeString(pduType)); + } else if ((operation == WALK) && (vbs.size() != 1)) { + throw new IllegalArgumentException( + "There must be exactly one OID supplied for walk operations"); + } + if ((pduType == PDU.V1TRAP) && (version != SnmpConstants.version1)) { + throw new IllegalArgumentException( + "V1TRAP PDU type is only available for SNMP version 1"); + } + } + + private void checkTrapVariables(Vector vbs) { + if ((pduType == PDU.INFORM) || (pduType == PDU.TRAP)) { + if ((vbs.size() == 0) + || ((vbs.size() > 1) && (!((VariableBinding) vbs.get(0)).getOid().equals( + SnmpConstants.sysUpTime)))) { + vbs.add(0, new VariableBinding(SnmpConstants.sysUpTime, sysUpTime)); + } + if ((vbs.size() == 1) + || ((vbs.size() > 2) && (!((VariableBinding) vbs.get(1)).getOid().equals( + SnmpConstants.snmpTrapOID)))) { + vbs.add(1, new VariableBinding(SnmpConstants.snmpTrapOID, trapOID)); + } + } + } + + public synchronized void listen() throws IOException { + AbstractTransportMapping transport; + if (address instanceof TcpAddress) { + transport = new DefaultTcpTransportMapping((TcpAddress) address); + } else { + transport = new DefaultUdpTransportMapping((UdpAddress) address); + } + ThreadPool threadPool = ThreadPool.create("DispatcherPool", numDispatcherThreads); + MessageDispatcher mtDispatcher = new MultiThreadedMessageDispatcher(threadPool, + new MessageDispatcherImpl()); + + // add message processing models + mtDispatcher.addMessageProcessingModel(new MPv1()); + mtDispatcher.addMessageProcessingModel(new MPv2c()); + mtDispatcher.addMessageProcessingModel(new MPv3(localEngineID.getValue())); + + // add all security protocols + SecurityProtocols.getInstance().addDefaultProtocols(); + SecurityProtocols.getInstance().addPrivacyProtocol(new Priv3DES()); + + Snmp snmp = new Snmp(mtDispatcher, transport); + if (version == SnmpConstants.version3) { + USM usm = new USM(SecurityProtocols.getInstance(), localEngineID, 0); + SecurityModels.getInstance().addSecurityModel(usm); + if (authoritativeEngineID != null) { + snmp.setLocalEngine(authoritativeEngineID.getValue(), 0, 0); + } + // Add the configured user to the USM + addUsmUser(snmp); + } else { + CommunityTarget target = new CommunityTarget(); + target.setCommunity(community); + this.target = target; + } + + snmp.addCommandResponder(this); + + transport.listen(); + logger.info("Listening on " + address); + + try { + this.wait(); + } catch (InterruptedException ex) { + } + } + + private void addUsmUser(Snmp snmp) { + snmp.getUSM().addUser( + securityName, + new UsmUser(securityName, authProtocol, authPassphrase, privProtocol, + privPassphrase)); + } + + private Snmp createSnmpSession() throws IOException { + AbstractTransportMapping transport; + if (address instanceof TcpAddress) { + transport = new DefaultTcpTransportMapping(); + } else { + transport = new DefaultUdpTransportMapping(); + } + // Could save some CPU cycles: + // transport.setAsyncMsgProcessingSupported(false); + Snmp snmp = new Snmp(transport); + ((MPv3) snmp.getMessageProcessingModel(MPv3.ID)).setLocalEngineID(localEngineID.getValue()); + + if (version == SnmpConstants.version3) { + USM usm = new USM(SecurityProtocols.getInstance(), localEngineID, engineBootCount); + SecurityModels.getInstance().addSecurityModel(usm); + addUsmUser(snmp); + } + return snmp; + } + + private Target createTarget() { + if (version == SnmpConstants.version3) { + UserTarget target = new UserTarget(); + if (authPassphrase != null) { + if (privPassphrase != null) { + target.setSecurityLevel(SecurityLevel.AUTH_PRIV); + } else { + target.setSecurityLevel(SecurityLevel.AUTH_NOPRIV); + } + } else { + target.setSecurityLevel(SecurityLevel.NOAUTH_NOPRIV); + } + target.setSecurityName(securityName); + return target; + } else { + CommunityTarget target = new CommunityTarget(); + target.setCommunity(community); + return target; + } + } + + public PDU send() throws IOException { + Snmp snmp = createSnmpSession(); + this.target = createTarget(); + target.setVersion(version); + target.setAddress(address); + target.setRetries(retries); + target.setTimeout(timeout); + target.setMaxSizeRequestPDU(maxSizeResponsePDU); + snmp.listen(); + + PDU request = createPDU(target); + if (request.getType() == PDU.GETBULK) { + request.setMaxRepetitions(maxRepetitions); + request.setNonRepeaters(nonRepeaters); + } + for (int i = 0; i < vbs.size(); i++) { + request.add((VariableBinding) vbs.get(i)); + } + + PDU response = null; + if ((operation == WALK) || (operation == SNAPSHOT_CREATION)) { + ArrayList snapshot = null; + if (operation == SNAPSHOT_CREATION) { + snapshot = new ArrayList(); + } + walk(snmp, request, target, snapshot); + if (snapshot != null) { + createSnapshot(snapshot); + } + return null; + } else { + ResponseEvent responseEvent; + long startTime = System.currentTimeMillis(); + responseEvent = snmp.send(request, target); + if (responseEvent != null) { + response = responseEvent.getResponse(); + logger.info("Received response after " + + (System.currentTimeMillis() - startTime) + " millis"); + } + } + snmp.close(); + return response; + } + + private PDU walk(Snmp snmp, PDU request, Target target, final List snapshot) throws IOException { + request.setNonRepeaters(0); + OID rootOID = request.get(0).getOid(); + PDU response = null; + final WalkCounts counts = new WalkCounts(); + final long startTime = System.currentTimeMillis(); + TreeUtils treeUtils = new TreeUtils(snmp, new DefaultPDUFactory()); + TreeListener treeListener = new TreeListener() { + public boolean next(TreeEvent e) { + counts.requests++; + if (e.getVariableBindings() != null) { + VariableBinding[] vbs = e.getVariableBindings(); + counts.objects += vbs.length; + for (int i = 0; i < vbs.length; i++) { + if (snapshot != null) { + snapshot.add(vbs[i]); + } + logger.info(vbs[i].toString()); + } + } + return true; + } + + public void finished(TreeEvent e) { + if ((e.getVariableBindings() != null) && (e.getVariableBindings().length > 0)) { + next(e); + } + logger.info("Total requests sent: " + counts.requests); + logger.info("Total objects received: " + counts.objects); + logger.info("Total walk time: " + + (System.currentTimeMillis() - startTime) + " milliseconds"); + if (e.isError()) { + logger.error("The following error occurred during walk:"); + logger.error(e.getErrorMessage()); + } + synchronized (this) { + this.notify(); + } + } + }; + synchronized (treeListener) { + treeUtils.getSubtree(target, rootOID, null, treeListener); + try { + treeListener.wait(); + } catch (InterruptedException ex) { + logger.error("Tree retrieval interrupted: " + ex.toString()); + } + } + return response; + } + + private static Vector getVariableBindings(String[] args, int position) { + Vector v = new Vector(args.length - position + 1); + for (int i = position; i < args.length; i++) { + String oid = args[i]; + char type = 'i'; + String value = null; + int equal = oid.indexOf("={"); + if (equal > 0) { + oid = args[i].substring(0, equal); + type = args[i].charAt(equal + 2); + value = args[i].substring(args[i].indexOf('}') + 1); + } else if (oid.indexOf('-') > 0) { + StringTokenizer st = new StringTokenizer(oid, "-"); + if (st.countTokens() != 2) { + throw new IllegalArgumentException("Illegal OID range specified: '" + oid); + } + oid = st.nextToken(); + VariableBinding vbLower = new VariableBinding(new OID(oid)); + v.add(vbLower); + long last = Long.parseLong(st.nextToken()); + long first = vbLower.getOid().lastUnsigned(); + for (long k = first + 1; k <= last; k++) { + OID nextOID = new OID(vbLower.getOid().getValue(), 0, + vbLower.getOid().size() - 1); + nextOID.appendUnsigned(k); + VariableBinding next = new VariableBinding(nextOID); + v.add(next); + } + continue; + } + VariableBinding vb = new VariableBinding(new OID(oid)); + if (value != null) { + Variable variable; + switch (type) { + case 'i': + variable = new Integer32(Integer.parseInt(value)); + break; + case 'u': + variable = new UnsignedInteger32(Long.parseLong(value)); + break; + case 's': + variable = new OctetString(value); + break; + case 'x': + variable = OctetString.fromString(value, ':', 16); + break; + case 'd': + variable = OctetString.fromString(value, '.', 10); + break; + case 'b': + variable = OctetString.fromString(value, ' ', 2); + break; + case 'n': + variable = new Null(); + break; + case 'o': + variable = new OID(value); + break; + case 't': + variable = new TimeTicks(Long.parseLong(value)); + break; + case 'a': + variable = new IpAddress(value); + break; + default: + throw new IllegalArgumentException("Variable type " + type + " not supported"); + } + vb.setVariable(variable); + } + v.add(vb); + } + return v; + } + + private static Address getAddress(String transportAddress) { + String transport = "udp"; + int colon = transportAddress.indexOf(':'); + if (colon > 0) { + transport = transportAddress.substring(0, colon); + transportAddress = transportAddress.substring(colon + 1); + } + // set default port + if (transportAddress.indexOf('/') < 0) { + transportAddress += "/161"; + } + if (transport.equalsIgnoreCase("udp")) { + return new UdpAddress(transportAddress); + } else if (transport.equalsIgnoreCase("tcp")) { + return new TcpAddress(transportAddress); + } + throw new IllegalArgumentException("Unknown transport " + transport); + } + + private static String nextOption(String[] args, int position) { + if (position + 1 >= args.length) { + throw new IllegalArgumentException("Missing option value for " + args[position]); + } + return args[position + 1]; + } + + private static OctetString createOctetString(String s) { + OctetString octetString; + if (s.startsWith("0x")) { + octetString = OctetString.fromHexString(s.substring(2), ':'); + } else { + octetString = new OctetString(s); + } + return octetString; + } + + private int parseArgs(String[] args) { + for (int i = 0; i < args.length; i++) { + if (args[i].equals("-a")) { + String s = nextOption(args, i++); + if (s.equals("MD5")) { + authProtocol = AuthMD5.ID; + } else if (s.equals("SHA")) { + authProtocol = AuthSHA.ID; + } else { + throw new IllegalArgumentException("Authentication protocol unsupported: " + s); + } + } else if (args[i].equals("-A")) { + authPassphrase = createOctetString(nextOption(args, i++)); + } else if (args[i].equals("-X") || args[i].equals("-P")) { + privPassphrase = createOctetString(nextOption(args, i++)); + } else if (args[i].equals("-c")) { + community = createOctetString(nextOption(args, i++)); + } else if (args[i].equals("-b")) { + engineBootCount = Math.max(Integer.parseInt(nextOption(args, i++)), 0); + } else if (args[i].equals("-d")) { + String debugOption = nextOption(args, i++); + LogFactory.getLogFactory().getRootLogger().setLogLevel( + LogLevel.toLevel(debugOption)); + } else if (args[i].equals("-l")) { + localEngineID = createOctetString(nextOption(args, i++)); + } else if (args[i].equals("-e")) { + authoritativeEngineID = createOctetString(nextOption(args, i++)); + } else if (args[i].equals("-E")) { + contextEngineID = createOctetString(nextOption(args, i++)); + } else if (args[i].equals("-h")) { + printUsage(); + System.exit(0); + } else if (args[i].equals("-n")) { + contextName = createOctetString(nextOption(args, i++)); + } else if (args[i].equals("-m")) { + maxSizeResponsePDU = Integer.parseInt(nextOption(args, i++)); + } else if (args[i].equals("-r")) { + retries = Integer.parseInt(nextOption(args, i++)); + } else if (args[i].equals("-t")) { + timeout = Integer.parseInt(nextOption(args, i++)); + } else if (args[i].equals("-u")) { + securityName = createOctetString(nextOption(args, i++)); + } else if (args[i].equals("-V")) { + printVersion(); + System.exit(0); + } else if (args[i].equals("-Cr")) { + maxRepetitions = Integer.parseInt(nextOption(args, i++)); + } else if (args[i].equals("-Cn")) { + nonRepeaters = Integer.parseInt(nextOption(args, i++)); + } else if (args[i].equals("-Ce")) { + v1TrapPDU.setEnterprise(new OID(nextOption(args, i++))); + } else if (args[i].equals("-Ct")) { + trapOID = new OID(nextOption(args, i++)); + } else if (args[i].equals("-Cg")) { + v1TrapPDU.setGenericTrap(Integer.parseInt(nextOption(args, i++))); + } else if (args[i].equals("-Cs")) { + v1TrapPDU.setSpecificTrap(Integer.parseInt(nextOption(args, i++))); + } else if (args[i].equals("-Ca")) { + v1TrapPDU.setAgentAddress(new IpAddress(nextOption(args, i++))); + } else if (args[i].equals("-Cu")) { + String upTime = nextOption(args, i++); + v1TrapPDU.setTimestamp(Long.parseLong(upTime)); + sysUpTime.setValue(Long.parseLong(upTime)); + } else if (args[i].equals("-Ow")) { + operation = WALK; + } else if (args[i].equals("-Ocs")) { + operation = SNAPSHOT_CREATION; + snapshotFile = new File(nextOption(args, i++)); + if (!snapshotFile.canWrite() && snapshotFile.exists()) { + throw new IllegalArgumentException("Snapshot file '" + snapshotFile + + "' cannot be written"); + } + } else if (args[i].equals("-Ods")) { + operation = SNAPSHOT_DUMP; + snapshotFile = new File(nextOption(args, i++)); + if (!snapshotFile.canRead()) { + throw new IllegalArgumentException("Snapshot file '" + snapshotFile + + "' cannot be read"); + } + } else if (args[i].equals("-Ol")) { + operation = LISTEN; + } else if (args[i].equals("-OtCSV")) { + operation = CVS_TABLE; + } else if (args[i].equals("-OttCSV")) { + operation = TIME_BASED_CVS_TABLE; + } else if (args[i].equals("-Ot")) { + operation = TABLE; + } else if (args[i].equals("-Otd")) { + operation = TABLE; + useDenseTableOperation = true; + } else if (args[i].equals("-Cil")) { + lowerBoundIndex = new OID(nextOption(args, i++)); + } else if (args[i].equals("-Ciu")) { + upperBoundIndex = new OID(nextOption(args, i++)); + } else if (args[i].equals("-v")) { + String v = nextOption(args, i++); + if (v.equals("1")) { + version = SnmpConstants.version1; + } else if (v.equals("2c")) { + version = SnmpConstants.version2c; + } else if (v.equals("3")) { + version = SnmpConstants.version3; + } else { + throw new IllegalArgumentException("Version " + v + " not supported"); + } + } else if (args[i].equals("-x")) { + String s = nextOption(args, i++); + if (s.equals("DES")) { + privProtocol = PrivDES.ID; + } else if ((s.equals("AES128")) || (s.equals("AES"))) { + privProtocol = PrivAES128.ID; + } else if (s.equals("AES192")) { + privProtocol = PrivAES192.ID; + } else if (s.equals("AES256")) { + privProtocol = PrivAES256.ID; + } else if ((s.equals("3DES") || s.equalsIgnoreCase("DESEDE"))) { + privProtocol = Priv3DES.ID; + } else { + throw new IllegalArgumentException("Privacy protocol " + s + " not supported"); + } + } else if (args[i].equals("-p")) { + String s = nextOption(args, i++); + pduType = PDU.getTypeFromString(s); + if (pduType == Integer.MIN_VALUE) { + throw new IllegalArgumentException("Unknown PDU type " + s); + } + } else if (!args[i].startsWith("-")) { + return i; + } else { + throw new IllegalArgumentException("Unknown option " + args[i]); + } + } + return 0; + } + + protected static void printVersion() { + logger.info("SNMP4J Command Line Tool v1.9 Copyright " + (char) 0xA9 + + " 2004-2008, Frank Fock and Jochen Katz"); + logger.info("http://www.snmp4j.org"); + logger.info("SNMP4J is licensed under the Apache License 2.0:"); + logger.info("http://www.apache.org/licenses/LICENSE-2.0.txt"); + + } + + /** + * printUsage + */ + protected static void printUsage() { + String[] usage = new String[] { + "", + "Usage: SNMP4J [options] [transport:]address [OID[={type}value] ...]", + "", + " -a authProtocol Sets the authentication protocol used to", + " authenticate SNMPv3 messages. Valid values are", + " MD5 and SHA.", + " -A authPassphrase Sets the authentication pass phrase for authenticated", + " SNMPv3 messages.", + " -b engineBootCount Sets the engine boot count to the specified value", + " greater or equal to zero. Default is zero.", + " -c community Sets the community for SNMPv1/v2c messages.", + " -Ca agentAddress Sets the agent address field of a V1TRAP PDU.", + " The default value is '0.0.0.0'.", + " -Cg genericID Sets the generic ID for SNMPv1 TRAPs (V1TRAP).", + " The default is 1 (coldStart).", + " -Ce enterpriseOID Sets the enterprise OID field of a V1TRAP PDU.", + " -Cil lowerBoundIndex Sets the lower bound index for TABLE operations.", + " -Ciu upperBoundIndex Sets the upper bound index for TABLE operations.", + " -Cn non-repeaters Sets the non-repeaters field for GETBULK PDUs.", + " It specifies the number of supplied variables that", + " should not be iterated over. The default is 0.", + " -Cr max-repetitions Sets the max-repetitions field for GETBULK PDUs.", + " This specifies the maximum number of iterations", + " over the repeating variables. The default is 10.", + " -Cs specificID Sets the specific ID for V1TRAP PDU. The default is 0.", + " -Ct trapOID Sets the trapOID (1.3.6.1.6.3.1.1.4.1.0) of an INFORM", + " or TRAP PDU. The default is 1.3.6.1.6.3.1.1.5.1.", + " -Cu upTime Sets the sysUpTime field of an INFORM, TRAP, or", + " V1TRAP PDU.", + " -d debugLevel Sets the global debug level for Log4J logging output.", + " Valid values are OFF, ERROR, WARN, INFO, and DEBUG.", + " -e engineID Sets the authoritative engine ID of the command", + " responder used for SNMPv3 request messages. If not", + " supplied, the engine ID will be discovered.", + " -E contextEngineID Sets the context engine ID used for the SNMPv3 scoped", + " PDU. The authoritative engine ID will be used for the", + " context engine ID, if the latter is not specified.", + " -h Displays this message and then exits the application.", + " -l localEngineID Sets the local engine ID of the command generator", + " and the notification receiver (thus this SNMP4J-Tool)", + " used for SNMPv3 request messages. This option can be", + " used to avoid engine ID clashes through duplicate IDs", + " leading to usmStatsNotInTimeWindows reports.", + " -n contextName Sets the target context name for SNMPv3 messages. ", + " Default is the empty string.", + " -m maxSizeRespPDU The maximum size of the response PDU in bytes.", + " -Ocs Same as -Ow except that the retrieved values are also", + " written as a serialized ArrayList of VariableBinding", + " instances to the specified file. The snapshot format", + " can be read later by other applications, for example", + " MIB Explorer Pro 2.2 or later. See also -Ods.", + " -Ods Reads the snapshot file and dumps its contents on", + " standard out. No SNMP operation will be done.", + " See also -Ocs.", + " -Ol Activates listen operation mode. In this mode, the", + " application will listen for incoming TRAPs and INFORMs", + " on the supplied address. Received request will be", + " dumped to the console until the application is stopped.", + " -Ot Activates table operation mode. In this mode, the", + " application receives tabular data from the column", + " OIDs specified as parameters. The retrieved rows will", + " be dumped to the console ordered by their index values.", + " -Otd Activates dense table operation mode. In this mode, the", + " application receives tabular data from the column", + " OIDs specified as parameters. The retrieved rows will", + " be dumped to the console ordered by their index values.", + " In contrast to -Ot this option must not be used with", + " sparse tables. ", + " -OtCSV Same as -Ot except that for each SNMP row received", + " exactly one row of comma separated values will printed", + " to the console where the first column contains the row", + " index.", + " -OttCSV Same as -OtCSV except that each row's first column", + " will report the current time (millis after 1.1.1970)", + " when the request has been sent.", + " -Ow Activates walk operation mode for GETNEXT and GETBULK", + " PDUs. If activated, the GETNEXT and GETBULK operations", + " will be repeated until all instances within the", + " OID subtree of the supplied OID have been retrieved", + " successfully or until an error occurred.", + " -p pduType Specifies the PDU type to be used for the message.", + " Valid types are GET, GETNEXT, GETBULK (SNMPv2c/v3),", + " SET, INFORM, TRAP, and V1TRAP (SNMPv1).", + " -P privacyPassphrase Sets the privacy pass phrase for encrypted", + " SNMPv3 messages (same as -X).", + " -r retries Sets the number of retries used for requests. A zero", + " value will send out a request exactly once.", + " Default is 1.", + " -t timeout Sets the timeout in milliseconds between retries.", + " Default is 1000 milliseconds.", + " -u securityName Sets the security name for authenticated v3 messages.", + " -v 1|2c|3 Sets the SNMP protocol version to be used.", + " Default is 3.", + " -V Displays version information and then exits.", + " -x privacyProtocol Sets the privacy protocol to be used to encrypt", + " SNMPv3 messages. Valid values are DES, AES (AES128),", + " AES192, AES256, and 3DES(DESEDE).", + " -X privacyPassphrase Sets the privacy pass phrase for encrypted", + " SNMPv3 messages (same as -P).", + "", + "The address of the target SNMP engine is parsed according to the", + "specified selector (default selector is udp):", + "", + " udp | tcp hostname[/port]", + " ipv4Address[/port]", + " ipv6Address[/port]", + "", + "The OIDs have to be specified in numerical form, for example:", + " 1.3.6.1.2.1.1.5.0 (which will return the sysName.0 instance with a GET)", + "To request multiple instances, add additional OIDs with a space as", + "separator. For the last sub-identifier of a plain OID (without an assigned", + "value) a range can be specified, for example '1.3.6.1.2.1.2.2.1-10' will", + "has the same effect as enumerating all OIDs from '1.3.6.1.2.1.2.2.1' to", + "'1.3.6.1.2.1.2.2.10'.", + "For SET and INFORM request, you can specify a value for each OID by", + "using the following form: OID={type}value where is one of", + "the following single characters enclosed by '{' and '}':", + " i Integer32", + " u UnsingedInteger32, Gauge32", + " s OCTET STRING", + " x OCTET STRING specified as hex string where", + " bytes separated by colons (':').", + " d OCTET STRING specified as decimal string", + " where bytes are separated by dots ('.').", + " n Null", + " o OBJECT IDENTIFIER", + " t TimeTicks", + " a IpAddress", + " b OCTET STRING specified as binary string where", + " bytes are separated by spaces.", + "", + "An example for a complete SNMPv2c SET request to set sysName:", + " SNMP4J -c private -v 2c -p SET udp:localhost/161 \"1.3.6.1.2.1.1.5.0={s}SNMP4J\"", + "", + "To walk the whole MIB tree with GETBULK and using SNMPv3 MD5 authentication:", + " SNMP4J -a MD5 -A MD5UserAuthPassword -u MD5User -p GETBULK -Ow 127.0.0.1/161", + "", + "Listen for unauthenticated SNMPv3 INFORMs and TRAPs and all v1/v2c TRAPs:", + " SNMP4J -u aSecurityName -Ol 0.0.0.0/162", + "", + "Send an unauthenticated SNMPv3 notification (trap):", + " SNMP4J -p TRAP -v 3 -u aSecurityName 127.0.0.1/162 \"1.3.6.1.2.1.1.3.0={t}0\" \\", + " \"1.3.6.1.6.3.1.1.4.1.0={o}1.3.6.1.6.3.1.1.5.1\" \\", + " \"1.3.6.1.2.1.1.1.0={s}System XYZ, Version N.M\"", + "Retrieve rows of the columnar objects ifDescr to ifInOctets and ifOutOctets:", + " SNMP4J -c public -v 2c -Ot localhost 1.3.6.1.2.1.2.2.1.2-10\\", + " 1.3.6.1.2.1.2.2.1.16", "" }; + + for (int i = 0; i < usage.length; i++) { + logger.info(usage[i]); + } + } + + protected static void printVariableBindings(PDU response) { + for (int i = 0; i < response.size(); i++) { + VariableBinding vb = response.get(i); + logger.info(vb.toString()); + } + } + + protected static void printReport(PDU response) { + if (response.size() < 1) { + logger.info("REPORT PDU does not contain a variable binding."); + return; + } + + VariableBinding vb = response.get(0); + OID oid = vb.getOid(); + if (SnmpConstants.usmStatsUnsupportedSecLevels.equals(oid)) { + logger.info("REPORT: Unsupported Security Level."); + } else if (SnmpConstants.usmStatsNotInTimeWindows.equals(oid)) { + logger.info("REPORT: Message not within time window."); + } else if (SnmpConstants.usmStatsUnknownUserNames.equals(oid)) { + logger.info("REPORT: Unknown user name."); + } else if (SnmpConstants.usmStatsUnknownEngineIDs.equals(oid)) { + logger.info("REPORT: Unknown engine id."); + } else if (SnmpConstants.usmStatsWrongDigests.equals(oid)) { + logger.info("REPORT: Wrong digest."); + } else if (SnmpConstants.usmStatsDecryptionErrors.equals(oid)) { + logger.info("REPORT: Decryption error."); + } else if (SnmpConstants.snmpUnknownSecurityModels.equals(oid)) { + logger.info("REPORT: Unknown security model."); + } else if (SnmpConstants.snmpInvalidMsgs.equals(oid)) { + logger.info("REPORT: Invalid message."); + } else if (SnmpConstants.snmpUnknownPDUHandlers.equals(oid)) { + logger.info("REPORT: Unknown PDU handler."); + } else if (SnmpConstants.snmpUnavailableContexts.equals(oid)) { + logger.info("REPORT: Unavailable context."); + } else if (SnmpConstants.snmpUnknownContexts.equals(oid)) { + logger.info("REPORT: Unknown context."); + } else { + logger.info("REPORT contains unknown OID (" + oid.toString() + ")."); + } + logger.info(" Current counter value is " + vb.getVariable().toString() + "."); + } + + public synchronized void processPdu(CommandResponderEvent e) { + PDU command = e.getPDU(); + if (command != null) { + logger.info(command.toString()); + if ((command.getType() != PDU.TRAP) && (command.getType() != PDU.V1TRAP) + && (command.getType() != PDU.REPORT) && (command.getType() != PDU.RESPONSE)) { + command.setErrorIndex(0); + command.setErrorStatus(0); + command.setType(PDU.RESPONSE); + StatusInformation statusInformation = new StatusInformation(); + StateReference ref = e.getStateReference(); + try { + e.getMessageDispatcher().returnResponsePdu(e.getMessageProcessingModel(), + e.getSecurityModel(), e.getSecurityName(), e.getSecurityLevel(), + command, e.getMaxSizeResponsePDU(), ref, statusInformation); + } catch (MessageException ex) { + logger.error("Error while sending response: " + ex.toString()); + LogFactory.getLogger(SnmpRequest.class).error(ex); + } + } + } + } + + public PDU createPDU(Target target) { + PDU request; + if (target.getVersion() == SnmpConstants.version3) { + request = new ScopedPDU(); + ScopedPDU scopedPDU = (ScopedPDU) request; + if (contextEngineID != null) { + scopedPDU.setContextEngineID(contextEngineID); + } + if (contextName != null) { + scopedPDU.setContextName(contextName); + } + } else { + if (pduType == PDU.V1TRAP) { + request = v1TrapPDU; + } else { + request = new PDU(); + } + } + request.setType(pduType); + return request; + } + + public void table() throws IOException { + Snmp snmp = createSnmpSession(); + this.target = createTarget(); + target.setVersion(version); + target.setAddress(address); + target.setRetries(retries); + target.setTimeout(timeout); + snmp.listen(); + + TableUtils tableUtils = new TableUtils(snmp, this); + tableUtils.setMaxNumRowsPerPDU(maxRepetitions); + Counter32 counter = new Counter32(); + + OID[] columns = new OID[vbs.size()]; + for (int i = 0; i < columns.length; i++) { + columns[i] = ((VariableBinding) vbs.get(i)).getOid(); + } + long startTime = System.currentTimeMillis(); + synchronized (counter) { + + TableListener listener; + if (operation == TABLE) { + listener = new TextTableListener(); + } else { + listener = new CVSTableListener(System.currentTimeMillis()); + } + if (useDenseTableOperation) { + tableUtils.getDenseTable(target, columns, listener, counter, lowerBoundIndex, + upperBoundIndex); + } else { + tableUtils.getTable(target, columns, listener, counter, lowerBoundIndex, + upperBoundIndex); + } + try { + counter.wait(timeout); + } catch (InterruptedException ex) { + } + } + logger.info("Table received in " + (System.currentTimeMillis() - startTime) + + " milliseconds."); + snmp.close(); + } + + class CVSTableListener implements TableListener { + + private long requestTime; + + public CVSTableListener(long time) { + this.requestTime = time; + } + + public boolean next(TableEvent event) { + if (operation == TIME_BASED_CVS_TABLE) { + logger.info(requestTime); + logger.info(","); + } + logger.info("\"" + event.getIndex() + "\","); + for (int i = 0; i < event.getColumns().length; i++) { + Variable v = event.getColumns()[i].getVariable(); + String value = v.toString(); + switch (v.getSyntax()) { + case SMIConstants.SYNTAX_OCTET_STRING: { + StringBuffer escapedString = new StringBuffer(value.length()); + StringTokenizer st = new StringTokenizer(value, "\"", true); + while (st.hasMoreTokens()) { + String token = st.nextToken(); + escapedString.append(token); + if (token.equals("\"")) { + escapedString.append("\""); + } + } + } + case SMIConstants.SYNTAX_IPADDRESS: + case SMIConstants.SYNTAX_OBJECT_IDENTIFIER: + case SMIConstants.SYNTAX_OPAQUE: { + logger.info("\""); + logger.info(value); + logger.info("\""); + break; + } + default: { + logger.info(value); + } + } + if (i + 1 < event.getColumns().length) { + logger.info(","); + } + } + return true; + } + + public void finished(TableEvent event) { + synchronized (event.getUserObject()) { + event.getUserObject().notify(); + } + } + + } + + class TextTableListener implements TableListener { + + public void finished(TableEvent event) { + logger.info("Table walk completed with status " + event.getStatus() + + ". Received " + event.getUserObject() + " rows."); + synchronized (event.getUserObject()) { + event.getUserObject().notify(); + } + } + + public boolean next(TableEvent event) { + logger.info("Index = " + event.getIndex() + ":"); + for (int i = 0; i < event.getColumns().length; i++) { + logger.info(event.getColumns()[i]); + } + ((Counter32) event.getUserObject()).increment(); + return true; + } + + } + + // public static void main(String args[]) throws Exception { +// test(String args[]); +//} + +// private static void test(String args[]) throws Exception { +// try { +// /* +// * Initialize Log4J logging: if +// * (System.getProperty("log4j.configuration") == null) { +// * BasicConfigurator.configure(); } +// * Logger.getRootLogger().setLevel(Level.OFF); +// */ +// SnmpRequest snmpRequest = new SnmpRequest(args); +// if (snmpRequest.operation == SNAPSHOT_DUMP) { +// snmpRequest.dumpSnapshot(); +// } else { +// try { +// if (snmpRequest.operation == LISTEN) { +// snmpRequest.listen(); +// } else if ((snmpRequest.operation == TABLE) +// || (snmpRequest.operation == CVS_TABLE) +// || (snmpRequest.operation == TIME_BASED_CVS_TABLE)) { +// snmpRequest.table(); +// } else { +// PDU response = snmpRequest.send(); +// if ((snmpRequest.getPduType() == PDU.TRAP) +// || (snmpRequest.getPduType() == PDU.REPORT) +// || (snmpRequest.getPduType() == PDU.V1TRAP) +// || (snmpRequest.getPduType() == PDU.RESPONSE)) { +// logger.info(PDU.getTypeString(snmpRequest.getPduType()) +// + " sent successfully"); +// } else if (response == null) { +// if (snmpRequest.operation != WALK) { +// logger.info("Request timed out."); +// } +// } else if (response.getType() == PDU.REPORT) { +// printReport(response); +// } else if (snmpRequest.operation == DEFAULT) { +// logger.info("Response received with requestID=" +// + response.getRequestID() + ", errorIndex=" +// + response.getErrorIndex() + ", " + "errorStatus=" +// + response.getErrorStatusText() + "(" +// + response.getErrorStatus() + ")"); +// printVariableBindings(response); +// } else { +// logger.info("Received something strange: requestID=" +// + response.getRequestID() + ", errorIndex=" +// + response.getErrorIndex() + ", " + "errorStatus=" +// + response.getErrorStatusText() + "(" +// + response.getErrorStatus() + ")"); +// printVariableBindings(response); +// } +// } +// } catch (IOException ex) { +// logger.error("Error while trying to send request: " + ex.toString()); +// } +// } +// } catch (IllegalArgumentException iaex) { +// logger.error("Error: " + iaex.toString()); +// } +// } + + private void createSnapshot(List snapshot) { + FileOutputStream fos = null; + try { + fos = new FileOutputStream(snapshotFile); + ObjectOutputStream oos = new ObjectOutputStream(fos); + oos.writeObject(snapshot); + oos.flush(); + } catch (Exception ex) { + logger.info(ex.toString()); + } finally { + if (fos != null) { + try { + fos.close(); + } catch (IOException ex1) { + logger.error("Error: " + ex1.toString()); + } + } + } + } + +// private void dumpSnapshot() { +// FileInputStream fis = null; +// try { +// fis = new FileInputStream(snapshotFile); +// ObjectInputStream ois = new ObjectInputStream(fis); +// List l = (List) ois.readObject(); +// int i = 1; +// logger.info("Dumping snapshot file '" + snapshotFile + "':"); +// for (Iterator it = l.iterator(); it.hasNext(); i++) { +// logger.info("" + i + ": " + it.next()); +// } +// logger.info("Dumped " + l.size() + " variable bindings."); +// } catch (Exception ex) { +// logger.info("dumpSnapshot error"); +// } finally { +// if (fis != null) { +// try { +// fis.close(); +// } catch (IOException ex1) { +// logger.error("Error: " + ex1.toString()); +// } +// } +// } +// } + + public void setAddress(Address address) { + this.address = address; + } + + public void setVersion(int version) { + this.version = version; + } + + public void setVbs(Vector vbs) { + this.vbs = vbs; + } + + public void setUseDenseTableOperation(boolean useDenseTableOperation) { + this.useDenseTableOperation = useDenseTableOperation; + } + + public void setUpperBoundIndex(OID upperBoundIndex) { + this.upperBoundIndex = upperBoundIndex; + } + + public void setTrapOID(OID trapOID) { + this.trapOID = trapOID; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public void setTarget(Target target) { + this.target = target; + } + + public void setSysUpTime(TimeTicks sysUpTime) { + this.sysUpTime = sysUpTime; + } + + public void setSecurityName(OctetString securityName) { + this.securityName = securityName; + } + + public void setRetries(int retries) { + this.retries = retries; + } + + public void setPrivProtocol(OID privProtocol) { + this.privProtocol = privProtocol; + } + + public void setPrivPassphrase(OctetString privPassphrase) { + this.privPassphrase = privPassphrase; + } + + public void setPduType(int pduType) { + this.pduType = pduType; + } + + public void setOperation(int operation) { + this.operation = operation; + } + + public void setNumDispatcherThreads(int numDispatcherThreads) { + this.numDispatcherThreads = numDispatcherThreads; + } + + public void setNonRepeaters(int nonRepeaters) { + this.nonRepeaters = nonRepeaters; + } + + public void setMaxRepetitions(int maxRepetitions) { + this.maxRepetitions = maxRepetitions; + } + + public void setLowerBoundIndex(OID lowerBoundIndex) { + this.lowerBoundIndex = lowerBoundIndex; + } + + public void setContextName(OctetString contextName) { + this.contextName = contextName; + } + + public void setContextEngineID(OctetString contextEngineID) { + this.contextEngineID = contextEngineID; + } + + public void setCommunity(OctetString community) { + this.community = community; + } + + public void setAuthoritativeEngineID(OctetString authoritativeEngineID) { + this.authoritativeEngineID = authoritativeEngineID; + } + + public void setAuthProtocol(OID authProtocol) { + this.authProtocol = authProtocol; + } + + public void setAuthPassphrase(OctetString authPassphrase) { + this.authPassphrase = authPassphrase; + } + + class WalkCounts { + public int requests; + public int objects; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/codec/SnmpCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/codec/SnmpCodecFactory.java new file mode 100644 index 0000000..8d5cc48 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/codec/SnmpCodecFactory.java @@ -0,0 +1,26 @@ +package com.eactive.eai.adapter.socket2.protocol.snmp.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class SnmpCodecFactory implements ProtocolCodecFactory { + private ProtocolDecoder decoder; + + public SnmpCodecFactory(ISocketAdapter adapter) { + decoder = new SnmpDecoder(adapter); + } + + public SnmpCodecFactory() { + decoder = new SnmpDecoder(); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + throw new UnsupportedOperationException(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/codec/SnmpDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/codec/SnmpDecoder.java new file mode 100644 index 0000000..a1afaae --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/snmp/codec/SnmpDecoder.java @@ -0,0 +1,72 @@ +package com.eactive.eai.adapter.socket2.protocol.snmp.codec; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; +import org.snmp4j.PDU; +import org.snmp4j.asn1.BER; +import org.snmp4j.asn1.BERInputStream; +import org.snmp4j.smi.Integer32; +import org.snmp4j.smi.OctetString; + +import java.io.IOException; + +public class SnmpDecoder extends ProtocolDecoderAdapter { + protected final Logger logger; + //protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public SnmpDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + //errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public SnmpDecoder() { + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + //errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void decode(IoSession session, ByteBuffer buffer, ProtocolDecoderOutput protocolDecoderOutput) + throws Exception { + logger.info("SnmpDecoder | " + session + " "); + + java.nio.ByteBuffer pduBuffer = (java.nio.ByteBuffer) buffer.buf(); + + // decode the bytes using SNMP4J API + PDU pdu = new PDU(); + try (BERInputStream bis = new BERInputStream(pduBuffer)){ + BER.MutableByte mutableByte = new BER.MutableByte(); +// int length = BER.decodeHeader(bis, mutableByte); +// int startPos = (int) bis.getPosition(); + + if (mutableByte.getValue() != BER.SEQUENCE) { + String txt = "SNMPv2c PDU must start with SEQUENCE"; + throw new IOException(txt); + } + + Integer32 version = new Integer32(); + version.decodeBER(bis); + + //decode community string + OctetString securityName = new OctetString(); + securityName.decodeBER(bis); + + // decode the remaining PDU + pdu.decodeBER(bis); + logger.info("SnmpDecoder | PDU - " + pdu); + } catch(Exception e) { + logger.error("SnmpDecoder | error", e); + } + protocolDecoderOutput.write(pdu); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/stream/StreamFixedHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/stream/StreamFixedHandler.java new file mode 100644 index 0000000..a74fcfe --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/stream/StreamFixedHandler.java @@ -0,0 +1,80 @@ +package com.eactive.eai.adapter.socket2.protocol.stream; + +import org.apache.mina.common.IoSession; +import org.apache.mina.handler.StreamIoHandler; + +import java.io.*; + + +public class StreamFixedHandler extends StreamIoHandler { + protected void processStreamIo(IoSession session, InputStream in, OutputStream out) { + // You *MUST* execute stream I/O logic in a separate thread. + new Worker(in, out).start(); + } + + private static class Worker extends Thread { + private final InputStream in; + private final OutputStream out; + + public Worker(InputStream in, OutputStream out) { + setDaemon(true); + this.in = in; + this.out = out; + } + + @Override + public void run() { + + try ( + BufferedReader reader = new BufferedReader(new InputStreamReader(this.in)); + PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(this.out))); + ){ +// String url; +// Map headers = new TreeMap(); +// BufferedReader in = new BufferedReader(new InputStreamReader(this.in)); +// PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(this.out))); +// +// try { +// // Get request URL. +// url = in.readLine().split(" ")[1]; +// +// // Read header +// String line; +// while ((line = in.readLine()) != null && !line.equals("")) { +// String[] tokens = line.split(": "); +// headers.put(tokens[0], tokens[1]); +// } +// +// // Write header +// out.println("HTTP/1.0 200 OK"); +// out.println("Content-Type: text/html"); +// out.println("Server: MINA Example"); +// out.println(); +// +// // Write content +// out.println(""); +// out.println("

Request Summary for: " + url + "

"); +// out +// .println(""); +// +// Iterator it = headers.entrySet().iterator(); +// while (it.hasNext()) { +// Entry e = (Entry) it.next(); +// out.println(""); +// } +// +// out.println("
KeyValue
" + e.getKey() + "" +// + e.getValue() + "
"); +// +// for (int i = 0; i < 1024; i++) { +// out.println("this is line: " + i + "
"); +// } +// +// out.println(""); + writer.flush(); + } catch (Exception e) { +// System.out.println("Error"); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/stream/StreamFixedServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/stream/StreamFixedServer.java new file mode 100644 index 0000000..95a0383 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/stream/StreamFixedServer.java @@ -0,0 +1,22 @@ +package com.eactive.eai.adapter.socket2.protocol.stream; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.ack.AckServerFilter; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class StreamFixedServer extends TcpAdapterServer { + public StreamFixedServer(SocketAdapterContext context) throws Exception { + super(context); + + //this.handler = new StreamFixedHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + if ("Y".equals(context.getAckSupport())) { + config.getFilterChain().addAfter("codec", "ack", new AckServerFilter(this)); + } + } +} + diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/TcseedClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/TcseedClient.java new file mode 100644 index 0000000..383c303 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/TcseedClient.java @@ -0,0 +1,20 @@ +package com.eactive.eai.adapter.socket2.protocol.tcseed; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.tcseed.handshake.TcseedClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class TcseedClient extends TcpAdapterClient { + + public TcseedClient(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new TcseedHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "tcseed", new TcseedClientFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/TcseedHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/TcseedHandler.java new file mode 100644 index 0000000..050e10e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/TcseedHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.tcseed; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class TcseedHandler extends ProtocolHandler { + public TcseedHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/TcseedServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/TcseedServer.java new file mode 100644 index 0000000..4574993 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/TcseedServer.java @@ -0,0 +1,19 @@ +package com.eactive.eai.adapter.socket2.protocol.tcseed; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.tcseed.handshake.TcseedServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class TcseedServer extends TcpAdapterServer { + public TcseedServer(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new TcseedHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "tcseed", new TcseedServerFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/handshake/TcseedClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/handshake/TcseedClientFilter.java new file mode 100644 index 0000000..199a007 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/handshake/TcseedClientFilter.java @@ -0,0 +1,37 @@ +package com.eactive.eai.adapter.socket2.protocol.tcseed.handshake; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + + +public class TcseedClientFilter extends TcseedFilter { + public TcseedClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { + + case STATE_MESSAGE: + + byte[] decrypted = ts.Decrypt(m.getBytes()); + if (decrypted == null || decrypted.length == 0) { + throw new Exception("TcseedClientFilter received message is invalid - check if message is encrypted : " + m.hexDump()); + } + m.setBytes(decrypted); + + nextFilter.messageReceived(session, m); + + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/handshake/TcseedFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/handshake/TcseedFilter.java new file mode 100644 index 0000000..9ca8e21 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/handshake/TcseedFilter.java @@ -0,0 +1,100 @@ +package com.eactive.eai.adapter.socket2.protocol.tcseed.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; +import tcseed.tcseed; + +public abstract class TcseedFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + + private static final String NEXT_FILTER = TcseedFilter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = TcseedFilter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + + protected enum State { + STATE_HANDSHAKE, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = State.STATE_MESSAGE; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected tcseed ts = new tcseed(); + + protected TcseedFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + + /** + * tcseed init + */ + ts.Init_Key(context.getTcseedKeyStore()); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + if (parent.contains(TcseedFilter.class)) { + throw new IllegalStateException("A filter chain cannot contain more than one DesFilter."); + } + + IoSession session = parent.getSession(); + session.setAttribute(NEXT_FILTER, nextFilter); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + if (filterState.state == State.STATE_MESSAGE) { + byte[] encrypted = ts.Encrypt(m.getBytes()); + m = new ByteMessage(encrypted); + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/handshake/TcseedServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/handshake/TcseedServerFilter.java new file mode 100644 index 0000000..9e9b6c2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/tcseed/handshake/TcseedServerFilter.java @@ -0,0 +1,37 @@ +package com.eactive.eai.adapter.socket2.protocol.tcseed.handshake; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.common.IoSession; + + +public class TcseedServerFilter extends TcseedFilter { + public TcseedServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + switch (filterState.state) { + case STATE_MESSAGE: + + byte[] decrypted = ts.Decrypt(m.getBytes()); + if (decrypted == null || decrypted.length == 0) { + throw new Exception("TcseedServerFilter received message is invalid - check if message is encrypted : " + m.hexDump()); + } + + m.setBytes(decrypted); + + nextFilter.messageReceived(session, m); + + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/UdpClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/UdpClient.java new file mode 100644 index 0000000..a4142c3 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/UdpClient.java @@ -0,0 +1,28 @@ +package com.eactive.eai.adapter.socket2.protocol.udp; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.UdpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.ChunkCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.codec.FixedPayloadCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class UdpClient extends UdpAdapterClient { + public UdpClient(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new UdpHandler(this); + + if ("UDP_FIXED_LENGTH_HEADER".equals(context.getProtocol())) { + if ("NONE".equals(context.getLlFieldType())) { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new ChunkCodecFactory(this))); + } else { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + } + } else if ("UDP_FIXED_LENGTH_PAYLOAD".equals(context.getProtocol())) { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedPayloadCodecFactory(this))); + } else { + throw new Exception("invalid protocol in UDP category - " + context.getProtocol()); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/UdpHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/UdpHandler.java new file mode 100644 index 0000000..b7a88bd --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/UdpHandler.java @@ -0,0 +1,27 @@ +package com.eactive.eai.adapter.socket2.protocol.udp; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class UdpHandler extends ProtocolHandler { + +// typedef struct { +// char dgubun [ 4]; /* DATA구분 */ +// /* "IXIJ" : 업종지수 */ +// char upcode [ 3]; /* 업종코드 */ +// /* 001:코스피종합, 201:코스피200 */ +// /* 301:코스닥종합 */ +// char date [ 8]; /* 날짜 YYYYMMDD */ +// char time [ 6]; /* 시간 HHMMSS */ +// char jisu [ 8]; /* 지수 9(6)v9(2) */ +// char sign [ 1]; /* 부호 */ +// /* '+':상승 '-':하락 ' ':보합 */ +// char change [ 8]; /* 대비 9(6)v9(2) */ +// char drate [ 5]; /* 등락율 9(3)v9(2) */ +// char filler [20]; /* FILLER */ +//} + + public UdpHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/UdpServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/UdpServer.java new file mode 100644 index 0000000..c7cdab1 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/UdpServer.java @@ -0,0 +1,28 @@ +package com.eactive.eai.adapter.socket2.protocol.udp; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.UdpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.ChunkCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.codec.FixedPayloadCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class UdpServer extends UdpAdapterServer { + public UdpServer(SocketAdapterContext context) throws Exception { + super(context); + + this.handler = new UdpHandler(this); + + if ("UDP_FIXED_LENGTH_HEADER".equals(context.getProtocol())) { + if ("NONE".equals(context.getLlFieldType())) { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new ChunkCodecFactory(this))); + } else { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + } + } else if ("UDP_FIXED_LENGTH_PAYLOAD".equals(context.getProtocol())) { + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedPayloadCodecFactory(this))); + } else { + throw new Exception("invalid protocol in UDP category - " + context.getProtocol()); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/udp_sample.txt b/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/udp_sample.txt new file mode 100644 index 0000000..2e6f621 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/udp/udp_sample.txt @@ -0,0 +1,129 @@ +-------------------------------------------------------------------------------------------- +UdpServer.java +-------------------------------------------------------------------------------------------- +import java.io.*; +import java.net.*; +import java.util.*; + +public class UdpServer { + // 파일을 읽어 단어들을 어레이리스트에 담아 반환 한다. + public static ArrayList readFile() throws IOException { + ArrayList wordList = new ArrayList(); + BufferedReader fin = new BufferedReader(new FileReader("hello.txt")); + StringTokenizer st = new StringTokenizer(fin.readLine()); + + while(st.hasMoreTokens()) { + wordList.add(st.nextToken()); + } + + return wordList; + } + + public static void main (String[] args) { + DatagramSocket socket = null; // UDP소켓 + DatagramPacket out = null; // UDP패킷 전송 객체 + DatagramPacket in = null; // UDP패킷 수신 객체 + byte packetBuf[] = new byte[1024]; // 패킷 버퍼 + + if (args.length != 1) { + System.out.println("사용법: java UdpServer port"); + System.exit(0); + } + + try{ + // UDP 소켓을 생성해 지정된 포트에 바인딩 한다. + socket = new DatagramSocket(Integer.parseInt(args[0])); + + // 무한 루프를 돌려 UDP패킷을 수신 받는다. + while(true) { + // UDP패킷을 생성해 수신을 받는다. + in = new DatagramPacket(packetBuf, 1024); + socket.receive(in); + + // 수신지의 포트를 설정 한다. + int port = in.getPort(); + + // 수신지의 주소를 설정 한다. + InetAddress inet = in.getAddress(); + + // 읽어온 단어들을 이터레이터로 변환 한다. + Iterator iterator = readFile().iterator(); + + // 단어들을 읽어 들이기 위한 루프를 돌린다. + while(iterator.hasNext()) { + String word = (String)iterator.next(); + + // 단어들을 전송하기 위한 UDP패킷을 생성한다. + out = new DatagramPacket(word.getBytes(), word.length(), inet, port); + + // 전송한다. + socket.send(out); + + // 전송한 단어와 수신지의 주소를 출력한다. + System.out.println("send: word=" + word + " " + + "dest=" + inet.getHostAddress()); + } + } + } catch(Exception e) { + e.printStackTrace(); + } + } +} + +-------------------------------------------------------------------------------------------- +UdpClient.java +-------------------------------------------------------------------------------------------- +import java.net.*; +import java.io.*; + +public class UdpClient { + public static void main(String[] args) { + DatagramSocket socket = null; // UDP 소켓 + DatagramPacket out = null; // UDP 패킷 전송 객체 + DatagramPacket in = null; // UDP 패킷 수신 객체 + InetAddress serverInet = null; // 서버 주소 객체 + byte[] packetBuf = new byte[1024]; // 패킷 버퍼 + String word = null; // 단어 + + if(args.length != 2) { + System.out.println("사용법: java MyEcho hostname port(7)"); + System.exit(0); + } + + String host = args[0]; + int port = Integer.parseInt(aegs[1]); + + try{ + // UDP 소켓 생성 + socket = new DatagramSocket(); + + // 서버 주소 객체 생성 + serverInet = InetAddress.getByName(host); + + // UDP 패킷 전송 객체 생성 + out = new DatagramPacket(packetBuf, 2, serverInet, port); + + // UDP 패킷 수신 객체 생성 + in = new DatagramPacket(packetBuf, 1024); + + // UDP 공 패킷을 지정한 호스트로 전송한다. + socket.send(out); + + // 패킷을 받기 위해 루프를 돌린다. + while(true) { + // 패킷을 받는다. + socket.receive(in); + + // 받아온 패킷을 문자열로 변환 한다. 만약 수신된 데이터가 없다면 루프를 종료 한다. + if((word = new String(in.getData(), 0, in.getLength())) == null) break; + // 수신된 단어를 출력한다. + System.out.println("recv: " + word); + } + + // 소켓 닫기 + socket.close(); + } catch(Exception e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/VariableHeaderClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/VariableHeaderClient.java new file mode 100644 index 0000000..e65cfcb --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/VariableHeaderClient.java @@ -0,0 +1,27 @@ +package com.eactive.eai.adapter.socket2.protocol.variableheader; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.handshake.IgnoreFilter; +import com.eactive.eai.adapter.socket2.protocol.variableheader.codec.VariableHeaderCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class VariableHeaderClient extends TcpAdapterClient { + public VariableHeaderClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new VariableHeaderHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new VariableHeaderCodecFactory(this))); + + /** + * ignore PING(ACK) message + */ + config.getFilterChain().addAfter("codec", "ignore", new IgnoreFilter(this)); + } + + @Override + public Object sendMessage(Object message) throws EAIException { + return super.sendMessage(message); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/VariableHeaderHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/VariableHeaderHandler.java new file mode 100644 index 0000000..e97f92e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/VariableHeaderHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.variableheader; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class VariableHeaderHandler extends ProtocolHandler { + public VariableHeaderHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/VariableHeaderServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/VariableHeaderServer.java new file mode 100644 index 0000000..7b8e63a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/VariableHeaderServer.java @@ -0,0 +1,21 @@ +package com.eactive.eai.adapter.socket2.protocol.variableheader; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedpayload.handshake.IgnoreFilter; +import com.eactive.eai.adapter.socket2.protocol.variableheader.codec.VariableHeaderCodecFactory; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class VariableHeaderServer extends TcpAdapterServer { + public VariableHeaderServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new VariableHeaderHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new VariableHeaderCodecFactory(this))); + + /** + * ignore PING(ACK) message + */ + config.getFilterChain().addAfter("codec", "ignore", new IgnoreFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/codec/VariableHeaderCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/codec/VariableHeaderCodecFactory.java new file mode 100644 index 0000000..d31f9b0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/codec/VariableHeaderCodecFactory.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.variableheader.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class VariableHeaderCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + + public VariableHeaderCodecFactory(ISocketAdapter adapter) { + encoder = new VariableHeaderEncoder(adapter); + decoder = new VariableHeaderDecoder(adapter); + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/codec/VariableHeaderDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/codec/VariableHeaderDecoder.java new file mode 100644 index 0000000..3130d94 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/codec/VariableHeaderDecoder.java @@ -0,0 +1,290 @@ +package com.eactive.eai.adapter.socket2.protocol.variableheader.codec; + +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; + +public class VariableHeaderDecoder extends ProtocolDecoderAdapter { + protected final Logger logger; + protected final Logger errLogger; + + public static final int MAX_PAYLOAD_SIZE = 25 * 1024 * 1024; // 25MB + + private static final String DECODER_STATE_KEY = VariableHeaderDecoder.class.getName() + ".STATE"; + + private enum State { + STATE_HEADER_READ, STATE_PAYLOAD_READ; + } + + private static class CodecState { + State state = State.STATE_HEADER_READ; + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public VariableHeaderDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + + @SuppressWarnings("static-access") + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) throws Exception { + CodecState codecState = (CodecState) session.getAttribute(DECODER_STATE_KEY); + if (codecState == null) { + codecState = new CodecState(); + codecState.buffer.limit(context.getLlFieldOffset() + context.getLlFieldLength()); + session.setAttribute(DECODER_STATE_KEY, codecState); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + StringBuilder sb = new StringBuilder(); + sb.append("VariableHeaderDecoder"); + //sb.append(codecState.state); + if (codecState.state == State.STATE_PAYLOAD_READ) { + sb.append("(" + codecState.payloadSize + ")"); + } + sb.append(" | decode : " + CommonLib.hexDump(in, context)); + logger.debug(sb.toString()); + adapter.addRecentRecvTrace(session, sb.toString()); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + switch (codecState.state) { + case STATE_HEADER_READ: + if (readHeader(session, codecState, in)) { + /** + * payload size < 0 인 경우 + */ + if (codecState.payloadSize < 0) { + throw new EAIException("RECEAINNA008", context.getAdapterName() + + " (" + context.getLlFieldType() + "," + context.getLlFieldOffset() + "," + context.getLlFieldLength() + + ") | when read header, ll length field is invalid | " + CommonLib.hexDump(codecState.buffer, context)); + /** + * payload size == 0 인 경우 + */ + } else if (codecState.payloadSize == 0) { + if (context.isSync()) { + throw new Exception(" payload size 0 (ping). 'SYNC' response type socket does not support ping(size 0) message."); + } + + //codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_INFO ) { + logger.info(context.getAdapterName() + " | payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "payload size 0 (ping) -> ignore. - " + CommonLib.hexDump(in, context)); + } + + /** + * header 값을 읽은 후 buffer의 position을 이동해 준다. + * 이 작업을 안해주면 무한루프에 빠질 수 있다. + * 예) 법원 공탁금 (_LAW_IN_SOC_AsS{...}) + */ + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + break; + } + + /** + * ll.include = 'Y' - LL을 포함해서 넘긴다. + */ + if ("Y".equals(context.getLlInclude())) { + try { + codecState.buffer.position(context.getLlFieldOffset() + context.getLlFieldLength()) + .limit(codecState.payloadSize + context.getLlFieldLength()); + } catch(IllegalArgumentException e) { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); + sb.append("offset=" + context.getLlFieldOffset() + context.getLlFieldLength()); + sb.append(", limit=" + codecState.payloadSize + context.getLlFieldLength()); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA007"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + /** + * ll.include = 'N' - LL을 제외하고 넘긴다. + */ + } else { + try { + codecState.buffer.position(context.getLlFieldOffset()).limit(codecState.payloadSize); + } catch(IllegalArgumentException e) { + StringBuilder sb = new StringBuilder(); + sb.append(context.getAdapterName() + " | error when handling buffer | "); + sb.append("offset=" + context.getLlFieldOffset()); + sb.append(", limit=" + codecState.payloadSize); + logger.error(sb.toString()); + errLogger.error(sb.toString()); + adapter.addRecentError(sb.toString()); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA007"); + throw e; + } + } + + /** + * offset + ll 을 읽었고, 더 이상 읽을 것(payload)이 없는 경우 + * - ll.length value = ll.offset + ll.field.length + */ + if (codecState.buffer.position() == codecState.buffer.limit()) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + break; + } + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(context.getLlFieldOffset() + context.getLlFieldLength()); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + + break; + } + + session.setAttribute(ProtocolHandler.CODEC_STATE_BUFFER, CommonLib.hexDumpRead(codecState.buffer, context)); + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read header : " + in); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + if ("BIN".equals(context.getLlFieldType())) { + codecState.payloadSize = 0; + for (int i=0; i MAX_PAYLOAD_SIZE) { + throw new Exception("max payload size(" + MAX_PAYLOAD_SIZE + ") exceeded : " + + codecState.payloadSize + " | " + + CommonLib.hexDump(codecState.buffer, context)); + } + + /** + * ll.field.include = 'Y' - 헤더 길이를 빼 준다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + codecState.payloadSize = codecState.payloadSize - context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 더해서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + codecState.payloadSize = codecState.payloadSize + context.getLlFieldOffset(); + } + + /** + * recv.header.length - 가변 헤더 길이만큼 전체 길이를 더해서 length를 계산한다. + */ + codecState.payloadSize = codecState.payloadSize + context.getRecvHeaderLength(); + + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | read payload : " + in); + } + */ + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + return true; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/codec/VariableHeaderEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/codec/VariableHeaderEncoder.java new file mode 100644 index 0000000..9519fd5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/variableheader/codec/VariableHeaderEncoder.java @@ -0,0 +1,131 @@ +package com.eactive.eai.adapter.socket2.protocol.variableheader.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class VariableHeaderEncoder implements ProtocolEncoder { + protected final Logger logger; + protected final Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public VariableHeaderEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) throws Exception { + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + //****************************** + /** + * ll.include = 'Y' - 통째로 보낸다. + */ + if ("Y".equals(context.getLlInclude())) { + ByteBuffer buffer = ByteBuffer.allocate(m.size() - context.getLlFieldLength()); + buffer.put(m.getBytes(0, context.getLlFieldOffset())); + buffer.put(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + buffer.flip(); + m.setByteBuffer(buffer); + } + + + int length = m.size(); + ByteBuffer buffer = ByteBuffer.allocate(context.getLlFieldLength() + length).limit(context.getLlFieldLength() + length); + + /** + * ll.field.include = 'Y' - header 길이 포함하여 ll 을 계산한다. + */ + if ("Y".equals(context.getLlFieldInclude())) { + length = length + context.getLlFieldLength(); + } + + /** + * ll.offset.exclude = 'Y' - offset 만큼의 크기를 빼서 length를 계산한다. + */ + if ("Y".equals(context.getLlOffsetExclude())) { + length = length - context.getLlFieldOffset(); + } + + /** + * send.header.length - 가변 헤더 길이만큼 전체 길이를 빼서 length를 계산한다. + */ + length = length - context.getSendHeaderLength(); + + + /** + * [1] before-payload + */ + buffer.put(m.getBytes(0, context.getLlFieldOffset())); + + /** + * [2] write header + */ + if ("BIN".equals(context.getLlFieldType())) { + int tmpLength = length; + byte[] header = new byte[context.getLlFieldLength()]; + for (int i = context.getLlFieldLength()-1; i>=0; i--) { + header[i] = (byte) (tmpLength % 256); + tmpLength = tmpLength / 256; + } + buffer.put(header); + } else { // "CHAR" + + String lenStr = CommonLib.getFormatString(length, context.getLlFieldLength()); + buffer.put(lenStr.getBytes()); + + } + /** + * [3] after-payload + */ + buffer.put(m.getBytes(context.getLlFieldOffset(), m.getBytes().length - context.getLlFieldOffset())); + + + + //***************************** by-Pass용 로직 + // ByteBuffer buffer = ByteBuffer.allocate(m.size()).limit(m.size()); + // buffer.put(m.getBytes()); + + + /** + * write + */ + int mark = buffer.position(); + buffer.position(0); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | VariableHeaderEncoder | encode : " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, "VariableHeaderEncoder | encode : " + CommonLib.hexDump(buffer, context)); + } + buffer.position(mark); + buffer.flip(); + out.write(buffer); + out.flush(); + } + + + public void dispose(IoSession session) throws Exception { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbClient.java new file mode 100644 index 0000000..043df4e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbClient.java @@ -0,0 +1,19 @@ +package com.eactive.eai.adapter.socket2.protocol.xc3epb; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xc3epb.handshake.Xc3EpbClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class Xc3EpbClient extends TcpAdapterClient { + + public Xc3EpbClient(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new Xc3EpbHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + + config.getFilterChain().addAfter("codec","xc3epb.fixed", new Xc3EpbClientFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbConstants.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbConstants.java new file mode 100644 index 0000000..be61114 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbConstants.java @@ -0,0 +1,13 @@ +package com.eactive.eai.adapter.socket2.protocol.xc3epb; + + +public class Xc3EpbConstants { + public static final int LL_FIELD_LENGTH = 8; + public static final int HEADER_LENGTH = 2; + public static final int MESSAGE_TYPE_OFFSET = 0; + public static final int ENCRYPTED_YN_OFFSET = 1; + + private Xc3EpbConstants() { + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbHandler.java new file mode 100644 index 0000000..d17413f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.xc3epb; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class Xc3EpbHandler extends ProtocolHandler { + public Xc3EpbHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbServer.java new file mode 100644 index 0000000..c4b604f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/Xc3EpbServer.java @@ -0,0 +1,19 @@ +package com.eactive.eai.adapter.socket2.protocol.xc3epb; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xc3epb.handshake.Xc3EpbServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class Xc3EpbServer extends TcpAdapterServer { + + public Xc3EpbServer(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new Xc3EpbHandler(this); + + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + + config.getFilterChain().addAfter("codec","xc3epb.fixed", new Xc3EpbServerFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/handshake/Xc3EpbClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/handshake/Xc3EpbClientFilter.java new file mode 100644 index 0000000..066f353 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/handshake/Xc3EpbClientFilter.java @@ -0,0 +1,238 @@ +package com.eactive.eai.adapter.socket2.protocol.xc3epb.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xc3epb.Xc3EpbConstants; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; + + +public class Xc3EpbClientFilter extends Xc3EpbFilter { + public Xc3EpbClientFilter(ISocketAdapter adapter) { + super(adapter); + } + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_KEYINIT; + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + XC_v3 xc = new XC_v3(); + xc.init(context.getXc3epbPassword(), context.getXc3epbConfigPath(), 1);//MODE 1 (client) + session.setAttribute(XC3_SESSION_KEY, xc); + process(nextFilter, session, null); + } + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + process(nextFilter, session, m); + } + public void process(NextFilter nextFilter, IoSession session, Object message) throws Exception { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + + try { + XC_v3 xc = (XC_v3) session.getAttribute(XC3_SESSION_KEY); + + switch (filterState.state) { + case STATE_KEYINIT: + byte[] keyInit = xc.keyinitBin(); + + ByteMessage mKeyInit = new ByteMessage() + .append("S".getBytes()) + .append("Y".getBytes()) + .append(keyInit); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xc3EpbClientFilter | key init " + filterState.state.toString() + " | " + mKeyInit.hexDump()); + adapter.addRecentSendTrace(session, context.getAdapterName() + " | Xc3EpbClientFilter | key init " + filterState.state.toString() + " | " + mKeyInit.hexDump()); + } + + session.write(mKeyInit); + + filterState.state = State.STATE_KEYFINAL; + session.setAttribute(FILTER_STATE_KEY, filterState); + break; + case STATE_KEYFINAL: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xc3EpbClientFilter | " + filterState.state.toString() + " | " + m.hexDump()); + adapter.addRecentRecvTrace(session, context.getAdapterName() + " | Xc3EpbClientFilter | " + filterState.state.toString() + " | " + m.hexDump()); + } + /** + * 메시지구분 [0|1] : S(세션키교환) / D (표준전문) / P (폴링) + * 암화화여부 [1|1] : Y(세션키로 암호화된 메시지) / N (평문메시지) + */ + String messageType = new String(m.getBytes(Xc3EpbConstants.MESSAGE_TYPE_OFFSET, 1)); + String encryptedYn = new String(m.getBytes(Xc3EpbConstants.ENCRYPTED_YN_OFFSET, 1)); + + if("S".equals(messageType)){ + filterState.state = State.STATE_HANDSHAKE; + }else if ("D".equals(messageType)){ + filterState.state = State.STATE_MESSAGE; + }else{ + throw new Exception("not support message type ("+messageType+")"); + } + session.setAttribute(FILTER_STATE_KEY, filterState); + + boolean isEncrypted = false; + if ("Y".equals(encryptedYn)){ + isEncrypted = true; + }else if ("N".equals(encryptedYn)){ + isEncrypted = false; + }else { + throw new Exception("not support encrypted code ("+encryptedYn+")"); + } + session.setAttribute(ENCRYPTED_YN_KEY,isEncrypted); + + byte[] keydata = m.getBytes(2); + int ret = xc.keyFinal(keydata); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xc3EpbClientFilter | ret " + ret +" "+ filterState.state.toString() + " | " + new ByteMessage(keydata).hexDump()); + adapter.addRecentSend(session, context.getAdapterName() + " | Xc3EpbClientFilter | ret " + ret +" "+ filterState.state.toString() + " | " + new ByteMessage(keydata).hexDump()); + } + if (ret == 300){ + byte[] retryKeyInit = xc.keyinitBin(); + ByteMessage mRetryKeyInit = new ByteMessage() + .append("S".getBytes()) + .append("Y".getBytes()) + .append(retryKeyInit); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xc3EpbClientFilter | retry key init " + filterState.state.toString() + " | " + mRetryKeyInit.hexDump()); + adapter.addRecentSend(session, context.getAdapterName() + " | Xc3EpbClientFilter | retry key init " + filterState.state.toString() + " | " + mRetryKeyInit.hexDump()); + } + session.write(mRetryKeyInit); + filterState.state = State.STATE_KEYINIT; + session.setAttribute(FILTER_STATE_KEY, filterState); + }else{ + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + filterState.state = State.STATE_MESSAGE; + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + + break; + + case STATE_MESSAGE: + m = decrypt(m, session); + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake | " + m.hexDump()); + } + + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | xc3epb error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | xc3epb error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | xc3epb error - " + e.getMessage(), e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + adapter.getSessionPool().remove(session); + session.close(); + + throw new Exception(context.getAdapterName() + " | xc3epb error - " + e.getMessage()); + } + } + @SuppressWarnings("static-access") + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XC3EpbFilter | " + filterState.state.toString() + " | " + m.hexDump()); + } + + try { + switch (filterState.state) { + case STATE_KEYINIT : + case STATE_KEYFINAL : + case STATE_HANDSHAKE : + + break; + case STATE_MESSAGE: + m = encrypt(m, session); + break; + default : + break; + + } + + + + } catch(XCException xce) { + adapter.addRecentError(context.getAdapterName() + " | xc3epb error - " + xce.getMessage(), xce); + logger.error(context.getAdapterName() + " | xc3epb error - " + xce.getMessage(), xce); + errLogger.error(context.getAdapterName() + " | xc3epb error - " + xce.getMessage(), xce); + throw new XCException(context.getAdapterName() + " | xc3epb error - " + xce.getMessage()); + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + protected ByteMessage encrypt(ByteMessage m, IoSession session) throws Exception { + + ByteMessage em = new ByteMessage(); +// if (context.isPollingUse() && isPollingPattern(m)) { +// //메시지구분/암호화여부추가 +// em.append("P".getBytes()).append("Y".getBytes()); +// }else{ +// //메시지구분/암호화여부추가 +// em.append("D".getBytes()).append("Y".getBytes()); +// } + + XC_v3 xc = (XC_v3) session.getAttribute(XC3_SESSION_KEY); + byte[] encrypted = xc.encode(m.getBytes(2)); + em.append(m.getBytes(0,2)); + em.append(encrypted); + return em; + } + protected ByteMessage decrypt(ByteMessage m, IoSession session) throws Exception { + /** + * 암호화 여부 체크 + */ + if ('Y' != m.getByte(Xc3EpbConstants.ENCRYPTED_YN_OFFSET)){ + ByteMessage dm = new ByteMessage(m.getBytes(2)); + return dm; + } + + XC_v3 xc = (XC_v3) session.getAttribute(XC3_SESSION_KEY); + + byte[] decrypted = xc.decode(m.getBytes(2)); + + ByteMessage dm = new ByteMessage(m.getBytes(0,2)); + dm.append(decrypted); + + if(context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE){ + logger.debug(context.getAdapterName() + " | Xc3EpbFilter | decrypt " + dm.hexDump()); + } + return dm; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/handshake/Xc3EpbFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/handshake/Xc3EpbFilter.java new file mode 100644 index 0000000..7336f81 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/handshake/Xc3EpbFilter.java @@ -0,0 +1,78 @@ +package com.eactive.eai.adapter.socket2.protocol.xc3epb.handshake; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; + + +public abstract class Xc3EpbFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + + protected static final String ENCODING = "UTF-8"; + + private static final String NEXT_FILTER = Xc3EpbFilter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = Xc3EpbFilter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + protected static final String XC3_SESSION_KEY = "XC3_SESSION_KEY"; + protected static final String ENCRYPTED_YN_KEY = "ENCRYPTED_YN_KEY"; + protected static final String TERMINAL_KEY = "TERMINAL_KEY"; + + protected enum State { + STATE_KEYINIT, + STATE_KEYFINAL, + STATE_HANDSHAKE, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = State.STATE_MESSAGE; //State.STATE_HANDSHAKE; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + public Xc3EpbFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + +// @Override +// public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { +// if (parent.contains(Xc3EpbFilter.class)) { +// throw new IllegalStateException("A filter chain cannot contain more than one Xc3EbpFilter."); +// } +// +// IoSession session = parent.getSession(); +// session.setAttribute(NEXT_FILTER, nextFilter); +// } + + public boolean isPollingPattern(ByteMessage m) throws Exception { + ByteMessage bm = m; + if ("Y".equals(context.getLlInclude())) { + bm = (new ByteMessage()) + .append(m.getBytes(0, context.getLlFieldOffset())) + .append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + } + + if ((context.isPollingReceiver() && bm.getString().matches(context.getPollingResponsePattern())) + || (context.isPollingSender() && bm.getString().matches(context.getPollingRequestPattern()))) + return true; + + return false; + } + +// protected void setSessionState(IoSession session, String state) { +// session.setAttribute(SESSION_STATE, state); +// } +// +// protected String getSessionState(IoSession session) { +// return (String) session.getAttribute(SESSION_STATE); +// } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/handshake/Xc3EpbServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/handshake/Xc3EpbServerFilter.java new file mode 100644 index 0000000..d20d713 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xc3epb/handshake/Xc3EpbServerFilter.java @@ -0,0 +1,378 @@ +package com.eactive.eai.adapter.socket2.protocol.xc3epb.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xc3epb.Xc3EpbConstants; +import com.eactive.eai.common.message.ExtMessageKeys; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.property.PropertyLoginKeys; +import com.eactive.eai.common.session.TerminalVO; +import com.eactive.eai.common.util.ContainerUtil; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.util.Properties; + + +public class Xc3EpbServerFilter extends Xc3EpbFilter { + public Xc3EpbServerFilter(ISocketAdapter adapter) { + super(adapter); + } + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_HANDSHAKE; + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + if (ContainerUtil.get() != ContainerUtil.TOMCAT) { + XC_v3 xc = new XC_v3(); + xc.init(context.getXc3epbPassword(), context.getXc3epbConfigPath(), 2);//MODE 2 (server) + session.setAttribute(XC3_SESSION_KEY, xc); + } + + nextFilter.sessionOpened(session); + + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | xc3 init error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | xc3 init error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | xc3 init error - " + e.getMessage(), e); + + try { + adapter.getSessionPool().remove(session); + session.close(); + } catch(Exception ignor) { + logger.warn("session.close", ignor); + } + + throw new Exception(context.getAdapterName() + " | xc3 init error - " + e.getMessage()); + } + } + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + process(nextFilter, session, m); + } + + public void process(NextFilter nextFilter, IoSession session, Object message) throws Exception { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + /** + * set state offset , length : value + * 메시지구분 [0 |1 ] : S(세션키교환) / D (표준전문) / P (폴링) / E(장애전문) + * 암화화여부 [1 |1 ] : Y(세션키로 암호화된 메시지) / N (평문메시지) + */ + String messageType = new String(m.getBytes(Xc3EpbConstants.MESSAGE_TYPE_OFFSET, 1)); + String encryptedYn = new String(m.getBytes(Xc3EpbConstants.ENCRYPTED_YN_OFFSET, 1)); + + + if("S".equals(messageType)){ + filterState.state = State.STATE_HANDSHAKE; + }else if ("P".equals(messageType)){ + filterState.state = State.STATE_MESSAGE; + }else if ("D".equals(messageType) || "E".equals(messageType)){ + String type = (String)session.getAttribute("messageType"); + if (type != null){ + //오류 + throw new Exception("messageType exist " + type); + } + session.setAttribute("messageType", messageType); + filterState.state = State.STATE_MESSAGE; + }else{ + throw new Exception("not support message type ("+messageType+")"); + } + session.setAttribute(FILTER_STATE_KEY, filterState); + + String oldEncryptedYn = (String)session.getAttribute(ENCRYPTED_YN_KEY); + + try { + if (oldEncryptedYn != null && !oldEncryptedYn.equals(encryptedYn)){ + throw new Exception("change encrypted yn "); + } + + if ("Y".equals(encryptedYn)){ + ; + }else if ("N".equals(encryptedYn)){ + ; + }else { + throw new Exception("not support encrypted code ("+encryptedYn+")"); + } + session.setAttribute(ENCRYPTED_YN_KEY,encryptedYn); + + + switch (filterState.state) { + case STATE_HANDSHAKE: + XC_v3 xc = (XC_v3) session.getAttribute(XC3_SESSION_KEY); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | Xc3EpbServerFilter | " + filterState.state.toString() + " | " + m.hexDump()); + adapter.addRecentRecvTrace(session, context.getAdapterName() + " | Xc3EpbServerFilter | key init " + filterState.state.toString() + " | " + m.hexDump()); + } + byte[] finalKey = xc.keyFinal(m.getBytes(2),null); + + ByteMessage keyFinal = new ByteMessage().append(m.getBytes(0, 2)).append(finalKey); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE && m != null) { + logger.debug(context.getAdapterName() + " | Xc3EpbServerFilter | key final " + filterState.state.toString() + " | " + keyFinal.hexDump()); + adapter.addRecentSendTrace(session, context.getAdapterName() + " | Xc3EpbServerFilter | key final " + filterState.state.toString() + " | " + keyFinal.hexDump()); + } + + session.write(keyFinal.getBytes()); + + break; + + case STATE_MESSAGE: + m = decrypt(m, session); + if (!"P".endsWith(messageType)){ + recvParsing(m.getBytes(),session); + } + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake | " + m.hexDump()); + } + + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | xc3epb error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | xc3epb error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | xc3epb error - " + e.getMessage(), e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + adapter.getSessionPool().remove(session); + session.close(); + + throw new Exception(context.getAdapterName() + " | xc3epb error - " + e.getMessage()); + } + } + @SuppressWarnings("static-access") + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XC3EpbFilter | " + filterState.state.toString() + " | " + m.hexDump()); + } + + try { + switch (filterState.state) { + case STATE_KEYINIT : + case STATE_KEYFINAL : + case STATE_HANDSHAKE : + + break; + case STATE_MESSAGE: + /** + * check polling message - skip polling + */ + sendParsing(m.getBytes(), session); + m = encrypt(m, session); + break; + default : + break; + + } + + } catch(XCException xce) { + adapter.addRecentError(context.getAdapterName() + " | xc3epb error - " + xce.getMessage(), xce); + logger.error(context.getAdapterName() + " | xc3epb error - " + xce.getMessage(), xce); + errLogger.error(context.getAdapterName() + " | xc3epb error - " + xce.getMessage(), xce); + throw new XCException(context.getAdapterName() + " | xc3epb error - " + xce.getMessage()); + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + protected ByteMessage encrypt(ByteMessage m, IoSession session) throws Exception { + //bytemessage에는 업무데이터만 있음 + + String encryptedYn = (String)session.getAttribute(ENCRYPTED_YN_KEY); + + ByteMessage em = new ByteMessage(); + + if (context.isPollingUse() && isPollingPattern(m)) { + //메시지구분/암호화여부추가 + em.append("P".getBytes()).append(encryptedYn.getBytes()); + }else{ + String type = (String)session.removeAttribute("messageType"); + if (type == null){ + //오류 + throw new Exception("messageType empty"); + } + //메시지구분/암호화여부추가 + em.append(type.getBytes()).append(encryptedYn.getBytes()); + } + /** + * 암호화 여부 체크 + */ + if ("Y".equals(encryptedYn) ){ + XC_v3 xc = (XC_v3) session.getAttribute(XC3_SESSION_KEY); + byte[] encrypted = xc.encode(m.getBytes()); + em.append(encrypted); + + }else{ + em.append(m.getBytes()); + } + + return em; + } + protected ByteMessage decrypt(ByteMessage m, IoSession session) throws Exception { + /** + * 암호화 여부 체크 + */ + if ('Y' != m.getByte(Xc3EpbConstants.ENCRYPTED_YN_OFFSET)){ + ByteMessage dm = new ByteMessage(m.getBytes(2)); + return dm; + } + + XC_v3 xc = (XC_v3) session.getAttribute(XC3_SESSION_KEY); + + byte[] decrypted = xc.decode(m.getBytes(2)); + + ByteMessage dm = new ByteMessage(decrypted); + if(context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE){ + logger.debug(context.getAdapterName() + " | Xc3EpbFilter | decrypt " + dm.hexDump()); + } + return dm; + } + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { +// TerminalVO vo = (TerminalVO)session.getAttribute(TERMINAL_KEY); +// if (vo != null){ +// try{ +// SessionManager.getInstance().removeTerminal(vo.getTerminalNo()); +// }catch(Exception e){ +// logger.error("sessionManager error",e); +// } +// } + nextFilter.sessionClosed(session); + } + /** + * 요청 과 응답 분리 + * 분리될경우 요청에서 세션을 넣고 응답에서 셋션을 꺼낸다음 응답에서 ehcache에 넣어야됨 + * 2번 파싱하는건 + * 1. 거래일경우 표준전문의 서비스ID 추출 + * 2. 개국거래일경우 국코드,청코드 추출 + * + * @param data + */ + private void recvParsing(byte[] data, IoSession session){ + PropManager pManager = PropManager.getInstance(); + Properties prop = pManager.getProperties(PropertyLoginKeys.BEGIN); + String ATM = prop.getProperty(PropertyLoginKeys.BEGIN_SERVICE_ID_ATM); + String UNMANNED = prop.getProperty(PropertyLoginKeys.BEGIN_SERVICE_ID_UNMANNED); + String ROFC_CD = ""; + String BRN_CD = ""; + String terminalNo = ""; + try{ + JSONObject requestJson = (JSONObject) JSONValue.parse(new String(data,ENCODING)); + JSONObject headerJson = (JSONObject) requestJson.get(ExtMessageKeys.GROUP_HEADER); + JSONObject systemHeaderJson = (JSONObject) headerJson.get(ExtMessageKeys.GROUP_STD_HEADER); + String serviceId = (String) systemHeaderJson.get(ExtMessageKeys.FIELD_SERVICE_ID); + + logger.debug("Xc3EpbServerFilter] serviceId = " + serviceId); + if (ATM.equals(serviceId) || UNMANNED.equals(serviceId)){//개국거래일경우 + JSONObject commonHeaderJson = (JSONObject) headerJson.get(ExtMessageKeys.GROUP_STD_COMMON); + terminalNo = (String) commonHeaderJson.get(ExtMessageKeys.FIELD_DLNG_TMNL_NO);// 로그인거래 와 다를경우 확인필요 + + ROFC_CD = (String) commonHeaderJson.get(ExtMessageKeys.FIELD_ROFC_CD); + BRN_CD = (String) commonHeaderJson.get(ExtMessageKeys.FIELD_BRN_CD); + TerminalVO vo = new TerminalVO(); + vo.setTerminalNo(terminalNo); + vo.setRofcCd(ROFC_CD); + vo.setBrncd(BRN_CD); + vo.setOpenTran(true); + session.setAttribute(TERMINAL_KEY,vo); + logger.debug("set terminl vo=" + vo); + }else{//개국이외의 거래 + TerminalVO vo = (TerminalVO)session.getAttribute(TERMINAL_KEY); + if (vo == null || !vo.isOpen()){ // 개국전에 들어왔을경우 + logger.error("before open tran close session"); + session.close(); + } + } + }catch(Exception e){ + logger.error("recvParsing error "+e.getMessage(),e); + } + + } + private void sendParsing(byte[] data, IoSession session) throws Exception{ + if (context.isPollingUse() && isPollingPattern(new ByteMessage(data))) { + return; + } + TerminalVO vo = (TerminalVO)session.getAttribute(TERMINAL_KEY); + if (vo == null) { + session.close(); + logger.error("session vo null" ); + return; + } + boolean isOpenTran = vo.isOpenTran(); + if (isOpenTran){ + try{ + JSONObject requestJson = (JSONObject) JSONValue.parse(new String(data,ENCODING)); + JSONObject headerJson = (JSONObject) requestJson.get(ExtMessageKeys.GROUP_HEADER); + JSONObject systemHeaderJson = (JSONObject) headerJson.get(ExtMessageKeys.GROUP_STD_HEADER); //20220405 + String responseType = (String) systemHeaderJson.get(ExtMessageKeys.FIELD_RSPNS_RSLT_DVSN_CD); + + logger.debug("Xc3EpbServerFilter] responseType = " + responseType); +// if(STDMessage.RESPONSE_TYPE_CODE_N.contentEquals(responseType)) {//정상 +// EAIServerManager eaiServerManager = EAIServerManager.getInstance(); +// String serverName = eaiServerManager.getLocalServerName(); +// TerminalInfoVO terminalInfoVO = new TerminalInfoVO(vo.getTerminalNo()); +// terminalInfoVO.setBrnCode(vo.getBrncd()); +// terminalInfoVO.setRofcCode(vo.getRofcCd()); +// terminalInfoVO.setSocInstance(serverName); +// terminalInfoVO.setSocRemoteAddr(session.getRemoteAddress().toString()); +// terminalInfoVO.setSocSessionStatus(TerminalInfoVO.Status.active); +// terminalInfoVO.setCreateTime(DatetimeUtil.getCurrentDateTime()); +// try{ +// SessionManager.getInstance().putTerminal(vo.getTerminalNo(), vo, terminalInfoVO); +// }catch(Exception e){ +// logger.error("sessionManager error",e); +// } +// vo.setOpen(true); +// }else{ +// //SessionManager.getInstance().removeTerminal(vo.getTerminalNo()); +// //session.close(); +// vo.setOpen(false); +// } + vo.setOpenTran(false);//개국거래 종료로 false로 셋팅 + session.setAttribute(TERMINAL_KEY,vo); + }catch(Exception e){ + logger.error("sendParsing error "+e.getMessage(),e); + } + } + + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureClient.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureClient.java new file mode 100644 index 0000000..4b4010e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureClient.java @@ -0,0 +1,63 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xecure.envelope.XecureEnvelopeFilter; +import com.eactive.eai.adapter.socket2.protocol.xecure.fixed.handshake.XecureFixedClientFilter; +import com.eactive.eai.adapter.socket2.protocol.xecure.fixedheader.handshake.XecureFixedHeaderClientFilter; +import com.eactive.eai.adapter.socket2.protocol.xecure.welcome.codec.XecureWelcomeCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xecure.welcome.handshake.XecureWelcomeClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class XecureClient extends TcpAdapterClient { + + public XecureClient(SocketAdapterContext context) throws Exception { + super(context); + + if ("BASIC".equals(context.getXecureType())) { + context.setLlFieldType("CHAR"); + context.setLlFieldOffset(0); + context.setLlFieldLength(7); + context.setLlFieldInclude("N"); + context.setLlOffsetExclude("N"); + context.setLlInclude("Y"); + } else if ("WELCOME".equals(context.getXecureType())) { + context.setLlFieldType("CHAR"); + context.setLlFieldOffset(0); + context.setLlFieldLength(4); + context.setLlFieldInclude("Y"); + context.setLlOffsetExclude("N"); + context.setLlInclude("Y"); + } else if ("FIXEDHEADER".equals(context.getXecureType())) { + context.setLlFieldType("CHAR"); + context.setLlFieldOffset(0); + context.setLlFieldLength(7); + context.setLlFieldInclude("N"); + context.setLlOffsetExclude("N"); + context.setLlInclude("Y"); + } + + if ("FIXED".equals(context.getXecureType()) || "BASIC".equals(context.getXecureType())) { + this.handler = new XecureHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "xecure.fixed", new XecureFixedClientFilter(this)); + } else if ("ENVELOPE".equals(context.getXecureType())) { + this.handler = new XecureHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "xecure.fixed", new XecureFixedClientFilter(this)); + config.getFilterChain().addAfter("xecure.fixed", "xecure.envelope", new XecureEnvelopeFilter(this)); + } else if ("WELCOME".equals(context.getXecureType())) { + this.handler = new XecureHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new XecureWelcomeCodecFactory(this))); + config.getFilterChain().addAfter("codec", "xecure.welcome", new XecureWelcomeClientFilter(this)); + } else if ("FIXEDHEADER".equals(context.getXecureType())) { + this.handler = new XecureHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "xecure.fixedheader", new XecureFixedHeaderClientFilter(this)); + } else { + throw new Exception(context.getAdapterName() + " | UNKNOWN Xecure Type - " + context.getXecureType()); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureConstants.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureConstants.java new file mode 100644 index 0000000..9f14340 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureConstants.java @@ -0,0 +1,20 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure; + + +public class XecureConstants { + public static final String XECURE = "XECURE"; + public static final byte[] WELCOME = "|0001|THIS IS LOTTO DELIVERY DAEMON v1.0|".getBytes(); + //public static final String WELCOME = "2 |0001|THIS IS LOTTO DELIVERY DAEMON v1.0|"; + public static final byte[] KEY_INIT_MESSAGE = "KEY_INIT".getBytes(); + public static final byte[] KEY_FINAL_MESSAGE = "KEY_FINAL".getBytes(); + + + public static final int HEADER_LENGTH = 7 + 1 + 16; // (7) total size (1) security type (16) 판매점 아이디 + public static final int TAIL_LENGTH = 2; + + public static final String CODEC_KEY = "XECURE_CODEC_KEY"; + + public static final String FIXED_HEADER_HANDSHAKE = "XC100|"; // SGNG_넘버스4 전문구분 - Xecure Connect Session Key Share + public static final String FIXED_HEADER_MESSAGE = "XC200|"; // SGNG_넘버스4 전문구분 - 암호화된 평문 전문 전체(헤더+바디) + public static final int FIXED_HEADER_PART_LEHGTH = 6; // SGNG_넘버스4 전문구분(5) +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureErrorMessage.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureErrorMessage.java new file mode 100644 index 0000000..2081f4d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureErrorMessage.java @@ -0,0 +1,255 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure; + +import java.util.Hashtable; + + +public class XecureErrorMessage { + static Hashtable hash = new Hashtable(); + + static { + //-------------------------------------------------------------------------------- + //Exp Library Internal Error + //-------------------------------------------------------------------------------- + hash.put("-10", "ERR_EXP_INTERNAL | 내부함수(EXP) 호출 오류. 개발자에게 문의하세요."); + + //-------------------------------------------------------------------------------- + //XTU Library Internal Error + //-------------------------------------------------------------------------------- + hash.put("-11", "ERR_XTU_INTERNAL | 내부함수(XTU) 호출 오류. 개발자에게 문의하세요."); + + //-------------------------------------------------------------------------------- + //Invalid O/S Error + //-------------------------------------------------------------------------------- + hash.put("-12", "ERR_NOT_COMPILED_FOR_UNIX | 윈도우즈 환경에서만 지원되는 함수입니다."); + + //-------------------------------------------------------------------------------- + //Verifies Client Certificate + //-------------------------------------------------------------------------------- + hash.put("-101", "ERR_TRINITY_INVALID_CERT_LEN | 인증서 길이가 올바르지 않습니다."); + hash.put("-102", "ERR_TRINITY_INVALID_CERTTYPE | 지원하지 않는 인증서 타입입니다."); + hash.put("-103", "ERR_TRINITY_CONNECT_FAIL | RA 클라이언트 프로그램과의 접속에 실패했습니다."); + hash.put("-104", "ERR_TRINITY_SEND_FAIL | RA 클라이언트로 메시지 전송에 실패했습니다."); + hash.put("-105", "ERR_TRINITY_RECV_FAIL | RA 클라이언트로부터 메시지 수신에 실패했습니다."); + hash.put("-106", "ERR_TRINITY_REVOKED | 인증서가 폐기되었습니다."); + hash.put("-107", "ERR_TRINITY_SUSPENDED | 사용이 정지된 인증서입니다."); + hash.put("-108", "ERR_TRINITY_INVALID_CERT | 인증서가 존재하지 않거나 잘못된 인증서입니다."); + hash.put("-109", "ERR_TRINITY_RA_INTERNAL | RA 클라이언트 내부오류."); + hash.put("-110", "ERR_TRINITY_INVALID_RESULT | RA 클라이언트로부터의 결과오류"); + hash.put("-111", "ERR_TRINITY_AUTH_FAIL | 사용자 인증 실패"); + hash.put("-112", "ERR_TRINITY_RMP_INTERNAL | TRINITY 내부오류입니다."); + + //-------------------------------------------------------------------------------- + //For client library + //-------------------------------------------------------------------------------- + hash.put("-201", "ERR_CLIENT_INVALID_CERTFILE | 인증서 데이터가 올바르지 않습니다. 인증서 파일 내용을 확인해 보세요."); + + //-------------------------------------------------------------------------------- + //Set config parameters + //-------------------------------------------------------------------------------- + hash.put("-301", "ERR_CONFIG_LOAD_FAIL | 설정(config) 파일 열기 오류. 파일의 경로등을 확인하세요."); + hash.put("-302", "ERR_CONFIG_PARAMETER_FAIL | 설정 파라미터 읽기 오류. 설정파일의 내용이 올바른지 확인하세요."); + + //-------------------------------------------------------------------------------- + //Handles file I/O + //-------------------------------------------------------------------------------- + hash.put("-401", "ERR_FILE_CERT_READ_FAIL | 인증서 파일 읽기를 실패했습니다."); + hash.put("-402", "ERR_FILE_KEY_OPEN_FAIL | 서버의 비밀키 파일 열기를 실패했습니다. 설정파일에서 파일명 및 경로를 확인하세요. (Server Secret Key File)"); + hash.put("-403", "ERR_FILE_KEY_READ_FAIL | 서버의 비밀키 파일 읽기를 실패했습니다."); + hash.put("-404", "ERR_FILE_CERT_OPEN_FAIL | 인증서 파일 열기를 실패했습니다. 설정파일에서 파일명 및 경로를 확인하세요. (Server Certificate File)"); + hash.put("-405", "ERR_FILE_CERT_WRITE_FAIL | 서버의 인증서 저장에 실패했습니다."); + + //-------------------------------------------------------------------------------- + //Handshake of SCP3.0 + //-------------------------------------------------------------------------------- + hash.put("-501", "ERR_HANDSHAKE_INVALID_INPUT | 입력값 오류. 입력버퍼 중에 NULL 값이 있습니다."); + hash.put("-502", "ERR_HANDSHAKE_INVALID_INPUT_LEN | 입력길이 오류. 길이값이 너무 작거나 너무 큽니다."); + hash.put("-503", "ERR_HANDSHAKE_INVALID_DATA_LENGTH | 입력길이 오류. 입력 길이값이 틀립니다."); + hash.put("-504", "ERR_HANDSHAKE_INVALID_CLIENT_VERSION | 클라이언트 버전 오류. 입력값 또는 클라이언트 라이브러리 버전을 확인하세요."); + hash.put("-505", "ERR_HANDSHAKE_INVALID_SESSION_ID_LEN | 세션아이디 길이값 오류. 세션아이디 길이(sid_len)는 0 에서 32 사이어야 합니다."); + hash.put("-506", "ERR_HANDSHAKE_INVALID_CERT_LEN | 다운로드된 인증서 길이가 부적절합니다. (너무 크거나 음수입니다.) 데이터 전송상태를 확인하세요."); + hash.put("-507", "ERR_HANDSHAKE_NOT_INITAILIZED | 라이브러리 초기화가 되어 있지 않습니다. 초기화 함수를 먼저 호출하세요."); + hash.put("-508", "ERR_HANDSHAKE_INVALID_CONTENT_TYPE | 컨텐트타입 오류. 입력버퍼 내용이 부적절합니다."); + hash.put("-509", "ERR_HANDSHAKE_INVALID_PROTOCOL_VERSION | 프로토콜 버전 오류. 입력값을 확인하세요."); + hash.put("-510", "ERR_HANDSHAKE_NOT_SUPPORTED_MODE | 지원되지 않는 인증모드. 개발자에게 문의하세요."); + hash.put("-511", "ERR_HANDSHAKE_INVALID_SECRET_LEN | 비밀값 길이 오류. 개발자에게 문의하세요."); + hash.put("-512", "ERR_HANDSHAKE_INVALID_PROCESS_ID_LEN | 프로세스 아이디 오류. 입력값을 확인하세요."); + hash.put("-513", "ERR_HANDSHAKE_INVALID_PROCESS_ID | 프로세스 아이디 오류. 개발자에게 문의하세요."); + hash.put("-514", "ERR_HANDSHAKE_BAD_MAC | 맥값 오류. 데이터 위변조 되었거나 키값이 틀림. 키공유를 다시 하세요. 또는 개발자에게 문의하세요."); + hash.put("-515", "ERR_HANDSHAKE_INVALID_SERVER_VERSION | 서버 버전 오류. 입력값을 확인하세요."); + hash.put("-516", "ERR_HANDSHAKE_INVALID_CLIENT_ID_LEN | 클라이언트 아이디 오류. 입력값을 확인하세요. 또는 컨텍스트(ctx) 가 변경되었는지 확인하세요."); + hash.put("-517", "ERR_HANDSHAKE_INVALID_SERVER_ID_LEN | 서버 아이디 오류. 입력값을 확인하세요. 또는 컨텍스트(ctx) 가 변경되었는지 확인하세요."); + hash.put("-518", "ERR_HANDSHAKE_SMAN_NOT_SET | 세션 매니저가 세팅되어 있지 않습니다. 설정파일 값(use sman)을 변경한 후 세션 매니저를 구동하십시오."); + hash.put("-519", "ERR_HANDSHAKE_NOT_SUPPORTED_TYPE | 지원되지 않는 인증서 업데이트 타입입니다. 설정파일의 Update Type 값이 1로 되어 있는지 확인하세요."); + hash.put("-520", "ERR_HANDSHAKE_INVALID_PROFILE_LIST | 프로파일 리스트 오류. 제품버전 또는 입력값을 확인하세요."); + hash.put("-521", "ERR_HANDSHAKE_NOT_SUPORTED_PROFILE | 지원되지 않는 프로파일입니다. 제품버전 또는 입력값을 확인하세요."); + + //-------------------------------------------------------------------------------- + //Key derivation function + //-------------------------------------------------------------------------------- + hash.put("-601", "ERR_KDF_MALLOC_FAIL | 치명적 오류. 메모리 할당 실패."); + + //-------------------------------------------------------------------------------- + //Most high layer of XecureConnect3.0 + //-------------------------------------------------------------------------------- + hash.put("-701", "ERR_MAIN_INVALID_SMODE | 서브젝트 모드값(smode) 오류. 입력값을 확인하세요."); + hash.put("-702", "ERR_MAIN_INVALID_CERTMODE | 인증모드 오류. 클라이언트 설정파일 내용을 확인하세요. cert mode 값은 0x01 - 0x03 사이 값이어야 합니다."); + hash.put("-703", "ERR_MAIN_INVALID_TMODE | 트랜잭션 모드값(tmode) 오류. 입력값을 확인하세요."); + hash.put("-704", "ERR_MAIN_INVALID_CONTENT_TYPE | 컨텐트타입 오류. 입력버퍼 내용이 부적절합니다."); + hash.put("-705", "ERR_MAIN_NOKEY | 세션 리쥼 실패. 마스터키가 폐기되거나 존재하지 않습니다."); + hash.put("-706", "ERR_MAIN_NOT_INITAILIZED | 라이브러리가 초기화 되어 있지 않습니다."); + hash.put("-707", "ERR_MAIN_SIGNER_IS_NOT_CLIENT | 클라이언트에서만 사용할 수 있는 함수입니다. XC_SIGNGEN 함수를 참조하세요."); + hash.put("-708", "ERR_MAIN_CALLER_IS_NOT_CLIENT | 클라이언트 전용 함수입니다."); + hash.put("-709", "ERR_MAIN_CALLER_IS_NOT_SERVER | 서버가 호출하는 함수입니다."); + hash.put("-710", "ERR_MAIN_INVALID_USER_NAME | 사용자의 주민번호 (name) 값이 올바르지 않습니다."); + hash.put("-711", "ERR_MAIN_INVALID_INPUT | 입력값이 올바르지 않습니다."); + hash.put("-712", "ERR_MAIN_INVALID_INPUT_LEN | 입력값 길이 오류. 길이 변수가 올바른지 확인하세요."); + hash.put("-713", "ERR_MAIN_INVALID_CERT_TYPE | 지원되지 않는 인증서 형식입니다."); + hash.put("-714", "ERR_MAIN_NOT_WINDOWS_VERSION | 윈도우즈 환경에서 실행될 수 없는 코드입니다."); + hash.put("-715", "ERR_MAIN_INVALID_TYPE | 지원하지 않는 타입입니다."); + + //-------------------------------------------------------------------------------- + //Message encrypt and decrypt + //-------------------------------------------------------------------------------- + hash.put("-801", "ERR_MESSAGE_INVALID_INPUT | 입력값 오류. 입력버퍼 중에 NULL 값이 있습니다."); + hash.put("-802", "ERR_MESSAGE_NOT_INITAILIZED | 라이브러리 초기화가 되어 있지 않습니다. 초기화 함수를 먼저 호출하세요."); + hash.put("-803", "ERR_MESSAGE_INVALID_INPUT_LEN | 입력길이 오류. 길이값이 너무 작거나 너무 큽니다.만일 63KB 보다 큰 메시지를 암복호 해야 한다면 XC_MSGLONG 함수를 사용하세요."); + hash.put("-804", "ERR_MESSAGE_INVALID_DATA_LEN | 입력길이 오류. 입력 길이값이 틀립니다."); + hash.put("-805", "ERR_MESSAGE_INVALID_SESSION_ID_LEN | 세션아이디 길이값 오류. 세션아이디 길이(sid_len)는 0 에서 32 사이어야 합니다. 보다 자세한 사항은 개발자에게 문의하세요."); + hash.put("-806", "ERR_MESSAGE_NOT_SUPPORTED_SYMM_ALGORITHM | 지원되지 않는 알고리즘. 입력값을 확인하세요."); + hash.put("-807", "ERR_MESSAGE_INVALID_CONTENT_TYPE | 컨텐트타입 오류. 입력값이 틀립니다. 입력값을 확인하세요"); + hash.put("-808", "ERR_MESSAGE_INVALID_SEQ_NUM | 시퀀스넘버 오류. 같은 메시지가 반복되었습니다. 혹은 외부 공격가능성도 있습니다. 적용단계에서 오류가 없었다면 개발자에게 문의하세요."); + hash.put("-809", "ERR_MESSAGE_BAD_MAC | 맥값 오류. 데이터 위변조 되었거나 키값이 틀림. 키공유를 다시 하세요. 또는 개발자에게 문의하세요."); + hash.put("-810", "ERR_MESSAGE_INVALID_VERSION | 메세지의 버전이 올바르지 않습니다. 입력값 또는 클라이언트 라이브러리 버전을 확인하세요."); + hash.put("-811", "ERR_MESSAGE_INVALID_MAGALG | 지원되지 않는 맥 알고리즘입니다. 개발자에게 문의하세요."); + hash.put("-812", "ERR_MESSAGE_MALLOC_FAIL | 메모리 할당 실패."); + + //-------------------------------------------------------------------------------- + //Decode PEM type data + //-------------------------------------------------------------------------------- + hash.put("-901", "ERR_PEM_INVALID_INPUT | 입력값 중에 NULL 값이 있습니다. 인증서 및 키데이터 또는 입력값등을 확인하세요."); + hash.put("-902", "ERR_PEM_INVALID_SEPERATOR | 데이터의 형식이 올바르지 않습니다. 인증서 또는 키파일의 내용을 확인하세요."); + + //-------------------------------------------------------------------------------- + //Calculate P_hash + //-------------------------------------------------------------------------------- + hash.put("-1001", "ERR_PHASH_INVALID_INPUT | 입력값 중에 NULL 값이 있습니다."); + hash.put("-1002", "ERR_PHASH_MALLOC_FAIL | 치명적 오류. 메모리 할당 실패."); + + //-------------------------------------------------------------------------------- + //For server library. + //-------------------------------------------------------------------------------- + hash.put("-1101", "ERR_SERVER_INVALID_KEYFILE | 서버의 비밀키 파일 형식 오류. 비밀키 파일의 내용을 확인하세요."); + hash.put("-1102", "ERR_SERVER_INVALID_CERTFILE | 서버의 인증서 파일 형식 오류. 인증서 파일의 내용을 확인하세요."); + hash.put("-1103", "ERR_SERVER_INVALID_PASSWD | 비밀키에 대한 패스워드가 올바르지 않습니다."); + + //-------------------------------------------------------------------------------- + //Stores and searches session keys through session manager + //-------------------------------------------------------------------------------- + hash.put("-1201", "ERR_SMAN_SOCKET_INIT_FAIL | 클라이언트 소켓 초기화 실패. O/S 의 소켓 라이브러리 지원여부를 확인하세요."); + hash.put("-1202", "ERR_SMAN_INVALID_SESSION_ID_LEN | 세션아이디 길이 오류. 컨텍스트(ctx) 내용이 바뀌었는지 확인하세요."); + hash.put("-1203", "ERR_SMAN_CONNECT_FAIL | 세션매니저 접속오류. 세션매니저의 아이피 설정 확인 또는 세션매니저가 구동되어 있는지 확인하세요."); + hash.put("-1204", "ERR_SMAN_SEND_FAIL | 세션매니저 통신오류. 메세지 전송실패."); + hash.put("-1205", "ERR_SMAN_RECV_FAIL | 세션매니저 통신오류. 메세지 수신실패."); + hash.put("-1206", "EERR_SMAN_DECODE_FAIL | 세션매니저 전문오류. 개발자에게 문의하세요."); + hash.put("-1207", "ERR_SMAN_KEY_EXPIRED | 세션키가 폐기됨. 클라이언트는 키공유를 다시 해야 합니다."); + hash.put("-1208", "ERR_SMAN_SESSIONMANAGER_INTERNAL | 세션매니저 내부오류. 개발자에게 문의하세요."); + hash.put("-1209", "ERR_SMAN_MASTERKEY_NOT_EXIST | 마스터키가 없거나 폐기되었습니다. 클라이언트는 키공유를 다시하세요."); + + //-------------------------------------------------------------------------------- + //Interface with client cert UI + //-------------------------------------------------------------------------------- + hash.put("-1301", "ERR_XTU_INVALID_PASSWD | 사용자 비밀키에 대한 패스워드가 올바르지 않습니다."); + + //-------------------------------------------------------------------------------- + //For license check + //-------------------------------------------------------------------------------- + hash.put("-1401", "ERR_LICENSE_MISMATCH | 발급된 라이선스 키 값이 해당 시스템을 위해 발급된 값이 아닙니다."); + hash.put("-1402", "ERR_LICENSE_EXPIRED | 라이선스의 유효기간이 만료 되었읍니다."); + hash.put("-1403", "ERR_LICENSE_GET_SYSTEMID_FAIL | 해당 시스템의 고유정보를 얻지 못해습니다. 네트웍 설정 등이 정상인지 살펴보세요."); + hash.put("-1404", "ERR_LICENSE_FILE_OPEN_FAIL | 라이선스 파일을 읽을 수 없습니다. 파일의 위치 또는 존재여부를 확인하세요."); + hash.put("-1405", "ERR_LICENSE_INTERNAL | 라이선스 관련 내부오류입니다. 개발자에게 문의하세요.."); + + //-------------------------------------------------------------------------------- + //IDV + //-------------------------------------------------------------------------------- + hash.put("-1501", "ERR_IDV_NAME_NULL | 사용자 아이디(주민번호) 정보가 필요합니다. 함수 입력값 중에 정보가 들어 있는지 확인하세요."); + hash.put("-1502", "ERR_IDV_VERIFY_FAIL | vid 검증실패. 본인확인 검증에 실패했습니다."); + hash.put("-1503", "ERR_IDV_INVALID_INPUT_LEN | 입력길이값(in_len)이 틀립니다."); + + //-------------------------------------------------------------------------------- + //Digital sign and envelope + //-------------------------------------------------------------------------------- + hash.put("-1601", "ERR_PKCS7_INVALID_PASSWD | 비밀키에 대한 패스워드가 올바르지 않습니다."); + + //-------------------------------------------------------------------------------- + //Path validation + //-------------------------------------------------------------------------------- + hash.put("-1701", "ERR_PVD_INVALID_INPUT | 입력값이 올바르지 않습니다."); + hash.put("-1702", "ERR_PVD_CERT_INVALID | 인증서가 올바르지 않습니다."); + hash.put("-1703", "ERR_PVD_CERT_DN_INVALID | 인증서의 DN 값이 올바르지 않습니다."); + hash.put("-1704", "ERR_PVD_CERT_SIGN_INVALID | 인증서의 서명값이 올바르지 않습니다."); + hash.put("-1705", "ERR_PVD_CERT_NOT_YET_VALID | 인증서를 아직 사용할 수 없습니다."); + hash.put("-1706", "ERR_PVD_CERT_EXPIRED | 인증서의 유효기간이 만료되었습니다."); + hash.put("-1707", "ERR_PVD_CERT_REVOKED | 인증서가 폐기되었습니다."); + hash.put("-1708", "ERR_PVD_CERT_NOT_FOUND | 인증서를 찾을 수 없습니다."); + hash.put("-1709", "ERR_PVD_CERT_EXT_INVALID | 인증서의 확장필드가 올바르지 않습니다."); + hash.put("-1710", "ERR_PVD_CERT_EXT_NOT_EXIST | 인증서의 확장필드가 존재하지 않습니다."); + hash.put("-1711", "ERR_PVD_CERT_NAME_MISMATCH | 인증서명이 일치하지 않습니다."); + hash.put("-1712", "ERR_PVD_CERT_KEYID_MISMATCH | 인증서의 키아이디 값이 일치하지 않습니다."); + hash.put("-1713", "ERR_PVD_CERT_KEYUSAGE_INVALID | 인증서의 key usage 값이 올바르지 않습니다."); + hash.put("-1714", "ERR_PVD_CERT_POLICY_INVALID | 인증서의 policy 가 초과되었습니다."); + hash.put("-1715", "ERR_PVD_CERT_BC_INVALID | 인증서의 bc 가 올바르지 않습니다."); + hash.put("-1716", "ERR_PVD_CERT_CRLDP_INVALID | 인증서의 crldp 가 올바르지 않습니다."); + hash.put("-1718", "ERR_PVD_CERT_AIA_INVALID | 인증서의 aia 가 올바르지 않습니다."); + hash.put("-1719", "ERR_PVD_ROOT_SIGN_INVALID | 루트 인증서의 sign 이 올바르지 않습니다."); + hash.put("-1720", "ERR_PVD_ROOT_NOT_YET_VALID | 루트 인증서를 아직 사용할 수 없습니다."); + hash.put("-1721", "ERR_PVD_ROOT_EXPIRED | 루트 인증서가 폐기되었습니다."); + hash.put("-1722", "ERR_PVD_PATH_NOT_FOUND | 경로를 찾을 수 없습니다."); + hash.put("-1723", "ERR_PVD_PATH_LENGTH_EXCEED | 경로가 제한 길이를 초과했습니다."); + hash.put("-1724", "ERR_PVD_CRL_INVALID | CRL 이 올바르지 않습니다."); + hash.put("-1725", "ERR_PVD_CRL_DN_INVALID | CRL DN 이 올바르지 않습니다."); + hash.put("-1726", "ERR_PVD_CRL_SIGN_INVALID | CRL 서명값이 올바르지 않습니다."); + hash.put("-1727", "ERR_PVD_CRL_EXPIRED | CRL 이 폐기되었습니다."); + hash.put("-1728", "ERR_PVD_CRL_NOT_AVAIL | CRL 을 사용할 수 없습니다."); + hash.put("-1729", "ERR_PVD_CRL_NOT_FOUND | CRL 을 찾을 수 없습니다."); + hash.put("-1730", "ERR_PVD_STORE_ERROR | 인증서 저장소 오류입니다."); + hash.put("-1731", "ERR_PVD_LDAP_ERROR | LDAP 오류입니다."); + hash.put("-1732", "ERR_PVD_OCSP_ERROR | OCSP 오류입니다."); + hash.put("-1733", "ERR_PVD_NOTSUPPORTED_POLICY_CODE | 지원하지 않는 인증서 정책코드 또는 지원하지 않는 인증기관에서 발급한 인증서입니다. 인증서 정책코드 파일을 확인 또는 정책코드 관련 API 를 참조하세요."); + hash.put("-1734", "ERR_PVD_PARESE_URL | AIA 필드 파싱에 실패 했습니다."); + hash.put("-1735", "ERR_PVD_SOCKET_CLIENT | OCSP 서버 연결에 실패 했습니다."); + hash.put("-1736", "ERR_PVD_NO_RESP_LIST | OCSP 응답에 목록정보가 없습니다."); + + //-------------------------------------------------------------------------------- + //Client cert select UI + //-------------------------------------------------------------------------------- + hash.put("-1801", "ERR_XWCS_CNBUF_OVERFLOW | CN 버퍼의 저장 한도를 초과했습니다. 인증서 정책코드 파일을 참조하거나 관리자에게 문의하세요."); + hash.put("-1802", "ERR_XWCS_CN_NOMATCH | 해당 CN 이 저장되어 있지 않습니다. 인증서 정책코드 파일을 확인 또는 정책코드 관련 API 를 참조하세요."); + + //-------------------------------------------------------------------------------- + //POLICY + //-------------------------------------------------------------------------------- + hash.put("-1901", "ERR_POLICY_LIST_OVERFLOW | 정책코드 테이블의 저장 한도를 초과했습니다. 인증서 정책코드 파일을 참조하거나 관리자에게 문의하세요."); + hash.put("-1902", "ERR_POLICY_CODE_NOMATCH | 일치하는 인증서 정책코드가 없습니다. 인증서 정책코드 파일을 확인 또는 정책코드 관련 API 를 참조하세요."); + hash.put("-1903", "ERR_POLICY_CNLIST_OVERFLOW | CN 리스트 테이블의 저장 한도를 초과했습니다. 인증서 정책코드 파일을 참조하거나 관리자에게 문의하세요."); + hash.put("-1904", "ERR_POLICY_CN_NOMATCH | 일치하는 CN 정보가 없습니다. 인증서 정책코드 파일을 확인 또는 정책코드 관련 API 를 참조하세요."); + hash.put("-1905", "ERR_POLICY_FILE_OPEN_FAIL | 파일 열기에 실패했습니다. 주어진 경로에 파일이 있는지 확인하세요."); + hash.put("-1906", "ERR_POLICY_FILE_READ_FAIL/td> | 파일 읽기에 실패했습니다. 파일 내용이 올바른지 확인하세요."); + hash.put("-1907", "ERR_POLICY_FIRST_BLOCKBEGIN | 필터링 파일 형식이 잘못 되었습니다. 블럭기호는 가장 처음에 나올 수 없습니다."); + hash.put("-1908", "ERR_POLICY_INVALID_BLOCKEND | 필터링 파일 형식이 잘못 되었습니다. 블럭의 닫힘기호가 발견되지 않았거나 잘못 위치해 있습니다."); + hash.put("-1909", "ERR_POLICY_INVALID_CN_CONST | CN 상수값이 올바르지 않습니다. 입력값 중 CN 상수값을 확인하세요."); + hash.put("-1910", "ERR_POLICY_RESERVED_CN | 이미 등록되어 있은 CN 입니다."); + } + + static public String getErrorMessage(String key) { + String value = hash.get(key); + if (value == null) { + return "Unknown Error."; + } + return value; + } + + static public String getErrorMessage(int key) { + return getErrorMessage(String.valueOf(key)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureFilter.java new file mode 100644 index 0000000..e29ec40 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureFilter.java @@ -0,0 +1,226 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure; + +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + +import java.io.*; +import java.util.Properties; + +public abstract class XecureFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + +// private static final String NEXT_FILTER = XecureFilter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = XecureFilter.class.getName() + ".STATE"; + + public static final String SESSION_STATE = "SESSION_STATE"; + + protected enum State { + STATE_WELCOME, + STATE_KEY_INIT, + STATE_KEY_INIT_SEND, + STATE_KEY_FINAL, + STATE_KEY_FINAL_SEND, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = null; + public byte[] key; // token? + + public FilterState() {} + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected boolean isConfigLoaded = false; + protected byte[] cert; + protected byte[] key; + protected String password; + protected byte[] remoteCert; + + protected XecureFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public synchronized void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + super.onPreAdd(parent, name, nextFilter); + + if (isConfigLoaded) { + return; + } + + try { + File file = new File(context.getXecureConfigPath()); + if (!file.exists()) { + throw new Exception(context.getAdapterName() + " | " + getClass().getSimpleName() + " | xecure.config.path '" + context.getXecureConfigPath() + "' is invalid"); + } + + File pf = file.getParentFile(); + if(pf == null) { + throw new Exception("'cert file path not found - " + file.getAbsolutePath()); + } + String certPath = null; + if(pf.getParentFile() != null) { + certPath = pf.getParentFile().getPath() + File.separator + "cert"; + } + else { + throw new Exception("'cert file path not found - " +pf.getAbsolutePath()); + } + Properties prop = loadXecureConfigFile(context.getXecureConfigPath()); + + if (context.isServer()) { + /** + * local cert + */ + String certFile = prop.getProperty("Local Certificate File"); + if (certFile == null) { + throw new Exception("'Local Certificate File' property does not exist in xecure config file - " + context.getXecureConfigPath()); + } + try { + cert = readFile(certPath + File.separator + certFile); + } catch (FileNotFoundException e) { + throw new Exception(context.getAdapterName() + " | " + getClass().getSimpleName() + " | Local Certificate File '" + certFile + "' does not exist."); + } + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | " + getClass().getSimpleName() + " | load local cert file - " + certPath + File.separator + certFile); + } + + /** + * local key + */ + String keyFile = prop.getProperty("Local Secret Key File"); + if (keyFile == null) { + throw new Exception("'Local Secret Key File' property does not exist in xecure config file - " + context.getXecureConfigPath()); + } + try { + key = readFile(certPath + File.separator + keyFile); + } catch (FileNotFoundException e) { + throw new Exception(context.getAdapterName() + " | " + getClass().getSimpleName() + " | Local Secret Key File '" + keyFile + "' does not exist."); + } + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | " + getClass().getSimpleName() + " | load local key file - " + certPath + File.separator + keyFile); + } + + /** + * password + */ + String passwordString = prop.getProperty("Local Password"); + if (passwordString == null) { + throw new Exception("'Local Password' property does not exist in xecure config file - " + context.getXecureConfigPath()); + } +// if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { +// logger.debug(context.getAdapterName() + " | read password - *****"); +// } + password = passwordString; + } + + /** + * remote cert + */ + if (context.isClient()) { + String remoteCertFile = context.getXecureRemoteCert(); + try { + remoteCert = readFile(certPath + File.separator + remoteCertFile); + } catch (FileNotFoundException e) { + throw new Exception(context.getAdapterName() + " | " + getClass().getSimpleName() + " | xecure.remote.cert '" + remoteCertFile + "' file does not exist."); + } + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | " + getClass().getSimpleName() + " | load remote cert (public key) file - " + certPath + File.separator + remoteCertFile); + } + } + + isConfigLoaded = true; + } catch (Exception e) { + throw e; + } + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + /* + if (context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG) { + logger.debug(context.getAdapterName() + " | session created : " + session); + } + */ + + synchronized(session) { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_KEY_INIT; + session.setAttribute(FILTER_STATE_KEY, filterState); + //setSessionState(session, filterState.state.toString()); + } + } + + // handshake future + session.setAttribute(ProtocolHandler.HANDSHAKE_FUTURE, new SimpleFuture()); + } + + @Override + public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception { + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + xc.close(); + + nextFilter.sessionClosed(session); + } + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + + + protected Properties loadXecureConfigFile(String filename) throws Exception { + Properties prop = new Properties(); + + + try ( BufferedReader br = new BufferedReader(new FileReader(filename)) ) { +// StringBuffer sb = new StringBuffer(); + String line = null; + while ((line = br.readLine()) != null) { + if (line.matches("(Server|Client|Local) (Certificate File|Secret Key File|Password)[\\s]+=.+")) { + String[] columns = line.split("=", 2); + prop.put(columns[0].trim(), columns[1].trim()); + } + } + }catch(Exception ex) { + throw ex; + } + return prop; + } + + protected byte[] readFile(String filename) throws Exception { + File file = new File(filename); + int fsize = (int)file.length(); + byte[] buffer = new byte[fsize]; + + try ( + FileInputStream fis = new FileInputStream(filename); + BufferedInputStream bis = new BufferedInputStream(fis); + ) { + bis.read(buffer); + }catch(Exception ex) { + throw ex; + } + return buffer; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureHandler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureHandler.java new file mode 100644 index 0000000..6fde350 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureHandler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class XecureHandler extends ProtocolHandler { + public XecureHandler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureServer.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureServer.java new file mode 100644 index 0000000..0f14b58 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/XecureServer.java @@ -0,0 +1,62 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xecure.envelope.XecureEnvelopeFilter; +import com.eactive.eai.adapter.socket2.protocol.xecure.fixed.handshake.XecureFixedServerFilter; +import com.eactive.eai.adapter.socket2.protocol.xecure.fixedheader.handshake.XecureFixedHeaderServerFilter; +import com.eactive.eai.adapter.socket2.protocol.xecure.welcome.codec.XecureWelcomeCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xecure.welcome.handshake.XecureWelcomeServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class XecureServer extends TcpAdapterServer { + public XecureServer(SocketAdapterContext context) throws Exception { + super(context); + + if ("BASIC".equals(context.getXecureType())) { + context.setLlFieldType("CHAR"); + context.setLlFieldOffset(0); + context.setLlFieldLength(7); + context.setLlFieldInclude("N"); + context.setLlOffsetExclude("N"); + context.setLlInclude("Y"); + } else if ("WELCOME".equals(context.getXecureType())) { + context.setLlFieldType("CHAR"); + context.setLlFieldOffset(0); + context.setLlFieldLength(4); + context.setLlFieldInclude("Y"); + context.setLlOffsetExclude("N"); + context.setLlInclude("Y"); + } else if ("FIXEDHEADER".equals(context.getXecureType())) { + context.setLlFieldType("CHAR"); + context.setLlFieldOffset(0); + context.setLlFieldLength(7); + context.setLlFieldInclude("N"); + context.setLlOffsetExclude("N"); + context.setLlInclude("Y"); + } + + if ("FIXED".equals(context.getXecureType()) || "BASIC".equals(context.getXecureType())) { + this.handler = new XecureHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "xecure.fixed", new XecureFixedServerFilter(this)); + } else if ("ENVELOPE".equals(context.getXecureType())) { + this.handler = new XecureHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "xecure.fixed", new XecureFixedServerFilter(this)); + config.getFilterChain().addAfter("xecure.fixed", "xecure.envelope", new XecureEnvelopeFilter(this)); + } else if ("WELCOME".equals(context.getXecureType())) { + this.handler = new XecureHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new XecureWelcomeCodecFactory(this))); + config.getFilterChain().addAfter("codec", "xecure.welcome", new XecureWelcomeServerFilter(this)); + } else if ("FIXEDHEADER".equals(context.getXecureType())) { + this.handler = new XecureHandler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addAfter("codec", "xecure.fixedheader", new XecureFixedHeaderServerFilter(this)); + } else { + throw new Exception(context.getAdapterName() + " | UNKNOWN Xecure Type - " + context.getXecureType()); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/envelope/XecureEnvelopeFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/envelope/XecureEnvelopeFilter.java new file mode 100644 index 0000000..f11606e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/envelope/XecureEnvelopeFilter.java @@ -0,0 +1,268 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.envelope; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureFilter; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + +import java.io.File; +import java.io.FileNotFoundException; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class XecureEnvelopeFilter extends XecureFilter { + public XecureEnvelopeFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public synchronized void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + if (isConfigLoaded) { + return; + } + + File file = new File(context.getXecureConfigPath()); + + File pf = file.getParentFile(); + if(pf == null) { + throw new Exception("'cert file path not found - " + file.getAbsolutePath()); + } + + String certPath = null; + + if(pf.getParentFile() != null) { + certPath = pf.getParentFile().getPath() + File.separator + "cert"; + } + else { + throw new Exception("'cert file path not found - " +pf.getAbsolutePath()); + } + + Properties prop = loadXecureConfigFile(context.getXecureConfigPath()); + + /** + * local cert + */ + String certFile = prop.getProperty("Local Certificate File"); + if (certFile == null) { + throw new Exception("'Local Certificate File' property does not exist in xecure config file - " + context.getXecureConfigPath()); + } + try { + cert = readFile(certPath + File.separator + certFile); + } catch (FileNotFoundException e) { + throw new Exception(context.getAdapterName() + " | " + getClass().getSimpleName() + " | Local Certificate File '" + certFile + "' does not exist."); + } + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | " + getClass().getSimpleName() + " | load local cert file - " + certPath + File.separator + certFile); + } + + /** + * local key + */ + String keyFile = prop.getProperty("Local Secret Key File"); + if (keyFile == null) { + throw new Exception("'Local Secret Key File' property does not exist in xecure config file - " + context.getXecureConfigPath()); + } + try { + key = readFile(certPath + File.separator + keyFile); + } catch (FileNotFoundException e) { + throw new Exception(context.getAdapterName() + " | " + getClass().getSimpleName() + " | Local Secret Key File '" + keyFile + "' does not exist."); + } + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | " + getClass().getSimpleName() + " | load local key file - " + certPath + File.separator + keyFile); + } + + /** + * password + */ + String passwordString = prop.getProperty("Local Password"); + if (passwordString == null) { + throw new Exception("'Local Password' property does not exist in xecure config file - " + context.getXecureConfigPath()); + } +// if (context.getTraceLevel() >= context.TRACE_LEVEL_TRACE) { +// logger.debug(context.getAdapterName() + " | read password - *****"); +// } + password = passwordString; + + /** + * remote cert + */ + String remoteCertFile = context.getXecureRemoteCert(); + try { + remoteCert = readFile(certPath + File.separator + remoteCertFile); + } catch (FileNotFoundException e) { + throw new Exception(context.getAdapterName() + " | " + getClass().getSimpleName() + " | xecure.remote.cert '" + remoteCertFile + "' file does not exist."); + } + if (context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE) { + logger.debug(context.getAdapterName() + " | " + getClass().getSimpleName() + " | load remote cert (public key) file - " + certPath + File.separator + remoteCertFile); + } + + isConfigLoaded = true; + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = null; + + if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else { + throw new Exception("Unknown data format"); + } + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_MESSAGE: + if ("Y".equals(context.getLlInclude())) { + ByteMessage bm = new ByteMessage(m.getBytes(0, context.getLlFieldOffset())); + bm.append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + m = bm; + } + m = new ByteMessage(xc.envdec(m.getBytes(), cert, key, password)); + + if ("Y".equals(context.getLlInclude())) { + ByteBuffer buffer = ByteBuffer.allocate(context.getLlFieldLength() + m.size()); + + int size = m.size(); + if ("Y".equals(context.getLlFieldInclude())) { + size = size + context.getLlFieldLength(); + } + if ("Y".equals(context.getLlOffsetExclude())) { + size = size - context.getLlFieldOffset(); + } + + byte[] ll = null; + if ("CHAR".equals(context.getLlFieldType())) { + ll = CommonLib.getFormatString(size, context.getLlFieldLength()).getBytes(); + } else { + ll = new byte[context.getLlFieldLength()]; + for (int i = context.getLlFieldLength()-1; i>=0; i--) { + ll[i] = (byte) (size % 256); + size = size / 256; + } + } + + buffer.put(m.getBytes(0, context.getLlFieldOffset())); + buffer.put(ll); + buffer.put(m.getBytes(context.getLlFieldOffset())); + buffer.flip(); + m.setByteBuffer(buffer); + } + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureEnvelopeFilter | messageReceived() - after envdec - " + m.hexDump()); + } + break; + + default: + break; + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + + nextFilter.messageReceived(session, m); + } + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_MESSAGE: + if ("Y".equals(context.getLlInclude())) { + ByteMessage bm = new ByteMessage(m.getBytes(0, context.getLlFieldOffset())); + bm.append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + bm = new ByteMessage(xc.envenc(bm.getBytes(), remoteCert)); + m = new ByteMessage(); + + int size = bm.size(); + if ("Y".equals(context.getLlFieldInclude())) { + size = size + context.getLlFieldLength(); + } + if ("Y".equals(context.getLlOffsetExclude())) { + size = size - context.getLlFieldOffset(); + } + String lenStr = CommonLib.getFormatString(size, context.getLlFieldLength()); + + m.append(bm.getBytes(0, context.getLlFieldOffset())) + .append(lenStr.getBytes()) + .append(bm.getBytes(context.getLlFieldOffset())); + } else { + m = new ByteMessage(xc.envenc(m.getBytes(), remoteCert)); + } + + + //m = (new ByteMessage(m.getBytes(0, 7))).append(xc.envenc(m.getBytes(7), remoteCert)); + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureEnvelopeFilter | filterWrite() - after envenc - " + m.hexDump()); + } + break; + + default: + break; + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + + ByteBuffer buffer = ByteBuffer.wrap(m.getBytes()); + nextFilter.filterWrite(session, new WriteRequest(buffer, writeRequest.getFuture(), writeRequest.getDestination())); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixed/handshake/XecureFixedClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixed/handshake/XecureFixedClientFilter.java new file mode 100644 index 0000000..9b18a20 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixed/handshake/XecureFixedClientFilter.java @@ -0,0 +1,145 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.fixed.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.sf.xc3.Base64; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class XecureFixedClientFilter extends XecureFixedFilter { + public XecureFixedClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + /** + * xc - init + */ + XC_v3 xc = new XC_v3(); + int ret = xc.init(password, context.getXecureConfigPath(), 1); + if (ret < 0) { + throw new Exception("cannot init xecure connector. ret=" + ret + " : " + XecureErrorMessage.getErrorMessage(ret)); + } + + xc.msgLong(); + + /** + * put xc into session + */ + session.setAttribute(XecureConstants.XECURE, xc); + + /** + * change state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + filterState.state = State.STATE_KEY_INIT; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + +// String base64 = xc.keyInit(remoteCert); + String base64 ="";//TODO kb version => 우체국 version + //byte[] token = Base64.decode(base64); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureFixedClientFilter | KEY_INIT | " + base64.substring(0, 40) + "..."); + } + +// WriteFuture future = session.write(format(base64.getBytes(), session)); + session.write(format(base64.getBytes(), session)); + //future.join(context.getTimeout() * 1000L); + //internalSendMessage(session, new ByteMessage(Constants.KEY_INIT_MESSAGE)); + + filterState.state = State.STATE_KEY_FINAL; + setSessionState(session, filterState.state.toString()); + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | " + e.getMessage() + " | " + xcMessage); + } + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_KEY_FINAL: + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureFixedClientFilter | KEY_FINAL | " + m); + } + + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + + if ("Y".equals(context.getLlInclude())) { + ByteMessage bm = new ByteMessage(m.getBytes(0, context.getLlFieldOffset())); + bm.append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + m = bm; + } + + byte[] bytes = Base64.decode(m.getBytes()); + + xc.keyFinal(bytes); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + break; + + case STATE_MESSAGE: + if (!"ENVELOPE".equals(context.getXecureType())) { + /** + * 전자 봉투 방식 아닌 경우만.. + */ + m = decrypt(m, session); + } + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixed/handshake/XecureFixedFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixed/handshake/XecureFixedFilter.java new file mode 100644 index 0000000..eabb881 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixed/handshake/XecureFixedFilter.java @@ -0,0 +1,221 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.fixed.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureFilter; +import com.sf.xc3.Base64; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.commons.lang3.StringUtils; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +abstract public class XecureFixedFilter extends XecureFilter { + + public XecureFixedFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteBuffer) { + m = new ByteMessage((ByteBuffer) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFilter | " + m.hexDump()); + adapter.addRecentSend(m.hexDump()); + } + */ + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); +// XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_MESSAGE: +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + if (!"ENVELOPE".equals(context.getXecureType())) { + /** + * 전자 봉투 방식 아닌 경우만.. + */ + m = encrypt(m, session); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFixedFilter | filterWrite() - after encryption - " + m.hexDump()); + } + } + break; + + default: + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFixedClientFilter - " + filterState.state + " - " + m.hexDump()); + } + */ + break; + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + protected byte[] format(byte[] msg, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); +// XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + ByteMessage m = new ByteMessage(msg); + +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + + if ("Y".equals(context.getLlInclude())) { + ByteMessage bm = new ByteMessage(m.getBytes(0, context.getLlFieldOffset())); + bm.append(StringUtils.leftPad("0", context.getLlFieldLength())); + bm.append(m.getBytes(context.getLlFieldOffset())); + m = bm; + } + + return m.getBytes(); + } + + protected ByteMessage encrypt(ByteMessage m, IoSession session) throws Exception { + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + ByteMessage encrypted = null; + if ("Y".equals(context.getLlInclude())) { + ByteMessage bm = new ByteMessage(m.getBytes(0, context.getLlFieldOffset())); + bm.append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + ByteMessage ll = new ByteMessage(m.getBytes(context.getLlFieldOffset(), context.getLlFieldLength())); + bm = new ByteMessage(Base64.encode(xc.encode(bm.getBytes()))); + encrypted = new ByteMessage(); + encrypted.append(bm.getBytes(0, context.getLlFieldOffset())) + .append(ll.getBytes()) + .append(bm.getBytes(context.getLlFieldOffset())); + } else { + encrypted = new ByteMessage(Base64.encode(xc.encode(m.getBytes()))); + } + return encrypted; + } + + protected ByteMessage decrypt(ByteMessage m, IoSession session) throws Exception { + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + ByteMessage result = null; + + if ("Y".equals(context.getLlInclude())) { + /** + * input + */ +// byte[] ll = m.getBytes(context.getLlFieldOffset(), context.getLlFieldLength()); + m.getBytes(context.getLlFieldOffset(), context.getLlFieldLength()); + ByteMessage bm = new ByteMessage(m.getBytes(0, context.getLlFieldOffset())); + bm.append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + byte[] input = bm.getBytes(); + + /** + * output + */ + byte[] output = null; + try { + output = Base64.decode(input); + output = xc.decode(output, true).getBytes(); + output = Base64.decode(output); + } catch(Exception e) { +// e.printStackTrace(); + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + throw new Exception("xecure - decode error. " + e.getMessage() + " | " + xcMessage); + } + + /** + * formatting + */ + result = new ByteMessage(output); + ByteBuffer buffer = ByteBuffer.allocate(context.getLlFieldLength() + output.length); + String lenStr = CommonLib.getFormatString(output.length, context.getLlFieldLength()); + buffer.put(result.getBytes(0, context.getLlFieldOffset())); + buffer.put(lenStr.getBytes()); + buffer.put(result.getBytes(context.getLlFieldOffset())); + buffer.flip(); + result.setByteBuffer(buffer); + } else { + /** + * input + */ + byte[] input = m.getBytes(); + + /** + * output + */ + byte[] output = null; + try { + output = Base64.decode(input); + output = xc.decode(output, true).getBytes(); + output = Base64.decode(output); + } catch(Exception e) { +// e.printStackTrace(); + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + throw new Exception("xecure - decode error. " + e.getMessage() + " | " + xcMessage); + } + + /** + * formatting + */ + result = new ByteMessage(output); + + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFixedFilter | | " + result.hexDump()); + } + + return result; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixed/handshake/XecureFixedServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixed/handshake/XecureFixedServerFilter.java new file mode 100644 index 0000000..8227ef2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixed/handshake/XecureFixedServerFilter.java @@ -0,0 +1,152 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.fixed.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.sf.xc3.Base64; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class XecureFixedServerFilter extends XecureFixedFilter { + public XecureFixedServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + /** + * xc -init + */ +// XC_v3 xc = new XC_v3(cert, key, password); + XC_v3 xc = null;//TODO kb version => 우체국 version + int ret = xc.init(password, context.getXecureConfigPath(), 2); + if (ret < 0) { + throw new Exception("cannot init xecure connector. ret=" + ret + " : " + XecureErrorMessage.getErrorMessage(ret)); + } + + xc.msgLong(); + + /** + * put xc into session + */ + session.setAttribute(XecureConstants.XECURE, xc); + + /** + * change state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + filterState.state = State.STATE_KEY_FINAL; + setSessionState(session, filterState.state.toString()); + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | " + e.getMessage() + " | " + xcMessage); + } + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + XC_v3 xc = null; + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_KEY_FINAL: + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureFixedServerFilter | KEY_FINAL | " + m.hexDump()); + } + +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + + if ("Y".equals(context.getLlInclude())) { + ByteMessage bm = new ByteMessage(m.getBytes(0, context.getLlFieldOffset())); + bm.append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + m = bm; + } + + byte[] bytes = Base64.decode(m.getBytes()); + + String token = xc.keyFinal(bytes, 2); + //String token = xc.keyFinal(bytes, 2, cert, key, password); + + filterState.key = token.getBytes(); //Base64.decode(token); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureFixedServerFilter | KEY_FINAL | " + token.substring(0,40) + "..."); + } + +// WriteFuture future = session.write(format(filterState.key, session)); + session.write(format(filterState.key, session)); + //future.join(context.getTimeout() * 1000L); + + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + break; + + case STATE_MESSAGE: + if (!"ENVELOPE".equals(context.getXecureType())) { + /** + * 전자 봉투 방식 아닌 경우만.. + */ + m = decrypt(m, session); + } + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + if (xc != null) { + xc.close(); + } + adapter.getSessionPool().remove(session); + session.close(); + + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixedheader/handshake/XecureFixedHeaderClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixedheader/handshake/XecureFixedHeaderClientFilter.java new file mode 100644 index 0000000..d45e988 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixedheader/handshake/XecureFixedHeaderClientFilter.java @@ -0,0 +1,138 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.fixedheader.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.sf.xc3.Base64; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class XecureFixedHeaderClientFilter extends XecureFixedHeaderFilter { + public XecureFixedHeaderClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + /** + * xc - init + */ + XC_v3 xc = new XC_v3(); + int ret = xc.init(password, context.getXecureConfigPath(), 1); + if (ret < 0) { + throw new Exception("cannot init xecure connector. ret=" + ret + " : " + XecureErrorMessage.getErrorMessage(ret)); + } + + //set default : msgShort + //xc.msgLong(); + + /** + * put xc into session + */ + session.setAttribute(XecureConstants.XECURE, xc); + + /** + * change state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + filterState.state = State.STATE_KEY_INIT; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + +// String base64 = xc.keyInit(remoteCert); + String base64 = "";//TODO kb version => ¿ìü±¹ version + //byte[] token = Base64.decode(base64); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureFixedHeaderClientFilter | KEY_INIT | " + base64.substring(0, 40) + "..."); + } + +// WriteFuture future = session.write(format(base64.getBytes(), XecureConstants.FIXED_HEADER_HANDSHAKE.getBytes(), session)); + session.write(format(base64.getBytes(), XecureConstants.FIXED_HEADER_HANDSHAKE.getBytes(), session)); + //future.join(context.getTimeout() * 1000L); + //internalSendMessage(session, new ByteMessage(Constants.KEY_INIT_MESSAGE)); + + filterState.state = State.STATE_KEY_FINAL; + setSessionState(session, filterState.state.toString()); + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | " + e.getMessage() + " | " + xcMessage); + } + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_KEY_FINAL: + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureFixedHeaderClientFilter | KEY_FINAL | " + m); + } + + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + + ByteMessage bm = new ByteMessage(m.getBytes(context.getLlFieldLength() + XecureConstants.FIXED_HEADER_PART_LEHGTH)); + m = bm; + + byte[] bytes = Base64.decode(m.getBytes()); + + xc.keyFinal(bytes); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + break; + + case STATE_MESSAGE: + m = decrypt(m, session); + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixedheader/handshake/XecureFixedHeaderFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixedheader/handshake/XecureFixedHeaderFilter.java new file mode 100644 index 0000000..e71fb66 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixedheader/handshake/XecureFixedHeaderFilter.java @@ -0,0 +1,174 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.fixedheader.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureFilter; +import com.sf.xc3.Base64; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.commons.lang3.StringUtils; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +abstract public class XecureFixedHeaderFilter extends XecureFilter { + + public XecureFixedHeaderFilter(ISocketAdapter adapter) { + super(adapter); + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteBuffer) { + m = new ByteMessage((ByteBuffer) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFilter | " + m.hexDump()); + adapter.addRecentSend(m.hexDump()); + } + */ + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); +// XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_MESSAGE: +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + m = encrypt(m, session); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFixedHeaderFilter | filterWrite() - after encryption - " + m.hexDump()); + } + + break; + + default: + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFixedClientFilter - " + filterState.state + " - " + m.hexDump()); + } + */ + break; + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + protected byte[] format(byte[] msg, byte[] part, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); +// XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + ByteMessage m = new ByteMessage(StringUtils.leftPad("0", context.getLlFieldLength())); + m.append(part); + m.append(msg); + + return m.getBytes(); + } + + protected ByteMessage encrypt(ByteMessage m, IoSession session) throws Exception { + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + +// ByteMessage hdr = new ByteMessage(m.getBytes(0, context.getLlFieldLength() + XecureConstants.FIXED_HEADER_PART_LEHGTH)); +// ByteMessage bm = new ByteMessage(m.getBytes(context.getLlFieldLength() + XecureConstants.FIXED_HEADER_PART_LEHGTH)); + ByteMessage bm = new ByteMessage(Base64.encode(xc.encode(m.getBytes()))); + + String lenStr = CommonLib.getFormatString(bm.size(), context.getLlFieldLength()); + ByteMessage encrypted = new ByteMessage(); + encrypted.append(lenStr.getBytes()); + encrypted.append(XecureConstants.FIXED_HEADER_MESSAGE.getBytes()); + encrypted.append(bm.getBytes()); + + return encrypted; + } + + protected ByteMessage decrypt(ByteMessage m, IoSession session) throws Exception { + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + ByteMessage result = null; + + /** + * input + */ +// byte[] headerPart = m.getBytes(context.getLlFieldLength(), XecureConstants.FIXED_HEADER_PART_LEHGTH); + m.getBytes(context.getLlFieldLength(), XecureConstants.FIXED_HEADER_PART_LEHGTH); + ByteMessage bm = new ByteMessage(m.getBytes(context.getLlFieldLength() + XecureConstants.FIXED_HEADER_PART_LEHGTH)); + byte[] input = bm.getBytes(); + + /** + * output + */ + byte[] output = null; + try { + output = Base64.decode(input); + output = xc.decode(output, true).getBytes(); + output = Base64.decode(output); + } catch(Exception e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + throw new Exception("xecure - decode error. " + e.getMessage() + " | " + xcMessage); + } + + /** + * formatting + */ + result = new ByteMessage(output); + ByteBuffer buffer = ByteBuffer.allocate( + context.getLlFieldLength() + XecureConstants.FIXED_HEADER_PART_LEHGTH + output.length); + + String lenStr = CommonLib.getFormatString(output.length, context.getLlFieldLength()); + buffer.put(lenStr.getBytes()); +// buffer.put(headerPart); // '전문구분' 정보는 업무팀에 보내지 않음 + buffer.put(result.getBytes()); + buffer.flip(); + result.setByteBuffer(buffer); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFixedHeaderFilter | | " + result.hexDump()); + } + + return result; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixedheader/handshake/XecureFixedHeaderServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixedheader/handshake/XecureFixedHeaderServerFilter.java new file mode 100644 index 0000000..287b3c6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/fixedheader/handshake/XecureFixedHeaderServerFilter.java @@ -0,0 +1,146 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.fixedheader.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.sf.xc3.Base64; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class XecureFixedHeaderServerFilter extends XecureFixedHeaderFilter { + public XecureFixedHeaderServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + /** + * xc -init + */ +// XC_v3 xc = new XC_v3(cert, key, password); + XC_v3 xc = null;//TODO kb version => ¿ìü±¹ version + int ret = xc.init(password, context.getXecureConfigPath(), 2); + if (ret < 0) { + throw new Exception("cannot init xecure connector. ret=" + ret + " : " + XecureErrorMessage.getErrorMessage(ret)); + } + + //set default : msgShort + //xc.msgLong(); + + /** + * put xc into session + */ + session.setAttribute(XecureConstants.XECURE, xc); + + /** + * change state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + filterState.state = State.STATE_KEY_FINAL; + setSessionState(session, filterState.state.toString()); + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | " + e.getMessage() + " | " + xcMessage); + } + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + XC_v3 xc = null; + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_KEY_FINAL: + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureFixedHeaderServerFilter | KEY_FINAL | " + m.hexDump()); + } + +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + + byte[] headerPart = m.getBytes(context.getLlFieldLength(), XecureConstants.FIXED_HEADER_PART_LEHGTH); + ByteMessage bm = new ByteMessage(m.getBytes(context.getLlFieldLength() + XecureConstants.FIXED_HEADER_PART_LEHGTH)); + m = bm; + + byte[] bytes = Base64.decode(bm.getBytes()); + + String token = xc.keyFinal(bytes, 2); + //String token = xc.keyFinal(bytes, 2, cert, key, password); + + filterState.key = token.getBytes(); //Base64.decode(token); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureFixedHeaderServerFilter | KEY_FINAL | " + token.substring(0,40) + "..."); + } + +// WriteFuture future = session.write(format(filterState.key, headerPart, session)); + session.write(format(filterState.key, headerPart, session)); + //future.join(context.getTimeout() * 1000L); + + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + break; + + case STATE_MESSAGE: + m = decrypt(m, session); + nextFilter.messageReceived(session, m); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + if (xc != null) { + xc.close(); + } + adapter.getSessionPool().remove(session); + session.close(); + + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/sign/XecureSignFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/sign/XecureSignFilter.java new file mode 100644 index 0000000..a9bc51e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/sign/XecureSignFilter.java @@ -0,0 +1,120 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.sign; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureFilter; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class XecureSignFilter extends XecureFilter { + protected byte[] cert; + protected byte[] key; + + public XecureSignFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = null; + + if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else { + throw new Exception("Unknown data format"); + } + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_MESSAGE: + m = new ByteMessage(xc.verify(m.getBytes())); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureSignFilter | messageReceived() - after verify - " + m.hexDump()); + } + break; + + default: + break; + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + + nextFilter.messageReceived(session, m); + } + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_MESSAGE: + String s = xc.sign(m.getBytes(), cert, key, password); + m = new ByteMessage(s); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureSignFilter | filterWrite() - after sign - " + m.hexDump()); + } + break; + + default: + break; + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeCodecFactory.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeCodecFactory.java new file mode 100644 index 0000000..fe6feab --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeCodecFactory.java @@ -0,0 +1,30 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.welcome.codec; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.mina.filter.codec.ProtocolCodecFactory; +import org.apache.mina.filter.codec.ProtocolDecoder; +import org.apache.mina.filter.codec.ProtocolEncoder; + +public class XecureWelcomeCodecFactory implements ProtocolCodecFactory { + private ProtocolEncoder encoder; + private ProtocolDecoder decoder; + private ISocketAdapter adapter; + + + public XecureWelcomeCodecFactory(ISocketAdapter adapter) { + encoder = new XecureWelcomeEncoder(adapter); + decoder = new XecureWelcomeDecoder(adapter); + this.adapter = adapter; + if(this.adapter != null) { + this.adapter.getUptime(); + } + } + + public ProtocolDecoder getDecoder() throws Exception { + return decoder; + } + + public ProtocolEncoder getEncoder() throws Exception { + return encoder; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeConstants.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeConstants.java new file mode 100644 index 0000000..acb194b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeConstants.java @@ -0,0 +1,15 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.welcome.codec; + +public class XecureWelcomeConstants { + //public static final String WELCOME = "2 |0001|THIS IS LOTTO DELIVERY DAEMON v1.0|"; + public static final byte[] WELCOME = "|0001|THIS IS LOTTO DELIVERY DAEMON v1.0|".getBytes(); + public static final byte[] KEY_INIT_MESSAGE = "KEY_INIT".getBytes(); + public static final byte[] KEY_FINAL_MESSAGE = "KEY_FINAL".getBytes(); + + public static final String XECURE = "XECURE"; + + public static final int HEADER_LENGTH = 7 + 1 + 16; // (7) total size (1) security type (16) 판매점 아이디 + public static final int TAIL_LENGTH = 2; + + public static final String CODEC_KEY = "XECURE_CODEC_KEY"; +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeDecoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeDecoder.java new file mode 100644 index 0000000..4f83eba --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeDecoder.java @@ -0,0 +1,310 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.welcome.codec; + +import com.eactive.eai.adapter.EAIException; +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolDecoderAdapter; +import org.apache.mina.filter.codec.ProtocolDecoderOutput; + +public class XecureWelcomeDecoder extends ProtocolDecoderAdapter { + final protected Logger logger; + final protected Logger errLogger; + + private static enum State { + STATE_HEADER_READ, + STATE_PAYLOAD_READ, + STATE_TAIL_READ; + } + + public static class CodecState { + State state = State.STATE_HEADER_READ; + byte securityType = '0'; // 0:plain 1:DES 2:XecureConnect + ByteBuffer buffer = ByteBuffer.allocate(0).setAutoExpand(true); + int payloadSize; + byte[] payload; + } + + SocketAdapterContext context; + ISocketAdapter adapter; + + public XecureWelcomeDecoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void decode(IoSession session, ByteBuffer in, ProtocolDecoderOutput out) + throws Exception { + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureWelcomeDecoder | decode : " + CommonLib.hexDump(in, context)); + adapter.addRecentRecvTrace(session, "XecureWelcomeDecoder | decode : " + CommonLib.hexDump(in, context)); + } + + CodecState codecState = (CodecState) session.getAttribute(XecureWelcomeConstants.CODEC_KEY); + + if (codecState == null) { + codecState = new CodecState(); + session.setAttribute(XecureWelcomeConstants.CODEC_KEY, codecState); + } + + while(in.hasRemaining()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getTimeout()); + + String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + + if (sessionState.startsWith("STATE_WELCOME")) { + decodeWelcomeWelcome(session, in, out, codecState); + } else if (sessionState.startsWith("STATE_KEY_")) { + decodeWelcomeHandshake(session, in, out, codecState); + } else { + decodeWelcomeMessage(session, in, out, codecState); + } + } + } + + private void decodeWelcomeWelcome(IoSession session, ByteBuffer in, ProtocolDecoderOutput out, CodecState codecState) + throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureWelcomeDecoder | decodeWelcomeWelcome - " + codecState.state.toString()); + } + */ + + switch (codecState.state) { + case STATE_HEADER_READ: + codecState.buffer.limit(7); + if (readHeader(session, codecState, in)) { + codecState.buffer.position(7).limit(codecState.payloadSize-2); + //codecState.payloadSize = codecState.payloadSize - 7 - 2; + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + codecState.payload = new byte[codecState.buffer.limit()-7-17-2]; + codecState.buffer.position(7+17); + codecState.buffer.get(codecState.payload); + codecState.buffer.position(codecState.payloadSize-2).limit(codecState.payloadSize); + + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + codecState.state = State.STATE_TAIL_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_TAIL_READ: + if (readTail(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(7); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + } + } + + private void decodeWelcomeHandshake(IoSession session, ByteBuffer in, ProtocolDecoderOutput out, CodecState codecState) + throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureWelcomeDecoder | decodeWelcomeHandshake - " + codecState.state.toString()); + } + */ + + switch (codecState.state) { + case STATE_HEADER_READ: + codecState.buffer.limit(7); + if (readHeader(session, codecState, in)) { + codecState.buffer.position(7).limit(codecState.payloadSize-3); + //codecState.payloadSize = codecState.payloadSize - 7 - 2; + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + codecState.payload = new byte[codecState.buffer.limit()-7-23-3]; + codecState.buffer.position(7+23); + codecState.buffer.get(codecState.payload); + codecState.buffer.position(codecState.payloadSize-3).limit(codecState.payloadSize); + + codecState.state = State.STATE_TAIL_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_TAIL_READ: + if (readTail(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(7); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + } + } + + private void decodeWelcomeMessage(IoSession session, ByteBuffer in, ProtocolDecoderOutput out, CodecState codecState) + throws Exception { + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureWelcomeDecoder | decodeWelcomeMessage - " + codecState.state.toString()); + } + */ + + switch (codecState.state) { + case STATE_HEADER_READ: + codecState.buffer.limit(7); + if (readHeader(session, codecState, in)) { + codecState.buffer.position(7).limit(codecState.payloadSize-2); + //codecState.payloadSize = codecState.payloadSize - 7 - 2; + + codecState.state = State.STATE_PAYLOAD_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_PAYLOAD_READ: + if (readPayload(session, codecState, in)) { + codecState.payload = new byte[codecState.buffer.limit()-7-17-2]; + codecState.buffer.position(7+17); + codecState.buffer.get(codecState.payload); + codecState.buffer.position(codecState.payloadSize-2).limit(codecState.payloadSize); + + codecState.state = State.STATE_TAIL_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + case STATE_TAIL_READ: + if (readTail(session, codecState, in)) { + byte[] bytes = new byte[codecState.buffer.limit()-2]; + codecState.buffer.position(0); + codecState.buffer.get(bytes); + + ByteMessage message = new ByteMessage(bytes); + out.write(message); + + codecState.buffer.position(0).limit(7); + if (context.isClient() && context.isPermanent() && context.isPollingUse()) { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getPollingTimeout()); + } else { + session.setIdleTime(IdleStatus.BOTH_IDLE, context.getIdleTimeout()); + } + + codecState.state = State.STATE_HEADER_READ; + session.setAttribute(ProtocolHandler.CODEC_STATE, codecState.state.toString()); + } + break; + } + } + + private boolean readHeader(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + logger.debug(context.getAdapterName() + " | " + sessionState + " - read header - " + CommonLib.hexDump(in, context)); + } + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.buffer.flip(); + + try { + byte[] header = new byte[codecState.buffer.limit()]; + codecState.buffer.get(header); + codecState.payloadSize = Integer.parseInt(new String(header)); + //codecState.securityType = codecState.buffer.get(); + } catch (NumberFormatException e) { + throw new EAIException("RECEAINNA008", context.getAdapterName() + " | when read header, number format is invalid - " + e.getMessage() + " | " + CommonLib.hexDump(codecState.buffer, context)); + } + + return true; + } + + private boolean readPayload(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + logger.debug(context.getAdapterName() + " | " + sessionState + " - read payload : " + CommonLib.hexDump(in, context)); + } + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.buffer.flip(); + + return true; + } + + private boolean readTail(IoSession session, CodecState codecState, ByteBuffer in) throws Exception { + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + logger.debug(context.getAdapterName() + " | " + sessionState + " - read tail : " + CommonLib.hexDump(in, context)); + } + + if (codecState.buffer.remaining() > in.remaining()) { + codecState.buffer.put(in); + return false; + } + + while(codecState.buffer.hasRemaining()) { + codecState.buffer.put(in.get()); + } + + codecState.buffer.flip(); + + return true; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeEncoder.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeEncoder.java new file mode 100644 index 0000000..da3284f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/codec/XecureWelcomeEncoder.java @@ -0,0 +1,198 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.welcome.codec; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.adapter.socket2.protocol.xecure.welcome.codec.XecureWelcomeDecoder.CodecState; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.filter.codec.ProtocolEncoder; +import org.apache.mina.filter.codec.ProtocolEncoderOutput; + +public class XecureWelcomeEncoder implements ProtocolEncoder { + final protected Logger logger; + final protected Logger errLogger; + + SocketAdapterContext context; + ISocketAdapter adapter; + + public XecureWelcomeEncoder(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public void encode(IoSession session, Object message, ProtocolEncoderOutput out) + throws Exception { + + CodecState codecState = (CodecState) session.getAttribute(XecureWelcomeConstants.CODEC_KEY); + + if (codecState == null) { + codecState = new CodecState(); + //codecState.buffer.limit(Constants.HEADER_LENGTH); + session.setAttribute(XecureWelcomeConstants.CODEC_KEY, codecState); + } + + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + + ByteBuffer buffer = null; + if (sessionState.startsWith("STATE_WELCOME")) { + buffer = formatWelcomeWelcome(m, codecState); + } else if (sessionState.startsWith("STATE_KEY_")) { + buffer = formatWelcomeHandshake(m, codecState); + } else { + buffer = formatWelcomeMessage(m, codecState); + } + + + int mark = buffer.position(); + buffer.position(0); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | " + sessionState + " - encode - " + CommonLib.hexDump(buffer, context)); + adapter.addRecentSendTrace(session, sessionState + " - encode - " + CommonLib.hexDump(buffer, context)); + } + + buffer.position(mark); + buffer.flip(); + out.write(buffer); + } + + private ByteBuffer formatWelcomeWelcome(ByteMessage message, CodecState codecState) throws Exception { + ByteBuffer buffer = ByteBuffer.allocate(message.getBytes().length); + //buf.setAutoExpand(true); // Enable auto-expand for easier encoding + + /** + * write header (ll.field.include) + */ + String lenStr = CommonLib.getFormatString(message.getBytes().length, 7); + buffer.put(lenStr.getBytes()); // tatal message length + // tatal message length - left padding '0' + //buffer.put(StringUtils.leftPad(String.valueOf(m.getValue().length + Constants.HEADER_LENGTH + Constants.TAIL_LENGTH), 7, '0').getBytes()); + + /** + * padding - 17 bytes + */ + /* + // 암호화 타입 (0:plain 1:DES 2:Xecure Connect) + buffer.put(codecState.securityType); + + // 판매점 아이디 (16 Byte 고정으로 앞 또는 뒤를 공백문자로 채운다) + buffer.put(StringUtils.leftPad(" ", 16, ' ').getBytes()); + */ + buffer.put(message.getBytes(7, 17)); + + /** + * write payload + */ + buffer.put(message.getBytes(7+17, message.size()-7-17-2)); + + /** + * write tail + */ + buffer.put((byte) 0x0D); // CR '\r' + buffer.put((byte) 0x0A); // LF '\n' + + return buffer; + } + + private ByteBuffer formatWelcomeHandshake(ByteMessage message, CodecState codecState) throws Exception { + ByteBuffer buffer = ByteBuffer.allocate(message.getBytes().length); + //buf.setAutoExpand(true); // Enable auto-expand for easier encoding + + /** + * write header (ll.field.include) + */ + String lenStr = CommonLib.getFormatString(message.getBytes().length, 7); + buffer.put(lenStr.getBytes()); // tatal message length + + // tatal message length - left padding '0' + //buffer.put(StringUtils.leftPad(String.valueOf(m.getValue().length + Constants.HEADER_LENGTH + Constants.TAIL_LENGTH), 7, '0').getBytes()); + + /** + * padding - 23 bytes + */ + /* + // 암호화 타입 (0:plain 1:DES 2:Xecure Connect) + buffer.put(codecState.securityType); + + // 판매점 아이디 (22 Byte 고정으로 앞 또는 뒤를 공백문자로 채운다) + buffer.put("KB_DEV |4001|".getBytes()); + */ + buffer.put(message.getBytes(7, 23)); + + /** + * write payload + */ + buffer.put(message.getBytes(7+23, message.size()-7-23-3)); + + /** + * write tail + */ + buffer.put((byte) '|'); // '|' + buffer.put((byte) 0x0D); // CR '\r' + buffer.put((byte) 0x0A); // LF '\n' + + return buffer; + } + + private ByteBuffer formatWelcomeMessage(ByteMessage message, CodecState codecState) throws Exception { + ByteBuffer buffer = ByteBuffer.allocate(message.getBytes().length+2); + //buf.setAutoExpand(true); // Enable auto-expand for easier encoding + + /** + * write header (ll.field.include) + */ + String lenStr = CommonLib.getFormatString(message.getBytes().length+2, 7); + buffer.put(lenStr.getBytes()); // tatal message length + // tatal message length - left padding '0' + //buffer.put(StringUtils.leftPad(String.valueOf(m.getValue().length + Constants.HEADER_LENGTH + Constants.TAIL_LENGTH), 7, '0').getBytes()); + + /** + * padding - 17 bytes + */ + /* + // 암호화 타입 (0:plain 1:DES 2:Xecure Connect) + buffer.put(codecState.securityType); + + // 판매점 아이디 (16 Byte 고정으로 앞 또는 뒤를 공백문자로 채운다) + buffer.put(StringUtils.leftPad(" ", 16, ' ').getBytes()); + */ + buffer.put(message.getBytes(7, 17)); + + /** + * write payload + */ + buffer.put(message.getBytes(7+17, message.size()-7-17)); + + /** + * write tail + */ + buffer.put((byte) 0x0D); // CR '\r' + buffer.put((byte) 0x0A); // LF '\n' + + return buffer; + } + + public void dispose(IoSession session) throws Exception { + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/handshake/XecureWelcomeClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/handshake/XecureWelcomeClientFilter.java new file mode 100644 index 0000000..5aa0176 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/handshake/XecureWelcomeClientFilter.java @@ -0,0 +1,136 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.welcome.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.sf.xc3.Base64; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class XecureWelcomeClientFilter extends XecureWelcomeFilter { + public XecureWelcomeClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + /** + * xc - init + */ + XC_v3 xc = new XC_v3(); + int ret = xc.init(password, context.getXecureConfigPath(), 1); + if (ret < 0) { + throw new Exception("cannot init xecure connector. ret=" + ret + " : " + XecureErrorMessage.getErrorMessage(ret)); + } + + /** + * welcome + */ + xc.msgShort(); + + /** + * put xc into session + */ + session.setAttribute(XecureConstants.XECURE, xc); + + /** + * change state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + filterState.state = State.STATE_WELCOME; + setSessionState(session, filterState.state.toString()); + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | " + e.getMessage() + " | " + xcMessage); + } + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_WELCOME: + filterState.state = State.STATE_KEY_INIT; + setSessionState(session, filterState.state.toString()); + +// String base64 = xc.keyInit(remoteCert); + String base64 = null;//TODO kb version => ¿ìü±¹ version + byte[] token = Base64.decode(base64); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureWelcomeClientFilter - KEY_INIT | " + base64.substring(0, 40) + "..., token["+ new String(token)+"]"); + } + +// WriteFuture future = session.write(format(base64.getBytes(), session)); + session.write(format(base64.getBytes(), session)); + //future.join(context.getTimeout() * 1000L); + //internalSendMessage(session, new ByteMessage(Constants.KEY_INIT_MESSAGE)); + + filterState.state = State.STATE_KEY_FINAL; + setSessionState(session, filterState.state.toString()); + break; + + case STATE_KEY_FINAL: + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureWelcomeClientFilter - KEY_FINAL | " + m); + } + + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + byte[] bytes = Base64.decode(m.getBytes(7+23, m.size()-7-23-3)); + + xc.keyFinal(bytes); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + break; + + case STATE_MESSAGE: + ByteMessage result = decrypt(m, session); + nextFilter.messageReceived(session, result); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/handshake/XecureWelcomeFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/handshake/XecureWelcomeFilter.java new file mode 100644 index 0000000..f2fdd0f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/handshake/XecureWelcomeFilter.java @@ -0,0 +1,262 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.welcome.handshake; + +import com.eactive.eai.adapter.socket2.common.CommonLib; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureFilter; +import com.sf.xc3.Base64; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.ByteBuffer; +import org.apache.mina.common.IoSession; +import org.apache.mina.common.WriteFuture; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +abstract public class XecureWelcomeFilter extends XecureFilter { + public XecureWelcomeFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFilter | " + m.hexDump()); + adapter.addRecentSend(m.hexDump()); + } + */ + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); +// XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_MESSAGE: +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + m = encrypt(m, session); + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureWelcomeFilter | filterWrite() - after encryption - " + m.hexDump()); + } + break; + + default: + /* + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | XecureFixedClientFilter - " + filterState.state + " - " + m.hexDump()); + } + */ + break; + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + protected byte[] format(byte[] msg, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); +// XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + ByteMessage m = new ByteMessage(msg); + + String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + byte[] bytes = null; + if (sessionState.startsWith("STATE_WELCOME")) { + bytes = (new ByteMessage(String.format("%-7s", "0000000"))) + .append("0") // 암호화 타입 (0:plain 1:DES 2:Xecure Connect) + .append(String.format("%16s", " ")) + .append(m.getBytes()) + .append("\r\n".getBytes()) + .getBytes(); + } else if (sessionState.startsWith("STATE_KEY_")) { + bytes = (new ByteMessage(String.format("%-7s", "0000000"))) + .append("0") // 암호화 타입 (0:plain 1:DES 2:Xecure Connect) + .append(String.format("%22s", "KB_DEV |4001|")) + .append(m.getBytes()) + .append("|\r\n".getBytes()) + .getBytes(); + } else { + bytes = (new ByteMessage(String.format("%-24s", "0000000"))) + .append("2") // 암호화 타입 (0:plain 1:DES 2:Xecure Connect) + .append(String.format("%16s", " ")) + //.append(Base64.encode(xc.encode(m.getBytes()))) + .append(m.getBytes()) + .append("\r\n".getBytes()) + .getBytes(); + } + + return bytes; + } + + protected ByteMessage encrypt(ByteMessage m, IoSession session) throws Exception { + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + byte[] bytes = (new ByteMessage(m.getBytes(0, 7+17))) + .append(Base64.encode(xc.encode(m.getBytes(7+17, m.size()-7-17)))) + //.append("\r\n") + .getBytes(); + return new ByteMessage(bytes); + } + + /** + * BASIC/FIXED/WELCOME/B2BHEADER 종류에 따라 codec을 만들지 않고 이쪽에서 작업한다. ^^; + */ + protected ByteMessage decrypt(ByteMessage m, IoSession session) throws Exception { + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + byte[] input = null; + + if (m.getByte(7) != '2') { + return m; + } + input = m.getBytes(7+17); + + byte[] output = null; + + try { + output = Base64.decode(input); + output = xc.decode(output, true).getBytes(); + output = Base64.decode(output); + } catch(Exception e) { +// e.printStackTrace(); + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + throw new Exception("xecure - decode error. " + e.getMessage() + " | " + xcMessage); + } + + ByteMessage result = new ByteMessage(output); + ByteBuffer buffer = null; + buffer = ByteBuffer.allocate(7 + 17 + output.length); + String lenStr = CommonLib.getFormatString(7 + 17 + output.length, 7); + buffer.put(lenStr.getBytes()); + buffer.put(m.getBytes(7, 17)); + buffer.put(output); + //buffer.put(m.getBytes(m.size()-2, 2)); + buffer.flip(); + result.setByteBuffer(buffer); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + logger.debug(context.getAdapterName() + " | including LL | " + CommonLib.hexDump(buffer, context)); + } + + return result; + } + + + protected void internalSendMessage(IoSession session, Object message) throws Exception { + try { + //SocketAdapterManager.getInstance().memoryLog("SEND", session, context, message.toString()); + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + ByteMessage m = null; + if (message == null) { + throw new Exception("cannot write null message."); + } else if (message instanceof ByteMessage) { + m = (ByteMessage) message; + } else if (message instanceof String) { + m = new ByteMessage((String) message); + } else if (message instanceof byte[]) { + m = new ByteMessage((byte[]) message); + } else { + throw new Exception("cannot write unknow format message."); + } + + String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + byte[] bytes = null; + if (sessionState.startsWith("STATE_WELCOME")) { + bytes = (new ByteMessage(m.getBytes(0, 7+17))) + .append(Base64.encode(xc.encode(m.getBytes(7+17, m.size()-7-17-2)))) + .append(m.getBytes(m.size()-2)) + .getBytes(); + } else if (sessionState.startsWith("STATE_KEY_")) { + bytes = (new ByteMessage(m.getBytes(0, 7+23))) + .append(Base64.encode(xc.encode(m.getBytes(7+23, m.size()-7-23-3)))) + .append(m.getBytes(m.size()-3)) + .getBytes(); + } else { + bytes = (new ByteMessage(m.getBytes(0, 7+17))) + .append(Base64.encode(xc.encode(m.getBytes(7+17, m.size()-7-17)))) + //.append("\r\n") + .getBytes(); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_DEBUG ) { + if (message instanceof byte[]) { + logger.debug(context.getAdapterName() + " | including LL | " + CommonLib.hexDump((byte[]) message, true, context)); + adapter.addRecentSend(session, CommonLib.hexDump((byte[]) message, true, context)); + } else if (message instanceof String) { + logger.debug(context.getAdapterName() + " | including LL | " + CommonLib.hexDump(((String) message).getBytes(), true, context)); + adapter.addRecentSend(session, message.toString()); + } else { + logger.debug(context.getAdapterName() + " | including LL | " + message); + adapter.addRecentSend(session, message.toString()); + } + } + + WriteFuture future = session.write(bytes); + future.join(context.getTimeout() * 1000L); + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/handshake/XecureWelcomeServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/handshake/XecureWelcomeServerFilter.java new file mode 100644 index 0000000..7e545ed --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure/welcome/handshake/XecureWelcomeServerFilter.java @@ -0,0 +1,138 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure.welcome.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureConstants; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.eactive.eai.adapter.socket2.protocol.xecure.welcome.codec.XecureWelcomeConstants; +import com.sf.xc3.Base64; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + +public class XecureWelcomeServerFilter extends XecureWelcomeFilter { + public XecureWelcomeServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + /** + * xc - init + */ +// XC_v3 xc = new XC_v3(cert, key, password); + XC_v3 xc = null;//TODO kb version => ¿ìü±¹ version + int ret = xc.init(password, context.getXecureConfigPath(), 2); + if (ret < 0) { + throw new Exception("cannot init xecure connector. ret=" + ret + " : " + XecureErrorMessage.getErrorMessage(ret)); + } + + /** + * welcome + */ + xc.msgShort(); + + /** + * put xc into session + */ + session.setAttribute(XecureConstants.XECURE, xc); + + /** + * send 'WELCOME' message + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + filterState.state = State.STATE_WELCOME; + setSessionState(session, filterState.state.toString()); + +// WriteFuture future = session.write(format(XecureWelcomeConstants.WELCOME, session)); + session.write(format(XecureWelcomeConstants.WELCOME, session)); + //future.join(context.getTimeout() * 1000L); + + filterState.state = State.STATE_KEY_FINAL; + setSessionState(session, filterState.state.toString()); + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | " + e.getMessage() + " | " + xcMessage); + } + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + + try { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(XecureConstants.XECURE); + + switch (filterState.state) { + case STATE_KEY_FINAL: + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureWelcomeServerFilter - KEY_FINAL | " + m.hexDump()); + } + +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + byte[] bytes = Base64.decode(m.getBytes(7+23, m.size()-7-23-3)); + + String token = xc.keyFinal(bytes, 2); + //String token = xc.keyFinal(bytes, 2, cert, key, password); + + filterState.key = token.getBytes(); //Base64.decode(token); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | XecureWelcomeServerFilter - KEY_FINAL | " + token.substring(0,40) + "..."); + } + +// WriteFuture future = session.write(format(filterState.key, session)); + session.write(format(filterState.key, session)); + //future.join(context.getTimeout() * 1000L); + + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + break; + + case STATE_MESSAGE: + ByteMessage result = decrypt(m, session); + nextFilter.messageReceived(session, result); + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Client.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Client.java new file mode 100644 index 0000000..d46179d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Client.java @@ -0,0 +1,25 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure2; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.cisco.codec.CiscoCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xecure2.handshake.Xecure2ClientFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class Xecure2Client extends TcpAdapterClient { + + public Xecure2Client(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new Xecure2Handler(this); + + if ("CISCO".equals(context.getXecureType())) + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new CiscoCodecFactory(this))); + else + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + + //avoid Polling Filter +// config.getFilterChain().addAfter("codec", "xecure2.fixed", new Xecure2ClientFilter(this)); + config.getFilterChain().addLast("xecure2.fixed", new Xecure2ClientFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Constants.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Constants.java new file mode 100644 index 0000000..3a451f8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Constants.java @@ -0,0 +1,12 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure2; + + +public class Xecure2Constants { + public static final String XECURE2 = "XECURE2"; + public static final int COMMON_PART_LENGTH = 70; + public static final int ENCRYPTED_CODE_OFFSET = 50; + + private Xecure2Constants() { + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Handler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Handler.java new file mode 100644 index 0000000..9cefe12 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Handler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure2; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class Xecure2Handler extends ProtocolHandler { + public Xecure2Handler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Server.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Server.java new file mode 100644 index 0000000..f5fd579 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/Xecure2Server.java @@ -0,0 +1,25 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure2; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.cisco.codec.CiscoCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xecure2.handshake.Xecure2ServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + +public class Xecure2Server extends TcpAdapterServer { + + public Xecure2Server(SocketAdapterContext context) throws Exception { + super(context); + this.handler = new Xecure2Handler(this); + + if ("CISCO".equals(context.getXecureType())) + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new CiscoCodecFactory(this))); + else + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + + //avoid Polling Filter +// config.getFilterChain().addAfter("codec", "xecure2.fixed", new Xecure2ServerFilter(this)); + config.getFilterChain().addLast("xecure2.fixed", new Xecure2ServerFilter(this)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/handshake/Xecure2ClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/handshake/Xecure2ClientFilter.java new file mode 100644 index 0000000..34f7dd6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/handshake/Xecure2ClientFilter.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure2.handshake; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + + +public class Xecure2ClientFilter extends Xecure2Filter { + public Xecure2ClientFilter(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/handshake/Xecure2Filter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/handshake/Xecure2Filter.java new file mode 100644 index 0000000..301fa67 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/handshake/Xecure2Filter.java @@ -0,0 +1,413 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure2.handshake; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure2.Xecure2Constants; +import com.eactive.eai.common.util.Logger; +import com.sf.xc.KBXCServer; +import com.sf.xc.XCException; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + +import java.util.Arrays; + + +public abstract class Xecure2Filter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + + private static final String NEXT_FILTER = Xecure2Filter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = Xecure2Filter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + + protected enum State { + STATE_HANDSHAKE, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = State.STATE_MESSAGE; //State.STATE_HANDSHAKE; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + protected Xecure2Filter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + if (parent.contains(Xecure2Filter.class)) { + throw new IllegalStateException("A filter chain cannot contain more than one Xecure2Filter."); + } + + IoSession session = parent.getSession(); + session.setAttribute(NEXT_FILTER, nextFilter); + } + + @Override + public void sessionCreated(NextFilter nextFilter, IoSession session) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if (filterState == null) { + filterState = new FilterState(); + filterState.state = State.STATE_HANDSHAKE; + session.setAttribute(FILTER_STATE_KEY, filterState); + } + + nextFilter.sessionCreated(session); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + try { + /** + * XCServer init + * JGY 20100423 +// */ +// KBXCServer.init(context.getXecure2ConfigPath()); +// KBXCServer xs = new KBXCServer(context.getXecure2SmIp(), context.getXecure2SmPort()); + + /** + * put xs into session + */ +// session.setAttribute(Xecure2Constants.XECURE2, xs); + + nextFilter.sessionOpened(session); + + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | xecure2 init error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | xecure2 init error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | xecure2 init error - " + e.getMessage(), e); + + try { + adapter.getSessionPool().remove(session); + session.close(); + } catch(Exception ignor) { + logger.warn("session.close", ignor); + } + + throw new Exception(context.getAdapterName() + " | xecure2 init error - " + e.getMessage()); + } + } + + @SuppressWarnings("static-access") + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = (ByteMessage) message; + + /** + * set state + * 거래구분 [28|4] + * 거래코드 [32|4] + * 0800|1210 : 키공유요구 + */ + String tranType = new String(m.getBytes(28, 4)); + String tranCode = new String(m.getBytes(32, 4)); + + if ("0800".equals(tranType) && "1210".equals(tranCode)) { + filterState.state = State.STATE_HANDSHAKE; + } else { + filterState.state = State.STATE_MESSAGE; + } + session.setAttribute(FILTER_STATE_KEY, filterState); + + try { + KBXCServer xs = (KBXCServer) session.getAttribute(Xecure2Constants.XECURE2); + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xecure2ServerFilter | " + filterState.state.toString() + " | " + m.hexDump()); + } + + /** + * 기관 SessionID set[12] + * sid : 이용자기관번호(40|8) + 단말번호(56|4) + * handshake 시 설정하며, keyFinal 호출 시 정보를 넘겨준다 + */ + byte[] sid = new byte[12]; + System.arraycopy(m.getBytes(40, 8), 0, sid, 0, 8); + System.arraycopy(m.getBytes(56, 4), 0, sid, 8, 4); + + switch (filterState.state) { + case STATE_HANDSHAKE: + /** + * Key Final + * received key init : offset|92, length|300 + */ + try { + byte[] finalKey = xs.keyFinal(m.getBytes(Xecure2Constants.COMMON_PART_LENGTH + 22, 300), sid, 1); + +// ByteMessage keyFinal = new ByteMessage(m.getBytes(0, Xecure2Constants.COMMON_PART_LENGTH + 22)) +// .append(finalKey).padding(392, (byte) 0x20) +// .append("1".getBytes()).padding(500, (byte) 0x20); //1:인증키승인, 2:세션키승인, 3:키승인오류 + ByteMessage keyFinal = new ByteMessage(m.getBytes(0, 37)) + .append("000".getBytes()) + .append(m.getBytes(40, 30 + 22)) + .append(finalKey).padding(500, (byte) 0x20) + ; //공통정보[응답코드]에 '000' 설정, offset:37, length:3, exception 시 '799' + + filterState.state = State.STATE_MESSAGE; + session.setAttribute(FILTER_STATE_KEY, filterState); + + nextFilter.messageReceived(session, keyFinal); + + } catch(XCException xce) { + adapter.addRecentError(context.getAdapterName() + " | xecure2 key final error[XCException] - " + xce.getMessage(), xce); + logger.error(context.getAdapterName() + " | xecure2 key final error[XCException] - " + xce.getMessage(), xce); + errLogger.error(context.getAdapterName() + " | xecure2 key final error[XCException] - " + xce.getMessage(), xce); +// throw new XCException(context.getAdapterName() + " | xecure2 key final error - " + xce.getMessage()); +// nextFilter.messageReceived(session, new ByteMessage(m.getByteBuffer().put(392, (byte) 0x33))); + nextFilter.messageReceived(session, + new ByteMessage(m.getByteBuffer().put(37, (byte)0x37).put(38, (byte)0x39).put(39, (byte)0x39))); + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | xecure2 key final error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | xecure2 key final error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | xecure2 key final error - " + e.getMessage(), e); +// nextFilter.messageReceived(session, new ByteMessage(m.getByteBuffer().put(392, (byte) 0x33))); + nextFilter.messageReceived(session, + new ByteMessage(m.getByteBuffer().put(37, (byte)0x37).put(38, (byte)0x39).put(39, (byte)0x39))); + } + + break; + + case STATE_MESSAGE: + /** + * decrypt + */ + try { + xs.setSid(sid); + m = decrypt(m, session); + nextFilter.messageReceived(session, m); + } catch(XCException xce) { + adapter.addRecentError(context.getAdapterName() + " | xecure2 decrypt error[XCException] - " + xce.getMessage(), xce); + logger.error(context.getAdapterName() + " | xecure2 decrypt error[XCException] - " + xce.getMessage(), xce); + errLogger.error(context.getAdapterName() + " | xecure2 decrypt error[XCException] - " + xce.getMessage(), xce); + nextFilter.messageReceived(session, + new ByteMessage(m.getByteBuffer().put(37, (byte)0x37).put(38, (byte)0x39).put(39, (byte)0x39))); + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | xecure2 decrypt error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | xecure2 decrypt error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | xecure2 decrypt error - " + e.getMessage(), e); + nextFilter.messageReceived(session, + new ByteMessage(m.getByteBuffer().put(37, (byte)0x37).put(38, (byte)0x39).put(39, (byte)0x39))); + } + + break; + + default: + throw new Exception(" invalid message during handshake | " + m.hexDump()); + } + + } catch(Exception e) { + adapter.addRecentError(context.getAdapterName() + " | xecure2 error - " + e.getMessage(), e); + logger.error(context.getAdapterName() + " | xecure2 error - " + e.getMessage(), e); + errLogger.error(context.getAdapterName() + " | xecure2 error - " + e.getMessage(), e); +// SMSLogger.loggingSMSWithCode(context.getAdapterName(), "RECEAINNA012"); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + adapter.getSessionPool().remove(session); + session.close(); + + throw new Exception(context.getAdapterName() + " | xecure2 error - " + e.getMessage()); + } + } + + @SuppressWarnings("static-access") + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xecure2Filter | " + filterState.state.toString() + " | " + m.hexDump()); + } + + try { + /** + * check polling message - skip polling + */ + if (!context.isPollingUse() || !isPollingPattern(m)) { + + /** + * set state + * 거래구분 [28|4] + * 거래코드 [32|4] + * 0810|1210 : 키공유응답 + */ + String tranType = new String(m.getBytes(28, 4)); + String tranCode = new String(m.getBytes(32, 4)); + + if ("0810".equals(tranType) && "1210".equals(tranCode)) { + filterState.state = State.STATE_HANDSHAKE; + } else { + filterState.state = State.STATE_MESSAGE; + } + session.setAttribute(FILTER_STATE_KEY, filterState); + + /** + * check 기관 SessionID set[12] + * sid : 이용자기관번호(40|8) + 단말번호(56|4) + */ + KBXCServer xs = (KBXCServer) session.getAttribute(Xecure2Constants.XECURE2); + + byte[] sid = new byte[12]; + System.arraycopy(m.getBytes(40, 8), 0, sid, 0, 8); + System.arraycopy(m.getBytes(56, 4), 0, sid, 8, 4); + + if ( xs.mSid == null || !Arrays.equals(sid, xs.getSid()) ) { +// System.arraycopy(sid, 0, xs.mSid, 0, sid.length); + xs.setSid(sid); + } + + switch (filterState.state) { + case STATE_HANDSHAKE: + /** + * change state + */ + filterState.state = State.STATE_MESSAGE; + session.setAttribute(FILTER_STATE_KEY, filterState); + + break; + + case STATE_MESSAGE: + /** + * encrypt + */ + m = encrypt(m, session); + + break; + } + } + + } catch(XCException xce) { + adapter.addRecentError(context.getAdapterName() + " | xecure2 error - " + xce.getMessage(), xce); + logger.error(context.getAdapterName() + " | xecure2 error - " + xce.getMessage(), xce); + errLogger.error(context.getAdapterName() + " | xecure2 error - " + xce.getMessage(), xce); + throw new XCException(context.getAdapterName() + " | xecure2 error - " + xce.getMessage()); + } + + /** + * next filter + */ + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } + + protected ByteMessage decrypt(ByteMessage m, IoSession session) throws Exception { + /** + * 암호화 여부 체크 + */ + if ('7' != m.getByte(Xecure2Constants.ENCRYPTED_CODE_OFFSET)) + return m; + + /** + * 암호화 구간(168 bytes) + * 카드 M/S DATA(104) + 비밀번호(16) + Filler(48) + */ + KBXCServer xs = (KBXCServer) session.getAttribute(Xecure2Constants.XECURE2); + + byte[] decrypted = xs.decrypt(m.getBytes(70, 168)); + + ByteMessage dm = new ByteMessage(m.getBytes(0, 70)) + .append(decrypted).padding(70+168, (byte) 0x20) + .append(m.getBytes(70+168)); + + return dm; + } + + protected ByteMessage encrypt(ByteMessage m, IoSession session) throws Exception { + /** + * 암호화 여부 체크 + */ + if ('7' != m.getByte(Xecure2Constants.ENCRYPTED_CODE_OFFSET)) + return m; + + KBXCServer xs = (KBXCServer) session.getAttribute(Xecure2Constants.XECURE2); + + /** + * 암호화 구간 + * + * 통장을 이용한 입금/통장정리(0210/4410, 0210/7280) [3800 bytes] + * - offset|109, recvLen|3616, sendLen|3691 + * 기타 [500 bytes] + * - offset|110, recvLen|12, sendLen|128 + */ + String tranType = new String(m.getBytes(28, 4)); + String tranCode = new String(m.getBytes(32, 4)); + byte[] encrypted = null; + ByteMessage em = new ByteMessage(); + + if ("0210".equals(tranType) && ("4410".equals(tranCode) || "7280".equals(tranCode))) { + encrypted = xs.encrypt(m.getBytes(70+39, 3616)); + em.append(m.getBytes(0, 70+39)) + .append(encrypted).padding(3800, (byte) 0x20); +// } else if("0210".equals(tranType) && "4420".equals(tranCode)) { //ATM 현금입금(카드)(0210/4420) 수용 +// encrypted = xs.encrypt(m.getBytes(70+40, 16)); +// em.append(m.getBytes(0, 70+40)) +// .append(encrypted).padding(70+40+128, (byte) 0x20) +// .append(m.getBytes(70+40+128)); +// } else { +// encrypted = xs.encrypt(m.getBytes(70+40, 12)); +// em.append(m.getBytes(0, 70+40)) +// .append(encrypted).padding(70+40+128, (byte) 0x20) +// .append(m.getBytes(70+40+128)); +// } + } else if("0210".equals(tranType) && "7281".equals(tranCode)){ + encrypted = xs.encrypt(m.getBytes(70+2, 2550)); + em.append(m.getBytes(0, 70+2)) + .append(encrypted).padding(3000, (byte) 0x20); + } else { + encrypted = xs.encrypt(m.getBytes(70+40, 80)); + em.append(m.getBytes(0, 70+40)) + .append(encrypted).padding(70+40+128, (byte) 0x20) + .append(m.getBytes(70+40+128)); + } + + + return em; + } + + public boolean isPollingPattern(ByteMessage m) throws Exception { + ByteMessage bm = m; + if ("Y".equals(context.getLlInclude())) { + bm = (new ByteMessage()) + .append(m.getBytes(0, context.getLlFieldOffset())) + .append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + } + + if ((context.isPollingReceiver() && bm.getString().matches(context.getPollingResponsePattern())) + || (context.isPollingSender() && bm.getString().matches(context.getPollingRequestPattern()))) + return true; + + return false; + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/handshake/Xecure2ServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/handshake/Xecure2ServerFilter.java new file mode 100644 index 0000000..6acf60e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure2/handshake/Xecure2ServerFilter.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure2.handshake; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + + +public class Xecure2ServerFilter extends Xecure2Filter { + public Xecure2ServerFilter(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Client.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Client.java new file mode 100644 index 0000000..4ba2332 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Client.java @@ -0,0 +1,24 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure3; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterClient; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xecure3.envelope.Xecure3EnvelopeClientFilter; +import org.apache.mina.common.IoFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class Xecure3Client extends TcpAdapterClient { + + public Xecure3Client(SocketAdapterContext context) throws Exception { + super(context); + + if ("ENVELOPE".equals(context.getXecureType())) { + this.handler = new Xecure3Handler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addLast("xecure3.envelope", (IoFilter) new Xecure3EnvelopeClientFilter(this)); + } else { + throw new Exception(context.getAdapterName() + " | UNKNOWN Xecure3 Type - " + context.getXecureType()); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Constants.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Constants.java new file mode 100644 index 0000000..9d94b8c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Constants.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure3; + + +public class Xecure3Constants { + public static final String XECURE3 = "XECURE3"; + + private Xecure3Constants() { + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Handler.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Handler.java new file mode 100644 index 0000000..aa5d473 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Handler.java @@ -0,0 +1,10 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure3; + +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.ProtocolHandler; + +public class Xecure3Handler extends ProtocolHandler { + public Xecure3Handler(ISocketAdapter adapter) { + super(adapter); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Server.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Server.java new file mode 100644 index 0000000..fec7d98 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/Xecure3Server.java @@ -0,0 +1,22 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure3; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.TcpAdapterServer; +import com.eactive.eai.adapter.socket2.protocol.fixedheader.codec.FixedHeaderCodecFactory; +import com.eactive.eai.adapter.socket2.protocol.xecure3.envelope.Xecure3EnvelopeServerFilter; +import org.apache.mina.filter.codec.ProtocolCodecFilter; + + +public class Xecure3Server extends TcpAdapterServer { + public Xecure3Server(SocketAdapterContext context) throws Exception { + super(context); + + if ("ENVELOPE".equals(context.getXecureType())) { + this.handler = new Xecure3Handler(this); + config.getFilterChain().addFirst("codec", new ProtocolCodecFilter(new FixedHeaderCodecFactory(this))); + config.getFilterChain().addLast("xecure3.envelope", new Xecure3EnvelopeServerFilter(this)); + } else { + throw new Exception(context.getAdapterName() + " | UNKNOWN Xecure3 Type - " + context.getXecureType()); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/envelope/Xecure3EnvelopeClientFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/envelope/Xecure3EnvelopeClientFilter.java new file mode 100644 index 0000000..48d4099 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/envelope/Xecure3EnvelopeClientFilter.java @@ -0,0 +1,192 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure3.envelope; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.eactive.eai.adapter.socket2.protocol.xecure3.Xecure3Constants; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Xecure3EnvelopeClientFilter extends Xecure3EnvelopeFilter { + public Xecure3EnvelopeClientFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception { + /** + * xc - init + */ + XC_v3 xc = new XC_v3(); + + /** + * put xc into session + */ + session.setAttribute(Xecure3Constants.XECURE3, xc); + + /** + * change state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + filterState.state = State.STATE_HANDSHAKE; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + + String KeyInitMessage = "START KB ENVELOPE HANDSHAKE"; + session.write(KeyInitMessage); + + } + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(Xecure3Constants.XECURE3); + + try { + + switch (filterState.state) { + case STATE_HANDSHAKE: + +// String sessionState = (String) session.getAttribute(ProtocolHandler.SESSION_STATE); + +// XCPem.decodePemFile(context.getXecure3ServerCert(), m.getString()); + +// try { + +// XCNpki.getChainCertInfo(context.getXecure3ServerCert(),context.getXecure3CertStore()); + +// } catch (XCException e) { +// adapter.addRecentError(context.getAdapterName() + " | xecure error - ", e); +// logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | ", e); +// errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | ", e); +// SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); +// +// nextFilter.filterClose(session); +// if (xc != null) { +// xc.close(); +// } +// adapter.getSessionPool().remove(session); +// session.close(); +// +// throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | "); +// } + +// session.write(XCPem.encodePemFile(context.getXecure3ClientCert(), "certificate")); + + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xecure3EnvelopeClientFilter | "); + } + + filterState.state = State.STATE_MESSAGE; + setSessionState(session, filterState.state.toString()); + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + + break; + + case STATE_MESSAGE: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xecure3EnvelopeClientFilter | "); + } + + m = new ByteMessage(xc.envdec(m.getBytes(), readFile(context.getXecure3ClientCert()),readFile(context.getXecure3CertKey()),context.getXecure3CertPassword())); + + nextFilter.messageReceived(session, m); + + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + if (xc != null) { + xc.close(); + } + adapter.getSessionPool().remove(session); + session.close(); + + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + } + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(Xecure3Constants.XECURE3); + + try { + + if(State.STATE_MESSAGE.equals(filterState.state)) { + + m = new ByteMessage(xc.envenc(m.getBytes(), readFile(context.getXecure3ServerCert()))); + + } + + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String key = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(key); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + if (xc != null) { + xc.close(); + } + adapter.getSessionPool().remove(session); + session.close(); + + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/envelope/Xecure3EnvelopeFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/envelope/Xecure3EnvelopeFilter.java new file mode 100644 index 0000000..d8c98cf --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/envelope/Xecure3EnvelopeFilter.java @@ -0,0 +1,82 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure3.envelope; + + +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.common.util.Logger; +import org.apache.mina.common.IoFilterAdapter; +import org.apache.mina.common.IoSession; + +import java.io.*; + + +public class Xecure3EnvelopeFilter extends IoFilterAdapter { + protected final Logger logger; + protected final Logger errLogger; + +// private static final String NEXT_FILTER = Xecure3EnvelopeFilter.class.getName() + ".NextFilter"; + protected static final String FILTER_STATE_KEY = Xecure3EnvelopeFilter.class.getName() + ".STATE"; + protected static final String SESSION_STATE = "SESSION_STATE"; + + protected enum State { + STATE_HANDSHAKE, + STATE_FINAL, + STATE_MESSAGE; + } + + protected static class FilterState { + public State state = State.STATE_MESSAGE; + } + + protected SocketAdapterContext context; + protected ISocketAdapter adapter; + + public Xecure3EnvelopeFilter(ISocketAdapter adapter) { + this.adapter = adapter; + this.context = adapter.getContext(); + + logger = SocketLoggerManager.getInstance().getLogger(context.getAdapterGroupName()); + errLogger = SocketLoggerManager.getInstance().getErrLogger(); + } + + public boolean isPollingPattern(ByteMessage m) throws Exception { + ByteMessage bm = m; + if ("Y".equals(context.getLlInclude())) { + bm = (new ByteMessage()) + .append(m.getBytes(0, context.getLlFieldOffset())) + .append(m.getBytes(context.getLlFieldOffset() + context.getLlFieldLength())); + } + + if ((context.isPollingReceiver() && bm.getString().matches(context.getPollingResponsePattern())) + || (context.isPollingSender() && bm.getString().matches(context.getPollingRequestPattern()))) + return true; + + return false; + } + + protected void setSessionState(IoSession session, String state) { + session.setAttribute(SESSION_STATE, state); + } + + protected String getSessionState(IoSession session) { + return (String) session.getAttribute(SESSION_STATE); + } + + protected byte[] readFile(String filename) throws FileNotFoundException, IOException { + File file = new File(filename); + int fsize = (int)file.length(); + byte[] buffer = new byte[fsize]; + + try ( + FileInputStream fis = new FileInputStream(filename); + BufferedInputStream bis = new BufferedInputStream(fis); + ) { + bis.read(buffer); + }catch(Exception ex) { + throw ex; + } + return buffer; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/envelope/Xecure3EnvelopeServerFilter.java b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/envelope/Xecure3EnvelopeServerFilter.java new file mode 100644 index 0000000..f8d82cb --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/protocol/xecure3/envelope/Xecure3EnvelopeServerFilter.java @@ -0,0 +1,219 @@ +package com.eactive.eai.adapter.socket2.protocol.xecure3.envelope; + +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import com.eactive.eai.adapter.socket2.protocol.xecure.XecureErrorMessage; +import com.eactive.eai.adapter.socket2.protocol.xecure3.Xecure3Constants; +import com.sf.xc3.XCException; +import com.sf.xc3.XC_v3; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoSession; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class Xecure3EnvelopeServerFilter extends Xecure3EnvelopeFilter { + protected byte[] cert; + protected byte[] key; + + public Xecure3EnvelopeServerFilter(ISocketAdapter adapter) { + super(adapter); + } + + @Override + public void onPreAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws Exception { + + cert = readFile(context.getXecure3ServerCert().toString()); + key = readFile(context.getXecure3CertKey().toString()); + + IoSession session = parent.getSession(); + + /** + * xc -init + */ +// XC_v3 xc = new XC_v3(cert, key , context.getXecure3CertPassword().toString()); + XC_v3 xc = null;//TODO kb version => ¿ìü±¹ version + + /** + * put xc into session + */ + session.setAttribute(Xecure3Constants.XECURE3, xc); + + /** + * change state + */ + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + if (filterState == null) { + filterState = new FilterState(); + session.setAttribute(FILTER_STATE_KEY, filterState); + } + } + + + @Override + public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws Exception { + ByteMessage m = (ByteMessage) message; + XC_v3 xc = null; + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + + if("START KB ENVELOPE HANDSHAKE".equals(new String(m.getBytes()))) { + filterState.state = State.STATE_HANDSHAKE; + session.setAttribute(SESSION_STATE, filterState.state.toString()); + } + + try { + + xc = (XC_v3) session.getAttribute(Xecure3Constants.XECURE3); + + switch (filterState.state) { + case STATE_HANDSHAKE: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xecure3EnvelopeServerFilter | "); + } + +// session.write(XCPem.encodePemFile(context.getXecure3ServerCert(), "certificate")); + + filterState.state = State.STATE_FINAL; + setSessionState(session, filterState.state.toString()); + + break; + + case STATE_FINAL: + +// XCPem.decodePemFile(context.getXecure3ClientCert(), m.getString()); + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xecure3EnvelopeServerFilter | "); + } + +// try { +// logger.debug(context.getAdapterName() + " | Xecure3EnvelopeServerFilter | Before getChainCertInfo | "); +// logger.debug(context.getAdapterName() + context.getXecure3ClientCert() + context.getXecure3CertStore()); +// +// XCNpki.getChainCertInfo(context.getXecure3ClientCert(),context.getXecure3CertStore()); +// +// if ( context.getTraceLevel() >= context.TRACE_LEVEL_TRACE ) { +// logger.debug(context.getAdapterName() + " | Xecure3EnvelopeServerFilter | "); +// } +// +// String KeyFinal_Message = "ENVELOPE FINAL HANDSHAKE"; +// session.write(KeyFinal_Message); +// +// filterState.state = State.STATE_MESSAGE; +// setSessionState(session, filterState.state.toString()); +// +// } catch (XCException e) { +// adapter.addRecentError(context.getAdapterName() + " | xecure error - ", e); +// logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | ", e); +// errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | ", e); +// SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); +// +// nextFilter.filterClose(session); +// if (xc != null) { +// xc.close(); +// } +// adapter.getSessionPool().remove(session); +// session.close(); +// +// throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | "); +// } + + nextFilter.sessionCreated(session); + nextFilter.sessionOpened(session); + + break; + + case STATE_MESSAGE: + if ( context.getTraceLevel() >= SocketAdapterContext.TRACE_LEVEL_TRACE ) { + logger.debug(context.getAdapterName() + " | Xecure3EnvelopeServerFilter | "); + } + + m = new ByteMessage(xc.envdec(m.getBytes(), readFile(context.getXecure3ServerCert()),readFile(context.getXecure3CertKey()),context.getXecure3CertPassword())); + + + nextFilter.messageReceived(session, m); + + break; + + default: + throw new Exception(" invalid message during handshake .. : " + m); + } + } catch(XCException e) { + String xcMessage = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + + if (matcher.find()) { + String keyValue = matcher.group(1); + xcMessage = XecureErrorMessage.getErrorMessage(keyValue); + } + + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage, e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + // nextFilter.filterClose(session); + // if (xc != null) { + // xc.close(); + // } + // adapter.getSessionPool().remove(session); + // session.close(); + + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + xcMessage); + } + } + + + @Override + public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception { + ByteMessage m = null; + + if (writeRequest.getMessage() instanceof byte[]) { + m = new ByteMessage((byte[]) writeRequest.getMessage()); + } else if (writeRequest.getMessage() instanceof ByteMessage) { + m = (ByteMessage) writeRequest.getMessage(); + } else if (writeRequest.getMessage() instanceof String) { + m = new ByteMessage((String) writeRequest.getMessage()); + } else { + throw new Exception("Unknown data format"); + } + + FilterState filterState = (FilterState) session.getAttribute(FILTER_STATE_KEY); + XC_v3 xc = (XC_v3) session.getAttribute(Xecure3Constants.XECURE3); + + try { + + if(State.STATE_MESSAGE.equals(filterState.state)) { + + m = new ByteMessage(xc.envenc(m.getBytes(), readFile(context.getXecure3ClientCert()))); + + } + + + } catch(Exception e) { + + String Message = ""; + Matcher matcher = Pattern.compile("(\\-[0-9]+)").matcher(e.getMessage()); + if (matcher.find()) { + String keyValue = matcher.group(1); + Message = XecureErrorMessage.getErrorMessage(keyValue); + } + adapter.addRecentError(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + Message, e); + logger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + Message, e); + errLogger.error(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + Message, e); + SMSLogger.loggingSMS4Soc(context.getAdapterName(), context.getDescription(), "RECEAINNA012"); + + nextFilter.filterClose(session); + if (xc != null) { + xc.close(); + } + adapter.getSessionPool().remove(session); + session.close(); + + throw new XCException(context.getAdapterName() + " | xecure error - " + e.getMessage() + " | " + Message); + } + + nextFilter.filterWrite(session, new WriteRequest(m, writeRequest.getFuture(), writeRequest.getDestination())); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/NetAdmin.java b/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/NetAdmin.java new file mode 100644 index 0000000..bcb0491 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/NetAdmin.java @@ -0,0 +1,37 @@ +package com.eactive.eai.adapter.socket2.tool.admin; + + + +public class NetAdmin { + static public void main(String[] args) throws Exception { + String hostname = "localhost"; + int port = 8281; + + if (args.length == 1) { + hostname = args[0]; + } else if (args.length == 2) { + System.out.println("args[0] " + args[0]); + System.out.println("args[1] " + args[1]); + hostname = args[0]; + port = Integer.parseInt(args[1]); + } + + Shell shell = new Shell(hostname, port); + shell.loop(); + } + + public static void printHelp() { + StringBuffer sb = new StringBuffer(); + sb.append("\n\t\t[소켓어뎁터 관리명령 도움말]\n\n"); + sb.append("start - 소켓어뎁터 기동명령 ( netadmin start adapterGroupName adapterName )"); + sb.append("stop - 소켓어뎁터 중지명령 ( netadmin stop adapterGroupName adapterName )"); + sb.append("disconnect - 소켓DISCONNECT명령 ( netadmin disconnect remoteIPAddress remotePort# )"); + sb.append("get connection - Connection정보 조회 ( netadmin get connection [ all | summary | adapterGroupName ] )"); + sb.append("get session - Session정보 조회 ( netadmin get session [ all | adapterGroupName ] )"); + sb.append("get config - Adapter Config정보 조회 ( netadmin get config adapterName )"); + sb.append("set connection - Max Connection 수 조정 ( netadmin set connection adapterName #OfConnection )"); + sb.append("set thread - Max Thread 수 조정 ( netadmin set thread adapterName #OfSession )"); + sb.append("set trace - 소켓어뎁터 추적관리 레벨 조정 ( netadmin set trace adapterName [ 0 | 1 | 2] )\n"); + System.out.println(sb.toString()); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/Shell.java b/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/Shell.java new file mode 100644 index 0000000..75b6b71 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/tool/admin/Shell.java @@ -0,0 +1,108 @@ +package com.eactive.eai.adapter.socket2.tool.admin; + +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.Parser; + +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.util.Date; + +public class Shell { + static String welcomeMsg = "\nNetAdmin: Release 2.0 - Production on " + (new Date()).toString() + "\n" + + "Copyright (c) KB. All rights reserved.\n\n" + + "Socket Adapter Administration System v2.0"; + static String byeMsg = "\nBye!\nSocket Adapter Administration System v2.0"; + static String prompt; + static String context = ""; + + String hostname; + int port; + //NETAdmin session = new NETAdmin(); + ISocketAdapter admin; + + //CommandLineParser parser; + Parser parser; + Options options; + + public Shell(String hostname, int port) throws Exception { + // set hostname:port + this.hostname = hostname; + this.port = port; + + // set prompt + prompt = "\nnetadmin-" + hostname + ":" + port + "| " + context + "> "; + + /** + * create socket adapter + */ + SocketAdapterContext adminContext = new SocketAdapterContext(); + adminContext.setProtocol("FIXED_LENGTH_HEADER"); + adminContext.setAdapterGroupName("AdminAdapterGroup"); + adminContext.setAdapterName("AdminAdapter"); + adminContext.setBoundUsage("IOBOUND"); + adminContext.setSocketType("CLIENT"); + adminContext.setHostName(hostname); + adminContext.setPortNumber(port); + adminContext.setAckSupport("N"); + adminContext.setLlFieldType("BIN"); + adminContext.setLlFieldLength(4); + adminContext.setResponseType("SYNC"); + adminContext.setTimeout(10); + adminContext.setMaxConnection(1); + adminContext.setPermanent("Y"); + adminContext.setTraceLevel(adminContext.TRACE_LEVEL_DEFAULT); + admin = SocketAdapterFactory.createSocketAdapter(adminContext); + SimpleFuture future = admin.start(); + Object o = future.join(60000L); + if (o instanceof Exception) + throw (Exception) o; + } + + public void loop() throws Exception { + BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); + System.out.println(welcomeMsg); + do { + // set prompt + prompt = "\nnetadmin-" + hostname + ":" + port + "| " + context + "> "; + System.out.print(prompt); + String line = in.readLine(); + + try { + if(line != null) process(line); + } catch(Exception e) { + System.out.println("loop error "+ e.toString()); + } + } while(true); + } + + public void process(String line) throws Exception { + if (line.trim().matches("[ ]*")) { + return; + } else if (line.trim().matches("(exit|quit|bye)")) { + try { + SimpleFuture future = admin.stop(); + future.join(); + } catch(Exception e) { + System.out.println("stop error"); + } + System.out.println(byeMsg); + System.exit(1); + } + + byte[] response = (byte[]) admin.sendMessage(line.getBytes()); + if (line.trim().startsWith("cc") || line.trim().startsWith("cd")) { + String res = new String(response); + if ("..".equals(context) || "/".equals(context)) { + context = ""; + } else if (res.trim().startsWith("usage") || res.trim().startsWith("ERROR")) { + } else { + context = res; + } + } + System.out.println(new String(response)); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/socket2/tool/monitor/SocketMonitor.java b/src/main/java/com/eactive/eai/adapter/socket2/tool/monitor/SocketMonitor.java new file mode 100644 index 0000000..a367b43 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/socket2/tool/monitor/SocketMonitor.java @@ -0,0 +1,56 @@ +package com.eactive.eai.adapter.socket2.tool.monitor; + +import com.eactive.eai.adapter.socket2.common.SimpleFuture; +import com.eactive.eai.adapter.socket2.config.SocketAdapterContext; +import com.eactive.eai.adapter.socket2.config.SocketAdapterFactory; +import com.eactive.eai.adapter.socket2.protocol.ISocketAdapter; + +public class SocketMonitor { + String hostname; + int port; + ISocketAdapter adapter; + + public SocketMonitor(String hostname, int port) throws Exception { + this.hostname = hostname; + this.port = port; + } + + public String getConnectionList() throws Exception { + start(); + try { + byte[] result = (byte[]) adapter.sendMessage("monitor connection"); + return new String(result); + } finally { + stop(); + } + } + + private void start() throws Exception { + SocketAdapterContext adminContext = new SocketAdapterContext(); + adminContext.setProtocol("FIXED_LENGTH_HEADER"); + adminContext.setAdapterGroupName("AdminAdapterGroup"); + adminContext.setAdapterName("AdminAdapter"); + adminContext.setBoundUsage("IOBOUND"); + adminContext.setSocketType("CLIENT"); + adminContext.setHostName(hostname); + adminContext.setPortNumber(port); + adminContext.setAckSupport("N"); + adminContext.setLlFieldType("BIN"); + adminContext.setLlFieldLength(4); + adminContext.setResponseType("SYNC"); + adminContext.setTimeout(10); + adminContext.setMaxConnection(1); + adminContext.setPermanent("Y"); + adminContext.setTraceLevel(adminContext.TRACE_LEVEL_DEFAULT); + adapter = SocketAdapterFactory.createSocketAdapter(adminContext); + SimpleFuture future = adapter.start(); + Object o = future.join(60000L); + if (o instanceof Exception) + throw (Exception) o; + } + + private void stop() throws Exception { + SimpleFuture future = adapter.stop(); + future.join(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/ClientUtil.java b/src/main/java/com/eactive/eai/adapter/wca/ClientUtil.java new file mode 100644 index 0000000..d42a9e4 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/ClientUtil.java @@ -0,0 +1,65 @@ +package com.eactive.eai.adapter.wca; + +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.log.InsertErrorLog; +import com.eactive.eai.common.util.Logger; + +import java.util.Properties; + +public class ClientUtil implements SNAProperties +{ + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + public static ClientUtil clientUtil = new ClientUtil(); + + /** + * 1. 기능 : ClientUtil Singleton Object 반환 + * 2. 처리 개요 : ClientUtil Singleton Object 반환한다. + * 3. 주의사항 + * + * @return ClientUtil Singleton object + **/ + public static ClientUtil getInstance(){ + return clientUtil; + } + + /** + * 1. 기능 : 트랜잭션 에러 로그 추가 + * 2. 처리 개요 : TSSSNA001 추가 (세션이 끊겼을 경우, 가용한 WCA 세션이 없을 경우 , LU 가 없을 경우) + * 3. 주의사항 + * + **/ + public void insertErrorLog(String sAdapterGrpName, String sGroupCode, String sLUName, + String sDataType, String sKey, String sErrCode) + { + try { + // 로그 추가 + InsertErrorLog log = new InsertErrorLog(); + // 우선 제거 + log.insertErrorLog(sAdapterGrpName, sGroupCode, sLUName, sDataType, sKey, sErrCode); + } catch(Exception e) { + if(adapter_logger.isError()) adapter_logger.error("에러 로그 추가시 에러 발생 : " + e.toString()); + } + } + + /** + * 1. 기능 : DATA TYPE으로 property 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + **/ + public void setDataTypeProperty(String sDataType, Properties prop) + { + if (sDataType.substring(0,1).equals(DATA_TYPE_DFS_PREFIX)) + prop.setProperty(DATA_TYPE, DATA_TYPE_DFS); + else if (sDataType.substring(0,1).equals(DATA_TYPE_NORMAL_PREFIX)) + prop.setProperty(DATA_TYPE, DATA_TYPE_NORMAL); + else if (sDataType.substring(0,1).equals(DATA_TYPE_TIMEOUT_PREFIX)) + prop.setProperty(DATA_TYPE, DATA_TYPE_TIMEOUT); + else + prop.setProperty(DATA_TYPE, sDataType); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/SNAAdapterClient.java b/src/main/java/com/eactive/eai/adapter/wca/SNAAdapterClient.java new file mode 100644 index 0000000..a6c18f7 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/SNAAdapterClient.java @@ -0,0 +1,475 @@ +package com.eactive.eai.adapter.wca; + +import com.eactive.eai.adapter.ElinkDefaultAdapter; +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.data.WCAHeader; +import com.eactive.eai.adapter.wca.data.WCAQueue; +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.util.MyUtil; +import com.eactive.eai.common.util.Logger; + +import java.util.ArrayList; +import java.util.Properties; + + +/** +* 1. 기능 : SNAAdapter를 통신을 위한 client 접근 모듈 +* 2. 처리 개요 : +* - OUTBOUNT Client 호출 메소드 재정의한 클래스 +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : SNAProperties +* @since : 2005. 6. 16. 오후 3:39:43 +*/ +public class SNAAdapterClient extends ElinkDefaultAdapter implements SNAProperties { + + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + /** + * SNAAdapter 관리 instance + */ + SNAAdapterManager smanager = SNAAdapterManager.getInstance(); + + /** + * 생성자 + */ + public SNAAdapterClient() { + } + + /** + * 1. 기능 : SNAAdapter 통신을 위한 client 호출 메소드 + * 2. 처리 개요 : + * - Adapter 그룹에 해당하는 WCA 세션을 할당하여 데이타 송수신한다. + * LU 이름이 정의되어 있을 경우, 해당 LU 그룹 세션을 할당한다. + * - LU 세션이 사용중일 경우, 다른 LU 세션 그룹 세션을 이용한다. + * 3. 주의사항 + * + * @param prop 프라퍼티 정보 (프라퍼티 정보는 SNAProperties에 정의) + * @param message 송신데이타 + * @exception Exception + **/ + public Object execute(Properties prop, Object message) throws Exception { + WCASession wcaSession = null; + String sKey = null; + byte[] pRetBuff = null; + String sCurNodeName = ""; + String sCurGroupCode = ""; + int nTranTimeout = -1; + + long lStartTime = 0L, lEndTime = 0L; + + // 20200724 Start + // Info 레벨로 변경 + // 시간 측정 + // if (adapter_logger.isDebug()) { lStartTime = System.currentTimeMillis(); } + if (adapter_logger.isInfo()) { lStartTime = System.currentTimeMillis(); } + // 20200724 End + + // 1. Validation + if (message == null) { + throw new WCAException(WCAException.E_SEND_DATA_ERROR, "송신데이타가 NULL 입니다."); + } + + String sAdapterGrpName = prop.getProperty(ADAPTER_GRP_NAME); + if (sAdapterGrpName == null) { + throw new WCAException(WCAException.E_SEND_DATA_ERROR, "어댑터 그룹 이름"); + } + + String sAdapterName = prop.getProperty(ADAPTER_NAME); + if (sAdapterName == null) { + throw new WCAException(WCAException.E_SEND_DATA_ERROR, "어댑터 그룹"); + } + + sKey = prop.getProperty(TRAN_KEY); + if (sKey == null) { + throw new WCAException(WCAException.E_SEND_DATA_ERROR, "Transaction Key"); + } + + String sLUName = prop.getProperty(LU_NAME) == null ? "" : prop.getProperty(LU_NAME); + // String sDataType = prop.getProperty(DATA_TYPE)== null ? "" : prop.getProperty(DATA_TYPE); + String sTranMode = prop.getProperty(TRAN_MODE)== null ? "" : prop.getProperty(TRAN_MODE); + + byte[] pDataBuff = (byte[])message; + byte[] pSndBuff = new byte[pDataBuff.length + WCAHeader.WCA_HEADER_LEN]; + byte[] pHeaderBuff = null; + + if (adapter_logger.isInfo()) { + adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] SEND - Properties = " + prop); + } + + if (adapter_logger.isDebug()) { + adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Data = " + MyUtil.printBytes(WCADefine.EBCDIC_CODE, pDataBuff.length, pDataBuff)); + } + + // 2. Properties에서 Header 정보를 구하여 송신데이타 조립 + WCAHeader header = new WCAHeader(); + header.setKey(sKey); + header.setLUName(prop.getProperty(LU_NAME)); + header.setMode(prop.getProperty(TRAN_MODE)); + header.setDataType(prop.getProperty(DATA_TYPE)); + header.toString(); + pHeaderBuff = header.getHeader(); + + System.arraycopy(pHeaderBuff, 0, pSndBuff, 0, WCAHeader.WCA_HEADER_LEN); + System.arraycopy(pDataBuff , 0, pSndBuff, WCAHeader.WCA_HEADER_LEN, pDataBuff.length); + + // 요청한 timeout으로 설정, 없을 경우 DB에 있는 값으로 한다. + String sTranTimeout = prop.getProperty(TRAN_TIMEOUT) == null ? "-1" : prop.getProperty(TRAN_TIMEOUT); + if (adapter_logger.isInfo()) { + adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] Client Request TRAN TIMEOUT = " + sTranTimeout); + } + + nTranTimeout = Integer.parseInt(sTranTimeout); + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapterClient:execute> [" + sAdapterGrpName + "] Key Str = " + sKey); + } + + // 3. Queue 생성 + WCAQueue queueWSA = new WCAQueue(pSndBuff.length, pSndBuff); + queueWSA.setKey(sKey); + queueWSA.setTimeout(nTranTimeout); + + try { + int nLuGrpCount = 1; + + // 4. LU 이름이 정의되었을 경우 해당 LU 세션 그룹 세션을 구한다. + if (!sLUName.trim().equals("")) { + if (adapter_logger.isInfo()) { + adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Dedicate 호출, LU 이름 = " + sLUName + ", So Set LU Group Count to 1."); + } + + // smanager.getGroupCode(sLUName); + ArrayList alInfo = smanager.getNodeAndGroupName(sLUName); + sCurNodeName = (String)alInfo.get(0); + sCurGroupCode = (String)alInfo.get(1); + } + else { + // 어댑터 그룹에 속한 WCA 세션 풀 크기를 구함 + nLuGrpCount = smanager.getLuGroupMapCount(sAdapterGrpName); + if (nLuGrpCount < 1) { + if (adapter_logger.isInfo()) { + adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Invalid LU Group Count, Count = " + nLuGrpCount + ", So Set Count to 1."); + } + nLuGrpCount = 1; + } + + if (adapter_logger.isInfo()) { + adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] LU Group Count = " + nLuGrpCount); + } + } + + int iSendCnt = 0; + + // 4. 전송 (LU 가 사용중일 경우 다른 LU 세션 그룹으로 전송한다.) + for (iSendCnt = 0; iSendCnt < nLuGrpCount; iSendCnt++) { + if (iSendCnt > 0) { + if (adapter_logger.isWarn()) { + adapter_logger.warn("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] LU 세션 사용중 -> 재송신 "); + } + } + + // 어댑터 그룹, LU 그룹 노드, LU 그룹에 해당하는 WCA 세션을 얻어옴 + wcaSession = getWCASession(queueWSA, sAdapterGrpName, sCurNodeName, sCurGroupCode); + + // 20200825 Start + if (wcaSession == null) { + throw new WCAException(WCAException.E_SOFTLINK_NO_SESSION_SLOT, toString()); + } + // 20200825 End + + // 얻어온 WCA 세션 정보 로깅 + if (adapter_logger.isInfo()) { + adapter_logger.warn("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Session = " + + wcaSession.toString() + ", Trans Timeout = " + wcaSession.getTranTimeout()); + } + + // 요청한 timeout으로 설정이 없을 경우 DB에 있는 값으로 한다. + if (nTranTimeout == -1) { + nTranTimeout = wcaSession.getTranTimeout() + 20; // DB 설정 값 + 20초 + queueWSA.setTimeout(nTranTimeout); + } + + // 얻어온 WCA 세션에서 LU 그룹 노드 이름 및 LU 그룹 이름 추출 + sCurNodeName = wcaSession.getNodeName(); + sCurGroupCode = wcaSession.getGroupCode(); + + wcaSession.registerRcvQueue(sKey, queueWSA); + wcaSession.sendData(pSndBuff.length, pSndBuff); + + if (adapter_logger.isDebug()) { + adapter_logger.warn("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Send Data OK"); + } + + // 호스트 데이터에 대한 수신 대기 + synchronized (queueWSA) { + if (adapter_logger.isDebug()) { + adapter_logger.warn("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Wait to Receive Response..."); + } + + // 데이터를 수신할때까지 대기... + if (queueWSA.getCurrQueueDataCnt() == 0) { + try { + if (adapter_logger.isDebug()) { + adapter_logger.warn("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] REMAIN_TRANSACTION_TIMEOUT = " + queueWSA.getRemainedTime()); + } + + // 20200724 Start + // 로그 레벨 변경 + // if (adapter_logger.isDebug()) { adapter_logger.warn("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Before Wait"); } + if (adapter_logger.isInfo()) { adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Before Wait"); } + // 20200724 End + + queueWSA.wait(queueWSA.getRemainedTime()); + + // 20200724 Start + // 로그 레벨 변경 + // if (adapter_logger.isDebug()) { adapter_logger.debug("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] After Wait"); } + if (adapter_logger.isInfo()) { adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] After Wait"); } + // 20200724 End + } + // 데이터를 수신하였거나, Timeout이 발생하면 세션 상태를 READY로 전환 + catch (InterruptedException ie) { + if (adapter_logger.isWarn()) { + adapter_logger.warn("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Interupt Wait"); + } + } + } + } + + // 5. 수신 데이타 확인 + // 수신 데이터 갯수 확인, 0인 경우, 타임 아웃 처리 + if (queueWSA.getCurrQueueDataCnt() == 0) { + if (adapter_logger.isInfo()) { + adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] RECV - Transaction Timeout"); + } + WCAException exception = new WCAException(WCAException.E_WCA_TRANTIMEOUT); + exception.setMessage(WCAException.displayError(WCAException.E_WCA_TRANTIMEOUT) + ", KEY = " + sKey ); + throw exception; + } + else { + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Try to get Data From WCAQueue"); + } + + // LU가 사용중인 경우 세션그룹 수 만큼 다른 세션 그룹에 할당한다. + //if (queueWSA.getResendFlag()) { + // 2010.11.16 갈길수차장, 홍명준팀장 요청 : LU연결 전체가 없을 경우 버그 수정 + + // 20191011 Start + // if (queueWSA.getResendFlag() && nLuGrpCount > 1) { + if (queueWSA.getResendFlag() && nLuGrpCount > 1 && (iSendCnt < (nLuGrpCount - 1))) { + // 20191011 End + queueWSA.initRecvData(); + continue; + } + + // 정상 수신 데이터 처리 + byte[] pRecvBuff = queueWSA.getDataFromQueue(); + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Host Data is Received..."); + adapter_logger.debug("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Transaction End..."); + } + + // 20200724 Start + // Debug 모드인 경우에 데이터 로깅 처리로 로그 레벨 변경 + /* + if (adapter_logger.isInfo()) { + adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] RECV - " + + MyUtil.printBytes(WCADefine.EBCDIC_CODE, pRecvBuff.length, pRecvBuff)); + } + */ + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] RECV - " + + MyUtil.printBytes(WCADefine.EBCDIC_CODE, pRecvBuff.length, pRecvBuff)); + } + // 20200724 End + + // property 설정 + byte[] pRecvModeBuff = new byte[WCAHeader.LEN_MODE]; + byte[] pRecvStatusBuff = new byte[WCAHeader.LEN_DATA_TYPE]; + byte[] pRecvLuNameBuff = new byte[WCAHeader.LEN_LUNAME]; + pRetBuff = new byte[pRecvBuff.length - WCAHeader.WCA_HEADER_LEN]; + + System.arraycopy(pRecvBuff, WCAHeader.OFFSET_MODE, pRecvModeBuff, 0, WCAHeader.LEN_MODE); + System.arraycopy(pRecvBuff, WCAHeader.OFFSET_LUNAME, pRecvLuNameBuff, 0, WCAHeader.LEN_LUNAME); + System.arraycopy(pRecvBuff, WCAHeader.OFFSET_DATA_TYPE, pRecvStatusBuff, 0, WCAHeader.LEN_DATA_TYPE); + System.arraycopy(pRecvBuff, WCAHeader.WCA_HEADER_LEN, pRetBuff, 0, pRecvBuff.length - WCAHeader.WCA_HEADER_LEN); + + // 20200724 Start + /* + if (new String(pRecvBuff).indexOf(WCAException.WCA_ERROR_PREFIX) != -1) { + prop.setProperty(DATA_TYPE, DATA_TYPE_ERROR); + + // 로그 + String sLogGroupCode = ""; + String sLogErrCode = new String(pRetBuff).substring(0, WCAException.SOFTLINK_ERROR_SIZE); + if (wcaSession != null) { + sLogGroupCode = wcaSession.getGroupCode(); + } + ClientUtil.getInstance().insertErrorLog(sAdapterGrpName, sLogGroupCode, sLUName, sTranMode, sKey, sLogErrCode); + } + // 20191011 Start + else if (new String(pRecvBuff).indexOf(WCAException.SOFTLINK_ERROR_PREFIX) != -1) { + prop.setProperty(DATA_TYPE, DATA_TYPE_ERROR); + + // 로그 + String sLogGroupCode = ""; + String sLogErrCode = new String(pRetBuff).substring(0, WCAException.SOFTLINK_ERROR_SIZE); + if (wcaSession != null) { + sLogGroupCode = wcaSession.getGroupCode(); + } + ClientUtil.getInstance().insertErrorLog(sAdapterGrpName, sLogGroupCode, sLUName, sTranMode, sKey, sLogErrCode); + } + // 20191011 End + */ + // public static final String SOFTLINK_ERROR_PREFIX = "RECEAISNA"; + // public static final String WCA_ERROR_PREFIX = "RECEAIOWA"; + + String strRecvErrorPrefix = ""; + if (pRetBuff != null && pRetBuff.length >= 12) { + byte[] pRecvErrorPrefix = new byte[6]; + System.arraycopy(pRetBuff, 0, pRecvErrorPrefix, 0, 6); + strRecvErrorPrefix = new String(pRecvErrorPrefix); + } + + if (strRecvErrorPrefix.compareTo("RECEAI") == 0) { + prop.setProperty(DATA_TYPE, DATA_TYPE_ERROR); + + byte[] pRecvErrorMsg = new byte[12]; + System.arraycopy(pRetBuff, 0, pRecvErrorMsg, 0, WCAException.SOFTLINK_ERROR_SIZE); + String strRecvErrorMsg = new String(pRecvErrorMsg); + + String sLogGroupCode = ""; + if (wcaSession != null) { + sLogGroupCode = wcaSession.getGroupCode(); + } + + ClientUtil.getInstance().insertErrorLog(sAdapterGrpName, sLogGroupCode, sLUName, sTranMode, sKey, strRecvErrorMsg); + } + // 20200724 End + else { + // DATA Type Propperties 변경 + ClientUtil.getInstance().setDataTypeProperty(new String(pRecvStatusBuff), prop); + + // 20070522 : LU_NAME Trim + prop.setProperty(LU_NAME, new String(pRecvLuNameBuff).trim()); + } + + break; + } + } + + // 20200724 Start + // Info 레벨로 변경 + /* + // 수신 시간 측정 + if (adapter_logger.isDebug()) { + lEndTime = System.currentTimeMillis(); + adapter_logger.debug("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Lapse time = " + (lEndTime - lStartTime) + "ms"); + } + */ + if (adapter_logger.isInfo()) { + lEndTime = System.currentTimeMillis(); + + long elapseTime = lEndTime - lStartTime; + + adapter_logger.info("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] Lapse time = " + elapseTime + "ms"); + + if (elapseTime > 5000) { + adapter_logger.error("SNAAdapterClient:execute> OVEROVERTIME [" + sAdapterGrpName + "] [" + sKey + "] Lapse time = " + elapseTime + "ms"); + } + else if (elapseTime > 1000) { + adapter_logger.error("SNAAdapterClient:execute> OVERTIME [" + sAdapterGrpName + "] [" + sKey + "] Lapse time = " + elapseTime + "ms"); + } + } + // 20200724 End + + return pRetBuff; + } + catch (WCAException wca) { + if (sKey != null && wcaSession != null) { + wcaSession.unregisterRcvQueue(sKey); + } + + if (adapter_logger.isError()) { + adapter_logger.error("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] " + wca.toString()); + } + + //wca.printStackTrace(); + + // 로그 + String sLogGroupCode = ""; + if (wcaSession != null) { + sLogGroupCode = wcaSession.getGroupCode(); + } + + ClientUtil.getInstance().insertErrorLog(sAdapterGrpName, sLogGroupCode, sLUName, sTranMode, sKey, wca.getErrorReturnCode()); + throw wca; + } + catch (Exception e) { + if (sKey != null && wcaSession != null) { + wcaSession.unregisterRcvQueue(sKey); + } + + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapterClient:execute> [" + sAdapterGrpName + "] [" + sKey + "] " + e.toString()); + } + adapter_logger.error("SNAAdapterClient:execute error", e); + throw new WCAException(e); + } + } + + + /** + * 1. 기능 : 타임아웃동 이용가능한 WCA 세션 (softlink와 연결된 TCP 세션)이 있을때까지 대기) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param queueWSA QUEUE 데이타 + * @param sAdapterGrpName 어댑터 그룹 이름 + * @param sNodeNmae LU 그룹 노드 이름 + * @param sGroupCode LU 그룹 이름 + * + * @return WCASession WCA Session Object + **/ + private WCASession getWCASession(WCAQueue queueWSA, String sAdapterGrpName, String sNodeName, String sGroupCode) throws WCAException { + if (queueWSA.getTimeout() == -1) { + queueWSA.setDefaultTimeout(WCADefine.DEFAULT_TRANSACTION_TIMEOUT); + } + + while (true) { + try { + return smanager.getWCASession(sAdapterGrpName, sNodeName, sGroupCode); + } + catch (WCAException e) { + // "WCA세션이 없는 경우"가 아니면 + if (!e.getErrorReturnCode().equals(WCAException.E_SOFTLINK_NO_SESSION_SLOT)) { + throw e; + } + + // 타임아웃 발생하였다면 + if (queueWSA.getRemainedTime() <= 0L) { + throw e; + } + else { + try { + Thread.sleep(100); + } + catch (InterruptedException interrupted) {} + + continue; + } + } + } + } +} + + + + diff --git a/src/main/java/com/eactive/eai/adapter/wca/SNAAdapterListener.java b/src/main/java/com/eactive/eai/adapter/wca/SNAAdapterListener.java new file mode 100644 index 0000000..0750103 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/SNAAdapterListener.java @@ -0,0 +1,111 @@ +package com.eactive.eai.adapter.wca; + +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListenerSupport; +import com.eactive.eai.adapter.wca.cfg.SNAAdapter; +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.common.util.ContainerUtil; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : SNAAdapter 어댑터 그룹 시작, 종료시 수행되어야 할 작업 +* 2. 처리 개요 : +* - 어댑터 그룹 시작시 SNAAdapterManager에 등록하며 세션 정보를 초기화한다. +* - 어댑터 그룹 종료시 세션 종료한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class SNAAdapterListener extends AdapterListenerSupport +{ + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + /** + * 1. 기능 : 어댑터 시작 메소드 + * 2. 처리 개요 : + * - SNAAdapterManager 등록 및 초기화, INBOUND handler 등록 + * 3. 주의사항 + * + * @exception AdapterException + **/ + public void start() throws AdapterException { + int nRet = 0; + + if (ContainerUtil.get() == ContainerUtil.TOMCAT) { + return; + } + + adapter_logger.warn("SNAAdapterListener:start> Try To Start Adapter, AdapterInfo = " + info); + + SNAAdapterManager smanager = SNAAdapterManager.getInstance(); + + String sAdapterGroupName = this.info.getAdapterGroupName(); + String sAdapterName = this.info.getName(); + // String eventListenerClass = PropManager.getInstance().getProperty(TableInfoEx.T_SNAADPTER_PROP_GROUP_NAME, "sna.event.listener.class"); + + // 어댑터 그룹:어댑터에 해당하는 SNA Adapter 추가 및 설정 + try { + // 기존에 해당 어댑터 그룹에 어댑터가 존재하는지 검사 + /* + SNAAdapter prevSnaAdapter = smanager.selectSnaAdapter(sAdapterGroupName); + if(prevSnaAdapter != null) { + adapter_logger.error("SNAAdapterListener:start> Already Adapter Exist, So Don't Create New Adapter, Adapter Group Name = " + sAdapterGroupName); + return; + } + */ + + // 새로운 SNAAdapter 오브젝트 생성 + SNAAdapter snaAdapter = new SNAAdapter(sAdapterGroupName, sAdapterName); + + // SNA Adapter에 해당하는 LU 그룹 정보 정보를 저장하기 위한 오브젝트 생성 및 LU 그룹에 대한 정보 Load + nRet = snaAdapter.initAdapter(); + if (nRet <= 0) { + adapter_logger.warn("SNAAdapterListener:start> " + info + " LU 세션 그룹 정보가 존재하지 않습니다."); + return; + } + + // SNA 어댑터 맵에 새롭게 생성한 SNA 어댑터 추가 + smanager.insertSnaAdapter(sAdapterGroupName, snaAdapter); + + // SNA 어댑터 시작 (어댑터에 속한 세션 Pool을 초기화하고 세션 Pool을 시작) + snaAdapter.startAdapter(); + + // sAdapter.registerEventHandler((WCAEventListener)(Class.forName(eventListenerClass).newInstance())); + + adapter_logger.warn("SNAAdapterListener:start> Success To Start Adapter, AdapterInfo = " + info); + } + catch (Exception e) { + adapter_logger.error("SNAAdapterListener:start> Exception Occurred, AdapterInfo = " + info + ", Msg = " + e.getMessage(), e); + } + } + + /** + * 1. 기능 : 어댑터 종료 메소드 + * 2. 처리 개요 : + * - 세션 종료 + * 3. 주의사항 + * + * @exception AdapterException + **/ + public void stop() throws AdapterException { + if (ContainerUtil.get() == ContainerUtil.TOMCAT) { + return; + } + + adapter_logger.warn("SNAAdapterListener:stop> Try To Stop Adapter, AdapterInfo = " + info); + + String adapterGroupName = this.info.getAdapterGroupName(); + String adapterName = this.info.getName(); + + SNAAdapterManager.getInstance().stopAdapter(adapterGroupName, adapterName); + + adapter_logger.warn("SNAAdapterListener:stop> Success To Stop Adapter, AdapterInfo = " + info); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/SNAAdapterTestCall.java b/src/main/java/com/eactive/eai/adapter/wca/SNAAdapterTestCall.java new file mode 100644 index 0000000..2a3c4c0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/SNAAdapterTestCall.java @@ -0,0 +1,52 @@ +package com.eactive.eai.adapter.wca; + +import com.eactive.eai.adapter.wca.cfg.SNAAdapter; +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.common.testcall.TestCallException; +import com.eactive.eai.common.testcall.TestCallSupport; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : SNAAdapter 동작 여부 판단 +* 2. 처리 개요 : +* - 어댑터 그룹에 속한 세션 상태를 반환 +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class SNAAdapterTestCall extends TestCallSupport +{ + /** + * SNAAdapter 트레이스를 위한 logger + */ + Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + /** + * 1. 기능 : 어댑터 시작 메소드 + * 2. 처리 개요 : + * - 어댑터 그룹에 해당하는 세션이 하나이상이면 true, 아니면 flase 반환 + * 3. 주의사항 + * + * @exception TestCallException + **/ + public boolean isAlive() throws TestCallException { + int nConnected = 0 ; + String adapterGroupName = this.adapterInfo.getAdapterGroupName(); + + if (trc_logger.isDebug()) { trc_logger.debug("SNAAdapterTestCall] ## adapterGroupName = " + adapterGroupName); } + SNAAdapter snaAdapter = SNAAdapterManager.getInstance().selectSnaAdapter(adapterGroupName); + if (snaAdapter == null) { + nConnected = 0; + return false; + } + + if (nConnected > 0) { + return true; + } + + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/SNAProperties.java b/src/main/java/com/eactive/eai/adapter/wca/SNAProperties.java new file mode 100644 index 0000000..6e389e2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/SNAProperties.java @@ -0,0 +1,70 @@ +package com.eactive.eai.adapter.wca; + +/** +* 1. 기능 : Client 호출 프로퍼티 KEY 및 VALUE 정의 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public interface SNAProperties +{ + // Properteis KEY 설정 + public static final String TRAN_KEY = "TRAN_KEY"; // Transaction 마다 유일한 Key 값 (UUID) + public static final String ADAPTER_GRP_NAME = "ADAPTER_GRP_NAME"; // Adapter Group Name + public static final String ADAPTER_NAME = "ADAPTER_NAME"; // Adapter Name + public static final String LU_NAME = "LU_NAME"; // LU Name (dedicate LU 일경우만 설정) + public static final String TRAN_MODE = "TRAN_MODE"; // Transaction Mode (Response / NonResponse) + public static final String DATA_TYPE = "DATA_TYPE"; // TimeOut Data, DFS, Normal Data + public static final String TRAN_TIMEOUT = "TRAN_TIMEOUT"; // TimeOut (단위 : 초) + + // Properties 값 설정 + public static final String TRAN_MODE_RESPONSE = "R"; // Response Transaction Mode + public static final String TRAN_MODE_NONRESPONSE = "N"; // NonResponse Transaction Mode + public static final String TRAN_MODE_TERMINAL = "T"; // 가상 터미널 TRAN_MODE_RESPONSE와 같이 처리 + + public static final String DATA_TYPE_FIRST = "F"; + public static final String DATA_TYPE_MIDDLE = "M"; + public static final String DATA_TYPE_LAST = "L"; + public static final String DATA_TYPE_ONLY = "O"; + + public static final String DATA_TYPE_NORMAL_PREFIX = "N"; + public static final String DATA_TYPE_NORMAL = DATA_TYPE_NORMAL_PREFIX + "D"; + public static final String DATA_TYPE_NORMAL_ONLY = DATA_TYPE_NORMAL_PREFIX + DATA_TYPE_ONLY; // Normal Data Type (only) + public static final String DATA_TYPE_NORMAL_FIRST = DATA_TYPE_NORMAL_PREFIX + DATA_TYPE_FIRST; // Normal Data Type (First) + public static final String DATA_TYPE_NORMAL_MIDDLE = DATA_TYPE_NORMAL_PREFIX + DATA_TYPE_MIDDLE; // Normal Data Type (Middle) + public static final String DATA_TYPE_NORMAL_LAST = DATA_TYPE_NORMAL_PREFIX + DATA_TYPE_LAST; // Normal Data Type (Last) + + public static final String DATA_TYPE_TIMEOUT_PREFIX = "T"; + public static final String DATA_TYPE_TIMEOUT = DATA_TYPE_TIMEOUT_PREFIX + "D"; + public static final String DATA_TYPE_TIMEOUT_ONLY = DATA_TYPE_TIMEOUT_PREFIX + DATA_TYPE_ONLY; // TimeOut Data (delayed data) Type (Only) + public static final String DATA_TYPE_TIMEOUT_FIRST = DATA_TYPE_TIMEOUT_PREFIX + DATA_TYPE_FIRST; // TimeOut Data (delayed data) Type (Fi) + public static final String DATA_TYPE_TIMEOUT_MIDDLE = DATA_TYPE_TIMEOUT_PREFIX + DATA_TYPE_MIDDLE; // TimeOut Data (delayed data) Type (Middle) + public static final String DATA_TYPE_TIMEOUT_LAST = DATA_TYPE_TIMEOUT_PREFIX + DATA_TYPE_LAST; // TimeOut Data (delayed data) Type (Last) + + public static final String DATA_TYPE_DFS_PREFIX = "D"; + public static final String DATA_TYPE_DFS = DATA_TYPE_DFS_PREFIX + "F"; + public static final String DATA_TYPE_DFS_ONLY = DATA_TYPE_DFS_PREFIX + DATA_TYPE_ONLY; + public static final String DATA_TYPE_DFS_FIRST = DATA_TYPE_DFS_PREFIX + DATA_TYPE_FIRST; + public static final String DATA_TYPE_DFS_MIDDLE = DATA_TYPE_DFS_PREFIX + DATA_TYPE_MIDDLE; + public static final String DATA_TYPE_DFS_LAST = DATA_TYPE_DFS_PREFIX + DATA_TYPE_LAST; + + public static final String DATA_TYPE_SEND_OK = "SO"; // SEND OK Data Type + public static final String DATA_TYPE_ERROR = "ER"; // ERROR Data Type + + public static final String DATA_TYPE_ADAPTER_OK = "AO"; // 자동 백업 명령 + public static final String DATA_TYPE_ADAPTER_ERROR = "AE"; // 자동 복구 명령 + + public static final String DATA_TYPE_GET_ADAPTER_STATUS = "QS"; // 현재 어댑터 status 반환 명령 + + // 20090810 Start + public static final String DATA_TYPE_APP_CODE = "CD"; // 현재 어댑터 Data Code 송신 명령 + // 20090810 End + + // 20190828 Start + public static final String DATA_TYPE_WCA_ADPT_INFO = "WN"; // 현재 WCA 어댑터 정보 송신 명령 + // 20190828 End +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/WCAEventInterface.java b/src/main/java/com/eactive/eai/adapter/wca/WCAEventInterface.java new file mode 100644 index 0000000..0f536fc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/WCAEventInterface.java @@ -0,0 +1,41 @@ + + +package com.eactive.eai.adapter.wca; + +/** +* 1. 기능 : INBOUND 처리 interface +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 24. 오전 10:33:12 +*/ +public interface WCAEventInterface { + /** + * 1. 기능 : 수신 타임 이후에 수신된 데이터 처리 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param adapterGrpName 어댑터 그룹 이름 + * @param adapterName 어댑터 이름 + * @param nLen 송신 길이 + * @param pBuff 송신 데이타 + **/ + public abstract void handleTimeoutData(String adapterGrpName, String adapterName, String sGroupCode, int nLen, byte[] pBuff); + + /** + * 1. 기능 : NonResponse Transaction Mode 데이터 처리 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param adapterGrpName 어댑터 그룹 이름 + * @param adapterName 어댑터 이름 + * @param nLen 송신 길이 + * @param pBuff 송신 데이타 + **/ + public abstract void handleNonRspData(String adapterGrpName, String adapterName, String sGroupCode, int nLen, byte[] pBuff); + +} + \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/WCAEventListener.java b/src/main/java/com/eactive/eai/adapter/wca/WCAEventListener.java new file mode 100644 index 0000000..de18980 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/WCAEventListener.java @@ -0,0 +1,162 @@ +package com.eactive.eai.adapter.wca; + +import com.eactive.eai.adapter.RequestDispatcher; +import com.eactive.eai.adapter.wca.data.WCAHeader; +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.util.MyUtil; +import com.eactive.eai.common.util.Logger; + +import java.util.Properties; + +/** +* 1. 기능 : INBOUND 처리 interface 구현 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class WCAEventListener implements WCAEventInterface, SNAProperties +{ + /** + * SNAAdapter 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + /** + * 1. 기능 : NonResponse Transaction Mode 데이터 처리 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param adapterGrpName 어댑터 그룹 이름 + * @param adapterName 어댑터 이름 + * @param nLen 송신 길이 + * @param pBuff 송신 데이타 + **/ + public void handleNonRspData(String adapterGrpName, String adapterName, String sGroupCode, int nLen, byte[] pBuff) { + WCAEventProcess(adapterGrpName, adapterName, sGroupCode, nLen, pBuff); + } + + /** + * 1. 기능 : NonResponse Transaction Mode 데이터 처리 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param adapterGrpName 어댑터 그룹 이름 + * @param adapterName 어댑터 이름 + * @param nLen 송신 길이 + * @param pBuff 송신 데이타 + **/ + public void handleTimeoutData(String adapterGrpName, String adapterName, String sGroupCode, int nLen, byte[] pBuff) { + WCAEventProcess(adapterGrpName, adapterName, sGroupCode, nLen, pBuff); + } + + /** + * 1. 기능 : INBOUND 데이타 처리 로직 + * 2. 처리 개요 : + * - Softlink 수신 데이타에서 프로퍼티 정보와 송신데이타 추출한다. + * - 프로퍼티 설정한다. + * - EAI INBOUND 호출한다. + * 3. 주의사항 + * + * @param adapterGrpName 어댑터 그룹 이름 + * @param adapterName 어댑터 이름 + * @param nLen 송신 길이 + * @param pBuff 송신 데이타 + **/ + private void WCAEventProcess(String adapterGrpName, String adapterName, String sGroupCode, int nLen, byte[] pBuff) { + try { + byte[] pDataBuff = new byte[pBuff.length - WCAHeader.WCA_HEADER_LEN]; + byte[] pHeaderBuff = new byte[WCAHeader.WCA_HEADER_LEN]; + + // 1. 프러퍼티 정보 및 송신 데이타 추출 + System.arraycopy(pBuff, 0, pHeaderBuff, 0, WCAHeader.WCA_HEADER_LEN); + System.arraycopy(pBuff, WCAHeader.WCA_HEADER_LEN, pDataBuff, 0, pBuff.length - WCAHeader.WCA_HEADER_LEN); + + WCAHeader header = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pHeaderBuff); + + // 2. 프로퍼티 설정 + Properties prop = new Properties(); + prop.setProperty(TRAN_KEY, header.getKey()); + prop.setProperty(ADAPTER_GRP_NAME, adapterGrpName); + prop.setProperty(ADAPTER_NAME, adapterName); + prop.setProperty(LU_NAME, header.getLUName()); + prop.setProperty(TRAN_MODE, String.valueOf(header.getMode())); + ClientUtil.getInstance().setDataTypeProperty(header.getDataType(), prop); + + // response mode 일고 normal 데이타인경우 -> DATA TYPE을 timeout으로 설정 + if (header.getDataType().length() == WCAHeader.LEN_DATA_TYPE && + (String.valueOf(header.getMode()).equals(TRAN_MODE_RESPONSE) || String.valueOf(header.getMode()).equals(TRAN_MODE_TERMINAL)) && + header.getDataType().substring(0,1).equals(DATA_TYPE_NORMAL_PREFIX)) { + prop.setProperty(DATA_TYPE, DATA_TYPE_TIMEOUT); + } + + // 20200724 Start + /* + if (new String(pDataBuff).indexOf(WCAException.WCA_ERROR_PREFIX) != -1) { + prop.setProperty(DATA_TYPE, DATA_TYPE_ERROR); + + // 로그 + String sLogErrCode = new String(pDataBuff).substring(0, WCAException.SOFTLINK_ERROR_SIZE); + + String luName = prop.getProperty(LU_NAME, ""); + String tranMode = prop.getProperty(TRAN_MODE, ""); + String tranKey = prop.getProperty(TRAN_KEY, ""); + + ClientUtil.getInstance().insertErrorLog(adapterGrpName, sGroupCode,luName, tranMode, tranKey, sLogErrCode); + } + */ + // public static final String WCA_ERROR_PREFIX = "RECEAIOWA"; + if (pDataBuff != null && pDataBuff.length >= 12) { + byte[] pRecvErrorPrefix = new byte[9]; + System.arraycopy(pDataBuff, 0, pRecvErrorPrefix, 0, 9); + String strRecvErrorPrefix = new String(pRecvErrorPrefix); + + if (strRecvErrorPrefix.compareTo(WCAException.WCA_ERROR_PREFIX) == 0) { + byte[] pRecvErrorMsg = new byte[12]; + System.arraycopy(pDataBuff, 0, pRecvErrorMsg, 0, WCAException.SOFTLINK_ERROR_SIZE); + String strRecvErrorMsg = new String(pRecvErrorMsg); + + prop.setProperty(DATA_TYPE, DATA_TYPE_ERROR); + + String luName = prop.getProperty(LU_NAME, ""); + String tranMode = prop.getProperty(TRAN_MODE, ""); + String tranKey = prop.getProperty(TRAN_KEY, ""); + + ClientUtil.getInstance().insertErrorLog(adapterGrpName, sGroupCode,luName, tranMode, tranKey, strRecvErrorMsg); + } + } + // 20200724 End + + // 20200724 Start + // Debug 모드인 경우에 데이터 로깅 처리로 로그 레벨 변경 + /* + if (adapter_logger.isInfo()) { + adapter_logger.info("WCAEventListener:WCAEventProcess> [" + adapterGrpName + "][" + adapterName + "] RECV - " + MyUtil.printBytes(WCADefine.EBCDIC_CODE, nLen, pBuff)); + } + */ + if (adapter_logger.isDebug()) { + adapter_logger.debug("WCAEventListener:WCAEventProcess> [" + adapterGrpName + "][" + adapterName + "] RECV - " + MyUtil.printBytes(WCADefine.EBCDIC_CODE, nLen, pBuff)); + } + // 20200724 End + + if (adapter_logger.isDebug()) { + adapter_logger.debug("WCAEventListener:WCAEventProcess> Call RequestDispatcher's Handle Function."); + } + + // 3. EAI INBOUND 호출 + Object obj = RequestDispatcher.getRequestDispatcher(adapterGrpName).handle(adapterName, pDataBuff, prop); + + if (adapter_logger.isDebug()) { + adapter_logger.debug("WCAEventListener:WCAEventProcess> Evnet Handler End... + "+obj); + } + } + catch (Exception e) { + adapter_logger.error("WCAEventListener:WCAEventProcess> [" + adapterGrpName + "][" + adapterName + "] Exception Msg = " + e.getMessage(), e); +// System.out.println("WCAEventProcess] error occures "); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/WCASession.java b/src/main/java/com/eactive/eai/adapter/wca/WCASession.java new file mode 100644 index 0000000..f3699b7 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/WCASession.java @@ -0,0 +1,452 @@ +package com.eactive.eai.adapter.wca; + +import com.eactive.eai.adapter.wca.cfg.SNAAdapter; +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.cfg.SessionGroupDataEx; +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.servlet.TableInfoEx; +import com.eactive.eai.adapter.wca.util.MyUtil; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : WCA 세션 정보 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 22. 오후 5:53:46 +*/ +public class WCASession { + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + private String sNodeName = ""; // Softlink Node Name + private String sIpAddr = null; // Softlink Ip 주소 + private int nPortNo = 0; // SoftLink Port 번호 + private Thread threadSession; // Softlink 수신 처리를 담당하는 스레드 + private String sAdapterGrpName = null; // 어댑터 그룹 이름 + private String sAdapterName = null; // 어댑터 이름 + private String sGroupCode = null; // LU 그룹 이름 + private WCASessionThread wcaSessionThread = null; // Softlink 수신 처리를 담당하는 WCA 세션 Runnable 클래스 + private int nSessNum; // WCA 세션 수 + private boolean bBackupSessionPool = false; // Backup 세션 여부 (true: 백업 세션) + + private boolean bLogYN = true; // 로깅 여부 + private int nLogLevel = 1; // 로그 레벨 + private int nLogSize = 4; // 로그 파일 사이즈 + private int nTransTimeout = WCADefine.DEFAULT_TRANSACTION_TIMEOUT * 1000; // 트랜잭션 타임아웃 + + private boolean bBackupEnableFlag = true; // 백업 세션 사용 가능여부 플래그 + private SNAAdapter snaAdapter = null; // WCA 세션을 포함하고 있는 SNAAdapter 오브젝트 + + public boolean getBackupEnableFlag() { + return bBackupEnableFlag; + } + + public void setBackupEnableFlag(boolean bBackupEnableFlag) { + this.bBackupEnableFlag = bBackupEnableFlag; + return; + } + + /** + * 1. 기능 : 노드 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodName 노드이름 + **/ + public void setNodeName(String sNodeName) { + if (sNodeName == null) { sNodeName = ""; } + this.sNodeName = sNodeName.trim(); + } + + /** + * 1. 기능 : 노드 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 노드이름 + **/ + public String getNodeName() { + return sNodeName; + } + + /** + * 1. 기능 : 세션 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 세션 정보 + **/ + public String toString() { + StringBuffer sTemp = new StringBuffer(); + + // 20090810 Start + // sTemp.append(" " + sAdapterGrpName + "-" + sGroupCode + "-" + nSessNum); + sTemp.append(" " + sAdapterGrpName + "-" + sNodeName + "-" + sGroupCode + "-" + nSessNum); + // 20090810 End + + if (bBackupSessionPool) { sTemp.append(":BACKUP "); } + else { sTemp.append(" "); } + + return sTemp.toString(); + } + + public String getLogPrefix() { + StringBuffer sTemp = new StringBuffer(); + + sTemp.append("[" + sAdapterGrpName + "][" + sNodeName + "][" + sGroupCode + "][" + nSessNum + "]"); + if (bBackupSessionPool) { sTemp.append("[BACKUP]"); } + + return sTemp.toString(); + } + + /** + * 1. 기능 : WCA 세션 생성자 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sIpAddr Softlink Ip 주소 + * @param nPortNo SoftLink Port 번호 + * @param sAdapterGrpName 어댑터 그룹 이름 + * @param sAdapterName 어댑터 이름 + * @param sGroupCode LU 그룹 이름 + * @param nSessId WCA 세션 수 + **/ + public WCASession(String sIpAddr, int nPortNo, String sAdapterGrpName, String sAdapterName, String sGroupCode, int nSessNum) { + this.sIpAddr = sIpAddr; + this.nPortNo = nPortNo; + this.sAdapterGrpName = sAdapterGrpName; + this.sAdapterName = sAdapterName; + this.sGroupCode = sGroupCode; + this.nSessNum = nSessNum; + snaAdapter = SNAAdapterManager.getInstance().selectSnaAdapter(sAdapterGrpName); + } + + /** + * 1. 기능 : 어댑터 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 어댑터 그룹 이름 + **/ + public String getAdapterGroupName() { + return sAdapterGrpName; + } + + /** + * 1. 기능 : LU 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 그룹 이름 + **/ + public String getGroupCode() { + return sGroupCode; + } + + /** + * 1. 기능 : 트랜잭션 타임아웃 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param timeout 트랜잭션 타임아웃 + **/ + public void setTranTimeout(int timeout) { + this.nTransTimeout = timeout; + } + + + /** + * 1. 기능 : 트랜잭션 타임아웃 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 트랜잭션 타임아웃 + **/ + public int getTranTimeout() { + return this.nTransTimeout; + } + + + /** + * 1. 기능 : Sotlink 세션 정보 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sIpAddr Softlink Ip 주소 + * @param nPortNo SoftLink Port 번호 + * @param nSessNum WCA 세션 수 + **/ + public void setSessionInfo(String sIpAddr, int nPortNo, int nSessNum) { + this.sIpAddr = sIpAddr; + this.nPortNo = nPortNo; + this.nSessNum = nSessNum; + } + + public void setSessionInfo(String sIpAddr, int nPortNo) { + this.sIpAddr = sIpAddr; + this.nPortNo = nPortNo; + } + + /** + * 1. 기능 : Sotlink 세션 정보 갱신 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sessgroup LU 세션 그룹 정보 + **/ + public void updateSessionInfoEx(SessionGroupDataEx sessgroup) { + // 로컬 세션인 경우 + if (!isBackupSessionPool()) { + setSessionInfo(sessgroup.getSoftLinkSevrName(), sessgroup.getPort()); + } + // 백업 세션인 경우 + else { + setSessionInfo(sessgroup.getBackupNodeName(), sessgroup.getBackupPort()); + } + + setLogInfo(sessgroup.isLogWritable(), sessgroup.getLogLevel(), sessgroup.getLogSize() ); + setTranTimeout(sessgroup.getTranTimeout()); + setBackupEnableFlag(sessgroup.getBackupEnableFlag()); + + wcaSessionThread.updateSessionInfoEx(sessgroup); + } + + /** + * 1. 기능 : WCA APP CODE 정보 갱신 (updateSessionInfoEx 함수를 참조하여 개발) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sessgroup LU 세션 그룹 정보 + **/ + public void updateWcaAppCodeEx() { + wcaSessionThread.updateWcaAppCodeEx(); + } + + /* + * 1. 기능 : 로그 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param bLogYN 로깅 여부 + * @param nLogLevel 로깅 레벨 + * @param nLogSize 로깅 파일 사이즈 + **/ + public void setLogInfo(boolean bLogYN, int nLogLevel, int nLogSize) { + this.bLogYN = bLogYN; + this.nLogLevel = nLogLevel; + this.nLogSize = nLogSize; + } + + + /** + * 1. 기능 : 백업 세션 여부 설정 (true: 백업 세션) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param flag 백업 세션 여부 + **/ + public void setBackupSessionPool(boolean flag) { + bBackupSessionPool = flag; + } + + /** + * 1. 기능 : 백업 세션 여부 반환 (true: 백업 세션) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 세션 여부 + **/ + public boolean isBackupSessionPool() { + return bBackupSessionPool; + } + + /** + * 1. 기능 : 데이터 송신별 수신 데이터를 대기할 Queue를 등록 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param objKey HashMap에 저장될 unique한 key (UUID) + * @param objData HashMap에 저장될 값 (송신에 대한 Queue 데이타) + * @return 0 + **/ + public int registerRcvQueue(Object objKey, Object objData) { + wcaSessionThread.registerRcvQueue(objKey, objData); + return 0; + } + + /** + * 1. 기능 : Queue에 등록된 송신에 대한 Queue 데이타 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param objKey HashMap에 저장될 unique한 key (UUID) + **/ + public void unregisterRcvQueue(Object objKey) { + wcaSessionThread.unregisterRcvQueue(objKey); + } + + /** + * 1. 기능 : Softlink와 연결된 세션수를 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Softlink와 연결된 세션수 + **/ + public int getConnectedSessNum() { + return wcaSessionThread.getConnectedSessNum(); + } + + /** + * 1. 기능 : 세션에 해당하는 Thread Group 이름 반환 + * 2. 처리 개요 : + * - Thread Group 이름은 LU 그룹 이름으로 한다. + * - 백업 세션일 경우 ":BACKUP"을 추가한다. + * 3. 주의사항 + * + * @return Thread Group 이름 + **/ + private String getThreadGroupName() { + StringBuffer sTemp = new StringBuffer(); + + // LU 그룹 이름이 rule에 따라 설정되지 않을 가능성을 대비하여 어댑터 그룹명까지 포함한다. + // LU 그룹 이름이 동일한 경우가 있을 경우, 스레드 그룹 이름이 동일하여 + // 해당 어댑터를 종료할때 제대로 종료되지 않을 가능성이 있다. + // sTemp.append(sAdapterGrpName + "-" + sGroupCode); + sTemp.append(sAdapterGrpName + "-" + sNodeName + "-" + sGroupCode); + if (bBackupSessionPool) { sTemp.append(":BACKUP"); } + return sTemp.toString(); + } + + /** + * 1. 기능 : 세션에 해당하는 Thread Group 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Thread Group + **/ + private ThreadGroup getThreadGroup() { + ThreadGroup threadGroup = snaAdapter.getThreadGroup(sNodeName, sGroupCode); + if (threadGroup == null) { + threadGroup = snaAdapter.putThreadGroup(sNodeName, sGroupCode, getThreadGroupName()); + } + + return threadGroup; + } + + /** + * 1. 기능 : 세션 초기화 + * 2. 처리 개요 : + * - Softlink 수신 처리를 담당하는 WCA 세션 Runnable 클래스 생성 및 세션 정보를 설정한다. + * - 수신 Thread 생성 및 start 시킨다. + * 3. 주의사항 + * + * @return 성공여부 (성공 : 0, 실패 : -1) + **/ + public int initWCASession() { + try { + String eventListenerClass = PropManager.getInstance().getProperty(TableInfoEx.T_SNAADPTER_PROP_GROUP_NAME, "sna.event.listener.class"); + WCAEventListener listener = (WCAEventListener)(Class.forName(eventListenerClass).newInstance()); + + // 20090810 Start + // wcaSessionThread = new WCASessionThread(sIpAddr, nPortNo, sAdapterGrpName, sAdapterName, sGroupCode, nSessNum, bBackupSessionPool, bLogYN, nLogLevel, nLogSize); + wcaSessionThread = new WCASessionThread(sNodeName, sIpAddr, nPortNo, sAdapterGrpName, sAdapterName, sGroupCode, nSessNum, bBackupSessionPool, bLogYN, nLogLevel, nLogSize); + // 20090810 End + + wcaSessionThread.setTranTimeout(nTransTimeout); + wcaSessionThread.registerEventHandler(listener); + + // 20090810 Start + wcaSessionThread.setBackupEnableFlag(bBackupEnableFlag); + // 20090810 End + + //threadSession = new Thread(getThreadGroup(),wcaSessionThread, wcaSessionThread.toString()); + + // " " + sNodeName + "-" + sAdapterGrpName + "-" + sGroupCode + "-" + nSessNum + " " + String sThreadName = MyUtil.replaceString(toString(), "<", ""); + sThreadName = MyUtil.replaceString(sThreadName, ">", ""); + threadSession = new Thread(getThreadGroup(), wcaSessionThread, sThreadName); + threadSession.setDaemon(false); + threadSession.start(); + + return 0; + } + catch (Exception e) { + if(adapter_logger.isError()) adapter_logger.error("initWCASesion] - [" + WCAException.E_ETC + "] " + toString() + " : " + e.toString(), e); + return -1; + } + } + + /** + * 1. 기능 : 세션 종료 + * 2. 처리 개요 : + * - WCA 세션 Runnable 클래스의 running 상태를 false로 설정한다. + * - Softlink TCP 세션 close한다. + * 3. 주의사항 + **/ + public void stopAdapter() { + wcaSessionThread.stopAdapter(); + wcaSessionThread.closeSoftLink(); + } + + /** + * 1. 기능 : INBOUND 핸들러 등록 + * 2. 처리 개요 : + * - WCA 세션 Runnable 클래스의 INBOUND 핸들러 등록한다. + * 3. 주의사항 + **/ + public void registerEventHandler(Object objHandler) { + wcaSessionThread.registerEventHandler(objHandler); + return; + } + + /** + * 1. 기능 : 수신 Thread TCP 세션 상태를 설정 + * 2. 처리 개요 : + * - WCA 세션 Runnable 클래스의 TCP 세션 상태를 설정한다. + * 0 : 연결안됨, 1 : TCP 세션 연결, 2 : TCP 세션 사용중 (사용안함) + * 3. 주의사항 + **/ + /* + public void setSessionStat(int nSessStat) { + wcaSessionThread.setSessionStat(nSessStat); + return; + } + */ + + /** + * 1. 기능 : OUTBOUND 데이타 송신 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public int sendData(int nLen, byte[] pBuff) throws WCAException { + return wcaSessionThread.sendData(nLen, pBuff); + } + + /** + * 1. 기능 : Softlink TCP 세션 가능 여부 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Softlink TCP 세션 가능 여부 (true : 사용가능) + **/ + public boolean isAvailable() { + return wcaSessionThread.isAvailable(); + } + + /** + * 1. 기능 : Softlink TCP 세션 close + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public void closeSoftLink() throws WCAException { + wcaSessionThread.closeSoftLink(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/WCASessionPool.java b/src/main/java/com/eactive/eai/adapter/wca/WCASessionPool.java new file mode 100644 index 0000000..9cc3d09 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/WCASessionPool.java @@ -0,0 +1,697 @@ +package com.eactive.eai.adapter.wca; + +import com.eactive.eai.adapter.wca.cfg.SessionGroupDataEx; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.common.util.Logger; + +import java.util.LinkedList; + +/** +* 1. 기능 : WCA 세션 풀 정보 +* 2. 처리 개요 : +* - LU 그룹별로 풀이 생성된다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 22. 오후 5:03:52 +*/ +public class WCASessionPool { + /** + * SNAAdapter 트레이스 로깅을 위한 logger + */ + Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + // 20090810 Start + private String sNodeName = ""; // Softlink Host Name + // 20090810 End + + private String sIpAddr = null; // Softlink Ip 주소 + private int nPortNo = 0; // SoftLink Port 번호 + private int nSessNum = 0; // WCA 세션 수 + private String sAdapterGroupName = null; // 어댑터 그룹 이름 + private String sAdapterName = null; // 어댑터 이름 + private String sGroupCode = null; // LU 그룹 이름 + + private int nLocalSessionIdx = 0; // Pool에 설정된 세션 수 + public LinkedList listWCASession = null; // Pool에 설정된 세션 리스트 + + private String sAutoBackupCvsYN = null; // 자동 BACKUP 모드 (Y: yes , N: No) + + // BACKUP 전환 FLAG를 하나만 세팅 --> 수동 백업 복귀시 무조건 정상세션으루 전환하기 위함 + private boolean bBackupMode = false; // BACKUP 전환 FLAG + + // 20090810 Start + private boolean bBackupEnableFlag = true; // 백업 기능 사용 가능 여부 + // 20090810 End + + private boolean bBackupSessionPool = false; // Backup Pool 여부 (true: 백업 세션) + + private boolean bLogYN = true; // 로깅 여부 + private int nLogLevel = 1; // 로그 레벨 + private int nLogSize = 4; // 로그 파일 사이즈 + + private int tran_timeout = WCADefine.DEFAULT_TRANSACTION_TIMEOUT ; // 트랜잭션 타임아웃 + + private boolean isStarted = false; // Pool 동작 여부 (true : 동작중) + + // 20090810 + public boolean getBackupEnableFlag() { + return bBackupEnableFlag; + } + + public void setBackupEnableFlag(boolean bBackupEnableFlag) { + this.bBackupEnableFlag = bBackupEnableFlag; + return; + } + // 20090810 End + + /** + * 1. 기능 : 노드 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodName 노드이름 + **/ + public void setNodeName(String s_node_name) { + if (s_node_name == null ) { s_node_name = ""; } + this.sNodeName = s_node_name.trim(); + } + + /** + * 1. 기능 : 노드 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 노드이름 + **/ + public String getNodeName() { + return this.sNodeName; + } + + /** + * 1. 기능 : WCA 세션 POOL Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sIpAddr Softlink Ip 주소 + * @param nPortNo SoftLink Port 번호 + * @param nSessId WCA 세션 수 + **/ + public WCASessionPool(String sIpAddr, int nPortNo, int nSessNum) { + this.sIpAddr = sIpAddr; + this.nPortNo = nPortNo; + this.nSessNum = nSessNum; + listWCASession = new LinkedList(); + } + + /** + * 1. 기능 : 세션 Pool 정보 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGroupName 어댑터 그룹 이름 + * @param sAdapterName 어댑터 이름 + * @param sGrpCode LU 그룹 이름 + **/ + public void setSessionPoolInfo(String sAdapterGroupName, String sAdapterName, String sGroupCode) { + this.sAdapterGroupName = sAdapterGroupName; + this.sAdapterName = sAdapterName; + this.sGroupCode = sGroupCode; + } + + + /** + * 1. 기능 : 세션 Pool 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 세션 Pool 정보 + **/ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(" " + sNodeName + "-" + sGroupCode ); + if (bBackupSessionPool) { sb.append(":BACAKUP "); } + else { sb.append(" "); } + return sb.toString(); + } + + /** + * 1. 기능 : 어댑터 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 어댑터 그룹 이름 + **/ + public String getAdapterGroupName() { + return sAdapterGroupName; + } + + /** + * 1. 기능 : 어댑터 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 어댑터 이름 + **/ + public String getAdapterName() { + return sAdapterName; + } + + /** + * 1. 기능 : Softlink Ip 주소 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Softlink Ip 주소 반환 + **/ + public String getHostName() { + return sIpAddr; + } + + /** + * 1. 기능 : Softlink Port 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Softlink Ip Port 반환 + **/ + public int getPort() { + return nPortNo; + } + + /** + * 1. 기능 : LU 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 그룹 이름 + **/ + public String getGroupCode() { + return sGroupCode; + } + + /** + * 1. 기능 : WCA 세션 수 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return WCA 세션 수 반환 + **/ + public int getSessNum() { + return nSessNum; + } + + /** + * 1. 기능 : Sotlink 세션 정보 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sIpAddr Softlink Ip 주소 + * @param nPortNo SoftLink Port 번호 + * @param nSessNum WCA 세션 수 + **/ + public void setSessionInfo(String sNodeName, String sIpAddr, int nPortNo, int nSessNum) { + this.sNodeName = sNodeName; + this.sIpAddr = sIpAddr; + this.nPortNo = nPortNo; + this.nSessNum = nSessNum; + } + + /** + * 1. 기능 : 트랜잭션 타임아웃 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param timeout 트랜잭션 타임아웃 + **/ + public void setTranTimeout(int timeout) { + this.tran_timeout = timeout; + } + + + + /** + * 1. 기능 : 트랜잭션 타임아웃 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 트랜잭션 타임아웃 + **/ + public int getTranTimeout() { + return this.tran_timeout; + } + + + /** + * 1. 기능 : 세션 Pool이 동작 여부 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 세션 Pool이 동작 여부 + **/ + public boolean isStarted() { + return isStarted; + } + + + /** + * 1. 기능 : 로그 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param bLogYN 로깅 여부 + * @param nLogLevel 로깅 레벨 + * @param nLogSize 로깅 파일 사이즈 + **/ + public void setLogInfo(boolean bLogYN, int nLogLevel, int nLogSize) { + this.bLogYN = bLogYN; + this.nLogLevel = nLogLevel; + this.nLogSize = nLogSize; + } + + /** + * 1. 기능 : 세션 정보 갱신 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sessgroup LU 세션 그룹 정보 + **/ + public void updateLuGroupInfoEx(SessionGroupDataEx sessgroup) { + WCASession wcaSession = null; + + String sLogStr = "[" + sNodeName + "][" + sGroupCode + "]"; + + if (bBackupSessionPool) { + sLogStr += "[BACAKUP]"; + } + + // 로컬 세션 Pool인 경우 + if (!isBackupSessionPool()) { + adapter_logger.warn("WCASessionPool:updateLuGroupInfoEx> " + sLogStr + " 세션 정보 설정, Value = [" + sessgroup.getNodeName() + "][" + + sessgroup.getSoftLinkSevrName() + "][" + sessgroup.getPort() + "][" + sessgroup.getSessionCnt() + "]"); + setSessionInfo(sessgroup.getNodeName(), sessgroup.getSoftLinkSevrName(), sessgroup.getPort(), sessgroup.getSessionCnt()); + + adapter_logger.warn("WCASessionPool:updateLuGroupInfoEx> " + sLogStr + " 백업 전환 모드 설정"); + setBackupCvsInfo(sessgroup.getBackupCvsMode()); + } + // 백업 세션 Pool인 경우 + else { + adapter_logger.warn("WCASessionPool:updateLuGroupInfoEx> " + sLogStr + " 백업 세션 정보 설정, Value = [" + sessgroup.getNodeName() + "][" + + sessgroup.getBackupNodeName() + "][" + sessgroup.getBackupPort() + "][" + sessgroup.getSessionCnt() + "]"); + setSessionInfo(sessgroup.getNodeName(), sessgroup.getBackupNodeName(), sessgroup.getBackupPort(), sessgroup.getSessionCnt()); + } + + adapter_logger.warn("WCASessionPool:updateLuGroupInfoEx> " + sLogStr + " 로그 관련 정보 설정, Value = [" + sessgroup.isLogWritable() + "][" + + sessgroup.getLogLevel() + "][" + sessgroup.getLogSize() + "]"); + setLogInfo(sessgroup.isLogWritable(), sessgroup.getLogLevel(), sessgroup.getLogSize()); + + adapter_logger.warn("WCASessionPool:updateLuGroupInfoEx> " + sLogStr + " 트랜잭션 타임아웃 값 설정, Value = " + sessgroup.getTranTimeout()); + setTranTimeout(sessgroup.getTranTimeout()); + + // 백업 세션 사용 가능 여부 플래그 설정 + adapter_logger.warn("WCASessionPool:updateLuGroupInfoEx> " + sLogStr + " 백업 세션 사용 가능 여부 플래그 설정, Value = " + sessgroup.getBackupEnableFlag()); + setBackupEnableFlag(sessgroup.getBackupEnableFlag()); + + // 세션 풀 안에 존재하는 WCA Session 오브젝트 정보 갱니 + for (int i = 0; i < listWCASession.size(); i++) { + wcaSession = (WCASession)listWCASession.get(i); + if (wcaSession == null) { + continue; + } + + wcaSession.updateSessionInfoEx(sessgroup); + } + } + + /** + * 1. 기능 : WCA APP CODE 정보 갱신 (updateLuGroupInfoEx 함수를 참조하여 개발) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sessgroup LU 세션 그룹 정보 + **/ + public void updateWcaAppCodeEx() { + WCASession wcaSession = null; + + // 세션 풀 안에 존재하는 WCA Session 오브젝트 정보 갱니 + for (int i = 0; i < listWCASession.size(); i++) { + wcaSession = (WCASession)listWCASession.get(i); + if (wcaSession == null) { + continue; + } + + wcaSession.updateWcaAppCodeEx(); + } + } + + /** + * 1. 기능 : 백업 정보 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAutoBackupCvsYN 자동 백업 전환 여부 + **/ + public void setBackupCvsInfo(String sAutoBackupCvsYN) { + this.sAutoBackupCvsYN = sAutoBackupCvsYN; + } + + public String getBackupCvsInfo() { + return sAutoBackupCvsYN; + } + + /** + * 1. 기능 : 백업 세션 여부 설정 (true: 백업 세션) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param flag 백업 세션 여부 + **/ + public void setBackupSessionPool(boolean flag) { + bBackupSessionPool = flag; + } + + /** + * 1. 기능 : 백업 세션 여부 반환 (true: 백업 세션) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 세션 여부 + **/ + public boolean isBackupSessionPool() { + return bBackupSessionPool; + } + + /** + * 1. 기능 : 수동 백업 세션 전환 설정 (true : 백업 세션, false : 세션 복구) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param flag 백업 전환 모드 + **/ + public void setManualBackupMode(boolean flag) { + // bManualBackupMode = flag; + bBackupMode = flag; + + if (flag == true) { + adapter_logger.warn("WCASessionPool:setManualBackupMode> " + toString() + "수동 백업모드로 전환되었습니다."); + } + else { + adapter_logger.warn("WCASessionPool:setManualBackupMode> " + toString() + "수동 백업모드로 복구되었습니다."); + } + } + + /** + * 1. 기능 : 자동 백업 세션 전환 설정 (true : 백업 세션, false : 세션 복구) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param flag 백업 전환 모드 + **/ + public void setAutoBackupMode(boolean flag) { + if (sAutoBackupCvsYN.equalsIgnoreCase(WCADefine.WCA_AUTO_BACKUP_CVS_MODE_YES)) { + bBackupMode = flag; + if (flag == true) { + if (adapter_logger.isInfo()) { adapter_logger.info(toString() + "자동 백업 모드 메시지 수신하었습니다."); } + } + else { + if (adapter_logger.isInfo()) { adapter_logger.info(toString() + "자동 백업 복구 메세지 수신하였습니다."); } + } + } + else { + if (flag == true) { + if (adapter_logger.isInfo()) { adapter_logger.info(toString() + "자동 백업 모드 메시지 수신하었습니다. 자동 백업 모드가 아닙니다."); } + } + else { + if (adapter_logger.isInfo()) { adapter_logger.info(toString() + "자동 백업 복구 메세지 수신하였습니다. 자동 백업 모드가 아닙니다."); } + } + } + } + + public void setWCAAutoBackup() { + if (sAutoBackupCvsYN.equalsIgnoreCase(WCADefine.WCA_AUTO_BACKUP_CVS_MODE_YES)) { + bBackupMode = true; + adapter_logger.warn(toString() + "가용율이 0입니다. 백업 모드로 전환합니다."); + } + else { + adapter_logger.warn(toString() + "가용율이 0입니다. 자동 백업 모드가 아닙니다."); + } + } + + /** + * 1. 기능 : 백업 모드로 전환되었는지 판단 (true: 백업 세션) + * 2. 처리 개요 : + * 다음의 경우 백업 모드로 전환 + * - 수동 백업 전환 메세지 수신한 경우 + * - 자동 백업 모드가 YES 이고 자동 백업 전환 메세지 수신한 경우 + * 3. 주의사항 + * + * @return 백업 전환 여부 + **/ + public boolean getBackupMode() { + return bBackupMode; + } + + /** + * 1. 기능 : Softlink와 연결된 세션수를 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Softlink와 연결된 세션수 + **/ + public int getConnectedSessNum() { + int nTotalSessNum = 0; + WCASession wcaSession = null; + + for (int i = 0; i < nSessNum; i++) { + if (listWCASession.size() <= i) { break; } + wcaSession = (WCASession)listWCASession.get(i); + nTotalSessNum += wcaSession.getConnectedSessNum(); + } + + return nTotalSessNum; + } + + /** + * 1. 기능 : Softlink와 설정된 세션수를 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Softlink와 설정된 세션수 + **/ + public int getConfiguredSessNum() { + return nSessNum; + } + + /** + * 1. 기능 : 세션 Pool 초기화 + * 2. 처리 개요 : + * - WCA 세션 수 만큼 WCASession을 생성 및 초기화한다. + * - WCA 세션 리스트에 추가한다. + * - isStarted를 true 로 설정한다. + * 3. 주의사항 + * + **/ + // 20200603 Start + // 백업 세션 연결 처리를 위해서 WCA Session Thread에 의해서 호출되는 경우, 백업 세션이 정해진 세션수보다 늘어나는 것을 방지하기 위해서 synchronized 함수로 변경 + // public void initAndStartWcaSessionInSessionPool() { + public synchronized void initAndStartWcaSessionInSessionPool() { + // 20200603 end + WCASession wcaSession = null; + int wcsSessionCount = 0; + + // 20200603 Start + // isStarted 값 설정 위치를 함수 시작 위치로 이동 + adapter_logger.error("WCASessionPool:initAndStartWcaSessionInSessionPool> " + toString() + ", Start, Set isStarted = true"); + isStarted = true; + // 20200603 End + + for (int i = 0; i < nSessNum; i++) { + // 20200603 Start + synchronized (listWCASession) { + wcsSessionCount = listWCASession.size(); + } + + if (wcsSessionCount >= nSessNum) { + adapter_logger.error("WCASessionPool:initAndStartWcaSessionInSessionPool> " + toString() + ", Already Max Session Count"); + break; + } + // 20200603 End + + wcaSession = new WCASession(sIpAddr, nPortNo, sAdapterGroupName, sAdapterName, sGroupCode, i); + wcaSession.setBackupSessionPool(bBackupSessionPool); + wcaSession.setLogInfo(bLogYN, nLogLevel, nLogSize); + wcaSession.setTranTimeout(tran_timeout); + + // 20090810 Start + wcaSession.setNodeName(sNodeName); + wcaSession.setBackupEnableFlag(bBackupEnableFlag); + // 20090810 End + + wcaSession.initWCASession(); + + adapter_logger.error("WCASessionPool:initAndStartWcaSessionInSessionPool> " + toString() + ", Add wcaSession to listWCASession"); + + synchronized (listWCASession) { + listWCASession.addLast(wcaSession); + } + } + + // 20200603 Start + // isStarted 값 설정 위치를 함수 시작 위치로 이동 + /* + adapter_logger.error("WCASessionPool:initAndStartWcaSessionInSessionPool> " + toString() + ", Set isStarted = true"); + isStarted = true; + */ + // 20200603 End + + return; + } + + /** + * 1. 기능 : 세션 수 추가 + * 2. 처리 개요 : + * - 증가한 세션수 만큼 WCASession을 생성 및 초기화한다. + * - WCA 세션 리스트에 추가한다. + * 3. 주의사항 + * + **/ + public void increaseSessionPool(int nOldSessNum, int nNewSessNum) { + WCASession wcaSession = null; + + if (adapter_logger.isDebug()) { adapter_logger.debug(toString() + " increaseSessionPool is starting"); } + + for (int i = nOldSessNum; i < nNewSessNum; i++) { + wcaSession = new WCASession(sIpAddr, nPortNo, sAdapterGroupName, sAdapterName, sGroupCode, i); + wcaSession.setBackupSessionPool(bBackupSessionPool); + wcaSession.setLogInfo(bLogYN, nLogLevel, nLogSize); + wcaSession.setTranTimeout(tran_timeout); + + wcaSession.initWCASession(); + + synchronized (listWCASession) { + listWCASession.addLast(wcaSession); + } + } + + adapter_logger.warn("WCASessionPool:increaseSessionPool> " + toString() + " " + (nNewSessNum - nOldSessNum) + " 세션이 증가하였습니다. "); + } + + /** + * 1. 기능 : 세션 Pool 종료 + * 2. 처리 개요 : + * - WCA 세션 리스트에 등록된 WCA 세션의 stopAdapter를 호출한다. + * 3. 주의사항 + **/ + public void stopAdapter() { + String strLogPrefix = getLogPrefix(); + + adapter_logger.warn("WCASessionPool:stopAdapter> " + strLogPrefix + " Start To Stop WCA Session List"); + adapter_logger.warn("WCASessionPool:stopAdapter> " + strLogPrefix + " WCA Session Count = " + listWCASession.size()); + + for (int i = 0; i < listWCASession.size(); i++) { + WCASession wcaSession = (WCASession)listWCASession.get(i); + wcaSession.stopAdapter(); + } + + adapter_logger.warn("WCASessionPool:stopAdapter> " + strLogPrefix + " Clear WCA Session List"); + synchronized (listWCASession) { + listWCASession.clear(); + } + + adapter_logger.warn("WCASessionPool:stopAdapter> " + strLogPrefix + " Set isStarted Flag to False"); + isStarted = false; + + adapter_logger.warn("WCASessionPool:stopAdapter> " + strLogPrefix + " Start To Stop WCA Session List"); + } + + public String getLogPrefix() { + StringBuffer sbLogPrefix = new StringBuffer(); + sbLogPrefix.append("[" + sAdapterGroupName + "][" + sNodeName + "]["+ sGroupCode + "]"); + if (bBackupSessionPool) { + sbLogPrefix.append("[BACAKUP]"); + } + + return sbLogPrefix.toString(); + } + + /** + * 1. 기능 : INBOUND 핸들러 등록 + * 2. 처리 개요 : + * - WCA 세션 리스트에 등록된 WCA 세션에 INBOUND 핸들러 등록한다. + * 3. 주의사항 + **/ + public void registerEventHandler(Object objHandler) { + int i; + WCASession wcaSession = null; + + for (i = nLocalSessionIdx; i < listWCASession.size(); i++) { + wcaSession = (WCASession)listWCASession.get(i); + wcaSession.registerEventHandler(objHandler); + } + + return; + } + + + /** + * 1. 기능 : WCA 세션을 반환 + * 2. 처리 개요 : + * - 세션 Pool이 송신 가능한지 판단한다. (트랜잭션 모드가 "S" 일경우) + * - WCA 세션풀내에서 이용가능한 세션을 부하 분산울 위해서 라운드 로빈 방식으로 구한다. + * 3. 주의사항 + * + * @return WCASession WCA 세션 + **/ + public synchronized WCASession getWCASessionInSessionPool() { + WCASession wcaSession = null; + int i = 0; + + // 해당 세션이 없을 경우 + if (listWCASession.size() == 0) { + if (trc_logger.isInfo()) { + trc_logger.info("getWCASessionInSessionPool] - listWCASession Size = 0 " + toString()); + } + + return null; + } + + // WCA 세션 풀에서 부하 분산을 위해서 라운드 로빈 방식으로 WCA 세션을 구함 + nLocalSessionIdx = nLocalSessionIdx % listWCASession.size(); + for (i = nLocalSessionIdx; i < listWCASession.size(); i++) { + wcaSession = (WCASession)listWCASession.get(i); + if (wcaSession.isAvailable()) { + nLocalSessionIdx++; + return wcaSession; + } + } + + if (i == listWCASession.size()) { + for (i = 0; i < nLocalSessionIdx; i++) { + wcaSession = (WCASession)listWCASession.get(i); + if (wcaSession.isAvailable()) { + nLocalSessionIdx++; + return wcaSession; + } + } + } + + nLocalSessionIdx++; + //trc_logger.error("getWCASessionInSessionPool] Available Session doesn't Exist...." + toString() ); + + return null; + } + + public int getPortNo() { + return nPortNo; + } + + public void setPortNo(int nPortNo) { + this.nPortNo = nPortNo; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/WCASessionThread.java b/src/main/java/com/eactive/eai/adapter/wca/WCASessionThread.java new file mode 100644 index 0000000..2536f9f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/WCASessionThread.java @@ -0,0 +1,2048 @@ +package com.eactive.eai.adapter.wca; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.SocketException; +import java.net.SocketTimeoutException; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.wca.cfg.SNAAdapter; +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.cfg.SessionGroupDataEx; +import com.eactive.eai.adapter.wca.data.AppCodeCmd; +import com.eactive.eai.adapter.wca.data.ManualBackupCmd; +import com.eactive.eai.adapter.wca.data.WCAAdapterInfoCmd; +import com.eactive.eai.adapter.wca.data.WCAHeader; +import com.eactive.eai.adapter.wca.data.WCAQueue; +import com.eactive.eai.adapter.wca.data.WCAQueueData; +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.util.CodeCvrt; +import com.eactive.eai.adapter.wca.util.MyLog; +import com.eactive.eai.adapter.wca.util.MyUtil; +import com.eactive.eai.common.errorcode.ErrorCodeHandler; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.LogKeys; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.SMSLogUtil; + +/** +* 1. 기능 : Softlink TCP 세션 연결 및 수신 데이타를 처리한다. +* 2. 처리 개요 : +* - +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 17. 오후 10:01:13 +*/ +public class WCASessionThread implements Runnable { + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + // 20090810 Start + private String sNodeName = ""; // Softlink Node Name + // 20090810 End + + private Socket sockSoftLink = null; // SoftLink와 연결할 Socket + //private BufferedInputStream isSoftLink = null; // Socket에 대한 InputStream + private InputStream isSoftLink = null; // Socket에 대한 InputStream + private BufferedOutputStream osSoftLink = null; // Socket에 대한 OutputStream + private HashMap hmapRcvData = null; // 세션에서 수신된 데이터를 저장할 Queue에 대한 HashMap + private MyLog myLog = null; // 메시지 로그 처리 오브젝트 + private MyLog myTrc = null; // 트레이스 처리 오브젝트 + private String sIpAddr = null; // SoftLink IP 주소 + private int nPortNo = 0; // SoftLink Port 번호 + private String sAdapterGroupName = null; // SoftLink 세션에 대한 Adapter Group Name + private String sAdapterName = null; // SoftLink 세션에 대한 Adapter Name + private String sGroupCode = null; // SoftLink 세션에 대한 Group Code + private int nSessId = 0; // SoftLiInk 세션 ID + private WCAEventInterface wcaEventHandler = null; // SoftLiInk 세션에 대한 수신 데이터 처리 이벤트 핸들러 + + private int nRcvTimeout = 0; // 데이터 수신 Timeout + private int nConnTimeout = 0; // 세션 연결 Timeout + private int nSessStat = 0; // TCP 세션 상태 0 : 연결안됨, 1 : TCP 세션 연결, 2 : TCP 세션 사용중 (사용안함) + + private int nDisconnectCnt = 0; // 세션 해제 횟수 + private int nContinuousDisconnectCnt = 0; // 연속적으로 세션 연결 실패 횟수 + private int nSndCnt = 0; // 데이터 송신 횟수 + private int nRcvCnt = 0; // 데이터 수신 횟수 + + private boolean bRunning = false; // Thread 동작 여부 + private boolean bBackupSessionPool = false; // Backup 세션 여부 + + // Softlink IP 주소가 여러개인 경우, 백업 모드 기능 자체를 사용할 수 없음 + private boolean bBackupEnableFlag = true; // Backup 세션 전환 사용 가능 여부 + + private boolean bBeforeConn = false; // 이전 TCP 세션 연결 여부 + + private int tran_timeout = WCADefine.DEFAULT_TRANSACTION_TIMEOUT ; // 트랜잭션 타임아웃 + private String tran_mode; // 송신(S),수신(R) 모드 + + long lReadStartTime = 0L, lReadEndTime = 0L, lNotifyEndTime = 0L; + + private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd=HH:mm:ss.SSS"); + + private SNAAdapter snaAdapter = null; + + // 20090810 + public boolean getBackupEnableFlag() { + return bBackupEnableFlag; + } + + public void setBackupEnableFlag(boolean bBackupEnableFlag) { + this.bBackupEnableFlag = bBackupEnableFlag; + return; + } + // 20090810 End + + + /** + * 1. 기능 : 노드 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodName 노드이름 + **/ + public void setNodeName(String s_node_name) { + if (s_node_name == null) { s_node_name = ""; } + this.sNodeName = s_node_name.trim(); + } + + /** + * 1. 기능 : 노드 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 노드이름 + **/ + public String getNodeName() { + return this.sNodeName; + } + + /** + * 1. 기능 : 세션 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 세션 정보 + **/ + public String toString() { + StringBuffer sb_name = new StringBuffer(); + + sb_name.append(" " + sGroupCode + "-" + nSessId); + + if (bBackupSessionPool) { + sb_name.append(":BACKUP "); + } + else { + sb_name.append(" "); + } + + return sb_name.toString(); + } + + /** + * 1. 기능 : INBOUND 핸들러 등록 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public void registerEventHandler(Object objHandler) { + wcaEventHandler = (WCAEventInterface)objHandler; + return; + } + + /** + * 1. 기능 : 트랜잭션 타임아웃 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param timeout 트랜잭션 타임아웃 + **/ + public void setTranTimeout(int timeout) { + this.tran_timeout = timeout; + } + + /** + * 1. 기능 : 트랜잭션 타임아웃 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 트랜잭션 타임아웃 + **/ + public int getTranTimeout() { + return this.tran_timeout; + } + + /** + * 1. 기능 : 트랜잭션 송수신 모드 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sTranMode 트랜잭션 송수신 모드 + **/ + public void setTranMode(String sTranMode) { + if (sTranMode == null ) { sTranMode = ""; } + this.tran_mode = sTranMode; + } + + /** + * 1. 기능 : 트랜잭션 송수신 모드 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 트랜잭션 송수신 모드 + **/ + public String getTranMode() { + return this.tran_mode; + } + + /** + * 1. 기능 : Sotlink 세션 정보 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sIpAddr Softlink Ip 주소 + * @param nPortNo SoftLink Port 번호 + * @param nSessNum WCA 세션 수 + **/ + public void setSessionInfo(String sIpAddr, int nPortNo) { + this.sIpAddr = sIpAddr; + this.nPortNo = nPortNo; + } + + public void updateSessionInfoEx(SessionGroupDataEx sessgroup) { + // 로컬 세션인 경우 + if (!isBackupSessionPool()) { + setSessionInfo(sessgroup.getSoftLinkSevrName(), sessgroup.getPort()); + } + // 백업 세션인 경우 + else { + setSessionInfo(sessgroup.getBackupNodeName(), sessgroup.getBackupPort()); + } + + setLogInfo(sessgroup.isLogWritable(), sessgroup.getLogLevel(), sessgroup.getLogSize()); + setTranTimeout(sessgroup.getTranTimeout()); + setBackupEnableFlag(sessgroup.getBackupEnableFlag()); + + // APP_CODE 프라퍼티가 변경되었을 경우, Softlink에게 데이터 전송 + try { + sendWcaSessionAppCode(true); + } + catch (Exception e) { + adapter_logger.warn("WCASessionThread:updateSessionInfoEx> Exception Msg = " + e.getMessage()); + } + + myLog.logMsg(MyLog.INFO, toString() + " 세션 정보 갱신 " + sessgroup.toString()); + } + + // 2020.05.27 updateSessionInfoEx 함수를 참조하여 개발함 + public void updateWcaAppCodeEx() { + // APP_CODE 프라퍼티가 변경되었을 경우, Softlink에게 데이터 전송 + try { + adapter_logger.warn("WCASessionThread:updateWcaAppCodeEx> Try to Send Wca AppCode"); + sendWcaSessionAppCode(false); + } + catch (Exception e) { + adapter_logger.warn("WCASessionThread:updateWcaAppCodeEx> Exception Msg = " + e.getMessage()); + } + + myLog.logMsg(MyLog.INFO, toString() + " WCA APP CODE 정보 갱신"); + } + + /** + * 1. 기능 : 로그 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param bLogYN 로깅 여부 + * @param nLogLevel 로깅 레벨 + * @param nLogSize 로깅 파일 사이즈 + **/ + public void setLogInfo(boolean bLogYN, int nLogLevel, int nLogSize) { + if (myLog != null) { + myLog.setLogLevel(nLogLevel); + myLog.setTraceOnOff(bLogYN); + myLog.setMaxLogFileSize(nLogSize); + } + + if (myTrc != null) { + myTrc.setLogLevel(nLogLevel); + myTrc.setTraceOnOff(bLogYN); + myTrc.setMaxLogFileSize(nLogSize); + } + } + + /** + * 1. 기능 : SoftLink와의 세션을 관리할 쓰레드 클래스 생성 함수 + * 2. 처리 개용 : + * - 파라미터로 넘어온 정보를 내부 변수에 설정한다. + * - 로그와 트레이스를 저장하기 위한 로그 처리 클래스의 오브젝트를 생성한다. + * 3. 주의사항 + * - 트레이스 처리의 동기화를 위해서 myTrc 클래스에 대한 동기화를 수행한다. + * - 송신 데이터 버퍼 형식 : 길이(4) + Data(n) + * + * @param sIpAddr Softlink Ip 주소 + * @param nPortNo SoftLink Port 번호 + * @param sAdapterGroupName 어댑터 그룹 이름 + * @param sAdapterName 어댑터 이름 + * @param sGroupCode LU 그룹 이름 + * @param nSessId Pool에 설정된 세션 수 + * @param bBackupSessionPool Backup Pool 여부 (true: 백업 세션) + * @param bLogYN 로깅 여부 + * @param nLogLevel 로그 레벨 + * @param nLogSize 로그 파일 사이즈 + */ + public WCASessionThread(String sNodeName, String sIpAddr, int nPortNo, + String sAdapterGroupName, String sAdapterName, String sGroupCode, int nSessId, + boolean bBackupSessionPool, + boolean bLogYN, int nLogLevel, int nLogSize) { + try { + this.sNodeName = sNodeName; + this.sIpAddr = sIpAddr; + this.nPortNo = nPortNo; + this.sAdapterGroupName = sAdapterGroupName; + this.sAdapterName = sAdapterName; + this.sGroupCode = sGroupCode; + + this.nSessId = nSessId; + this.bBackupSessionPool = bBackupSessionPool; + + nSessStat = WCADefine.SESS_STAT_NOTCONN; + + hmapRcvData = new HashMap(); + nRcvTimeout = WCADefine.DEFAULT_RECEIVE_TIMEOUT; + nConnTimeout = WCADefine.DEFAULT_CONNECT_TIMEOUT; + + snaAdapter = SNAAdapterManager.getInstance().selectSnaAdapter(sAdapterGroupName); + + String sLogDirectory = PropManager.getInstance().getProperty(LogKeys.LOGGER_INFO, LogKeys.LOG_DIRECOTRY_PREFIX); + if (sLogDirectory==null || sLogDirectory.equals("")) { + sLogDirectory = WCADefine.SERVER_NAME + File.separatorChar + "wca"; + } + else { + sLogDirectory = sLogDirectory + File.separatorChar + WCADefine.SERVER_NAME + File.separatorChar + "wca"; + } + + //if (trc_logger.isDebug()) trc_logger.debug(">> sLogDirectory = " + sLogDirectory); + // 로그와 트레이스 처리를 위한 오브젝트 생성 + String sMyTrcPath = ""; + String sMyLogPath = ""; + + if (bBackupSessionPool) { + // 20090810 Start + /* + myTrc = new MyLog(bLogYN, nLogLevel, nLogSize, sLogDirectory + File.separatorChar + sGroupCode + "-" + nSessId + "_BACKUP.trc"); + myLog = new MyLog(bLogYN, nLogLevel, nLogSize, sLogDirectory + File.separatorChar + sGroupCode + "-" + nSessId + "_BACKUP.log"); + + sMyTrcPath = sLogDirectory + File.separatorChar + sGroupCode + "-" + nSessId + "_BACKUP.trc"; + sMyLogPath = sLogDirectory + File.separatorChar + sGroupCode + "-" + nSessId + "_BACKUP.log"; + */ + myTrc = new MyLog(bLogYN, nLogLevel, nLogSize, sLogDirectory + File.separatorChar + sNodeName + "_" + sGroupCode + "-" + nSessId + "_BACKUP.trc"); + myLog = new MyLog(bLogYN, nLogLevel, nLogSize, sLogDirectory + File.separatorChar + sNodeName + "_" + sGroupCode + "-" + nSessId + "_BACKUP.log"); + + sMyTrcPath = sLogDirectory + File.separatorChar + sNodeName + "_" + sGroupCode + "-" + nSessId + "_BACKUP.trc"; + sMyLogPath = sLogDirectory + File.separatorChar + sNodeName + "_" + sGroupCode + "-" + nSessId + "_BACKUP.log"; + // 200908010 End + } + else { + // 20090810 Start + /* + myTrc = new MyLog(bLogYN, nLogLevel, nLogSize, sLogDirectory + File.separatorChar + sGroupCode + "-" + nSessId + ".trc"); + myLog = new MyLog(bLogYN, nLogLevel, nLogSize, sLogDirectory + File.separatorChar + sGroupCode + "-" + nSessId + ".log"); + + sMyTrcPath = sLogDirectory + File.separatorChar + sGroupCode + "-" + nSessId + ".trc"; + sMyLogPath = sLogDirectory + File.separatorChar + sGroupCode + "-" + nSessId + ".log"; + */ + myTrc = new MyLog(bLogYN, nLogLevel, nLogSize, sLogDirectory + File.separatorChar + sNodeName + "_" + sGroupCode + "-" + nSessId + ".trc"); + myLog = new MyLog(bLogYN, nLogLevel, nLogSize, sLogDirectory + File.separatorChar + sNodeName + "_" + sGroupCode + "-" + nSessId + ".log"); + + sMyTrcPath = sLogDirectory + File.separatorChar + sNodeName + "_" + sGroupCode + "-" + nSessId + ".trc"; + sMyLogPath = sLogDirectory + File.separatorChar + sNodeName + "_" + sGroupCode + "-" + nSessId + ".log"; + // 20090810 End + } + + /* 20080523 Start */ + try { + if (adapter_logger.isWarn()) { + adapter_logger.warn("adapter_logger trc_logger Path : " + Logger.LOGGER_ADAPTER); + adapter_logger.warn("adapter_logger adapter_logger Path : " + WCADefine.ADAPTER_LOGGER_NAME); + adapter_logger.warn("adapter_logger myTrc Path : " + sMyTrcPath); + adapter_logger.warn("adapter_logger myLog Path : " + sMyLogPath); + } + + myLog.logMsg(MyLog.WARN, "trc_logger Path : " + Logger.LOGGER_ADAPTER); + myLog.logMsg(MyLog.WARN, "adapter_logger Path : " + WCADefine.ADAPTER_LOGGER_NAME); + myLog.logMsg(MyLog.WARN, "myTrc Path : " + sMyTrcPath); + myLog.logMsg(MyLog.WARN, "myLog Path : " + sMyLogPath); + } + catch(Exception ignore) { + System.out.println("WCASessionThread> Exception Msg = " + ignore.toString()); + } + /* 20080523 End */ + } + catch(Exception e) { + adapter_logger.error("WCASessionThread] - [" + WCAException.E_ETC + "] " + toString() + e.toString()); + } + } + + /** + * 1. 기능 : 백업 세션 여부 설정 (true: 백업 세션) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param flag 백업 세션 여부 + **/ + public void setBackupSessionPool(boolean flag) { + bBackupSessionPool = flag; + } + + /** + * 1. 기능 : 백업 세션 여부 반환 (true: 백업 세션) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 세션 여부 + **/ + public boolean isBackupSessionPool() { + return bBackupSessionPool; + } + + /** + * 1. 기능 : 데이터 송신별 수신 데이터를 대기할 Queue를 등록 + * 2. 처리 개요 : + * - 송신 데이터의 트랜잭션 Key 필드를 기준으로 HashMap에 등록한다. + * 3. 주의사항 + * - WLI의 송신 쓰레드는 데이터 송신 후, 등록한 Queue를 대기한다. + * + * @param objKey HashMap에 저장될 unique한 key (UUID) + * @param objData HashMap에 저장될 값 (송신에 대한 Queue 데이타) + * @return 0 + **/ + public int registerRcvQueue(Object objKey, Object objData) { + synchronized (hmapRcvData) { + hmapRcvData.put(objKey, objData); + } + return 0; + } + + /** + * 1. 기능 : Queue에 등록된 송신에 대한 Queue 데이타 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param objKey HashMap에 저장될 unique한 key (UUID) + **/ + public int unregisterRcvQueue(Object objKey) { + synchronized (hmapRcvData) { + hmapRcvData.remove(objKey); + } + return 0; + } + + /** + * 1. 기능 : SoftLink 세션을 연결한다. + * 2. 처리 개요 : + * - SoftLink와 TCP 세션을 연결한다. + * - 세션이 연결되면 소켓에 대한 In/Out 스트림을 생성한다. + * 3. 주의사항 + * + * @param nTimeout 연결 Timeout + * @return 세션 연결 결과 + * @exception IOException + */ + public boolean connectSoftLink(int nTimeout) throws IOException { + SocketAddress sockAddr = null; + + try { + sockSoftLink = new Socket(); + myLog.logMsg(MyLog.DEBUG, "connectSoftLink] New Socket is Created..."); + sockAddr = new InetSocketAddress(sIpAddr, nPortNo); + myLog.logMsg(MyLog.INFO, "connectSoftLink] New Socket Address, Addr = " + sockAddr); + + myLog.logMsg(MyLog.DEBUG, "connectSoftLink] Try Connect to SoftLink..., nTimeout = " + nTimeout + "ms"); + sockSoftLink.connect(sockAddr, nTimeout); + + myLog.logMsg(MyLog.INFO, "RECVEIVE Buffer Size = " + sockSoftLink.getReceiveBufferSize()); + //sockSoftLink.setReceiveBufferSize(2048); + myLog.logMsg(MyLog.INFO, "connectSoftLink] Session is Connected...(Local Port = " + sockSoftLink.getLocalPort() + ")"); + + //isSoftLink = new BufferedInputStream(sockSoftLink.getInputStream()); + isSoftLink = sockSoftLink.getInputStream(); + osSoftLink = new BufferedOutputStream(sockSoftLink.getOutputStream()); + + myLog.logMsg(MyLog.INFO, "connectSoftLink] Socket In/Out Stream is Opened..."); + + // if true, pakcets are sent as quickly as possible regardless of their size + sockSoftLink.setTcpNoDelay(true); + + nSessStat = WCADefine.SESS_STAT_READY; + nContinuousDisconnectCnt = 0; + return true; + } + catch (Exception e) { + myLog.logMsg(MyLog.ERROR, "connectSoftLink] " + e.toString()); + + // softlink가 내려가고 EAI가 내려갔을 경우,,, 세션이 백션으로 가야함...(2분) + if (nContinuousDisconnectCnt % WCADefine.DEFAULT_BACKUP_CONVERSION_CHECK == 0) { + checkBackupConversion(); + } + + nContinuousDisconnectCnt++; + nDisconnectCnt++; + return false; + } + } + + /** + * 1. 기능 : Thread 종료 + * 2. 처리 개요 : + * - running 상태 Flag를 false로 설정한다. + * 3. 주의사항 + **/ + public void stopAdapter() { + myLog.logMsg(MyLog.INFO, "stopAdapter] Thread is Stopping. " + toString() ); + bRunning = false; + } + + /** + * 1. 기능 : 어댑터 상태 설정 + * 2. 처리 개요 : 어댑터 그룹 이용가능한 세션이 없을 경우 어댑터 상태를 false로 한다. + * 3. 주의사항 + **/ + private void setAdapterStatus(boolean flag) { + int nAdapterConnected; + + /* 20080523 수정 시작 */ + /* + 어댑터 상태를 사용안함으로 설정할때, EAI Framework쪽에서 어댑터 정보를 메모리에서 + 삭제하기 때문에 getAdapterVO 함수 호출시 NULL 값이 리턴되어 synchronized(av) 라인 처리시 + java.lang.NullPointerException 발생함 + --> 전체 로직을 try, catch로 묶음 + */ + try { + AdapterManager amanager = AdapterManager.getInstance(); + AdapterVO av = amanager.getAdapterVO(this.sAdapterGroupName,this.sAdapterName); + + synchronized (av) { + // if (av.isStatus() == flag) + //{ + try { + nAdapterConnected = snaAdapter.getConnectedSessNum(); + if (av != null) { + if (nAdapterConnected <= 0 ) { + av.setStatus(false); + } + else { + av.setStatus(true); + } + } + } + catch (Exception e) { + adapter_logger.error("setAdapterStatus error", e); + } + //} + } + } + catch (Exception e) { + myLog.logMsg(MyLog.INFO, "setAdapterStatus] Exception Msg = " + e.toString()); + } + /* 20080523 수정 끝 */ + } + + /** + * 1. 기능 : 처리되지 않은 트랜잭션 출력 및 notify + * 2. 처리 개요 : + * 3. 주의사항 + **/ + private void traceRemainTransaction() { + int iRemainWorkCnt = 0; + String sKey = null; + WCAQueue queueWSA = null; + WCAHeader header = null; + String sMessage = ""; + String sCode = ""; + char cMode ; + boolean bRecvSendOK = false; + + Iterator iter = null; + + HashMap copy = (HashMap)hmapRcvData.clone(); + iter = copy.keySet().iterator(); + + myLog.logMsg(MyLog.ERROR, ">>>>>>>>> " + toString() +" Remain Work is started. (Number = "+copy.size() + ") <<<<<<<<<<"); + while (iter.hasNext()) { + try { + iRemainWorkCnt++; + + sKey = (String)iter.next(); + if (sKey == null) { + if (adapter_logger.isError()) { adapter_logger.error("traceRemainTransaction] " + toString() + "sKey is null"); } + myLog.logMsg(MyLog.ERROR, "traceRemainTransaction] sKey is null"); + continue; + } + + myLog.logMsg(MyLog.ERROR, "Remain Work " + String.valueOf(iRemainWorkCnt) + "] TRANSACTION KEY = " + sKey); + + // notify + synchronized (hmapRcvData) { + queueWSA = (WCAQueue)hmapRcvData.remove(sKey); + } + + synchronized (queueWSA) { + bRecvSendOK = queueWSA.getRecvSendOKFlag(); + cMode = queueWSA.getMode(); + } + + if (bRecvSendOK) { + sCode = WCAException.E_SOFTLINK_RECV_SESSION_CLOSE; + } + else { + sCode = WCAException.E_SOFTLINK_SEND_SESSION_CLOSE; + } + + if (adapter_logger.isError()) { adapter_logger.error(WCAException.displayError(sCode) + toString() + " TRANSACTION KEY = " + sKey); } + sMessage = sCode + ErrorCodeHandler.getMessage(sCode); + + // 데이타 조립 + header = new WCAHeader(); + byte[] pBuff = new byte[WCAHeader.WCA_HEADER_LEN + sMessage.getBytes().length]; + System.arraycopy(header.getHeader(), 0, pBuff, 0, WCAHeader.WCA_HEADER_LEN); + System.arraycopy(sMessage.getBytes(), 0, pBuff, WCAHeader.WCA_HEADER_LEN, sMessage.getBytes().length); + + // NonResponse 모드이고 sendok를 받았으면 INBOUND로 보낸다. 그외는 notify + if (cMode == (WCAHeader.TRAN_MODE_NONRESPONSE).charAt(0) && bRecvSendOK){ + myLog.logMsg(MyLog.DEBUG, "traceRemainTransaction] NonResponse, send OK is received ... inbound"); + byte[] pRecvBuff = queueWSA.getDataFromQueue(); + System.arraycopy(pRecvBuff, 0, pBuff, 0, WCAHeader.WCA_HEADER_LEN); + + if (wcaEventHandler != null) { + myLog.logMsg(MyLog.DEBUG, "traceRemainTransaction] Call Event Handler : handleTimeoutData()"); + wcaEventHandler.handleNonRspData(sAdapterGroupName, sAdapterName, sGroupCode, pBuff.length, pBuff); + } + else { + myLog.logMsg(MyLog.ERROR, "traceRemainTransaction] Event Handler is Not Registered, So Discard Data..."); + } + } + else { + synchronized (queueWSA) { + WCAQueueData qdataWSA = new WCAQueueData(pBuff.length, pBuff); + queueWSA.addDataToQueue(qdataWSA); + myLog.logMsg(MyLog.DEBUG, "traceRemainTransaction] (START) Notify WLI Thread..."); + queueWSA.notifyAll(); + myLog.logMsg(MyLog.DEBUG, "traceRemainTransaction] (END) Notify WLI Thread..."); + } + } + } + catch (Exception e) { + if (adapter_logger.isError()) { adapter_logger.error(WCAException.displayError(WCAException.E_INFORM_ERROR, sKey)); } + } + } + } + + /** + * 1. 기능 : 데이타 수신 대기 및 수신 데이타 처리 + * 2. 처리 개요 : + * - 세션이 연결될때까지 계속 socket 연결 시도한다. + * - bRunning가 true 일 동안 계속 Socket InputStream을 read한다. + * - 수신 데이타를 DATA TYPE에 따라 처리한다. + * 3. 주의사항 + **/ + public void run() { + int nRcvLen; + byte[] pLenBuff = null; + int nDataLen = 0; + int nCheckOldWCAQueueCnt = 0; + + int nConnectedSessNum = 0; + int nConfiguredSessNum = 0; + + myLog.logMsg(MyLog.INFO, "Transaction Timeout = " + tran_timeout + ", Transaction Mode = " + tran_mode); + myLog.logMsg(MyLog.INFO, "run] " + toString() + " Thread is Started. (Thread Group Name = " + Thread.currentThread().getThreadGroup().getName() + ")"); + //adapter_logger.debug(toString() + " Thread is Started. (Thread Group Name = " + Thread.currentThread().getThreadGroup().getName() + ")"); + + bRunning = true; + + while(true) { + try { + // Thread stop 시켰을 경우 종료한다. + if (!bRunning) { + myLog.logMsg(MyLog.DEBUG, "run] " + toString() + " bRunning = false so stop"); + break; + } + + // 1. Socket 연결 시도 + if (nSessStat == WCADefine.SESS_STAT_NOTCONN) { + if (bBackupSessionPool) { + nConfiguredSessNum = snaAdapter.getConfiguredBackupSessNum(sNodeName, sGroupCode); + nConnectedSessNum = snaAdapter.getConnectedBackupSessNum(sNodeName, sGroupCode); + } + else { + nConfiguredSessNum = snaAdapter.getConfiguredNormalSessNum(sNodeName, sGroupCode); + nConnectedSessNum = snaAdapter.getConnectedNormalSessNum(sNodeName, sGroupCode); + } + + if (nConfiguredSessNum < nConnectedSessNum) { + if (adapter_logger.isWarn()) { adapter_logger.warn("설정된 세션수보다 많은 세션수가 존재합니다. Thread 종료합니다.[" + nConnectedSessNum + "/" + nConfiguredSessNum + "]"); } + myLog.logMsg(MyLog.WARN, "설정된 세션수보다 많은 세션수가 존재합니다. Thread 종료합니다.[" + nConnectedSessNum + "/" + nConfiguredSessNum + "]"); + closeSoftLink(); + break; + } + + myLog.logMsg(MyLog.DEBUG, "run] Status = SESS_STAT_NOTCONN, So Retry to Connect To SoftLink...."); + if (connectSoftLink(nConnTimeout) == false) { + myLog.logMsg(MyLog.ERROR, "run] Can't Connect To SoftLink, Sleep " + WCADefine.DEFAULT_SESS_RECOVERY_GAP); + + if (bBeforeConn) { + adapter_logger.error(WCAException.displayError(WCAException.E_SOFTLINK_NOTCONN,toString())); + myLog.logMsg(MyLog.WARN, "run] Session is Closed "); + + bBeforeConn = false; + + /* 20080523 SMS 로그 추가 시작 */ + try { + int nSessCnt = snaAdapter.getConnectedNormalSessNum(sNodeName, sGroupCode); + + if (adapter_logger.isWarn()) { adapter_logger.warn("getConnectedNormalSessNum> " + sAdapterGroupName + ", " + sGroupCode + " = "+ nSessCnt); } + myLog.logMsg(MyLog.WARN, "getConnectedNormalSessNum> " + sAdapterGroupName + ", " + sGroupCode + " = "+ nSessCnt); + + if (!bBackupSessionPool) { + if (nSessCnt == 0) { + // String strSmsMsg = sAdapterGroupName + " Session is Closed"; + // String strSmsMsg = sGroupCode + " Session is Closed"; + String strSmsMsg = "Session is Closed"; + try { + if (adapter_logger.isWarn()) { adapter_logger.warn("WCASessionThread:run> Log SMS Msg, Msg = " + sGroupCode + " " + strSmsMsg); } + myLog.logMsg(MyLog.WARN, "WCASessionThread:run> Log SMS Msg, Msg = " + sGroupCode + " " + strSmsMsg); + SMSLogUtil.loggingSMS(sGroupCode, strSmsMsg); + } + catch (Exception ignore) { + myLog.logMsg(MyLog.DEBUG, "run] Exception, While Write SMS Log, Msg = " + ignore.toString()); + } + } + } + } + catch (Exception ignore) { + System.out.println("WCASessionThread:run> Exception Msg = " + ignore.toString()); + } + /* 20080523 SMS 로그 추가 끝 */ + } + + Thread.sleep(WCADefine.DEFAULT_SESS_RECOVERY_GAP * 1000); + continue; + } + } + + // 세션이 복귀되면 adapter 상태를 변경한다. + if (!bBeforeConn) { + setAdapterStatus(false); + sendAdapterStatusData(); + + // 20090810 Start + sendWcaSessionAppCode(true); + // 20090810 End + } + + bBeforeConn = true; + + // Socket 수신 타임 아웃 설정 + //sockSoftLink.setSoTimeout(WCADefine.DEFAULT_SOCK_RCV_TIMEOUT * 1000); + + // 2. Socket 수신 데이타 대기 -- 길이 필드 수신 (4 바이트) + String dateString = formatter.format(ZonedDateTime.now()); + lReadStartTime = System.currentTimeMillis(); + + pLenBuff = recvLenthField(WCADefine.LEGTH_FIELD_SIZE); + if (pLenBuff == null) { // Connection is Close... + closeSoftLink(); + continue; + } + + // 3. 길이 필드 변환 + // 20090302 Start + /* + nDataLen = Integer.parseInt(new String(pLenBuff)); + */ + nDataLen = getInt(pLenBuff, 0); + // 20090302 End + myLog.logMsg(MyLog.INFO, "run] Data Length Field = " + nDataLen); + if (nDataLen < 0) { + myLog.logMsg(MyLog.ERROR, "run] Invalid Data Length Field... So Close Session"); + closeSoftLink(); + continue; + } + + // 4. 데이타 수신 + byte[] pDataBuff = recvDataField(nRcvTimeout, nDataLen); + if (pDataBuff == null) { // Connection is Close... + closeSoftLink(); + continue; + } + + lReadEndTime = System.currentTimeMillis(); + if (adapter_logger.isDebug()) { adapter_logger.debug(dateString + " : WCA_RECEIVING_TIME = " + (lReadEndTime - lReadStartTime)); } + myLog.logMsg(MyLog.DEBUG, "WCA_RECEIVING_TIME = " + (lReadEndTime - lReadStartTime)); + + nRcvLen = pDataBuff.length; + myLog.logMsg(MyLog.INFO, "run] Receive Data Field Length = " + nRcvLen); + + // 5. 수신 데이타 처리 + handleRcvData(nRcvLen, pDataBuff); + } + catch (java.lang.NumberFormatException n) { // 길이 데이타를 파싱못할경우... + myLog.logMsg(MyLog.ERROR, "run] " + WCAException.displayError(WCAException.E_RECVERR_DATALEN, toString(), MyUtil.toHex(pLenBuff))); + if (adapter_logger.isError()) { adapter_logger.error(WCAException.displayError(WCAException.E_RECVERR_DATALEN, toString(), MyUtil.toHex(pLenBuff))); } + this.closeSoftLink(); + } + catch (SocketTimeoutException ste) { + myLog.logMsg(MyLog.DEBUG, "run] SocketTimeoutException ocurrs"); + nCheckOldWCAQueueCnt++; + if (WCADefine.DEFAULT_SOCK_RCV_TIMEOUT * nCheckOldWCAQueueCnt > WCADefine.DEFAULT_TRANSACTION_DELETE_TIMEOUT) { + myLog.logMsg(MyLog.DEBUG, "run] There is No Data to Read, Running..."); + nCheckOldWCAQueueCnt = 0; + myLog.logMsg(MyLog.DEBUG, "run] Check Old WCAQueue..."); + /* + long lCurrTime = System.currentTimeMillis(); + // HashMap에 WCAQueue가 무한적 추가되는 것을 막기 위해서, 시간이 경과한 WCAQueue를 삭제함. + synchronized(hmapRcvData) { + Iterator iter = hmapRcvData.keySet().iterator(); + while(iter.hasNext()) { + String sKey = (String)iter.next(); + if (sKey == null) { if (trc_logger.isDebug()) trc_logger.debug("run] sKey is null");} + + WCAQueue wcaQueue = (WCAQueue)hmapRcvData.get(sKey); + if (wcaQueue == null) { if (trc_logger.isDebug()) trc_logger.debug("run] wcaQueue is null");} + + if (wcaQueue != null) { + long lTimeGap = lCurrTime - wcaQueue.lCreateTime; + + if (lTimeGap > (WCADefine.DEFAULT_TRANSACTION_DELETE_TIMEOUT * 1000)) { + myLog.logMsg(MyLog.ERROR, "run] Delete TRANSACTION Queue, Key = " + sKey); + if (adapter_logger.isError()) adapter_logger.error(toString() + " Delete TRANSACTION Queue, Key = " + sKey); + hmapRcvData.remove(sKey); + } + } + } + } + */ + } + } + catch (java.net.SocketException socket) { + myLog.logMsg(MyLog.ERROR, "run] Error = " + socket.toString()); + this.closeSoftLink(); + } + catch (Exception e) { + myLog.logMsg(MyLog.ERROR, "run] Error = " + e.toString()); + if (adapter_logger.isError()) { adapter_logger.error("[" + WCAException.E_ETC + "] " + toString() + " 프로그램 에러입니다. ", e); } + this.closeSoftLink(); + } + } + + // 어댑터 상태 체크 + setAdapterStatus(true); + + // 미처리 트랜잭션 출력 + traceRemainTransaction(); + + // Thread 종료시 LOG 파일 close + myLog.logMsg(MyLog.INFO, "run] " + toString() + " Thread is Stopped"); + + //adapter_logger.debug(toString() + " Thread is Stopped"); + closeLogStream(); + } + + + /** + * 1. 기능 : 수신 데이타 처리 + * 2. 처리 개요 : + * - 수신 데이타 트레이스 파일에 로깅 + * - DATA TYPE에 따라 각 처리 함수로 분기한다. + * 3. 주의사항 + **/ + public void handleRcvData(int nLen, byte[] pBuff) { + String sDataType = null; + + boolean isLogFirstData = false; + String strFirstData = ""; + + String luName = ""; + String threadName = ""; + long startTime = 0; + + WCAHeader wcaHeader = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pBuff); + + nRcvCnt++; + // 트레이스 로깅 + /* + synchronized(myTrc) { + myTrc.logMsg("SoftLink -> WCA (LEN = " + nLen + ")"); + myTrc.logMsg("WCA Header : " + wcaHeader.toString()); + myTrc.logData(WCADefine.EBCDIC_CODE, nLen, pBuff); + } + */ + sDataType = wcaHeader.getDataType(); + + myLog.logMsg(MyLog.INFO, "handleRcvData] Receive DATA_TYPE VALUE = " + sDataType ); + + // 송신 완료 + if (sDataType.equals(WCAHeader.DATA_TYPE_SEND_OK)) { + myLog.logMsg(MyLog.DEBUG, "handleRcvData] Status Mode : Send OK "); + handleSendOK(nLen, pBuff); + } + else if (sDataType.equals(WCAHeader.DATA_TYPE_TIMEOUT_ONLY) || sDataType.equals(WCAHeader.DATA_TYPE_TIMEOUT_LAST)) { + myLog.logMsg(MyLog.DEBUG, "handleRcvData] Status Mode : Timeout "); + handleTimeout(nLen, pBuff); + } + else if (sDataType.equals(WCAHeader.DATA_TYPE_NORMAL_FIRST) || sDataType.equals(WCAHeader.DATA_TYPE_NORMAL_MIDDLE) || + sDataType.equals(WCAHeader.DATA_TYPE_DFS_FIRST) || sDataType.equals(WCAHeader.DATA_TYPE_DFS_MIDDLE) || + sDataType.equals(WCAHeader.DATA_TYPE_TIMEOUT_FIRST) || sDataType.equals(WCAHeader.DATA_TYPE_TIMEOUT_MIDDLE)) { + myLog.logMsg(MyLog.DEBUG, "handleRcvData] Status Mode : Normal First, Normal Middle, Delay First, Delat Middel "); + handleData(nLen, pBuff); + } + else if (sDataType.equals(WCAHeader.DATA_TYPE_NORMAL_ONLY) || sDataType.equals(WCAHeader.DATA_TYPE_NORMAL_LAST) || + sDataType.equals(WCAHeader.DATA_TYPE_DFS_ONLY) || sDataType.equals(WCAHeader.DATA_TYPE_DFS_LAST)) { + /// DEBUG_LOG : 20200406 + isLogFirstData = false; + + // 운영 환경이 기본 로그 레벨이 warn임, 20200406 가용성 테스트 이후에 isInfo으로 변경 해야 함. (KB 김양규 차장님 요청 사항) + if (adapter_logger.isInfo()) { + // if (adapter_logger.isError()) { + if (nLen > WCAHeader.WCA_HEADER_LEN + 60) { + isLogFirstData = true; + + byte[] bFirstData = new byte[60]; + System.arraycopy(pBuff, WCAHeader.WCA_HEADER_LEN, bFirstData, 0, 60); + + strFirstData = new String(CodeCvrt.cvrtEbc2Ksc(bFirstData)); + luName = wcaHeader.getLUName(); + threadName = Thread.currentThread().getName(); + + adapter_logger.error("handleRcvData> ST " + threadName + ", " + luName + ", " + strFirstData); + + startTime = System.currentTimeMillis(); + } + } + + myLog.logMsg(MyLog.DEBUG, "handleRcvData] Status Mode : NORML_ONLY, NORML_LAST, DFS"); + handleNormalDFS(nLen, pBuff); + + if (isLogFirstData == true) { + long endTime = System.currentTimeMillis(); + long elapseTime = endTime - startTime; + + adapter_logger.error("handleRcvData> EN " + threadName + ", " + luName + ", " + strFirstData + ", " + elapseTime); + + if (elapseTime > 5000) { + adapter_logger.error("handleRcvData> OVEROVERTIME " + elapseTime + ", " + threadName + ", " + luName + ", " + strFirstData); + } + else if (elapseTime > 1000) { + adapter_logger.error("handleRcvData> OVERTIME " + elapseTime + ", " + threadName + ", " + luName + ", " + strFirstData); + } + } + } + else if (sDataType.equals(WCAHeader.DATA_TYPE_ERROR)) { + myLog.logMsg(MyLog.DEBUG, "handleRcvData] Status Mode : Error"); + handleError(nLen, pBuff); + } + else if (sDataType.equals(WCAHeader.DATA_TYPE_ADAPTER_ERROR) || sDataType.equals(WCAHeader.DATA_TYPE_ADAPTER_OK)) { + myLog.logMsg(MyLog.DEBUG, "handleRcvData] Status Mode : DATA_TYPE_ADAPTER_ERROR, DATA_TYPE_ADAPTER_OK"); + handleAutoBackup(nLen, pBuff); + } + else if (sDataType.equals(WCAHeader.DATA_TYPE_GET_ADAPTER_STATUS)) { + myLog.logMsg(MyLog.DEBUG, "handleRcvData] Status Mode : DATA_TYPE_GET_ADAPTER_STATUS"); + handleAutoBackup(nLen, pBuff); + } + else { + myLog.logMsg(MyLog.ERROR, "handleRcvData] " + WCAException.displayError(WCAException.E_SOFTLINK_UNKNOWN_COMMAND, toString(), sDataType)); + if (adapter_logger.isError()) { adapter_logger.error(WCAException.displayError(WCAException.E_SOFTLINK_UNKNOWN_COMMAND, toString(), sDataType)); } + } + + return; + } + + /** + * 1. 기능 : 송신 완료 (Send OK) 데이타 처리 + * 2. 처리 개요 : + * - NONRESPONSE 모드 : + * 1. 송신 Queue에 있을 경우 : 데이타 수신했음을 알려준다. + * 2. 송신 Queue에 없을 경우 : 타임아웃 데이타로 INBOUND handleTimeoutData 핸들러로 보낸다. + * - RESPONSE 모드 : 수신 데이타 대기한다. + * 3. 주의사항 + **/ + public void handleSendOK(int nLen, byte[] pBuff) { + myLog.logMsg(MyLog.DEBUG, "handleRcvData] Receive STATUS_SENDOK..."); + + String sKey = null; + + WCAHeader wcaHeader = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pBuff); + + char cMode = wcaHeader.getMode(); + myLog.logMsg(MyLog.DEBUG, "handleSendOK] Tran Mode = " + cMode); + + sKey = getKey(wcaHeader); + myLog.logMsg(MyLog.DEBUG, "handleSendOK] Key = " + sKey); + + /* NONRESPONSE 모드 */ + if (cMode == (WCAHeader.TRAN_MODE_NONRESPONSE).charAt(0)) { + myLog.logMsg(MyLog.DEBUG, "handleSendOK] Response Mode = MODE_NONRESPONSE"); + + WCAQueue queueWSA = null; + synchronized (hmapRcvData) { + queueWSA = (WCAQueue)hmapRcvData.remove(sKey); + } + + if (queueWSA != null) { + synchronized (queueWSA) { + queueWSA.setRecvSendOKFlag(true); + WCAQueueData qdataWSA = new WCAQueueData(nLen, pBuff); + myLog.logMsg(MyLog.DEBUG, "handleSendOK] Add Queue Data, Length = " + nLen); + queueWSA.addDataToQueue(qdataWSA); + myLog.logMsg(MyLog.DEBUG, "handleSendOK] Notify WLI Thread..."); + queueWSA.notifyAll(); + lNotifyEndTime = System.currentTimeMillis(); + String dateString = formatter.format(ZonedDateTime.now()); + if (adapter_logger.isDebug()) { adapter_logger.debug(dateString + " : WCA_PROCESSIING_TIME = " + (lNotifyEndTime - lReadEndTime)); } + } + } + else { + if (wcaEventHandler != null) { + myLog.logMsg(MyLog.DEBUG, "handleSendOK] Call Event Handler : handleTimeoutData()"); + wcaEventHandler.handleTimeoutData(sAdapterGroupName, sAdapterName, sGroupCode, nLen, pBuff); + } + else { + myLog.logMsg(MyLog.ERROR, "handleSendOK] Event Handler is Not Registered, So Discard Data..."); + } + } + } + else if (cMode == (WCAHeader.TRAN_MODE_RESPONSE).charAt(0) || cMode == (WCAHeader.TRAN_MODE_TERMINAL).charAt(0)) { + myLog.logMsg(MyLog.DEBUG, "handleSendOK] Response Mode = MODE_RESPONSE"); + myLog.logMsg(MyLog.DEBUG, "handleSendOK] Wait Host Data..."); + WCAQueue queueWSA = null; + synchronized (hmapRcvData){ + queueWSA = (WCAQueue)hmapRcvData.get(sKey); + if (queueWSA != null) + queueWSA.setRecvSendOKFlag(true); + } + } + else { + myLog.logMsg(MyLog.ERROR, "handleSendOK] Receive Unknown Mode, Mode = " + cMode); + } + + return; + } + + /** + * 1. 기능 : Timeout 데이타 처리 + * 2. 처리 개요 : + * - TIMOUT 첫번째 데이타일 경우 (DATA_TYPE_TIMEOUT_ONLY) : + * 수신데이타를 INBOUND 핸들러로 보낸다. + * - TIMOUT 데이타가 하나이상의 패킷일 경우 : + * Queue에 저장된 키값을 구한다. (key값이 없을 경우 에러로그만 남긴다.) + * 1. 송신 Queue에 있을 경우 : 수신된 모든 데이타를 INBOUND 핸들러로 보낸다. + * 2. 송신 Queue에 없을 경우 : 현재 받은 데이타만 INBOUND 핸들러로 보낸다. + * 3. 주의사항 + **/ + public void handleTimeout(int nLen, byte[] pBuff) { + String sKey = null; + String sDataType = null; + byte[] pRecvBuff = null; + char cMode; + + WCAHeader wcaHeader = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pBuff); + + sDataType = wcaHeader.getDataType(); + myLog.logMsg(MyLog.DEBUG, "handleTimeout] Data Type = " + sDataType); + cMode = wcaHeader.getMode(); + myLog.logMsg(MyLog.DEBUG, "handleTimeout] Tran Mode = " + cMode); + + if (sDataType.equals(WCAHeader.DATA_TYPE_TIMEOUT_ONLY)){ + pRecvBuff = pBuff; + } + else { + sKey = getKey(wcaHeader); + if (sKey == null) { + myLog.logMsg(MyLog.ERROR, "handleTimeout] Key is NULL" ); + if (adapter_logger.isError()) { adapter_logger.error("handleTimeout] - " + WCAException.displayError(WCAException.E_RECVDATA_ERROR, toString(), "Key is NULL")); } + return; + } + + WCAQueue queueWSA = null; + synchronized (hmapRcvData) { + queueWSA = (WCAQueue)hmapRcvData.remove(sKey); + } + + if (queueWSA != null) { + synchronized (queueWSA) { + WCAQueueData qdataWSA = new WCAQueueData(nLen, pBuff); + myLog.logMsg(MyLog.DEBUG,"handleTimeout] Add Queue Data, Length = " + nLen); + queueWSA.addDataToQueue(qdataWSA); + } + pRecvBuff = queueWSA.getDataFromQueue(); + } + else { + myLog.logMsg(MyLog.ERROR, "handleTimeout] - [" + WCAException.E_SOFTLINK_RECV_DATA_NOTFOUND + "] Queue Data doesn't existed...."); + if (adapter_logger.isError()) { adapter_logger.error("handleTimeout] - [" + WCAException.E_SOFTLINK_RECV_DATA_NOTFOUND + "] " + toString() + " Queue Data doesn't existed...."); } + return; + } + } + + if (wcaEventHandler != null) { + myLog.logMsg(MyLog.DEBUG, "handleTimeout] Call Event Handler : handleTimeoutData()"); + wcaEventHandler.handleTimeoutData(sAdapterGroupName, sAdapterName, sGroupCode, pRecvBuff.length, pRecvBuff); + } + else { + myLog.logMsg(MyLog.ERROR, "handleTimeout] Event Handler is Not Registered, So Discard Data..."); + } + } + + /** + * 1. 기능 : 수신 데이타를 Queue에 저장한다. + * 2. 처리 개요 : + * - DATA TYPE이 FIRST, MIDDEL인 경우 Queue에 저장될 key 값을 구하여 Queue 값을 구한다. + * - Queue에 수신데이타 저장 값이 있을 경우 Queue 데이타를 추가하며, + * 없을 경우 Queue를 생성하여 Queue 데이타를 추가한다. + * - Respnse 모드이고 timeout 데이타인 경우 setResTimeoutFlag(true)을 설정해준다. + * (차후 INBOUND 핸들러로 보내기 위함) + * 3. 주의사항 + * + **/ + public void handleData(int nLen, byte[] pBuff) { + String sKey = null; + + WCAHeader wcaHeader = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pBuff); + + sKey = getKey(wcaHeader); + if (sKey == null) { + myLog.logMsg(MyLog.ERROR, "handleData] - "+ WCAException.displayError(WCAException.E_RECVDATA_ERROR, toString(), "Key is NULL")); + if (adapter_logger.isError()) { adapter_logger.error("handleData] - "+ WCAException.displayError(WCAException.E_RECVDATA_ERROR, toString(), "Key is NULL")); } + return; + } + + WCAQueue queueWSA = null; + synchronized (hmapRcvData) { + queueWSA = (WCAQueue)hmapRcvData.get(sKey); + } + + // Status가 DATA_TYPE_TIMEOUT_FIRST인 경우 LUNAME으로 Hashmap에 저장한다. + String sDataType = wcaHeader.getDataType(); + char cMode = wcaHeader.getMode(); + myLog.logMsg(MyLog.DEBUG, "handleData] Data Type = " + sDataType + ", Mode = " + cMode); + + if (queueWSA == null) { + queueWSA = new WCAQueue(); + registerRcvQueue(sKey, queueWSA); + + // DFS가 아니고 response 모드인 경우 -> 타임아웃데이타 + if ((String.valueOf(cMode).equals(WCAHeader.TRAN_MODE_RESPONSE) || String.valueOf(cMode).equals(WCAHeader.TRAN_MODE_TERMINAL)) && + !sDataType.substring(0,1).equals(WCAHeader.DATA_TYPE_DFS_PREFIX)) { + queueWSA.setResTimeoutFlag(true); + } + } + + if (queueWSA != null) { + synchronized (queueWSA) { + WCAQueueData qdataWSA = new WCAQueueData(nLen, pBuff); + myLog.logMsg(MyLog.DEBUG,"handleData] Add Queue Data, Length = " + nLen); + queueWSA.addDataToQueue(qdataWSA); + } + } + return; + } + + /** + * 1. 기능 : Normal Data 및 DFS 데이타를 처리한다. + * 2. 처리 개요 : + * - NONRESPONSE 모드 : + * 1. Queue에 있을 경우 : 수신된 모든 데이타를 INBOUND 핸들러로 보낸다. + * 2. Queue에 없을 경우 : 수신된 현재 데이타를 INBOUND 핸들러로 보낸다. + * - RESPONSE 모드 : + * 1. Queue에 있을 경우 : RESPONSE 모드이고 TIMEOUT 데이타이면 INBOUND 핸들러로 보낸다. + * 그외의 경우 데이타 수신했음을 알려준다. (notify) + * 2. Queue에 없을 경우 : timeout 데이타로 INBOUND 핸들러로 보낸다. + * 3. 주의사항 + * + **/ + public void handleNormalDFS(int nLen, byte[] pBuff) { + String sKey = null; + char cMode; + byte[] pRecvBuff = null; + + WCAHeader wcaHeader = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pBuff); + + sKey = getKey(wcaHeader); + if (sKey == null) { + myLog.logMsg(MyLog.ERROR, "handleNormalDFS] - " + WCAException.displayError(WCAException.E_RECVDATA_ERROR, toString(), "Key is NULL")); + if (adapter_logger.isError()) { adapter_logger.error("handleNormalDFS] - " + WCAException.displayError(WCAException.E_RECVDATA_ERROR, toString(), "Key is NULL")); } + return; + } + + cMode = wcaHeader.getMode(); + myLog.logMsg(MyLog.DEBUG, "handleNormalDFS] Tran Mode = " + cMode); + + if (cMode == (WCAHeader.TRAN_MODE_NONRESPONSE).charAt(0)) { + WCAQueue queueWSA = null; + synchronized(hmapRcvData) { + queueWSA = (WCAQueue)hmapRcvData.remove(sKey); + } + + if (queueWSA != null) { + synchronized (queueWSA) { + WCAQueueData qdataWSA = new WCAQueueData(nLen, pBuff); + myLog.logMsg(MyLog.DEBUG,"handleNormalDFS] Add Queue Data, Length = " + nLen); + queueWSA.addDataToQueue(qdataWSA); + } + pRecvBuff = queueWSA.getDataFromQueue(); + } + else { + pRecvBuff = pBuff; + myLog.logMsg(MyLog.DEBUG, "handleNormalDFS] - [" + WCAException.E_SOFTLINK_RECV_DATA_NOTFOUND +"] Queue Data doesn't existed...."); + } + + if (wcaEventHandler != null) { + myLog.logMsg(MyLog.DEBUG, "handleNormalDFS] Call Event Handler : handleNonRspData()"); + wcaEventHandler.handleNonRspData(sAdapterGroupName, sAdapterName, sGroupCode, pRecvBuff.length, pRecvBuff); + } + else { + myLog.logMsg(MyLog.ERROR, "handleNormalDFS] Event Handler is Not Registered, So Discard Data..."); + } + } + else if (cMode == (WCAHeader.TRAN_MODE_RESPONSE).charAt(0) || cMode == (WCAHeader.TRAN_MODE_TERMINAL).charAt(0)) { + WCAQueue queueWSA = null; + synchronized (hmapRcvData) { + queueWSA = (WCAQueue)hmapRcvData.remove(sKey); + } + + if (queueWSA != null) { + synchronized (queueWSA) { + WCAQueueData qdataWSA = new WCAQueueData(nLen, pBuff); + myLog.logMsg(MyLog.DEBUG,"handleNormalDFS] Add Queue Data, Length = " + nLen); + queueWSA.addDataToQueue(qdataWSA); + + // timeout데이타일 경우 + if (queueWSA.getResTimeoutFlag()) { + pRecvBuff = queueWSA.getDataFromQueue(); + if (wcaEventHandler != null) { + myLog.logMsg(MyLog.DEBUG, "handleNormalDFS] Call Event Handler : handleTimeoutData()"); + wcaEventHandler.handleTimeoutData(sAdapterGroupName, sAdapterName, sGroupCode, pRecvBuff.length, pRecvBuff); + } + else { + myLog.logMsg(MyLog.ERROR, "handleNormalDFS] Event Handler is Not Registered, So Discard Data..."); + } + } + else { + myLog.logMsg(MyLog.DEBUG, "handleNormalDFS] Notify WLI Thread..."); + + // 20200724 Start + if (adapter_logger.isInfo()) { adapter_logger.debug("Before Notify WLI Thread, " + sAdapterGroupName + ", " + sAdapterName + ", " + sGroupCode); } + // 20200724 End + + queueWSA.notifyAll(); + + // 20200724 Start + if (adapter_logger.isInfo()) { adapter_logger.debug("After Notify WLI Thread, " + sAdapterGroupName + ", " + sAdapterName + ", " + sGroupCode); } + // 20200724 End + + lNotifyEndTime = System.currentTimeMillis(); + String dateString = formatter.format(ZonedDateTime.now()); + + // 20200724 Start + // 로그 레벨 변경 + // if (adapter_logger.isDebug()) { adapter_logger.debug(dateString + " : WCA_PROCESSIING_TIME = " + (lNotifyEndTime - lReadEndTime)); } + if (adapter_logger.isInfo()) { adapter_logger.info(dateString + " : WCA_PROCESSIING_TIME = " + (lNotifyEndTime - lReadEndTime)); } + // 20200724 End + } + } + } + else { + if (wcaEventHandler != null) { + myLog.logMsg(MyLog.DEBUG, "handleNormalDFS] Call Event Handler : handleTimeoutData()"); + wcaEventHandler.handleTimeoutData(sAdapterGroupName, sAdapterName, sGroupCode, nLen, pBuff); + } + else { + myLog.logMsg(MyLog.ERROR, "handleNormalDFS] Event Handler is Not Registered, So Discard Data..."); + } + } + } + else { + myLog.logMsg(MyLog.ERROR, "handleNormalDFS] Receive Unknown Mode, Mode = " + cMode); + adapter_logger.error("handleNormalDFS] - " + WCAException.displayError(WCAException.E_SOFTLINK_UNKNOWN_COMMAND, toString(), "Unknown Mode = " + cMode) ); + } + } + + /** + * 1. 기능 : ERROR Data 및 DFS 데이타를 처리한다. + * 2. 처리 개요 : + * - Queue에 있을 경우 : + * 1. "LU사용중"이라는 에러코드인 경우 setResendFlag(true)로 설정한다. + * (차후 다른 LU 그룹으로 Resend 하기 위함) + * 2. 그외의 경우 : 그외의 경우 데이타 수신했음을 알려준다. (notify) + * - Queue에 없을 경우 : 수신된 데이타를 INBOUND 핸들러로 보낸다. + * 3. 주의사항 + * + **/ + public void handleError(int nLen, byte[] pBuff) { + String sKey = null; + byte[] bErrCode = new byte[WCAException.SOFTLINK_ERROR_SIZE]; + byte[] bErrMsg = null; + + WCAHeader wcaHeader = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pBuff); + + if (nLen >= (WCAHeader.WCA_HEADER_LEN + WCAException.SOFTLINK_ERROR_SIZE)) { + System.arraycopy(pBuff, WCAHeader.WCA_HEADER_LEN, bErrCode, 0, WCAException.SOFTLINK_ERROR_SIZE); + String sErrCode = new String(bErrCode); + myLog.logMsg(MyLog.DEBUG, "handleError] ErrCode = " + sErrCode); + } + + if (nLen > (WCAHeader.WCA_HEADER_LEN + WCAException.SOFTLINK_ERROR_SIZE)) { + bErrMsg = new byte[nLen - WCAHeader.WCA_HEADER_LEN - WCAException.SOFTLINK_ERROR_SIZE]; + System.arraycopy(pBuff, WCAHeader.WCA_HEADER_LEN + WCAException.SOFTLINK_ERROR_SIZE, bErrMsg, 0, nLen - WCAHeader.WCA_HEADER_LEN - WCAException.SOFTLINK_ERROR_SIZE); + String sErrMsg = new String(bErrMsg); + myLog.logMsg(MyLog.DEBUG, "handleError] ErrMsg = " + sErrMsg); + } + + sKey = getKey(wcaHeader); + myLog.logMsg(MyLog.DEBUG, "handleError] Key = " + sKey); + + if (bErrCode != null && bErrMsg != null) { + String sRecvErrCode = new String(bErrCode); + if (adapter_logger.isError()) { adapter_logger.error("[" + sRecvErrCode+"] " + toString() + " " + sKey + " : " + new String(bErrMsg)); } + } + + WCAQueue queueWSA = null; + synchronized (hmapRcvData) { + queueWSA = (WCAQueue)hmapRcvData.remove(sKey); + } + + if (queueWSA != null) { + // 해당 LU 세션이 사용중, 다운일 경우 다른 LU 세션으로 보낸다. + if (new String(bErrCode).equals(WCAException.E_HOST_LU_DOWN) || new String(bErrCode).equals(WCAException.E_HOST_LU_IN_USED) + || new String(bErrCode).equals(WCAException.E_HOST_LU_NON_EXIST)) { + queueWSA.setResendFlag(true); + } + + synchronized (queueWSA) { + WCAQueueData qdataWSA = new WCAQueueData(nLen, pBuff); + myLog.logMsg(MyLog.DEBUG,"handleError] Add Queue Data, Length = " + nLen); + queueWSA.addDataToQueue(qdataWSA); + myLog.logMsg(MyLog.DEBUG, "handleError] Notify WLI Thread..."); + queueWSA.notifyAll(); + lNotifyEndTime = System.currentTimeMillis(); + String dateString = formatter.format(ZonedDateTime.now()); + if (adapter_logger.isDebug()) adapter_logger.debug(dateString + " : WCA_PROCESSIING_TIME = " + (lNotifyEndTime - lReadEndTime)); + } + } + else { + /* + if (wcaEventHandler != null) { + myLog.logMsg(MyLog.DEBUG, "handleError] Call Event Handler : handleTimeoutData()"); + wcaEventHandler.handleTimeoutData(sAdapterGroupName, sAdapterName, nLen, pBuff); + } + else { + myLog.logMsg(MyLog.ERROR, "handleError] Event Handler is Not Registered, So Discard Data..."); + } + */ + myLog.logMsg(MyLog.DEBUG, "handleError] Doesnt' Exist Data in Queue!!"); + } + } + + /** + * 1. 기능 : 수동 백업 및 복구 명령을 처리한다. + * 2. 처리 개요 : + * - DATA_TYPE_ADAPTER_ERROR 인 경우 : 해당 어댑터 그룹, LU 그룹을 백업모드로 전환한다. + * - DATA_TYPE_ADAPTER_OK 인 경우 : 해당 어댑터 그룹, LU 그룹을 백업모드에서 복귀한다. + * 3. 주의사항 + * + **/ + public void handleAutoBackup(int nLen, byte[] pBuff) { + ManualBackupCmd cmd = new ManualBackupCmd(ManualBackupCmd.BACKUP_CMD_LEN, pBuff); + + String sBackupAdapterGrpName = null; + String sBackupLUGrpName = null; + + try { + String sDataType = cmd.getDataType(); + sBackupAdapterGrpName = cmd.getAdapterGrpName(); + sBackupLUGrpName = cmd.getLUGrpName(); + + // 20090810 Start + if (bBackupEnableFlag == false) { + myLog.logMsg(MyLog.NOTICE, "handleAutoBackup] Backup Enable Flag is False, So Ignore 자동 백업 명령 (" + + sBackupAdapterGrpName + "/" + sNodeName + "/" + sBackupLUGrpName + ")"); + return; + } + // 20090810 End + + // 수동 백업 전환 + if (sDataType.equals(ManualBackupCmd.DATA_TYPE_ADAPTER_ERROR)) { + myLog.logMsg(MyLog.NOTICE, "handleAutoBackup] 자동 백업 명령 수신 (" + sBackupAdapterGrpName + "/" + sNodeName + "/" + sBackupLUGrpName + ")"); + adapter_logger.warn("handleAutoBackup] - " + toString() + " 자동 백업 명령 수신 " + sBackupAdapterGrpName + "/" + sBackupLUGrpName); + + if (bBackupEnableFlag == true) { + if (isBackupSessionPool()) { return; } + snaAdapter.setAutoBackupMode(sNodeName, sBackupLUGrpName, true); + } + else { + myLog.logMsg(MyLog.NOTICE, "handleAutoBackup] bBackupEnableFlag is False, So Ignore Data"); + adapter_logger.warn("handleAutoBackup] bBackupEnableFlag is False, So Ignore Data"); + } + // 20090810 End + } + else { // 수동 복구 전환 + myLog.logMsg(MyLog.NOTICE, "handleAutoBackup] 자동 복구 명령 수신 (" + sBackupAdapterGrpName + "/" + sBackupLUGrpName + ")"); + adapter_logger.warn("handleAutoBackup] - " + toString() + " 자동 복구 명령 수신 " + sBackupAdapterGrpName + "/" + sBackupLUGrpName); + + if (bBackupEnableFlag == true) { + if (isBackupSessionPool()) { return; } + snaAdapter.setAutoBackupMode(sNodeName, sBackupLUGrpName, false); + } + else { + myLog.logMsg(MyLog.NOTICE, "handleAutoBackup] bBackupEnableFlag is False, So Ignore Data"); + adapter_logger.warn("handleAutoBackup] bBackupEnableFlag is False, So Ignore Data"); + } + // 20090810 End + } + } + catch (WCAException e) { + // 해당 세션을 찾지 못하였을 경우 + if (e.getErrorReturnCode().equals(WCAException.E_SOFTLINK_NOT_FOUND_SESSION)) { + adapter_logger.error(WCAException.displayError(WCAException.E_SOFTLINK_NOT_FOUND_SESSION, "백업 전환/복구 세션 시 발생[" + sBackupAdapterGrpName + "/" + sBackupLUGrpName + "]")); + } + } + } + + + /** + * 1. 기능 : Header 데이타에서 Queue에 저장된 Key 값 추출 + * 2. 처리 개요 : + * - Transaction Key가 없는경우 LU 이름으로 한다. + * 3. 주의사항 + * + **/ + private String getKey(WCAHeader wcaHeader) { + String sKey = wcaHeader.getKey(); + + if (sKey == null || (sKey != null && sKey.equals(new String(WCAHeader.NULL_TRANKEY)))) { + myLog.logMsg(MyLog.DEBUG, "getKey] Key is null or empty, So LuName is Key " ); + sKey = wcaHeader.getLUName().trim(); + } + myLog.logMsg(MyLog.DEBUG, "getKey] Key = (" + sKey + ")"); + + if (sKey == null || (sKey != null && sKey.equals(new String(WCAHeader.NULL_TSNAME)))) { + myLog.logMsg(MyLog.DEBUG, "getKey] Key, LuName is null or empty" ); + return null; + } + + return sKey; + } + + /** + * 1. 기능 : SoftLink 세션을 통해서 데이터를 수신한다. + * 2. 처리 개요 : + * - SoftLink 세션을 통해서 파라미터인 nDataLen 값 만큼 데이터를 수신한다. + * - 정해진 데이터를 nTimeout시간안에 수신하지 못하면 장애처리 한다. + * 3. 주의사항 + * - 이 함수를 호출하기 전에 먼저 데이터 길이 필드를 수신한 해야 한다. + * + * @param nTimeout 데이터 수신 Timeout + * @param nDataLen 수신할 데이터 길이 + * @return pBuff 수신된 데이터가 저장된 버퍼 + */ + public byte[] recvDataField(int nTimeout, int nDataLen) { + byte[] pBuff = null; + int nRcvLen = 0; + int nRemainLen = 0; + int nBuffPos = 0; + long lStartTime = 0; + long lCurrTime = 0; + + try { + pBuff = new byte[nDataLen]; + nRemainLen = nDataLen; + + //sockSoftLink.setSoTimeout(1000); + sockSoftLink.setSoTimeout(0); + + lStartTime = new Date().getTime(); + + myLog.logMsg(MyLog.DEBUG, "[Before Receiving Data] "); + while (nRemainLen > 0) { + nRcvLen = isSoftLink.read(pBuff, nBuffPos, nRemainLen); + if (nRcvLen < 0) { + myLog.logMsg(MyLog.ERROR, "recvDataField] " + WCAException.displayError(WCAException.E_SOFTLINK_NOTCONN, toString()) + " ( nRcvLen = " + nRcvLen + ")"); + if (adapter_logger.isError()) { adapter_logger.error(WCAException.displayError(WCAException.E_SOFTLINK_NOTCONN, toString())); } + return null; + } + else { + nRemainLen -= nRcvLen; + nBuffPos += nRcvLen; + } + + lCurrTime = new Date().getTime(); + if (lCurrTime - lStartTime > (nTimeout * 1000)) { + sockSoftLink.setSoTimeout(0); + if (adapter_logger.isError()) { adapter_logger.error("recvDataField] - " + toString() + " Recv Timeout, StartTime = " + lStartTime + ", CurrTime = " + lCurrTime); } + myLog.logMsg(MyLog.ERROR, "recvDataField] Recv Timeout, StartTime = " + lStartTime + ", CurrTime = " + lCurrTime); + return null; + } + } + myLog.logMsg(MyLog.DEBUG, "[After Receiving Data] "); + sockSoftLink.setSoTimeout(0); + + return pBuff; + } + catch(Exception e) { + myLog.logMsg(MyLog.ERROR, "recvDataField] Error :" + e.toString()); + if (adapter_logger.isError()) { adapter_logger.error("recvDataField] " + WCAException.E_ETC + "] " + toString() + " Error :" + e.toString()); } + + try { + sockSoftLink.setSoTimeout(0); + } + catch(SocketException se) { + myLog.logMsg(MyLog.ERROR, "recvDataField] Error :" + e.toString()); + if (adapter_logger.isError()) { adapter_logger.error("recvDataField] - [" + WCAException.E_ETC + "] " + toString() + " Error :" + e.toString()); } + } + + return null; + } + } + + public byte[] recvLenthField(int nDataLen) throws Exception { + byte[] pBuff = null; + int nRcvLen = 0; + int nRemainLen = 0; + int nBuffPos = 0; + + try { + pBuff = new byte[nDataLen]; + nRemainLen = nDataLen; + + //sockSoftLink.setSoTimeout(1000 * WCADefine.DEFAULT_SOCK_RCV_TIMEOUT); + sockSoftLink.setSoTimeout(0); + + myLog.logMsg(MyLog.DEBUG, "[Before Receiving Data Length] "); + while (nRemainLen > 0) { + nRcvLen = isSoftLink.read(pBuff, nBuffPos, nRemainLen); + if (nRcvLen < 0) { + myLog.logMsg(MyLog.ERROR, "recvLenthField] " + WCAException.displayError(WCAException.E_SOFTLINK_NOTCONN, toString()) + " ( nRcvLen = " + nRcvLen + ")"); + if (adapter_logger.isError()) { adapter_logger.error(WCAException.displayError(WCAException.E_SOFTLINK_NOTCONN, toString())); } + return null; + } + else { + nRemainLen -= nRcvLen; + nBuffPos += nRcvLen; + } + } + + myLog.logMsg(MyLog.DEBUG, "[After Receiving Data Length] "); + sockSoftLink.setSoTimeout(0); + + return pBuff; + } + catch (Exception e) { + throw e; + } + } + + /** + * 1. 기능 : SoftLink TCP 세션 상태 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 세션 상태 + * 0 : 연결안됨, 1 : TCP 세션 연결, 2 : TCP 세션 사용중 (사용안함) + */ + public void setSessionStat(int nSessStat) { + this.nSessStat = nSessStat; + } + + /** + * 1. 기능 : SoftLink TCP 세션 이용 가능 상태 반환 + * 2. 처리 개요 : + * - SESS_STAT_READY 일 경우 true 반환 + * 3. 주의사항 + * + * @param 세션 상태 + * 0 : 연결안됨 (SESS_STAT_NOTCONN), + * 1 : TCP 세션 연결 (SESS_STAT_READY), + * 2 : TCP 세션 사용중 (SESS_STAT_INUSE - 사용안함) + */ + public boolean isAvailable() { + boolean bAvailable = false; + + if (nSessStat == WCADefine.SESS_STAT_READY) { + bAvailable = true; + } + else { + bAvailable = false; + } + + return bAvailable; + } + + /** + * 1. 기능 : Softlink와 연결된 세션수를 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Softlink와 연결된 세션수 + **/ + public int getConnectedSessNum() { + int nSessNum = 0; + + if (nSessStat > 0) { + nSessNum++; + } + + return nSessNum; + } + + /** + * 1. 기능 : 호스트로 송신한 데이터를 SoftLink 세션을 통해서 호트로 송신한다. + * 2. 처리 개요 : + * - 트레이스 파일에 해당 데이터를 트레이스한다. + * - 데이터의 내용을 호스트로 송신하기 위해 SoftLink 세션으로 송신한다. + * 3. 주의사항 + * - 트레이스 처리의 동기화를 위해서 myTrc 클래스에 대한 동기화를 수행한다. + * - 송신 데이터 버퍼 형식 : 길이(4) + Data(n) + * + * @param nLen 송신할 데이터의 길이 + * @param pBuff 송신할 데이터가 저장된 버퍼 + * @return nLen 송신된 데이터 길이 + * @exception WCAException + */ + public int sendData(int nLen, byte[] pBuff) throws WCAException { + byte[] pLenBuff = null; + long lStartTime = 0L, lEndTime = 0L; + WCAHeader wcaHeader = null; + + try { + // 길이에 대한 길이 필드 생성 + // 20090302 Start + // pLenBuff = MyUtil.getLenBuff(nLen, WCADefine.LEGTH_FIELD_SIZE); + pLenBuff = setInt(nLen); + // 20090302 End + + wcaHeader = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pBuff); + + // 데이터 트레이스 + /* + synchronized(myTrc) { + myTrc.logMsg("WCA -> SoftLink (LEN = " + nLen + ")"); + myTrc.logMsg("WCA Header : " + wcaHeader.toString()); + myTrc.logData(WCADefine.EBCDIC_CODE, nLen, pBuff); + } + */ + + // 길이 필드 및 데이터 송신 + synchronized (osSoftLink) { + String dateString = formatter.format(ZonedDateTime.now()); + + lStartTime = System.currentTimeMillis(); + osSoftLink.write(pLenBuff, 0, WCADefine.LEGTH_FIELD_SIZE); + osSoftLink.write(pBuff, 0, nLen); + osSoftLink.flush(); + lEndTime = System.currentTimeMillis(); + + if (adapter_logger.isDebug()) { adapter_logger.debug(dateString + " : WCA_SENDING_TIME = " + (lEndTime - lStartTime) + ", KEY = "+wcaHeader.getKey()); } + } + /* + synchronized(myTrc) { + myTrc.logMsg("[After Sending] WCA_SENDING_TIME = " + (lEndTime - lStartTime) + "("+wcaHeader.getKey() + ")"); + myTrc.logMsg("[After Sending] WCA -> SoftLink : " + wcaHeader.toString()); + } + */ + nSndCnt++; + return nLen; + } + catch (IOException ioe) { + adapter_logger.error(WCAException.E_SOFTLINK_SENDERR, ioe); + throw new WCAException(WCAException.E_SOFTLINK_SENDERR, ioe); + } + catch (Exception e) { + adapter_logger.error(WCAException.E_SOFTLINK_SENDERR, e); + throw new WCAException(WCAException.E_SOFTLINK_SENDERR, e); + } + } + + // 20090810 Start + /** + * 1. 기능 : WCA 어댑터 APP_CODE 명령 전송 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception WCAException + */ + public void sendWcaSessionAppCode(boolean bSendAdapterInfo) throws WCAException + { + int nLen = 0; + byte[] pBuff = null; + byte[] pLenBuff = null; + String sAppCode = ""; +// String sSendWcaAdapterInfo = "0"; + StringBuffer sbAppCode = new StringBuffer(); + + // 20190828 Start + try { + /* + sSendWcaAdapterInfo = AdapterPropManager.getInstance().getProperty(sAdapterName, "SEND_WCA_ADAPTER_INFO"); + if ("1".compareToIgnoreCase(sSendWcaAdapterInfo) == 0) { + this.sendWcaAdapterInfo(); + } + */ + + if (bSendAdapterInfo == true) { + this.sendWcaAdapterInfo(); + } + } + catch (Exception e) { + adapter_logger.error(WCAException.E_SOFTLINK_SENDERR, e); + } + // 20190828 End + + try { + // 어댑터 프라퍼티에 등록할 경우 + sAppCode = AdapterPropManager.getInstance().getProperty(sAdapterName, "APP_CODE"); + + // For Test + // sDataCode = "ABC,DEF,XYZ"; + + // APP_CODE 값이 NULL 이거나 길이가 0이라도 Softlink APP 코드 정보를 클리어 하기 위해 보내야 함. + if (sAppCode == null) { + myLog.logMsg(MyLog.WARN, "sendWcaSessionAppCode> Data Code is null, So Send Dummy App Code to Softlink"); + sAppCode = ""; + sbAppCode.append(sAppCode); + } + else { + sAppCode = sAppCode.trim(); + if (sAppCode.length() < 3) { + myLog.logMsg(MyLog.WARN, "sendWcaSessionAppCode> Data Code[" + sAppCode + "] is Invalid, So Send Dummy App Code to Softlink"); + sAppCode = ""; + sbAppCode.append(sAppCode); + } + else { + // 불필요한 공백 삭제 + ArrayList alDataCode = MyUtil.stringTokenizer(sAppCode, ","); + if (alDataCode != null) { + for (int i = 0; i < alDataCode.size(); i++) { + String sTempDataCode = (String)alDataCode.get(i); + sbAppCode.append(sTempDataCode.trim()); + + // 마지막 항목이 아니면 "," 추가 + if (i != (alDataCode.size() - 1)) { + sbAppCode.append(","); + } + } + } + } + } + + AppCodeCmd cmd = new AppCodeCmd(sbAppCode.toString()); + + pBuff = cmd.getData(); + nLen = pBuff.length; + + // 길이에 대한 길이 필드 생성 + // 20090302 Start + // pLenBuff = MyUtil.getLenBuff(nLen, WCADefine.LEGTH_FIELD_SIZE); + pLenBuff = setInt(nLen); + // 20090302 End + + myLog.logMsg(MyLog.WARN, "sendWcaSessionDataCode> App Code = " + sbAppCode.toString()); + myLog.logData(WCADefine.ASCII_CODE, nLen, pBuff); + + // 길이 필드 및 데이터 송신 + synchronized (osSoftLink) { + osSoftLink.write(pLenBuff, 0, WCADefine.LEGTH_FIELD_SIZE); + osSoftLink.write(pBuff, 0, nLen); + osSoftLink.flush(); + } + } + catch (IOException ioe) { + adapter_logger.error(WCAException.E_SOFTLINK_SENDERR, ioe); + throw new WCAException(WCAException.E_SOFTLINK_SENDERR, ioe); + } + catch (Exception e) { + adapter_logger.error(WCAException.E_SOFTLINK_SENDERR, e); + throw new WCAException(WCAException.E_SOFTLINK_SENDERR, e); + } + } + // 20090810 End + + // 20190828 Start + /** + * 1. 기능 : 어댑터 정보 명령 전송 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception WCAException + */ + public void sendWcaAdapterInfo() throws WCAException { + int nLen = 0; + byte[] pBuff = null; + byte[] pLenBuff = null; + String sAdptInfo = ""; + + try { + sAdptInfo = this.sAdapterName; + + WCAAdapterInfoCmd cmd = new WCAAdapterInfoCmd(sAdptInfo); + + pBuff = cmd.getData(); + nLen = pBuff.length; + + // 길이에 대한 길이 필드 생성 + // 20090302 Start + // pLenBuff = MyUtil.getLenBuff(nLen, WCADefine.LEGTH_FIELD_SIZE); + pLenBuff = setInt(nLen); + // 20090302 End + + myLog.logMsg(MyLog.WARN, "sendWcaAdapterInfo> Adapter Info = " + sAdptInfo); + myLog.logData(WCADefine.ASCII_CODE, nLen, pBuff); + + // 길이 필드 및 데이터 송신 + synchronized (osSoftLink) { + osSoftLink.write(pLenBuff, 0, WCADefine.LEGTH_FIELD_SIZE); + osSoftLink.write(pBuff, 0, nLen); + osSoftLink.flush(); + } + } + catch (IOException ioe) { + adapter_logger.error(WCAException.E_SOFTLINK_SENDERR, ioe); + throw new WCAException(WCAException.E_SOFTLINK_SENDERR, ioe); + } + catch (Exception e) { + adapter_logger.error(WCAException.E_SOFTLINK_SENDERR, e); + throw new WCAException(WCAException.E_SOFTLINK_SENDERR, e); + } + } + // 20190828 End + + /** + * 1. 기능 : 어댑터 상태 명령 전송 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception WCAException + */ + public void sendAdapterStatusData() throws WCAException { + int nLen = 0; + byte[] pBuff = null; + byte[] pLenBuff = null; + + try { + // 첫번째 세션만 수행 + if (nSessId != 0) { return; } + if (this.isBackupSessionPool()) { return; } + + ManualBackupCmd cmd = new ManualBackupCmd(); + cmd.setAdapterGrpName(this.sAdapterGroupName); + cmd.setLUGrpName(this.sGroupCode); + cmd.setDataType(WCAHeader.DATA_TYPE_GET_ADAPTER_STATUS); + + pBuff = cmd.getData(); + nLen = pBuff.length; + + // 길이에 대한 길이 필드 생성 + // 20090302 Start + // pLenBuff = MyUtil.getLenBuff(nLen, WCADefine.LEGTH_FIELD_SIZE); + pLenBuff = setInt(nLen); + // 20090302 End + + // 데이터 트레이스 + /* + WCAHeader wcaHeader = new WCAHeader(WCAHeader.WCA_HEADER_LEN, pBuff); + synchronized(myTrc) { + myTrc.logMsg("WCA -> SoftLink (LEN = " + nLen + ")"); + myTrc.logMsg("WCA Header : " + wcaHeader.toString()); + myTrc.logData(WCADefine.EBCDIC_CODE, nLen, pBuff); + } + */ + + // 길이 필드 및 데이터 송신 + synchronized (osSoftLink) { + osSoftLink.write(pLenBuff, 0, WCADefine.LEGTH_FIELD_SIZE); + osSoftLink.write(pBuff, 0, nLen); + osSoftLink.flush(); + } + } + catch (IOException ioe) { + adapter_logger.error(WCAException.E_SOFTLINK_SENDERR, ioe); + throw new WCAException(WCAException.E_SOFTLINK_SENDERR, ioe); + } + catch (Exception e) { + adapter_logger.error(WCAException.E_SOFTLINK_SENDERR, e); + throw new WCAException(WCAException.E_SOFTLINK_SENDERR, e); + } + } + + /** + * 1. 기능 : Softlink TCP 세션 close + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public void closeSoftLink() { + try { + try { + if (nSessStat != WCADefine.SESS_STAT_NOTCONN) { + // 20200825 Start + if (isSoftLink != null) { + try { + isSoftLink.close(); + isSoftLink = null; + } + catch (Exception ignore1) { + adapter_logger.error("closeSoftLink] - [" + WCAException.E_ETC +"] " + toString() + " isSoftLink.close, Error = " + ignore1.toString()); + } + } + + if (osSoftLink != null) { + try { + osSoftLink.close(); + osSoftLink = null; + } + catch (Exception ignore2) { + adapter_logger.error("closeSoftLink] - [" + WCAException.E_ETC +"] " + toString() + " osSoftLink.close Error = " + ignore2.toString()); + } + } + // 20200825 End + + sockSoftLink.close(); + } + else { + return; + } + } + catch (IOException ioe) { + myLog.logMsg(MyLog.ERROR, "closeSoftLink] - [" + WCAException.E_ETC + "] Error = " + ioe.toString()); + adapter_logger.error("closeSoftLink] - [" + WCAException.E_ETC +"] " + toString() + " Error = " + ioe.toString()); + } + + // 어댑터 상태 체크 + myLog.logMsg(MyLog.DEBUG, "setAdapterStatus] setting"); + setAdapterStatus(true); + myLog.logMsg(MyLog.DEBUG, "setAdapterStatus] ending"); + + // 미처리 트랜잭션 출력 + traceRemainTransaction(); + + // 백업 전환 + checkBackupConversion(); + } + finally { + myLog.logMsg(MyLog.INFO, "socketClose] SessStat = SESS_STAT_NOTCONN"); + nSessStat = WCADefine.SESS_STAT_NOTCONN; + } + } + + /** + * 1. 기능 : 자동 백업 전환 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + private void checkBackupConversion() { + try { + if (bRunning && !isBackupSessionPool()) { + // 20091005 Start + // 백업 Enable Flag가 false 이면 백업 전환 처리를 하지 않는다. + if (bBackupEnableFlag == false) { + myLog.logMsg(MyLog.WARN, "checkBackupConversion] - bBackupEnableFlag is " + bBackupEnableFlag); + return; + } + // 20091005 End + + // 20091005 Start + /* + // 백업 모드 이면 return + if (snaAdapter.getBackupMode(sNodeName, sGroupCode)) return; + */ + // 20091005 End + + myLog.logMsg(MyLog.DEBUG, "setWCAAutoBackup] starting "); + int nConnectedSessNum = snaAdapter.getConnectedNormalSessNum(sNodeName, sGroupCode); + myLog.logMsg(MyLog.DEBUG, "setWCAAutoBackup] nConnectedSessNum = " + nConnectedSessNum); + if (nConnectedSessNum == 0) { + snaAdapter.setWCAAutoBackup(sNodeName, sGroupCode); + setAdapterStatus(true); + } + + myLog.logMsg(MyLog.DEBUG, "setWCAAutoBackup] ending "); + } + } + catch (WCAException e) { + myLog.logMsg(MyLog.ERROR, "closeSoftLink] - [" + e.getErrorReturnCode() + "] Error = " + e.toString()); + adapter_logger.error("closeSoftLink] - [" + e.getErrorReturnCode() +"] " + toString() + " Error = " + e.toString()); + } + } + + /** + * 1. 기능 : Softlink input/output stream close + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public void closeLogStream() { + // 20200825 Start + // myLog.closeLogStream(); + // myTrc.closeLogStream(); + + if (myLog != null) { myLog.closeLogStream(); } + if (myTrc != null) { myTrc.closeLogStream(); } + // 20200825 End + } + + int setInt(byte[] buf, int val, int idx) { + buf[idx++] = (byte)((val & 0xff000000) / 0x1000000); + buf[idx++] = (byte)((val & 0x00ff0000) / 0x10000); + buf[idx++] = (byte)((val & 0x0000ff00) / 0x100); + buf[idx++] = (byte)(val & 0x000000ff); + + return 4; + } + + byte[] setInt(int val) { + byte[] buf = new byte[4]; + int idx = 0; + + buf[idx++] = (byte)((val & 0xff000000) / 0x1000000); + buf[idx++] = (byte)((val & 0x00ff0000) / 0x10000); + buf[idx++] = (byte)((val & 0x0000ff00) / 0x100); + buf[idx++] = (byte)(val & 0x000000ff); + + return buf; + } + + int setInt2(byte[] buf, int val, int idx) { + buf[idx++] = (byte)(val & 0x000000ff); + buf[idx++] = (byte)((val & 0x0000ff00) / 0x100); + buf[idx++] = (byte)((val & 0x00ff0000) / 0x10000); + buf[idx++] = (byte)((val & 0xff000000) / 0x1000000); + + return 4; + } + + static int getInt(byte[] buf, int idx) { + int b1 = 0, b2 = 0, b3 = 0, b4 = 0; + + b1 = (buf [idx] >= 0) ? buf[idx] : 0x100 + buf[idx]; + b2 = (buf [idx + 1] >= 0) ? buf[idx + 1] : 0x100 + buf[idx + 1]; + b3 = (buf [idx + 2] >= 0) ? buf[idx + 2] : 0x100 + buf[idx + 2]; + b4 = (buf [idx + 3] >= 0) ? buf[idx + 3] : 0x100 + buf[idx + 3]; + + return b1 * 0x1000000 + b2 * 0x10000 + b3 * 0x100 + b4; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/LUHostDataEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUHostDataEx.java new file mode 100644 index 0000000..d430335 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUHostDataEx.java @@ -0,0 +1,123 @@ +package com.eactive.eai.adapter.wca.cfg; + +import java.io.Serializable; + +/** +* 1. 기능 : LU 정보 Object 클래스 +* 2. 처리 개요 : LU 정보를 Get/Set 한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : Serializable +* @since : +*/ +public class LUHostDataEx implements Serializable +{ + /** + * SNA 어댑터 서버 이름 + */ + private String sSNAAdptrSevrName; + /** + * SNA 어댑터 서버 IP 주소 + */ + private String sSNAAdptrSevrIPName; + /** + * SNA 어댑터 서버 Comment + */ + private String sSNAAdptrSevrCtnt; + + /** + * 1. 기능 : Defualt Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public LUHostDataEx() { + } + + /** + * 1. 기능 : SNA 어댑터 서버 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sSNAAdptrSevrName SNA 어댑터 서버 이름 + **/ + public void setSNAAdptrSevrName(String sSNAAdptrSevrName) { + if (sSNAAdptrSevrName == null) { sSNAAdptrSevrName = ""; } + this.sSNAAdptrSevrName = sSNAAdptrSevrName.trim(); + } + + /** + * 1. 기능 : SNA 어댑터 서버 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return SNA 어댑터 서버 이름 + **/ + public String getSNAAdptrSevrName() { + return this.sSNAAdptrSevrName; + } + + /** + * 1. 기능 : SNA 어댑터 서버 IP 주소 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sSNAAdptrSevrIPName SNA 어댑터 서버 IP 주소 + **/ + public void setSNAAdptrSevrIPName(String sSNAAdptrSevrIPName) { + if (sSNAAdptrSevrIPName == null) { sSNAAdptrSevrIPName = ""; } + this.sSNAAdptrSevrIPName = sSNAAdptrSevrIPName.trim(); + } + + /** + * 1. 기능 : SNA 어댑터 서버 IP 주소 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return SNA 어댑터 서버 IP 주소 + **/ + public String getSNAAdptrSevrIPName() { + return this.sSNAAdptrSevrIPName; + } + + /** + * 1. 기능 : SNA 어댑터 서버 Comment 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sSNAAdptrSevrCtnt SNA 어댑터 서버 Comment + **/ + public void setSNAAdptrSevrCtnt(String sSNAAdptrSevrCtnt) { + if (sSNAAdptrSevrCtnt == null) { sSNAAdptrSevrCtnt = ""; } + this.sSNAAdptrSevrCtnt = sSNAAdptrSevrCtnt.trim(); + } + + /** + * 1. 기능 : SNA 어댑터 서버 Comment 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return SNA 어댑터 서버 Comment + **/ + public String getSNAAdptrSevrCtnt() { + return this.sSNAAdptrSevrCtnt; + } + + + /** + * 1. 기능 : LU 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 정보 + **/ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("LUHostData[ 어댑터 서버 이름 =").append(sSNAAdptrSevrName); + sb.append(", 어댑터 서버 IP =").append(sSNAAdptrSevrIPName); + sb.append(", 어댑터 서버 설명 =").append(sSNAAdptrSevrCtnt); + sb.append(" ]"); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/LUHostJDBCEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUHostJDBCEx.java new file mode 100644 index 0000000..e76ed19 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUHostJDBCEx.java @@ -0,0 +1,103 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.wca.jdbc.BaseJDBC; +import com.eactive.eai.adapter.wca.jdbc.JDBCException; +import com.eactive.eai.common.util.Logger; + +import java.sql.SQLException; + +/** +* 1. 기능 : LU 호스트 테이블을 접근하기 위한 JDBC 클래스 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : LUHostQuery.java +* @since : +*/ +public class LUHostJDBCEx extends BaseJDBC implements LUHostQueryEx +{ + Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + /** + * 1. 기능 : LU 호스트 정보 추가 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data LUHostData Object + * @return 추가된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int insertLUHost(LUHostDataEx data) throws JDBCException { + try { + getDsConnection(); + setStatement(INSERT_LU_HOST); + + this.preparedStatement.setString(1,data.getSNAAdptrSevrName()); + this.preparedStatement.setString(2,data.getSNAAdptrSevrIPName()); + this.preparedStatement.setString(3,data.getSNAAdptrSevrCtnt()); + + return executeUpdate(); + } + catch(SQLException e) { + throw new JDBCException("LUHostJDBC","insertLUHost",e); + } + finally { + this.close(); + } + } + + /** + * 1. 기능 : LU 호스트 정보 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data LUHostData Object + * @return 삭제된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int deleteLUHost(LUHostDataEx data) throws JDBCException { + try { + getDsConnection(); + setStatement(DELETE_LU_HOST); + this.preparedStatement.setString(1,data.getSNAAdptrSevrName()); + + return executeUpdate(); + } + catch(SQLException e) { + throw new JDBCException("LUHostJDBC","deleteLUHost",e); + } + finally { + this.close(); + } + } + + /** + * 1. 기능 : LU 호스트 정보 수정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data LUHostData Object + * @return 수정된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int updateLUHost(LUHostDataEx data) throws JDBCException { + try { + getDsConnection(); + setStatement(UPDATE_LU_HOST); + this.preparedStatement.setString(1,data.getSNAAdptrSevrIPName()); + this.preparedStatement.setString(2,data.getSNAAdptrSevrCtnt()); + this.preparedStatement.setString(3,data.getSNAAdptrSevrName()); + + return executeUpdate(); + } + catch(SQLException e) { + throw new JDBCException("LUHostJDBC","updateLUHost",e); + } + finally { + this.close(); + } + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/LUHostQueryEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUHostQueryEx.java new file mode 100644 index 0000000..f36c007 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUHostQueryEx.java @@ -0,0 +1,42 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.wca.servlet.TableInfoEx; + +/** +* 1. 기능 : LU 호스트 관리 SQL Query문을 정의한 인터페이스 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +*/ +public interface LUHostQueryEx +{ + /** + * 노드 이름에 해당하는 LU 호스트 SELECT QUERY + */ + public static final String GET_ALL_LU_HOST = "SELECT SNAAdptrSevrName, SNAAdptrSevrIPName, SNAAdptrSevrCtnt " + + "FROM " + TableInfoEx.T_LU_HOST + " where 1=1 " + + " ORDER BY SNAAdptrSevrName "; + /** + * LU 호스트 INSERT QUERY + */ + public static final String INSERT_LU_HOST = "INSERT INTO "+ TableInfoEx.T_LU_HOST + + " (SNAAdptrSevrName, SNAAdptrSevrIPName, SNAAdptrSevrCtnt ) " + + "VALUES(?, ?, ?)"; + + /** + * LU 호스트 DELETE QUERY + */ + public static final String DELETE_LU_HOST = "DELETE FROM "+ TableInfoEx.T_LU_HOST + + " WHERE SNAAdptrSevrName=?"; + + /** + * LU 호스트 UPDATE QUERY + */ + public static final String UPDATE_LU_HOST = "UPDATE "+ TableInfoEx.T_LU_HOST + + " SET SNAAdptrSevrIPName=?, SNAAdptrSevrCtnt=? " + + "WHERE SNAAdptrSevrName=? "; +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/LUInfoDataEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUInfoDataEx.java new file mode 100644 index 0000000..09d122b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUInfoDataEx.java @@ -0,0 +1,416 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.wca.global.WCADefine; + +import java.io.Serializable; + +/** +* 1. 기능 : LU 정보 Object 클래스 +* 2. 처리 개요 : LU 정보를 Get/Set 한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : Serializable +* @since : +*/ +public class LUInfoDataEx implements Serializable +{ + /** + * 노드 정보 (SNA 어댑터가 구동하는 서버 이름) + */ + private String nodeName; + /** + * EAI 어댑터 그룹 이름 + */ + private String adpterGroupName; + /** + * LU 그룹 이름 + */ + private String groupName; + /** + * PU 이름 + */ + private String puName; + /** + * LU 이름 + */ + private String luName; + /** + * 송수신 모드 : RR(‘1’)/Dedicated(’2’)/ RNR-Send(‘3’)/RNR-Recv(‘4’) + */ + private String tranMode; + /** + * LU 세션을 ACTIVE하기 위해 Connection Point로 사용하는 HOST측 Application을 의미하는 ID값 + */ + private String applyID; + + /** + * 백업 LU 여부 + */ + private String backupLUYN; + /** + * 로그 기록 여부 + */ + private String logYN; + /** + * 로그 레벨 + */ + private String StringlogLevel; + /** + * 로그 사이즈 (단위 : M) + */ + private int logSize; + + // 20080527 Start + /** + * 원격 LU 여부 + */ + private String rmtLUYN; + // 20080527 Start + + /** + * 1. 기능 : Defualt Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public LUInfoDataEx() { + } + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodName 노드이름 + **/ + public LUInfoDataEx(String sNodName) { + this.nodeName = sNodName; + } + + /** + * 1. 기능 : 노드 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodName 노드이름 + **/ + public void setNodeName(String sNodName) { + if (sNodName == null) { sNodName = ""; } + this.nodeName = sNodName.trim(); + } + + /** + * 1. 기능 : 노드 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 노드이름 + **/ + public String getNodeName() { + return this.nodeName; + } + + /** + * 1. 기능 : 어댑터 그룹 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGroupName 어댑터 그룹 이름 + **/ + public void setAdapterGroupName(String sAdapterGroupName) { + if (sAdapterGroupName == null) { sAdapterGroupName = ""; } + this.adpterGroupName = sAdapterGroupName.trim(); + } + + /** + * 1. 기능 : 어댑터 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 어댑터 그룹 이름 + **/ + public String getAdapterGroupName() { + return this.adpterGroupName; + } + + /** + * 1. 기능 : LU 그룹 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sGroupName LU 그룹 이름 + **/ + public void setGroupName(String sGroupName) { + if (sGroupName == null) { sGroupName = ""; } + this.groupName = sGroupName.trim(); + } + + /** + * 1. 기능 : LU 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 그룹 이름 + **/ + public String getGroupName() { + return this.groupName; + } + + /** + * 1. 기능 : PU 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sPUName PU 이름 + **/ + public void setPUName(String sPUName) { + if (sPUName == null) { sPUName = ""; } + this.puName = sPUName.trim(); + } + + /** + * 1. 기능 : PU 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return PU 이름 + **/ + public String getPUName() { + return this.puName; + } + + /** + * 1. 기능 : LU 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sLUName LU 이름 + **/ + public void setLUName(String sLUName) { + if (sLUName == null) { sLUName = ""; } + this.luName = sLUName.trim(); + } + + /** + * 1. 기능 : LU 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 이름 + **/ + public String getLUName() { + return this.luName; + } + + /** + * 1. 기능 : 송수신 모드 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sTranMode 송수신 모드 + **/ + public void setTranMode(String sTranMode) { + if (sTranMode == null) { sTranMode = ""; } + this.tranMode = sTranMode.trim(); + } + + /** + * 1. 기능 : 송수신 모드 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 송수신 모드 + **/ + public String getTranMode() { + return this.tranMode; + } + + /** + * 1. 기능 : 송신 가능 여부 반환 + * 2. 처리 개요 : RECV_ONLY 모드가 아닌경우 true 반환 + * 3. 주의사항 + * + * @return 송신가능 여부 + **/ + public boolean isSendable() { + if (!tranMode.equals(WCADefine.LU_TRAN_MODE_RECV_ONLY)) { + return true; + } + else { + return false; + } + } + + /** + * 1. 기능 : Application ID 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sApplyID Application ID + **/ + public void setApplyID(String sApplyID) { + if (sApplyID == null) { sApplyID = ""; } + this.applyID = sApplyID.trim(); + } + + /** + * 1. 기능 : Application ID 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Application ID + **/ + public String getApplyID() { + return this.applyID; + } + + + + /** + * 1. 기능 : 로그 기록 여부 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sLogYN 로그 기록 여부 + **/ + public void setLogYN(String sLogYN) { + if (sLogYN == null) { sLogYN = WCADefine.DEFAULT_WCA_LOG; } + logYN = sLogYN; + } + + /** + * 1. 기능 : 로그 기록 여부 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 로그 기록 여부 + **/ + public String getLogYN() { + return this.logYN; + } + + /** + * 1. 기능 : 로그 기록 여부 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sLogYN 로그 기록 여부 + **/ + public void setBackupLUYN(String sBackupLUYN) { + if (sBackupLUYN == null) { sBackupLUYN = WCADefine.DEFAULT_BACKUP_LU_NO; } + backupLUYN = sBackupLUYN; + } + + /** + * 1. 기능 : 백업 LU 여부 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 LU 여부 + **/ + public String getBackupLUYN() { + return this.backupLUYN; + } + + // 20080527 Start + /** + * 1. 기능 : 원격 LU 여부 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sRmtLUYN 원격 LU 여부 + **/ + public void setRmtLUYN(String sRmtLUYN) { + if (sRmtLUYN == null) { sRmtLUYN = WCADefine.DEFAULT_REMOTE_LU_NO; } + rmtLUYN = sRmtLUYN; + } + + /** + * 1. 기능 : 원격 LU 여부 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 원격 LU 여부 + **/ + public String getRmtLUYN() { + return this.rmtLUYN; + } + // 20080527 End + + /** + * 1. 기능 : 로그 레벨 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sLogLevel 로그 레벨 + **/ + public void setLogLevel(String sLogLevel) { + if (sLogLevel == null) { sLogLevel = WCADefine.DEFAULT_WCA_STRING_LOG_LEVEL; } + StringlogLevel = sLogLevel; + } + + /** + * 1. 기능 : 로그 레벨 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 로그 레벨 + **/ + public String getStringLogLevel() { + return this.StringlogLevel; + } + + /** + * 1. 기능 : 로그 사이즈 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sLogLevel 로그 레벨사이즈 + **/ + public void setLogSize(String sLogSize) { + try { + if (sLogSize == null) { sLogSize = String.valueOf(WCADefine.DEFAULT_WCA_LOG_SIZE); } + if (sLogSize!=null && sLogSize.equals("")) { sLogSize = String.valueOf(WCADefine.DEFAULT_WCA_LOG_SIZE); } + this.logSize = Integer.parseInt(sLogSize.trim()); + } + catch (Exception e) { + this.logSize = WCADefine.DEFAULT_WCA_LOG_SIZE; + } + } + + /** + * 1. 기능 : 로그 사이즈 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 로그 사이즈 + **/ + public int getLogSize() { + return this.logSize; + } + + /** + * 1. 기능 : LU 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 정보 + **/ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("LUInfoData[ 노드 =").append(nodeName); + sb.append(", 어댑터 그룹 이름 =").append(adpterGroupName); + sb.append(", LU 그룹 이름 =").append(groupName); + sb.append(", PU 이름 =").append(puName); + sb.append(", LU 이름 =").append(luName); + sb.append(", 송수신 모드 =").append(tranMode); + sb.append(", Application ID =").append(applyID); + sb.append(", 백업 LU 여부 =").append(backupLUYN); + sb.append(", 로그 기록 여부 =").append(logYN); + sb.append(", 로그 레벨 =").append(StringlogLevel); + sb.append(", 로그 사이즈 =").append(logSize); + sb.append(" ]"); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/LUInfoJDBCEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUInfoJDBCEx.java new file mode 100644 index 0000000..bd4d2a6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUInfoJDBCEx.java @@ -0,0 +1,254 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.wca.jdbc.BaseJDBC; +import com.eactive.eai.adapter.wca.jdbc.JDBCException; +import com.eactive.eai.adapter.wca.util.DateUtil; +import com.eactive.eai.common.util.Logger; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; + +/** +* 1. 기능 : LU 정보 테이블을 접근하기 위한 JDBC 클래스 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : LUInfoQuery.java +* @since : +*/ +public class LUInfoJDBCEx extends BaseJDBC implements LUInfoQueryEx +{ + Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + /** + * 1. 기능 : 노드이름에 해당하는 모든 LU 정보 반환 + * 2. 처리 개요 : 검색된 LU 정보를 LUInfoData Object 저장한다. + * 3. 주의사항 + * + * @params nodeName 노드 이름 + * @return HashMap 노드에 해당하는 모든 LU 정보를 저장한다. + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + /* + public HashMap getLUInfos(String nodeName) throws JDBCException { + ResultSet rs = null; + + try { + getDsConnection(); + setStatement(GET_ALL_LU_INFO); + preparedStatement.setString(1, nodeName); + rs = executeSelect(); + + HashMap luinfos = new HashMap(); + LUInfoData luinfo = null; + while(rs.next()) { + luinfo = new LUInfoData(rs.getString(1)); + luinfo.setAdapterGroupName(rs.getString(2)); + luinfo.setGroupName(rs.getString(3)); + luinfo.setPUName(rs.getString(4)); + luinfo.setLUName(rs.getString(5)); + luinfos.put(luinfo.getLUName(), luinfo); + } + trc_logger.debug("getLUInfos] luinfos size = " + luinfos.size()); + return luinfos; + } catch(Exception e) { + e.printStackTrace(); + throw new JDBCException("LUInfoJDBC","getLUInfos",e); + } finally { + this.close(rs); + } + } + */ + public HashMap getLUInfos(String nodeName) throws JDBCException { + ResultSet rs = null; + + try { + getDsConnection(); + + // 20080827 Start + /* + setStatement(GET_ALL_LU_INFO); + preparedStatement.setString(1, nodeName); + */ + setStatement(GET_ALL_NODE_LU_INFO); + // 20080827 End + rs = executeSelect(); + + // LU 정보 저장 + HashMap luInfos = new HashMap(); + + LUInfoDataEx luinfo = null; + String sTranMode = null; + String sGroupName = ""; + + /* + public static final String GET_ALL_NODE_LU_INFO + = "SELECT \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\", \"PUName\", \"LUName\", \"SndrcvDstcd\" " + + "FROM " + TableInfoEx.T_LU_INFO + + " ORDER BY \"LUGroupName\", \"AdptrGstatSevrName\", \"AdptrGroupName\" "; + */ + + while (rs.next()) { + sGroupName = rs.getString(3); + sTranMode = rs.getString(6); + luinfo = new LUInfoDataEx(rs.getString(1)); + luinfo.setAdapterGroupName(rs.getString(2)); + luinfo.setGroupName(sGroupName); + luinfo.setPUName(rs.getString(4)); + luinfo.setLUName(rs.getString(5)); + luinfo.setTranMode(sTranMode); + + luInfos.put(luinfo.getLUName(), luinfo); + } + + if(trc_logger.isDebug()) { + trc_logger.debug("getLUInfos] luinfos size = " + luInfos.size()); + } + + return luInfos; + } + catch (Exception e) { + trc_logger.error("LUInfoJDBC", e); + throw new JDBCException("LUInfoJDBC","getLUInfos",e); + } + finally { + this.close(rs); + } + } + /** + * 1. 기능 : LU 정보 추가 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data LUInfoData Object + * @return 추가된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int insertLUInfo(LUInfoDataEx data) throws JDBCException { + try { + DateUtil dateUtil = new DateUtil(); + String sDateTime = dateUtil.getDateMilliTime(); + getDsConnection(); + + setStatement(INSERT_LU_INFO); + this.preparedStatement.setString(1,data.getNodeName()); + this.preparedStatement.setString(2,data.getAdapterGroupName()); + this.preparedStatement.setString(3,data.getGroupName()); + this.preparedStatement.setString(4,data.getPUName()); + this.preparedStatement.setString(5,data.getLUName()); + this.preparedStatement.setString(6,data.getTranMode()); + this.preparedStatement.setString(7,data.getApplyID()); + this.preparedStatement.setString(8,data.getBackupLUYN()); + this.preparedStatement.setString(9,data.getLogYN()); + this.preparedStatement.setString(10,data.getStringLogLevel()); + this.preparedStatement.setInt(11,data.getLogSize()); + this.preparedStatement.setString(12, sDateTime); + this.preparedStatement.setString(13, sDateTime); + + // 20080827 Start + /* + // 20080527 Start + this.preparedStatement.setString(14,data.getRmtLUYN()); + // 20080527 End + */ + // 20080827 End + + return executeUpdate(); + } + catch (SQLException e) { + throw new JDBCException("LUInfoJDBC", "insertLUInfo", e); + } + finally { + this.close(); + } + } + + /** + * 1. 기능 : LU 정보 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data LUInfoData Object + * @return 삭제된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int deleteLUInfo(LUInfoDataEx data) throws JDBCException { + try { + getDsConnection(); + setStatement(DELETE_LU_INFO); + this.preparedStatement.setString(1,data.getNodeName()); + this.preparedStatement.setString(2,data.getAdapterGroupName()); + this.preparedStatement.setString(3,data.getGroupName()); + this.preparedStatement.setString(4,data.getPUName()); + this.preparedStatement.setString(5,data.getLUName()); + + return executeUpdate(); + } + catch (SQLException e) { + throw new JDBCException("LUInfoJDBC", "deleteLUInfo", e); + } + finally { + this.close(); + } + } + + /** + * 1. 기능 : LU 정보 수정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data LUInfoData Object + * @return 수정된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int updateLUInfo(LUInfoDataEx data) throws JDBCException { + try { + DateUtil dateUtil = new DateUtil(); + + getDsConnection(); + setStatement(UPDATE_LU_INFO); + this.preparedStatement.setString(1,data.getTranMode()); + this.preparedStatement.setString(2,data.getApplyID()); + this.preparedStatement.setString(3,data.getBackupLUYN()); + this.preparedStatement.setString(4,data.getLogYN()); + this.preparedStatement.setString(5,data.getStringLogLevel()); + this.preparedStatement.setInt(6,data.getLogSize()); + this.preparedStatement.setString(7, dateUtil.getDateMilliTime()); + + // 20080827 Start + // 20080527 Start + /* + this.preparedStatement.setString(8,data.getNodeName()); + this.preparedStatement.setString(9,data.getAdapterGroupName()); + this.preparedStatement.setString(10,data.getGroupName()); + this.preparedStatement.setString(11,data.getPUName()); + this.preparedStatement.setString(12,data.getLUName()); + */ + /* + this.preparedStatement.setString(8,data.getRmtLUYN()); + this.preparedStatement.setString(9,data.getNodeName()); + this.preparedStatement.setString(10,data.getAdapterGroupName()); + this.preparedStatement.setString(11,data.getGroupName()); + this.preparedStatement.setString(12,data.getPUName()); + this.preparedStatement.setString(13,data.getLUName()); + */ + // 20080527 End + this.preparedStatement.setString(8,data.getNodeName()); + this.preparedStatement.setString(9,data.getAdapterGroupName()); + this.preparedStatement.setString(10,data.getGroupName()); + this.preparedStatement.setString(11,data.getPUName()); + this.preparedStatement.setString(12,data.getLUName()); + // 20080827 End + return executeUpdate(); + } + catch (SQLException e) { + throw new JDBCException("LUInfoJDBC", "updateLUInfo", e); + } + finally { + this.close(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/LUInfoQueryEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUInfoQueryEx.java new file mode 100644 index 0000000..a3ad432 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/LUInfoQueryEx.java @@ -0,0 +1,88 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.wca.servlet.TableInfoEx; + +/** +* 1. 기능 : LU 정보 관리 SQL Query문을 정의한 인터페이스 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +*/ +public interface LUInfoQueryEx +{ + /** + * 노드 이름에 해당하는 LU 정보 SELECT QUERY + */ + public static final String GET_ALL_LU_INFO = "SELECT ADPTRGSTATSEVRNAME, ADPTRGROUPNAME, LUGROUPNAME, PUNAME, LUNAME, SNDRCVDSTCD " + + "FROM " + TableInfoEx.T_LU_INFO + " where ADPTRGSTATSEVRNAME=? " + + " ORDER BY ADPTRGSTATSEVRNAME, ADPTRGROUPNAME, LUGROUPNAME "; + + // 20080827 추가 + /** + * 노드 이름에 상관없이 모든 LU 정보 SELECT QUERY + */ + public static final String GET_ALL_NODE_LU_INFO = "SELECT ADPTRGSTATSEVRNAME, ADPTRGROUPNAME, LUGROUPNAME, PUNAME, LUNAME, SNDRCVDSTCD " + + "FROM " + TableInfoEx.T_LU_INFO + + " ORDER BY LUGROUPNAME, ADPTRGSTATSEVRNAME, ADPTRGROUPNAME "; + // 20080827 Start + // 20080527 Start + /** + * LU 정보 INSERT QUERY + */ + /* + public static final String INSERT_LU_INFO = "INSERT INTO "+ TableInfo.T_LU_INFO + + " (AdptrGstatSevrName, AdptrGroupName, LUGroupName, PUName, LUName, SndrcvDstcd, UapplIDName, BkupLUYn, " + + " LogUseYn, LogLvelName, MaxLogFileVal, LUInfoRegiHMS, LUAmndHMS )" + + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + */ + /* + public static final String INSERT_LU_INFO = "INSERT INTO "+ TableInfoEx.T_LU_INFO + + " (AdptrGstatSevrName, AdptrGroupName, LUGroupName, PUName, LUName, SndrcvDstcd, UapplIDName, BkupLUYn, " + + " LogUseYn, LogLvelName, MaxLogFileVal, LUInfoRegiHMS, LUAmndHMS, RmtLUYn )" + + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + */ + // 20080527 End + public static final String INSERT_LU_INFO = "INSERT INTO "+ TableInfoEx.T_LU_INFO + + " (ADPTRGSTATSEVRNAME, ADPTRGROUPNAME, LUGROUPNAME, PUNAME, LUNAME, SNDRCVDSTCD, UAPPLIDNAME, BKUPLUYN, " + + " LOGUSEYN, LOGLVELNAME, MAXLOGFILEVAL, LUINFOREGIHMS, LUAMNDHMS )" + + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + // 20080827 End + + /** + * LU 정보 DELETE QUERY + */ + public static final String DELETE_LU_INFO = "DELETE FROM "+ TableInfoEx.T_LU_INFO + + " WHERE ADPTRGSTATSEVRNAME=? AND ADPTRGROUPNAME=? AND LUGROUPNAME=? " + + " AND PUNAME=? AND LUNAME=?"; + + /** + * LU 정보 UPDATE QUERY + */ + // 20080827 Start + // 20080527 Start + /* + public static final String UPDATE_LU_INFO = "UPDATE "+ TableInfo.T_LU_INFO + + " SET SndrcvDstcd=?, UapplIDName=?, BkupLUYn =?, " + + " LogUseYn=?, LogLvelName=?, MaxLogFileVal=?, LUAmndHMS=? " + + "WHERE AdptrGstatSevrName=? AND AdptrGroupName=? AND LUGroupName=? " + + " AND PUName=? AND LUName=?"; + */ + /* + public static final String UPDATE_LU_INFO = "UPDATE "+ TableInfoEx.T_LU_INFO + + " SET SndrcvDstcd=?, UapplIDName=?, BkupLUYn =?, " + + " LogUseYn=?, LogLvelName=?, MaxLogFileVal=?, LUAmndHMS=?, RmtLUYn=? " + + "WHERE AdptrGstatSevrName=? AND AdptrGroupName=? AND LUGroupName=? " + + " AND PUName=? AND LUName=?"; + */ + // 20080527 End + public static final String UPDATE_LU_INFO = "UPDATE "+ TableInfoEx.T_LU_INFO + + " SET SNDRCVDSTCD=?, UAPPLIDNAME=?, BKUPLUYN =?, " + + " LOGUSEYN=?, LOGLVELNAME=?, MAXLOGFILEVAL=?, LUAMNDHMS=? " + + "WHERE ADPTRGSTATSEVRNAME=? AND ADPTRGROUPNAME=? AND LUGROUPNAME=? " + + " AND PUNAME=? AND LUNAME=?"; + // 20080827 End +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/SNAAdapter.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/SNAAdapter.java new file mode 100644 index 0000000..e376ae5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/SNAAdapter.java @@ -0,0 +1,2238 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.wca.WCASession; +import com.eactive.eai.adapter.wca.WCASessionPool; +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.jdbc.JDBCException; +import com.eactive.eai.adapter.wca.jdbc.JDBCFactory; +import com.eactive.eai.adapter.wca.util.MyUtil; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; + + +/** +* 1. 기능 : EAI 어댑터 그룹 이름에 해당하는 Adapter +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class SNAAdapter +{ + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + /** + * LU 그룹 세션 풀 리스트 + */ + private LinkedList listWCALocalSessonPool = null; + + /** + * 백업 LU 그룹 세션 풀 리스트 + */ + private LinkedList listWCABackupSessonPool = null; + + /** + * 세션풀 get index (round robin 방식으로 세션풀 할당하기 위함) + */ + private int nLocalSessionPoolIdx = 0; + + /** + * 어댑터 그룹 이름 + */ + public String adapterGroupName = null; + + /** + * 어댑터 이름 + */ + public String adapterName = null; + + int lugrpCount = 0; // 어댑터에 속한 노드별 LU 그룹 갯수 + + SNAAdapterManager smanager = SNAAdapterManager.getInstance(); + + /** + * 어댑터 그룹 이름, LU 그룹 세션 정보 + * 키 : 어댑터 그룹 이름 + * 값 : lugrpNodeMap (HashMap) 오브젝트 + * + * lugrpNodeMap : + * 키 : 소프트링크 노드 이름 + * 값 : lugrpGroupMap (HashMap) 오브젝트 + * + * lugrpGroupMap : + * 키 : LU 그룹 이름 + * 값 : SessionGroupDataEx 클래스 오브젝트(LU 그룹 세션 정보) + */ + private HashMap lugrpNodeMap = null; + + /** + * threadNodeMap + * 키 : Softlink Node 이름 + * 값 : threadGroupMap(LU 그룹별 쓰레드 그룹 HashMap 오브젝트) + * + * threadGroupMap + * 키 : LU 그룹 이름 + * 값 : ThreadGroup(쓰레드 그룹 오브젝트) + * + * threadGroupName : "어댑터 그룹" + "-" + "노드 이름" + "-" + "LU 그룹 코드" + * threadName : "어댑터 그룹" + "-" + "노드 이름" + "-" + "LU 그룹 코드" + "세션 번호" + [":BACKUP"] + */ + private HashMap threadNodeMap = null; + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param adapterGrpName 어댑터 그룹 이름 + * @param adapterName 어댑터 이름 + **/ + public SNAAdapter(String adapterGroupName, String adapterName) { + this.adapterGroupName = adapterGroupName; + this.adapterName = adapterName; + } + + /** + * 1. 기능 : SNA Adapter에 해당하는 LU 그룹 정보 정보를 저장하기 위한 오브젝트 생성 및 LU 그룹에 대한 정보 Load + * 2. 처리개요 : + * 3. 주의사항 : + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * + * @return LU 노드 정보 맵의 크기 + **/ + public int initAdapter() { + String sLogStr = "[" + adapterGroupName + "]"; + + listWCALocalSessonPool = new LinkedList(); // 정상 세션플 리스트 + listWCABackupSessonPool = new LinkedList(); // 백업 세션풀 리스트 + + threadNodeMap = new HashMap(); // 쓰레드 노드 맵 + + adapter_logger.warn("SNAAdapter:initAdapter> " + sLogStr + " Try To Load LU Group Info"); + + // LU 그룹 정보 맵을 로드 + lugrpNodeMap = loadAdapterInfo(adapterGroupName, adapterName); + if (lugrpNodeMap == null) { + adapter_logger.warn("SNAAdapter:initAdapter> " + sLogStr + " lugrpNodeMap is NULL"); + return 0; + } + else { + lugrpCount = getLuGrpNodeAndGroupMapCount(); + + adapter_logger.warn("SNAAdapter:initAdapter> " + sLogStr + " Success To Load LU Group Info, LU Group Count = " + lugrpCount); + printLuGroupInfo(); + + return lugrpCount; + } + } + + /** + * 1. 기능 : 어댑터 그룹 이름, LU 그룹 이름별 세션 정보 저장 + * 2. 처리 개요 : + * - DB에서 어댑터 그룹 이름에 해당하는 LU 그룹 이름별 세션 정보를 hashmap에 저장한다. + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * @return HashMap 어댑터 그룹 이름에 해당하는 LU 그룹 이름별 세션 정보 + **/ + public HashMap loadAdapterInfo(String sAdapterGrpName, String sAdapterName) { + JDBCFactory factory = JDBCFactory.newInstance(); + SessionGroupJDBCEx jdbc = null; + + String softlinkIpAddrs = null; + String localHostName = null; + String sStartBackupSession = "0"; // 백업 세션 시작 여부 + + ArrayList alSoftlinkIpAddr = null; + ArrayList alSoftlinkHostName = new ArrayList(); + + HashMap lugrpNodeTempMap = new HashMap(); + + String logStr = "[" + sAdapterGrpName + "]"; + + try { + adapter_logger.warn("SNAAdapter:loadAdapterInfo> " + logStr + " Start To Load Adapter LU Session Group Info"); + + jdbc = (SessionGroupJDBCEx)factory.create(SessionGroupJDBCEx.class); + + // WCA가 기동되는 로컬 호스트 이름을 구함 + localHostName = EAIServerManager.getInstance().getLocalServerHostName(); + + // 어댑터 이름을 기준으로 프라퍼티 정보에서 SOFTLINK_IP 정보를 구함 + // 값이 없거나 1개 이상의 Softlink IP가 Comma로 구분되어 설정될 수 있음 + softlinkIpAddrs = getSoftlinkIpAddrProperty(sAdapterName); + adapter_logger.warn("SNAAdapter:loadAdapterInfo> " + logStr + " SoftLink Property Value = " + softlinkIpAddrs); + + // 20090810 Start + // softlinkIpAddr = "127.0.0.1, 192.168.175.66 "; // 테스트를 위한 임시값 설정 + // adapter_logger.warn("loadAdapterInfo> Temporary Softlink IP = " + softlinkIpAddr); + + // Softlink IP 주소 리스트를 토큰화 하고, 공백 제거 + alSoftlinkIpAddr = MyUtil.stringTokenizer(softlinkIpAddrs, ","); + if (alSoftlinkIpAddr == null) { + throw new Exception("softlinkIpAddrs is NLL sAdapterName=" + sAdapterName); + } + + for (int i = 0; i < alSoftlinkIpAddr.size(); i++) { + String sTempSoftlinkIpAddr = ""; + sTempSoftlinkIpAddr = (String)alSoftlinkIpAddr.get(i); + alSoftlinkIpAddr.set(i, sTempSoftlinkIpAddr.trim()); + } + + // Softlink IP 주소 리스트에한 Softlink 노드 이름을 구함 + for (int i = 0; i < alSoftlinkIpAddr.size(); i++) { + // IP에 해당하는 Softlink 호스트 이름을 구함 + String softlinkHostName = getSoftlinkHostName((String)alSoftlinkIpAddr.get(i)); + if (softlinkHostName.compareTo(localHostName) == 0) { + alSoftlinkIpAddr.set(i, "127.0.0.1"); + } + + alSoftlinkHostName.add(softlinkHostName); + + adapter_logger.warn("loadAdapterInfo> " + logStr + " [" + i + "] Softlink Host Name = " + (String)alSoftlinkHostName.get(i) + + ", IP = " + (String)alSoftlinkIpAddr.get(i)); + } + + // IP가 여러개 지정되어 있을 경우에는 백업 세션 관련 처리는 수행하지 않는다. + if (alSoftlinkIpAddr.size() > 1) { + adapter_logger.warn("SNAAdapter:loadAdapterInfo> " + logStr + "] Set Forcely sStartBackupSessionFlag = 0"); + sStartBackupSession = "0"; + } + else { + // 백업 세션 시작 여부 정보를 Property에서 읽어옴 + sStartBackupSession = getStartBackupSessionProperty(sAdapterName); + adapter_logger.warn("SNAAdapter:loadAdapterInfo> " + logStr + " sStartBackupSessionFlag = " + sStartBackupSession); + } + + // Softlink IP 주소가 2개 이상인 경우에는 백업 모드 관련 기능을 사용할 수 없다는 플래그를 설정 + boolean bBackupSessionEnableFlag = true; + if (alSoftlinkIpAddr.size() > 1) { + adapter_logger.warn("SNAAdapter:loadAdapterInfo> " + logStr + " bBackupSessionEnableFlag = " + bBackupSessionEnableFlag); + bBackupSessionEnableFlag = false; + } + + for (int i = 0; i < alSoftlinkIpAddr.size(); i++) { + HashMap lugrpGroupMap = new HashMap(); + + jdbc.getAdapterInfo(lugrpGroupMap, (String)alSoftlinkHostName.get(i), + (String)alSoftlinkIpAddr.get(i), sAdapterGrpName, sStartBackupSession, bBackupSessionEnableFlag); + + if (lugrpGroupMap != null) { + lugrpNodeTempMap.put((String)alSoftlinkHostName.get(i), lugrpGroupMap); + } + } + + adapter_logger.warn("SNAAdapter:loadAdapterInfo> " + logStr + " Success To Load Adapter LU Session Group Info"); + + return lugrpNodeTempMap; + } + catch (JDBCException e) { + adapter_logger.error("SNAAdapter:loadAdapterInfo> " + logStr + ", Exception Msg = " + e.getMessage(), e); + return null; + } + catch (java.net.UnknownHostException host) { + adapter_logger.error("SNAAdapter:loadAdapterInfo> " + logStr + ", Exception Msg = " + host.getMessage(), host); + return null; + } + catch (Exception ex) { + adapter_logger.error("SNAAdapter:loadAdapterInfo> " + logStr + ", Exception Msg = " + ex.getMessage(), ex); + return null; + } + } + + + /** + * 1. 기능 : 어댑터 프라퍼티 중에서 SOFTLINK_IP 프라퍼티를 읽어들임 + * 2. 처리 개요 + * 3. 주의사항 + * + * @param adapterName 어댑터 이름 + * + * @return 어댑터 이름에 해당하는 Softlink IP Property 정보 + **/ + public String getSoftlinkIpAddrProperty(String adapterName) { + String softlinkIpAddrProperty = ""; + String propertyName = "SOFTLINK_IP"; + + adapter_logger.warn("SNAAdapter:getSoftlinkIpAddrProperty> PROPERTY_GROUP = " + adapterName + ", PROPERTY = " + propertyName); + + softlinkIpAddrProperty = AdapterPropManager.getInstance().getProperty(adapterName, propertyName); + + // Property가 설정되어 있지 않은 경우, 로컬 호스트 이름과 로컬 IP 주소(127.0.0.1) 사용 + if (softlinkIpAddrProperty == null) { + adapter_logger.warn("SNAAdapter:getSoftlinkIpAddrProperty> [" + adapterName + "] softlinkIpAddr is NULL, So Set To 127.0.0.1"); + softlinkIpAddrProperty = "127.0.0.1"; + } + // Property 값이 유효하지 않은 경우, 로컬 호스트 이름과 로컬 IP 주소(127.0.0.1) 사용 + else if (softlinkIpAddrProperty.trim().length() == 0) { + if (adapter_logger.isInfo()) { + adapter_logger.info("SNAAdapter:getSoftlinkIpAddrProperty> [" + adapterName + "] softlinkIpAddr Length is 0, So Set To 127.0.0.1"); + } + + softlinkIpAddrProperty = "127.0.0.1"; + } + + adapter_logger.info("SNAAdapter:getSoftlinkIpAddrProperty> [" + adapterName + "] softlinkIpAddr = " + softlinkIpAddrProperty); + + return softlinkIpAddrProperty.trim(); + } + + /** + * 1. 기능 : Softlink IP 주소에 해당하는 Softlink Node 이름을 구함 + * 2. 처리 개요 + * 3. 주의사항 + * + * @param softlinkIpAddr Softlink IP 주소 + * + * @return Softlink Node 이름 + **/ + public String getSoftlinkHostName(String softlinkIpAddr) { + String softlinkHostName = ""; + + JDBCFactory factory = JDBCFactory.newInstance(); + SessionGroupJDBCEx jdbc = null; + String localHostName = ""; + + adapter_logger.warn("SNAAdapter:getSoftlinkHostName> Softlink IP Address = " + softlinkIpAddr); + + try { + localHostName = EAIServerManager.getInstance().getLocalServerHostName(); + if (softlinkIpAddr.compareTo("127.0.0.1") == 0) { + adapter_logger.info("SNAAdapter:getSoftlinkHostName> IP is Local Loopback IP Address, So Return Local HostName, HostName = " + localHostName); + return localHostName; + } + + jdbc = (SessionGroupJDBCEx)factory.create(SessionGroupJDBCEx.class); + + adapter_logger.info("SNAAdapter:getSoftlinkHostName> Try to Get Softlink Host Name for IP " + softlinkIpAddr); + + softlinkHostName = jdbc.getSoftlinkNodeName(softlinkIpAddr); + + // 소프트링크 호스트 이름을 가져오지 못한 경우, 로컬 호스트 이름과 로컬 IP 주소(127.0.0.1) 사용 + if (softlinkHostName == null) { + adapter_logger.warn("SNAAdapter:getSoftlinkHostName> [" + softlinkIpAddr + "] softlinkHostName is NULL, So Return Local HostName, HostName = " + localHostName); + return localHostName; + } + + if (softlinkHostName.length() == 0) { + adapter_logger.warn("SNAAdapter:getSoftlinkHostName> [" + softlinkIpAddr + "] softlinkHostName Length is 0, So Return Local HostName, HostName = " + localHostName); + return localHostName; + } + + adapter_logger.warn("SNAAdapter:getSoftlinkHostName> [" + softlinkIpAddr + "] softlinkHostName = " + softlinkHostName); + + return softlinkHostName; + } + catch (JDBCException e) { + adapter_logger.warn("SNAAdapter:getSoftlinkHostName> JDBCException Occur, softlinkIpAddr = " + softlinkIpAddr, e); + adapter_logger.error(e.getMessage(), e); + return localHostName; + } + catch (java.net.UnknownHostException host) { + adapter_logger.warn("SNAAdapter:getSoftlinkHostName> UnknownHostException Occur, softlinkIpAddr = " + softlinkIpAddr, host); + adapter_logger.error(host.getMessage(), host); + return localHostName; + } + } + + + + /** + * 1. 기능 : 어댑터에 속한 세션 Pool을 초기화하고 세션 Pool을 시작 + * 2. 처리 개요 : + * 3. 주의사항 + * @param sGroupCode LU 그룹 이름 + **/ + public void startAdapter() { + SessionGroupDataEx lugrpInfo = null; // LU 그룹 정보 + HashMap lugrpGroupMap = null; // LU 그룹 정보 맵 + + try { + // SNAAdapter에 대한 LU 그룹 노드 맵을 돌면서 처리 + Iterator iterNode = lugrpNodeMap.keySet().iterator(); + while (iterNode.hasNext()) { + String sNodeName = (String)iterNode.next(); + adapter_logger.warn("SNAAdapter:startAdapter> [" + adapterGroupName + "] Start Process LU Group Info, NodeName = " + sNodeName); + + lugrpGroupMap = (HashMap)lugrpNodeMap.get(sNodeName); + if (lugrpGroupMap == null) { + adapter_logger.warn("SNAAdapter:startAdapter> [" + adapterGroupName + "] LU GROUP Node Map is NULL, NodeName = " + sNodeName); + continue; + } + + // SNAAdapter에 대한 LU 그룹 노드에 대한 LU 그룹 맵을 돌면서 처리 + Iterator iterGroup = lugrpGroupMap.keySet().iterator(); + while (iterGroup.hasNext()) { + String sGroupCode = (String)iterGroup.next(); + adapter_logger.warn("SNAAdapter:startAdapter> [" + adapterGroupName + "] Start Process LU Group Info, NodeName = " + sNodeName + + ", GroupCode = " + sGroupCode); + + lugrpInfo = (SessionGroupDataEx)lugrpGroupMap.get(sGroupCode); + if (lugrpInfo == null) { + adapter_logger.warn("SNAAdapter:startAdapter> [" + adapterGroupName + "] LU GROUP Map is NULL, NodeName = " + sNodeName + + ", GroupCode = " + sGroupCode); + continue; + } + + // 로컬 및 백업 세션 풀 정보를 초기화하고, 세션 풀에 속한 세션을 시작 시킴 + // 백업 세션풀은 START_BACKUP_SESSION 프라퍼티에 따라 시작 여부가 결정됨. + initAndStartLocalAndBackupSessionPool(lugrpInfo); + } + } + return; + } + catch (Exception e) { + adapter_logger.error("SNAAdapter:startAdapter> [" + adapterGroupName + "] @@@ Error :" + e.toString(), e); + return; + } + } + + /** + * 1. 기능 : 로컬 및 백업 세션 풀 정보를 초기화하고, 세션 풀에 속한 세션을 시작 시킴 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param lugrpInfo LU 그룹 정보 + **/ + + public void initAndStartLocalAndBackupSessionPool(SessionGroupDataEx lugrpInfo) { + String nodeNmae = (String)lugrpInfo.getNodeName(); + String lugrpName = (String)lugrpInfo.getGroupName(); + String sLogStr = "[" + adapterGroupName + "]"; + String sSessPoolInfo = "[" + nodeNmae + "][" + lugrpName + "]"; + + // 세션 Pool 정보 초기화 및 설정 + adapter_logger.warn("SNAAdapter:initAndStartLocalAndBackupSessionPool> " + sLogStr + " Init Session Pool Info, Session Pool = " + sSessPoolInfo); + initSessionPoolInfo(lugrpInfo, true); + + // 세션 풀에 속한 세션을 start 시킨다. + adapter_logger.warn("SNAAdapter:initAndStartLocalAndBackupSessionPool> " + sLogStr + " Start Session Pool, Session Pool = " + sSessPoolInfo); + startSessionPool(true); + + // 백업 세션 정보 확인 + if (lugrpInfo.getBackupNodeName().equals("") || lugrpInfo.getBackupPort() == 0 || lugrpInfo.getSessionCnt() == 0) { + adapter_logger.warn("SNAAdapter:initAndStartLocalAndBackupSessionPool> " + sLogStr + " Invalid Backup Session Info, So Don't Initialize Backup Session Pool, Session Pool = " + sSessPoolInfo); + return; + } + + /// 백업 세션 정보 초기화 및 설정 + adapter_logger.warn("SNAAdapter:initAndStartLocalAndBackupSessionPool> " + sLogStr + " Init Backup Session Pool Info, Session Pool = " + sSessPoolInfo); + initSessionPoolInfo(lugrpInfo, false); + + if (lugrpInfo.getStartBackupSession().equals("1")) { + adapter_logger.warn("SNAAdapter:initAndStartLocalAndBackupSessionPool> " + sLogStr + " Start Backup Session Pool, Session Pool = " + sSessPoolInfo); + startSessionPool(false); + } + else { + adapter_logger.warn("SNAAdapter:initAndStartLocalAndBackupSessionPool> " + sLogStr + " Don't Start Backup Session Pool, Session Pool = " + sSessPoolInfo); + } + } + + /** + * 1. 기능 : 어댑터 그룹에 속한 LU 그룹과 현재 설정된 백업 모드 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 그룹 및 백업 모드 정보 [ + * Key : LU 그룹 이름, value : Boolean Object 백업 모드 정보 (true : 백업, false : 정상) + **/ + public HashMap getLuGrpBackupModeMap() throws WCAException { + boolean bBackupMode = false; + int nSessNum = 0; + HashMap lugrpNodeAndGroupBackupModeMap = new HashMap(); + + if (lugrpNodeMap == null) { + return lugrpNodeAndGroupBackupModeMap; + } + + // LU 그룹 노드맵에서 키에 대한 Iterator를 구함 + Iterator iterNode = lugrpNodeMap.keySet().iterator(); + + // LU 그룹 노드맵 키에 대한 Iterator를 돌면서 처리 + while (iterNode.hasNext()) { + // LU 그룹 노드맵에서 노드 이름을 구함 + String sNodeName = (String)iterNode.next(); + + // LU 그룹 노드맵에서 노드 이름을 기준으로 LU 그룹 맵을 구함 + HashMap lugrpGroupMap = (HashMap)lugrpNodeMap.get(sNodeName); + if (lugrpGroupMap == null) { + adapter_logger.info("SNAAdapter:getLuGrpBackupModeMap> Node에 대한 LU 그룹 맵이 없음, NodeName = " + sNodeName); + continue; + } + + // LU 그룹별 백업 모드 정보를 저장할 임시 HashMap 오브젝트 생성 + HashMap tempHashMap = new HashMap(); + + // LU 그룹 맵에서 키에 대한 Iterator를 구함 + Iterator iterGroup = lugrpGroupMap.keySet().iterator(); + + // LU 그룹맵의 키에 대한 Iterator를 돌면서 처리 + while (iterGroup.hasNext()) { + // LU 그룹 맵에서 LU 그룹 값을 구함 + String sLuGroupName = (String)iterGroup.next(); + + // LU 그룹의 백업 모드 정보를 구함 + bBackupMode = getBackupMode(sNodeName, sLuGroupName); + + // LU 그룹의 백업 모드 정보를 구함 + nSessNum = getConnectedSessNum(sNodeName, sLuGroupName); + + // adapter_logger.error("SNAAdapter:getLuGrpBackupModeMap> [" + sNodeName + "][" + sLuGroupName + "] Session Count = " + nSessNum); + + // 임시 HashMap에 저장 + /* + if(bBackupMode) + tempHashMap.put(sLuGroupName, "TRUE"); + else + tempHashMap.put(sLuGroupName, "FALSE"); + */ + + // "세션 상태":"백업 상태" + if (nSessNum > 0) { + if (bBackupMode) { + tempHashMap.put(sLuGroupName, "TRUE:TRUE"); + } + else { + tempHashMap.put(sLuGroupName, "TRUE:FALSE"); + } + } + else { + if (bBackupMode) { + tempHashMap.put(sLuGroupName, "FALSE:TRUE"); + } + else { + tempHashMap.put(sLuGroupName, "FALSE:FALSE"); + } + } + } + + // 임시 HashMap을 리턴할 HashMap에 저장 + lugrpNodeAndGroupBackupModeMap.put(sNodeName, tempHashMap); + } + + // printLuGrpBackModeMap(lugrpNodeAndGroupBackupModeMap); + + return lugrpNodeAndGroupBackupModeMap; + } + + /** + * 1. 기능 : 설정된 백업 모드 정보 출력 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param luGroupMode 백업 모드 정보 + **/ + public void printLuGrpBackModeMap(HashMap lugrpNodeAndGroupBackupModeMap) { + Iterator iterNode = lugrpNodeAndGroupBackupModeMap.keySet().iterator(); + + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapter:printLuGrpBackModeMap> [" + adapterGroupName + "] Start Print LU Group Backup Mode"); + } + + while (iterNode.hasNext()) { + String sNodeName = (String)iterNode.next(); + HashMap lugrpGroupBackupModeMap = (HashMap)lugrpNodeAndGroupBackupModeMap.get(sNodeName); + if (lugrpGroupBackupModeMap == null) { + continue; + } + + Iterator iterGroup = lugrpGroupBackupModeMap.keySet().iterator(); + while (iterGroup.hasNext()) { + String sLuGroupName = (String)iterGroup.next(); + String sValue = (String)lugrpGroupBackupModeMap.get(sLuGroupName); + + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapter:printLuGrpBackModeMap> [" + adapterGroupName + "] " + sNodeName + "-" + sLuGroupName + "=" + sValue); + } + } + } + + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapter:printLuGrpBackModeMap> [" + adapterGroupName + "] End Print LU Group Backup Mode"); + } + } + + + /** + * 1. 기능 : 해당되는 LU 세션 풀 중지 + * 2. 처리 개요 : + * - 세셔 그룹에 속한 thread를 종료시킨다. + * - Thread Group에 속한 thread가 종료할 때까지 기다린다. + * - Thread Group을 Thread Group 리스트에서 삭제한다. + * - 세션 풀 리스트 삭제한다. + * 3. 주의사항 + * + * @param sessgroup SessionGroupData object + **/ + public void stopSessionPoolEx(SessionGroupDataEx sessgroup) { + String sLuGroupName = sessgroup.getGroupName(); + String sNodeName = sessgroup.getNodeName(); + + int i = 0; + WCASessionPool wcaSessionPool; + + // 1. Thread 종료 + for (i = 0; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + if (sNodeName.equals(wcaSessionPool.getNodeName())) { + if (sLuGroupName.equals(wcaSessionPool.getGroupCode())) { + wcaSessionPool.stopAdapter(); + } + } + } + + for (i = 0; i < listWCABackupSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCABackupSessonPool.get(i); + if (sNodeName.equals(wcaSessionPool.getNodeName())) { + if (sLuGroupName.equals(wcaSessionPool.getGroupCode())) { + wcaSessionPool.stopAdapter(); + } + } + } + + // 2. Thread 종료할 때까지 대기한다. + if (threadNodeMap == null) { + return; + } + + HashMap threadGroupMap = (HashMap)threadNodeMap.get(sNodeName); + if (threadGroupMap == null) { + adapter_logger.warn("SNAAdapter:stopSessionPoolEx> " + adapterGroupName + " THREAD GROUPS IS NULL"); + return; + } + + ThreadGroup threadGroup = (ThreadGroup)threadGroupMap.get(sLuGroupName); + waitForThreadEnd(threadGroup); + + // 3. Thread Group haspmap에서 삭제한다. + deleteThreadGroup(sNodeName, sLuGroupName); + + // 4. 세션 풀 리스트 삭제한다. + deleteSessionPool(sNodeName, sLuGroupName); + } + + + /** + * 1. 기능 : LU 그룹에 해당하는 세션 풀 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sGroupCode LU 그룹 이름 + **/ + public void deleteSessionPool(String sNodeName, String sGroupCode) { + int i = 0; + WCASessionPool wcaSessionPool = null; + + if (listWCALocalSessonPool.size() != 0) { + for (i = 0; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + if (wcaSessionPool.getNodeName().equals(sNodeName)) { + if (wcaSessionPool.getGroupCode().equals(sGroupCode)) { + listWCALocalSessonPool.remove(wcaSessionPool) ; + } + } + } + } + + if (listWCABackupSessonPool.size() != 0) { + for (i = 0; i < listWCABackupSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCABackupSessonPool.get(i); + if (wcaSessionPool.getNodeName().equals(sNodeName)) { + if (wcaSessionPool.getGroupCode().equals(sGroupCode)) { + listWCABackupSessonPool.remove(wcaSessionPool) ; + } + } + } + } + + return; + } + + /** + * 1. 기능 : 어댑터 그룹에 해당하는 모든 LU 그룹 세션을 중지 + * 2. 처리 개요 : + * - 세셔 그룹에 속한 thread를 종료시킨다. + * - Thread Group에 속한 thread가 종료할 때까지 기다린다. + * 3. 주의사항 + **/ + public void stopAdapter() { + int i = 0; + WCASessionPool wcaSessionPool; + + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] Try To Stop Adapter"); + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] listWCALocalSessonPool size = " + listWCALocalSessonPool.size()); + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] listWCABackupSessonPool size = " + listWCABackupSessonPool.size()); + + // 1. Thread 종료 + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] Start To Stop Local Session Pool"); + for (i = 0; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + wcaSessionPool.stopAdapter(); + //trc_logger.info(wcaSessionPool.toString() + " is stopping" ); + } + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] End To Stop Local Session Pool"); + + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] Start To Stop Backup Session Pool"); + for (i = 0; i < listWCABackupSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCABackupSessonPool.get(i); + wcaSessionPool.stopAdapter(); + //trc_logger.info(wcaSessionPool.toString() + " is stopping" ); + } + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] End To Stop Backup Session Pool"); + + // 2. Thread 종료할 때까지 대기한다. + printThreadInfo(); + if (threadNodeMap == null) { + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] threadNodeMap is NULL, So Return"); + return; + } + + // 어댑터 그룹에 속한 노드별 LU 그룹별 쓰레드를 종료하는 것을 대기 + Iterator iterNode = threadNodeMap.keySet().iterator(); + while (iterNode.hasNext()) { + String sNodeName = (String)iterNode.next(); + HashMap threadGroupMap = (HashMap)threadNodeMap.get(sNodeName); + + ThreadGroup threadGroup = null; // 노드별, LU 그룹별 쓰레드 그룹 + String sLuGroupName = null; // 노드별, LU 그룹 코드 + + Iterator iterGroup = threadGroupMap.keySet().iterator(); + while (iterGroup.hasNext()) { + sLuGroupName = (String)iterGroup.next(); + threadGroup = (ThreadGroup)threadGroupMap.get(sLuGroupName); + + waitForThreadEnd(threadGroup); + } + } + + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] Clear WCA Session Pool List"); + listWCALocalSessonPool.clear(); + listWCABackupSessonPool.clear(); + + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] Clear Thread Node Map"); + threadNodeMap.clear(); + /* + iterNode = threadNodeMap.keySet().iterator(); + while(iterNode.hasNext()) { + String sNodeName = (String)iterNode.next(); + threadNodeMap.remove(sNodeName); + } + */ + + nLocalSessionPoolIdx = 0; + + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] Clear LU Group Node Map"); + lugrpNodeMap.clear(); + /* + iterNode = lugrpNodeMap.keySet().iterator(); + while(iterNode.hasNext()) { + String sNodeName = (String)iterNode.next(); + lugrpNodeMap.remove(sNodeName); + } + */ + adapter_logger.warn("SNAAdapter:stopAdapter> [" + adapterGroupName + "] Success To Stop Adapter"); + } + + + /** + * 1. 기능 : Thread Group에 속한 Thread가 종료될때 까지 대기한다. + * 2. 처리 개요 : + * - Thread Group에 속한 thread가 종료할 때까지 기다린다. + * 3. 주의사항 + * + * @param threadGroup Thread Group + **/ + public void waitForThreadEnd(ThreadGroup threadGroup) { + int nSleepCount = 0; + + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] Start To Wait Thread End, Thread Group Name = " + threadGroup.getName()); + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] Thread Group Name = " + threadGroup.getName() + ", Thread Count = " + threadGroup.activeCount()); + + while (threadGroup.activeCount() > 0) { + try { + // 20190927 START + nSleepCount++; + // 20190927 END + + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] Waiting, Thread Group Name = " + threadGroup.getName() + ", Thread Count = " + threadGroup.activeCount()); + Thread.sleep(1000); + + // 20190927 START + // 무한정 대기를 방지하기 위해서 10초 이상 대기시 interrupt 호출, 일단 원인 파악을 위해서 막음 + /* + if (nSleepCount == 10) { + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] Call interrupt()"); + threadGroup.interrupt(); + printThreadInfo(); + } + */ + // 20190927 END + + // 20200724 Start + if (nSleepCount >= 15) { + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] Call interrupt()"); + threadGroup.interrupt(); + printThreadInfo(); + } + // 20200724 End + + // 20190927 START + // 종료 중 생성된 쓰레드가 생성된 것을 대비해서 한번더 호출 + if ((nSleepCount % 10) == 0) { + int i; + WCASessionPool wcaSessionPool; + + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] nSleepCount = " + nSleepCount); + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] Try To Stop Adapter"); + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] listWCALocalSessonPool size = " + listWCALocalSessonPool.size()); + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] listWCABackupSessonPool size = " + listWCABackupSessonPool.size()); + + // 1. Thread 종료 + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] Start To Stop Local Session Pool"); + for(i = 0; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + wcaSessionPool.stopAdapter(); + //trc_logger.info(wcaSessionPool.toString() + " is stopping" ); + } + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] End To Stop Local Session Pool"); + + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] Start To Stop Backup Session Pool"); + for(i = 0; i < listWCABackupSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCABackupSessonPool.get(i); + wcaSessionPool.stopAdapter(); + //trc_logger.info(wcaSessionPool.toString() + " is stopping" ); + } + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] End To Stop Backup Session Pool"); + } + // 20190927 END + } + catch(Exception e) { + adapter_logger.warn("SNAAdapter:waitForThreadEnd> ", e); + } + } + + adapter_logger.warn("SNAAdapter:waitForThreadEnd> [" + adapterGroupName + "] End To Wait Thread End, Thread Group Name = " + threadGroup.getName()); + try { + threadGroup.destroy(); + } + catch (Exception e) { + adapter_logger.warn("SNAAdapter:waitForThreadEnd> ", e); + } + } + + + /** + * 1. 기능 : LU 세션 풀 정보 초기화 및 설정 + * 2. 처리 개요 : + * - WCASessionPool 생성 및 정보 값을 설정한다. + * - WCASessionPool start 시킨다. + * - listWCALocalSessonPool에 추가한다. + * 3. 주의사항 + * + * @param sessgroup SessionGroupData object + **/ + public void initSessionPoolInfo(SessionGroupDataEx sessgroup, boolean isLocalSession) { + WCASessionPool wcaSessionPool= null; + + String sGroupIp = null; + + if (isLocalSession) { + sGroupIp = sessgroup.getSoftLinkSevrName(); + wcaSessionPool = new WCASessionPool(sGroupIp, sessgroup.getPort(), sessgroup.getSessionCnt()); + wcaSessionPool.setBackupCvsInfo(sessgroup.getBackupCvsMode()); + } + else { + wcaSessionPool = new WCASessionPool(sessgroup.getBackupNodeName(), sessgroup.getBackupPort(), sessgroup.getSessionCnt()); + wcaSessionPool.setSessionPoolInfo(adapterGroupName, adapterName, sessgroup.getGroupName()); + wcaSessionPool.setBackupSessionPool(true); + } + + wcaSessionPool.setSessionPoolInfo(adapterGroupName, adapterName, sessgroup.getGroupName()); + + wcaSessionPool.setLogInfo(sessgroup.isLogWritable(), sessgroup.getLogLevel(), sessgroup.getLogSize() ); + wcaSessionPool.setTranTimeout(sessgroup.getTranTimeout()); + + wcaSessionPool.setNodeName(sessgroup.getNodeName()); + wcaSessionPool.setBackupEnableFlag(sessgroup.getBackupEnableFlag()); + + if (isLocalSession) { + listWCALocalSessonPool.addLast(wcaSessionPool); + } + else { + listWCABackupSessonPool.addLast(wcaSessionPool); + } + } + + + /** + * 1. 기능 : 세션 시작 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public void startSessionPool(boolean isLocalSession) { + WCASessionPool wcaSessionPool = null; + + // 로컬 세션인 경우 + if (isLocalSession) { + for (int i = 0; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + if (!wcaSessionPool.isStarted()) { + wcaSessionPool.initAndStartWcaSessionInSessionPool(); + } + } + } + // 백업 세션인 경우 + else { + for (int i = 0; i < listWCABackupSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCABackupSessonPool.get(i); + if (!wcaSessionPool.isStarted()) { + wcaSessionPool.initAndStartWcaSessionInSessionPool(); + } + } + } + } + + public void startSessionPool(String sNodeName, String sGroupCode) { + try { + WCASessionPool wcaSessionPool = getLocalSessionPool(sNodeName, sGroupCode); + if(wcaSessionPool != null) { + adapter_logger.warn("SNAAdapter:startSessionPool> " + wcaSessionPool.toString() + " startSessionPool...."); + if (!wcaSessionPool.isStarted()) { + wcaSessionPool.initAndStartWcaSessionInSessionPool(); + } + } + } + catch (WCAException e) { + adapter_logger.error(e.toString(), e); + } + } + + + /** + * 1. 기능 : 세션 증가 + * 2. 처리 개요 : 증가한 세션수만큼 증가시킨다. + * - 백업 풀 : 서버와 port가 변경되지않았을 경우 + * - etc : port가 변경되지않았을 경우 + * 3. 주의사항 + * @param sessPool WCASessionPool object + * @param sessgroup SessionGroupData object + **/ + public void increaseSessionPoolEx(WCASessionPool sessPool, SessionGroupDataEx newGroup) { + int nOldSessNum = sessPool.getSessNum(); + int nNewSessNum = newGroup.getSessionCnt(); + + // 백업 풀인 경우 + if (sessPool.isBackupSessionPool()) { + if (sessPool.getHostName().equals(newGroup.getBackupNodeName()) && + sessPool.getPort() == newGroup.getPort() && nOldSessNum < nNewSessNum) { + sessPool.increaseSessionPool(nOldSessNum, nNewSessNum); + } + } + else { + if (sessPool.getPort() == newGroup.getPort() && nOldSessNum < nNewSessNum) { + sessPool.increaseSessionPool(nOldSessNum, nNewSessNum); + } + } + } + + + /** + * 1. 기능 : 백업 세션 시작 + * 2. 처리 개요 : + * - 백업 세션이 시작되지 않았으면 시작시킨다. + * 3. 주의사항 + * @param sGroupCode LU 그룹 이름 + **/ + public void startBackupSessionPool(String sNodeName, String sGroupCode) { + try { + WCASessionPool wcaSessionPool = getBackupSessionPool(sNodeName, sGroupCode); + + // 백업 모드이고 백업 세션이 시작되지 않았으면 시작시킨다. + if (!wcaSessionPool.getBackupMode() && !wcaSessionPool.isStarted()) { + adapter_logger.warn("SNAAdapter:startBackupSessionPool> " + wcaSessionPool.toString() + " startBackupSessionPool...."); + wcaSessionPool.initAndStartWcaSessionInSessionPool(); + } + } + catch (WCAException e) { + if (adapter_logger.isError()) { + adapter_logger.error("WCAException", e); + } + } + } + + + + /** + * 1. 기능 : 어댑터 그룹 이름별로 SoftLink와 설정된 세션 수 반환 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public int getConfiguredSessNum() { + int nTotalSessNum = 0; + + nTotalSessNum = getConfiguredNormalSessNum(); + nTotalSessNum += getConfiguredBackupSessNum(); + + return nTotalSessNum; + } + + public int getConfiguredNormalSessNum() { + return getConfiguredSessNum(listWCALocalSessonPool, "", ""); + } + + public int getConfiguredBackupSessNum() { + return getConfiguredSessNum(listWCABackupSessonPool, "", ""); + } + + public int getConfiguredSessNum(String sNodeName, String sGroupCode) { + int nTotalSessNum = 0; + + nTotalSessNum = getConfiguredNormalSessNum(sNodeName, sGroupCode); + nTotalSessNum += getConfiguredBackupSessNum(sNodeName, sGroupCode); + + return nTotalSessNum; + } + + public int getConfiguredNormalSessNum(String sNodeName, String sGroupCode) { + return getConfiguredSessNum(listWCALocalSessonPool, sNodeName, sGroupCode); + } + + public int getConfiguredBackupSessNum(String sNodeName, String sGroupCode) { + return getConfiguredSessNum(listWCABackupSessonPool, sNodeName, sGroupCode); + } + + + /** + * 1. 기능 : 어댑터 그룹 이름별, LU 그룹 이름별로 SoftLink와 설정된 세션 수 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sGroupCode LU 그룹 이름 + **/ + private int getConfiguredSessNum(LinkedList sesspool, String sNodeName, String sGroupCode) { + WCASessionPool wcaSessionPool = null; + int nTotalSessNum = 0; + int nSessNum = 0; + + if (sesspool.size() != 0) { + for (int i = 0; i < sesspool.size(); i++) { + wcaSessionPool = (WCASessionPool)sesspool.get(i); + nSessNum = wcaSessionPool.getConfiguredSessNum(); + if (!sGroupCode.equals("")) { + // 20110411 Start mjhong + /* + if (wcaSessionPool.getGroupCode().equals(sGroupCode)) + return nSessNum; + */ + if (wcaSessionPool.getNodeName().equals(sNodeName)) { + if (wcaSessionPool.getGroupCode().equals(sGroupCode)) { + return nSessNum; + } + } + // 20110411 End mjhong + } + else { + nTotalSessNum += nSessNum; + } + } + } + return nTotalSessNum; + } + + /** + * 1. 기능 : 어댑터 그룹 이름별로 SoftLink와 연결된 세션수 반환 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public synchronized int getConnectedSessNum() { + int nTotalSessNum = 0; + + nTotalSessNum = getConnectedNormalSessNum(); + nTotalSessNum += getConnectedBackupSessNum(); + + return nTotalSessNum; + } + + public int getConnectedNormalSessNum() { + return getConnectedSessNum(listWCALocalSessonPool); + } + + public int getConnectedBackupSessNum() { + return getConnectedSessNum(listWCABackupSessonPool); + } + + /** + * 1. 기능 : 어댑터 그룹 이름별, LU 그룹 이름별로 SoftLink와 연결된 세션수 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sGroupCode LU 그룹 이름 + **/ + public int getConnectedSessNum(String sNodeName, String sGroupCode) { + int nTotalSessNum = 0; + + nTotalSessNum = getConnectedNormalSessNum(sNodeName, sGroupCode); + nTotalSessNum += getConnectedBackupSessNum(sNodeName, sGroupCode); + + return nTotalSessNum; + } + + public int getConnectedNormalSessNum(String sNodeName, String sGroupCode) { + return getConnectedSessNum(listWCALocalSessonPool, sNodeName, sGroupCode); + } + + public int getConnectedBackupSessNum(String sNodeName, String sGroupCode) { + return getConnectedSessNum(listWCABackupSessonPool, sNodeName, sGroupCode); + } + + private int getConnectedSessNum(LinkedList sesspool) { + WCASessionPool wcaSessionPool = null; + int nTotalSessNum = 0; + int nSessNum = 0; + + if (sesspool.size() != 0) { + for (int i = 0; i < sesspool.size(); i++) { + wcaSessionPool = (WCASessionPool)sesspool.get(i); + nSessNum = wcaSessionPool.getConnectedSessNum(); + nTotalSessNum += nSessNum; + } + } + + return nTotalSessNum; + } + + private int getConnectedSessNum(LinkedList sesspool, String sNodeName, String sGroupCode) { + WCASessionPool wcaSessionPool = null; + int nTotalSessNum = 0; + int nSessNum = 0; + + if (sesspool.size() != 0) { + for (int i = 0; i < sesspool.size(); i++) { + wcaSessionPool = (WCASessionPool)sesspool.get(i); + nSessNum = wcaSessionPool.getConnectedSessNum(); + if (wcaSessionPool.getNodeName().equals(sNodeName)) { + if (wcaSessionPool.getGroupCode().equals(sGroupCode)) { + nTotalSessNum += nSessNum; + } + } + } + } + return nTotalSessNum; + } + + /** + * 1. 기능 : BACKUP POOL 수동 전환 모드 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodeName LU 그룹 노드 이름 + * @param sGroupCode LU 그룹 이름 + * @param flag Backup Mode (Y/N) + **/ + public void setManualBackupMode(String sNodeName, String sGroupCode, boolean flag) throws WCAException { + // LU 그룹 노드 및 LU 그룹에 해당하는 WCA Session Pool을 구함 + WCASessionPool wcaSessionPool = getLocalSessionPool(sNodeName, sGroupCode); + + // WCA Session Pool에 대한 Backup 전환 여부 가능 플래그 검사 + if (wcaSessionPool.getBackupEnableFlag() == false) { + adapter_logger.warn("SNAAdapter:setManualBackupMode> [" + adapterGroupName + "] " + sNodeName + "-" + sGroupCode + ", Backup Enable Flag is False, So Return"); + return; + } + + adapter_logger.warn("SNAAdapter:setManualBackupMode> [" + adapterGroupName + "] " + sNodeName + "-" + sGroupCode + ", Set Manual Backup Flag to " + flag); + wcaSessionPool.setManualBackupMode(flag); + + // 백업 세션이 시작되지 않았으면 시작한다. + if (flag) { + adapter_logger.warn("SNAAdapter:setManualBackupMode> [" + adapterGroupName + "] " + sNodeName + "-" + sGroupCode + ", Try to Start Backup Session Pool"); + startBackupSessionPool(sNodeName, sGroupCode); + } + } + + /** + * 1. 기능 : BACKUP POOL 자동 전환 모드 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodeName LU 그룹 노드 이름 + * @param sGroupCode LU 그룹 이름 + * @param flag Backup Mode (Y/N) + **/ + public void setAutoBackupMode(String sNodeName, String sGroupCode, boolean flag) throws WCAException { + WCASessionPool wcaSessionPool = getLocalSessionPool(sNodeName, sGroupCode); + + // WCA Session Pool에 대한 Backup 전환 여부 가능 플래그 검사 + if (wcaSessionPool.getBackupEnableFlag() == false) { + adapter_logger.warn("SNAAdapter:setAutoBackupMode> [" + adapterGroupName + "] " + sNodeName + "-" + sGroupCode + ", Backup Enable Flag is False, So Return"); + return; + } + + adapter_logger.warn("SNAAdapter:setAutoBackupMode> [" + adapterGroupName + "] " + sNodeName + "-" + sGroupCode + ", Set Auto Backup Flag to " + flag); + wcaSessionPool.setAutoBackupMode(flag); + + // 백업 세션이 시작되지 않았으면 시작한다. + if (flag) { + if (wcaSessionPool.getBackupCvsInfo().equalsIgnoreCase(WCADefine.WCA_AUTO_BACKUP_CVS_MODE_YES)) { + adapter_logger.warn("SNAAdapter:setAutoBackupMode> [" + adapterGroupName + "] " + sNodeName + "-" + sGroupCode + ", Try to Start Backup Session Pool"); + startBackupSessionPool(sNodeName, sGroupCode); + } + else { + adapter_logger.warn("SNAAdapter:setAutoBackupMode> [" + adapterGroupName + "] " + sNodeName + "-" + sGroupCode + ", Auto Backup is False, So Return"); + } + } + } + + public void setWCAAutoBackup(String sNodeName, String sGroupCode) throws WCAException { + WCASessionPool wcaSessionPool = getLocalSessionPool(sNodeName, sGroupCode); + wcaSessionPool.setWCAAutoBackup(); + + if (wcaSessionPool.getBackupCvsInfo().equalsIgnoreCase(WCADefine.WCA_AUTO_BACKUP_CVS_MODE_YES)) { + startBackupSessionPool(sNodeName, sGroupCode); + } + else { + adapter_logger.warn("SNAAdapter:setWCAAutoBackup> [" + adapterGroupName + "] " + sNodeName + "-" + sGroupCode + ", Auto Backup is False, So Return"); + } + } + + /** + * 1. 기능 : 현재 설정된 backup 모드 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodeName LU 그룹이 속한 노드 이름 + * @param sGroupCode LU 그룹 이름 + * @return Backup Mode (Y/N) + **/ + public boolean getBackupMode(String sNodeName, String sGroupCode) throws WCAException { + WCASessionPool wcaSessionPool = getLocalSessionPool(sNodeName, sGroupCode); + return wcaSessionPool.getBackupMode(); + } + + + /** + * 1. 기능 : 어댑터 그룹, LU 그룹 별 백업 세션 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGroupName 어댑터 그룹 이름 + * @param sNodeName LU 그룹 노드 이름 + * @param sGroupCode LU 그룹 이름 + * + * @return WCASession 백업 세션 + **/ + public WCASession getBackupWCASessionInSessionPoolList(String sNodeName, String sGroupCode) { + WCASessionPool wcaSessionPool = null; + WCASession wcaSession = null; + + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapter:getBackupWCASessionInSessionPoolList> [" + adapterGroupName + "] " + "Try to Find Session in Backup Session Pool List, NodeName = " + sNodeName + ", LU Group Name = " + sGroupCode); + } + + if (listWCABackupSessonPool.size() != 0) { + for (int i = 0; i < listWCABackupSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCABackupSessonPool.get(i); + if (wcaSessionPool.getNodeName().equals(sNodeName) && wcaSessionPool.getGroupCode().equals(sGroupCode)) { + // WCA 세션풀내에서 이용가능한 세션을 부하 분산울 위해서 라운드 로빈 방식으로 구한다. + wcaSession = wcaSessionPool.getWCASessionInSessionPool(); + break; + } + } + } + else { + adapter_logger.warn("SNAAdapter:getBackupWCASessionInSessionPoolList> [" + adapterGroupName + "] " + "listWCABackupSessonPool Size is 0, NodeName = " + sNodeName + ", LU Group Name = " + sGroupCode); + } + + return wcaSession; + } + + /** + * 1. 기능 : 어댑터 그룹, LU 그룹 별 세션 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sGroupCode LU 그룹 이름 + * @return WCASession 세션 + **/ + public WCASession getWCASessionInSessionPoolList() throws WCAException { + int i = 0; + WCASessionPool wcaSessionPool = null; + WCASession wcaSession = null; + + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapter:getWCASessionInSessionPoolList> [" + adapterGroupName + "] " + "Try to Find Session in Session Pool List"); + } + + // 세션 그룹이 없는 경우 + if (listWCALocalSessonPool.size() == 0){ + adapter_logger.warn("SNAAdapter:getWCASessionInSessionPoolList> [" + adapterGroupName + "] " + "listWCALocalSessonPool Size is 0"); + throw new WCAException( WCAException.E_SOFTLINK_NOT_FOUND_SESSION, adapterGroupName); + } + + // 부하 분산을 위해서 WCA 세션 풀간에서 이용가능한 WCA 세션을 구함 + nLocalSessionPoolIdx = nLocalSessionPoolIdx % listWCALocalSessonPool.size(); + for (i = nLocalSessionPoolIdx; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + + if (wcaSessionPool.getBackupMode()) { + wcaSession = getBackupWCASessionInSessionPoolList(wcaSessionPool.getNodeName(), wcaSessionPool.getGroupCode()); + } + else { + // WCA 세션풀내에서 이용가능한 세션을 부하 분산울 위해서 라운드 로빈 방식으로 구한다. + wcaSession = wcaSessionPool.getWCASessionInSessionPool(); + } + + // 이용가능한 WCA 세션을 찾은 경우, Loop Break + if (wcaSession != null) { + break; + } + } + + // 처음부터 다시 검색 + if (wcaSession == null) { + for (i = 0; i < nLocalSessionPoolIdx; i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + + if (wcaSessionPool.getBackupMode()) { + wcaSession = getBackupWCASessionInSessionPoolList(wcaSessionPool.getNodeName(), wcaSessionPool.getGroupCode()); + } + else { + // WCA 세션풀내에서 이용가능한 세션을 부하 분산울 위해서 라운드 로빈 방식으로 구한다. + wcaSession = wcaSessionPool.getWCASessionInSessionPool(); + } + + // 이용가능한 WCA 세션을 찾은 경우, Loop Break + if (wcaSession != null) { + break; + } + } + } + + if (wcaSession != null) { + nLocalSessionPoolIdx++; + return wcaSession; + } + + nLocalSessionPoolIdx++; + + adapter_logger.warn("SNAAdapter:getWCASessionInSessionPoolList> [" + adapterGroupName + "] " + "Can't Find Available WCA Session in Session Pool List"); + throw new WCAException(WCAException.E_SOFTLINK_NO_SESSION_SLOT, toString()); + } + + /** + * 1. 기능 : LU 그룹 노드 및 LU 그룹에 해당하는 이용가능한 세션 반환 + * 2. 처리 개요 : + * - 세션 풀 모드가 백업 일경우 백업 세션에서 할당받는다. + * 3. 주의사항 + * + * @param sNodeName LU 그룹 노드 이름 + * @param sGroupCode LU 그룹 이름 + * + * @return WCASession 세션 오브젝트 + **/ + + public WCASession getWCASessionInSessionPoolList(String sNodeName, String sGroupCode) throws WCAException { + int i = 0; + WCASessionPool wcaSessionPool = null; + WCASession wcaSession = null; + + if (adapter_logger.isDebug()) { + adapter_logger.debug("SNAAdapter:getWCASessionInSessionPoolList> [" + adapterGroupName + "] " + "Try to Find Session in Session Pool List, NodeName = " + sNodeName + ", LU Group Name = " + sGroupCode); + } + + if (listWCALocalSessonPool.size() == 0) { + adapter_logger.warn("SNAAdapter:getWCASessionInSessionPoolList> [" + adapterGroupName + "] " + "listWCALocalSessonPool Size is 0, NodeName = " + sNodeName + ", LU Group Name = " + sGroupCode); + throw new WCAException( WCAException.E_SOFTLINK_NOT_FOUND_SESSION, adapterGroupName ); + } + + for (i = 0; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + + // WCA 세션 Pool의 노드 이름 비교 + if (!wcaSessionPool.getNodeName().equals(sNodeName)) { + continue; + } + + // WCA 세션 Pool의 LU 그룹 이름 비교 + if(!wcaSessionPool.getGroupCode().equals(sGroupCode)) { + continue; + } + + // 백업 모드인 경우 + if (wcaSessionPool.getBackupMode()) { + wcaSession = getBackupWCASessionInSessionPoolList(wcaSessionPool.getNodeName(), wcaSessionPool.getGroupCode()); + } + else { + // WCA 세션풀내에서 이용가능한 세션을 부하 분산울 위해서 라운드 로빈 방식으로 구한다. + wcaSession = wcaSessionPool.getWCASessionInSessionPool(); + } + + // if(wcaSession != null) + break; + } + + if (wcaSession != null) { + return wcaSession; + } + + adapter_logger.warn("SNAAdapter:getWCASessionInSessionPoolList> [" + adapterGroupName + "] " + "Can't Find Available WCA Session, NodeName = " + sNodeName + ", LU Group Name = " + sGroupCode); + throw new WCAException( WCAException.E_SOFTLINK_NO_SESSION_SLOT, adapterGroupName+"/"+ sNodeName + "/" + sGroupCode); + } + + + /** + * 1. 기능 : 노드 이름 및 LU 그룹에 해당하는 백업 세션 풀 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sGroupCode LU 그룹 이름 + * @return 백업 WCASessionPool + **/ + public WCASessionPool getBackupSessionPool(String sNodeName, String sGroupCode) throws WCAException { + WCASessionPool wcaSessionPool = null; + + if (listWCABackupSessonPool.size() != 0) { + for (int i = 0; i < listWCABackupSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCABackupSessonPool.get(i); + if (wcaSessionPool.getNodeName().equals(sNodeName)) { + if (wcaSessionPool.getGroupCode().equals(sGroupCode)) { + return wcaSessionPool; + } + } + } + } + + throw new WCAException(WCAException.E_SOFTLINK_NOT_FOUND_SESSION, adapterGroupName+ "/" + sNodeName + "/" + sGroupCode + " 백업 세션" ); + } + + public WCASessionPool getLocalSessionPool(String sNodeName, String sGroupCode) throws WCAException { + WCASessionPool wcaSessionPool = null; + + if (listWCALocalSessonPool.size() != 0) { + for (int i = 0; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + if (wcaSessionPool.getNodeName().equals(sNodeName)) { + if (wcaSessionPool.getGroupCode().equals(sGroupCode)) { + return wcaSessionPool; + } + } + } + } + + throw new WCAException(WCAException.E_SOFTLINK_NOT_FOUND_SESSION, adapterGroupName + "/" + sNodeName + "/" + sGroupCode + " 정상 세션" ); + } + + + public void printSessionPool() { + int i = 0; + WCASessionPool wcaSessionPool = null; + + // 정상 세션 내용 로깅 + if (listWCALocalSessonPool.size() != 0) { + for (i = 0; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + adapter_logger.debug("\t " +wcaSessionPool.toString()); + } + } + + // 백업 세션 내용 로깅 + if (this.listWCABackupSessonPool.size() != 0) { + for (i = 0; i < listWCABackupSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCABackupSessonPool.get(i); + adapter_logger.debug("\t" + wcaSessionPool.toString()); + } + } + } + + // 20090228 Start + public String getStartBackupSessionProperty(String adapterName) { + String sStartBackupSession = null; + String propertyName = "START_BACKUP_SESSION"; + + adapter_logger.warn("SNAAdapter:getStartBackupSessionProperty> PROPERTY_GROUP = " + adapterName + ", PROPERTY = " + propertyName); + + sStartBackupSession = AdapterPropManager.getInstance().getProperty(adapterName, propertyName); + + // Property가 설정되어 있지 않은 경우, 디폴트 값인 "0" 사용 + if (sStartBackupSession == null) { + adapter_logger.warn("SNAAdapter:getStartBackupSessionProperty> [" + adapterName + "] sStartBackupSession is NULL, So Set To 0"); + sStartBackupSession = "0"; + } + + // Property 값이 유효하지 않은 경우, 디폴트 값인 "0" 사용 + if (sStartBackupSession.trim().length() == 0) { + adapter_logger.warn("SNAAdapter:getStartBackupSessionProperty> [" + adapterName + "] sStartBackupSession Length is 0, , So Set To 0"); + sStartBackupSession = "0"; + } + + adapter_logger.warn("SNAAdapter:getStartBackupSessionProperty> [" + adapterName + "] sStartBackupSession = " + sStartBackupSession); + + return sStartBackupSession; + } + + public int getLuGroupMapCount() { + return lugrpCount; + } + + private int getLuGrpNodeAndGroupMapCount() { + int nTempLuGrpCount = 0; + + if (lugrpNodeMap == null) { + adapter_logger.warn("SNAAdapter:getLuGrpMapCount> [" + adapterGroupName + "] " + "lugrpNodeMap is Null"); + return 0; + } + + Iterator iter = lugrpNodeMap.keySet().iterator(); + while (iter.hasNext()) { + String sNodeName = (String)iter.next(); + HashMap lugrpGroupMap = (HashMap)lugrpNodeMap.get(sNodeName); + if (lugrpGroupMap == null) { + continue; + } + + nTempLuGrpCount += lugrpGroupMap.keySet().size(); + } + + return nTempLuGrpCount; + } + + + public SessionGroupDataEx getLuGroupInfo(HashMap lugrpNodeMap, String sNodeName, String sLuGroupName) { + // 3. 노드 이름에 해당하는 LU 그룹 맵이 LU 그룹 노드맵에 존재하는지 검사 + HashMap lugrpGroupMap = (HashMap)lugrpNodeMap.get(sNodeName); + if (lugrpGroupMap == null) { + adapter_logger.warn("SNAAdapter:getLuGroupInfo> [" + adapterGroupName + "] " + "lugrpGroupMap is Null, NodeName = " + sNodeName); + return null; + } + + // 4. LU 그룹에 해당하는 LU 그룹 정보가 LU 그룹 맵에 존재하는지 검사 + SessionGroupDataEx lugrpInfo = (SessionGroupDataEx)lugrpGroupMap.get(sLuGroupName); + if (lugrpInfo == null) { + adapter_logger.warn("SNAAdapter:getLuGroupInfo> [" + adapterGroupName + "] " + "lugrpInfo is Null, NodeName = " + sNodeName + ", LU Group Name = " + sLuGroupName); + return null; + } + else { + return lugrpInfo; + } + } + + /** + * 1. 기능 : LU 그룹 세션 정보 추가 + * 2. 처리 개요 : + * - LU 그룹 세션 정보를 메모리에 추가한다. + * - LU 그룹 세션 구동한다. + * 3. 주의사항 + * + * @param SessionGroupData LU 그룹 세션 정보 + **/ + public void insertLuGroupInfoEx(SessionGroupDataEx data) throws WCAException { + String sLogStr = ""; + + try { + adapter_logger.warn("SNAAdapter:insertLuGroupInfoEx> Start Insert LU Group Info, Session Group Info = " + data.toString()); + + String sHostName = data.getNodeName(); + String sLuGroupName = data.getAdapterGroupName(); + sLogStr = "[" + adapterGroupName + "][" + sHostName + "][" + sLuGroupName + "]"; + + // LU 그룹 노드 정보는 어댑터가 기동시에 WCA (SOFTLINK_IP) 프라퍼티를 통해서 설정됨 + // 어댑터가 연결하고 있는 LU 그룹 노드 정보와 비교하여 존재하지 않으면, + // 자신과 관련 없는 노드에 LU 그룹이 추가된 것이기 때문에 데이터를 무시함. + HashMap lugrpGroupMap = (HashMap)lugrpNodeMap.get(sHostName); + if (lugrpGroupMap == null) { + adapter_logger.warn("SNAAdapter:insertLuGroupInfoEx> " + sLogStr + " There is No Match LU Group Node Map"); + return; + } + + // LU 그룹 정보에 대한 Softlink IP 주소, 백업 세션 풀 시작 옵션, 백업 세션 사용 가능 여부 플래등을 설정 + if (setLuGroupAdditionalInfo(data) == false) { + adapter_logger.warn("SNAAdapter:insertSessionGroupEx> " + sLogStr + " setLuGroupAddtionalInfo() Fail"); + return; + } + + adapter_logger.warn("SNAAdapter:insertSessionGroupEx> " + sLogStr + " Put Adapter LU Session Group to LU Group Map"); + lugrpGroupMap.put(sLuGroupName, data); + lugrpCount++; + + adapter_logger.warn("SNAAdapter:insertSessionGroupEx> " + sLogStr + " Init And Start Session Pool for LU Group"); + initAndStartLocalAndBackupSessionPool(data); + + adapter_logger.warn("SNAAdapter:insertSessionGroupEx> " + sLogStr + " Complete Insert LU Group"); + } + catch (Exception e) { + adapter_logger.error("SNAAdapter:insertSessionGroupEx> " + sLogStr, e); + } + } + + /** + * 1. 기능 : LU 그룹 세션 정보 삭제 + * 2. 처리 개요 : + * - LU 그룹 세션 종료한다. + * - LU 그룹 세션 정보를 메모리에 삭제한다. + * 3. 주의사항 + * + * @param SessionGroupData LU 그룹 세션 정보 + **/ + public void deleteLuGroupInfoEx(SessionGroupDataEx data) { + String sLogStr = ""; + + try { + adapter_logger.warn("SNAAdapter:deleteLuGroupInfoEx> Start To Delete LU Group Info, Session Group Info = " + data.toString()); + + String sHostName = data.getNodeName(); + String sLuGroupName = data.getAdapterGroupName(); + sLogStr = "[" + adapterGroupName + "][" + sHostName + "][" + sLuGroupName + "]"; + + // LU 그룹 노드 정보는 어댑터가 기동시에 WCA (SOFTLINK_IP) 프라퍼티를 통해서 설정됨 + // 어댑터가 연결하고 있는 LU 그룹 노드 정보와 비교하여 존재하지 않으면, + // 자신과 관련 없는 노드에 LU 그룹이 추가된 것이기 때문에 데이터를 무시함. + HashMap lugrpGroupMap = (HashMap)lugrpNodeMap.get(sHostName); + if (lugrpGroupMap == null) { + adapter_logger.warn("SNAAdapter:deleteLuGroupInfoEx> " + sLogStr + " There is No Match LU Group Node Map"); + return; + } + + stopSessionPoolEx(data); + + adapter_logger.warn("SNAAdapter:deleteLuGroupInfoEx> " + sLogStr + " Remove Adapter LU Session Group to LU Group Map"); + lugrpGroupMap.remove(sLuGroupName); + lugrpCount--; + + adapter_logger.warn("SNAAdapter:deleteLuGroupInfoEx> " + sLogStr + " Complete Delete LU Group"); + } + catch (Exception e) { + adapter_logger.error("SNAAdapter:deleteLuGroupInfoEx> " + sLogStr + " Exception Msg = " + e.getMessage(), e); + } + } + + /** + * 1. 기능 : LU 세션 풀, 백업 세션 풀 갱신 + * 2. 처리 개요 : + * - ip, port가 변하지 않고 wca 세션수만 증가했다면, 증가한 세션 수 만큼 증가시킨다. + * - 세션 정보를 갱신한다. + * 3. 주의사항 + * @param sessgroup SessionGroupData object + **/ + public void updateLuGroupInfoEx(SessionGroupDataEx data) throws WCAException { + String sLogStr = ""; + + try { + adapter_logger.warn("SNAAdapter:updateLuGroupInfoEx> Start To Update LU Group Info, Session Group Info = " + data.toString()); + + String sHostName = data.getNodeName(); + String sLuGroupName = data.getAdapterGroupName(); + + // 로그용 정보 문자열 조립 + sLogStr = "[" + adapterGroupName + "][" + sHostName + "][" + sLuGroupName + "]"; + + // LU 그룹 노드 정보는 어댑터가 기동시에 WCA (SOFTLINK_IP) 프라퍼티를 통해서 설정됨 + // 어댑터가 연결하고 있는 LU 그룹 노드 정보와 비교하여 존재하지 않으면, + // 자신과 관련 없는 노드에 LU 그룹이 추가된 것이기 때문에 데이터를 무시함. + HashMap lugrpGroupMap = (HashMap)lugrpNodeMap.get(sHostName); + if (lugrpGroupMap == null) { + adapter_logger.warn("SNAAdapter:updateLuGroupInfoEx> " + sLogStr + " There is No Match LU Group Node Map"); + return; + } + + // LU 그룹 정보에 대한 Softlink IP 주소, 백업 세션 풀 시작 옵션, 백업 세션 사용 가능 여부 플래등을 설정 + if (setLuGroupAdditionalInfo(data) == false) { + adapter_logger.warn("SNAAdapter:updateLuGroupInfoEx> " + sLogStr + " setLuGroupAddtionalInfo() Fail"); + return; + } + + WCASessionPool wcaSessionPool = null; + WCASessionPool wcaBackupSessionPool = null; + + // WCA 세션 Pool을 찾음 + wcaSessionPool = getLocalSessionPool(sHostName, sLuGroupName); + if (wcaSessionPool == null) { + adapter_logger.warn("SNAAdapter:updateLuGroupInfoEx> " + sLogStr + " Can't Find Local Session Pool"); + return; + } + + wcaSessionPool.updateLuGroupInfoEx(data); + + // 세션 수가 증가된 경우에는 WCA 세션 수 증가 + increaseSessionPoolEx(wcaSessionPool, data); + + // 백업 세션이 정의되지 않았으면 return + if (data.getBackupNodeName().equals("") || data.getBackupPort() == 0 || data.getSessionCnt() == 0) + return; + + try { + wcaBackupSessionPool = getBackupSessionPool(sHostName, sLuGroupName); + wcaBackupSessionPool.updateLuGroupInfoEx(data); + increaseSessionPoolEx(wcaBackupSessionPool, data); + } + catch (WCAException e) { + // 백업 세션이 없을 경우 백업 세션 생성 + initSessionPoolInfo(data, false); + } + + if (data.getStartBackupSession().equals("1")) { + adapter_logger.warn("SNAAdapter:updateLuGroupInfoEx> " + sLogStr + " Start Backup Session Pool"); + startSessionPool(false); + } + else { + adapter_logger.warn("SNAAdapter:updateLuGroupInfoEx> " + sLogStr + " Don't Start Backup Session Pool"); + } + } + catch (Exception e) { + adapter_logger.error("SNAAdapter:updateLuGroupInfoEx> " + sLogStr, e); + } + } + + /** + * 1. 기능 : WCA APP CODE 정보 갱신 (updateSessionInfoEx 함수를 참조하여 개발) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data SessionGroupDataEx object + **/ + public void updateWcaAppCodeEx(WcaInfoDataEx wcaInfo) throws WCAException { + // 0. 새롭게 LU 그룹 정보 맵을 로딩하고, 기존 어댑터 그룹에 해당하는 LU 그룹 노드 맵을 구함 + HashMap luGrpNodeMap = loadAdapterInfo(adapterGroupName, adapterName); + + if (luGrpNodeMap == null) { + throw new WCAException("SNAAdapter:updateWcaAppCodeEx> luGrpNodeMap not found adapterGroupName=" + adapterGroupName + ", adapterName=" + adapterName); + } + + try { + AdapterPropManager.getInstance().setProperty(adapterName, "APP_CODE", wcaInfo.appCd); + adapter_logger.error("SNAAdapter:updateWcaAppCodeEx> [" + adapterGroupName + "][" + adapterName + "] Success to set Property APP_CODE = [" + wcaInfo.appCd + "]"); + + // 기존에도 있어고 현재에도 있는 것들은 정보가 갱신된 경우 처리 + Iterator iterNewNode = luGrpNodeMap.keySet().iterator(); + while (iterNewNode.hasNext()) { + String sNodeName = (String)iterNewNode.next(); + HashMap luGrpGroupMap = (HashMap)luGrpNodeMap.get(sNodeName); + Iterator iterNewGroup = luGrpGroupMap.keySet().iterator(); + + while (iterNewGroup.hasNext()) { + String sLuGroupName = (String)iterNewGroup.next(); + SessionGroupDataEx oNewLuGroupInfo = (SessionGroupDataEx)luGrpGroupMap.get(sLuGroupName); + + // 기존 LU 그룹 정보에서 갱신된 LU 그룹 정보에 해당하는 것을 찾지 못한 경우, Continue + SessionGroupDataEx oLuGroupInfo = getLuGroupInfo(lugrpNodeMap, oNewLuGroupInfo.getNodeName(), oNewLuGroupInfo.getGroupName()); + if (oLuGroupInfo == null) { continue; } + + adapter_logger.warn("SNAAdapter:updateWcaAppCodeEx> [" + adapterGroupName + "] Update WCA App Code = [" + oLuGroupInfo.getNodeName() + "][" + oLuGroupInfo.getGroupName() + "]"); + + WCASessionPool wcaLocalSessionPool = null; + WCASessionPool wcaBackupSessionPool = null; + + // 로컬 세션 풀 정보 갱신 + wcaLocalSessionPool = getLocalSessionPool(oLuGroupInfo.getNodeName(), oLuGroupInfo.getGroupName()); + if (wcaLocalSessionPool != null) { + adapter_logger.warn("SNAAdapter:updateWcaAppCodeEx> [" + adapterGroupName + "] wcaLocalSessionPool is not null"); + wcaLocalSessionPool.updateWcaAppCodeEx(); + } + else { + adapter_logger.warn("SNAAdapter:updateWcaAppCodeEx> [" + adapterGroupName + "] wcaLocalSessionPool is null"); + } + + // 백업 세션 풀 정보 갱신 + wcaBackupSessionPool = getBackupSessionPool(oLuGroupInfo.getNodeName(), oLuGroupInfo.getGroupName()); + if (wcaBackupSessionPool != null) { + adapter_logger.warn("SNAAdapter:updateWcaAppCodeEx> [" + adapterGroupName + "] wcaBackupSessionPool is not null"); + wcaBackupSessionPool.updateWcaAppCodeEx(); + } + else { + adapter_logger.warn("SNAAdapter:updateWcaAppCodeEx> [" + adapterGroupName + "] wcaBackupSessionPool is null"); + } + } + } + } + catch (Exception e) { + adapter_logger.warn("SNAAdapter:updateWcaAppCodeEx> [" + adapterGroupName + "] Update LU Group Exception, Msg = " + e.getMessage(), e); + } + } + + public void printThreadInfo() { + if (threadNodeMap == null) { + adapter_logger.warn("SNAAdapter:printThreadInfo> [" + adapterGroupName + "] threadNodeMap is NULL, So Return"); + return; + } + + Iterator iterNode = threadNodeMap.keySet().iterator(); + while (iterNode.hasNext()) { + String sNodeName = (String)iterNode.next(); + printThreadInfo(sNodeName); + } + } + + public void printThreadInfo(String sNodeName) { + if (threadNodeMap == null) { + adapter_logger.warn("SNAAdapter:printThreadInfo> [" + adapterGroupName + "] threadNodeMap is NULL, So Return"); + return; + } + + HashMap threadGroupMap = (HashMap)threadNodeMap.get(sNodeName); + if (threadGroupMap == null) { + return; + } + + Iterator iterGroup = threadGroupMap.keySet().iterator(); + while (iterGroup.hasNext()) { + String sLuGroupName = (String)iterGroup.next(); + printThreadInfo(sNodeName, sLuGroupName); + } + } + + public void printThreadInfo(String sNodeName, String sLuGroupName) { + if (threadNodeMap == null) { + adapter_logger.warn("SNAAdapter:printThreadInfo> [" + adapterGroupName + "] threadNodeMap is NULL, So Return"); + return; + } + + HashMap threadGroupMap = (HashMap)threadNodeMap.get(sNodeName); + if (threadGroupMap == null) { + return; + } + + ThreadGroup info = (ThreadGroup)threadGroupMap.get(sLuGroupName); + if (info == null) { + return; + } + + adapter_logger.warn("SNAAdapter:printThreadInfo> [" + adapterGroupName + "]" + info.toString()); + + return; + } + + /** + * LU 그룹 정보에 대한 Softlink IP 주소와 백업 세션 풀 시작 옵션, 백업 세션 사용 가능 여부 플래등을 설정 + * + * @param data LU 그룹에 대한 세션 정보 + * + * @return LU 그룹에 대한 세션 정보 갱신 성공 여부 + */ + public boolean setLuGroupAdditionalInfo(SessionGroupDataEx data) { + String softlinkIpAddr = "127.0.0.1"; + String sStartBackupSession = "0"; + + try { + String localHostName = EAIServerManager.getInstance().getLocalServerHostName(); + if (localHostName.equals(data.getNodeName())) { + adapter_logger.warn("SNAAdapter:setLuGroupAddtionalInfo> LU Group Node Name equals Local Host Name, So Set Softlink IP to 127.0.0.1"); + softlinkIpAddr = "127.0.0.1"; + } + else { + // LU 호스트 테이블에서 추가된 LU 그룹의 노드 이름에 해당하는 IP 주소를 가져옴 + SessionGroupJDBCEx jdbc = new SessionGroupJDBCEx(); + softlinkIpAddr = jdbc.getSoftlinkIpAddr(data.getNodeName()); + if (softlinkIpAddr == null) { + adapter_logger.error("SNAAdapter:setLuGroupAddtionalInfo> softlinkIpAddr is NULL, NodeName = " + data.getNodeName()); + return false; + } + + softlinkIpAddr = softlinkIpAddr.trim(); + + if (softlinkIpAddr.length() == 0) { + adapter_logger.error("SNAAdapter:setLuGroupAddtionalInfo> softlinkIpAddr Length is 0, NodeName = " + data.getNodeName()); + return false; + } + } + + adapter_logger.warn("SNAAdapter:setLuGroupAddtionalInfo> softlinkIpAddr = " + softlinkIpAddr + ", softlinkHostName = " + data.getNodeName()); + + String softlinkIpAddrs = getSoftlinkIpAddrProperty(adapterName); + ArrayList alSoftlinkIpAddr = MyUtil.stringTokenizer(softlinkIpAddrs, ","); + + if (alSoftlinkIpAddr == null) { + throw new Exception("softlinkIpAddrs is NULL"); + } + + if (alSoftlinkIpAddr.size() > 1) { + adapter_logger.warn("SNAAdapter:setLuGroupAddtionalInfo> [" + adapterGroupName + "] Set Forcely sStartBackupSessionFlag = 0"); + data.setBackupEnableFlag(false); + sStartBackupSession = "0"; + } + else { + data.setBackupEnableFlag(true); + // 백업 세션 시작 여부 정보를 Property에서 읽어옴 + sStartBackupSession = getStartBackupSessionProperty(adapterName); + } + + adapter_logger.warn("SNAAdapter:setLuGroupAddtionalInfo> [" + adapterGroupName + "] sStartBackupSessionFlag = " + sStartBackupSession); + data.setStartBackupSession(sStartBackupSession); + + return true; + } + catch (Exception e) { + adapter_logger.warn("SNAAdapter:setLuGroupAddtionalInfo> ", e); + return false; + } + } + + + + /** + * 1. 기능 : HashMap에 저장된 어댑터 그룹, LU 그룹에 속한 Thread Group 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * @param sGroupCode LU 그룹 이름 + * @return Thread Group 정보 정보들 (ThreadGroup Object를 저장한 HashMap) + **/ + public ThreadGroup getThreadGroup(String sNodeName, String sLuGroupName) { + // LU 세션 그룹 + HashMap threadGroupMap = (HashMap)threadNodeMap.get(sNodeName); + if (threadGroupMap == null) { + adapter_logger.warn("SNAAdapter:getThreadGroup> [" + adapterGroupName + "] threadGroupMap is NULL, NodeName = " + sNodeName); + return null; + } + + ThreadGroup threadGroup = (ThreadGroup)threadGroupMap.get(sLuGroupName); + return threadGroup; + } + + /** + * 1. 기능 : Thread Group 생성 및 HashMap에 저장 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param nodeName SoftLink 노드 이름 + * @param lugrpName LU 그룹 이름 + * @param threadGroupName Thread Group 이름 + * + * @return Thread Group 정보 오브젝트 (ThreadGroup Object를 저장한 HashMap) + **/ + public synchronized ThreadGroup putThreadGroup(String nodeName, String lugrpName, String threadGroupName) { + ThreadGroup threadGroup = null; + + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] Start To PU Thread Group, NodeName = " + nodeName + ", LU Group Name = " + lugrpName); + + // 어댑터 그룹에 해당하는 Softlink 노드별 쓰레드 그룹 맵이 없을 경우, 새로운 맵을 생성하고 threadGroups 맵에 추가 + if (threadNodeMap == null) { + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] threadNodeMap is NULL, So Create New One"); + threadNodeMap = new HashMap(); + } + + // Softlink 노드별 쓰레드 그룹 맵에서 LU 그룹별 맵을 얻음 + HashMap threadGroupMap = (HashMap)threadNodeMap.get(nodeName); + + // Softlink 노드별 쓰레드 그룹 맵에서 LU 그룹별 맵이 없을 경우, 새로운 맵을 생성하고 을 얻음 + if (threadGroupMap == null) { + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] threadGroupMap is NULL, So Create New One, NodeName = " + nodeName); + threadGroupMap = new HashMap(); + + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] Create New Thread Group, Thread Group Name = " + threadGroupName); + threadGroup = new ThreadGroup(threadGroupName); + + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] Put Thread Group to Thread Group Map, LU Group Name = " + lugrpName + ", Thread Group Name = " + threadGroupName); + threadGroupMap.put(lugrpName, threadGroup); + + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] Put Thread Group Map to Thread Node Map, LU Group Name = " + lugrpName + ", Thread Group Name = " + threadGroupName); + synchronized(threadNodeMap) { + threadNodeMap.put(nodeName, threadGroupMap); + } + } + else { + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] Thread Group Map Already Exist, LU Group Name = " + lugrpName); + threadGroup = (ThreadGroup)threadGroupMap.get(lugrpName); + if (threadGroup == null) { + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] Create New Thread Group, Thread Group Name = " + threadGroupName); + threadGroup = new ThreadGroup(threadGroupName); + + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] Put Thread Group to Thread Group Map, LU Group Name = " + lugrpName + ", Thread Group Name = " + threadGroupName); + threadGroupMap.put(lugrpName, threadGroup); + } + else { + adapter_logger.warn("SNAAdapter:putThreadGroup> [" + adapterGroupName + "] Thread Group Already Exist, LU Group Name = " + lugrpName); + } + + } + + return threadGroup; + } + + /** + * 1. 기능 : Thread Group 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * @param sGroupCode LU 그룹 이름 + **/ + public synchronized void deleteThreadGroup(String nodeName, String lugrpName) { + adapter_logger.warn("SNAAdapter:deleteThreadGroup> [" + adapterGroupName + "] Start To Delete LU Thread Group, NodeName = " + nodeName + ", LU Group Name = " + lugrpName); + if (threadNodeMap == null) { + adapter_logger.warn("SNAAdapter:deleteThreadGroup> [" + adapterGroupName + "] Thread Node Map is NULL, so Return"); + return; + } + + HashMap threadGroupMap = (HashMap)threadNodeMap.get(nodeName); + if (threadGroupMap == null) { + adapter_logger.warn("SNAAdapter:deleteThreadGroup> [" + adapterGroupName + "] Thread Group Map is NULL, so Return, NodeName = " + nodeName); + return; + } + + threadGroupMap.remove(lugrpName); + + adapter_logger.warn("SNAAdapter:deleteThreadGroup> [" + adapterGroupName + "] Success To Delete LU Thread Group, NodeName = " + nodeName + ", LU Group Name = " + lugrpName); + } + + + /** + * 1. 기능 : WCA 프라퍼티 정보 갱신 처리 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public void updateWcaInfo() throws WCAException { + // 0. 새롭게 LU 그룹 정보 맵을 로딩하고, 기존 어댑터 그룹에 해당하는 LU 그룹 노드 맵을 구함 + HashMap newLuGrpNodeMap = loadAdapterInfo(adapterGroupName, adapterName); + HashMap oldLuGrpNodeMap = lugrpNodeMap; + + if (newLuGrpNodeMap == null) { + throw new WCAException("LuGrpNodeMap not found adapterGroupName=" + adapterGroupName + ", adapterName=" + adapterName); + } + // 1. 기존에는 있었으나, 현재에 삭제된 것을 찾아서 종료/삭제 처리 + try { + Iterator iterOldNode = oldLuGrpNodeMap.keySet().iterator(); + while (iterOldNode.hasNext()) { + String sOldNodeName = (String)iterOldNode.next(); + HashMap oldLuGrpGroupNap = (HashMap)oldLuGrpNodeMap.get(sOldNodeName); + Iterator iterOldGroup = oldLuGrpGroupNap.keySet().iterator(); + while (iterOldGroup.hasNext()) { + String sOldLuGroupName = (String)iterOldGroup.next(); + SessionGroupDataEx oLuGrpInfo = (SessionGroupDataEx)oldLuGrpGroupNap.get(sOldLuGroupName); + + // 새로운 LU 그룹 맵에서 기존 정보를 찾음 + SessionGroupDataEx oDeleteLuGrpInfo = getLuGroupInfo(newLuGrpNodeMap, oLuGrpInfo.getNodeName(), oLuGrpInfo.getGroupName()); + + // 새로운 LU 그룹에 없는 경우는 종료하고 삭제해야 할 대상임 + if (oDeleteLuGrpInfo == null) { + adapter_logger.warn("SNAAdapter:updateWcaInfo> [" + adapterName + "] Delete LU Group = [" + + oLuGrpInfo.getNodeName() + "][" + oLuGrpInfo.getGroupName() + "]"); + + // 종료하고, 삭제 + deleteLuGroupInfoEx(oLuGrpInfo); + } + } + } + } + catch (Exception e) { + adapter_logger.warn("SNAAdapter:updateWcaInfo> [" + adapterGroupName + "] Delete LU Group Exception", e); + } + + // 2. 기존과 현재에 모두 있는 경우 업데이트 처리 + try { + // 기존에도 있어고 현재에도 있는 것들은 정보가 갱신된 경우 처리 + Iterator iterNewNode = newLuGrpNodeMap.keySet().iterator(); + while (iterNewNode.hasNext()) { + String sNewNodeName = (String)iterNewNode.next(); + HashMap newLuGrpGroupMap = (HashMap)newLuGrpNodeMap.get(sNewNodeName); + Iterator iterNewGroup = newLuGrpGroupMap.keySet().iterator(); + while (iterNewGroup.hasNext()) { + String sNewLuGroupName = (String)iterNewGroup.next(); + SessionGroupDataEx oNewLuGroupInfo = (SessionGroupDataEx)newLuGrpGroupMap.get(sNewLuGroupName); + + // 기존 LU 그룹 정보에서 갱신된 LU 그룹 정보에 해당하는 것을 찾지 못한 경우, Continue + SessionGroupDataEx oOldLuGroupInfo = getLuGroupInfo(lugrpNodeMap, oNewLuGroupInfo.getNodeName(), oNewLuGroupInfo.getGroupName()); + if (oOldLuGroupInfo == null) { + // 삭제 대상은 3단계에서 처리 + continue; + } + + adapter_logger.warn("SNAAdapter:updateWcaInfo> [" + adapterGroupName + "] Update LU Group = [" + + oOldLuGroupInfo.getNodeName() + "][" + oOldLuGroupInfo.getGroupName() + "]"); + + WCASessionPool wcaLocalSessionPool = null; + WCASessionPool wcaBackupSessionPool = null; + + // [바로 갱신이 가능한 것들 처리] + // 로깅 정보 갱신(로그 여부, 로그 레벨, 로그 사이즈 갱신 + // 트랜잭션 타임아웃 (tran_timeout) 갱신 + // 백업 자동 전환 모드(backup_cvs_mode), 백업 전환 가능 여부(bBackupEnableFlag) 갱신 + + // [바로 갱신이 불가능한 것들 처리] + // 소프트링크 IP 주소(softLinkSevrName), 소프트링크 포트(port) 갱신 + // 백업 노드 이름(backup_node_name), 백업 노트 포트 번호(backup_port) 갱신 + // 세션 연결 갯수(sess_cnt) 갱신 + + // 로컬 세션 풀 정보 갱신 + wcaLocalSessionPool = getLocalSessionPool(oOldLuGroupInfo.getNodeName(), oOldLuGroupInfo.getGroupName()); + if (wcaLocalSessionPool != null) { + wcaLocalSessionPool.updateLuGroupInfoEx(oNewLuGroupInfo); + } + + // 백업 세션 풀 정보 갱신 + wcaBackupSessionPool = getBackupSessionPool(oOldLuGroupInfo.getNodeName(), oOldLuGroupInfo.getGroupName()); + if (wcaBackupSessionPool != null) { + wcaBackupSessionPool.updateLuGroupInfoEx(oNewLuGroupInfo); + } + } + } + } + catch (Exception e) { + adapter_logger.warn("SNAAdapter:updateWcaInfo> [" + adapterGroupName + "] Update LU Group Exception, Msg = " + e.getMessage(), e); + } + + // 3. 기존에는 없었으나, 현재에 추가된 것을 찾아서 추가 처리 + try { + Iterator iterNewNode = newLuGrpNodeMap.keySet().iterator(); + while (iterNewNode.hasNext()) { + String sNewNodeName = (String)iterNewNode.next(); + HashMap newLuGrpGroupMap = (HashMap)newLuGrpNodeMap.get(sNewNodeName); + Iterator iterMewGroup = newLuGrpGroupMap.keySet().iterator(); + while (iterMewGroup.hasNext()) { + String sNewLuGroupName = (String)iterMewGroup.next(); + SessionGroupDataEx oNewLuGrpInfo = (SessionGroupDataEx)newLuGrpGroupMap.get(sNewLuGroupName); + + // 기존 LU 그룹 맵에서 해당하는 정보를 찾음 + SessionGroupDataEx oOldLuGrpInfo = getLuGroupInfo(oldLuGrpNodeMap, oNewLuGrpInfo.getNodeName(), oNewLuGrpInfo.getGroupName()); + + // 기존에 LU 그룹맵에 없는 경우 추가해야 할 대상임 + if (oOldLuGrpInfo == null) { + adapter_logger.warn("SNAAdapter:updateWcaInfo> [" + adapterGroupName + "] Insert LU Group = [" + + oNewLuGrpInfo.getNodeName() + "][" + oNewLuGrpInfo.getGroupName() + "]"); + // oNewLuGrpInfo 정보를 이용해서 추가 하고, 시작 + insertLuGroupInfoEx(oNewLuGrpInfo); + } + } + } + } + catch (Exception e) { + adapter_logger.warn("SNAAdapter:updateWcaInfo> [" + adapterGroupName + "] Insert LU Group Exception, Msg = " + e.getMessage(), e); + } + + return; + } + + /** + * 1. 기능 : 어댑터 정보 반환 + * 2. 처리 개요 : 어댑터 그룹 이름을 반환한다. + * 3. 주의사항 + * + * @return 어댑터 정보 + **/ + public String toString() { + return " " + adapterGroupName + " "; + } + + /** + * 1. 기능 : 어댑터 그룹에 해당하는 모든 LU 세션 정보 출력 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public void printLuGroupInfo() { + if (lugrpNodeMap == null) { + adapter_logger.warn("SNAAdapter:printLuGroupInfo> lugrpNodeMap is null"); + return; + } + + Iterator iterNode = lugrpNodeMap.keySet().iterator(); + while (iterNode.hasNext()) { + String nodeName = (String)iterNode.next(); + printLuGroupInfo(nodeName); + } + + return; + } + + + /** + * 1. 기능 : 특정 노드의 LU 그룹에 해당하는 LU 세션 정보 출력 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodeName Softlink Node Name + **/ + public void printLuGroupInfo(String nodeName) { + if (lugrpNodeMap == null) { + adapter_logger.warn("SNAAdapter:printLuGroupInfo> lugrpNodeMap is null"); + return; + } + + HashMap lugrpGroupMap = (HashMap)lugrpNodeMap.get(nodeName); + if (lugrpGroupMap == null) { + adapter_logger.warn("SNAAdapter:printLuGroupInfo> lugrpGroupMap is null, NodeName = " + nodeName); + return; + } + + Iterator iterGroup = lugrpGroupMap.keySet().iterator(); + while (iterGroup.hasNext()) { + String lugrpName = (String)iterGroup.next(); + printLuGroupInfo(nodeName, lugrpName); + } + } + + /** + * 1. 기능 : 어댑터 그룹, LU 그룹에 해당하는 LU 세션 정보 출력 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodeName Softlink Node Name + * @param sGroupCode LU 그룹 이름 + **/ + public void printLuGroupInfo(String nodeName, String lugrpName) { + if (lugrpNodeMap == null) { + adapter_logger.warn("SNAAdapter:printLuGroupInfo> lugrpNodeMap is null"); + return; + } + + HashMap lugrpGroupMap = (HashMap)lugrpNodeMap.get(nodeName); + if (lugrpGroupMap == null) { + adapter_logger.warn("SNAAdapter:printLuGroupInfo> lugrpGroupMap is null, NodeName = " + nodeName); + return; + } + + SessionGroupDataEx lugrpInfo = (SessionGroupDataEx)lugrpGroupMap.get(lugrpName); + if (lugrpInfo == null) { + adapter_logger.warn("SNAAdapter:printLuGroupInfo> lugrpGroupMap is null, NodeName = " + nodeName + ", LU Group Name = " + lugrpName); + return; + } + + if (adapter_logger.isDebug()) { + adapter_logger.debug(lugrpInfo.toString()); + } + } + + /** + * 1. 기능 : SNA 어댑터에 속한 모든(로컬/백업) WCA Session Pool에 대해서 INBOUND 핸들러 등록 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param objHandler INBOUND 핸들러 instance + **/ + public void registerEventHandler(Object objHandler) { + int i = 0; + WCASessionPool wcaSessionPool; + + adapter_logger.warn("SNAAdapter:registerEventHandler> [" + adapterGroupName + "] Start to Register Event Handler"); + + adapter_logger.warn("SNAAdapter:registerEventHandler> [" + adapterGroupName + "] Start to Register Event Handler For Local Session Pool List, Size = " + listWCALocalSessonPool.size()); + for (i = 0; i < listWCALocalSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCALocalSessonPool.get(i); + wcaSessionPool.registerEventHandler(objHandler); + } + + adapter_logger.warn("SNAAdapter:registerEventHandler> [" + adapterGroupName + "] Start to Register Event Handler For Backup Session Pool List, Size = " + listWCABackupSessonPool.size()); + for (i = 0; i < listWCABackupSessonPool.size(); i++) { + wcaSessionPool = (WCASessionPool)listWCABackupSessonPool.get(i); + wcaSessionPool.registerEventHandler(objHandler); + } + + adapter_logger.warn("SNAAdapter:registerEventHandler> [" + adapterGroupName + "] Success to Register Event Handler"); + + return; + } +} + + + diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/SNAAdapterManager.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/SNAAdapterManager.java new file mode 100644 index 0000000..5c0f952 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/SNAAdapterManager.java @@ -0,0 +1,446 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.wca.WCASession; +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.jdbc.JDBCException; +import com.eactive.eai.adapter.wca.jdbc.JDBCFactory; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +import java.util.ArrayList; +import java.util.HashMap; + + +/** +* 1. 기능 : SNAAdpaterManager(WCA) 관리, Singleton 패턴 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 22. 오후 4:49:17 +*/ +public class SNAAdapterManager +{ + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + /** + * Adapter 맵 + * 키 : 어댑터 그룹 이름 + * 값 : SNAAdapter 클래스 오브젝트 + */ + HashMap adapterMap; + + /** + * LU 정보 List (LU 이름이 정의되어 있을 경우 해당 LU 세션 그룹으로 데이타 송신하기 위함) + * 키 : LU 이름 + * 값 : LUInfoDataEx 클래스 오브젝트 + */ + HashMap luMap; + + /** + * SNAAdapterManager Single Instance + */ + static SNAAdapterManager smanager = new SNAAdapterManager(); + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * - LU 정보를 로딩한다. + * 3. 주의사항 + **/ + private SNAAdapterManager() { + adapterMap = new HashMap(); // 어댑터 정보 Map 오브젝트 생성 + luMap = new HashMap(); // LU 정보 Map 오브젝트 생성 + + // 모든 LU 정보를 LU 정보 테이블에서 로드하여 HashMap(luMap)에 저장 + loadLUInfos(); + } + + /** + * 1. 기능 : 모든 LU 정보를 LU 정보 테이블에서 로드하여 HashMap(luMap)에 저장 + * 2. 처리 개요 + * 3. 주의사항 + **/ + public synchronized void loadLUInfos() { + JDBCFactory factory = JDBCFactory.newInstance(); + LUInfoJDBCEx jdbc = null; + + try { + adapter_logger.warn("SNAAdapterManager:loadLUInfos> Start To Load Adapter LU Info."); + + jdbc = (LUInfoJDBCEx)factory.create(LUInfoJDBCEx.class); + luMap = jdbc.getLUInfos(EAIServerManager.getInstance().getLocalServerHostName()); + + adapter_logger.warn("SNAAdapterManager:loadLUInfos> Success To Load LU Info."); + } + catch (java.net.UnknownHostException host) { + adapter_logger.error("SNAAdapterManager:loadLUInfos> " + host.getMessage(), host); + } + catch (JDBCException e) { +// e.printStackTrace(); + adapter_logger.error("SNAAdapterManager:loadLUInfos> " + e.getMessage(), e); + } + } + + /** + * 1. 기능 : LU 이름에 해당하는 LU 그룹 노드 이름 및 LU 그룹 이름 반환 + * 2. 처리 개요 : + * - LU 이름이 정의 되어 있으면 해당 LU 그룹 세션을 구한다. + * - 특정 LU로 데이터를 전송할때, 해당 LU를 포함하고 있는 노드 및 LU 그룹 정보를 추출하기 위해 사용된다. + * 3. 주의사항 + * + * @param luName LU 이름 + * + * @return LU에 해당하는 LU 그룹 노드 이름 및 LU 그룹 이름을 포함하는 ArrayList + **/ + public ArrayList getNodeAndGroupName(String luName) throws WCAException { + ArrayList alInfo = new ArrayList(); + + if (luName == null) { + adapter_logger.error("SNAAdapterManager:getNodeAndGroupName> LU Name is NULL"); + alInfo.add(""); // Dummy 노드 이름 + alInfo.add(""); // Dummy LU 그룹 이름 + return alInfo; + } + + if (luName.trim().equals("")) { + adapter_logger.error("SNAAdapterManager:getNodeAndGroupName> LU Name Length is 0"); + alInfo.add(""); + alInfo.add(""); + return alInfo; + } + + LUInfoDataEx luInfo = (LUInfoDataEx)luMap.get(luName); + if (luInfo == null) { + adapter_logger.error("SNAAdapterManager:getGroupCode> " + WCAException.displayError(WCAException.E_LUNAME_NO_EXIST, "LU 이름 = " + luName)); + throw new WCAException(WCAException.E_LUNAME_NO_EXIST, "LU 이름 = " + luName); + } + + alInfo.add(luInfo.getNodeName()); + alInfo.add(luInfo.getGroupName()); + + return alInfo; + } + + /** + * 1. 기능 : SNAAdapterManager Singleton Object 반환 + * 2. 처리 개요 : SNAAdapterManager Singleton Object 반환한다. + * 3. 주의사항 + * + * @return SNAAdapterManager Singleton object + **/ + public static SNAAdapterManager getInstance() { + if (smanager == null) { + smanager = new SNAAdapterManager(); + } + + return smanager; + } + + /** + * 1. 기능 : 어댑터 그룹에 해당하는 SNA Adapter 오브젝트를 어댑터 맵에 추가한다. + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * @param sessgroups SessionGroupData Object를 저장한 HashMap + **/ + public void insertSnaAdapter(String adapterGroupName, SNAAdapter snaAdapter) { + adapter_logger.warn("SNAAdapterManager:insertAdapterToMap> Put Adapter in Adapter Map, sAdapterGrpName = " + adapterGroupName); + synchronized (adapterMap) { + adapterMap.put(adapterGroupName, snaAdapter); + } + return; + } + + /** + * 1. 기능 : 어댑터 그룹에 해당하는 어댑터 오브젝트를 구함 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * + * @param SNAAdapter 오브젝트 + **/ + public SNAAdapter selectSnaAdapter(String adapterGroupName) { + SNAAdapter snaAdapter = (SNAAdapter)adapterMap.get(adapterGroupName); + return snaAdapter; + } + + /** + * 1. 기능 : 어댑터 맵에서 어댑터 그룹에 해당하는 SNA Adapter 오브젝트를 삭제한다. + * 2. 처리 개요 : + * - SNAAdapter를 HashMap(adapters)에 삭제한다. + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + **/ + public void deleteSnaAdapter(String adapterGroupName) { + adapter_logger.warn("SNAAdapterManager:deleteSnaAdapter> Delete Adapter in Adapter Map, sAdapterGrpName = " + adapterGroupName); + try { + synchronized (adapterMap) { + adapterMap.remove(adapterGroupName); + } + } + catch (Exception e) { + adapter_logger.warn("SNAAdapterManager:deleteSnaAdapter> Exception", e); + // e.printStackTrace(); + } + } + + + /** + * 1. 기능 : 어댑터 그룹 이름에 해당하는 SNA 어댑터를 종료한다. + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param adapterGroupName 어댑터 그룹 이름 + * @param adapterName 어댑터 이름 + **/ + public void stopAdapter(String adapterGroupName, String adapterName) { + String sLogStr = "[" + adapterGroupName + "][" + adapterName + "]"; + + adapter_logger.warn("SNAAdapterManager:stopAdapter> Try To Stop Adapter, " + sLogStr); + + SNAAdapter snaAdapter = selectSnaAdapter(adapterGroupName); + if (snaAdapter == null) { + adapter_logger.warn("SNAAdapterManager:stopAdapter> There is No Adapter, So Return, " + sLogStr); + return; + } + + adapter_logger.warn("SNAAdapterManager:stopAdapter> Strart To Stop Adapter, " + sLogStr); + snaAdapter.stopAdapter(); + + /* + adapter_logger.warn("SNAAdapterManager:stopAdapter> Try To Delete Adapter From Adapter Map, " + sLogStr); + deleteSnaAdapter(adapterGroupName); + */ + + adapter_logger.warn("SNAAdapterManager:stopAdapter> Success To Stop Adapter, " + sLogStr); + } + + /** + * 1. 기능 : 어댑터 그룹, LU 그룹에 해당하는 WCA 세션 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * @param sNodeName LU 그룹 노드 이름 + * @param sGroupCode LU 그룹 이름 + **/ + public WCASession getWCASession(String adapterGroupName, String nodeName, String lugrpName) throws WCAException { + // 어댑터 그룹에 해당하는 어댑터 오브젝트를 구함 + SNAAdapter snaAdapter = selectSnaAdapter(adapterGroupName); + if (snaAdapter == null) { + adapter_logger.warn("SNAAdapterManager:getWCASession> There is No Adapter, sAdapterGrpName = [" + adapterGroupName + "]"); + throw new WCAException(WCAException.E_ADAPTERGROUP_NO_EXIST); + } + + // LU 그룹 노드 정보와 LU 그룹명이 두가지 다 있거나, 두가지 다 없어나 해야 한다. + if (nodeName.equals("") || lugrpName.equals("")) { + return snaAdapter.getWCASessionInSessionPoolList(); + } + else { + return snaAdapter.getWCASessionInSessionPoolList(nodeName, lugrpName); + } + } + + /** + * 1. 기능 : BACKUP POOL 수동 전환 모드 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * @param sNodeName LU 그룹 노드 이름 + * @param sGroupCode LU 그룹 이름 + * @param flag 백업 여부 (true : 백업, false : 정상) + **/ + public void setManualBackupMode(String sAdapterGroupName, String sNodeName, String sGroupCode, boolean flag) throws WCAException { + adapter_logger.warn("SNAAdapterManager:setManualBackupMode> [" + sAdapterGroupName + "][" + sNodeName + "][" + sGroupCode + "][" + flag + "]"); + + SNAAdapter sAdapter = (SNAAdapter)adapterMap.get(sAdapterGroupName); + if (sAdapter == null) { + adapter_logger.warn("SNAAdapterManager:setManualBackupMode> There is No Adapter, sAdapterGrpName = [" + sAdapterGroupName + "]"); + throw new WCAException(WCAException.E_SOFTLINK_NOT_FOUND_SESSION, "수동 백업/복구 모드 전환시 발생 [" +sAdapterGroupName+"]"); + } + + sAdapter.setManualBackupMode(sNodeName, sGroupCode, flag); + } + + + /** + * 1. 기능 : 어댑터 그룹에 속한 LU 그룹과 현재 설정된 백업 모드 정보 반환 + * 2. 처리 개요 : 모니터링에서 사용하기 위한 함수임 + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * + * @return LU 그룹 및 백업 모드 정보 [ + * Key : LU 그룹 이름, value : Boolean Object 백업 모드 정보 (true : 백업, false : 정상) + **/ + public HashMap getLuGrpBackupModeMap(String adapterGroupName) throws WCAException { + SNAAdapter snaAdapter = selectSnaAdapter(adapterGroupName); + if (snaAdapter == null) { + adapter_logger.warn("SNAAdapterManager:getLuGrpBackupModeMap> There is No Adapter, sAdapterGrpName = [" + adapterGroupName + "]"); + return new HashMap(); + } + + return snaAdapter.getLuGrpBackupModeMap(); + } + + + /** + * 1. 기능 : 모니터링으로부터 새로운 LU 그룹이 추가되었다는 Command를 처리 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data LU 그룹 정보 오브젝트 + **/ + public void insertLuGroupInfoEx(SessionGroupDataEx lugrpInfo) throws WCAException { + SNAAdapter snaAdapter = selectSnaAdapter(lugrpInfo.getAdapterGroupName()); + + // adapter db에 정의되지 않았을 경우 + if (snaAdapter == null) { + adapter_logger.warn("SNAAdapterManager:insertLuGroupInfoEx> " + lugrpInfo.getAdapterGroupName() +"이 구동되지 않았습니다."); + return; + } + + snaAdapter.insertLuGroupInfoEx(lugrpInfo); + + return; + } + + /** + * 1. 기능 : 모니터링으로부터 새로운 LU 그룹이 추가되었다는 Command를 처리 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data LU 그룹 정보 오브젝트 + **/ + public void deleteLuGroupInfoEx(SessionGroupDataEx lugrpInfo) throws WCAException { + SNAAdapter snaAdapter = selectSnaAdapter(lugrpInfo.getAdapterGroupName()); + + // adapter db에 정의되지 않았을 경우 + if (snaAdapter == null) { + adapter_logger.warn("SNAAdapterManager:deleteLuGroupInfoEx> " + lugrpInfo.getAdapterGroupName() +"이 구동되지 않았습니다."); + return; + } + + snaAdapter.deleteLuGroupInfoEx(lugrpInfo); + + return; + } + + /** + * 1. 기능 : 모니터링으로부터 LU 그룹 정보가 갱신되었다는 Command를 처리 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data LU 그룹 정보 오브젝트 + **/ + public void updateLuGroupInfoEx(SessionGroupDataEx lugrpInfo) throws WCAException { + SNAAdapter snaAdapter = selectSnaAdapter(lugrpInfo.getAdapterGroupName()); + + // adapter db에 정의되지 않았을 경우 + if (snaAdapter == null) { + adapter_logger.warn("SNAAdapterManager:updateLuGroupInfoEx> " + lugrpInfo.getAdapterGroupName() +"이 구동되지 않았습니다."); + return; + } + + snaAdapter.updateLuGroupInfoEx(lugrpInfo); + + return; + } + + /** + * 1. 기능 : 모니터링으로부터 WCA AppCode 정보가 갱신되었다는 Command를 처리 (updateWcaInfo 함수를 참조하여 개발) + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param wcaInfo WcaInfoDataEx 오브젝트 + **/ + public void updateWcaAppCodeEx(WcaInfoDataEx wcaInfo) throws WCAException { + adapter_logger.warn("SNAAdapterManager:updateWcaAppCodeEx> sEaiNodeName = [" + wcaInfo.sEaiNodeName + "], sEaiInstanceName = [" + wcaInfo.sEaiInstanceName + "]"); + adapter_logger.warn("SNAAdapterManager:updateWcaAppCodeEx> sAdapterGroupName = [" + wcaInfo.sAdapterGroupName + "], sAdapterName = [" + wcaInfo.sAdapterName + "]"); + + SNAAdapter snaAdapter = selectSnaAdapter(wcaInfo.sAdapterGroupName); + + // adapter가 db에 정의되지 않았을 경우 + if (snaAdapter == null) { + adapter_logger.warn("SNAAdapterManager:updateWcaAppCodeEx> " + wcaInfo.sAdapterGroupName +"이 구동되지 않았습니다."); + return; + } + + if (snaAdapter.adapterName.equals(wcaInfo.sAdapterName) == false) { + adapter_logger.warn("SNAAdapterManager:updateWcaAppCodeEx> Adapter Name is not same, snaAdapter.adapterName = [" + snaAdapter.adapterName + "]"); + return; + } + + try { + snaAdapter.updateWcaAppCodeEx(wcaInfo); + } + catch (Exception e) { + adapter_logger.warn("SNAAdapterManager:updateWcaAppCodeEx> [" + wcaInfo.sAdapterGroupName + "] Exception Msg = " + e.getMessage()); + } + + return; + } + + /** + * 1. 기능 : 모니터링으로부터 WCA 정보가 갱신되었다는 Command를 처리 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data WCA 정보 오브젝트 + **/ + public void updateWcaInfo(WcaInfoDataEx wcaInfo) { + SNAAdapter snaAdapter = selectSnaAdapter(wcaInfo.sAdapterGroupName); + + // adapter db에 정의되지 않았을 경우 + if (snaAdapter == null) { + adapter_logger.warn("SNAAdapterManager:updateWcaInfo> " + wcaInfo.sAdapterGroupName +"이 구동되지 않았습니다."); + return; + } + + if (wcaInfo.sAdapterName.equals(snaAdapter.adapterName) == false) { + adapter_logger.warn("SNAAdapterManager:updateWcaAppCodeEx> " + wcaInfo.sAdapterGroupName +"이 구동되지 않았습니다."); + return; + } + + try { + snaAdapter.updateWcaInfo(); + } + catch (Exception e) { + adapter_logger.warn("SNAAdapterManager:updateWcaInfo> [" + wcaInfo.sAdapterGroupName + "] Exception Msg = " + e.getMessage()); + } + + return; + } + + /** + * 1. 기능 : 어댑터 그룹에 속한 전체 LU 그룹 갯수를 구함. + * 2. 처리 개요 : 어댑터로 데이터를 송신할때, WCA 세션을 찾을때 사용함 + * 3. 주의사항 + * + * @param adapterGroupName 어댑터 그룹 이름 + * + * @return 어댑터 그룹에 속한 전체 LU 그룹 갯수 + **/ + public int getLuGroupMapCount(String adapterGroupName) { + SNAAdapter snaAdapter = selectSnaAdapter(adapterGroupName); + + // adapter db에 정의되지 않았을 경우 + if (snaAdapter == null) { + adapter_logger.warn("SNAAdapterManager:getLuGroupMapCount> " + adapterGroupName +"이 구동되지 않았습니다."); + return 0; + } + + return snaAdapter.getLuGroupMapCount(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/SessionGroupDataEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/SessionGroupDataEx.java new file mode 100644 index 0000000..baf89c2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/SessionGroupDataEx.java @@ -0,0 +1,723 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.util.MyLog; + +import java.io.Serializable; + +/** +* 1. 기능 : LU 그룹 정보 Object 클래스 +* 2. 처리 개요 : LU 그룹 정보를 Get/Set 한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : Serializable +* @since : +*/ +public class SessionGroupDataEx implements Serializable +{ + /** + * 노드 정보 (SNA 어댑터가 구동하는 서버 이름) + */ + private String node_name; + /** + * EAI 어댑터 그룹 이름 + */ + private String adpter_group_name; + /** + * LU 그룹 이름 + */ + private String group_name; + /** + * 소프트링크 접속 TCP 포트 번호 + */ + private int port; + /** + * WCA와 맺을 소켓 세션 수 + */ + private int sess_cnt; + /** + * 트랜잭션 타임아웃 (단위:초) + */ + private int tran_timeout; + + /** + * DUMMY 메시지 구분 위치 + */ + private int dummy_offset; + /** + * 호스트 송신 RU 크기 + */ + private int host_snd_ru_size; + /** + * 호스트 수신 RU 크기 + */ + private int host_rcv_ru_size; + /** + * LU 그룹 세션 Application id + */ + private String applyID; + + /** + * 백업 자동 전환 모드 ‘1’ - 자동, ‘0’ - 수동 + */ + private String backup_cvs_mode; + /** + * 장애 발생 시 Fail-Over할 서버 이름 + */ + private String backup_node_name; + /** + * 백업 소프트링크 접속 TCP 포트 번호 + */ + private int backup_port; + + /** + * 백업 전환 기준 장애율 + */ + private int backup_cvs_val; + + /** + * Log On/Off 설정 (‘1’/’0’) + */ + private String log_yn; + + /** + * 로그 레벨 (int) + */ + private int log_level; + + /** + * 로그 레벨 (‘DEBUG’,’INFO’, ‘WARN’,’ERROR’,’FATAL’) + */ + private String string_log_level; + + /** + * 로그 사이즈 (단위 : M) + */ + private int log_size; + + // 20090810 + private boolean bBackupEnableFlag = true; + + public boolean getBackupEnableFlag() { + return bBackupEnableFlag; + } + + public void setBackupEnableFlag(boolean bBackupEnableFlag) { + this.bBackupEnableFlag = bBackupEnableFlag; + return; + } + // 20090810 End + + // 20080527 Start + /** + * SoftLink Server IP Address + */ + private String softLinkSevrName; + // 20080527 End + + // 20090227 Start ("1"/"0") + private String update_lu_applyID = "0"; + + /** + * 1. 기능 : LU Application ID 변경 여부 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sApplyID Application ID + **/ + public void setUpdateLuApplyID(String sUpdateLuApplyID) { + if (sUpdateLuApplyID == null) { sUpdateLuApplyID = "0"; } + this.update_lu_applyID = sUpdateLuApplyID.trim(); + } + + /** + * 1. 기능 : LU Application ID 변경 여부 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Update LU Application ID 여부 + **/ + public String getUpdateLuApplyID() { + return this.update_lu_applyID; + } + // 20090227 End + + // 20090228 Start ("1"/"0") + private String start_backup_session = "0"; + + /** + * 1. 기능 : LU Application ID 변경 여부 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sApplyID Application ID + **/ + public void setStartBackupSession(String sStartBackupSession) { + if (sStartBackupSession == null) { start_backup_session = "0"; } + this.start_backup_session = sStartBackupSession.trim(); + } + + /** + * 1. 기능 : LU Application ID 변경 여부 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Update LU Application ID 여부 + **/ + public String getStartBackupSession() { + return this.start_backup_session; + } + // 20090227 End + /** + * 1. 기능 : Defualt Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public SessionGroupDataEx() { + } + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param node_name 노드이름 + * @param adpter_group_name 어댑터 그룹 이름 + **/ + public SessionGroupDataEx(String node_name, String adpter_group_name) { + this.node_name = node_name; + this.adpter_group_name = adpter_group_name; + } + + /** + * 1. 기능 : 노드 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sNodName 노드이름 + **/ + public void setNodeName(String s_node_name) { + if (s_node_name == null) { s_node_name = ""; } + this.node_name = s_node_name.trim(); + } + + /** + * 1. 기능 : 노드 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 노드이름 + **/ + public String getNodeName() { + return this.node_name; + } + + /** + * 1. 기능 : 어댑터 그룹 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sAdapterGroupName 어댑터 그룹 이름 + **/ + public void setAdapterGroupName(String s_adpter_group_name) { + if (s_adpter_group_name == null) { s_adpter_group_name = ""; } + this.adpter_group_name = s_adpter_group_name.trim(); + } + + /** + * 1. 기능 : 어댑터 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 어댑터 그룹 이름 + **/ + public String getAdapterGroupName() { + return this.adpter_group_name; + } + + /** + * 1. 기능 : LU 그룹 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sGroupName LU 그룹 이름 + **/ + public void setGroupName(String s_group_name) { + if (s_group_name == null) { s_group_name = ""; } + this.group_name = s_group_name.trim(); + } + + /** + * 1. 기능 : LU 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 그룹 이름 + **/ + public String getGroupName() { + return this.group_name; + } + + /** + * 1. 기능 : 포트 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sPort 포트 (default : 0) + **/ + public void setPort(String sPort) { + if (sPort == null) { sPort ="0"; } + if (sPort != null && sPort.equals("")) { sPort ="0"; } + this.port = Integer.parseInt(sPort.trim()); + } + + /** + * 1. 기능 : 포트 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 포트 + **/ + public int getPort() { + return this.port; + } + + /** + * 1. 기능 : WCA 세션 수 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sSessCnt WCA 세션 수 (default : 0) + **/ + public void setSessionCnt(String sSessCnt) { + if (sSessCnt == null) { sSessCnt ="0"; } + if (sSessCnt != null && sSessCnt.equals("")) { sSessCnt ="0"; } + this.sess_cnt = Integer.parseInt(sSessCnt.trim()); + } + + /** + * 1. 기능 : WCA 세션 수 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return WCA 세션 수 + **/ + public int getSessionCnt() { + return this.sess_cnt; + } + + /** + * 1. 기능 : DUMMY 메시지 구분 위치 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sOffset DUMMY 메시지 구분 위치 (default : 0) + **/ + public void setDummyOffset(String sOffset) { + if (sOffset == null) { sOffset ="0"; } + if (sOffset != null && sOffset.equals("")) { sOffset ="0"; } + this.dummy_offset = Integer.parseInt(sOffset.trim()); + } + + /** + * 1. 기능 : DUMMY 메시지 구분 위치 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return DUMMY 메시지 구분 위치 + **/ + public int getDummyOffset() { + return this.dummy_offset; + } + /** + * 1. 기능 : 호스트 송신 RU 크기 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sRUSize 호스트 송신 RU 크기 (default : 0) + **/ + public void setHostSndRUSize(String sRUSize) { + if (sRUSize == null) { sRUSize ="0"; } + if (sRUSize != null && sRUSize.equals("")) { sRUSize ="0"; } + this.host_snd_ru_size = Integer.parseInt(sRUSize.trim()); + } + + /** + * 1. 기능 : 호스트 송신 RU 크기 설정 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 호스트 송신 RU 크기 설정 + **/ + public int getHostSndRUSize() { + return this.host_snd_ru_size; + } + + /** + * 1. 기능 : 호스트 수신 RU 크기 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sRUSize 호스트 수신 RU 크기 (default : 0) + **/ + public void setHostRcvRUSize(String sRUSize) { + if (sRUSize == null) { sRUSize ="0"; } + if (sRUSize != null && sRUSize.equals("")) { sRUSize ="0"; } + this.host_rcv_ru_size = Integer.parseInt(sRUSize.trim()); + } + + /** + * 1. 기능 : 호스트 수신 RU 크기 설정 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 호스트 수신 RU 크기 설정 + **/ + public int getHostRcvRUSize() { + return this.host_rcv_ru_size; + } + + /** + * 1. 기능 : Application ID 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sApplyID Application ID + **/ + public void setApplyID(String sApplyID) { + if (sApplyID == null) { sApplyID = ""; } + this.applyID = sApplyID.trim(); + } + + /** + * 1. 기능 : Application ID 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Application ID + **/ + public String getApplyID() { + return this.applyID; + } + + /** + * 1. 기능 : 백업 자동 전환 모드 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param s_mode 백업 자동 전환 모드 (default : N) + **/ + public void setBackupCvsMode(String s_mode) { + if (s_mode == null) { s_mode = WCADefine.DEFAULT_MANUAL_BACKUP_CVS_MODE; } + if (s_mode != null && s_mode.equals("")) { s_mode = WCADefine.DEFAULT_MANUAL_BACKUP_CVS_MODE; } + this.backup_cvs_mode = s_mode.trim(); + } + + /** + * 1. 기능 : 백업 자동 전환 모드 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return BUSY 백업 자동 전환 모드 + **/ + public String getBackupCvsMode() { + return this.backup_cvs_mode; + } + + /** + * 1. 기능 : 백업 서버 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param s_node_name 백업 서버 이름 + **/ + public void setBackupNodeName(String s_node_name) { + if (s_node_name == null) { s_node_name = ""; } + this.backup_node_name = s_node_name; + } + + /** + * 1. 기능 : 백업 서버 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 서버 이름 + **/ + public String getBackupNodeName() { + return this.backup_node_name; + } + + // 20080527 Start + /** + * 1. 기능 : SoftLink Server 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param s_softlink_sevr_name SoftLink Server 이름 + **/ + public void setSoftLinkSevrName(String s_softlink_sevr_name) { + if (s_softlink_sevr_name == null) { softLinkSevrName = "127.0.0.1"; } + this.softLinkSevrName = s_softlink_sevr_name; + } + + /** + * 1. 기능 : SoftLink Server 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return SoftLink Server 이름 + **/ + public String getSoftLinkSevrName() { + return this.softLinkSevrName; + } + // 20080527 End + + /** + * 1. 기능 : 백업 서버 포트 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sPort 백업 서버 포트 + **/ + public void setBackupPort(String sPort) { + if (sPort == null) { sPort ="0"; } + if (sPort != null && sPort.equals("")) { sPort ="0"; } + this.backup_port = Integer.parseInt(sPort.trim()); + } + + /** + * 1. 기능 : 백업 서버 포트 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 서버 포트 + **/ + public int getBackupPort() { + return this.backup_port; + } + + /** + * 1. 기능 : 백업 전환 기준 장애율 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param s_backup_val 백업 전환 기준 장애율 + **/ + public void setBackupCvsVal(String s_backup_val) { + if (s_backup_val == null) { s_backup_val ="0"; } + if (s_backup_val != null && s_backup_val.equals("")) { s_backup_val ="0"; } + this.backup_cvs_val = Integer.parseInt(s_backup_val.trim()); + } + + /** + * 1. 기능 : 백업 전환 기준 장애율 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 전환 기준 장애율 반환 + **/ + public int getBackupCvsVal() { + return this.backup_cvs_val; + } + + /** + * 1. 기능 : 로그 기록 여부 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sLogYN 로그 기록 여부 + **/ + public void setLogYN(String s_log_yn) { + if (s_log_yn == null) { s_log_yn = WCADefine.DEFAULT_WCA_LOG; } + log_yn = s_log_yn; + } + + /** + * 1. 기능 : 로그 기록 여부 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 로그 기록 여부 (Y/N) + **/ + public String getLogYN() { + return this.log_yn; + } + + /** + * 1. 기능 : 로그 기록 여부 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 로그 기록 여부(true/false) + **/ + public boolean isLogWritable() { + if (log_yn.equalsIgnoreCase(WCADefine.WCA_LOG_YES)) { return true; } + return false; + } + + /** + * 1. 기능 : 로그 레벨 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sLogLevel 로그 레벨 + **/ + public void setLogLevel(String s_log_level) { + try { + if (s_log_level == null) { log_level = WCADefine.DEFAULT_WCA_LOG_LEVEL; } + + if (s_log_level.equalsIgnoreCase("DEBUG")) { + log_level = MyLog.DEBUG; + string_log_level = "DEBUG"; + } + else if (s_log_level.equalsIgnoreCase("INFO")) { + log_level = MyLog.INFO; + string_log_level = "INFO"; + } + else if (s_log_level.equalsIgnoreCase("NOTICE")) { + log_level = MyLog.NOTICE; + string_log_level = "NOTICE"; + } + else if (s_log_level.equalsIgnoreCase("WARN")) { + log_level = MyLog.WARN; + string_log_level = "WARN"; + } + else if (s_log_level.equalsIgnoreCase("ERROR")) { + log_level = MyLog.ERROR; + string_log_level = "ERROR"; + } + else if (s_log_level.equalsIgnoreCase("ALERT")) { + log_level = MyLog.ALERT; + string_log_level = "ALERT"; + } + else if (s_log_level.equalsIgnoreCase("EMERGENCY")) { + log_level = MyLog.EMERGENCY; + string_log_level = "EMERGENCY"; + } + else { + log_level = WCADefine.DEFAULT_WCA_LOG_LEVEL; + string_log_level = WCADefine.DEFAULT_WCA_STRING_LOG_LEVEL; + } + } + catch (Exception e) { + log_level = WCADefine.DEFAULT_WCA_LOG_LEVEL; + } + } + + /** + * 1. 기능 : 로그 레벨 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return integer type 로그 레벨 + **/ + public int getLogLevel() { + return this.log_level; + } + + /** + * 1. 기능 : 로그 레벨 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return String type 로그 레벨 + **/ + public String getStringLogLevel() { + return this.string_log_level; + } + + /** + * 1. 기능 : 로그 사이즈 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sLogLevel 로그 레벨사이즈 + **/ + public void setLogSize(String s_log_size) { + try { + if (s_log_size == null) { s_log_size = String.valueOf(WCADefine.DEFAULT_WCA_LOG_SIZE); } + if (s_log_size != null && s_log_size.equals("")) { s_log_size = String.valueOf(WCADefine.DEFAULT_WCA_LOG_SIZE); } + this.log_size = Integer.parseInt(s_log_size.trim()); + } + catch (Exception e) { + this.log_size = WCADefine.DEFAULT_WCA_LOG_SIZE; + } + } + + /** + * 1. 기능 : 로그 사이즈 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 로그 사이즈 + **/ + public int getLogSize() { + return this.log_size; + } + + /** + * 1. 기능 : 트랜잭션 타임아웃 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param s_timeout 트랜잭션 타임아웃 + **/ + public void setTranTimeout(String s_timeout) { + if (s_timeout == null) { s_timeout = String.valueOf(WCADefine.DEFAULT_TRANSACTION_TIMEOUT); } + if (s_timeout != null && s_timeout.equals("")) { s_timeout = String.valueOf(WCADefine.DEFAULT_TRANSACTION_TIMEOUT); } + this.tran_timeout = Integer.parseInt(s_timeout.trim()); + } + + /** + * 1. 기능 : 트랜잭션 타임아웃 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 트랜잭션 타임아웃 + **/ + public int getTranTimeout() { + return this.tran_timeout; + } + + + + /** + * 1. 기능 : LU 그룹 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 정보 + **/ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("SessionGroupData[ 노드 =").append(node_name); + sb.append(", 어댑터 그룹 이름 =").append(adpter_group_name); + sb.append(", LU 그룹 이름 =").append(group_name); + sb.append(", IP =").append(softLinkSevrName); + sb.append(", \nPort =").append(port); + sb.append(", WCA 세션 수 =").append(sess_cnt); + // 20090228 Start + sb.append(", 백업 세션 시작 =").append(start_backup_session); + // 20090228 End + // 20090810 Start + sb.append(", 백업 동작 여부 =").append(bBackupEnableFlag); + // 20090810 End + sb.append(", 트랜잭션 타임아웃 =").append(tran_timeout); + sb.append(", DUMMY 메시지 구분 위치 =").append(dummy_offset); + sb.append(", 호스트 송신 RU 크기 =").append(host_snd_ru_size); + sb.append(", 호스트 수신 RU 크기 =").append(host_rcv_ru_size); + sb.append(", Apply id =").append(applyID); + sb.append(", \n백업 자동 전환 모드 =").append(backup_cvs_mode); + sb.append(", 백업 서버 =").append(backup_node_name); + sb.append(", 백업 Port =").append(backup_port); + sb.append(", 백업 전환 기준 장애율 =").append(backup_cvs_val); + sb.append(", \n로깅 여부 =").append(log_yn); + sb.append(", 로그 레벨 =").append(log_level); + sb.append(", 로그 사이즈 =").append(log_size); + sb.append(" ]"); + + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/SessionGroupJDBCEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/SessionGroupJDBCEx.java new file mode 100644 index 0000000..b59eef5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/SessionGroupJDBCEx.java @@ -0,0 +1,477 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.jdbc.BaseJDBC; +import com.eactive.eai.adapter.wca.jdbc.JDBCException; +import com.eactive.eai.adapter.wca.util.DateUtil; +import com.eactive.eai.common.util.Logger; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.HashMap; + +/** +* 1. 기능 : LU 그룹 정보 테이블을 접근하기 위한 JDBC 클래스 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : SessionGroupQuery.java +* @since : +*/ +public class SessionGroupJDBCEx extends BaseJDBC implements SessionGroupQueryEx +{ + /** + * SNAAdapter 트레이스 로깅을 위한 logger + */ + Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + // 20080827 Start + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + // 20080827 End + + // 20080827 Start + /** + * 1. 기능 : Softlink IP 주소에 해당하는 노드 이름을 구한다. + * 2. 처리 개요 + * 3. 주의사항 + * + * @params softlinkIpAddr Softlink IP 주소 + * + * @return Softlink 노드 이름 + * + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public String getSoftlinkNodeName(String softlinkIpAddr) throws JDBCException { + ResultSet rs = null; + String softlinkNodeName = ""; + + try { + getDsConnection(); + + if(adapter_logger.isInfo()) + adapter_logger.info("getSoftlinkNodeName> Query = " + GET_SOFTLINK_NODE_NAME); + + setStatement(GET_SOFTLINK_NODE_NAME); + + this.preparedStatement.setString(1, softlinkIpAddr); + + rs = executeSelect(); + + while (rs.next()) { + softlinkNodeName = rs.getString(1); + adapter_logger.info("getSoftlinkNodeName> softlinkNodeName = " + softlinkNodeName); + } + + return softlinkNodeName; + + } + catch (Exception e) { + if(adapter_logger.isError()) { + adapter_logger.error("getSoftlinkNodeName> Exception Occur, Msg", e); + } + throw new JDBCException("SessionGroupJDBC","getSoftlinkNodeName",e); + } + finally { + try { + if (rs != null) { rs.close(); } + } + catch(Exception ex) {} + this.close(); + } + } + // 20080827 End + + /** + * 1. 기능 : Softlink 노드 이름에 해당하는 시스템의 IP 주소를 구한다. + * 2. 처리 개요 + * 3. 주의사항 + * + * @params softlinkNodeName Softlink 노드 이름 + * + * @return Softlink IP 주소 + * + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public String getSoftlinkIpAddr(String softlinkNodeName) throws JDBCException { + ResultSet rs = null; + String softlinkIpAddr = ""; + + try { + getDsConnection(); + + if (adapter_logger.isInfo()) { + adapter_logger.info("getSoftlinkIpAddr> Query = " + GET_SOFTLINK_IP_ADDR); + } + + setStatement(GET_SOFTLINK_IP_ADDR); + + this.preparedStatement.setString(1, softlinkNodeName); + + rs = executeSelect(); + + while (rs.next()) { + softlinkIpAddr = rs.getString(1); + adapter_logger.info("getSoftlinkNodeName> softlinkNodeName = " + softlinkNodeName); + } + + return softlinkIpAddr; + } + catch (Exception e) { + adapter_logger.error("getSoftlinkIpAddr> Exception Occur, Msg", e); + throw new JDBCException("SessionGroupJDBC", "getSoftlinkIpAddr", e); + } + finally { + try { + if (rs != null) { + rs.close(); + } + } + catch (Exception ex) { } + this.close(); + } + } + // 20080827 End + + /** + * 1. 기능 : 노드, 어댑터 그룹 이름에 해당하는 모든 LU 그룹 정보 반환 + * 2. 처리 개요 : 검색된 LU 그룹 정보를 SessionGroupData Object 저장한다. + * 3. 주의사항 + * + * @params nodeName 노드 이름 + * @params adapterGroupName 어댑터 그룹 이름 + * @return HashMap 노드, 어댑터 그룹 이름에 해당하는 모든 LU 그룹 정보를 저장한다. + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + // 20090228 Start + // 20080827 Start + // public HashMap getAdapterInfo(String nodeName, String adapterGroupName) throws JDBCException { + // public HashMap getAdapterInfo(String nodeName, String nodeIpAddr, String adapterGroupName) throws JDBCException { + // 20080827 End + public HashMap getAdapterInfo(HashMap luGroupInfoMap, String nodeName, String nodeIpAddr, + String adapterGroupName, String sStartBackupSession, boolean bBackupSessionEnableFlag) throws JDBCException { + // 20090228 End + ResultSet rs = null; + + try { + getDsConnection(); + setStatement(GET_ADAPTER); + this.preparedStatement.setString(1, nodeName); + this.preparedStatement.setString(2, adapterGroupName); + rs = executeSelect(); + + SessionGroupDataEx info = null; + + while (rs.next()) { + info = new SessionGroupDataEx(rs.getString(1), rs.getString(2)); // 어댑터 기동 서버명 및 어댑터 그룹 이름 값 설정 + info.setGroupName(rs.getString(3)); // LU 그룹 설정 + info.setPort(rs.getString(4)); + info.setSessionCnt(rs.getString(5)); + info.setBackupCvsMode(rs.getString(6)); + info.setBackupNodeName(rs.getString(7)); + info.setBackupPort(rs.getString(8)); + info.setBackupCvsVal(rs.getString(9)); + info.setLogYN(rs.getString(10)); + info.setLogLevel(rs.getString(11)); + info.setLogSize(rs.getString(12)); + info.setTranTimeout(rs.getString(13)); + + // 20080827 Start + // info.setSoftLinkSevrName(rs.getString(14)); + info.setSoftLinkSevrName(nodeIpAddr); + // info.setSoftLinkSevrName("127.0.0.1"); // For 임시 테스트 + // 20080827 End + + // 20090228 Start + info.setStartBackupSession(sStartBackupSession); + // 20090228 End + + // 20090810 Start + info.setBackupEnableFlag(bBackupSessionEnableFlag); + // 20090810 End + + if (trc_logger.isDebug()){ + trc_logger.debug("=================================================="); + trc_logger.debug("getAdapterInfo] " + info.toString()); + trc_logger.debug("=================================================="); + } + + // 2008.09.09 Start + if (adapter_logger.isWarn()) { + adapter_logger.warn("getAdapterInfo> " + info.toString()); + adapter_logger.warn("getAdapterInfo> Add Session Info To " + info.getGroupName()); + } + // 2008.09.09 End + + // 20090810 Start + // LU 그룹 값을 키로 하여 LU 그룹 세션 정보 저장 + // sessgroups.put(info.getGroupName(), info); + luGroupInfoMap.put(info.getGroupName(), info); + // 20090810 End + } + + return luGroupInfoMap; + + } + catch (Exception e) { + adapter_logger.error("getAdapterInfo error", e); + throw new JDBCException("SessionGroupJDBC","getAdapterInfo",e); + } + finally { + try { + if (rs != null) { + rs.close(); + } + } + catch (Exception ex) { } + this.close(); + } + } + + + /** + * 1. 기능 : LU 그룹 정보 등록 및 해당하는 LU 정보 수정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data SessionGroupData Object + * @return 추가된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int insertSessionGroup(SessionGroupDataEx data) throws JDBCException { + int nExeCnt = 0; + try { + DateUtil dateUtil = new DateUtil(); + String sDateTime = dateUtil.getDateMilliTime(); + getDsConnection(); + setAutoCommit(false); + setStatement(INSERT_SESSION_GROUP); + this.preparedStatement.setString(1,data.getNodeName()); + this.preparedStatement.setString(2,data.getAdapterGroupName()); + this.preparedStatement.setString(3,data.getGroupName()); + this.preparedStatement.setInt(4,data.getPort()); + this.preparedStatement.setInt(5,data.getSessionCnt()); + this.preparedStatement.setInt(6,data.getTranTimeout()); + this.preparedStatement.setInt(7,data.getDummyOffset()); + this.preparedStatement.setInt(8,data.getHostSndRUSize()); + this.preparedStatement.setInt(9,data.getHostRcvRUSize()); + this.preparedStatement.setString(10,data.getApplyID()); + + this.preparedStatement.setString(11,data.getBackupCvsMode()); + this.preparedStatement.setInt(12,data.getBackupCvsVal()); + this.preparedStatement.setString(13,data.getBackupNodeName()); + this.preparedStatement.setInt(14,data.getBackupPort()); + + this.preparedStatement.setString(15,data.getLogYN()); + this.preparedStatement.setString(16,data.getStringLogLevel()); + this.preparedStatement.setInt(17,data.getLogSize()); + + this.preparedStatement.setString(18, sDateTime); + this.preparedStatement.setString(19, sDateTime); + + // 20080827 Start + // 20080527 Start + // this.preparedStatement.setString(20, data.getSoftLinkSevrName()); + // 20080527 End + // 20080827 End + + nExeCnt =executeUpdate(); + + setStatement(UPDATE_LU_INFO); + this.preparedStatement.setString(1,data.getApplyID()); + this.preparedStatement.setString(2,data.getLogYN()); + this.preparedStatement.setString(3,data.getStringLogLevel()); + this.preparedStatement.setInt(4,data.getLogSize()); + this.preparedStatement.setString(5,sDateTime); + this.preparedStatement.setString(6,data.getNodeName()); + this.preparedStatement.setString(7,data.getAdapterGroupName()); + this.preparedStatement.setString(8,data.getGroupName()); + nExeCnt += executeUpdate(); + commit(); + return nExeCnt; + } + catch (SQLException e) { + throw new JDBCException("SessionGroupJDBC","insertSessionGroup",e); + } + finally { + this.close(); + } + } + + /** + * 1. 기능 : LU 그룹 정보 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data SessionGroupData Object + * @return 삭제된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int deleteSessionGroup(SessionGroupDataEx vo) throws JDBCException { + int nExeCnt = 0; + try { + getDsConnection(); + setStatement(DELETE_SESSION_GROUP); + this.preparedStatement.setString(1,vo.getNodeName()); + this.preparedStatement.setString(2,vo.getAdapterGroupName()); + this.preparedStatement.setString(3,vo.getGroupName()); + nExeCnt = executeUpdate(); + return nExeCnt; + } + catch (SQLException e) { + throw new JDBCException("SessionGroupJDBC","deleteSessionGroup",e); + } + finally { + this.close(); + } + } + + /** + * 1. 기능 : LU 그룹 정보와 LU 그룹에 해당하느 LU 정보 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data SessionGroupData Object + * @return 삭제된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int deleteAllSessionGroup(SessionGroupDataEx vo) throws JDBCException { + int nExeCnt = 0; + try { + getDsConnection(); + setAutoCommit(false); + + setStatement(DELETE_SESSION_GROUP); + this.preparedStatement.setString(1,vo.getNodeName()); + this.preparedStatement.setString(2,vo.getAdapterGroupName()); + this.preparedStatement.setString(3,vo.getGroupName()); + nExeCnt = executeUpdate(); + + setStatement(DELETE_ALL_LU_INFO); + this.preparedStatement.setString(1,vo.getNodeName()); + this.preparedStatement.setString(2,vo.getAdapterGroupName()); + this.preparedStatement.setString(3,vo.getGroupName()); + nExeCnt += executeUpdate(); + + commit(); + return nExeCnt; + } + catch (SQLException e) { + throw new JDBCException("SessionGroupJDBC","deleteAllSessionGroup",e); + } + finally { + this.close(); + } + } + + /** + * 1. 기능 : LU 그룹 정보 및 해당하는 LU 정보 수정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data SessionGroupData Object + * @return 수정된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int updateSessionGroup(SessionGroupDataEx data) throws JDBCException { + int nExeCnt = 0; + try { + DateUtil dateUtil = new DateUtil(); + + getDsConnection(); + setAutoCommit(false); + // 세션 그룹 update + setStatement(UPDATE_SESSION_GROUP); + this.preparedStatement.setInt(1,data.getPort()); + this.preparedStatement.setInt(2,data.getSessionCnt()); + this.preparedStatement.setInt(3,data.getTranTimeout()); + this.preparedStatement.setInt(4,data.getDummyOffset()); + this.preparedStatement.setInt(5,data.getHostSndRUSize()); + this.preparedStatement.setInt(6,data.getHostRcvRUSize()); + this.preparedStatement.setString(7,data.getApplyID()); + + this.preparedStatement.setString(8,data.getBackupCvsMode()); + this.preparedStatement.setInt(9,data.getBackupCvsVal()); + this.preparedStatement.setString(10,data.getBackupNodeName()); + this.preparedStatement.setInt(11,data.getBackupPort()); + + this.preparedStatement.setString(12,data.getLogYN()); + this.preparedStatement.setString(13,data.getStringLogLevel()); + this.preparedStatement.setInt(14,data.getLogSize()); + + this.preparedStatement.setString(15, dateUtil.getDateMilliTime()); + + // 20080827 Start + // 20080527 Start + /* + this.preparedStatement.setString(16,data.getNodeName()); + this.preparedStatement.setString(17,data.getAdapterGroupName()); + this.preparedStatement.setString(18,data.getGroupName()); + */ + /* + this.preparedStatement.setString(16,data.getSoftLinkSevrName()); + this.preparedStatement.setString(17,data.getNodeName()); + this.preparedStatement.setString(18,data.getAdapterGroupName()); + this.preparedStatement.setString(19,data.getGroupName()); + */ + // 20080527 End + this.preparedStatement.setString(16,data.getNodeName()); + this.preparedStatement.setString(17,data.getAdapterGroupName()); + this.preparedStatement.setString(18,data.getGroupName()); + // 20080827 End + + nExeCnt = executeUpdate(); + + // 20090227 Start + // LU applcation id & LU 로그 update + /* + setStatement(UPDATE_LU_INFO); + this.preparedStatement.setString(1,data.getApplyID()); + this.preparedStatement.setString(2,data.getLogYN()); + this.preparedStatement.setString(3,data.getStringLogLevel()); + this.preparedStatement.setInt(4,data.getLogSize()); + this.preparedStatement.setString(5,dateUtil.getDateMilliTime()); + this.preparedStatement.setString(6,data.getNodeName()); + this.preparedStatement.setString(7,data.getAdapterGroupName()); + this.preparedStatement.setString(8,data.getGroupName()); + */ + if (data.getUpdateLuApplyID().compareTo("1") == 0) { + setStatement(UPDATE_LU_INFO); + this.preparedStatement.setString(1,data.getApplyID()); + this.preparedStatement.setString(2,data.getLogYN()); + this.preparedStatement.setString(3,data.getStringLogLevel()); + this.preparedStatement.setInt(4,data.getLogSize()); + this.preparedStatement.setString(5,dateUtil.getDateMilliTime()); + this.preparedStatement.setString(6,data.getNodeName()); + this.preparedStatement.setString(7,data.getAdapterGroupName()); + this.preparedStatement.setString(8,data.getGroupName()); + } + else { + setStatement(UPDATE_LU_INFO_EXCEPT_APPL_ID); + this.preparedStatement.setString(1,data.getLogYN()); + this.preparedStatement.setString(2,data.getStringLogLevel()); + this.preparedStatement.setInt(3,data.getLogSize()); + this.preparedStatement.setString(4,dateUtil.getDateMilliTime()); + this.preparedStatement.setString(5,data.getNodeName()); + this.preparedStatement.setString(6,data.getAdapterGroupName()); + this.preparedStatement.setString(7,data.getGroupName()); + } + // 20090227 End + nExeCnt += executeUpdate(); + commit(); + return nExeCnt; + } + catch (SQLException e) { + adapter_logger.error("updateSessionGroup error", e); + throw new JDBCException("SessionGroupJDBC","updateSessionGroup",e); + } + finally { + this.close(); + } + } +} + diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/SessionGroupQueryEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/SessionGroupQueryEx.java new file mode 100644 index 0000000..5891126 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/SessionGroupQueryEx.java @@ -0,0 +1,124 @@ +package com.eactive.eai.adapter.wca.cfg; + +import com.eactive.eai.adapter.wca.servlet.TableInfoEx; + +/** +* 1. 기능 : LU 그룹 정보 관리 SQL Query문을 정의한 인터페이스 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +*/ +public interface SessionGroupQueryEx +{ + /** + * 노드 이름에 해당하는 모든 LU 그룹 정보 SELECT QUERY + */ + /* + public static final String GET_ALL_ADAPTER = "SELECT AdptrGstatSevrName, AdptrGroupName, LUGroupName, SoftLinkPortNo, WCASessCnt, " + + " BkupAutoCnvsnYn, BkupAdptrGstatSevrName, BkupSoftLinkPortNo, BkupCnvsnBaseObstclRt, " + + " LogUseYn, LogLvelName, MaxLogFileVal, SvcToutVal " + + "FROM " + TableInfoEx.T_LU_GROUP + " where AdptrGstatSevrName=? "; + */ + + // 20080827 Start + /** + * 노드 이름, 어댑터 그룹 이름에 해당하는 모든 LU 그룹 정보 SELECT QUERY + */ + /* + public static final String GET_ADAPTER = "SELECT AdptrGstatSevrName, AdptrGroupName, LUGroupName, SoftLinkPortNo, WCASessCnt, " + + " BkupAutoCnvsnYn, BkupAdptrGstatSevrName, BkupSoftLinkPortNo, BkupCnvsnBaseObstclRt, " + + " LogUseYn, LogLvelName, MaxLogFileVal, SvcToutVal, SoftLinkSevrName " + + "FROM " + TableInfoEx.T_LU_GROUP + " where AdptrGstatSevrName=? AND AdptrGroupName=?"; + */ + public static final String GET_ADAPTER = "SELECT ADPTRGSTATSEVRNAME, ADPTRGROUPNAME, LUGROUPNAME, SOFTLINKPORTNO, WCASESSCNT, " + + " BKUPAUTOCNVSNYN, BKUPADPTRGSTATSEVRNAME, BKUPSOFTLINKPORTNO, BKUPCNVSNBASEOBSTCLRT, " + + " LOGUSEYN, LOGLVELNAME, MAXLOGFILEVAL, SVCTOUTVAL " + + "FROM " + TableInfoEx.T_LU_GROUP + " where ADPTRGSTATSEVRNAME=? AND ADPTRGROUPNAME=?"; + // 20080827 End + + // 20080827 Start + /** + * 노드 이름, 어댑터 그룹 이름에 해당하는 모든 LU 그룹 정보 SELECT QUERY + */ + public static final String GET_SOFTLINK_NODE_NAME = "SELECT SNAADPTRSEVRNAME FROM " + TableInfoEx.T_LU_HOST + " where SNAADPTRSEVRIPNAME=?"; + + public static final String GET_SOFTLINK_IP_ADDR = "SELECT SNAADPTRSEVRIPNAME FROM " + TableInfoEx.T_LU_HOST + " where SNAADPTRSEVRNAME=?"; + // 20080827 End + + // 20080827 Start + // 20080527 Start + /** + * LU 그룹 정보 INSERT QUERY + */ + /* + public static final String INSERT_SESSION_GROUP = "INSERT INTO " + TableInfoEx.T_LU_GROUP + + " (AdptrGstatSevrName, AdptrGroupName, LUGroupName, SoftLinkPortNo, WCASessCnt, " + + " SvcToutVal, DmyMsgSituVal, HostSndmsgRUVal, HostDpstRUVal, UapplIDName, " + + " BkupAutoCnvsnYn, BkupCnvsnBaseObstclRt, BkupAdptrGstatSevrName, BkupSoftLinkPortNo, " + + " LogUseYn, LogLvelName, MaxLogFileVal, "+ + " LUGroupRegiHMS, LUGroupAmndHMS, SoftLinkSevrName )" + + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + */ + public static final String INSERT_SESSION_GROUP = "INSERT INTO " + TableInfoEx.T_LU_GROUP + + " (ADPTRGSTATSEVRNAME, ADPTRGROUPNAME, LUGROUPNAME, SOFTLINKPORTNO, WCASESSCNT, " + + " SVCTOUTVAL, DMYMSGSITUVAL, HOSTSNDMSGRUVAL, HOSTDPSTRUVAL, UAPPLIDNAME, " + + " BKUPAUTOCNVSNYN, BKUPCNVSNBASEOBSTCLRT, BKUPADPTRGSTATSEVRNAME, BKUPSOFTLINKPORTNO, " + + " LOGUSEYN, LOGLVELNAME, MAXLOGFILEVAL, "+ + " LUGROUPREGIHMS, LUGROUPAMNDHMS )" + + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + // 20080527 End + // 20080827 End + + /** + * LU 그룹 정보 DELETE QUERY + */ + public static final String DELETE_SESSION_GROUP = "DELETE FROM "+ TableInfoEx.T_LU_GROUP + + " WHERE ADPTRGSTATSEVRNAME=? AND ADPTRGROUPNAME=? AND LUGROUPNAME=?"; + /** + * LU 그룹에 해당하는 모든 LU 정보 DELETE QUERY + */ + public static final String DELETE_ALL_LU_INFO = "DELETE FROM " + TableInfoEx.T_LU_INFO + + " WHERE ADPTRGSTATSEVRNAME=? AND ADPTRGROUPNAME=? AND LUGROUPNAME=? "; + // 20080827 Start + // 20080527 Start + /** + * LU 그룹 정보 UPDATE QUERY + */ + /* + public static final String UPDATE_SESSION_GROUP = "UPDATE "+ TableInfoEx.T_LU_GROUP + + " SET SoftLinkPortNo=?, WCASessCnt=?, " + + " SvcToutVal=?, DmyMsgSituVal=?, HostSndmsgRUVal=?, HostDpstRUVal=?, UapplIDName=?, " + + " BkupAutoCnvsnYn=?, BkupCnvsnBaseObstclRt=?, BkupAdptrGstatSevrName=?, BkupSoftLinkPortNo=?, " + + " LogUseYn=?, LogLvelName=?, MaxLogFileVal=?, " + + " LUGroupAmndHMS=?, SoftLinkSevrName=? " + + "WHERE AdptrGstatSevrName=? AND AdptrGroupName=? AND LUGroupName=?"; + */ + // 20080527 End + public static final String UPDATE_SESSION_GROUP = "UPDATE "+ TableInfoEx.T_LU_GROUP + + " SET SOFTLINKPORTNO=?, WCASESSCNT=?, " + + " SVCTOUTVAL=?, DMYMSGSITUVAL=?, HOSTSNDMSGRUVAL=?, HOSTDPSTRUVAL=?, UAPPLIDNAME=?, " + + " BKUPAUTOCNVSNYN=?, BKUPCNVSNBASEOBSTCLRT=?, BKUPADPTRGSTATSEVRNAME=?, BKUPSOFTLINKPORTNO=?, " + + " LOGUSEYN=?, LOGLVELNAME=?, MAXLOGFILEVAL=?, " + + " LUGROUPAMNDHMS=? " + + "WHERE ADPTRGSTATSEVRNAME=? AND ADPTRGROUPNAME=? AND LUGROUPNAME=?"; + // 20080827 End + /** + * LU 그룹에 속한 lu apply id 변경 & lu 로그 정보 + */ + public static final String UPDATE_LU_INFO = "UPDATE "+ TableInfoEx.T_LU_INFO + + " SET UAPPLIDNAME=?, LOGUSEYN=?, LOGLVELNAME=?, MAXLOGFILEVAL=?, LUAMNDHMS=? " + + " WHERE ADPTRGSTATSEVRNAME=? AND ADPTRGROUPNAME=? AND LUGROUPNAME=?"; + + // 20090227 Start + /** + * LU 그룹에 속한 lu 로그 정보 + */ + public static final String UPDATE_LU_INFO_EXCEPT_APPL_ID = "UPDATE "+ TableInfoEx.T_LU_INFO + + " SET LOGUSEYN=?, LOGLVELNAME=?, MAXLOGFILEVAL=?, LUAMNDHMS=? " + + " WHERE ADPTRGSTATSEVRNAME=? AND ADPTRGROUPNAME=? AND LUGROUPNAME=?"; + // 20090227 End +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/cfg/WcaInfoDataEx.java b/src/main/java/com/eactive/eai/adapter/wca/cfg/WcaInfoDataEx.java new file mode 100644 index 0000000..b0359b8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/cfg/WcaInfoDataEx.java @@ -0,0 +1,82 @@ +package com.eactive.eai.adapter.wca.cfg; + +import java.io.Serializable; + +/** +* 1. 기능 : LU 정보 Object 클래스 +* 2. 처리 개요 : LU 정보를 Get/Set 한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : Serializable +* @since : +*/ +public class WcaInfoDataEx implements Serializable +{ + /** + * EAI Framework 노드 이름 + */ + public String sEaiNodeName = ""; + + /** + * EAI Framework 인스턴스 이름 + */ + public String sEaiInstanceName = ""; + + /** + * WCA 어댑터 그룹 이름 + */ + public String sAdapterGroupName = ""; + + /** + * WCA 어댑터 이름 + */ + public String sAdapterName = ""; + + /** + * app_code + */ + public String appCd = ""; + + /** + * 1. 기능 : Defualt Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public WcaInfoDataEx(String sAdapterGroupName, String sAdapterName , String sEaiNodeName , String sEaiInstanceName , String appCd) { + if(sAdapterGroupName != null) + this.sAdapterGroupName = sAdapterGroupName.trim(); + + if(sAdapterName != null) + this.sAdapterName = sAdapterName.trim(); + + if(sEaiNodeName != null) + this.sEaiNodeName = sEaiNodeName.trim(); + + if(sEaiInstanceName != null) + this.sEaiInstanceName = sEaiInstanceName.trim(); + + if(appCd != null) + this.appCd = appCd.trim(); + } + + + /** + * 1. 기능 : LU 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 정보 + **/ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("WCA 정보 [ 어댑터 그룹 이름 =").append(sAdapterGroupName); + sb.append(", 어댑터 이름 =").append(sAdapterName); + sb.append(", 인스턴스명 =").append(sEaiInstanceName); + sb.append(", 노드명 =").append(sEaiNodeName); + sb.append(", 어플리케이션코드 =").append(appCd); + sb.append(" ]"); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/command/DBCommand.java b/src/main/java/com/eactive/eai/adapter/wca/command/DBCommand.java new file mode 100644 index 0000000..2555171 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/command/DBCommand.java @@ -0,0 +1,8 @@ +package com.eactive.eai.adapter.wca.command; + +public interface DBCommand +{ + public static final String CMD_UPDATE = "UPDATE"; + public static final String CMD_INSERT = "INSERT"; + public static final String CMD_DELETE = "DELETE"; +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/command/DeleteSessionGroupEx.java b/src/main/java/com/eactive/eai/adapter/wca/command/DeleteSessionGroupEx.java new file mode 100644 index 0000000..7b69d40 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/command/DeleteSessionGroupEx.java @@ -0,0 +1,66 @@ +package com.eactive.eai.adapter.wca.command; + +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.cfg.SessionGroupDataEx; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : EAI 서버에 실시간 LU 세션 그룹 삭제 +* 2. 처리 개요 : +* - SNAAdapterManager 클래스에 deleteSessionGroup 함수 실행 +* - softlink에 notify 해준다. +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ +public class DeleteSessionGroupEx extends Command +{ + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public DeleteSessionGroupEx() { + super("DeleteSessionGroup"); + } + + /** + * 1. 기능 : LU 세션 그룹 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception CommandException command 실행 시 발생하는 예외 상황 + **/ + public Object execute() throws CommandException + { + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + adapter_logger.warn("DeleteSessionGroupEx:execute> Start Execute Command, Command = " + this.name); + + if(!(args instanceof SessionGroupDataEx) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + adapter_logger.error("DeleteSessionGroupEx:execute> Invalid Data Type, Msg = " + msg); + throw new CommandException(msg); + } + + try { + SessionGroupDataEx data = (SessionGroupDataEx)args; + SNAAdapterManager.getInstance().deleteLuGroupInfoEx(data); + } + catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + adapter_logger.error("InsertSessionGroupEx:execute> Exception Occur, Msg = " + msg, e); +// e.printStackTrace(); + throw new CommandException(msg); + } + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/command/InsertSessionGroupEx.java b/src/main/java/com/eactive/eai/adapter/wca/command/InsertSessionGroupEx.java new file mode 100644 index 0000000..bffae54 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/command/InsertSessionGroupEx.java @@ -0,0 +1,65 @@ +package com.eactive.eai.adapter.wca.command; + +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.cfg.SessionGroupDataEx; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : EAI 서버에 실시간 LU 세션 그룹 등록 +* 2. 처리 개요 : +* - SNAAdapterManager 클래스에 insertSessionGroup 함수 실행 +* - softlink에 notify 해준다. +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ +public class InsertSessionGroupEx extends Command +{ + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public InsertSessionGroupEx() { + super("InsertSessionGroup"); + } + + /** + * 1. 기능 : LU 세션 그룹 등록 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception CommandException command 실행 시 발생하는 예외 상황 + **/ + public Object execute() throws CommandException + { + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + adapter_logger.warn("InsertSessionGroupEx:execute> Start Execute Command, Command = " + this.name); + + if(!(args instanceof SessionGroupDataEx)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + adapter_logger.error("InsertSessionGroupEx:execute> Invalid Data Type, Msg = " + msg); + throw new CommandException(msg); + } + + try { + SessionGroupDataEx data = (SessionGroupDataEx)args; + SNAAdapterManager.getInstance().insertLuGroupInfoEx(data); + } + catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + adapter_logger.error("InsertSessionGroupEx:execute> Exception Occur, Msg = " + msg, e); + throw new CommandException(msg); + } + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/command/StartSessionGroupEx.java b/src/main/java/com/eactive/eai/adapter/wca/command/StartSessionGroupEx.java new file mode 100644 index 0000000..e28c5ca --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/command/StartSessionGroupEx.java @@ -0,0 +1,65 @@ +package com.eactive.eai.adapter.wca.command; + +import com.eactive.eai.adapter.wca.cfg.SessionGroupDataEx; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : EAI 서버에 실시간 LU 세션 그룹 삭제 +* 2. 처리 개요 : +* - SNAAdapterManager 클래스에 deleteSessionGroup 함수 실행 +* - softlink에 notify 해준다. +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ +public class StartSessionGroupEx extends Command +{ + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public StartSessionGroupEx() { + super("DeleteSessionGroup"); + } + + /** + * 1. 기능 : LU 세션 그룹 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception CommandException command 실행 시 발생하는 예외 상황 + **/ + public Object execute() throws CommandException + { + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + adapter_logger.warn("DeleteSessionGroupEx:execute> Start Execute Command, Command = " + this.name); + + if(!(args instanceof SessionGroupDataEx) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + adapter_logger.error("DeleteSessionGroupEx:execute> Invalid Data Type, Msg = " + msg); + throw new CommandException(msg); + } + +// try { +// SessionGroupDataEx data = (SessionGroupDataEx)args; +// // SNAAdapterManager.getInstance().deleteLuGroupInfoEx(data); +// } +// catch (Exception e) { +// String rspErrorCode = "RECEAIMCM002"; +// String msg = makeException(rspErrorCode, e); +// adapter_logger.error("InsertSessionGroupEx:execute> Exception Occur, Msg = " + msg, e); +//// e.printStackTrace(); +// throw new CommandException(msg); +// } + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/command/StopSessionGroupEx.java b/src/main/java/com/eactive/eai/adapter/wca/command/StopSessionGroupEx.java new file mode 100644 index 0000000..aaa83d8 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/command/StopSessionGroupEx.java @@ -0,0 +1,64 @@ +package com.eactive.eai.adapter.wca.command; + +import com.eactive.eai.adapter.wca.cfg.SessionGroupDataEx; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : EAI 서버에 실시간 LU 세션 그룹 삭제 +* 2. 처리 개요 : +* - SNAAdapterManager 클래스에 deleteSessionGroup 함수 실행 +* - softlink에 notify 해준다. +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ +public class StopSessionGroupEx extends Command +{ + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public StopSessionGroupEx() { + super("DeleteSessionGroup"); + } + + /** + * 1. 기능 : LU 세션 그룹 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception CommandException command 실행 시 발생하는 예외 상황 + **/ + public Object execute() throws CommandException + { + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + adapter_logger.warn("DeleteSessionGroupEx:execute> Start Execute Command, Command = " + this.name); + + if(!(args instanceof SessionGroupDataEx) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + adapter_logger.error("DeleteSessionGroupEx:execute> Invalid Data Type, Msg = " + msg); + throw new CommandException(msg); + } + +// try { +// SessionGroupDataEx data = (SessionGroupDataEx)args; +// // SNAAdapterManager.getInstance().deleteLuGroupInfoEx(data); +// } +// catch (Exception e) { +// String rspErrorCode = "RECEAIMCM002"; +// String msg = makeException(rspErrorCode, e); +// adapter_logger.error("InsertSessionGroupEx:execute> Exception Occur, Msg = " + msg, e); +// throw new CommandException(msg); +// } + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/command/UpdateLUInfoEx.java b/src/main/java/com/eactive/eai/adapter/wca/command/UpdateLUInfoEx.java new file mode 100644 index 0000000..e4f9f6f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/command/UpdateLUInfoEx.java @@ -0,0 +1,96 @@ +package com.eactive.eai.adapter.wca.command; + +import com.eactive.eai.adapter.wca.cfg.LUInfoDataEx; +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : EAI 서버에 실시간 LU 정보 수정 +* 2. 처리 개요 : +* - SNAAdapterManager 클래스에 loadLUInfos, setLUGroupTranModes 함수 실행 +* - softlink에 notify 해준다. +* - LU별 로그 실시간 적용할 경우, softlink에 로그 정보를 notify 해준다. +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ + +public class UpdateLUInfoEx extends Command +{ + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public UpdateLUInfoEx() { + super("UpdateLUInfo"); + } + + /** + * 1. 기능 : LU 정보 수정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception CommandException command 실행 시 발생하는 예외 상황 + **/ + public Object execute() throws CommandException + { + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); +// Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + // 20080527 Start + /* + if(adapter_logger.isInfo()) adapter_logger.info(this.name + " is executed"); + */ + if(adapter_logger.isWarn()) adapter_logger.warn(this.name + " is executed"); + // 20080527 End + + if( !(args instanceof LUInfoDataEx) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if(adapter_logger.isError()) adapter_logger.error(msg); + throw new CommandException(msg); + } + + SNAAdapterManager manager = SNAAdapterManager.getInstance(); +// LUInfoDataEx lu_data = (LUInfoDataEx)args; + + // 20080827 Start + /* + if(!MyUtil.isLocalHostName(lu_data.getNodeName())) + { + if(trc_logger.isInfo()) trc_logger.info("UpdateLUInfoCommand]적용 Node명이 틀립니다. " +lu_data.getNodeName()); + return; + } + */ + // 20080827 End + + try { + // 1. 메모리 update + manager.loadLUInfos(); + + /* + if(adapter_logger.isWarn()) adapter_logger.warn(this.name + " Skip Update Commnad"); + + // 2. softlink notify + RuntimeUtil.getInstance().notifyAllSoftlink(); + */ + } + catch(Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if(adapter_logger.isError()) adapter_logger.error(msg, e); +// e.printStackTrace(); + throw new CommandException(msg); + } + return "success"; + } + +} + diff --git a/src/main/java/com/eactive/eai/adapter/wca/command/UpdateSessionGroupEx.java b/src/main/java/com/eactive/eai/adapter/wca/command/UpdateSessionGroupEx.java new file mode 100644 index 0000000..093c854 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/command/UpdateSessionGroupEx.java @@ -0,0 +1,66 @@ +package com.eactive.eai.adapter.wca.command; + +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.cfg.SessionGroupDataEx; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : EAI 서버에 실시간 LU 세션 그룹 수정 +* 2. 처리 개요 : +* - SNAAdapterManager 클래스에 updateSessionGroup 함수 실행 +* - softlink에 notify 해준다. +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ + +public class UpdateSessionGroupEx extends Command +{ + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public UpdateSessionGroupEx() { + super("UpdateSessionGroup"); + } + + /** + * 1. 기능 : LU 세션 그룹 수정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception CommandException command 실행 시 발생하는 예외 상황 + **/ + public Object execute() throws CommandException + { + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + adapter_logger.warn("UpdateSessionGroupEx:execute> Start Execute Command, Command = " + this.name); + + if( !(args instanceof SessionGroupDataEx) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + adapter_logger.error("UpdateSessionGroupEx:execute> Invalid Data Type, Msg = " + msg); + throw new CommandException(msg); + } + + try { + SessionGroupDataEx data = (SessionGroupDataEx)args; + SNAAdapterManager.getInstance().updateLuGroupInfoEx(data); + } + catch (Exception e){ + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + adapter_logger.error("InsertSessionGroupEx:execute> Exception Occur, Msg = " + msg, e); + throw new CommandException(msg); + } + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/command/UpdateWcaAppCodeEx.java b/src/main/java/com/eactive/eai/adapter/wca/command/UpdateWcaAppCodeEx.java new file mode 100644 index 0000000..849d2e0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/command/UpdateWcaAppCodeEx.java @@ -0,0 +1,66 @@ +package com.eactive.eai.adapter.wca.command; + +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.cfg.WcaInfoDataEx; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : EAI 서버에 실시간 LU 세션 그룹 수정 +* 2. 처리 개요 : +* - SNAAdapterManager 클래스에 updateWcaAppCode 함수 실행 +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ + +public class UpdateWcaAppCodeEx extends Command +{ + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public UpdateWcaAppCodeEx() { + super("UpdateWcaAppCodeEx"); + } + + /** + * 1. 기능 : LU 세션 그룹 수정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception CommandException command 실행 시 발생하는 예외 상황 + **/ + public Object execute() throws CommandException + { + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + adapter_logger.warn("UpdateWcaAppCodeEx:execute> Start Execute Command, Command = " + this.name); + + if (!(args instanceof WcaInfoDataEx)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + adapter_logger.error("UpdateWcaAppCodeEx:execute> Invalid Data Type, Msg = " + msg); + throw new CommandException(msg); + } + + try { + WcaInfoDataEx data = (WcaInfoDataEx)args; + SNAAdapterManager.getInstance().updateWcaAppCodeEx(data); + } + catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + adapter_logger.error("InsertSessionGroupEx:execute> Exception Occur, Msg = " + msg, e); + throw new CommandException(msg); + } + + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/command/UpdateWcaInfoEx.java b/src/main/java/com/eactive/eai/adapter/wca/command/UpdateWcaInfoEx.java new file mode 100644 index 0000000..bc92772 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/command/UpdateWcaInfoEx.java @@ -0,0 +1,66 @@ +package com.eactive.eai.adapter.wca.command; + +import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +import com.eactive.eai.adapter.wca.cfg.WcaInfoDataEx; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : EAI 서버에 실시간 LU 세션 그룹 삭제 +* 2. 처리 개요 : +* - SNAAdapterManager 클래스에 deleteSessionGroup 함수 실행 +* - softlink에 notify 해준다. +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ +public class UpdateWcaInfoEx extends Command +{ + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public UpdateWcaInfoEx() { + super("UpdateWcaInfo"); + } + + /** + * 1. 기능 : LU 세션 그룹 삭제 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception CommandException command 실행 시 발생하는 예외 상황 + **/ + public Object execute() throws CommandException + { + Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + adapter_logger.warn("UpdateWcaInfoEx:execute> Start Execute Command, Command = " + this.name); + + if(!(args instanceof WcaInfoDataEx) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + adapter_logger.error("UpdateWcaInfoEx:execute> Invalid Data Type, Msg = " + msg); + throw new CommandException(msg); + } + + try { + WcaInfoDataEx data = (WcaInfoDataEx)args; + SNAAdapterManager.getInstance().updateWcaInfo(data); + } + catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + adapter_logger.error("UpdateWcaInfoEx:execute> Exception Occur, Msg = " + msg, e); + + throw new CommandException(msg); + } + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/data/AppCodeCmd.java b/src/main/java/com/eactive/eai/adapter/wca/data/AppCodeCmd.java new file mode 100644 index 0000000..a4a239c --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/data/AppCodeCmd.java @@ -0,0 +1,55 @@ +package com.eactive.eai.adapter.wca.data; + +/** +* 1. 기능 : 백업 전환 / 복구 데이타 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class AppCodeCmd extends WCAHeader { + + public int nLen = 0; + + /** + * 1. 기능 : 백업 전환 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 전환 + **/ + public String toString() { + StringBuffer sbTmp = new StringBuffer(); + + sbTmp.append(getKey() + ", " + getLUName() + ", " + getMode() + ", " + getDataType()); + return sbTmp.toString(); + } + + /** + * 1. 기능 : DataCode Command 클래스 Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sDataCode 데이타 코드 + **/ + public AppCodeCmd(String sDataCode) { + this.nLen = WCA_HEADER_LEN + sDataCode.length(); + this.pHeaderBuff = new byte[nLen]; + setDataType(WCAHeader.DATA_TYPE_APP_CODE); + System.arraycopy(sDataCode.getBytes(), 0, pHeaderBuff, WCA_HEADER_LEN, sDataCode.getBytes().length); + } + + /** + * 1. 기능 : 데이타 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 데이타 + **/ + public byte[] getData() { + return pHeaderBuff; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/data/ManualBackupCmd.java b/src/main/java/com/eactive/eai/adapter/wca/data/ManualBackupCmd.java new file mode 100644 index 0000000..09af197 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/data/ManualBackupCmd.java @@ -0,0 +1,156 @@ +package com.eactive.eai.adapter.wca.data; + +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.util.MyUtil; + +/** +* 1. 기능 : 백업 전환 / 복구 데이타 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class ManualBackupCmd extends WCAHeader { + /** + * 어댑터 그룹 이름 길이 + */ + public static final int LEN_ADAPTER_GRP_NAME = 50; + + /** + * LU 그룹 이름 길이 + */ + public static final int LEN_LU_GRP_NAME = 55; + + /** + * 어댑터 그룹 이름 Offset + */ + public static final int OFFSET_ADAPTER_GRP_NAME = WCA_HEADER_LEN; + + /** + * LU 그룹 이름 Offset + */ + public static final int OFFSET_LU_GRP_NAME = OFFSET_ADAPTER_GRP_NAME + LEN_ADAPTER_GRP_NAME; + + /** + * 백업 전환 데이타 크기 + */ + public static final int BACKUP_CMD_LEN = OFFSET_LU_GRP_NAME + LEN_LU_GRP_NAME; + + /** + * 1. 기능 : 백업 전환 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 전환 + **/ + public String toString() { + StringBuffer sbTmp = new StringBuffer(); + + sbTmp.append(getKey() + ", " + getLUName() + ", " + getMode() + ", " + getDataType()); + return sbTmp.toString(); + } + + /** + * 1. 기능 : 백업 전환 Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param nLen 데이타 길이 + * @param pBuff 데이타 + **/ + public ManualBackupCmd(int nLen, byte[] pBuff) { + this.nLen = nLen; + this.pHeaderBuff = pBuff; + } + + public ManualBackupCmd() { + this.nLen = BACKUP_CMD_LEN; + this.pHeaderBuff = new byte[nLen]; + } + + /** + * 1. 기능 : 데이타 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 데이타 + **/ + public byte[] getData() { + return pHeaderBuff; + } + + /** + * 1. 기능 : 어댑터 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 어댑터 그룹 이름 + **/ + public String getAdapterGrpName() { + byte[] pBuff = new byte[LEN_ADAPTER_GRP_NAME]; + + System.arraycopy(pHeaderBuff, OFFSET_ADAPTER_GRP_NAME, pBuff, 0, LEN_ADAPTER_GRP_NAME); + + String sAdapterGrpName = new String(pBuff); + sAdapterGrpName = MyUtil.replaceString(sAdapterGrpName, String.valueOf((char)0x00), ""); + return sAdapterGrpName; + } + + /** + * 1. 기능 : 어댑터 그룹 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 어댑터 그룹 이름 + **/ + public void setAdapterGrpName(String adapterGrpName) throws WCAException { + if (adapterGrpName == null) { + throw new WCAException(WCAException.E_SEND_DATA_ERROR, "어댑터 그룹명"); + } + + // Space로 채움 + adapterGrpName = MyUtil.rightPadString(adapterGrpName, LEN_ADAPTER_GRP_NAME, " "); + + byte[] pBuff = adapterGrpName.getBytes(); + System.arraycopy(pBuff, 0, pHeaderBuff, OFFSET_ADAPTER_GRP_NAME, LEN_ADAPTER_GRP_NAME); + } + + /** + * 1. 기능 : LU 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 그룹 이름 + **/ + public String getLUGrpName() { + byte[] pBuff = new byte[LEN_LU_GRP_NAME]; + + System.arraycopy(pHeaderBuff, OFFSET_LU_GRP_NAME, pBuff, 0, LEN_LU_GRP_NAME); + + String sLUGrpName = new String(pBuff); + sLUGrpName = MyUtil.replaceString(sLUGrpName, String.valueOf((char)0x00), ""); + return sLUGrpName; + } + + /** + * 1. 기능 : LU 그룹 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param LU 그룹 이름 + **/ + public void setLUGrpName(String luGrpName) throws WCAException { + if (luGrpName == null) { + throw new WCAException(WCAException.E_SEND_DATA_ERROR, "LU 그룹명"); + } + + // Space로 채움 + luGrpName = MyUtil.rightPadString(luGrpName, LEN_LU_GRP_NAME, " "); + + byte[] pBuff = luGrpName.getBytes(); + System.arraycopy(pBuff, 0, pHeaderBuff, OFFSET_LU_GRP_NAME, LEN_LU_GRP_NAME); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/data/WCAAdapterInfoCmd.java b/src/main/java/com/eactive/eai/adapter/wca/data/WCAAdapterInfoCmd.java new file mode 100644 index 0000000..18c5664 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/data/WCAAdapterInfoCmd.java @@ -0,0 +1,55 @@ +package com.eactive.eai.adapter.wca.data; + +/** +* 1. 기능 : 백업 전환 / 복구 데이타 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class WCAAdapterInfoCmd extends WCAHeader { + + public int nLen = 0; + + /** + * 1. 기능 : 백업 전환 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 백업 전환 + **/ + public String toString() { + StringBuffer sbTmp = new StringBuffer(); + + sbTmp.append(getKey() + ", " + getLUName() + ", " + getMode() + ", " + getDataType()); + return sbTmp.toString(); + } + + /** + * 1. 기능 : DataCode Command 클래스 Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sDataCode 데이타 코드 + **/ + public WCAAdapterInfoCmd(String sAdapterInfo) { + this.nLen = WCA_HEADER_LEN + sAdapterInfo.length(); + this.pHeaderBuff = new byte[nLen]; + setDataType(WCAHeader.DATA_TYPE_WCA_ADPT_INFO); + System.arraycopy(sAdapterInfo.getBytes(), 0, pHeaderBuff, WCA_HEADER_LEN, sAdapterInfo.getBytes().length); + } + + /** + * 1. 기능 : 데이타 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 데이타 + **/ + public byte[] getData() { + return pHeaderBuff; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/data/WCAHeader.java b/src/main/java/com/eactive/eai/adapter/wca/data/WCAHeader.java new file mode 100644 index 0000000..f178c34 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/data/WCAHeader.java @@ -0,0 +1,273 @@ +package com.eactive.eai.adapter.wca.data; + +import com.eactive.eai.adapter.wca.SNAProperties; +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.util.MyUtil; + +/** +* 1. 기능 : Softlink와 데이타 송수신에 필요한 정보 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 23. 오전 11:16:42 +*/ +public class WCAHeader implements SNAProperties { + /** + * Transaction 키 길이 + */ + public static final int LEN_TRAN_KEY = 40; + + /** + * LU 이름 길이 + */ + public static final int LEN_LUNAME = 8; + + /** + * 호출 모드 (Response/Non-response) 길이 + */ + public static final int LEN_MODE = 1; + + /** + * HOST 수신 데이터의 종류 길이 + */ + public static final int LEN_DATA_TYPE = 2; + + + /** + * Transaction 키 Offset + */ + public static final int OFFSET_TRAN_KEY = 0; + + /** + * LU 이름 Offset + */ + public static final int OFFSET_LUNAME = LEN_TRAN_KEY; + + /** + * 호출 모드 (Response/Non-response) Offset + */ + public static final int OFFSET_MODE = OFFSET_LUNAME + LEN_LUNAME; + + /** + * HOST 수신 데이터의 종류 Offset + */ + public static final int OFFSET_DATA_TYPE = OFFSET_MODE + LEN_MODE; + + /** + * WCA Header 크기 + */ + public static final int WCA_HEADER_LEN = OFFSET_DATA_TYPE + LEN_DATA_TYPE; + + /** + * Tran Key가 null + */ + public static final byte[] NULL_TRANKEY = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + + /** + * LU 이름이 null + */ + public static final byte[] NULL_TSNAME = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + + /** + * 1. 기능 : Header 정보 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Header 정보 + **/ + public String toString() { + StringBuffer sbTmp = new StringBuffer(); + + sbTmp.append(getKey() + ", " + getLUName() + ", " + getMode() + ", " + getDataType()); + return sbTmp.toString(); + } + + /** + * Header 길이 + */ + int nLen = 0; + + /** + * Header 데이타 + */ + byte[] pHeaderBuff = null; + + /** + * 1. 기능 : WCA Header Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param nLen header 길이 + * @param pBuff header 데이타 + **/ + public WCAHeader(int nLen, byte[] pBuff) { + this.nLen = nLen; + this.pHeaderBuff = pBuff; + } + + /** + * 1. 기능 : WCA Header default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public WCAHeader() { + this.nLen = WCA_HEADER_LEN; + this.pHeaderBuff = new byte[WCA_HEADER_LEN]; + + for (int i = 0; i < WCA_HEADER_LEN; i++) { + pHeaderBuff[i] = (byte)0x00; + } + } + + /** + * 1. 기능 : Header 데이타 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return Header 데이타 + **/ + public byte[] getHeader() { + return pHeaderBuff; + } + + /** + * 1. 기능 : 트랜잭션 키 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 트랜잭션 키 + **/ + public String getKey() { + byte[] pBuff = new byte[LEN_TRAN_KEY]; + + System.arraycopy(pHeaderBuff, OFFSET_TRAN_KEY, pBuff, 0, LEN_TRAN_KEY); + + String sHeaderField = new String(pBuff); + return sHeaderField; + } + + /** + * 1. 기능 : 트랜잭션 키 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 트랜잭션 키 + **/ + public void setKey(String key) throws WCAException { + if (key == null) { + throw new WCAException(WCAException.E_SEND_DATA_ERROR, "Transaction Key"); + } + + // TRAN KEY Space로 채움 + key = MyUtil.rightPadString(key, LEN_TRAN_KEY, " "); + + byte[] pBuff = key.getBytes(); + System.arraycopy(pBuff, 0, pHeaderBuff, OFFSET_TRAN_KEY, LEN_TRAN_KEY); + } + + /** + * 1. 기능 : LU 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return LU 이름 + **/ + public String getLUName() { + byte[] pBuff = new byte[LEN_LUNAME]; + + System.arraycopy(pHeaderBuff, OFFSET_LUNAME, pBuff, 0, LEN_LUNAME); + + String sHeaderField = new String(pBuff); + + return sHeaderField; + } + + /** + * 1. 기능 : LU 이름 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param LU 이름 + **/ + public void setLUName(String tsname) throws WCAException { + try { + if (tsname == null) { tsname = ""; } + byte[] pBuff = tsname.getBytes(); + + int nLen = pBuff.length; + if (nLen > LEN_LUNAME) { + nLen = LEN_LUNAME; + } + System.arraycopy(pBuff, 0, pHeaderBuff, OFFSET_LUNAME, nLen); + } + catch (Exception e) { + throw new WCAException(WCAException.E_SEND_DATA_ERROR, "LU NAME"); + } + } + + /** + * 1. 기능 : 호출 모드 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 호출 모드 + **/ + public char getMode() { + return (char)pHeaderBuff[OFFSET_MODE]; + } + + /** + * 1. 기능 : 호출 모드 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 호출 모드 + **/ + public void setMode(String mode) throws WCAException { + if (mode == null) { + throw new WCAException(WCAException.E_SEND_DATA_ERROR, "호출모드"); + } + + mode = MyUtil.rightPadString(mode, LEN_MODE, " "); + byte[] pBuff = mode.getBytes(); + System.arraycopy(pBuff, 0, pHeaderBuff, OFFSET_MODE, LEN_MODE); + } + + /** + * 1. 기능 : host 수신 데이타 종류 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return host 수신 데이타 종류 + **/ + public String getDataType() { + byte[] pBuff = new byte[LEN_DATA_TYPE]; + + System.arraycopy(pHeaderBuff, OFFSET_DATA_TYPE, pBuff, 0, LEN_DATA_TYPE); + + String sHeaderField = new String(pBuff); + + return sHeaderField; + } + + /** + * 1. 기능 : host 수신 데이타 종류 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param host 수신 데이타 종류 + **/ + public void setDataType(String status) { + if (status == null) { status = ""; } + status = MyUtil.rightPadString(status, LEN_DATA_TYPE, " "); + + byte[] pBuff = status.getBytes(); + System.arraycopy(pBuff, 0, pHeaderBuff, OFFSET_DATA_TYPE, LEN_DATA_TYPE); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueue.java b/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueue.java new file mode 100644 index 0000000..d4872b0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueue.java @@ -0,0 +1,391 @@ +package com.eactive.eai.adapter.wca.data; + +import java.util.LinkedList; +import java.util.NoSuchElementException; + +/** +* 1. 기능 : EAI Outbound 송수신 데이타 Queue +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 17. 오후 3:22:03 +*/ +public class WCAQueue { + /** + * Queue에 누적된 데이터 카운트 + */ + int nAccQueueCnt = 0; + + /** + * 현재 Queue에 존재하는 데이터 카운트 + */ + int nCurrQueueCnt = 0; + + /** + * 현재 Queue 생성 시간 + */ + public long lCreateTime = 0; + + /** + * 트랜잭션 타임아웃 + */ + private long lTimeout = 0; + + /** + * 트랙잰션 default 타임아웃 + */ + private long lDefaultTimeout = 0; + + /** + * 수신 데이타 리스트 + */ + LinkedList listQueue = null; + + /** + * 송신 데이타 + */ + byte[] pSendBuff = null; + + /** + * 송신 데이타 길이 + */ + int nSendLen = 0; + + /** + * 트랜잭션 키 + */ + private String sKey = null; + + private String sGroupCode = null; + + /** + * 재전송 여부 ("LU가 사용중" 메세지 수신시 다른 LU 그룹 세션으로 데이타 송신한다.) + */ + boolean bResendFlag = false ; + + /** + * DFS 메세지 판단 getDataFromQueue할때 결정 + */ + boolean bDFSFlag = false ; + + /** + * Timeout 데이타로 처리할 것인지 판단 + * (response 모드이고 queue에 없는 경우 -> queue에 저장하여 inbound로 처리한다.) + */ + boolean bResTimeoutFlag = false ; + + boolean isRecvSendOK = false; + + /** + * 1. 기능 : WCA Queue default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public WCAQueue() { + lCreateTime = System.currentTimeMillis(); + + nAccQueueCnt = 0; + nCurrQueueCnt = 0; + listQueue = new LinkedList(); + } + + + /** + * 1. 기능 : WCA Queue Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param nLen 송신 데이타 길이 + * @param pBuff 송신 데이타 데이타 + **/ + public WCAQueue(int nLen, byte[] pBuff) { + lCreateTime = System.currentTimeMillis(); + + nAccQueueCnt = 0; + nCurrQueueCnt = 0; + listQueue = new LinkedList(); + nSendLen = nLen; + pSendBuff = pBuff; + } + + /** + * 1. 기능 : 송신 데이타 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 송신 데이타 + **/ + public byte[] getSendData() { + return pSendBuff; + } + + public byte[] getSendHeaderData() { + byte[] pBuff = new byte[WCAHeader.WCA_HEADER_LEN]; + + if (pSendBuff == null) { return null; } + + System.arraycopy(pSendBuff, 0, pBuff, 0, WCAHeader.WCA_HEADER_LEN); + return pBuff; + } + /** + * 1. 기능 : 트랜잭션 키 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 트랜잭션 키 + **/ + public void setKey(String key) { + sKey = key; + } + + /** + * 1. 기능 : 트랜잭션 키 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 트랜잭션 키 + **/ + public String getKey() { + return sKey; + } + + public void setGroupCode(String groupCode) { + sGroupCode = groupCode; + } + + public String getGroupCode() { + return sGroupCode; + } + + /** + * 1. 기능 : 호출 모드 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 호출 모드 + **/ + public char getMode() { + if (pSendBuff == null) { return WCAHeader.TRAN_MODE_NONRESPONSE.charAt(0); } + return (char)pSendBuff[WCAHeader.OFFSET_MODE]; + } + + /** + * 1. 기능 : 재전송 여부 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 재전송 여부(true : 재전송 yes, false : no) + **/ + public void setResendFlag(boolean flag) { + bResendFlag = flag; + } + + /** + * 1. 기능 : 재전송 여부 반환 + * 2. 처리 개요 : 재전송 대상이며 타임아웃이 발생하지 않았을 경우 true 반환한다. + * 3. 주의사항 + * + * @return 재전송 여부(true : 재전송 yes, false : no) + **/ + public boolean getResendFlag() { + if (bResendFlag == true && getRemainedTime() > 0) { + return true; + } + return false; + } + + /** + * 1. 기능 : 타임아웃 여부 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 타임아웃 여부(true : yes, false : no) + **/ + public void setResTimeoutFlag(boolean flag) { + bResTimeoutFlag = flag; + } + + /** + * 1. 기능 : 타임아웃 여부 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 타임아웃 여부(true : yes, false : no) + **/ + public boolean getResTimeoutFlag() { + return bResTimeoutFlag; + } + + public boolean getRecvSendOKFlag() { + return isRecvSendOK; + } + + public void setRecvSendOKFlag(boolean flag) { + isRecvSendOK = flag; + } + + /** + * 1. 기능 : 타임아웃 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 타임아웃 시간 + **/ + public void setTimeout(int timeout) { + lTimeout = (long)(timeout * 1000); + } + + public void setDefaultTimeout(int timeout) { + lDefaultTimeout = (long)(timeout * 1000); + } + + /** + * 1. 기능 : 타임아웃 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 타임아웃 시간 + **/ + public int getTimeout() { + if (lTimeout == -1L) { return (int)lDefaultTimeout; } + return (int)lTimeout; + } + + /** + * 1. 기능 : 남아있는 타임아웃 값 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 타임아웃 시간 + **/ + public long getRemainedTime() { + if (lTimeout == 0L) { + return 0L; + } + + long lCurrentTime = System.currentTimeMillis(); + long lRemainTime = lTimeout - (lCurrentTime - lCreateTime); + if (lTimeout < 0L || lRemainTime <= 0L) { // 타임아웃 발샐시 - 리턴 + return -1L; + } + else { + return lRemainTime; + } + } + + /** + * 1. 기능 : 수신 데이타 리스트에 추가 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return queueData 수신 데이타 + **/ + public synchronized int addDataToQueue(WCAQueueData queueData) { + listQueue.addLast(queueData); + return 0; + } + + /** + * 1. 기능 : 수신 데이타 초기화 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public synchronized void initRecvData() { + listQueue.clear(); + } + + /** + * 1. 기능 : 수신 데이타 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 수신 데이타 + **/ + public synchronized byte[] getDataFromQueue() { + try { + WCAQueueData queuedata = null; + int nTempBuffLen = WCAHeader.WCA_HEADER_LEN; + // 길이 계산 + //----------------------------------------- + // 2008.03.28 : 홍명준 + // 멀티페이지 처리 오류 수정 + //----------------------------------------- + for(int i = 0; i < listQueue.size(); i++) { + queuedata = (WCAQueueData)listQueue.get(i); + nTempBuffLen += (queuedata.pBuff.length - WCAHeader.WCA_HEADER_LEN) ; + // System.out.println("getDataFromQueue> " + i + " Size = " + queuedata.pBuff.length); + } + + // System.out.println("getDataFromQueue> nTempBuffLen = " + nTempBuffLen); + + byte[] pDataBuff = new byte[nTempBuffLen]; + int nBuffPos = WCAHeader.WCA_HEADER_LEN; + for (int i = 0; i < listQueue.size(); i++) { + queuedata = (WCAQueueData)listQueue.get(i); + + // System.out.println("getDataFromQueue> " + i + " Copy WCA Header"); + System.arraycopy(queuedata.pBuff, 0, pDataBuff, 0, WCAHeader.WCA_HEADER_LEN); + + // System.out.println("getDataFromQueue> " + i + " Copy WCA Data, BuffPos = " + nBuffPos + ", Length = " + (queuedata.pBuff.length - WCAHeader.WCA_HEADER_LEN)); + System.arraycopy(queuedata.pBuff, WCAHeader.WCA_HEADER_LEN, pDataBuff, nBuffPos, queuedata.pBuff.length - WCAHeader.WCA_HEADER_LEN); + nBuffPos += (queuedata.pBuff.length - WCAHeader.WCA_HEADER_LEN); + } + + return pDataBuff; + } + catch (NoSuchElementException ex) { +// System.out.println("getDataFromQueue> Queue is Empty : "+ ex.toString()); + return null; + } + catch (Exception e) { +// System.out.println("getDataFromQueue> Exception : " + e.toString()); + return null; + } + } + + /** + * 1. 기능 : 수신 데이타 수 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 수신 데이타 수 + **/ + public synchronized int getCurrQueueDataCnt() { + return listQueue.size(); + } + + /** + * 1. 기능 : DFS 반환 + * 2. 처리 개요 : DFS 메세지 판단 + * 3. 주의사항 + * + * @return DFS 여부(true : DFS yes, false : no) + **/ + public boolean getDFSFlag() { + return bDFSFlag; + } + + /** + * 1. 기능 : DFS 설정 + * 2. 처리 개요 : DFS 메세지 설정 + * 3. 주의사항 + * + * @return DFS 여부(true : DFS yes, false : no) + **/ + /* + public void setDFSFlag(byte[] pBuff) + { + byte[] pDFSBuff = new byte[3]; + if (pBuff.length >= WCAHeader.WCA_HEADER_LEN + 3) + System.arraycopy(pBuff, WCAHeader.WCA_HEADER_LEN, pDFSBuff, 0, pDFSBuff.length); + + System.out.println("------> DFS : " + new String(pDFSBuff)); + if((new String(pDFSBuff)).equals(new String(WCADefine.DFS_MSG))) + bDFSFlag = true; + else bDFSFlag = false; + } + */ +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueueData.java b/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueueData.java new file mode 100644 index 0000000..96c0c85 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/data/WCAQueueData.java @@ -0,0 +1,46 @@ +package com.eactive.eai.adapter.wca.data; + +/** +* 1. 기능 : EAI Outbound 수신 데이타 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 17. 오후 3:26:11 +*/ +public class WCAQueueData { + /** + * 수신 데이타 길이 + */ + public int nLen; + + /** + * 수신 데이타 + */ + public byte[] pBuff; + + /** + * 1. 기능 : WCA Queue Data default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public WCAQueueData() { + nLen = 0; + pBuff = null; + } + + /** + * 1. 기능 : WCA Queue Data default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param nLen 수신 데이타 길이 + * @param pBuff 수신 데이타 데이타 + **/ + public WCAQueueData(int nLen, byte[] pBuff) { + this.nLen = nLen; + this.pBuff = pBuff; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/exception/WCAException.java b/src/main/java/com/eactive/eai/adapter/wca/exception/WCAException.java new file mode 100644 index 0000000..d5d4b17 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/exception/WCAException.java @@ -0,0 +1,330 @@ +package com.eactive.eai.adapter.wca.exception; + +import com.eactive.eai.common.errorcode.ErrorCodeHandler; +import com.eactive.eai.common.exception.ExceptionUtil; + +/** +* 1. 기능 : WCA 예외 발생 처리 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 20. 오후 3:38:15 +*/ +public class WCAException extends Exception { + /** + * 에러 코드 + */ + public String sErrCode = null; + + /** + * 에러 메세지 + */ + public String sErrMsg = null; + + /** + * Softlink 에러 코드 크기 + */ + public static final int SOFTLINK_ERROR_SIZE = 12; + + /** + * Softlink 에러 코드 Prefix + */ + public static final String SOFTLINK_ERROR_PREFIX = "RECEAISNA"; + public static final String WCA_ERROR_PREFIX = "RECEAIOWA"; + /** + * Softlink "LU 가 사용중"(E_HOST_LU_IN_USED) 인 경우 에러 코드 + * "LU 가 다운 "(E_HOST_LU_DOWN) 인 경우 에러 코드 + * 해당 업무에 해당하는 LU가 없습니다 + * -> 다른 LU 그룹 세션으로 재정송됨. + */ + public static final String E_HOST_LU_IN_USED = SOFTLINK_ERROR_PREFIX + "002"; + public static final String E_HOST_LU_DOWN = SOFTLINK_ERROR_PREFIX + "001"; + public static final String E_HOST_LU_NON_EXIST = SOFTLINK_ERROR_PREFIX + "012"; + + /** + * {1} Softlink 연결이 되지 않습니다. + */ + public static final String E_SOFTLINK_NOTCONN = "RECEAIOWA001"; + + /** + * {1} Softlink 세션이 끊어졌습니다. + */ + public static final String E_SOFTLINK_CONNECTION_CLOSE = "RECEAIOWA002"; + + /** + * Softlink로 데이타 송신중에 장애가 발생하였습니다. + */ + public static final String E_SOFTLINK_SENDERR = "RECEAIOWA003"; + + /** + * Softlink로부터 데이타 수신중에 장애가 발생하였습니다. + */ + public static final String E_SOFTLINK_RECVERR = "RECEAIOWA004"; + + /** + * 해당하는 어댑터그룹이 존재하지 않습니다. + */ + public static final String E_ADAPTERGROUP_NO_EXIST = "RECEAIOWA005"; + + /** + * 해당하는 LU 이름이 존재하지 않습니다. [{1}] + */ + public static final String E_LUNAME_NO_EXIST = "RECEAIOWA006"; + + /** + * 송신데이타[{1}]가 정의되지 않았습니다. + */ + public static final String E_SEND_DATA_ERROR = "RECEAIOWA007"; + + /** + * {1} 수신데이타가 유효하지 않습니다. [{2}] + */ + public static final String E_RECVDATA_ERROR = "RECEAIOWA008"; + + /** + * {1} 수신데이타길이가 유효하지 않습니다. [{2}] + */ + public static final String E_RECVERR_DATALEN = "RECEAIOWA009"; + + /** + * {1} 정의되지 않은 데이터 타입입니다. [{2}] + */ + public static final String E_SOFTLINK_UNKNOWN_COMMAND = "RECEAIOWA010"; + + /** + * {1} 이용가능한 WCA 세션이 없습니다. + */ + public static final String E_SOFTLINK_NO_SESSION_SLOT = "RECEAIOWA011"; + + /** + * {1} 송신 가능한 WCA 세션이 없습니다. + */ + public static final String E_SOFTLINK_NO_SENDABLE_SESSION_SLOT = "RECEAIOWA017"; + + /** + * 송신중 SNA LU0 어댑터 세션이 Close 되었습니다. + */ + public static final String E_SOFTLINK_SEND_SESSION_CLOSE = "RECEAIOWA018"; + /** + * 수신중 SNA LU0 어댑터 세션이 Close 되었습니다. + */ + public static final String E_SOFTLINK_RECV_SESSION_CLOSE = "RECEAIOWA019"; + + /** + * {1} 해당하는 세션 정보가 정의되지 않았습니다. + */ + public static final String E_SOFTLINK_NOT_FOUND_SESSION = "RECEAIOWA012"; + + /** + * Transaction 시간동안 데이타 수신을 하지 못하였습니다. + */ + public static final String E_WCA_TRANTIMEOUT = "RECEAIOWA013"; + + /** + * 데이타베이스 작업시 장애가 발생하였습니다. + */ + public static final String E_DAO = "RECEAIOWA014"; + + /** + * 외부 프로세스 호출 실패하였습니다.[{1}] + */ + public static final String E_PROCESS_CALL = "RECEAIOWA015"; + + /** + * 시스템 적용 실패하였습니다. {1} + */ + public static final String E_UPDATE_APPLY = "RECEAIOWA016"; + + /** + * 미처리 데이타를 클라이언트에 알리는데 실패하였습니다.(skey) + */ + public static final String E_INFORM_ERROR = "RECEAIOWA020"; + + + // Recv data가 Queue에 있지 않을 경우 + public static final String E_SOFTLINK_RECV_DATA_NOTFOUND = "RECEAIOWA100"; + public static final String E_SOCKET_ERROR = "RECEAIOWA998"; + public static final String E_ETC = "RECEAIOWA999"; + + /** + * Host Name을 얻을 수 없습니다. + */ + public static final String E_UNKNOWN_HOST = "RECEAIOWA101"; + + /** + * {1} 백업모드 전환 [{2}] + */ + public static final String W_SOFTLINK_BACKUP_CONV = "RWCEAIOWA015"; + /** + * Thread Group {1}에 속한 Thread가 종료되지 않았습니다. (Active Thread Count ={2}) + */ + public static final String W_THREAD_GROUP_ACTIVE = "RWCEAIOWA001"; + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param e Exception Class + **/ + public WCAException(Exception e) { + super(); + if (e instanceof java.lang.NullPointerException) { + this.sErrCode = E_ETC; + this.sErrMsg = "NULL 값이 존재합니다 [" + e.getMessage() + "]"; + } + } + + public WCAException() { + super(); + } + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : ExceptionUtil을 이용하여 에러 메세지를 설정한다. + * 3. 주의사항 + * + * @param sErrCode 에러 코드 + * @param sErrMsg 에러 메세지 + **/ + public WCAException(String sErrCode, String sErrMsg) { + super(sErrCode); + this.sErrCode = sErrCode; + String[] args = new String[1]; + args[0] = sErrMsg; + this.sErrMsg = ExceptionUtil.make(sErrCode, args); + } + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : ExceptionUtil을 이용하여 에러 메세지를 설정한다. + * 3. 주의사항 + * + * @param sErrCode 에러 코드 + * @param sErrMsg1 에러 메세지 + * @param sErrMsg2 에러 메세지 + **/ + public WCAException(String sErrCode, String sErrMsg1, String sErrMsg2) { + super(sErrCode); + this.sErrCode = sErrCode; + String[] args = new String[2]; + args[0] = sErrMsg1; + args[1] = sErrMsg2; + this.sErrMsg = ExceptionUtil.make(sErrCode, args); + } + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : ExceptionUtil을 이용하여 에러 메세지를 설정한다. + * 3. 주의사항 + * + * @param sErrCode 에러 코드 + **/ + public WCAException(String sErrCode) { + super(sErrCode); + this.sErrCode = sErrCode; + this.sErrMsg = "["+sErrCode+"] " + ErrorCodeHandler.getMessage(sErrCode); + } + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : ExceptionUtil을 이용하여 에러 메세지를 설정한다. + * 3. 주의사항 + * + * @param sErrCode 에러 코드 + * @param e Throwable class + **/ + public WCAException(String sErrCode, Throwable e) { + super(sErrCode); + this.sErrCode = sErrCode; + this.sErrMsg = ExceptionUtil.make(e, sErrCode); + } + + /** + * 1. 기능 : ExceptionUtil을 이용하여 정형화된 에러 메세지를 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sErrCode 에러 코드 + **/ + public static String displayError(String sErrCode) { + String sErrMsg = ErrorCodeHandler.getMessage(sErrCode); + return ExceptionUtil.make(sErrCode, sErrMsg); + } + + /** + * 1. 기능 : ExceptionUtil을 이용하여 정형화된 에러 메세지를 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sErrCode 에러 코드 + * @param sErrMsg 에러 메세지 + **/ + public static String displayError(String sErrCode, String sErrMsg) { + String[] args = new String[1]; + args[0] = sErrMsg; + return ExceptionUtil.make(sErrCode, args); + } + + /** + * 1. 기능 : ExceptionUtil을 이용하여 정형화된 에러 메세지를 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sErrCode 에러 코드 + * @param sErrMsg1 에러 메세지 + * @param sErrMsg2 에러 메세지 + **/ + public static String displayError(String sErrCode, String sErrMsg1, String sErrMsg2) { + String[] args = new String[2]; + args[0] = sErrMsg1; + args[1] = sErrMsg2; + return ExceptionUtil.make(sErrCode, args); + } + + /** + * 1. 기능 : 예외 메세지 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 예외 메세지 + **/ + public String toString() { + if ("".equals(sErrMsg)) { + return super.toString(); + } + else { + return sErrMsg; + } + } + + /** + * 1. 기능 : 예외 메세지 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 예외 메세지 + **/ + public String getMessage() { + return toString(); + } + + public void setMessage(String msg) { + sErrMsg = msg; + } + + /** + * 1. 기능 : 예외 코드 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 예외 코드 + **/ + public String getErrorReturnCode() { + return sErrCode; + } +} + diff --git a/src/main/java/com/eactive/eai/adapter/wca/global/WCADefine.java b/src/main/java/com/eactive/eai/adapter/wca/global/WCADefine.java new file mode 100644 index 0000000..9767a86 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/global/WCADefine.java @@ -0,0 +1,211 @@ +package com.eactive.eai.adapter.wca.global; + +import com.eactive.eai.common.server.EAIServerManager; + +/** +* 1. 기능 : WCA Global 상수 정의 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : 2005. 6. 20. 오후 3:21:35 +*/ +public class WCADefine { + /** + * SoftLink 세션 상태 코드 : 연결안됨 + */ + public static final int SESS_STAT_NOTCONN = 0; + + /** + * SoftLink 세션 상태 코드 : TCP 세션 연결 + */ + public static final int SESS_STAT_READY = 1; + + /** + * SoftLink 세션 상태 코드 : TCP 세션 사용중 (사용안함) + */ + public static final int SESS_STAT_INUSE = 2; + + /** + * TCP Socket 길이 필드 크기 + */ + public static final int LEGTH_FIELD_SIZE = 4; + + /** + * TCP 데이타 수신 타임아웃 (단위 : 초) + */ + public static final int DEFAULT_RECEIVE_TIMEOUT = 30; + + /** + * Softlink Socket 연결 Timeout (단위 : milliseconds) + */ + public static final int DEFAULT_CONNECT_TIMEOUT = 30; + + /** + * defalut softlink port + */ + public static final int DEFAULT_SOFTLINK_PORT = 4000; + + /** + * defalut softlink 세션 수 + */ + public static final int DEFAULT_SESS_NUM_PER_GRP = 1; + + /** + * 세션 해제시 복구를 시작하기 전에 Sleep 하는 시간(초) + */ + public static final int DEFAULT_SESS_RECOVERY_GAP = 5; + + /** + * 백업 전환 체크 DEFAULT_SESS_RECOVERY_GAP * DEFAULT_BACKUP_CONVERSION_CHECK (2분) + */ + public static final int DEFAULT_BACKUP_CONVERSION_CHECK = 12 * 2; + /** + * default socket receive 타임아웃 시간(초) + */ + public static final int DEFAULT_SOCK_RCV_TIMEOUT = 10; + + /** + * default 트랜잭션 Timeout 시간(초) + */ + public static final int DEFAULT_TRANSACTION_TIMEOUT = 180; + + /** + * Delete Registered Recv queue Timeout 시간(초) + */ + public static final int DEFAULT_TRANSACTION_DELETE_TIMEOUT = 300; + + /** + * EAI instance (EAIServerManager는 WLI 엔진 부팅시 초기화) + */ + public static final String SERVER_NAME = EAIServerManager.getInstance().getLocalServerName(); + + /** + * SNA 어댑터 Logger 이름 + */ + public static final String ADAPTER_LOGGER_NAME = "FileLogger{SNA}" + "_" + SERVER_NAME; + + /** + * 어댑터 명 + */ + public static final String ADAPTER_NAME = "SNAAdapter"; + + /** + * ASCII / EBCDIC코드를 의미, logData() 함수의 파라미터로 사용됨. + */ + public static final char ASCII_CODE = 'A'; + public static final char EBCDIC_CODE = 'E'; + + /** + * WCA 세션 로그 파일 기록 여부 (Yes/No) + */ + public static final String WCA_LOG_YES = "1"; + public static final String WCA_LOG_NO = "0"; + + /** + * Default WCA 세션 로그 파일 기록 여부 + */ + public static final String DEFAULT_WCA_LOG = WCA_LOG_YES; + + /** + * Default WCA 세션 로그 레벨 + */ + public static final int DEFAULT_WCA_LOG_LEVEL = 1; + + /** + * Default WCA 세션 로그 레벨 + */ + public static final String DEFAULT_WCA_STRING_LOG_LEVEL = "DEBUG"; + + /** + * Default WCA 세션 로그 사이즈 + */ + public static final int DEFAULT_WCA_LOG_SIZE = 10; + + /** + * LU 그룹 세션 송수신 모드 (SEND) + */ + public static final String LU_GROUP_TRAN_MODE_SEND = "S"; + + /** + * LU 그룹 세션 송수신 모드 (RECV) + */ + public static final String LU_GROUP_TRAN_MODE_RECV = "R"; + + /** + * 자동 백업 전환 여부 (No/Yes) + */ + public static final String WCA_AUTO_BACKUP_CVS_MODE_NO = "0"; + public static final String WCA_AUTO_BACKUP_CVS_MODE_YES = "1"; + + /** + * Default 자동 백업 전환 여부 + */ + public static final String DEFAULT_MANUAL_BACKUP_CVS_MODE = WCA_AUTO_BACKUP_CVS_MODE_NO; + + /** + * LU 송수신 RECV ONLY 모드 + */ + public static final String LU_TRAN_MODE_SEND_RECV = "1"; + public static final String LU_TRAN_MODE_TERMINAL = "2"; + public static final String LU_TRAN_MODE_SEND_ONLY = "3"; + public static final String LU_TRAN_MODE_RECV_ONLY = "4"; + + /** + * LU 송수신 모드 정의 + */ + public static final String[][] LU_TRAN_MODE = {{LU_TRAN_MODE_SEND_RECV, "SENDRECV"}, + {LU_TRAN_MODE_TERMINAL, "TERMINAL"}, + {LU_TRAN_MODE_SEND_ONLY, "SENDONLY"}, + {LU_TRAN_MODE_RECV_ONLY, "RECVONLY"} + }; + + /** + * 백업 LU + */ + public static final String DEFAULT_BACKUP_LU_NO = "0"; + public static final String DEFAULT_BACKUP_LU_YES = "1"; + public static final String[][] BACKUP_LU_YN = {{DEFAULT_BACKUP_LU_NO, "아니오"}, + {DEFAULT_BACKUP_LU_YES, "예"} + }; + + /* 20080526 Start */ + /** + * 원격 LU 여부 + */ + public static final String DEFAULT_REMOTE_LU_NO = "0"; + public static final String DEFAULT_REMOTE_LU_YES = "1"; + public static final String[][] REMOTE_LU_YN = {{DEFAULT_REMOTE_LU_NO, "아니오"}, + {DEFAULT_REMOTE_LU_YES, "예"} + }; + /* 20080526 End */ + + /** + * Softlink 설정 정보 변경 실행 파일 + */ + public static final String SOFTLINK_CFG_UPDATE_COMMAND = "/SnaUpdateCfg"; + + /** + * Softlink 로그 정보 변경 실행 파일 + */ + public static final String SOFTLINK_LOG_UPDATE_COMMAND = "/SnaLog"; + + /** + * Softlink 구동 실행 파일 + */ + //public static final String SOFTLINK_START_COMMAND = "/SnaStart"; + public static final String SOFTLINK_START_COMMAND = "/softman"; + + /** + * Softlink 종료 실행 파일 + */ + public static final String SOFTLINK_STOP_COMMAND = "/SnaStop"; + + /** + * DFS 메세지 + */ + public static final byte[] DFS_MSG = {(byte)0xC4,(byte)0xC6,(byte)0xE2}; +} + diff --git a/src/main/java/com/eactive/eai/adapter/wca/jdbc/BaseJDBC.java b/src/main/java/com/eactive/eai/adapter/wca/jdbc/BaseJDBC.java new file mode 100644 index 0000000..ca80d74 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/jdbc/BaseJDBC.java @@ -0,0 +1,214 @@ +package com.eactive.eai.adapter.wca.jdbc; + +import com.eactive.eai.common.dao.Keys; +import com.eactive.eai.common.util.ServiceLocator; + +import javax.sql.DataSource; +import java.sql.*; + +/** +* 1. 기능 : DB Operation을 위한 JDBC 추상 클래스 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public abstract class BaseJDBC +{ + /** + * JDBC Connection object + */ + protected Connection conn; + + /** + * JDBC preparedStatement object + */ + protected PreparedStatement preparedStatement; + + /** + * JDBC Statement object + */ + protected Statement Statement; + + /** + * JDBC DataSource JNDI 이름 + */ + protected String jndiName; + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + **/ + public BaseJDBC() { + this.jndiName = Keys.EAI_DATASOURCE; + } + + /** + * 1. 기능 : JNDI 설정 + * 2. 처리 개요 : + * - + * 3. 주의사항 + * + * @param jndiDataSource jndi 이름 + **/ + protected void setJNDIName(String jndiDataSource) { + this.jndiName = jndiDataSource; + } + + /** + * 1. 기능 : PreparedStatement객체 획득 + * 2. 처리 개요 : + * - + * 3. 주의사항 + * + * @param sql 실행 query + **/ + public PreparedStatement getStatement(String sql) throws SQLException { + return conn.prepareStatement(sql); + } + + /** + * 1. 기능 : auto-commit 모드 설정 + * 2. 처리 개요 : + * - + * 3. 주의사항 + * + * @param b_autoCommit (true to enable auto-commit mode; false to disable it ) + **/ + public void setAutoCommit(boolean b_autoCommit) throws SQLException { + conn.setAutoCommit(b_autoCommit); + } + + /** + * 1. 기능 : commit 실행 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public void commit() throws SQLException { + conn.commit(); + setAutoCommit(true); + } + + /** + * 1. 기능 : rollback 실행 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public void rollback() throws SQLException { + conn.rollback(); + setAutoCommit(true); + } + + /** + * 1. 기능 : close 실행 + * 2. 처리 개요 : Connection object 및 JDBC resources 반환 + * 3. 주의사항 + **/ + public void close() { + close(null); + } + + /** + * 1. 기능 : close 실행 + * 2. 처리 개요 : Connection object 및 JDBC resources 반환 + * 3. 주의사항 + * + * @param rs ResultSet Object + **/ + public void close(ResultSet rs) { + if (rs != null) { + try{ rs.close(); } catch (Exception ignore) {} + } + if (preparedStatement != null) { + try { preparedStatement.close(); } catch (Exception ignore) {} + } + if (Statement != null) { + try { Statement.close(); } catch (Exception ignore) {} + } + if (conn != null) { + try { conn.close(); } catch (Exception ignore) {} + } + } + + /** + * 1. 기능 : 검색 query 실행 + * 2. 처리 개요 : preparedStatement Object에 query 실행 + * 3. 주의사항 + * + * @result rs ResultSet Object + **/ + public ResultSet executeSelect() throws SQLException { + ResultSet rs = preparedStatement.executeQuery(); + return rs; + } + + /** + * 1. 기능 : 변경 query 실행 + * 2. 처리 개요 : preparedStatement Object에 query 실행 + * 3. 주의사항 + * + * @result rs ResultSet Object + **/ + public int executeUpdate() throws SQLException { + return preparedStatement.executeUpdate(); + } + + /** + * 1. 기능 : query 설정 + * 2. 처리 개요 : preparedStatement Object에 query 설정 + * 3. 주의사항 + * + * @result rs ResultSet Object + **/ + public void setStatement(String query) throws SQLException { + if (preparedStatement != null) try { preparedStatement.close(); } catch(SQLException e) {} + preparedStatement = conn.prepareStatement(query); + preparedStatement.clearParameters(); + //preparedStatement.setQueryTimeout(300); // 단위 초 + } + + /** + * 1. 기능 : JDBC Connection 생성 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception JDBCException JDBC 에러 + ***/ + public void getDsConnection() throws JDBCException { + DataSource dataSource = null; + try { + dataSource = getDataSource(jndiName); + if(dataSource == null) { + throw new Exception("datasource is NULL - "+jndiName); + } + conn = dataSource.getConnection(); + } + catch(Exception e) { + throw new JDBCException("["+jndiName+"] connection을 얻을 수 없습니다."); + } + } + + /** + * 1. 기능 : JNDI 서비스로부터 JDBC DataSource 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @exception JDBCException JDBC 에러 + ***/ + private DataSource getDataSource(String dataSourceName) throws JDBCException { + DataSource dataSource = null; + try { + ServiceLocator sl = ServiceLocator.getInstance(); + dataSource = sl.getDataSource(jndiName); + return dataSource; + } + catch (Exception e) { + throw new JDBCException("["+jndiName+"]을 얻을 수 없습니다."); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/jdbc/CommonJDBC.java b/src/main/java/com/eactive/eai/adapter/wca/jdbc/CommonJDBC.java new file mode 100644 index 0000000..aa5f83e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/jdbc/CommonJDBC.java @@ -0,0 +1,269 @@ +package com.eactive.eai.adapter.wca.jdbc; + + +import com.eactive.eai.common.util.Logger; + +import java.sql.ResultSet; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; + +/** +* 1. 기능 : DB Operation을 위한 공통 JDBC 클래스 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class CommonJDBC extends BaseJDBC +{ + /** + * SNAAdapter 로깅을 위한 logger + */ + Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + /** + * 1. 기능 : insert/update/delete SQL 실행 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sQuery 실행 Query + **/ + public void update(String sQuery) throws JDBCException { + int nExeCnt = 0; + try { + getDsConnection(); + setAutoCommit(false); + setStatement(sQuery); + nExeCnt = executeUpdate(); + commit(); + } + catch (SQLException sqle) { + try { rollback(); } catch(Exception e) { + trc_logger.error("rollback error"); + } + //throw new JDBCException(sqle.getErrorCode(), sqle.getMessage()); + throw new JDBCException("SQLProc", "update", sqle); + } + finally { + close(); + } + } + + /** + * 1. 기능 : insert/update/delete MULTI SQL 실행 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param saSql[] 실행 Query 배열 + **/ + public void update(String[] saSql) throws JDBCException { + try { + getDsConnection(); + setAutoCommit(false); + + for( int i =0; i< saSql.length; i++) { + setStatement(saSql[i]); + executeUpdate(); + } + commit(); + } + catch (SQLException sqle) { + try { rollback(); } catch(Exception r) { + trc_logger.error("rollback error"); + } + //throw new JDBCException(sqle.getErrorCode(), sqle.getMessage()); + throw new JDBCException("SQLProc", "update", sqle); + } + catch (Exception e) { + try { rollback(); } catch(Exception r) { + trc_logger.error("rollback error"); + } + throw new JDBCException("SQLProc", "update", e); + } + finally { + close(); + } + } + + /** + * 1. 기능 : Query 검색 + * 2. 처리 개요 : + * 3. 주의사항 : + * + * @return SQLData Object + **/ + public SQLData select(String sQuery) throws JDBCException { + return select(sQuery, 0, 0, 0); + } + + /** + * 1. 기능 : Query 검색 + * 2. 처리 개요 : + * 3. 주의사항 : + * + * @param sQuery 실행 query + * @param nCurPageNum 현재 page 번호 + * @param nDispRowsCnt 한 화면에 보여줄수 있는 데이타수 + * @param nDispPagesCnt 한 화면에 보여줄수 있는 페이지수 + * @return SQLData Object + **/ + public SQLData select(String sQuery, + int nCurPageNum, + int nDispRowsCnt, + int nDispPagesCnt) throws JDBCException { + ResultSet rs = null; + + int nFromIndx = 0; + int nOrderByIndx = 0; + String sCountQuery = ""; + + SQLData dao_data = null; //데이타 object + int nTotalDatasCnt = 0; //전체 데이타 수 + int nTotalPagesCnt = 0; //전체 페이지 수 + + try { + getDsConnection(); + if (nCurPageNum != 0 && nDispRowsCnt != 0 && nDispPagesCnt != 0) { + nFromIndx = sQuery.toUpperCase().indexOf(" FROM "); // From 절이 시작되는 자리의 값 + nOrderByIndx = sQuery.toUpperCase().indexOf("ORDER BY"); // ORDER BY 절이 시작되는 자리의 값 + + if (nOrderByIndx != -1) { + sCountQuery = new StringBuffer() + .append("SELECT count(*) ") + .append(sQuery.substring(nFromIndx + 1, nOrderByIndx)).toString(); + } + else { + sCountQuery = new StringBuffer() + .append("SELECT count(*) ") + .append(sQuery.substring(nFromIndx + 1)).toString(); + } + + setStatement(sCountQuery); + rs = executeSelect(); + + if (rs.next()) { + nTotalDatasCnt = rs.getInt(1); + } + + try { + if (rs != null) + rs.close(); + } + catch (Exception ex) { + } + + nTotalPagesCnt = nTotalDatasCnt / nDispRowsCnt; + if (nTotalDatasCnt % nDispRowsCnt > 0) { + nTotalPagesCnt++; + } + + //전체 페이지가 현재 페이지보다 작을 경우 마지막 페이지번호를 현재페이지로... + if (nTotalPagesCnt < nCurPageNum) { + nCurPageNum = nTotalPagesCnt; + } + } + + //if(trc_logger.isDebug()) trc_logger.debug("DAO select query] nCurPageNum = " + nCurPageNum + "\n" + sQuery); + setStatement(sQuery); + rs = executeSelect(); + + dao_data = setSQLData(rs, nCurPageNum, nDispRowsCnt, + nDispPagesCnt, nTotalDatasCnt, + nTotalPagesCnt); + return dao_data; + + } + catch (SQLException sqle) { + throw new JDBCException("SQLProc", "select", sqle); + } + catch (Exception e) { + // System.out.println("select error - " + e.getMessage()); + throw new JDBCException("SQLProc", "select", e); + } + finally { + close(rs); + } + } + + /** + * 1. 기능 : 검색된 데이타를 SQLData Object 설정 + * 2. 처리 개요 : + * 3. 주의사항 : + * + * @param rs ResultSet Object + * @param nCurPageNum 현재 page 번호 + * @param nDispRowsCnt 한 화면에 보여줄수 있는 데이타수 + * @param nDispPagesCnt 한 화면에 보여줄수 있는 페이지수 + * @return SQLData Object + **/ + public SQLData setSQLData(ResultSet rs, int nCurPagesNum, + int nDispRowsCnt, int nDispPagesCnt, + int nTotalDatasCnt, int nTotalPagesCnt) throws JDBCException { + try { + ResultSetMetaData rsmd = null; + int nColumnCnt = 0; // resultSet에 담아있는 data의 열수 + + SQLData dao_data = new SQLData(); // DATA OBJECT + rsmd = rs.getMetaData(); + nColumnCnt = rsmd.getColumnCount(); // resultSet에 담아있는 data의 열수 + + // DAOData 객체의 hashtable에 넣을 행 값 + int nRowsNum = 0; + + // SQLDATA 객체에 Column Name을 Set + for (int nIndx = 1; nIndx <= nColumnCnt; nIndx++) { + dao_data.setColumnName(rsmd.getColumnName(nIndx)); + } + + // page를 나누지 않을 경우 + if (nCurPagesNum == 0 && nDispRowsCnt == 0 && nDispPagesCnt == 0) { + for (int nRowIndx = 0; rs.next(); nRowIndx++) { + for (int nColIndx = 1; nColIndx <= nColumnCnt; nColIndx++) { + // DAODATA 객체에 data를 set + dao_data.setHashData(nRowsNum, rsmd.getColumnName(nColIndx), rs.getString(rsmd.getColumnName(nColIndx))); + if (nColIndx == nColumnCnt) { + nRowsNum++; // hashtable의 행의 수 증가 + } + } + nTotalDatasCnt++; + } + } + // page를 나눌경우 + else { + for (int nRowIndx = 0; rs.next(); nRowIndx++) { + // display하는 page의 정보만을 DAODATA 객체 SET + if ( (nRowIndx >= ( (nCurPagesNum - 1) * nDispRowsCnt)) && (nRowIndx < (nCurPagesNum * nDispRowsCnt))) { + for (int nColIndx = 1; nColIndx <= nColumnCnt;nColIndx++) { + // DAODATA 객체에 Column Name을 Set + dao_data.setColumnName(rsmd.getColumnName(nColIndx)); + + // SQLDATA 객체에 data를 set + dao_data.setHashData(nRowsNum, rsmd.getColumnName(nColIndx), rs.getString(rsmd.getColumnName(nColIndx))); + + if (nColIndx == nColumnCnt) { + nRowsNum++; // hashtable의 행의 수 증가 + } + } + } + } + } + + // 페이지이동시 필요한 정보 SET + dao_data.setCurrentPageNum(nCurPagesNum); + dao_data.setDispRowsCount(nDispRowsCnt); + dao_data.setDispPagesCount(nDispPagesCnt); + dao_data.setTotalRowsCount(nTotalDatasCnt); + dao_data.setTotalPagesCount(nTotalPagesCnt); + dao_data.setTotalColumnsCount(nColumnCnt); + + return dao_data; + } + catch (Exception e) { + trc_logger.error("setDAOData error - " + e.toString()); + throw new JDBCException("SQLProc", "setDAOData", e); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/jdbc/JDBCException.java b/src/main/java/com/eactive/eai/adapter/wca/jdbc/JDBCException.java new file mode 100644 index 0000000..c6157ae --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/jdbc/JDBCException.java @@ -0,0 +1,151 @@ +package com.eactive.eai.adapter.wca.jdbc; + +import java.sql.SQLException; + +/** +* 1. 기능 : JDBC 예외 발생 처리 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class JDBCException extends Exception +{ + /** + * 에러 코드 + */ + String errorCode = ""; + + /** + * 에러 메세지 + */ + String errorMsg = ""; + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + **/ + public JDBCException() { + super("JDBCException is occured."); + } + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param msg 에러 메세지 + **/ + public JDBCException(String msg) { + super(msg); + } + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param code 에러 코드 + * @param msg 에러 메세지 + **/ + public JDBCException(int code, String msg) { + super(msg); + errorCode = String.valueOf(code); + errorMsg = msg; + } + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param func 발생 class + * @param method 발생 함수 + * @param e Exception 클래스 + **/ + public JDBCException(String func, String method, Exception e) { + super(method + " Method in " + func + " Function - "+ e.getMessage()); + if (e instanceof SQLException) { + //errorCode = "ORA-" + String.valueOf(((SQLException)e).getErrorCode()); + //errorMsg = ((SQLException)e).getMessage().trim(); + setOracleMessage((SQLException)e); + } + else { + errorMsg = e.getMessage(); + } + } + + public JDBCException(Exception e, String para) { + super(e.getMessage()); + if (e instanceof SQLException) { + //errorCode = "ORA-" + String.valueOf(((SQLException)e).getErrorCode()); + //errorMsg = ((SQLException)e).getMessage().trim(); + setOracleMessage((SQLException)e); + errorMsg = errorMsg + "[" + para + "]"; + } + else { + errorMsg = e.getMessage() + "[" + para + "]"; + } + } + + /** + * 1. 기능 : 오라클 에러 메세지 설정 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param e SQLException 클래스 + **/ + private void setOracleMessage(SQLException e) + { + int code = e.getErrorCode(); + errorCode = "ORA-" + String.valueOf(((SQLException)e).getErrorCode()); + switch (code) { + case 00001: errorMsg = "UNIQUE COLUMN에 중복된 값이 입력되었습니다."; break; + case 01401: errorMsg = "입력한 필드 길이가 너무 큽니다."; break; + default : errorMsg = e.getMessage().trim(); break; + } + } + + /** + * 1. 기능 : JDBC 예외 메세지 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 예외 메세지 + **/ + public String toString() { + if (errorMsg.equals("")) { + return super.toString(); + } + else { + return errorMsg; + } + } + + /** + * 1. 기능 : JDBC 예외 메세지 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param 예외 메세지 + **/ + public String getMessage() { + return toString(); + } + + /** + * 1. 기능 : 예외 코드 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return 예외 코드 + **/ + public String getErrorReturnCode() { + return errorCode; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/jdbc/JDBCFactory.java b/src/main/java/com/eactive/eai/adapter/wca/jdbc/JDBCFactory.java new file mode 100644 index 0000000..7b6b728 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/jdbc/JDBCFactory.java @@ -0,0 +1,54 @@ +package com.eactive.eai.adapter.wca.jdbc; + +/** +* 1. 기능 : +* 2. 처리 개요 : +* * - +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +*/ +public class JDBCFactory +{ + private JDBCFactory() { + } + + public static JDBCFactory newInstance() { + return new JDBCFactory(); + } + + public BaseJDBC create(String jdbcClassName) throws JDBCException { + Class wrapperClass = null; + try { + wrapperClass = Class.forName(jdbcClassName); + } + catch (Exception e) { + throw new JDBCException("Cannot find the DAO Class. - "+jdbcClassName); + } + + BaseJDBC wrapper = null; + try { + wrapper = (BaseJDBC)wrapperClass.newInstance(); + } + catch (Exception e) { + throw new JDBCException("Cannot create a instance of class. - "+e.getMessage()); + } + + return wrapper; + } + + public BaseJDBC create(Class daoClass) throws JDBCException { + BaseJDBC wrapper = null; + try { + wrapper = (BaseJDBC)daoClass.newInstance(); + } + catch (Exception e) { + throw new JDBCException("Cannot create a instance of class. - "+e.getMessage()); + } + + return wrapper; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/jdbc/SQLData.java b/src/main/java/com/eactive/eai/adapter/wca/jdbc/SQLData.java new file mode 100644 index 0000000..c6a67c2 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/jdbc/SQLData.java @@ -0,0 +1,301 @@ +package com.eactive.eai.adapter.wca.jdbc; + +import java.util.Hashtable; +import java.util.Vector; + +/** +* 1. 기능 : 검색된 SQL 데이타 저장한 Object +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class SQLData +{ + Hashtable ht_data = new Hashtable(); // SQL DATA 저장 + Vector v_colName = new Vector(); // Column Name 저장 + + int i_total_rows_cnt; // 전체 데이타 수 + int i_total_columns_cnt; // 전체 컬럼의 수 + int i_total_pages_cnt; // 전체 페이지 수 + int i_disp_rows_cnt; // 한 화면에 보여줄수 있는 데이타수 + int i_disp_pages_cnt; // 한 화면에 보여줄수 있는 페이지수 + int i_current_page_num; // 현재 page 번호 + int i_disp_datas_cnt = -1; // 한 화면에 보여주는 데이타 수 + + String DEFAULT_FIRST_BUTTON = "/btn_first_page.gif"; + String DEFAULT_PREV_BUTTON = "/btn_pre_page.gif"; + String DEFAULT_NEXT_BUTTON = "/btn_next_page.gif"; + String DEFAULT_LAST_BUTTON = "/btn_end_page.gif"; + + /** + * Hashtable에 검색된 SQL 데이타를 SET + * key -> (s_name + i_row_num ) + * value -> s_value + */ + public void setHashData (int i_row_num, String s_name, String s_value) { + this.i_disp_datas_cnt = i_row_num; + String s_key = s_name + i_row_num; + + if (s_value == null) { + s_value = ""; + } + ht_data.put((Object)s_key, s_value); + } + + /** + * Column Name을 SET + */ + public void setColumnName(String s_name) { + v_colName.addElement(s_name); + } + + /** + * Column Name들을 GET + */ + public Vector getColumnName() { + return v_colName; + } + + + /** + * 검색된 전체 데이타 ROW 수 SET + */ + public void setTotalRowsCount(int i_total_rows_cnt) { + this.i_total_rows_cnt = i_total_rows_cnt; + } + + /** + * 검색된 전체 데이타 COLUMN 수 SET + */ + public void setTotalColumnsCount(int i_total_columns_cnt) { + this.i_total_columns_cnt = i_total_columns_cnt; + } + + /** + * 한화면에 표시될 데이타 ROW 수 SET + */ + public void setDispRowsCount(int i_disp_rows_cnt) { + this.i_disp_rows_cnt = i_disp_rows_cnt; + } + + /** + * 현재 page번호 SET + */ + public void setCurrentPageNum(int i_current_page_num) { + this.i_current_page_num = i_current_page_num; + } + + /** + * 한 화면에 표시될 페이지이동번호 수 SET + * @param i_disp_pages_cnt 페이지번호의 수 + */ + public void setDispPagesCount(int i_disp_pages_cnt) { + this.i_disp_pages_cnt = i_disp_pages_cnt; + } + + /** + * 전체 페이지 수 SET + */ + public void setTotalPagesCount(int i_total_pages_cnt) { + if (i_disp_rows_cnt != 0) { + this.i_total_pages_cnt = i_total_pages_cnt; + } + } + + /** + * 검색된 전체 데이타 ROW 수 GET + */ + public int getTotalRowsCount() { + return i_total_rows_cnt; + } + + /** + * 검색된 전체 데이타 COLUMN 수 GET + */ + public int getTotalColumnsCount() { + return i_total_columns_cnt; + } + + /** + * 한화면에 표시될 데이타 ROW 수 SET + **/ + public int getDispRowsCount() { + return i_disp_rows_cnt; + } + + /** + * 전체 page 수를 GET + * @return 전체 page 수 + */ + public int getTotalPagesCount() { + return i_total_pages_cnt; + } + + /** + * 현재 page번호 SET + */ + public int getCurrentPageNum() { + return i_current_page_num; + } + + /** + * 전체 페이지 수 GET + */ + public int getDispDatasCount() { + if (i_disp_datas_cnt == -1) { + return i_disp_datas_cnt; + } + else { + return i_disp_datas_cnt + 1; + } + } + + /** + * s_key에 해당되는 value를 GET + */ + public String getSQLStringData(String s_key) { + Object o = ht_data.get( (Object) s_key); + + if (o == null) { + return ""; + } + else { + return o.toString().trim(); + } + } + + public String getSQLStringData(String keyStr, int index) { + return getSQLStringData(keyStr + index); + } + + public int getSQLIntData(String s_key) { + //return Integer.parseInt(ht_data.get( (Object) s_key).toString().trim()); + Object o = ht_data.get( (Object) (s_key)); + if (o == null || o.equals("")) { + o = (Object)"0"; + } + return Integer.parseInt((String)o); + } + + public int getSQLIntData(String s_key, int index) { + Object o = ht_data.get( (Object) (s_key + index)); + + if (o == null || o.equals("")) { + o = (Object)"0"; + } + return Integer.parseInt((String)o); + } + + /** + * 페이지 분할 HTML 데이타 + */ + public String getPageHtmlData(String s_javascript, String s_imagePath) { + // 이미지 + String btn_first = " "; + String btn_prev = " "; + String btn_next = " "; + String btn_last = " "; + + return getPageHtmlData(s_javascript, btn_first, btn_prev, btn_next, btn_last); + } + + public String getPageHtmlData(String s_javascript) { + String btn_first = "|◀"; + String btn_prev = "◀"; + String btn_next = "▶"; + String btn_last = "▶|"; + return getPageHtmlData(s_javascript, btn_first, btn_prev, btn_next, btn_last); + } + + public String getPageHtmlData(String s_javascript, String btn_first, String btn_prev, String btn_next, String btn_last) { + StringBuffer sb_page = new StringBuffer(); + + // page를 나누지 않을 경우 + if (i_disp_pages_cnt == 0) { + return ""; + } + + //데이타가 존재하지 않을 경우 + if (i_total_rows_cnt == 0) { + //sb_page.append("데이타가 존재하지 않습니다."); + } + else { + // 페이지 분할 할 경우 + if (i_total_pages_cnt != 0 ) { + // 페이지번호의 시작번호 + int i_start_page_num = 1; + // 페이지번호의 마지막번호 + int i_end_page_num = 1; + // 이전페이지 이동시의 시작페이지번호 + int i_prev_page_num = 1; + // 다음페이지 이동시의 시작페이지번호 + int i_next_page_num = 1; + + // 이전 페이지 번호 +// int i_prev_num = i_current_page_num - 1; +// int i_next_num = i_current_page_num + 1; + + // 시작페이지 + i_start_page_num = ( (i_current_page_num - 1) / i_disp_pages_cnt) * i_disp_pages_cnt + 1; + // 마지막 페이지 + i_end_page_num = ( (i_current_page_num - 1) / i_disp_pages_cnt) * i_disp_pages_cnt + i_disp_pages_cnt; + + if (i_end_page_num > i_total_pages_cnt) { + i_end_page_num = i_total_pages_cnt; + } + + // 처음으로 + if (i_current_page_num > 1) { + sb_page.append("" + btn_first + ""); + } + else { + sb_page.append(btn_first); + } + + //이전페이지 + if (i_start_page_num > i_disp_pages_cnt) { + i_prev_page_num = i_start_page_num - 1; + sb_page.append("" + btn_prev + ""); + } + else { + sb_page.append(btn_prev); + } + + //페이지 번호 이동 + for (int i_pageNum = i_start_page_num; i_pageNum <= i_end_page_num; i_pageNum++) { + if (i_pageNum == i_current_page_num) { + //sb_page.append("[" + i_pageNum + "]"); + sb_page.append(" | " + i_pageNum + ""); + } + else { + sb_page.append(" | " + i_pageNum + ""); + } + } + + sb_page.append(" | "); + + // 다음 페이지 + if (i_end_page_num < i_total_pages_cnt) { + i_next_page_num = i_end_page_num + 1; + sb_page.append("" + btn_next + ""); + } + else { + sb_page.append(btn_next); + } + + // 마지막 페이지 + if (i_current_page_num < i_total_pages_cnt) { + sb_page.append("" + btn_last + ""); + } + else { + sb_page.append(btn_last); + } + } + } + return sb_page.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/log/ErrorLogQuery.java b/src/main/java/com/eactive/eai/adapter/wca/log/ErrorLogQuery.java new file mode 100644 index 0000000..27b0e4f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/log/ErrorLogQuery.java @@ -0,0 +1,23 @@ +package com.eactive.eai.adapter.wca.log; + +import com.eactive.eai.adapter.wca.servlet.TableInfoEx; + +public interface ErrorLogQuery +{ + /** + * 에러 추가 query + */ + // 20191015 Start + // 쿼리 대소문자 변경으로 인해 변경 + /* + public static final String INSERT_ERROR_LOG = "INSERT INTO "+ TableInfoEx.T_ERROR_LOG + + " (\"MsgDpstHMS\", \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\", \"LUName\", " + + " \"LogPrcssSerno\", \"EAISvcSerno\", \"DataDstcd\", \"EAIErrCtnt\", \"FrtimMsgDpstHMS\" )" + + " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + */ + public static final String INSERT_ERROR_LOG = "INSERT INTO "+ TableInfoEx.T_ERROR_LOG + + " (MsgDpstHMS, AdptrGstatSevrName, AdptrGroupName, LUGroupName, LUName, " + + " LogPrcssSerno, EAISvcSerno, DataDstcd, EAIErrCtnt, FrtimMsgDpstHMS )" + + " VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; + // 20191015 End +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/log/InsertErrorLog.java b/src/main/java/com/eactive/eai/adapter/wca/log/InsertErrorLog.java new file mode 100644 index 0000000..52ee7d1 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/log/InsertErrorLog.java @@ -0,0 +1,78 @@ +package com.eactive.eai.adapter.wca.log; + +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.jdbc.BaseJDBC; +import com.eactive.eai.adapter.wca.jdbc.JDBCException; +import com.eactive.eai.adapter.wca.util.DateUtil; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +import java.sql.SQLException; + +public class InsertErrorLog extends BaseJDBC implements ErrorLogQuery +{ + Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + /** + * 1. 기능 : 에러 로그 추가 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param data SessionGroupData Object + * @return 추가된 레코드 수 + * @exception JDBCException DB 작업시 발행하는 예외 발생 정보 (SQLException 에러코드와 메세지 포함) + **/ + public int insertErrorLog(String adapterGroupName, String luGroupName, String luName, + String dataccd, String svcsno, String errcd) throws JDBCException { + int nExeCnt = 0; + StringBuffer sbLog = new StringBuffer(); + + if (luGroupName == null || luGroupName.equals("")) { luGroupName = " "; } + if (luName == null || luName.equals("")) { luName = " "; } + String sFrtimMsgDpstHMS = " "; + String sLogPrcssSerno = "100"; + if (errcd.equals(WCAException.E_SOFTLINK_RECV_SESSION_CLOSE)) { sLogPrcssSerno = "400"; } + + try { + DateUtil dateUtil = new DateUtil(); + String sDate = dateUtil.getDateMilliTime(); + getDsConnection(); + setStatement(INSERT_ERROR_LOG); + //MsgDpstHMS, AdptrGstatSevrName, AdptrGroupName, LUGroupName, LUName, + //LogPrcssSerno, EAISvcSerno, DataDstcd, EAIErrCtnt, FrtimMsgDpstHMS + this.preparedStatement.setString(1, sDate); + this.preparedStatement.setString(2, EAIServerManager.getInstance().getLocalServerHostName()); + this.preparedStatement.setString(3, adapterGroupName); + this.preparedStatement.setString(4, luGroupName); + this.preparedStatement.setString(5, luName); + this.preparedStatement.setString(6, sLogPrcssSerno); + this.preparedStatement.setString(7, svcsno); + this.preparedStatement.setString(8, dataccd); + this.preparedStatement.setString(9, errcd); + this.preparedStatement.setString(10, sFrtimMsgDpstHMS); + + sbLog.append(sDate + ",") + .append(EAIServerManager.getInstance().getLocalServerHostName() + ",") + .append(adapterGroupName + ",") + .append(luGroupName + ",") + .append(luName + ",") + .append(sLogPrcssSerno + ",") + .append(svcsno + ",") + .append(dataccd + ",") + .append(errcd + ",") + .append(sFrtimMsgDpstHMS); + if (trc_logger.isDebug()) { trc_logger.debug("Error Log = " + sbLog.toString()); } + + nExeCnt =executeUpdate(); + return nExeCnt; + } + catch (SQLException e) { + throw new JDBCException(e, svcsno); + } + catch (java.net.UnknownHostException host) { + throw new JDBCException("InsertErrorLog", "insertErrorLog", host); + } + finally { + this.close(); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/LUGroupServletEx.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/LUGroupServletEx.java new file mode 100644 index 0000000..f9eedea --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/LUGroupServletEx.java @@ -0,0 +1,538 @@ +//package com.eactive.eai.adapter.wca.servlet; +// +//import java.io.IOException; +//import java.util.HashMap; +//import java.util.Iterator; +//import java.util.StringTokenizer; +//import java.util.Vector; +//import javax.servlet.RequestDispatcher; +//import javax.servlet.ServletConfig; +//import javax.servlet.ServletException; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import javax.servlet.http.HttpSession; +//import org.apache.log4j.Logger; +// +//import com.eactive.eai.adapter.wca.cfg.LUInfoJDBCEx; +//import com.eactive.eai.adapter.wca.cfg.SNAAdapter; +//import com.eactive.eai.adapter.wca.cfg.SNAAdapterManager; +//import com.eactive.eai.adapter.wca.cfg.SessionGroupDataEx; +//import com.eactive.eai.adapter.wca.cfg.SessionGroupJDBCEx; +//import com.eactive.eai.adapter.wca.command.DBCommand; +//import com.eactive.eai.adapter.wca.command.DeleteSessionGroupEx; +//import com.eactive.eai.adapter.wca.command.InsertSessionGroupEx; +//import com.eactive.eai.adapter.wca.command.UpdateSessionGroupEx; +//import com.eactive.eai.adapter.wca.exception.WCAException; +//import com.eactive.eai.adapter.wca.global.WCADefine; +//import com.eactive.eai.adapter.wca.jdbc.CommonJDBC; +//import com.eactive.eai.adapter.wca.jdbc.JDBCException; +//import com.eactive.eai.adapter.wca.jdbc.JDBCFactory; +//import com.eactive.eai.adapter.wca.jdbc.SQLData; +//import com.eactive.eai.adapter.wca.util.SNAAgentUtil; +//import com.eactive.eai.agent.AgentUtil; +//import com.eactive.eai.agent.command.Command; +//import com.eactive.eai.common.server.EAIServerManager; +// +///** +//* 1. 기능 : LU 그룹 관리 서블릿 +//* 2. 처리 개요 : +//* 3. 주의사항 +//* +//* @author : +//* @version : +//* @see : +//* @since : +//*/ +//public class LUGroupServletEx extends HttpServlet implements DBCommand{ +// Logger logger = Logger.getLogger(LUGroupServletEx.class); +// /** +// * 1. 기능 : GET 데이타 처리 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @param response HttpServletResponse 객체 +// **/ +// public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { +// doPost(request, response); +// } +// +// /** +// * 1. 기능 : POST 데이타 처리 +// * 2. 처리 개요 : TYPE에 따라 함수 분기 +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @param response HttpServletResponse 객체 +// **/ +// public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { +// +// String srType = request.getParameter("TYPE")==null? "":request.getParameter("TYPE").trim(); +// +// try +// { +// if(srType.equals("INSERT")){ +// insertLUGroup(request); +// selectLUGroup(request); +// } +// else if(srType.equals("DELETE")){ +// deleteLUGroup(request); +// selectLUGroup(request); +// } +// else if(srType.equals("DELETE_ALL")){ +// deleteAllLUGroup(request); +// selectLUGroup(request); +// } +// else if(srType.equals("UPDATE")){ +// updateLUGroup(request); +// selectLUGroup(request); +// } +// else if(srType.equals("LIST")){ +// selectLUGroup(request); +// } +// +// else if(srType.equals("UPDATE_SELECT")){ // update page +// updateSelectLUGroup(request); +// +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_LU_GROUP_UPDATE); +// rd.forward(request, response); +// return; +// } +// else +// { +// selectLUGroup(request); +// } +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_LU_GROUP_LIST); +// rd.forward(request, response); +// } +// catch(JDBCException jdbc) +// { +// jdbc.printStackTrace(); +// String sErrorMsg = jdbc.toString(); +// request.setAttribute("errorMessage",sErrorMsg ); +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_ERROR); +// rd.forward(request, response); +// } +// catch(Exception e) +// { +// e.printStackTrace(); +// request.setAttribute("errorMessage", e.toString()); +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_ERROR); +// rd.forward(request, response); +// } +// } +// +// /** +// * 1. 기능 : LU 세션 그룹 조회 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @exception JDBCException +// **/ +// private void selectLUGroup(HttpServletRequest request) throws JDBCException { +// StringBuffer sbQuery = new StringBuffer(); +// +// // 20080827 Start +// // 20080527 Start +// /* +// sbQuery.append( "select \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\", \"SoftLinkPortNo\", \"WCASessCnt\", \"SvcToutVal\", " + +// " \"BkupAutoCnvsnYn\", \"BkupCnvsnBaseObstclRt\" " + +// " FROM " + TableInfo.T_LU_GROUP + +// " WHERE 1=1 "); +// */ +// /* +// sbQuery.append( "select \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\", \"SoftLinkPortNo\", \"WCASessCnt\", \"SvcToutVal\", " + +// " \"BkupAutoCnvsnYn\", \"BkupCnvsnBaseObstclRt\", \"SoftLinkSevrName\" " + +// " FROM " + TableInfoEx.T_LU_GROUP + +// " WHERE 1=1 "); +// */ +// // 20080527 End +// sbQuery.append( "select \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\", \"SoftLinkPortNo\", \"WCASessCnt\", \"SvcToutVal\", " + +// " \"BkupAutoCnvsnYn\", \"BkupCnvsnBaseObstclRt\" " + +// " FROM " + TableInfoEx.T_LU_GROUP + +// " WHERE 1=1 "); +// // 20080827 End +// +// try { +// // 1. page num +// String sCurrentPageNum = request.getParameter("CURRENT_PAGE_NUM"); +// if ( sCurrentPageNum == null || sCurrentPageNum.equals("") ) +// sCurrentPageNum = "1"; +// int nCurrentPageNum = Integer.parseInt(sCurrentPageNum); +// +// String sEaiSystemName = request.getParameter("NODENM")==null?"":request.getParameter("NODENM"); +// String sAdapterGroupName= request.getParameter("ADPTGRPNM")==null?"":request.getParameter("ADPTGRPNM"); +// +// String srSortColumn = request.getParameter("SORT_COLUMN")==null? "": request.getParameter("SORT_COLUMN"); +// String srSortNodeName = request.getParameter("SORT_NODENM")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_NODENM"); +// String srSortAdapterGrpName = request.getParameter("SORT_ADPTGRPNM")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_ADPTGRPNM"); +// String srSortLUGrpName = request.getParameter("SORT_LUGRPNM")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_LUGRPNM"); +// +// srSortNodeName = (srSortNodeName.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// srSortAdapterGrpName = (srSortAdapterGrpName.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// srSortLUGrpName = (srSortLUGrpName.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// +// // 2. get parameter and make conf query +// if (!sEaiSystemName.equals(SelectBoxData.ALL_SEARCH) && !sEaiSystemName.equals("")) +// sbQuery.append(" AND \"AdptrGstatSevrName\" = '" + sEaiSystemName + "' " ); +// if (!sAdapterGroupName.equals(SelectBoxData.ALL_SEARCH) && !sAdapterGroupName.equals("")) +// sbQuery.append(" AND \"AdptrGroupName\" = '" + sAdapterGroupName + "' "); +// +// if (srSortColumn.equals("SORT_NODENM")) +// sbQuery.append(" ORDER BY \"AdptrGstatSevrName\" " + srSortNodeName); +// else if (srSortColumn.equals("SORT_ADPTGRPNM")) +// sbQuery.append(" ORDER BY \"AdptrGroupName\" " + srSortAdapterGrpName); +// else if (srSortColumn.equals("SORT_LUGRPNM")) +// sbQuery.append(" ORDER BY \"LUGroupName\" " + srSortLUGrpName); +// else +// sbQuery.append(" ORDER BY \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\""); +// +// // 3. query execute +// JDBCFactory factory = JDBCFactory.newInstance(); +// CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); +// SQLData data = common.select(sbQuery.toString(), nCurrentPageNum, TableStyle.DISP_ROWS_COUNT, TableStyle.DISP_PAGES_COUNT); +// request.setAttribute("RESULT", data); +// } +// catch(JDBCException e) +// { +// throw e; +// } +// } +// +// /** +// * 1. 기능 : LU 세션 그룹 등록 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @exception Exception +// **/ +// public void insertLUGroup(HttpServletRequest request) throws Exception { +// JDBCFactory factory = JDBCFactory.newInstance(); +// SessionGroupJDBCEx jdbc = null; +// +// try { +// SessionGroupDataEx data = setParameter(request); +// jdbc = (SessionGroupJDBCEx)factory.create(SessionGroupJDBCEx.class); +// int result = jdbc.insertSessionGroup(data); +// logger.info("LU 그룹 등록 : " + data.toString()); +// updateApply(CMD_INSERT, data); +// } +// catch(JDBCException e) { +// e.printStackTrace(); +// throw e; +// } +// } +// +// /** +// * 1. 기능 : LU 세션 그룹 삭제 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @exception Exception +// **/ +// public void deleteLUGroup(HttpServletRequest request) throws Exception { +// JDBCFactory factory = JDBCFactory.newInstance(); +// SessionGroupJDBCEx jdbc = null; +// HashMap hmDatas = new HashMap(); +// String sAdapterGrpName = ""; +// String sLUGrpName = ""; +// +// try { +// jdbc = (SessionGroupJDBCEx)factory.create(SessionGroupJDBCEx.class); +// +// MakeQuery makeQuery = new MakeQuery(request); +// Vector vConfQuery = makeQuery.makeExeSql(); +// // 삭제할 checkbox 데이타 +// for(int nIndx=0;nIndx 0) // 에러가 있을 경우 +// throw new WebException("시스템 적용 실패하였습니다.
" + makeErrorString(result)) ; +// } +// +// private String makeErrorString(HashMap result) +// { +// StringBuffer sbResult = new StringBuffer(); +// Iterator it = result.keySet().iterator(); +// String sSvrName = null; +// String sResult = null; +// while(it.hasNext()) { +// sSvrName = (String)it.next(); +// sResult = (String)result.get(sSvrName); +// if (sResult.equals("success")) continue; +// sbResult.append(sSvrName + " : " + sResult +"
"); +// } +// return sbResult.toString(); +// } +// +// /** +// * 1. 기능 : 파라미터 정보로 SessionGroupData 객체 생성 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @return SessionGroupData 객체 +// **/ +// private SessionGroupDataEx setParameter(HttpServletRequest request) +// { +// // 1. 파라미터 설정 +// SessionGroupDataEx data = new SessionGroupDataEx(); +// String sNodeName = request.getParameter("NODENM")==null?"":request.getParameter("NODENM"); +// String sAdptGrpName = request.getParameter("ADPTGRPNM")==null?"":request.getParameter("ADPTGRPNM"); +// String sLUGrpName = request.getParameter("LUGRPNM")==null?"":request.getParameter("LUGRPNM"); +// String sPort = request.getParameter("SOFTLINKPORT")==null?"0":request.getParameter("SOFTLINKPORT"); +// String sSessCnt = request.getParameter("WCASSNCNT")==null?"0":request.getParameter("WCASSNCNT"); +// String sTranTimeout = request.getParameter("TRANTIMEOUT")==null?String.valueOf(WCADefine.DEFAULT_TRANSACTION_TIMEOUT):request.getParameter("TRANTIMEOUT"); +// String sTranMode = request.getParameter("SRECEMODE")==null?"":request.getParameter("SRECEMODE"); +// String sDummyOffset = request.getParameter("DUMMYOFFSET")==null?"0":request.getParameter("DUMMYOFFSET"); +// String sHostSndRUSize = request.getParameter("HOSTSNDRUSIZE")==null?"0":request.getParameter("HOSTSNDRUSIZE"); +// String sHostRcvRUSize = request.getParameter("HOSTRCVRUSIZE")==null?"0":request.getParameter("HOSTRCVRUSIZE"); +// String sApplyID = request.getParameter("APPLID")==null?"":request.getParameter("APPLID"); +// +// // 20090227 Start +// String sUpdateLuApplyID = request.getParameter("UPDATE_LU_APPLID")==null?"":request.getParameter("UPDATE_LU_APPLID"); +// // 20090227 End +// +// String sBkupAutoCvs = request.getParameter("BKUPAUTOCVSYN")==null?"":request.getParameter("BKUPAUTOCVSYN"); +// String sBkupCvsVal = request.getParameter("BKUPCVSBASVL")==null?"0":request.getParameter("BKUPCVSBASVL"); +// String sBkupnNodeName = request.getParameter("BKUPNODENM")==null?"":request.getParameter("BKUPNODENM"); +// String sBkupPort = request.getParameter("BKUPSOFTLINKPORT")==null?"0":request.getParameter("BKUPSOFTLINKPORT"); +// +// String sLogUsgYn = request.getParameter("LOGUSGYN")==null?"":request.getParameter("LOGUSGYN"); +// String sLogLevel = request.getParameter("LOGLVL")==null?"":request.getParameter("LOGLVL"); +// String sLogVal = request.getParameter("GRSTLOGFILESIZE")==null?"0":request.getParameter("GRSTLOGFILESIZE"); +// +// // 20080827 Start +// /* +// // 20080527 Start +// String sSoftLinkSevrName = request.getParameter("SOFTLINKSEVRNAME")==null? "127.0.0.1":request.getParameter("SOFTLINKSEVRNAME"); +// // 20080527 End +// */ +// String sSoftLinkSevrName = "127.0.0.1"; +// // 20080827 End +// +// // 2. vo 설정 +// data.setNodeName(sNodeName); +// data.setAdapterGroupName(sAdptGrpName); +// data.setGroupName(sLUGrpName); +// data.setPort(sPort); +// data.setSessionCnt(sSessCnt); +// data.setTranTimeout(sTranTimeout); +// data.setDummyOffset(sDummyOffset); +// data.setHostSndRUSize(sHostSndRUSize); +// data.setHostRcvRUSize(sHostRcvRUSize); +// data.setApplyID(sApplyID); +// +// // 20090227 Start +// data.setUpdateLuApplyID(sUpdateLuApplyID); +// // 20090227 End +// +// data.setBackupCvsMode(sBkupAutoCvs); +// data.setBackupCvsVal(sBkupCvsVal); +// data.setBackupNodeName(sBkupnNodeName); +// data.setBackupPort(sBkupPort); +// data.setLogYN(sLogUsgYn); +// data.setLogLevel(sLogLevel); +// data.setLogSize(sLogVal); +// +// // 20080527 Start +// data.setSoftLinkSevrName(sSoftLinkSevrName); +// // 20080527 End +// +// return data; +// } +// +// +//} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/LUHostServletEx.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/LUHostServletEx.java new file mode 100644 index 0000000..e54b63a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/LUHostServletEx.java @@ -0,0 +1,336 @@ +package com.eactive.eai.adapter.wca.servlet;//package com.eactive.eai.adapter.wca.servlet; +// +//import java.io.IOException; +//import java.util.HashMap; +//import java.util.Iterator; +//import java.util.StringTokenizer; +//import java.util.Vector; +// +//import javax.servlet.RequestDispatcher; +//import javax.servlet.ServletException; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +// +//import org.apache.log4j.Logger; +// +//import com.eactive.eai.adapter.wca.cfg.LUHostDataEx; +//import com.eactive.eai.adapter.wca.cfg.LUHostJDBCEx; +//import com.eactive.eai.adapter.wca.jdbc.CommonJDBC; +//import com.eactive.eai.adapter.wca.jdbc.JDBCException; +//import com.eactive.eai.adapter.wca.jdbc.JDBCFactory; +//import com.eactive.eai.adapter.wca.jdbc.SQLData; +// +///** +//* 1. ��� : LU ���� ���� +//* 2. ó�� ���� : +//* 3. ���ǻ��� +//* +//* @author : +//* @version : +//* @see : +//* @since : +//*/ +//public class LUHostServletEx extends HttpServlet { +// +// Logger logger = Logger.getLogger(LUHostServletEx.class); +// +// /** +// * 1. ��� : GET ����Ÿ ó�� +// * 2. ó�� ���� : +// * 3. ���ǻ��� +// * +// * @param request HttpServletRequest ��ü +// * @param response HttpServletResponse ��ü +// **/ +// public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { +// doPost(request, response); +// } +// +// /** +// * 1. ��� : POST ����Ÿ ó�� +// * 2. ó�� ���� : TYPE�� ���� �Լ� �б� +// * 3. ���ǻ��� +// * +// * @param request HttpServletRequest ��ü +// * @param response HttpServletResponse ��ü +// **/ +// public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { +// +// try +// { +// String srType = request.getParameter("TYPE")==null? "":request.getParameter("TYPE").trim(); +// +// if(srType.equals("INSERT")){ +// insertLUHost(request); +// selectLUHost(request); +// } +// else if(srType.equals("DELETE")){ +// deleteLUHost(request); +// selectLUHost(request); +// } +// else if(srType.equals("UPDATE")){ +// updateLUHost(request); +// selectLUHost(request); +// } +// else if(srType.equals("UPDATE_SELECT")) { // update page +// updateSelectLUHost(request); +// +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_LU_HOST_UPDATE); +// rd.forward(request, response); +// return; +// } +// else if(srType.equals("LIST")){ +// selectLUHost(request); +// } +// else +// { +// selectLUHost(request); +// } +// +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_LU_HOST_LIST); +// rd.forward(request, response); +// } +// catch(JDBCException jdbc) +// { +// jdbc.printStackTrace(); +// String sErrorMsg = jdbc.toString(); +// request.setAttribute("errorMessage",sErrorMsg ); +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_ERROR); +// rd.forward(request, response); +// } +// catch(Exception e) +// { +// e.printStackTrace(); +// request.setAttribute("errorMessage", e.toString()); +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_ERROR); +// rd.forward(request, response); +// } +// } +// +// /** +// * 1. ��� : LU ȣ��Ʈ ��ȸ +// * 2. ó�� ���� : +// * 3. ���ǻ��� +// * +// * @param request HttpServletRequest ��ü +// * @exception JDBCException +// **/ +// private void selectLUHost(HttpServletRequest request) throws JDBCException { +// StringBuffer sbQuery = new StringBuffer(); +// +// sbQuery.append( "select \"SNAAdptrSevrName\", \"SNAAdptrSevrIPName\", \"SNAAdptrSevrCtnt\" " + +// " FROM " + TableInfoEx.T_LU_HOST + +// " WHERE 1=1 "); +// +// // 1. page num +// String sCurrentPageNum = request.getParameter("CURRENT_PAGE_NUM"); +// if ( sCurrentPageNum == null || sCurrentPageNum.equals("") ) +// sCurrentPageNum = "1"; +// int nCurrentPageNum = Integer.parseInt(sCurrentPageNum); +// +// String srSortColumn = request.getParameter("SORT_COLUMN")==null? "": request.getParameter("SORT_COLUMN"); +// String srSortNodeName = request.getParameter("SORT_NODENM")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_NODENM"); +// String srSortNodeIp = request.getParameter("SORT_NODEIP")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_NODEIP"); +// +// srSortNodeName = (srSortNodeName.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// srSortNodeIp = (srSortNodeIp.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// +// if (srSortColumn.equals("SORT_NODENM")) +// sbQuery.append(" ORDER BY \"SNAAdptrSevrName\" " + srSortNodeName); +// else if (srSortColumn.equals("SORT_NODEIP")) +// sbQuery.append(" ORDER BY \"SNAAdptrSevrIPName\" " + srSortNodeIp); +// else +// sbQuery.append(" ORDER BY \"SNAAdptrSevrName\", \"SNAAdptrSevrIPName\" "); +// +// // 3. query execute +// JDBCFactory factory = JDBCFactory.newInstance(); +// CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); +// SQLData data = common.select(sbQuery.toString(), nCurrentPageNum, TableStyle.DISP_ROWS_COUNT, TableStyle.DISP_PAGES_COUNT); +// request.setAttribute("RESULT", data); +// } +// +// /** +// * 1. ��� : LU ȣ��Ʈ ��� +// * 2. ó�� ���� : +// * 3. ���ǻ��� +// * +// * @param request HttpServletRequest ��ü +// * @exception Exception +// **/ +// public void insertLUHost(HttpServletRequest request) throws Exception { +// JDBCFactory factory = JDBCFactory.newInstance(); +// LUHostJDBCEx jdbc = null; +// HashMap ludatas = null; +// LUHostDataEx data = null; +// int result = 0; +// +// try { +// jdbc = (LUHostJDBCEx)factory.create(LUHostJDBCEx.class); +// +// ludatas = setParameter(request); +// +// for(int nIndx=0; nIndx"); +// } +// return sbResult.toString(); +// } +// +// /** +// * 1. ��� : �Ķ���� ������ LUInfoData ��ü ���� +// * 2. ó�� ���� : +// * 3. ���ǻ��� +// * +// * @param request HttpServletRequest ��ü +// * @params HashMap LUInfoData ��ü ���� +// **/ +// private HashMap setParameter(HttpServletRequest request) +// { +// HashMap luhostdatas = new HashMap(); // lu ȣ��Ʈ ���� ���� +// int nLUHostCnt = 0; +// +// // 1. �Ķ���� +// String sSNAAdptrSevrName = request.getParameter("SNAADPTRSEVRNAME")==null?"":request.getParameter("SNAADPTRSEVRNAME").trim(); +// String sSNAAdptrSevrIPName = request.getParameter("SNAADPTRSEVRIPNAME")==null?"":request.getParameter("SNAADPTRSEVRIPNAME").trim(); +// String sSNAAdptrSevrCtnt = request.getParameter("SNAADPTRSEVRCTNT")==null?"":request.getParameter("SNAADPTRSEVRCTNT").trim(); +// +// LUHostDataEx data = new LUHostDataEx(); +// +// data.setSNAAdptrSevrName(sSNAAdptrSevrName); +// data.setSNAAdptrSevrIPName(sSNAAdptrSevrIPName); +// data.setSNAAdptrSevrCtnt(sSNAAdptrSevrCtnt); +// +// luhostdatas.put(String.valueOf(nLUHostCnt), data); +// +// return luhostdatas; +// } +// +// +//} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/LUInfoServletEx.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/LUInfoServletEx.java new file mode 100644 index 0000000..9b258fb --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/LUInfoServletEx.java @@ -0,0 +1,546 @@ +//package com.eactive.eai.adapter.wca.servlet; +// +//import java.io.IOException; +//import java.util.HashMap; +//import java.util.Iterator; +//import java.util.StringTokenizer; +//import java.util.Vector; +// +//import javax.servlet.RequestDispatcher; +//import javax.servlet.ServletException; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +// +//import org.apache.log4j.Logger; +// +//import com.eactive.eai.adapter.wca.cfg.LUInfoDataEx; +//import com.eactive.eai.adapter.wca.cfg.LUInfoJDBCEx; +//import com.eactive.eai.adapter.wca.command.UpdateLUInfoEx; +//import com.eactive.eai.adapter.wca.global.WCADefine; +//import com.eactive.eai.adapter.wca.jdbc.CommonJDBC; +//import com.eactive.eai.adapter.wca.jdbc.JDBCException; +//import com.eactive.eai.adapter.wca.jdbc.JDBCFactory; +//import com.eactive.eai.adapter.wca.jdbc.SQLData; +//import com.eactive.eai.adapter.wca.util.MyUtil; +//import com.eactive.eai.adapter.wca.util.SNAAgentUtil; +//import com.eactive.eai.agent.AgentUtil; +//import com.eactive.eai.agent.command.Command; +// +///** +//* 1. 기능 : LU 관리 서블릿 +//* 2. 처리 개요 : +//* 3. 주의사항 +//* +//* @author : +//* @version : +//* @see : +//* @since : +//*/ +//public class LUInfoServletEx extends HttpServlet { +// +// Logger logger = Logger.getLogger(LUInfoServletEx.class); +// +// /** +// * 1. 기능 : GET 데이타 처리 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @param response HttpServletResponse 객체 +// **/ +// public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { +// doPost(request, response); +// } +// +// /** +// * 1. 기능 : POST 데이타 처리 +// * 2. 처리 개요 : TYPE에 따라 함수 분기 +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @param response HttpServletResponse 객체 +// **/ +// public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { +// +// try +// { +// String srType = request.getParameter("TYPE")==null? "":request.getParameter("TYPE").trim(); +// +// if(srType.equals("INSERT")){ +// insertLUInfo(request); +// selectLUInfo(request); +// } +// else if(srType.equals("DELETE")){ +// deleteLUInfo(request); +// selectLUInfo(request); +// } +// else if(srType.equals("UPDATE")){ +// updateLUInfo(request); +// selectLUInfo(request); +// } +// else if(srType.equals("UPDATE_SELECT")){ // update page +// updateSelectLUInfo(request); +// +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_LU_INFO_UPDATE); +// rd.forward(request, response); +// return; +// } +// else if(srType.equals("LIST")){ +// selectLUInfo(request); +// } +// else +// { +// selectLUInfo(request); +// } +// +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_LU_INFO_LIST); +// rd.forward(request, response); +// } +// catch(JDBCException jdbc) +// { +// jdbc.printStackTrace(); +// String sErrorMsg = jdbc.toString(); +// request.setAttribute("errorMessage",sErrorMsg ); +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_ERROR); +// rd.forward(request, response); +// } +// catch(Exception e) +// { +// e.printStackTrace(); +// request.setAttribute("errorMessage", e.toString()); +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_ERROR); +// rd.forward(request, response); +// } +// } +// +// /** +// * 1. 기능 : LU 조회 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @exception JDBCException +// **/ +// private void selectLUInfo(HttpServletRequest request) throws JDBCException { +// StringBuffer sbQuery = new StringBuffer(); +// +// // 20080827 Start +// // 20080527 Start +// // Remote LU 칼럼 Select 추가 +// /* +// sbQuery.append( "select \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\", \"PUName\", \"LUName\", " + +// " \"SndrcvDstcd\", \"SndrcvDstcd\", \"UapplIDName\", \"BkupLUYn\", \"LUInfoRegiHMS\", \"LUAmndHMS\" " + +// " FROM " + TableInfo.T_LU_INFO + +// " WHERE 1=1 "); +// */ +// /* +// sbQuery.append( "select \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\", \"PUName\", \"LUName\", " + +// " \"SndrcvDstcd\", \"SndrcvDstcd\", \"UapplIDName\", \"BkupLUYn\", \"LUInfoRegiHMS\", \"LUAmndHMS\", \"RmtLUYn\" " + +// " FROM " + TableInfoEx.T_LU_INFO + +// " WHERE 1=1 "); +// */ +// // 20080527 End +// sbQuery.append( "select \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\", \"PUName\", \"LUName\", " + +// " \"SndrcvDstcd\", \"SndrcvDstcd\", \"UapplIDName\", \"BkupLUYn\", \"LUInfoRegiHMS\", \"LUAmndHMS\" " + +// " FROM " + TableInfoEx.T_LU_INFO + +// " WHERE 1=1 "); +// // 20080827 End +// +// // 1. page num +// String sCurrentPageNum = request.getParameter("CURRENT_PAGE_NUM"); +// if ( sCurrentPageNum == null || sCurrentPageNum.equals("") ) +// sCurrentPageNum = "1"; +// int nCurrentPageNum = Integer.parseInt(sCurrentPageNum); +// +// String sNodeName = request.getParameter("NODENM")==null?"":request.getParameter("NODENM"); +// String sAdapterGrpName= request.getParameter("ADPTGRPNM")==null?"":request.getParameter("ADPTGRPNM"); +// String sLuGrpName= request.getParameter("LUGRPNM")==null?"":request.getParameter("LUGRPNM"); +// String sRealLuGrpName = SelectBoxData.getInstance().getRealLUGrpName(sAdapterGrpName, sLuGrpName); +// String sUpmuName = request.getParameter("UPMUNAME")==null?"":request.getParameter("UPMUNAME"); +// +// String srSortColumn = request.getParameter("SORT_COLUMN")==null? "": request.getParameter("SORT_COLUMN"); +// String srSortNodeName = request.getParameter("SORT_NODENM")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_NODENM"); +// String srSortAdapterGrpName = request.getParameter("SORT_ADPTGRPNM")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_ADPTGRPNM"); +// String srSortLUGrpName = request.getParameter("SORT_LUGRPNM")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_LUGRPNM"); +// String srSortPUName = request.getParameter("SORT_PUNM")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_PUNM"); +// String srSortLUName = request.getParameter("SORT_LUNM")==null? TableInfoEx.SORT_ASC: request.getParameter("SORT_LUNM"); +// +// srSortNodeName = (srSortNodeName.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// srSortAdapterGrpName = (srSortAdapterGrpName.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// srSortLUGrpName = (srSortLUGrpName.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// srSortPUName = (srSortPUName.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// srSortLUName = (srSortLUName.equals(TableInfoEx.SORT_ASC)==true)?"ASC":"DESC"; +// +// // 2. get parameter and make conf query +// if (!sNodeName.equals(SelectBoxData.ALL_SEARCH) && !sNodeName.equals("")) +// sbQuery.append(" AND \"AdptrGstatSevrName\" = '" + sNodeName + "' " ); +// if (!sAdapterGrpName.equals(SelectBoxData.ALL_SEARCH) && !sAdapterGrpName.equals("")) +// sbQuery.append(" AND \"AdptrGroupName\" = '" + sAdapterGrpName + "' "); +// if (!sLuGrpName.equals(SelectBoxData.ALL_SEARCH) && !sLuGrpName.equals("")) +// { +// // 어댑터 그룹 전체 검색이 아닌경우 +// if (!sAdapterGrpName.equals(SelectBoxData.ALL_SEARCH) && !sAdapterGrpName.equals("")) +// sbQuery.append(" AND \"LUGroupName\" = '" + sRealLuGrpName + "' "); +// else +// sbQuery.append(" AND \"LUGroupName\" LIKE '%" + sLuGrpName + "%' "); +// } +// +// if (!sUpmuName.equals("ALL") && !sUpmuName.equals("")) +// sbQuery.append(" AND \"AdptrGroupName\" LIKE '%" + sUpmuName + "%' "); +// +// if (srSortColumn.equals("SORT_NODENM")) +// sbQuery.append(" ORDER BY \"AdptrGstatSevrName\" " + srSortNodeName); +// else if (srSortColumn.equals("SORT_ADPTGRPNM")) +// sbQuery.append(" ORDER BY \"AdptrGroupName\" " + srSortAdapterGrpName); +// else if (srSortColumn.equals("SORT_LUGRPNM")) +// sbQuery.append(" ORDER BY \"LUGroupName\" " + srSortLUGrpName); +// else if (srSortColumn.equals("SORT_PUNM")) +// sbQuery.append(" ORDER BY \"PUName\" " + srSortPUName); +// else if (srSortColumn.equals("SORT_LUNM")) +// sbQuery.append(" ORDER BY \"LUName\" " + srSortLUName); +// else +// sbQuery.append(" ORDER BY \"AdptrGstatSevrName\", \"AdptrGroupName\", \"LUGroupName\", \"PUName\", \"LUName\" "); +// +// // 3. query execute +// JDBCFactory factory = JDBCFactory.newInstance(); +// CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); +// SQLData data = common.select(sbQuery.toString(), nCurrentPageNum, TableStyle.DISP_ROWS_COUNT, TableStyle.DISP_PAGES_COUNT); +// request.setAttribute("RESULT", data); +// } +// +// /** +// * 1. 기능 : LU 등록 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @exception Exception +// **/ +// public void insertLUInfo(HttpServletRequest request) throws Exception { +// JDBCFactory factory = JDBCFactory.newInstance(); +// LUInfoJDBCEx jdbc = null; +// HashMap ludatas = null; +// LUInfoDataEx data = null; +// int result = 0; +// +// try { +// jdbc = (LUInfoJDBCEx)factory.create(LUInfoJDBCEx.class); +// +// ludatas = setParameter(request); +// for(int nIndx=0; nIndx0) +// throw new WebException("시스템 적용 실패하였습니다.
" + sErrorResult) ; +// } +// +// private String makeErrorString(HashMap result) +// { +// StringBuffer sbResult = new StringBuffer(); +// Iterator it = result.keySet().iterator(); +// String sSvrName = null; +// String sResult = null; +// while(it.hasNext()) { +// sSvrName = (String)it.next(); +// sResult = (String)result.get(sSvrName); +// if (sResult.equals("success")) continue; +// +// sbResult.append(sSvrName + " : " + sResult +"
"); +// } +// return sbResult.toString(); +// } +// +// /** +// * 1. 기능 : 파라미터 정보로 LUInfoData 객체 생성 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @params HashMap LUInfoData 객체 집합 +// **/ +// private HashMap setParameter(HttpServletRequest request) +// { +// +// String ALPABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +// boolean isAlpabet = false; +// HashMap ludatas = new HashMap(); // lu 정보 저장 +// int nFromLUName, nToLUName; +// int nLUInfoCnt = 0; +// int nToLULen = 0; +// +// // 1. 파라미터 +// String sNodeName = request.getParameter("NODENM")==null?"":request.getParameter("NODENM").trim(); +// String sAdptGrpName = request.getParameter("ADPTGRPNM")==null?"":request.getParameter("ADPTGRPNM").trim(); +// String sLUGrpName = request.getParameter("LUGRPNM")==null?"":request.getParameter("LUGRPNM").trim(); +// sLUGrpName = SelectBoxData.getInstance().getRealLUGrpName(sAdptGrpName, sLUGrpName); +// String sPUName = request.getParameter("PUNM")==null?"":request.getParameter("PUNM").trim(); +// String sLUName = request.getParameter("LUNM")==null?"":request.getParameter("LUNM").trim(); +// String sTranMode = request.getParameter("SRECEMODE")==null?"":request.getParameter("SRECEMODE").trim(); +// String sApplyID = request.getParameter("APPLID")==null?"":request.getParameter("APPLID").trim(); +// String sBackupLUYN = request.getParameter("BKUPLUYN")==null?"":request.getParameter("BKUPLUYN").trim(); +// String sFromLUName = request.getParameter("FROM_LUNM")==null?"":request.getParameter("FROM_LUNM").trim(); +// String sToLUName = request.getParameter("TO_LUNM")==null?"":request.getParameter("TO_LUNM").trim(); +// +// String sImmediateApply = request.getParameter("IMMEDIATE_APPLY")==null?"":request.getParameter("IMMEDIATE_APPLY").trim(); +// String sLogUsgYn = request.getParameter("LOGUSGYN")==null?"":request.getParameter("LOGUSGYN").trim(); +// String sLogLevel = request.getParameter("LOGLVL")==null?"":request.getParameter("LOGLVL").trim(); +// String sLogVal = request.getParameter("GRSTLOGFILESIZE")==null?"0":request.getParameter("GRSTLOGFILESIZE").trim(); +// +// // 20080827 Start +// // 20080527 Start +// // String sRmtLUYN = request.getParameter("RMTLUYN")==null?"0":request.getParameter("RMTLUYN").trim(); +// // 20080527 End +// String sRmtLUYN = WCADefine.DEFAULT_REMOTE_LU_NO; +// // 20080827 End +// +// sFromLUName = sFromLUName.toUpperCase(); +// sToLUName = sToLUName.toUpperCase(); +// +// // LU 범위가 설정되어있다면 +// if (!sFromLUName.equals("") && !sToLUName.equals("")) +// { +// String sNewLUName = null; +// +// // 알파벳이면 +// if ((nFromLUName = ALPABET.indexOf(sFromLUName)) != -1){ +// nToLUName = ALPABET.indexOf(sToLUName); +// isAlpabet = true; +// } +// else { +// nFromLUName = Integer.parseInt(sFromLUName); +// nToLUName = Integer.parseInt(sToLUName); +// nToLULen = sToLUName.length(); +// } +// +// for(int nIndx=nFromLUName; nIndx<=nToLUName; nIndx++) +// { +// if(isAlpabet) +// sNewLUName = sLUName + ALPABET.substring(nIndx, nIndx+1); +// else +// sNewLUName = sLUName + MyUtil.leftPadString(String.valueOf(nIndx), nToLULen, "0"); +// +// LUInfoDataEx data = new LUInfoDataEx(); +// +// data.setNodeName(sNodeName); +// data.setAdapterGroupName(sAdptGrpName); +// data.setGroupName(sLUGrpName); +// data.setPUName(sPUName); +// data.setLUName(sNewLUName); +// data.setTranMode(sTranMode); +// data.setApplyID(sApplyID); +// data.setBackupLUYN(sBackupLUYN); +// data.setLogYN(sLogUsgYn); +// data.setLogLevel(sLogLevel); +// data.setLogSize(sLogVal); +// +// // 20080527 Start +// data.setRmtLUYN(sRmtLUYN); +// // 20080527 End +// +// ludatas.put(String.valueOf(nLUInfoCnt), data); +// nLUInfoCnt++; +// } +// } +// else +// { +// LUInfoDataEx data = new LUInfoDataEx(); +// data.setNodeName(sNodeName); +// data.setAdapterGroupName(sAdptGrpName); +// data.setGroupName(sLUGrpName); +// data.setPUName(sPUName); +// data.setLUName(sLUName); +// data.setTranMode(sTranMode); +// data.setApplyID(sApplyID); +// data.setBackupLUYN(sBackupLUYN); +// data.setLogYN(sLogUsgYn); +// data.setLogLevel(sLogLevel); +// data.setLogSize(sLogVal); +// +// // 20080527 Start +// data.setRmtLUYN(sRmtLUYN); +// // 20080527 End +// +// ludatas.put(String.valueOf(nLUInfoCnt), data); +// +// } +// return ludatas; +// } +// +// +//} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/LURegisterServlet.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/LURegisterServlet.java new file mode 100644 index 0000000..e10e969 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/LURegisterServlet.java @@ -0,0 +1,95 @@ +//package com.eactive.eai.adapter.wca.servlet; +// +//import java.io.IOException; +// +//import javax.servlet.RequestDispatcher; +//import javax.servlet.ServletException; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +// +//import com.eactive.eai.adapter.wca.jdbc.CommonJDBC; +//import com.eactive.eai.adapter.wca.jdbc.JDBCException; +//import com.eactive.eai.adapter.wca.jdbc.JDBCFactory; +//import com.eactive.eai.adapter.wca.jdbc.SQLData; +// +///** +//* 1. 기능 : LU 관리 서블릿 +//* 2. 처리 개요 : +//* 3. 주의사항 +//* +//* @author : +//* @version : +//* @see : +//* @since : +//*/ +//public class LURegisterServlet extends HttpServlet { +// +// //Logger logger = Logger.getLogger(LURegisterServlet.class); +// /** +// * 1. 기능 : GET 데이타 처리 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @param response HttpServletResponse 객체 +// **/ +// public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { +// doPost(request, response); +// } +// +// /** +// * 1. 기능 : POST 데이타 처리 +// * 2. 처리 개요 : TYPE에 따라 함수 분기 +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @param response HttpServletResponse 객체 +// **/ +// public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { +// +// try +// { +// selectLURegisterServer(request); +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_LU_REGISTER); +// rd.forward(request, response); +// } +// catch(JDBCException jdbc) +// { +// jdbc.printStackTrace(); +// String sErrorMsg = jdbc.toString(); +// request.setAttribute("errorMessage",sErrorMsg ); +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_ERROR); +// rd.forward(request, response); +// } +// catch(Exception e) +// { +// e.printStackTrace(); +// request.setAttribute("errorMessage", e.toString()); +// RequestDispatcher rd = getServletContext().getRequestDispatcher(PathInfoEx.P_ERROR); +// rd.forward(request, response); +// } +// } +// +// +// /** +// * 1. 기능 : LU 등록 서버 리스트 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param request HttpServletRequest 객체 +// * @exception JDBCException +// **/ +// private void selectLURegisterServer(HttpServletRequest request) throws JDBCException { +// StringBuffer sbQuery = new StringBuffer(); +// sbQuery.append( "select DISTINCT \"EAISevrIP\", \"SevrLsnPortName\", \"HostName\"" + +// " FROM " + TableInfoEx.T_EAI_SVR + +// " WHERE \"EAISevrInstncName\" != '" + SelectBoxData.ALL_SEARCH + "' " + +// " ORDER BY \"HostName\", \"SevrLsnPortName\" "); +// +// JDBCFactory factory = JDBCFactory.newInstance(); +// CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); +// SQLData data = common.select(sbQuery.toString()); +// request.setAttribute("RESULT", data); +// } +//} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/MakeQuery.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/MakeQuery.java new file mode 100644 index 0000000..1cf1b3d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/MakeQuery.java @@ -0,0 +1,76 @@ +//package com.eactive.eai.adapter.wca.servlet; +// +//import java.util.Enumeration; +//import java.util.Vector; +//import javax.servlet.http.HttpServletRequest; +//import org.apache.log4j.Logger; +// +///** +//* 1. 기능 : JSP 에서 체크 박스 여러개 선택한 경우 선택한 데이타를 SQL 로 만든다 +//* 2. 처리 개요 : +//* 3. 주의사항 +//* +//* @author : +//* @version : +//* @see : +//* @since : +//*/ +//public class MakeQuery +//{ +// Logger logger = Logger.getLogger(MakeQuery.class); +// public static final String SQL_GUBUNJA = "SQL_GUBUNJA"; // 조건 검색할 파라미터명 +// public static final String SQL_CNT = "SQL_CNT"; // 조건 검색할 파라미터수 +// +// HttpServletRequest request = null; +// public MakeQuery(HttpServletRequest request) +// { +// this.request = request; +// } +// +// /** +// * 1. 기능 : HttpServletRequest객체에서 선택된 데이타로 조건절 SQL문을 만든다. +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @return 생성된 sql 집합 +// **/ +// public Vector makeExeSql() +// { +// StringBuffer sb_conf_sql = new StringBuffer(); +// Vector vConfQuery = new Vector(); +// +// String sGubunjaName = TableInfoEx.DELETE_RECODE_ID; +// String sParasCnt = request.getParameter(SQL_CNT)==null?"0":(String)request.getParameter(SQL_CNT); +// +// int nParasCnt = Integer.parseInt(sParasCnt); +// +// // 조건 파라미터명이 존재하지 않을 경우 +// if (sGubunjaName.equals("") || nParasCnt == 0) +// { +// logger.debug(SQL_GUBUNJA + "또는 " + SQL_CNT + " 파라미터 존재하지 않습니다"); +// return null; +// } +// +// // SQL_GUBUNJA 파라미터명과 동일한 경우 SQL문을 생성한다. +// Enumeration e_para = request.getParameterNames (); +// String saParas[] = null; +// String sParaName = null; +// String sParaValue = null; +// while ( e_para.hasMoreElements ( ) ) +// { +// sParaName = (String) e_para.nextElement (); +// saParas = request.getParameterValues ( sParaName ); +// +// for ( int i = 0; i < saParas.length ; i++ ) +// { +// sParaValue = (saParas[i]==null)? "": saParas[i]; +// if( (sParaName.length() >= sGubunjaName.length()) && +// (sParaName.substring(0, sGubunjaName.length()).equals(sGubunjaName))) +// { +// vConfQuery.addElement(sParaValue); +// } +// } +// } +// return vConfQuery; +// } +//} diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/PathInfoEx.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/PathInfoEx.java new file mode 100644 index 0000000..c94e3de --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/PathInfoEx.java @@ -0,0 +1,40 @@ +package com.eactive.eai.adapter.wca.servlet; + +/** +* 1. 기능 : JSP 및 서블릿에서 사용되는 경로정보 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ +public class PathInfoEx +{ + public static final String CSS_FILE = "/common/css/common.css"; + public static final String IMAGE_PATH = "/common/image"; + public static final String JS_PATH = "/common/js"; + + // 20080527 Start + public static final String P_LU_HOST_SERVLET = "/LUHostServletEx.do"; + public static final String P_LU_HOST_LIST = "/management/sna/luhost_list_ex.jsp"; + public static final String P_LU_HOST_INSERT = "/management/sna/luhost_insert_ex.jsp"; + public static final String P_LU_HOST_UPDATE = "/management/sna/luhost_update_ex.jsp"; + // 20080527 End + + public static final String P_LU_GROUP_SERVLET = "/LUGroupServletEx.do"; + public static final String P_LU_GROUP_LIST = "/management/sna/lugroup_list_ex.jsp"; + public static final String P_LU_GROUP_INSERT = "/management/sna/lugroup_insert_ex.jsp"; + public static final String P_LU_GROUP_UPDATE = "/management/sna/lugroup_update_ex.jsp"; + + public static final String P_LU_INFO_SERVLET = "/LUInfoServletEx.do"; + public static final String P_LU_INFO_LIST = "/management/sna/luinfo_list_ex.jsp"; + public static final String P_LU_INFO_INSERT = "/management/sna/luinfo_insert_ex.jsp"; + public static final String P_LU_INFO_UPDATE = "/management/sna/luinfo_update_ex.jsp"; + + public static final String P_LU_REGISTER_SERVLET = "/LURegisterServlet.do"; + public static final String P_LU_REGISTER = "/management/sna/lu_register.jsp"; + + public static final String P_ERROR = "/common/errors/errorDisplay.jsp"; +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/SelectBoxData.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/SelectBoxData.java new file mode 100644 index 0000000..9a80d85 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/SelectBoxData.java @@ -0,0 +1,612 @@ +package com.eactive.eai.adapter.wca.servlet; + +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.jdbc.CommonJDBC; +import com.eactive.eai.adapter.wca.jdbc.JDBCFactory; +import com.eactive.eai.adapter.wca.jdbc.SQLData; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import org.apache.log4j.Logger; + +/** +* 1. 기능 : JSP에서 표시될 select box 데이타 생성 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ +public class SelectBoxData extends BaseDAO +{ + Logger logger = Logger.getLogger(SelectBoxData.class); + private static SelectBoxData instance = new SelectBoxData(); + public static String ALL_SEARCH = "ALL"; + public static String LU_GRP_GUBUNJA = "_"; + + /** + * 1. 기능 : Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + private SelectBoxData() + { + } + + /** + * 1. 기능 : SelectBoxData Singleton Object 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return SelectBoxData Singleton object + **/ + public static SelectBoxData getInstance() + { + return instance; + } + + /** + * 1. 기능 : Node Name 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return selectbox script 데이타 (String)반환 + **/ + public String getNodeName(String value) throws DAOException { + StringBuffer sb_query = new StringBuffer(); + StringBuffer sb_result = new StringBuffer(); + + int nRsltCnt ; + String sNodeName = ""; + String sSelected = ""; + + if (value == null) value =""; + try { + // 20080808 Start : SNA Host 참조 테이블 변경 + /* + sb_query.append("SELECT DISTINCT \"HostName\" FROM " + TableInfoEx.T_EAI_SVR + + " WHERE \"HostName\" is not null " + + " ORDER BY \"HostName\""); + */ + sb_query.append("SELECT DISTINCT \"SNAAdptrSevrName\" FROM " + TableInfoEx.T_LU_HOST + + " WHERE \"SNAAdptrSevrName\" is not null " + + " ORDER BY \"SNAAdptrSevrName\""); + // 20080808 End + JDBCFactory factory = JDBCFactory.newInstance(); + CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); + SQLData data = common.select(sb_query.toString()); + nRsltCnt = data.getDispDatasCount(); + + for (int nIndx = 0 ; nIndx < nRsltCnt; nIndx++) + { + // 20080808 Start : SNA Host 참조 테이블 변경 + // sNodeName = data.getSQLStringData("HostName" + nIndx); + sNodeName = data.getSQLStringData("SNAAdptrSevrName" + nIndx); + // 20080808 End + + if (sNodeName.trim().equals("")) continue; + + if (sNodeName.equals(value)) + sSelected = "selected"; + else sSelected =""; + sb_result.append("" ); + } + + return sb_result.toString(); + } catch(Exception e) { + logger.error("getNodeName error", e); + throw new DAOException("SelectBoxData.getNodeName Error. - " + e.getMessage()); + } finally { + this.disconnect(); + } + } + +// public String getBackupNodeName(String value) throws DAOException { +// StringBuffer sb_query = new StringBuffer(); +// StringBuffer sb_result = new StringBuffer(); +// +// int nRsltCnt ; +// String sNodeName = ""; +// String sSelected = ""; +// +// if (value == null) value =""; +// try { +// sb_query.append("SELECT DISTINCT \"EAISevrIP\" FROM " + TableInfoEx.T_EAI_SVR + +// " WHERE \"EAISevrInstncName\" != '" + ALL_SEARCH +"'" + +// " ORDER BY \"EAISevrIP\" "); +// +// JDBCFactory factory = JDBCFactory.newInstance(); +// CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); +// SQLData data = common.select(sb_query.toString()); +// nRsltCnt = data.getDispDatasCount(); +// +// for (int nIndx = 0 ; nIndx < nRsltCnt; nIndx++) +// { +// sNodeName = data.getSQLStringData("EAISevrIP" + nIndx); +// +// sNodeName = getHostNameByIP(sNodeName); +// if (sNodeName != null && sNodeName.equals(value)) +// sSelected = "selected"; +// else sSelected =""; +// sb_result.append("" ); +// } +// +// return sb_result.toString(); +// } catch(Exception e) { +// logger.error("SelectBoxData.getBackupNodeName Error", e); +// throw new DAOException("SelectBoxData.getBackupNodeName Error. - " + e.getMessage()); +// } finally { +// this.disconnect(); +// } +// } + +// public String getHostNameByIP(String sIP) +// { +// try{ +// InetAddress inet1 = null; +// inet1 = InetAddress.getByName(sIP); +// return inet1.getHostName(); +// } +// catch (UnknownHostException host){ +// logger.error("getHostNameByIP error", host); +// return sIP; +// } +// } + + /** + * 1. 기능 : EAI instance 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return selectbox script 데이타 (String)반환 + **/ + public String getEaiSystemName(String value) throws DAOException { + StringBuffer sb_query = new StringBuffer(); + StringBuffer sb_result = new StringBuffer(); + + int nRsltCnt ; + String sEaiSvrName = ""; + String sSelected = ""; + + if (value == null) value =""; + try { + + sb_query.append("SELECT \"EAISevrInstncName\" FROM " + TableInfoEx.T_EAI_SVR + " ORDER BY \"EAISevrInstncName\""); + JDBCFactory factory = JDBCFactory.newInstance(); + CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); + SQLData data = common.select(sb_query.toString()); + + nRsltCnt = data.getDispDatasCount(); + sEaiSvrName = ""; + + for (int nIndx = 0 ; nIndx < nRsltCnt; nIndx++) + { + sEaiSvrName = data.getSQLStringData("EAISevrInstncName" + nIndx); + if (sEaiSvrName.equals(value)) + sSelected = "selected"; + else sSelected =""; + sb_result.append("" ); + } + + return sb_result.toString(); + } catch(Exception e) { + logger.error("SelectBoxData.getEaiSystemName Error. - ", e); + throw new DAOException("SelectBoxData.getEaiSystemName Error. - " + e.getMessage()); + } finally { + this.disconnect(); + } + } + + /** + * 1. 기능 : 업무 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return selectbox script 데이타 (String)반환 + **/ + public String getUpmuName(String value) throws DAOException { + StringBuffer sb_query = new StringBuffer(); + StringBuffer sb_result = new StringBuffer(); + + int nRsltCnt ; + String sUpmuName = ""; + String sSelected = ""; + + if (value == null) value =""; + try { + /* + sb_query.append("SELECT distinct ADPTGRPNAME " + + " FROM "+ + "( " + + " SELECT decode(pos1, 0, \"AdptrBzwkGroupName\", SUBSTR(\"AdptrBzwkGroupName\",pos1+1, pos2-pos1-1)) as ADPTGRPNAME " + + " FROM " + + " (SELECT INSTR(\"AdptrBzwkGroupName\",'_', 1, 1) as pos1, " + + " INSTR(\"AdptrBzwkGroupName\",'_', 1, 2) as pos2, " + + " \"AdptrBzwkGroupName\" from " + TableInfo.T_ADAPTER_GROUP + + " ) "+ + ") ORDER BY ADPTGRPNAME"); + */ + sb_query.append("SELECT distinct ADPTGRPNAME " + + " FROM "+ + "( " + + " SELECT CASE pos1 WHEN 0 THEN \"AdptrBzwkGroupName\" ELSE SUBSTR(\"AdptrBzwkGroupName\",pos1+1, pos2-pos1-1) END as ADPTGRPNAME " + + " FROM " + + " (SELECT LOCATE('_',\"AdptrBzwkGroupName\", 1) as pos1, " + + " LOCATE('_',\"AdptrBzwkGroupName\", LOCATE('_',\"AdptrBzwkGroupName\", 1) + 1) as pos2, " + + " \"AdptrBzwkGroupName\" from " + TableInfoEx.T_ADAPTER_GROUP + + " WHERE \"AdptrCd\" = 'SNA') TMP1 "+ + ") TMP2 ORDER BY ADPTGRPNAME"); + JDBCFactory factory = JDBCFactory.newInstance(); + CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); + SQLData data = common.select(sb_query.toString()); + + nRsltCnt = data.getDispDatasCount(); + sUpmuName = ""; + + for (int nIndx = 0 ; nIndx < nRsltCnt; nIndx++) + { + sUpmuName = data.getSQLStringData("ADPTGRPNAME" + nIndx); + + if (sUpmuName.equals(value)) + sSelected = "selected"; + else sSelected =""; + sb_result.append("" ); + } + + return sb_result.toString(); + } catch(Exception e) { + logger.error("SelectBoxData.getUpmuName Error", e); + throw new DAOException("SelectBoxData.getUpmuName Error. - " + e.getMessage()); + } finally { + this.disconnect(); + } + } + + /** + * 1. 기능 : 어댑터 그룹 이름 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return selectbox script 데이타 (String)반환 + **/ + public String getAdapterGrpName(String value) throws DAOException { + StringBuffer sb_query = new StringBuffer(); + StringBuffer sb_result = new StringBuffer(); + + int nRsltCnt ; + String sAdpaterGrpName = ""; + String sSelected = ""; + + if (value == null) value =""; + try { + sb_query.append("SELECT \"AdptrBzwkGroupName\" FROM " + TableInfoEx.T_ADAPTER_GROUP + " WHERE \"AdptrBzwkGroupName\" LIKE '%SNA%' ORDER BY \"AdptrBzwkGroupName\""); + JDBCFactory factory = JDBCFactory.newInstance(); + CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); + SQLData data = common.select(sb_query.toString()); + + nRsltCnt = data.getDispDatasCount(); + sAdpaterGrpName = ""; + + //sb_result.append("" ); + for (int nIndx = 0 ; nIndx < nRsltCnt; nIndx++) + { + sAdpaterGrpName = data.getSQLStringData("AdptrBzwkGroupName" + nIndx); + if (sAdpaterGrpName.equals(value)) + sSelected = "selected"; + else sSelected =""; + sb_result.append("" ); + } + + return sb_result.toString(); + } catch(Exception e) { + logger.error("SelectBoxData.getAdapterGrpName Error", e); + throw new DAOException("SelectBoxData.getAdapterGrpName Error. - " + e.getMessage()); + } finally { + this.disconnect(); + } + } + + /** + * 1. 기능 : 수동 백업 여부 전환 selectbox 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return selectbox script 데이타 (String)반환 + **/ + public String getBackupAutoCvs(String value) throws WCAException { + StringBuffer sb_result = new StringBuffer(); + String sSelected =""; + String[][] saBackupAutoCvs = {{WCADefine.WCA_AUTO_BACKUP_CVS_MODE_NO, "수동"}, + {WCADefine.WCA_AUTO_BACKUP_CVS_MODE_YES, "자동"} + }; + + if (value == null) value =""; + try { + for (int nIndx = 0 ; nIndx < saBackupAutoCvs.length; nIndx++) + { + if (saBackupAutoCvs[nIndx][0].equals(value)) + sSelected = "selected"; + else sSelected =""; + sb_result.append("" ); + } + return sb_result.toString(); + } catch(Exception e) { + logger.error("SelectBoxData.getBackupAutoCvs Error", e); + WCAException exception = new WCAException(); + exception.setMessage("SelectBoxData.getBackupAutoCvs Error. - " + e.getMessage()); + throw exception; + } + } + + /** + * 1. 기능 : LU 그룹 이름 selectbox 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return selectbox script 데이타 (String)반환 + **/ + public String getLUGrpName(String sNodeName, String sAdpaterGrpName, String value) throws DAOException { + StringBuffer sbQuery = new StringBuffer(); + StringBuffer sbResult = new StringBuffer(); + + int nRsltCnt ; + String sSelected = ""; + String sLUGrpName = ""; + String sDispLUGrpName = ""; + +// HashMap result = new HashMap(); + + if (sNodeName == null) sNodeName = ""; + if (value == null) value =""; + if (sAdpaterGrpName == null) sAdpaterGrpName =""; + + try { + sbQuery.append("SELECT DISTINCT \"LUGroupName\" FROM " + TableInfoEx.T_LU_GROUP + " WHERE 1=1 " ); + + if (!sNodeName.equals("") && !sNodeName.equals("ALL")){ + sbQuery.append(" AND \"AdptrGstatSevrName\" = '" + sNodeName + "' "); + } + if (!sAdpaterGrpName.equals("") && !sAdpaterGrpName.equals("ALL")){ + sbQuery.append(" AND \"AdptrGroupName\" = '" + sAdpaterGrpName + "' "); + } + sbQuery.append(" ORDER BY \"LUGroupName\" "); + + logger.debug(sbQuery.toString()); + + JDBCFactory factory = JDBCFactory.newInstance(); + CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); + SQLData data = common.select(sbQuery.toString()); + nRsltCnt = data.getDispDatasCount(); + + if (nRsltCnt < 0 ) nRsltCnt = 0; + String[] saRslt = new String[nRsltCnt]; + int nRealRsltIndx = 0; + for (int nIndx = 0 ; nIndx < nRsltCnt; nIndx++) + { + sLUGrpName = data.getSQLStringData("LUGroupName" + nIndx); + sDispLUGrpName = getDispLUGrpName(sLUGrpName); + + if (CheckDuplicate(saRslt, sDispLUGrpName, nRealRsltIndx)) + continue; + saRslt[nRealRsltIndx++] = sDispLUGrpName; + + if (sDispLUGrpName.equals(value)) + sSelected = "selected"; + else sSelected =""; + sbResult.append("" ); + } + return sbResult.toString(); + } catch(Exception e) { + logger.error("SelectBoxData.getLUGrpName Error. - ", e); + throw new DAOException("SelectBoxData.getLUGrpName Error. - " + e.getMessage()); + } finally { + this.disconnect(); + } + } + + /** + * 1. 기능 : orgin 배열에서 cnt까지 compare 가 있는지 확인 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param orgin 비교할 배열 + * @param compare 비교 문자 + * @param cnt 비교할 배열의 index + **/ + private boolean CheckDuplicate(String[] orgin, String compare, int cnt) + { + if (compare == null) return false; + for(int nIndx = 0; nIndx < cnt; nIndx++) + { + if (orgin[nIndx].equals(compare)) + return true; + } + return false; + } + + /** + * 1. 기능 : 표시할 LU 그룹 이름 반환 + * 2. 처리 개요 : LU 그룹 이름은 <어댑터 그룹 이름 + _ + 실제 LU 그룹 이름> + * 실제 LU 그룹 이름만 반환 + * 3. 주의사항 + * + * @param sName 전체 LU 그룹 이름 + * @return 표시할 LU 그룹 이름 + **/ + public String getDispLUGrpName(String sName) + { + int iIndx = 0; + if(sName == null) return ""; + if ((iIndx=sName.lastIndexOf(LU_GRP_GUBUNJA)) == -1) + return sName; + + return sName.substring(iIndx + 1); + } + + /** + * 1. 기능 : 전체 LU 그룹 이름 반환 + * 2. 처리 개요 : LU 그룹 이름은 <어댑터 그룹 이름 + _ + 실제 LU 그룹 이름> + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * @param sDispLUGrpName 실제 LU 그룹 이름 + * @return 전체 LU 그룹 이름 + **/ + public String getRealLUGrpName(String sAdapterGrpName, String sDispLUGrpName) + { + return sAdapterGrpName + LU_GRP_GUBUNJA + sDispLUGrpName; + } + + /** + * 1. 기능 : 로그 기록 여부 selectbox 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return selectbox script 데이타 (String)반환 + **/ + public String getLogYN(String value) throws WCAException { + StringBuffer sb_result = new StringBuffer(); + String sSelected =""; + String[][] saLogYN = {{WCADefine.WCA_LOG_YES, "예"}, + {WCADefine.WCA_LOG_NO, "아니오"} + }; + + if (value == null) value =""; + try { + for (int nIndx = 0 ; nIndx < saLogYN.length; nIndx++) + { + if (saLogYN[nIndx][0].equals(value)) + sSelected = "selected"; + else sSelected =""; + sb_result.append("" ); + } + return sb_result.toString(); + } catch(Exception e) { + logger.error("SelectBoxData.getLogYN Error", e); + WCAException exception = new WCAException(); + exception.setMessage("SelectBoxData.getLogYN Error. - " + e.getMessage()); + throw exception; + } + } + + /** + * 1. 기능 : 로그 레벨 selectbox 반환 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @return selectbox script 데이타 (String)반환 + **/ + public String getLogLevel(String value) throws WCAException { + StringBuffer sb_result = new StringBuffer(); + String sSelected =""; + String[][] saLogLevel = {{"DEBUG", "DEBUG"}, + {"INFO", "INFO"}, + {"WARN", "WARN"} + }; + + if (value == null) value =""; + try { + for (int nIndx = 0 ; nIndx < saLogLevel.length; nIndx++) + { + if (saLogLevel[nIndx][0].equals(value)) + sSelected = "selected"; + else sSelected =""; + sb_result.append("" ); + } + + return sb_result.toString(); + } catch(Exception e) { + logger.error("SelectBoxData.getLogLevel Error", e); + WCAException exception = new WCAException(); + exception.setMessage("SelectBoxData.getLogLevel Error. - " + e.getMessage()); + throw exception; + } + } + + + + /** + * LU TranMOde select box + */ + public String getLUGTranMode(String value) throws WCAException { + StringBuffer sb_result = new StringBuffer(); + String sSelected =""; + String[][] saTranMode = WCADefine.LU_TRAN_MODE; + + if (value == null) value =""; + try { + for (int nIndx = 0 ; nIndx < saTranMode.length; nIndx++) + { + if (saTranMode[nIndx][0].equals(value)) + sSelected = "selected"; + else sSelected =""; + sb_result.append("" ); + } + + return sb_result.toString(); + } catch(Exception e) { + logger.error("SelectBoxData.getLUGTranMode Error", e); + WCAException exception = new WCAException(); + exception.setMessage("SelectBoxData.getLUGTranMode Error. - " + e.getMessage()); + throw exception; + } + } + + /** + * Bdackup LU 여부 + */ + public String getBackupLUYN(String value) throws WCAException { + StringBuffer sb_result = new StringBuffer(); + String sSelected =""; + String[][] saBackupLUYN = WCADefine.BACKUP_LU_YN; + + if (value == null) value =""; + try { + for (int nIndx = 0 ; nIndx < saBackupLUYN.length; nIndx++) + { + if (saBackupLUYN[nIndx][0].equals(value)) + sSelected = "selected"; + else sSelected =""; + sb_result.append("" ); + } + + return sb_result.toString(); + } catch(Exception e) { + logger.error("SelectBoxData.getBackupLUYN Error.", e); + WCAException exception = new WCAException(); + exception.setMessage("SelectBoxData.getBackupLUYN Error. - " + e.getMessage()); + throw exception; + } + } + + /* 20080526 Start */ + /** + * Bdackup LU 여부 + */ + public String getRemoteLUYN(String value) throws WCAException { + StringBuffer sb_result = new StringBuffer(); + String sSelected = ""; + String[][] saRemoteLUYN = WCADefine.REMOTE_LU_YN; + + if(value == null) value = ""; + try { + for (int nIndx = 0 ; nIndx < saRemoteLUYN.length; nIndx++) + { + if(saRemoteLUYN[nIndx][0].equals(value)) + sSelected = "selected"; + else + sSelected = ""; + sb_result.append("" ); + } + + return sb_result.toString(); + } catch(Exception e) { + WCAException exception = new WCAException(); + exception.setMessage("SelectBoxData.getBackupLUYN Error. - " + e.getMessage()); + throw exception; + } + } + /* 20080526 End */ +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/TableInfoEx.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/TableInfoEx.java new file mode 100644 index 0000000..fa3ee4f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/TableInfoEx.java @@ -0,0 +1,45 @@ +package com.eactive.eai.adapter.wca.servlet; + +import com.eactive.eai.common.dao.Keys; + +/** +* 1. 기능 : 테이블 정보 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : +* @see : +* @since : +*/ +public class TableInfoEx +{ + // 삭제 레코드 구분자 + public static final String DELETE_RECODE_ID = "DEL"; + public static final String DELETE_RECODE_DELIMETER = ";"; + + // 테이블명 + // 20080527 Start + public static final String T_LU_HOST = "" + Keys.TABLE_OWNER + "TSEAIAD13"; + // 20080527 End + + // 20080612 Start + public static final String T_LU_PROPS = "" + Keys.TABLE_OWNER + "TSEAICM03"; + // 20080612 End + + public static final String T_LU_GROUP = "" + Keys.TABLE_OWNER + "TSEAIAD05"; + public static final String T_LU_INFO = "" + Keys.TABLE_OWNER + "TSEAIAD06"; + public static final String T_ERROR_LOG = "" + Keys.TABLE_OWNER + "TSEAIAD07"; + + public static final String T_ADAPTER_GROUP = "" + Keys.TABLE_OWNER + "TSEAIAD01"; + public static final String T_EAI_SVR = "" + Keys.TABLE_OWNER + "TSEAISY02"; + + // Softlink 프로퍼티 그룹 이름 + public static final String T_SOFTLINK_PROP_GRP_NAME = "SNAAdapter{DEFAULT}"; + public static final String T_SNAADPTER_PROP_GROUP_NAME = "SNAAdapter{DEFAULT}"; + + // sort + public static final String SORT_ASC = "▲"; + public static final String SORT_DESC = "▼"; +} + diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/TableStyle.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/TableStyle.java new file mode 100644 index 0000000..74e732a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/TableStyle.java @@ -0,0 +1,29 @@ +package com.eactive.eai.adapter.wca.servlet; + +/** +* 1. 기능 : 테이블 style 정보 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @see : +* @version : +* @since : +*/ +public class TableStyle +{ + /** + * 한 화면에 보여줄수 있는 데이타수 + */ + public static final int DISP_ROWS_COUNT = 10; + /** + * 한 화면에 보여줄수 있는 페이지수 + */ + public static final int DISP_PAGES_COUNT = 10; + + /** + * 테이블 마우스 over시 style 지정 + */ + public static final String S_TR_MOUSE_OVER = "onmouseover=\"this.style.background='#F6F6F6'\" onmouseout=\"this.style.background='#FFFFFF'\" style=\"cursor:hand\""; + public static final String S_TR_DEFAULT_MOUSE_OVER = "onmouseover=\"this.style.background='#F6F6F6'\" onmouseout=\"this.style.background='#FFFFFF'\""; +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/servlet/WebException.java b/src/main/java/com/eactive/eai/adapter/wca/servlet/WebException.java new file mode 100644 index 0000000..ddc4347 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/servlet/WebException.java @@ -0,0 +1,22 @@ +//package com.eactive.eai.adapter.wca.servlet; +// +///** +//* 1. 기능 : 운영관리 Exception 관리 +//* 2. 처리 개요 : +//* 3. 주의사항 +//* +//* @author : +//* @version : +//* @see : +//* @since : +//*/ +//public class WebException extends Exception +//{ +// public WebException() { +// super(); +// } +// +// public WebException(String msg) { +// super(msg); +// } +//} diff --git a/src/main/java/com/eactive/eai/adapter/wca/test/Virtual.java b/src/main/java/com/eactive/eai/adapter/wca/test/Virtual.java new file mode 100644 index 0000000..8805394 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/test/Virtual.java @@ -0,0 +1,440 @@ +package com.eactive.eai.adapter.wca.test; + +public class Virtual +{ +// commented : 테스트용으로 사용하지 않음 +// +// int nTestCnt = 0; +// int nSndLen; +// byte[] pRcvBuff = null; +// int nMaxTestCnt = 0; +// int nThreadId = 0; +// String sTestCode = null; +// +// public static int nMassSerialNo = 9; +// +// byte[] bWithdraw1 = { +// (byte)0xE3,(byte)0xE7,(byte)0xC1,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF0,(byte)0xF2,(byte)0x40,(byte)0xE3,(byte)0xF7,(byte)0xF2,(byte)0xF4,(byte)0xF7,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF7,(byte)0xE3,(byte)0xF2,(byte)0xE3,(byte)0xC8,(byte)0xF0,(byte)0xF0, +// (byte)0x40,(byte)0x40,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF2,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF4,(byte)0xF5,(byte)0x40,(byte)0x40,(byte)0x80,(byte)0x80,(byte)0x81,(byte)0x80,(byte)0x40,(byte)0x40,(byte)0xF0,(byte)0xC3,(byte)0xF0, +// (byte)0xF0,(byte)0xF0,(byte)0x40,(byte)0x40,(byte)0xF0,(byte)0x40,(byte)0x00,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0xF7,(byte)0xF2,(byte)0xF4,(byte)0xF7,(byte)0x1F,(byte)0xF0,(byte)0xF4,(byte)0xF0, +// (byte)0xF8,(byte)0x1F,(byte)0xF0,(byte)0xF1,(byte)0x1F,(byte)0xF0,(byte)0x1F,(byte)0xF0,(byte)0xF1,(byte)0xF0,(byte)0xF1,(byte)0x1F,(byte)0xF0,(byte)0xF0,(byte)0x1F,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF1, +// (byte)0xF0,(byte)0xF0,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x9D,(byte)0xA1,(byte)0x9D,(byte)0xA1,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F, +// (byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F +// }; +// +// byte[] bWithdraw2 = { +// (byte)0xE3,(byte)0xE7,(byte)0xC1,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF0,(byte)0xF2,(byte)0x40,(byte)0xE3,(byte)0xF7,(byte)0xF2,(byte)0xF4,(byte)0xF7,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF7,(byte)0xE3,(byte)0xF2,(byte)0xE3,(byte)0xC8,(byte)0xF0,(byte)0xF0, +// (byte)0x40,(byte)0x40,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF2,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF4,(byte)0xF5,(byte)0x40,(byte)0x40,(byte)0x80,(byte)0x80,(byte)0x81,(byte)0x80,(byte)0x40,(byte)0x40,(byte)0xF0,(byte)0xC3,(byte)0xF0, +// (byte)0xF5,(byte)0xF1,(byte)0x40,(byte)0x40,(byte)0xF0,(byte)0x40,(byte)0x00,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0xF7,(byte)0xF2,(byte)0xF4,(byte)0xF7,(byte)0x1F,(byte)0xF0,(byte)0xF4,(byte)0xF0, +// (byte)0xF8,(byte)0x1F,(byte)0xF0,(byte)0xF1,(byte)0x1F,(byte)0xF0,(byte)0x1F,(byte)0xF0,(byte)0xF1,(byte)0xF0,(byte)0xF1,(byte)0x1F,(byte)0xF0,(byte)0xF0,(byte)0x1F,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF1, +// (byte)0xF0,(byte)0xF0,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x9D,(byte)0xA1,(byte)0x9D,(byte)0xA1,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F, +// (byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F +// }; +// +// // 대량 거래를 테스트를 하기 위한 데이터 +// /* +// byte[] bSearch1 = { +// (byte)0xE3,(byte)0xE7,(byte)0xC1,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF0,(byte)0xF4,(byte)0x40,(byte)0xE3,(byte)0xF7,(byte)0xF2,(byte)0xF4,(byte)0xF7,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF7,(byte)0xE3,(byte)0xF2,(byte)0xE3,(byte)0xC8,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF6,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF4,(byte)0xF0,(byte)0xF0,(byte)0xF9,(byte)0xF4,(byte)0xF5,(byte)0x40,(byte)0x40,(byte)0x80,(byte)0x80,(byte)0x81,(byte)0x80,(byte)0x40,(byte)0x40,(byte)0xF0,(byte)0xC3,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF0,(byte)0xF0, +// (byte)0xF0,(byte)0xF0,(byte)0x40,(byte)0x40,(byte)0xF0,(byte)0x40,(byte)0x00,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0xF7,(byte)0xF2,(byte)0xF4,(byte)0xF7,(byte)0x1F,(byte)0xF0,(byte)0xF4,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF3,(byte)0xF9, +// (byte)0xF8,(byte)0x1F,(byte)0x1F,(byte)0x1F +// }; +// */ +// byte[] bSearch1 = { +// /* TRAN CODE */ (byte)0xE3,(byte)0xE7,(byte)0xC1,(byte)0xF0,(byte)0xF0,(byte)0xF2,(byte)0xF0,(byte)0xF4, +// /* BLANK */ (byte)0x40, +// /* 단말 매체 */ (byte)0xE3, +// /* 취급점번 */ (byte)0xF9,(byte)0xF2,(byte)0xF2,(byte)0xF9, +// /* 취급지번 */ (byte)0xF0,(byte)0xF0,(byte)0xF0, +// /* 기기번호 */ (byte)0xF8,(byte)0xE3,(byte)0xF4, +// /* TERM CODE */ (byte)0xE3,(byte)0xC8, +// /* Serial No */ (byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF8, /* 테스트 매번 채번 필요 */ +// /* 개설점번 */ (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40, +// /* 개설지번 */ (byte)0xF0,(byte)0xF0,(byte)0xF0, +// /* 업무식별코드 */ (byte)0xF0,(byte)0xF2, +// /* 입력식별코드 */ (byte)0xF4,(byte)0xF0,(byte)0xF0,(byte)0xF9, +// /* OP No */ (byte)0xF4,(byte)0xF5,(byte)0x40,(byte)0x40, +// /* 상황플래그 */ (byte)0x80,(byte)0x80,(byte)0x81,(byte)0x80, +// /* Reserved */ (byte)0x40,(byte)0x40, +// /* PF Key */ (byte)0xF0, +// +// /* ??? */ +// (byte)0xC3,(byte)0xF0,(byte)0xF0,(byte)0xF2,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0, +// (byte)0x40,(byte)0x40,(byte)0xF0,(byte)0x40,(byte)0x00,(byte)0x40,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00, +// (byte)0x00,(byte)0x00, +// +// /* 계좌번호 */ +// (byte)0xF9,(byte)0xF2,(byte)0xF2,(byte)0xF9,(byte)0x1F, +// (byte)0xF0,(byte)0xF1,(byte)0xF1,(byte)0xF4,(byte)0xF1,(byte)0xF1,(byte)0xF6, (byte)0xF5, +// +// /* ??? */ +// (byte)0x1F,(byte)0x1F,(byte)0x1F +// }; +// +// /*비밀번호 : 1004 */ +// byte[] bSearch2 = { +// /* TRAN CODE */ (byte)0xE3,(byte)0xE7,(byte)0xC1,(byte)0xD4,(byte)0xD3,(byte)0xE3,(byte)0xF0,(byte)0xF4, +// /* BLANK */ (byte)0x40, +// /* 단말 매체 */ (byte)0xE3, +// /* 취급점번 */ (byte)0xF9,(byte)0xF2,(byte)0xF2,(byte)0xF9, +// /* 취급지번 */ (byte)0xF0,(byte)0xF0,(byte)0xF0, +// /* 기기번호 */ (byte)0xF8,(byte)0xE3,(byte)0xF4, +// /* TERM CODE */ (byte)0xE3,(byte)0xC8, +// /* Serical No */ (byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF6, /* 테스트 매번 채번 필요 */ +// /* 개설점번 */ (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40, +// /* 개설지번 */ (byte)0xF0,(byte)0xF0,(byte)0xF0, +// /* 업무식별코드 */ (byte)0xF0,(byte)0xF1, +// /* 입력식별코드 */ (byte)0xF4,(byte)0xF0,(byte)0xF0,(byte)0xF9, +// /* OP No */ (byte)0xF4,(byte)0xF5,(byte)0x40,(byte)0x40, +// /* 상황플래그 */ (byte)0x88,(byte)0x80,(byte)0x80,(byte)0x80, +// /* Reserved */ (byte)0x00,(byte)0x01, +// /* PF Key */ (byte)0x40 +// }; +// +// byte[] bDeposit1 = { +// (byte)0xE3,(byte)0xE7,(byte)0xC1,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF0,(byte)0xF1,(byte)0x40,(byte)0xE3,(byte)0xF7,(byte)0xF2,(byte)0xF4,(byte)0xF7,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF7,(byte)0xE3,(byte)0xF2,(byte)0xE3,(byte)0xC8,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF4,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF1,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF4,(byte)0xF5,(byte)0x40,(byte)0x40,(byte)0x80,(byte)0x80,(byte)0x81,(byte)0x80,(byte)0x40,(byte)0x40,(byte)0xF0,(byte)0xC3,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF0,(byte)0xF0, +// (byte)0xF0,(byte)0xF0,(byte)0x40,(byte)0x40,(byte)0xF0,(byte)0x40,(byte)0x00,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40, +// (byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x40,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0x00,(byte)0xF7,(byte)0xF2,(byte)0xF4,(byte)0xF7,(byte)0x1F,(byte)0xF0,(byte)0xF4,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF3,(byte)0xF9, +// (byte)0xF8,(byte)0x1F,(byte)0xF0,(byte)0x1F,(byte)0xF0,(byte)0xF0,(byte)0x1F,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF1,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0xF0,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F, +// (byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x9C,(byte)0x61,(byte)0x9C,(byte)0x61,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F,(byte)0x1F +// }; +// +// // 텔레뱅킹 타행 이체 거래 : 비드 거래용 테스를 하기 위한 데이터 +// String sTelBank = "TBS680224123672210040120041005172233600000001 TEL05100000 EF2005062861382594102740 1004201002028776398 0000000010000"; +// +// public void testMassData() { +// byte[] pHeaderBuff = makeWSAHeader(); +// byte[] pSndBuff = null; +//// byte[] pRcvBuff = null; +// byte[] pSerialNo= null; +// byte[] pCvrtSerialNo = null; +// +// try { +// pSndBuff = new byte[pHeaderBuff.length + bSearch1.length]; +// System.arraycopy(pHeaderBuff, 0, pSndBuff, 0, pHeaderBuff.length); +// System.arraycopy(bSearch1, 0, pSndBuff, WCAHeader.WCA_HEADER_LEN, bSearch1.length); +// +// // 전문 일련 번호 설정 +// nMassSerialNo++; +// pSerialNo = MyUtil.getLenBuff(nMassSerialNo, 4); +// pCvrtSerialNo = CodeCvrt.cvrtKsc2Ebc(pSerialNo); +// System.arraycopy(pCvrtSerialNo, 0, pSndBuff, WCAHeader.WCA_HEADER_LEN + 22, 4); +// +// nSndLen = pSndBuff.length; +// +// ////call +// call(pHeaderBuff, bSearch1); +// +// System.out.println("THREAD(" + nThreadId + ") TRANSACTION(" + nTestCnt + ") END........."); +// +// +// pSndBuff = new byte[pHeaderBuff.length + bSearch2.length]; +// System.arraycopy(pHeaderBuff, 0, pSndBuff, 0, pHeaderBuff.length); +// System.arraycopy(bSearch2, 0, pSndBuff, WCAHeader.WCA_HEADER_LEN, bSearch2.length); +// +// // 전문 일련 번호 설정 +// nMassSerialNo++; +// pSerialNo = MyUtil.getLenBuff(nMassSerialNo, 4); +// pCvrtSerialNo = CodeCvrt.cvrtKsc2Ebc(pSerialNo); +// System.arraycopy(pCvrtSerialNo, 0, pSndBuff, WCAHeader.WCA_HEADER_LEN + 22, 4); +// +// nSndLen = pSndBuff.length; +// +// //pRcvBuff = webSnaAdaptor.sendrecv(myLog, nSndLen, pSndBuff); +// //call(pHeaderBuff, bSearch1); +// +//// System.out.println("THREAD(" + nThreadId + ") TRANSACTION( " + nTestCnt + ") END........."); +// +// } +// catch(Exception e) { +//// System.out.println("testMassData> Error : " + e.toString()); +// } +// } +// public void call(byte[] pHeaderBuff, byte[] pDataBuff) +// { +// try +// { +// ElinkAdapter adapter = null; +// ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); +// adapter = factory.getElinkAdapter(Keys.TYPE_SNA); +// if (adapter == null) +// { +// System.out.println("adapter is null"); +// } +// +// WCAHeader header = new WCAHeader(pHeaderBuff.length, pHeaderBuff); +// +// Properties prop = new Properties(); +// prop.setProperty("TRAN_KEY", header.getKey()); +// prop.setProperty("ADAPTER_GRP_NAME", "OUT_SNA_KESAPOOL_001"); +// //prop.setProperty("ADAPTER_GRP_NAME", "SNAAdapter_HOST_IN"); +// prop.setProperty("ADAPTER_NAME", "SNAAdapter{HOST}"); +// //prop.setProperty("LU_NAME", header.getTSName()); +// prop.setProperty("LU_NAME", ""); +// //prop.setProperty("LU_NAME", "T994471"); +// //prop.setProperty("TRAN_MODE", String.valueOf(header.getMode())); +// prop.setProperty("TRAN_MODE", "R"); +// prop.setProperty("DATA_TYPE", header.getDataType()); +// prop.setProperty("TRAN_TIMEOUT", "5"); +// +// /* +// prop.setProperty("LU_NAME", ""); +// prop.setProperty("TRAN_MODE", "R"); +// prop.setProperty("DATA_TYPE", ""); +// */ +//// byte[] ret = (byte[] )adapter.callService("OUT_SNA_KESAPOOL_001", prop, pDataBuff); +// adapter.callService("OUT_SNA_KESAPOOL_001", prop, pDataBuff); +// } +// catch(Exception e) +// { +//// e.printStackTrace(); +//// System.out.println(e.toString()); +// } +// } +// +// public static final int KMB_CAP_LEN = 50; +// public static final int KMB_USER_HEADER_LEN = 15; +// +// public byte[] makeHostData(String sHostMsg) { +// +// byte[] hostData = null; +// int nIdx = 0; +// +// hostData = new byte[KMB_CAP_LEN + KMB_USER_HEADER_LEN + sHostMsg.length()]; +// +// /* Set CAP */ +// if(sTestCode.equals("SA-P-12")) { // Dedicate LU - 대량 거래 (조회 거래) +// System.arraycopy("TTASKTBE".getBytes(), 0, hostData, 0, 8); nIdx += 8; +// } +// else if(sTestCode.equals("SA-P-16")) { // Dedicate LU - BID (텔레뱅킹 데이터) +// System.arraycopy("TTASKTBE".getBytes(), 0, hostData, 0, 8); nIdx += 8; +// } +// else { +// System.arraycopy("TTASKEA1".getBytes(), 0, hostData, 0, 8); nIdx += 8; +// } +// +// // BLANK +// hostData[nIdx] = 0x20; nIdx++; +// +// // 단말 매체 +// hostData[nIdx] = 'T'; nIdx++; +// +// // 취급 점번 +// System.arraycopy("1706".getBytes(), 0, hostData, nIdx, 4); nIdx += 4; +// +// // 취급지번 +// System.arraycopy("000".getBytes(), 0, hostData, nIdx, 3); nIdx += 3; +// +// // 기기 번호 +// System.arraycopy("2T0".getBytes(), 0, hostData, nIdx, 3); nIdx += 3; +// +// // TERM CODE +// if(sTestCode.equals("SA-P-16")) { // Dedicate LU - BID (텔레뱅킹 데이터) +// System.arraycopy("TB".getBytes(), 0, hostData, nIdx, 2); nIdx += 2; +// } +// else { +// System.arraycopy("EA".getBytes(), 0, hostData, nIdx, 2); nIdx += 2; +// } +// +// // SERIAL NO +// System.arraycopy("0000".getBytes(), 0, hostData, nIdx, 4); nIdx += 4; +// +// // 개설 점번 +// System.arraycopy("0000".getBytes(), 0, hostData, nIdx, 4); nIdx += 4; +// +// // 개설 지점 +// System.arraycopy("000".getBytes(), 0, hostData, nIdx, 3); nIdx += 3; +// +// // 업무 식별 코드 +// if(sTestCode.equals("SA-P-16")) { // Dedicate LU - BID (텔레뱅킹 데이터) +// System.arraycopy("TB".getBytes(), 0, hostData, nIdx, 2); nIdx += 2; +// } +// else { +// System.arraycopy("D0".getBytes(), 0, hostData, nIdx, 2); nIdx += 2; +// } +// +// // 입력 식별 코드 +// System.arraycopy("XKHB".getBytes(), 0, hostData, nIdx, 4); nIdx += 4; +// +// // OPERATOR NO +// System.arraycopy("0099".getBytes(), 0, hostData, nIdx, 4); nIdx += 4; +// +// // 상황 FLAG +// System.arraycopy("0000".getBytes(), 0, hostData, nIdx, 4); nIdx += 4; +// +// // RESERVED +// System.arraycopy("00".getBytes(), 0, hostData, nIdx, 2); nIdx += 2; +// +// // PF KEY +// hostData[nIdx] = 0x20; nIdx++; +// +// /* Set User Header */ +// // BLANK +// hostData[nIdx] = 0x20; nIdx++; +// +// // IBM -> TANDEM RECEIVE LINE +// if(sTestCode.equals("SA-P-16")) { // Dedicate LU - BID (텔레뱅킹 데이터) +// // System.arraycopy("TFOURCE ".getBytes(), 0, hostData, nIdx, 8); nIdx += 8; +// System.arraycopy("TNE1151 ".getBytes(), 0, hostData, nIdx, 8); nIdx += 8; +// } +// else if(sTestCode.equals("SA-P-07")) { // Dedicate LU - BID (텔레뱅킹 데이터) +// System.arraycopy("TFOURCE ".getBytes(), 0, hostData, nIdx, 8); nIdx += 8; +// } +// else { +// System.arraycopy("TRESPON ".getBytes(), 0, hostData, nIdx, 8); nIdx += 8; +// } +// +// // CAP DESTINATION +// System.arraycopy("EA1".getBytes(), 0, hostData, nIdx, 3); nIdx += 3; +// +// // CAP CONVERT CODE +// hostData[nIdx] = 'I'; nIdx++; +// +// // OFFSET CODE +// hostData[nIdx] = '9'; nIdx++; +// +// // BLANK +// hostData[nIdx] = 0x20; nIdx++; +// +// /* Set Data */ +// System.arraycopy(sHostMsg.getBytes(), 0, hostData, nIdx, sHostMsg.length()); nIdx += sHostMsg.length(); +// +// return hostData; +// } +// +// public byte[] makeWSAHeader() { +// +// byte[] pBuff = null; +// int nIdx = 0; +// +// try { +// pBuff = new byte[WCAHeader.WCA_HEADER_LEN]; +// +// // Key Data +// String strUid = new java.rmi.server.UID().toString(); +// System.out.println("Key = " + strUid); +// +// String pKeyStr = MyUtil.rightPadString(strUid, WCAHeader.LEN_TRAN_KEY, " "); +// System.arraycopy(pKeyStr.getBytes(), 0, pBuff, 0, WCAHeader.LEN_TRAN_KEY); +// nIdx += WCAHeader.LEN_TRAN_KEY; +// +// // TS Name +// String sLuName = null; +// +// if(sTestCode.equals("SA-P-6")) { // Pooled LU - Response Mode +// sLuName = ""; +// } +// else if(sTestCode.equals("SA-P-7")) { // Pooled LU - Non Response Mode +// sLuName = ""; +// } +// else if(sTestCode.equals("SA-P-9")) { // Dedicate LU - Reponse Mode +// sLuName = "T922984"; +// } +// else if(sTestCode.equals("SA-P-12")) { // Dedicate LU - 대량 거래 (조회 거래) +// sLuName = "T922984"; +// } +// else if(sTestCode.equals("SA-P-16")) { // Pooled LU - BID (텔레뱅킹 데이터) +// sLuName = ""; +// } +// else { +// sLuName = ""; +// } +// +// // System.arraycopy(" ".getBytes(), 0, pBuff, nIdx, 12); nIdx += 12; +// // System.arraycopy( "TRE1002 ".getBytes(), 0, pBuff, nIdx, 12); nIdx += 12; +// System.arraycopy(sLuName.getBytes(), 0, pBuff, nIdx, sLuName.length()); nIdx += sLuName.length(); +// for(int i = 0; i < (WCAHeader.LEN_LUNAME - sLuName.length()); i++) { +// pBuff[nIdx] = (byte)0x00; +// nIdx++; +// } +// +// if(sTestCode.equals("SA-P-6")) { // Pooled LU - Response Mode +// // Mode +// pBuff[nIdx] = (byte)(WCAHeader.TRAN_MODE_RESPONSE).charAt(0) ; nIdx++; +// } +// else if(sTestCode.equals("SA-P-7")) { // Pooled LU - Non Response Mode +// // Mode +// pBuff[nIdx] = (byte)(WCAHeader.TRAN_MODE_NONRESPONSE).charAt(0); nIdx++; +// } +// else if(sTestCode.equals("SA-P-9")) { // Dedicate LU - Reponse Mode +// // Mode +// pBuff[nIdx] = (byte)(WCAHeader.TRAN_MODE_RESPONSE).charAt(0); nIdx++; +// } +// else if(sTestCode.equals("SA-P-16")) { // Dedicate LU - BID (텔레뱅킹 데이터) +// pBuff[nIdx] = (byte)(WCAHeader.TRAN_MODE_NONRESPONSE).charAt(0); nIdx++; +// } +// else { +// // Mode +// pBuff[nIdx] = (byte)(WCAHeader.TRAN_MODE_RESPONSE).charAt(0); nIdx++; +// } +// +// // Status +// System.arraycopy("ND".getBytes(), 0, pBuff, nIdx, 2); nIdx += 2; +// +// return pBuff; +// } +// catch(Exception e) { +// System.out.println("makeSoftLinkHeader> Error :" + e.toString()); +// return null; +// } +// } +// +// public void testmain(String testCode) +// { +// sTestCode = testCode; +// if(sTestCode.equals("SA-P-12")) { // Dedicate LU - 대량 거래 (조회 거래) +// testMassData(); +// return; +// } +// +// byte[] pHeaderBuff = makeWSAHeader(); +// byte[] pHostDataBuff = null; +// +// if(sTestCode.equals("SA-P-16")) { // Dedicate LU - BID (텔레뱅킹 데이터) +// pHostDataBuff = makeHostData(sTelBank); +// } +// else { +// pHostDataBuff = makeHostData("EA1 LU0 Adaptor"); +// } +// +// byte[] pSndBuff = new byte[pHeaderBuff.length + pHostDataBuff.length]; +// +// //System.arraycopy(pHeaderBuff, 0, pSndBuff, 0, pHeaderBuff.length); +// +// // ASCII -> EBCDIC 코드 변환 +// byte[] pConvertedHostDataBuff = CodeCvrt.cvrtKsc2Ebc(pHostDataBuff); +// +// // HOST CAP의 상황 FLAG 설정 +// pConvertedHostDataBuff[43] = (byte)0x80; +// pConvertedHostDataBuff[44] = (byte)0x80; +// pConvertedHostDataBuff[45] = (byte)0x81; +// pConvertedHostDataBuff[46] = (byte)0x80; +// +// System.arraycopy(pConvertedHostDataBuff, 0, pSndBuff, WCAHeader.WCA_HEADER_LEN, pHostDataBuff.length); +// +// /* +// byte[] pSndBuff = new byte[pHeaderBuff.length + bSearch1.length]; +// System.arraycopy(pHeaderBuff, 0, pSndBuff, 0, pHeaderBuff.length); +// System.arraycopy(bSearch1, 0, pSndBuff, WCAHeader.WCA_HEADER_LEN, bSearch1.length); +// */ +// +// nSndLen = pSndBuff.length; +// +//// System.out.println("handleClient> Send Data, Length = " + nSndLen); +//// System.out.println( MyUtil.printBytes(WCADefine.ASCII_CODE, nSndLen, pSndBuff)); +// +// call(pHeaderBuff, pConvertedHostDataBuff); +// +//// System.out.println("THREAD(" + nThreadId + ") TRANSACTION(" + nTestCnt + ") END........."); +// //System.out.println("Configured Sess Num = " + webSnaAdaptor.getTotalConfiguredSessNum()); +// //System.out.println("Connected Sess Num = " + webSnaAdaptor.getTotalConnectedSessNum()); +// } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/CodeCvrt.java b/src/main/java/com/eactive/eai/adapter/wca/util/CodeCvrt.java new file mode 100644 index 0000000..760a175 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/CodeCvrt.java @@ -0,0 +1,258 @@ +package com.eactive.eai.adapter.wca.util; + + +/** + * 유형 설명을 삽입하십시오. + * 작성 날짜: (2002-03-05 오후 4:16:13) + * @author: Administrator + */ +public class CodeCvrt { + + /** 1 Byte asc2ebc code table */ + static byte ASC2EBC[] = { + // 0x00 - 0x7f + (byte)0x00,(byte)0x01,(byte)0x02,(byte)0x03,(byte)0x37,(byte)0x05,(byte)0x2e,(byte)0x2f,(byte)0x16,(byte)0x09,(byte)0x25,(byte)0x0b,(byte)0x0c,(byte)0x0d,(byte)0x0e,(byte)0x0f, // + (byte)0x10,(byte)0x11,(byte)0x12,(byte)0x13,(byte)0x3c,(byte)0x3d,(byte)0x32,(byte)0x26,(byte)0x18,(byte)0x19,(byte)0x3f,(byte)0x27,(byte)0x1c,(byte)0x1d,(byte)0x1e,(byte)0x1f, // + (byte)0x40,(byte)0x5a,(byte)0x7f,(byte)0x7b,(byte)0x5b,(byte)0x6c,(byte)0x50,(byte)0x7d,(byte)0x4d,(byte)0x5d,(byte)0x5c,(byte)0x4e,(byte)0x6b,(byte)0x60,(byte)0x4b,(byte)0x61, // !"#$%&'()*+,-./ + (byte)0xf0,(byte)0xf1,(byte)0xf2,(byte)0xf3,(byte)0xf4,(byte)0xf5,(byte)0xf6,(byte)0xf7,(byte)0xf8,(byte)0xf9,(byte)0x7a,(byte)0x5e,(byte)0x4c,(byte)0x7e,(byte)0x6e,(byte)0x6f, // 0123456789:;<=>? + (byte)0x7c,(byte)0xc1,(byte)0xc2,(byte)0xc3,(byte)0xc4,(byte)0xc5,(byte)0xc6,(byte)0xc7,(byte)0xc8,(byte)0xc9,(byte)0xd1,(byte)0xd2,(byte)0xd3,(byte)0xd4,(byte)0xd5,(byte)0xd6, // @ABCDEFGHIJKLMNO + (byte)0xd7,(byte)0xd8,(byte)0xd9,(byte)0xe2,(byte)0xe3,(byte)0xe4,(byte)0xe5,(byte)0xe6,(byte)0xe7,(byte)0xe8,(byte)0xe9,(byte)0x70,(byte)0xe0,(byte)0xa0,(byte)0xb0,(byte)0x6d, // PQRSTUVWXYZ[\]^_ + (byte)0x79,(byte)0x81,(byte)0x82,(byte)0x83,(byte)0x84,(byte)0x85,(byte)0x86,(byte)0x87,(byte)0x88,(byte)0x89,(byte)0x91,(byte)0x92,(byte)0x93,(byte)0x94,(byte)0x95,(byte)0x96, // `abcdefghijklmno + (byte)0x97,(byte)0x98,(byte)0x99,(byte)0xa2,(byte)0xa3,(byte)0xa4,(byte)0xa5,(byte)0xa6,(byte)0xa7,(byte)0xa8,(byte)0xa9,(byte)0xc0,(byte)0x6a,(byte)0xd0,(byte)0xa1,(byte)0x07, // pqrstuvwxyz{|}~ + }; + + /** 1 Byte ebc2ksc code table */ + static byte EBC2ASC[] = { + // 0x00 - 0xff + 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x7f,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, //  + 0x10,0x11,0x12,0x13,0x14,0x15,0x08,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f, // + (byte)0x80,0x21,0x22,0x23,0x24,0x0a,0x17,0x1b,0x28,0x29,0x2a,0x2b,0x2c,0x05,0x06,0x07, // ?"#$ ()*+, + 0x30,0x31,0x16,0x33,0x34,0x35,0x36,0x04,0x38,0x39,0x3a,0x3b,0x14,0x15,0x3e,0x1a, // 01 3456 89:; > + 0x20,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5b,0x2e,0x3c,0x28,0x2b,0x7c, // [.<(+| + 0x26,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x21,0x24,0x2a,0x29,0x3b,0x5e, // & !$*);^ + 0x2d,0x2f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7c,0x2c,0x25,0x5f,0x3e,0x3f, // -/ |,%_>? + 0x5b,0x1a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x3a,0x23,0x40,0x27,0x3d,0x22, // [ `:#@'=" + 0x5d,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x00,0x00,0x00,0x00,0x00,0x00, // ]abcdefghi + 0x1a,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,0x70,0x71,0x72,0x00,0x00,0x00,0x00,0x00,0x00, // jklmnopqr + 0x5d,0x7e,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x00,0x00,0x00,0x00,0x00,0x00, // ]~stuvwxyz + 0x5e,0x1a,0x5c,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x00,0x00,0x00,0x1a,0x1a,0x1a, // ^ \ + 0x7b,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, // {ABCDEFGHI + 0x7d,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, // }JKLMNOPQR + 0x5c,0x1a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a, // \ STUVWXYZ + 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x1a,0x1a,0x1a,0x1a,0x1a,(byte)0xff, // 0123456789 ? + }; + + /** + + 이 클래스를 생성할 수 없다. + + CodeConvert.cvtEbc2KSC 나 CodeConvert.cvtKsc2Ebc를 호출한다. + + */ + protected CodeCvrt() + { + } + /** + + EBCDIC 를 KSC로 변환한다. + + EBCDIC 한글은 0x0e, 0x0f로 구분되어 있어야 한다. + + input : 0x0e, EBCDIC 한글 코드, 0x0f + output : KSC 한글 코드 + + @param byte[] codes 변환할 EBCDIC 데이터 + @return byte[] KSC로 변환한 데이터 + + */ + public static byte[] cvrtEbc2Ksc(byte[] codes) + { + byte[] cvt; + int cvtPt; + int i; + + cvt = new byte[(codes.length)]; + cvtPt = 0; + + for(i = 0; i < codes.length; i++) + { + if( codes[i] == 0x0e ) // 한글 부분 : 2 byte conversion + { +// cvt[cvtPt++] = 0x0e; // 0x0e 그대로 변경 유지 + i++; + while( codes[i] != 0x0f ) + { + short h = (short)codes[i++]; + h = (short)(h & 0x00ff); + short l = (short)codes[i++]; + l = (short)(l & 0x00ff); + + if (0x40 <= h && h <= 0xd4 && 0x40 <= l && l <= 0xff) { + int pt = ((h - 0x40) * 192) + (l - 0x40); + int table = pt / 8640; + int t_pt = pt % 8640; + + char cKsc = 0; + + switch( table ) + { + case 0: + cKsc = Ebc2Ksc1.EBC2KSC[t_pt]; + break; + case 1: + cKsc = Ebc2Ksc2.EBC2KSC[t_pt]; + break; + case 2: + cKsc = Ebc2Ksc3.EBC2KSC[t_pt]; + break; + case 3: + cKsc = Ebc2Ksc4.EBC2KSC[t_pt]; + break; + } + + char temp = (char)(cKsc & 0x00FF); // Low Bytes + cvt[cvtPt+1] = (byte)temp; + cKsc = (char)(cKsc >> 8); // High Bytes + temp = (char)(cKsc & 0x00FF); + cvt[cvtPt] = (byte)temp; + cvtPt += 2; + } else { + cvt[cvtPt++] = 0x00; + cvt[cvtPt++] = 0x00; + } + } +// cvt[cvtPt++] = 0x0f; // 0x0f는 그대로 유지, pointer i는 for loop에서 증가 + } + else // 1 byte code conversion + { + short pt = (short)codes[i]; + pt = (short)(pt & 0x00ff); + cvt[cvtPt++] = (byte)EBC2ASC[pt]; + } + } + byte[] toReturn = new byte[cvtPt]; + System.arraycopy(cvt, 0, toReturn, 0, cvtPt); + return toReturn; + } + + public static byte cvrtEbc2Ksc2(byte codes) + { + short pt = (short)codes; + pt = (short)(pt & 0x00ff); + return (byte)EBC2ASC[pt]; + } + + /** + KSC 한글을 EBCDIC 한글로 변환한다. + + EBCDIC 한글은 0x0e로 시작하여 0x0f로 끝난다. + + input : 영문자 + 한글 + output : 영문자 0x0e 한글 0x0f + + @ param byte[] codes EBCDIC 한글로 변환할 KSC 한글 + @ retrun byte[] EBCDIC로 변환된 한글 + + */ + public static byte[] cvrtKsc2Ebc( byte[] codes ) + { + byte[] cvt; + int cvtPt; + int i; + boolean bHan; + + // 최악의 경우 코드가 2배로 늘어난다. + cvt = new byte[2 * codes.length]; + cvtPt = 0; + bHan = false; + + for (i = 0; i < codes.length; i++) + { + short h = (short)codes[i]; + h = (short)(h & 0x00ff); + + if( h >= 0x80 ) // 한글 부분 : 2 byte conversion + { + if (bHan == false) + { + bHan = true; + cvt[cvtPt++] = 0x0e; + } + i++; // 한글일땐 2 번째 Byte 조합 처리 + short l = (short)codes[i]; + l = (short)(l & 0x00ff); + + if (0xa1 <= h && h <= 0xfe && 0xa0 <= l && l <= 0xff) { + int pt = ((h - 0xa1) * 96) + (l - 0xa0); + int table = pt / 4800; + int t_pt = pt % 4800; + + char cEbc = 0; + switch( table ) + { + case 0: + cEbc = Ksc2Ebc1.KSC2EBC[t_pt]; + break; + case 1: + cEbc = Ksc2Ebc2.KSC2EBC[t_pt]; + break; + } + char temp = (char)(cEbc & 0x00FF); // Low Bytes + cvt[cvtPt+1] = (byte)temp; + cEbc = (char)(cEbc >> 8); // High Bytes + temp = (char)(cEbc & 0x00FF); + cvt[cvtPt] = (byte)temp; + cvtPt += 2; + } + else { + cvt[cvtPt++] = 0x00; + cvt[cvtPt++] = 0x00; + } + } + else // 1 byte code conversion + { + if (bHan == true) + { + bHan = false; + cvt[cvtPt++] = 0x0f; + } + cvt[cvtPt++] = (byte)ASC2EBC[h]; + } + } + if (bHan == true) + { + bHan = false; + cvt[cvtPt++] = 0x0f; + } + byte[] toReturn = new byte[cvtPt]; + System.arraycopy(cvt, 0, toReturn, 0, cvtPt); + return toReturn; + } + /** + Test main routine + + */ +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// byte[] test = "안녕 하세요. APT는 810-310입니다.".getBytes(); +// +// // EBCDIC로 바꾼다. +// byte[] result = cvrtKsc2Ebc(test); +// +// for (int i = 0; i < result.length; i++) +// { +// String ebcdic = Integer.toString((char)result[i] & 0x00ff, 16).toUpperCase(); +// +// if (ebcdic.length() == 2) +// System.out.print(ebcdic + " "); +// else +// System.out.print("0" + ebcdic + " "); +// } +// // 다시 한글로 바꾼다. +// byte[] result1 = cvrtEbc2Ksc(result); +// String han = new String(result1); +// } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/DateUtil.java b/src/main/java/com/eactive/eai/adapter/wca/util/DateUtil.java new file mode 100644 index 0000000..02fd676 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/DateUtil.java @@ -0,0 +1,153 @@ +package com.eactive.eai.adapter.wca.util; + +import java.util.Calendar; + +public class DateUtil +{ + private Calendar o_calender; // 카렌다 + public String s_date_sep = "-"; // 날짜구분 + public String s_time_sep = ":"; // 시간구분 + private final String[] DAY = {"일", "월", "화", "수", "목", "금", "토" }; // 요일 + + public DateUtil() + { + o_calender = Calendar.getInstance(); + } + + + /** + * 년도 반환 + * + * @return int 반환된 년도 + */ + public int getYear() + { + return o_calender.get(Calendar.YEAR); + } + + + /** + * 월 반환 + * + * @return int 반환된 월 + */ + public int getMonth() + { + return o_calender.get(Calendar.MONTH)+1; + } + + + /** + * 일 반환 + * + * @return int 반환된 일 + */ + public int getDay() + { + return o_calender.get(Calendar.DATE); + } + + + /** + * 요일 반환 + * + * @return int 반환된 요일 + */ + public String getDayOfWeek() + { + return DAY[o_calender.get(Calendar.DAY_OF_WEEK)-1]; + } + + + /** + * 시 반환 + * + * @return int 반환된 시 + */ + public int getHour() + { + return o_calender.get(Calendar.HOUR_OF_DAY); + } + + + /** + * 분 반환 + * + * @return int 반환된 분 + */ + public int getMinute() + { + return o_calender.get(Calendar.MINUTE); + } + + + /** + * 초 반환 + * + * @return int 반환된 초 + */ + public int getSecond() + { + return o_calender.get(Calendar.SECOND); + } + + /** + * milli초 반환 + * + * @return int 반환된 초 + */ + public int getMilliSecond() + { + return o_calender.get(Calendar.MILLISECOND); + } + + /** + * 년-월-일 반환 + */ + public String getDate() + { + return MyUtil.leftPadString(String.valueOf(getYear()), 2, "0") + + MyUtil.leftPadString(String.valueOf(getMonth()), 2, "0") + + MyUtil.leftPadString(String.valueOf(getDay()), 2, "0") ; + } + + + /** + * 시 분 초 반환 + */ + public String getTime() + { + //return getHour() + s_time_sep + getMinute() + s_time_sep + getSecond(); + return MyUtil.leftPadString(String.valueOf(getHour()), 2, "0") + + MyUtil.leftPadString(String.valueOf(getMinute()), 2, "0") + + MyUtil.leftPadString(String.valueOf(getSecond()), 2, "0") ; + } + + + /** + * 시 분 초 반환 + */ + public String getMilliTime() + { + return MyUtil.leftPadString(String.valueOf(getHour()), 2, "0") + + MyUtil.leftPadString(String.valueOf(getMinute()), 2, "0") + + MyUtil.leftPadString(String.valueOf(getSecond()), 2, "0") + + MyUtil.leftPadString(String.valueOf(getMilliSecond()), 6, "0") ; + } + + /** + * 년-월-일 시:분:초 반환 + * + */ + + public String getDateTime() + { + return getDate() + " " + getTime(); + } + + public String getDateMilliTime() + { + return getDate() + getTime() + MyUtil.leftPadString(String.valueOf(getMilliSecond()), 2, "0").substring(0,2) ; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc1.java b/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc1.java new file mode 100644 index 0000000..ec871a0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc1.java @@ -0,0 +1,595 @@ +package com.eactive.eai.adapter.wca.util; + +public class Ebc2Ksc1 { + protected static char EBC2KSC[] = { + // 0x4040 - 0x40ff + 0xa1a1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,//   + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4140 - 0x41ff + 0x0000,0xa1a2,0xa1a3,0xa1a4,0xa1a5,0xa1a6,0xa1a7,0xa1a8,0xa1a9,0xa1aa,0xa1ab,0xa1ac,0xa3fe,0xa1ae,0xa1af,0xa1b0,// 、。·‥…¨〃­―∥\ ̄‘’“ + 0xa1b1,0xa1b2,0xa1b3,0xa1b4,0xa1b5,0xa1b6,0xa1b7,0xa1b8,0xa1b9,0xa1ba,0xa1bb,0xa1bc,0xa1bd,0xa1be,0xa1bf,0xa1c0,// ”〔〕〈〉《》「」『』【】±×÷ + 0x0000,0x0000,0x0000,0xa1c4,0xa1c5,0xa1c6,0xa1c7,0xa1c8,0xa1c9,0x0000,0xa3de,0xa1cc,0xa1cd,0xa7a2,0xa7a3,0xa7a4,// ∞∴°′″℃ ^£¥㎖㎗ℓ + 0xa7a6,0xa7ae,0xa7af,0xa7b0,0xa7b7,0xa7b8,0xa1d7,0xa1d8,0xa1d9,0xa1da,0xa1db,0xa1dc,0xa1dd,0xa1de,0xa1df,0xa1e0,// ㏄㎜㎝㎞㎎㎏§※☆★○●◎◇◆□ + 0xa1e1,0xa1e2,0xa1e3,0xa1e4,0xa1e5,0xa1e6,0xa1e7,0xa1e8,0xa1e9,0xa1ea,0xa1eb,0xa3db,0xa3dd,0xa1c1,0xa1c2,0xa1c3,// ■△▲▽▼→←↑↓↔〓[]≠≤≥ + 0xa1ca,0xa1ce,0xa1cf,0xa1d0,0xa1d1,0xa1d2,0xa1d3,0xa1d4,0xa1d5,0xa1d6,0xa1ec,0xa1ed,0xa1ee,0xa1ef,0x0000,0x0000,// Å♂♀∠⊥⌒∂∇≡≒≪≫√∽ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4240 - 0x42ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xa1cb,0xa3ae,0xa3bc,0xa3a8,0xa3ab,0xa3fc,// ¢.<(+| + 0xa3a6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xa3a1,0xa3a4,0xa3aa,0xa3a9,0xa3bb,0xa1fe,// & !$*);¬ + 0xa3ad,0xa3af,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xa3ac,0xa3a5,0xa3df,0xa3be,0xa3bf,// -/ ,%_>? + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xa3e0,0xa3ba,0xa3a3,0xa3c0,0xa3a7,0xa3bd,0xa3a2,// `:#@'=" + 0x0000,0xa3e1,0xa3e2,0xa3e3,0xa3e4,0xa3e5,0xa3e6,0xa3e7,0xa3e8,0xa3e9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// abcdefghi + 0x0000,0xa3ea,0xa3eb,0xa3ec,0xa3ed,0xa3ee,0xa3ef,0xa3f0,0xa3f1,0xa3f2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// jklmnopqr + 0x0000,0xa1ad,0xa3f3,0xa3f4,0xa3f5,0xa3f6,0xa3f7,0xa3f8,0xa3f9,0xa3fa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ∼stuvwxyz + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0xa3fb,0xa3c1,0xa3c2,0xa3c3,0xa3c4,0xa3c5,0xa3c6,0xa3c7,0xa3c8,0xa3c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// {ABCDEFGHI + 0xa3fd,0xa3ca,0xa3cb,0xa3cc,0xa3cd,0xa3ce,0xa3cf,0xa3d0,0xa3d1,0xa3d2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// }JKLMNOPQR + 0xa3dc,0x0000,0xa3d3,0xa3d4,0xa3d5,0xa3d6,0xa3d7,0xa3d8,0xa3d9,0xa3da,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ₩ STUVWXYZ + 0xa3b0,0xa3b1,0xa3b2,0xa3b3,0xa3b4,0xa3b5,0xa3b6,0xa3b7,0xa3b8,0xa3b9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 0123456789 + // 0x4340 - 0x43ff + 0x0000,0xa4d5,0xa4d6,0xa4d7,0xa4d8,0xa4d9,0xa4da,0xa4db,0xa4dc,0xa4dd,0xa4de,0xa4df,0xa4e0,0xa4e1,0xa4e2,0xa4e3,// ㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯㅰㅱㅲㅳ + 0xa4e4,0xa4e5,0xa4e6,0xa4e7,0xa4e8,0xa4e9,0xa4ea,0xa4eb,0xa4ec,0xa4ed,0xa4ee,0xa4ef,0xa4f0,0xa4f1,0xa4f2,0xa4f3,// ㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿㆀㆁㆂㆃ + 0xa4f4,0xa4f5,0xa4f6,0xa4f7,0xa4f8,0xa4f9,0xa4fa,0xa4fb,0xa4fc,0xa4fd,0xa4fe,0x0000,0x0000,0x0000,0x0000,0x0000,// ㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4440 - 0x44ff + 0x0000,0xaaa1,0xaaa2,0xaaa3,0xaaa4,0xaaa5,0xaaa6,0xaaa7,0xaaa8,0xaaa9,0xaaaa,0xaaab,0xaaac,0xaaad,0xaaae,0xaaaf,// ぁあぃいぅうぇえぉおかがきぎく + 0xaab0,0xaab1,0xaab2,0xaab3,0xaab4,0xaab5,0xaab6,0xaab7,0xaab8,0xaab9,0xaaba,0xaabb,0xaabc,0xaabd,0xaabe,0xaabf,// ぐけげこごさざしじすずせぜそぞた + 0xaac0,0xaac1,0xaac2,0xaac3,0xaac4,0xaac5,0xaac6,0xaac7,0xaac8,0xaac9,0xaaca,0xaacb,0xaacc,0xaacd,0xaace,0xaacf,// だちぢっつづてでとどなにぬねのは + 0xaad0,0xaad1,0xaad2,0xaad3,0xaad4,0xaad5,0xaad6,0xaad7,0xaad8,0xaad9,0xaada,0xaadb,0xaadc,0xaadd,0xaade,0xaadf,// ばぱひびぴふぶぷへべぺほぼぽまみ + 0xaae0,0xaae1,0xaae2,0xaae3,0xaae4,0xaae5,0xaae6,0xaae7,0xaae8,0xaae9,0xaaea,0xaaeb,0xaaec,0xaaed,0xaaee,0xaaef,// むめもゃやゅゆょよらりるれろゎわ + 0xaaf0,0xaaf1,0xaaf2,0xaaf3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ゐゑをん + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4540 - 0x45ff + 0x0000,0xaba1,0xaba2,0xaba3,0xaba4,0xaba5,0xaba6,0xaba7,0xaba8,0xaba9,0xabaa,0xabab,0xabac,0xabad,0xabae,0xabaf,// ァアィイゥウェエォオカガキギク + 0xabb0,0xabb1,0xabb2,0xabb3,0xabb4,0xabb5,0xabb6,0xabb7,0xabb8,0xabb9,0xabba,0xabbb,0xabbc,0xabbd,0xabbe,0xabbf,// グケゲコゴサザシジスズセゼソゾタ + 0xabc0,0xabc1,0xabc2,0xabc3,0xabc4,0xabc5,0xabc6,0xabc7,0xabc8,0xabc9,0xabca,0xabcb,0xabcc,0xabcd,0xabce,0xabcf,// ダチヂッツヅテデトドナニヌネノハ + 0xabd0,0xabd1,0xabd2,0xabd3,0xabd4,0xabd5,0xabd6,0xabd7,0xabd8,0xabd9,0xabda,0xabdb,0xabdc,0xabdd,0xabde,0xabdf,// バパヒビピフブプヘベペホボポマミ + 0xabe0,0xabe1,0xabe2,0xabe3,0xabe4,0xabe5,0xabe6,0xabe7,0xabe8,0xabe9,0xabea,0xabeb,0xabec,0xabed,0xabee,0xabef,// ムメモャヤュユョヨラリルレロヮワ + 0xabf0,0xabf1,0xabf2,0xabf3,0xabf4,0xabf5,0xabf6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ヰヱヲンヴヵヶ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4640 - 0x46ff + 0x0000,0xa5a1,0xa5a2,0xa5a3,0xa5a4,0xa5a5,0xa5a6,0xa5a7,0xa5a8,0xa5a9,0xa5aa,0x0000,0x0000,0x0000,0x0000,0x0000,// ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹ + 0xa5b0,0xa5b1,0xa5b2,0xa5b3,0xa5b4,0xa5b5,0xa5b6,0xa5b7,0xa5b8,0xa5b9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ + 0x0000,0xa5c1,0xa5c2,0xa5c3,0xa5c4,0xa5c5,0xa5c6,0xa5c7,0xa5c8,0xa5c9,0xa5ca,0xa5cb,0xa5cc,0xa5cd,0xa5ce,0xa5cf,// ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟ + 0xa5d0,0xa5d1,0xa5d2,0xa5d3,0xa5d4,0xa5d5,0xa5d6,0xa5d7,0xa5d8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ΠΡΣΤΥΦΧΨΩ + 0x0000,0xa5e1,0xa5e2,0xa5e3,0xa5e4,0xa5e5,0xa5e6,0xa5e7,0xa5e8,0xa5e9,0xa5ea,0xa5eb,0xa5ec,0xa5ed,0xa5ee,0xa5ef,// αβγδεζηθικλμνξο + 0xa5f0,0xa5f1,0xa5f2,0xa5f3,0xa5f4,0xa5f5,0xa5f6,0xa5f7,0xa5f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// πρστυφχψω + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4740 - 0x47ff + 0x0000,0xa6a1,0xa6a2,0xa6a3,0xa6a4,0xa6a5,0xa6a6,0xa6a7,0xa6a8,0xa6a9,0xa6aa,0xa6ab,0xa6ac,0xa6ad,0xa6ae,0xa6af,// ─│┌┐┘└├┬┤┴┼━┃┏┓ + 0xa6b0,0xa6b1,0xa6b2,0xa6b3,0xa6b4,0xa6b5,0xa6b6,0xa6b7,0xa6b8,0xa6b9,0xa6ba,0xa6bb,0xa6bc,0xa6bd,0xa6be,0xa6bf,// ┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸ + 0xa6c0,0xa6c1,0xa6c2,0xa6c3,0xa6c4,0xa6c5,0xa6c6,0xa6c7,0xa6c8,0xa6c9,0xa6ca,0xa6cb,0xa6cc,0xa6cd,0xa6ce,0xa6cf,// ╂┒┑┚┙┖┕┎┍┞┟┡┢┦┧┩ + 0xa6d0,0xa6d1,0xa6d2,0xa6d3,0xa6d4,0xa6d5,0xa6d6,0xa6d7,0xa6d8,0xa6d9,0xa6da,0xa6db,0xa6dc,0xa6dd,0xa6de,0xa6df,// ┪┭┮┱┲┵┶┹┺┽┾╀╁╃╄╅ + 0xa6e0,0xa6e1,0xa6e2,0xa6e3,0xa6e4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ╆╇╈╉╊ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4840 - 0x48ff + 0x0000,0xa7a1,0xa7a5,0xa7a7,0xa7a8,0xa7a9,0xa7aa,0xa7ab,0xa7ac,0xa7ad,0xa7b1,0xa7b2,0xa7b3,0xa7b4,0xa7b5,0xa7b6,// ㎕㎘㎣㎤㎥㎦㎙㎚㎛㎟㎠㎡㎢㏊㎍ + 0xa7b9,0xa7ba,0xa7bb,0xa7bc,0xa7bd,0xa7be,0xa7bf,0xa7c0,0xa7c1,0xa7c2,0xa7c3,0xa7c4,0xa7c5,0xa7c6,0xa7c7,0xa7c8,// ㏏㎈㎉㏈㎧㎨㎰㎱㎲㎳㎴㎵㎶㎷㎸㎹ + 0xa7c9,0xa7ca,0xa7cb,0xa7cc,0xa7cd,0xa7ce,0xa7cf,0xa7d0,0xa7d1,0xa7d2,0xa7d3,0xa7d4,0xa7d5,0xa7d6,0xa7d7,0xa7d8,// ㎀㎁㎂㎃㎄㎺㎻㎼㎽㎾㎿㎐㎑㎒㎓㎔ + 0xa7d9,0xa7da,0xa7db,0xa7dc,0xa7dd,0xa7de,0xa7df,0xa7e0,0xa7e1,0xa7e2,0xa7e3,0xa7e4,0xa7e5,0xa7e6,0xa7e7,0xa7e8,// Ω㏀㏁㎊㎋㎌㏖㏅㎭㎮㎯㏛㎩㎪㎫㎬ + 0xa7e9,0xa7ea,0xa7eb,0xa7ec,0xa7ed,0xa7ee,0xa7ef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㏝㏐㏓㏃㏉㏜㏆ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4940 - 0x49ff + 0x0000,0xa1f0,0xa1f1,0xa1f2,0xa1f3,0xa1f4,0xa1f5,0xa1f6,0xa1f7,0xa1f8,0xa1f9,0xa1fa,0xa1fb,0xa1fc,0xa1fd,0xa2a1,// ∝∵∫∬∈∋⊆⊇⊂⊃∪∩∧∨⇒ + 0xa2a2,0xa2a3,0xa2a4,0xa2a5,0xa2a6,0xa2a7,0xa2a8,0xa2a9,0xa2aa,0xa2ab,0xa2ac,0xa2ad,0xa2ae,0xa2af,0xa2b0,0xa2b1,// ⇔∀∃´~ˇ˘˝˚˙¸˛¡¿ː∮ + 0xa2b2,0xa2b3,0xa2b4,0xa2b5,0xa2b6,0xa2b7,0xa2b8,0xa2b9,0xa2ba,0xa2bb,0xa2bc,0xa2bd,0xa2be,0xa2bf,0xa2c0,0xa2c1,// ∑∏¤℉‰◁◀▷▶♤♠♡♥♧♣⊙ + 0xa2c2,0xa2c3,0xa2c4,0xa2c5,0xa2c6,0xa2c7,0xa2c8,0xa2c9,0xa2ca,0xa2cb,0xa2cc,0xa2cd,0xa2ce,0xa2cf,0xa2d0,0xa2d1,// ◈▣◐◑▒▤▥▨▧▦▩♨☏☎☜☞ + 0xa2d2,0xa2d3,0xa2d4,0xa2d5,0xa2d6,0xa2d7,0xa2d8,0xa2d9,0xa2da,0xa2db,0xa2dc,0xa2dd,0xa2de,0xa2df,0xa2e0,0xa2e1,// ¶†‡↕↗↙↖↘♭♩♪♬㉿㈜№㏇ + 0xa2e2,0xa2e3,0xa2e4,0xa2e5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ™㏂㏘℡ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4a40 - 0x4aff + 0x0000,0xaca1,0xaca2,0xaca3,0xaca4,0xaca5,0xaca6,0xaca7,0xaca8,0xaca9,0xacaa,0xacab,0xacac,0xacad,0xacae,0xacaf,// АБВГДЕЁЖЗИЙКЛМН + 0xacb0,0xacb1,0xacb2,0xacb3,0xacb4,0xacb5,0xacb6,0xacb7,0xacb8,0xacb9,0xacba,0xacbb,0xacbc,0xacbd,0xacbe,0xacbf,// ОПРСТУФХЦЧШЩЪЫЬЭ + 0xacc0,0xacc1,0xacd1,0xacd2,0xacd3,0xacd4,0xacd5,0xacd6,0xacd7,0xacd8,0xacd9,0xacda,0xacdb,0xacdc,0xacdd,0xacde,// ЮЯабвгдеёжзийклм + 0xacdf,0xace0,0xace1,0xace2,0xace3,0xace4,0xace5,0xace6,0xace7,0xace8,0xace9,0xacea,0xaceb,0xacec,0xaced,0xacee,// нопрстуфхцчшщъыь + 0xacef,0xacf0,0xacf1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// эюя + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4b40 - 0x4bff + 0x0000,0xa8a1,0xa8a2,0xa8a3,0xa8a4,0x0000,0xa8a6,0x0000,0xa8a8,0xa8a9,0xa8aa,0xa8ab,0xa8ac,0xa8ad,0xa8ae,0xa8af,// ÆÐªĦ IJ ĿŁØŒºÞŦŊ + 0x0000,0xa8b1,0xa8b2,0xa8b3,0xa8b4,0xa8b5,0xa8b6,0xa8b7,0xa8b8,0xa8b9,0xa8ba,0xa8bb,0xa8bc,0xa8bd,0xa8be,0xa8bf,// ㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮ + 0xa8c0,0xa8c1,0xa8c2,0xa8c3,0xa8c4,0xa8c5,0xa8c6,0xa8c7,0xa8c8,0xa8c9,0xa8ca,0xa8cb,0xa8cc,0xa8cd,0xa8ce,0xa8cf,// ㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻ⓐⓑⓒ + 0xa8d0,0xa8d1,0xa8d2,0xa8d3,0xa8d4,0xa8d5,0xa8d6,0xa8d7,0xa8d8,0xa8d9,0xa8da,0xa8db,0xa8dc,0xa8dd,0xa8de,0xa8df,// ⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢ + 0xa8e0,0xa8e1,0xa8e2,0xa8e3,0xa8e4,0xa8e5,0xa8e6,0xa8e7,0xa8e8,0xa8e9,0xa8ea,0xa8eb,0xa8ec,0xa8ed,0xa8ee,0xa8ef,// ⓣⓤⓥⓦⓧⓨⓩ①②③④⑤⑥⑦⑧⑨ + 0xa8f0,0xa8f1,0xa8f2,0xa8f3,0xa8f4,0xa8f5,0xa8f6,0xa8f7,0xa8f8,0xa8f9,0xa8fa,0xa8fb,0xa8fc,0xa8fd,0xa8fe,0x0000,// ⑩⑪⑫⑬⑭⑮½⅓⅔¼¾⅛⅜⅝⅞ + 0xa9a1,0xa9a2,0xa9a3,0xa9a4,0xa9a5,0xa9a6,0xa9a7,0xa9a8,0xa9a9,0xa9aa,0xa9ab,0xa9ac,0xa9ad,0xa9ae,0xa9af,0xa9b0,// æđðħıijĸŀłøœßþŧŋʼn + 0xa9b1,0xa9b2,0xa9b3,0xa9b4,0xa9b5,0xa9b6,0xa9b7,0xa9b8,0xa9b9,0xa9ba,0xa9bb,0xa9bc,0xa9bd,0xa9be,0xa9bf,0xa9c0,// ㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎㈏ + 0xa9c1,0xa9c2,0xa9c3,0xa9c4,0xa9c5,0xa9c6,0xa9c7,0xa9c8,0xa9c9,0xa9ca,0xa9cb,0xa9cc,0xa9cd,0xa9ce,0xa9cf,0xa9d0,// ㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛⒜⒝⒞⒟ + 0xa9d1,0xa9d2,0xa9d3,0xa9d4,0xa9d5,0xa9d6,0xa9d7,0xa9d8,0xa9d9,0xa9da,0xa9db,0xa9dc,0xa9dd,0xa9de,0xa9df,0xa9e0,// ⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮⒯ + 0xa9e1,0xa9e2,0xa9e3,0xa9e4,0xa9e5,0xa9e6,0xa9e7,0xa9e8,0xa9e9,0xa9ea,0xa9eb,0xa9ec,0xa9ed,0xa9ee,0xa9ef,0xa9f0,// ⒰⒱⒲⒳⒴⒵⑴⑵⑶⑷⑸⑹⑺⑻⑼⑽ + 0xa9f1,0xa9f2,0xa9f3,0xa9f4,0xa9f5,0xa9f6,0xa9f7,0xa9f8,0xa9f9,0xa9fa,0xa9fb,0xa9fc,0xa9fd,0xa9fe,0x0000,0x0000,// ⑾⑿⒀⒁⒂¹²³⁴ⁿ₁₂₃₄ + // 0x4c40 - 0x4cff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4d40 - 0x4dff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4e40 - 0x4eff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x4f40 - 0x4fff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x5040 - 0x50ff + 0x0000,0xcaa1,0xcaa2,0xcaa3,0xcaa4,0xcaa5,0xcaa6,0xcaa7,0xcaa8,0xcaa9,0xcaaa,0xcaab,0xcaac,0xcaaf,0xcaad,0xcab0,// 伽佳假價加可呵哥嘉嫁家暇柯架歌 + 0xcab3,0xcab4,0xcab5,0xcab6,0xcab7,0xcab8,0xcab9,0xcaba,0xcabb,0xcabc,0xcabd,0xcabe,0xcabf,0xcac0,0x0000,0xcac1,// 稼苛茄街袈訶賈跏軻迦駕刻却各 恪 + 0x0000,0xcac3,0xcac4,0xcac5,0xcac6,0xcac7,0xcac8,0xcaca,0xcacb,0xcacc,0xcacd,0xcace,0xcacf,0xcad0,0xcad1,0xcad2,// 殼珏脚覺角閣刊墾奸姦干幹懇揀杆 + 0xcad5,0xcad6,0xcad7,0xcad9,0xcada,0xcadb,0xcadd,0xcade,0xcadc,0xcadf,0xcae0,0xcae1,0xcae2,0xcae3,0xcae4,0xcae5,// 澗癎看稈竿簡艮艱肝諫間乫喝曷渴碣 + 0xcae6,0xcae8,0x0000,0xcae7,0xcaea,0xcaeb,0xcaec,0xcaed,0xcaee,0xcaef,0xcaf0,0xcaf2,0xcaf3,0xcaf4,0xcaf5,0xcaf6,// 竭褐 葛鞨勘坎堪嵌感憾敢柑橄減甘 + 0xcaf7,0xcaf8,0xcafa,0x0000,0xcafc,0xcafe,0xcba1,0xcba2,0xcba3,0xcba4,0xcba5,0xcba6,0xcbaa,0xcba7,0xcba9,0xcbab,// 疳監紺 鑑龕匣岬甲胛鉀閘岡剛姜崗 + 0xcbac,0xcbad,0xcbae,0xcbaf,0xcbb0,0xcbb2,0xcbb5,0xcbba,0xcbb3,0xcbb7,0xcbb9,0xcbbb,0xcbbc,0xcbbd,0xcbbf,0xcbc0,// 康强彊慷江疆綱襁糠腔薑講鋼降介价 + 0xcbc1,0xcbc2,0xcbc4,0xcbc5,0xcbc6,0xcbc7,0xcbc8,0xcbc9,0xcbca,0xcbcb,0xcbcc,0xcbcd,0xcbce,0xcbcf,0xcbd2,0xcbd4,// 個凱愷愾慨改槪漑疥皆盖箇芥蓋開客 + 0xcbd5,0xcbd6,0xcbd7,0xcbd8,0xcbd9,0xcbdb,0xcbdc,0xcbdd,0xcbde,0xcbdf,0xcbe0,0xcbe2,0xcbe3,0xcbe1,0xcbe5,0xcbe8,// 坑更粳羹醵去居巨拒据據渠炬擧距遽 + 0xcbe7,0x0000,0xcbea,0xcbeb,0xcbec,0xcbed,0xcbee,0xcbef,0xcbf0,0xcbf3,0xcbf4,0xcbf5,0xcbf6,0xcbf7,0xcbf8,0xcbf9,// 車 鋸乾件健巾建愆虔蹇鍵騫乞傑杰 + 0xcbfb,0xcbfc,0xcbfe,0xcca1,0xcca3,0xcca4,0xcca5,0xcca7,0xcca8,0xcca9,0xccaa,0xccab,0xccac,0xccad,0xccaf,0xccb0,// 儉劍檢瞼黔劫怯偈憩揭擊格檄激覡隔 + 0x0000,0xccb1,0xccb7,0xccb2,0xccb3,0xccb4,0xccb5,0xccb6,0xccb8,0xccb9,0xccba,0xccbb,0xccbe,0xccbd,0xccbf,0x0000,// 堅肩牽犬甄絹繭見譴遣鵑潔決結 + // 0x5140 - 0x51ff + 0x0000,0xccc0,0xccc1,0xccc2,0xccc3,0xccc4,0x0000,0xccc5,0xccc7,0xccc8,0xcccb,0xcccd,0xccce,0xcccf,0x0000,0xccd1,// 缺訣兼慊箝 謙鎌京傾勁勍卿 境 + 0xccd2,0xccd3,0xccd4,0xccd9,0x0000,0xccd6,0xccd7,0xccd8,0xccda,0xccdb,0x0000,0xccdc,0xccdd,0x0000,0xccdf,0xcce1,// 庚徑慶暻 擎敬景更梗 涇炅 璟瓊 + 0x0000,0xcce2,0xcce3,0xcce4,0xcce5,0xcce6,0xcce7,0xcce8,0xcce9,0xccea,0xcceb,0xccec,0xcced,0xccee,0xccef,0xccf0,// 痙硬磬竟競絅經耕耿脛莖警輕逕鏡 + 0xccf1,0xccf2,0xccf3,0xccf4,0xccf5,0xccf6,0xccf8,0xccf9,0xccfa,0xccfb,0xccfc,0xccfd,0xccfe,0xcda2,0xcda3,0xcda4,// 頃頸驚鯨係啓契季屆悸戒桂械溪界癸 + 0xcda5,0x0000,0xcda6,0xcda7,0xcda8,0xcda9,0xcdaa,0xcdab,0xcdad,0xcdac,0x0000,0xcdae,0xcdb0,0xcdaf,0xcdb1,0xcdb2,// 磎 稽系繫繼計誡階谿 鷄叩古告呱 + 0xcdb3,0xcdb4,0xcdb5,0xcdb7,0xcdb8,0xcdb9,0xcdba,0xcdbb,0xcdbd,0x0000,0xcdbf,0xcdc0,0xcdc1,0xcdcc,0x0000,0xcdc3,// 固姑孤庫拷攷故敲枯 沽痼皐蠱 稿 + 0xcdc2,0xcdc5,0xcdc6,0xcdc7,0xcdc8,0xcdcb,0xcdcd,0x0000,0xcdce,0xcdcf,0xcdd0,0xcdd1,0xcdd2,0xcdd3,0xcdd4,0xcdd5,// 睾考股膏苦藁袴 誥賈辜錮雇顧高鼓 + 0xcdd6,0xcdd7,0xcdd8,0xcdd9,0xcdda,0xcddb,0xcddc,0xcddd,0xcdde,0xcddf,0xcde0,0xcde1,0xcde2,0xcde3,0xcde5,0xcde7,// 哭斛曲梏穀谷鵠困坤崑昆梱棍滾袞汨 + 0xcde8,0xcde9,0xcdea,0xcdeb,0xcdec,0xcded,0xcdee,0xcdef,0xcdf8,0xcdf1,0xcdf0,0xcdf2,0xcdf3,0xcdf4,0x0000,0x0000,// 滑骨供公共功孔工貢恭恐拱控攻 + 0xcdf6,0x0000,0xcdfb,0xcdfc,0xcdfd,0xcdfe,0xcea1,0xcea2,0x0000,0xcea3,0xcea4,0xcea6,0xcea8,0xcea9,0xceaa,0xceab,// 空 寡戈果瓜科菓 誇課過顆廓槨藿 + 0xceac,0x0000,0xcead,0xceae,0xceaf,0xceb0,0xceb1,0xceb2,0xceb6,0xceb3,0xceb4,0x0000,0xceb7,0xceb8,0xceb9,0xceba,// 郭 串冠官寬慣棺瓘款灌 管罐菅觀 + 0xcebb,0xcebc,0xcebd,0x0000,0xcebe,0xcebf,0xcec0,0xcec1,0xcec3,0xcec4,0xcec5,0xcec6,0xcec7,0xcec8,0xceca,0x0000,// 貫關館 刮恝括适光匡壙廣曠洸狂 + // 0x5240 - 0x52ff + 0x0000,0xcecb,0xcecc,0xcecd,0xcece,0xcecf,0xced0,0xced1,0xced2,0xced3,0xced4,0xced5,0xced6,0xced7,0xced8,0xced9,// 珖筐胱鑛卦掛罫乖傀塊壞怪愧拐槐 + 0xceda,0xcedb,0xcedc,0xcedd,0xcede,0xcedf,0xcee0,0xcee1,0xcee2,0xcee3,0xcee4,0xcee5,0xcee7,0xcee6,0xcee8,0xcee9,// 魁宏紘肱轟交僑咬喬嬌嶠巧敎攪校橋 + 0xceea,0xceeb,0xceec,0xceed,0xceee,0xceef,0xcef0,0xcef1,0xcef2,0xcef3,0xcef4,0x0000,0xcef5,0xcef6,0xcef7,0xcef8,// 狡皎矯絞翹膠蕎蛟較轎郊 餃驕鮫丘 + 0xcef9,0xcefa,0xcefb,0x0000,0xcefc,0x0000,0xcefd,0xcefe,0xcfa1,0xcfa2,0xcfa3,0xcfa4,0xcfa5,0xcfa7,0x0000,0x0000,// 久九仇 俱 具勾區口句咎嘔垢 + 0xcfa8,0xcfa9,0xcfaa,0xcfab,0xcfac,0xcfad,0x0000,0xcfae,0xcfaf,0xcfb0,0xcfb1,0xcfb2,0xcfb3,0xcfb4,0xcfb5,0xcfb6,// 寇嶇廐懼拘救 枸柩構歐毆毬求溝灸 + 0xcfb7,0xcfb8,0xcfb9,0x0000,0xcfba,0xcfbb,0xcfbc,0xcfbd,0xcfc5,0xcfbf,0xcfc0,0xcfc1,0xcfc2,0xcfc3,0x0000,0xcfc4,// 狗玖球 瞿矩究絿購臼舅舊苟衢 謳 + 0xcfc6,0xcfc7,0xcfc8,0xcfc9,0x0000,0xcfcb,0xcfcc,0xcfcd,0xcfce,0xcfcf,0xcfd0,0xcfd1,0x0000,0xcfd2,0xcfd3,0xcfd5,// 軀逑邱鉤 駒驅鳩鷗龜國局 菊鞠麴 + 0xcfd7,0xcfd8,0xcfda,0xcfd6,0xcfdb,0xcfdc,0xcfdd,0xcfde,0xcfdf,0xcfe0,0xcfe1,0xcfe2,0xcfe3,0xcfe5,0xcfe6,0xcfe7,// 窘群軍君郡堀屈掘窟宮弓穹窮躬倦券 + 0xcfe8,0xcfe9,0xcfea,0xcfeb,0xcfed,0xcfef,0xcff0,0xcff3,0xcff4,0xcff5,0xcff6,0xcff7,0xcff8,0x0000,0xcff9,0xcffa,// 勸卷圈拳權眷厥蹶闕机櫃潰詭 軌饋 + 0xcffd,0xcffe,0xd0a1,0xd0a2,0xd0a3,0xd0a4,0xd0a5,0xd0a6,0xd0a8,0xd0a9,0xd0aa,0xd0ad,0xd0ac,0xd0ae,0xd0af,0xd0b0,// 歸貴鬼龜叫圭奎揆珪硅窺葵糾規赳逵 + 0xd0b1,0xd0b3,0xd0b5,0xd0b6,0xd0b7,0xd0b8,0xd0b9,0xd0ba,0xd0bb,0xd0bc,0xd0bd,0xd0bf,0xd0be,0xd0c0,0xd0c1,0xd0c3,// 閨均筠菌鈞龜橘克剋劇戟極棘隙僅勤 + 0x0000,0xd0c4,0xd0c5,0xd0c6,0xd0c7,0x0000,0xd0c8,0xd0c9,0xd0ca,0xd0cb,0xd0cc,0xd0cd,0xd0ce,0xd0cf,0xd0d0,0x0000,// 懃斤根槿 瑾筋芹菫覲謹近饉契 + // 0x5340 - 0x53ff + 0x0000,0xd0d1,0xd0d3,0xd0d5,0xd0d6,0xd0d7,0xd0d8,0xd0db,0xd0da,0xd0dc,0xd0dd,0xd0de,0xd0e0,0x0000,0xd0e1,0xd0e2,// 今擒檎琴禁禽衿衾襟金錦及 急扱 + 0xd0e3,0x0000,0xd0e4,0xd0e5,0xd0e6,0xd0e7,0xd0e8,0xd0e9,0xd0ea,0xd0eb,0xd0ec,0xd0ed,0xd0ee,0xd0ef,0xd0f0,0xd0f1,// 汲 級給亘兢矜肯企伎其冀嗜器圻基 + 0xd0f3,0xd0f4,0xd0f5,0xd0f6,0xd0f7,0xd1c2,0xd0f8,0xd0fa,0xd0f9,0xd0fb,0xd0fc,0xd0fd,0xd0fe,0xd1a2,0xd1a3,0xd1a4,// 夔奇妓寄岐豈崎幾己忌技旗旣期杞棋 + 0xd1a5,0xd1a6,0xd1a7,0xd1a8,0xd1a9,0xd1aa,0xd1ab,0xd1ad,0xd1ae,0xd1b0,0xd1b1,0xd1b2,0xd1b3,0xd1b4,0xd1b6,0xd1b7,// 棄機欺氣汽沂淇琦琪璣畸畿碁磯祇祈 + 0xd1b8,0xd1b9,0xd1ba,0xd1bb,0x0000,0xd1bd,0xd1be,0xd1bf,0xd1a1,0xd1c0,0xd1c1,0xd1c3,0xd1c4,0xd1c6,0xd1c7,0xd1c8,// 祺箕紀綺 耆耭肌朞記譏起錡飢饑騎 + 0xd1c9,0xd1ca,0x0000,0xd1cb,0xd1cc,0xd1cd,0xd1ce,0xd1cf,0xd1d0,0xd1d1,0x0000,0xd1d2,0xd1d3,0xd1d7,0xd1d9,0xd1da,// 騏驥 麒緊佶吉拮桔金 喫儺懦拏拿 + 0x0000,0xd1e1,0xd1e7,0xd1ec,0xd1ee,0xd1f1,0xd1f4,0xd1f3,0xd1f5,0x0000,0xd1fb,0xd2a1,0xd2a5,0xd2a6,0x0000,0xd2ac,// 那諾暖煖難捺捏南 男納囊娘 乃 + 0xd2ae,0xd2af,0xd2b0,0xd2b1,0x0000,0xd2b3,0xd2b4,0xd2b6,0xd2b7,0xd2b8,0xd2b9,0xd2ba,0x0000,0xd2bb,0x0000,0xd2bd,// 內奈柰耐 女年秊念恬拈捻 寧 努 + 0xd2bf,0x0000,0xd2c0,0xd2c1,0xd2c5,0xd2d8,0xd2db,0xd2dc,0xd2dd,0xd2e0,0xd2e3,0x0000,0xd2ec,0xd2ed,0xd2ef,0xd2f6,// 奴 弩怒瑙濃膿農惱腦尿 嫩訥紐能 + 0xd2f9,0xd2fa,0xd2fb,0xd2fc,0xd2fd,0xd2fe,0xd3a1,0xd3a3,0xd3a4,0xd3a5,0xd3a6,0xd3a8,0xd3a9,0xd3aa,0xd3ab,0xd3ac,// 尼泥匿溺多茶丹但單團壇斷旦檀段湍 + 0xd3ad,0xd3ae,0xd3af,0xd3b0,0xd3b1,0xd3b2,0xd3b3,0xd3b4,0x0000,0x0000,0xd3b5,0xd3b7,0xd3b8,0xd3b9,0x0000,0x0000,// 短端簞緞蛋袒鄲鍛 撻獺疸達 + 0xd3ba,0xd3bd,0xd3be,0xd3bf,0xd3c1,0xd3c2,0xd3c3,0xd3c4,0xd3c5,0xd3c7,0xd3c8,0xd3c9,0xd3cb,0xd3cd,0xd3ce,0x0000,// 啖擔曇淡潭澹痰聃膽覃談譚沓答踏 + // 0x5440 - 0x54ff + 0x0000,0xd3cf,0x0000,0xd3d1,0xd3d2,0xd3d3,0xd3d0,0xd3d5,0xd3d6,0xd3d7,0xd3d8,0x0000,0xd3da,0xd3db,0xd3dc,0xd3de,// 遝 堂塘幢唐撞棠當糖 黨代垈大 + 0xd3df,0xd3e0,0xd3e1,0xd3e2,0xd3e3,0xd3e4,0xd3e5,0x0000,0xd3e6,0xd3e7,0xd3e8,0xd3e9,0xd3ea,0xd3eb,0xd3ec,0xd3ed,// 對岱帶待戴擡玳 臺袋貸隊黛宅德悳 + 0xd3ee,0xd3ef,0xd3f0,0xd3f1,0xd3f2,0xd3f3,0xd3f4,0xd3f5,0xd3f6,0xd3f8,0xd3f9,0xd3fa,0xd3fb,0xd3fd,0xd3fe,0xd4a1,// 倒刀到圖堵塗導屠島度徒悼挑搗桃棹 + 0xd4a3,0xd4a4,0xd4a5,0xd4a6,0xd4a7,0xd4a8,0xd4a9,0xd4aa,0xd4ab,0xd4ac,0x0000,0xd4ae,0xd4af,0xd4b0,0xd4b1,0xd4b2,// 淘渡滔濤燾盜睹禱稻萄 賭跳蹈逃途 + 0xd4b3,0xd4b4,0xd4b5,0xd4b6,0xd4b7,0xd4b8,0xd4b9,0xd4ba,0xd4bb,0xd4bc,0xd4bd,0xd4be,0xd4bf,0xd4c0,0xd4c1,0xd4c2,// 道都鍍陶韜毒瀆牘犢獨督禿篤纛讀墩 + 0xd4c3,0xd4c4,0xd4c6,0xd4c7,0xd4c9,0xd4ca,0xd4cb,0x0000,0xd4cc,0xd4cd,0xd4ce,0xd4cf,0xd4d0,0xd4d1,0xd4d2,0x0000,// 惇敦暾沌燉豚頓 乭突仝冬凍動同 + 0xd4d3,0xd4d4,0xd4d5,0xd4d6,0xd4d7,0xd4d8,0xd4db,0xd4d9,0xd4da,0xd4dd,0xd4dc,0xd4de,0xd4df,0xd4e0,0xd4e1,0xd4e2,// 憧東桐棟洞潼童疼瞳董胴銅兜斗杜枓 + 0xd4e3,0xd4e4,0xd4e5,0x0000,0x0000,0xd4e6,0xd4e7,0xd4e9,0xd4ea,0xd4eb,0xd4ed,0xd4ee,0xd4ef,0xd4f0,0xd4f2,0x0000,// 痘竇荳 讀豆頭屯臀遁遯鈍得橙 + 0x0000,0xd4f3,0xd4f4,0xd4f5,0xd4f6,0xd4f7,0xd4f8,0x0000,0xd4f9,0xd4fa,0xd4fb,0xd4fd,0xd4fe,0xd5a1,0xd5a2,0xd5a3,// 燈登等藤謄鄧 騰喇懶癩羅蘿螺裸 + 0xd5a4,0xd5a5,0xd5a6,0xd5a7,0x0000,0xd5a8,0xd5a9,0xd5aa,0xd5ac,0xd5ad,0xd5af,0xd5b0,0x0000,0xd5b1,0xd5b2,0xd5b3,// 邏樂洛烙 珞絡落酪駱亂卵 欄欒瀾 + 0xd5b4,0xd5b5,0xd5b6,0xd5b7,0x0000,0xd5b8,0xd5b9,0xd5ba,0xd5bb,0xd5bc,0xd5bd,0xd5be,0xd5bf,0xd5c0,0xd5c1,0xd5c2,// 爛蘭鸞剌 辣嵐擥攬欖濫籃纜藍襤覽 + 0xd5c3,0xd5c4,0xd5c5,0xd5c6,0xd5c7,0x0000,0xd5c8,0xd5c9,0xd5ca,0xd5cb,0xd5cc,0xd5cd,0xd5ce,0xd5d1,0xd5d2,0x0000,// 拉臘蠟廊朗 浪狼琅瑯螂郞來萊冷 + // 0x5540 - 0x55ff + 0x0000,0xd5d3,0xd5d4,0xd5d5,0xd5d7,0xd5d6,0xd5d8,0xd5d9,0x0000,0xd5da,0xd5db,0xd5dc,0xd5dd,0xd5de,0xd5df,0xd5e0,// 掠略亮兩倆凉梁 樑粮粱糧良諒輛 + 0xd5e1,0x0000,0xd5e2,0xd5e4,0xd5e5,0xd5e6,0xd5e8,0xd5e9,0xd5ea,0xd5eb,0x0000,0xd5ec,0x0000,0xd5ed,0xd5e7,0xd5ee,// 量 侶勵呂廬戾旅櫚濾 礪 藜慮蠣 + 0x0000,0x0000,0xd5ef,0xd5f0,0xd5f1,0xd5f2,0xd5f3,0xd5f4,0xd5f6,0xd5f5,0x0000,0xd5f7,0xd5f8,0xd5f9,0xd5fa,0xd5fb,// 閭驢驪麗黎力歷曆 瀝礫轢靂憐 + 0xd5fc,0xd5fd,0xd5fe,0xd6a1,0xd6a3,0xd6a4,0xd6a5,0xd6a6,0xd6a7,0xd6a8,0xd6a9,0xd6ab,0xd6aa,0xd6ac,0xd6ad,0xd6ae,// 戀攣漣煉練聯蓮輦連鍊冽劣列洌烈裂 + 0xd6af,0xd6b0,0xd6b1,0xd6b2,0xd6b3,0xd6b4,0x0000,0xd6b5,0xd6b6,0xd6b7,0xd6ba,0xd6bb,0x0000,0x0000,0xd6bc,0xd6be,// 廉斂殮濂簾獵 令伶囹嶺怜 玲羚 + 0xd6bf,0x0000,0x0000,0xd6c1,0xd6c3,0xd6c4,0xd6c2,0xd6c5,0xd6c6,0xd6c7,0xd6c9,0xd6ca,0xd6cb,0xd6cc,0xd6ce,0xd6d0,// 翎 逞零靈鈴領齡例禮醴隷勞撈櫓 + 0x0000,0xd6d3,0xd6d2,0xd6d4,0xd6d5,0x0000,0xd6d6,0xd6d7,0xd6d8,0xd6d9,0x0000,0xd6da,0xd6db,0xd6dc,0xd6dd,0x0000,// 爐瀘盧老 蘆虜路輅 露魯鷺鹵 + 0xd6de,0x0000,0xd6e0,0x0000,0xd6e2,0xd6e4,0xd6e3,0xd6e5,0xd6e6,0xd6e7,0xd6e8,0xd6e9,0xd6ea,0xd6eb,0xd6ec,0xd6ed,// 碌 綠 錄麓鹿論壟弄朧瀧瓏籠聾儡 + 0xd6ef,0xd6f0,0x0000,0x0000,0x0000,0xd6f3,0xd6f1,0xd6f4,0xd6f5,0xd6f6,0x0000,0xd6f7,0xd6f8,0xd6fa,0xd6fb,0xd6fc,// 牢磊 賴賂雷了僚 寮廖燎療瞭 + 0xd6f9,0xd6fd,0xd6fe,0xd7a1,0xd7a3,0x0000,0xd7a4,0xd7a6,0xd7a7,0xd7a8,0xd7a9,0xd7ab,0xd7ac,0xd7ae,0xd7b0,0x0000,// 料聊蓼遼龍 壘屢樓淚漏累縷褸陋 + 0xd7b1,0xd7b3,0xd7b4,0xd7b5,0xd7b6,0xd7b8,0xd7b9,0xd7ba,0xd7bb,0xd7bc,0xd7bd,0xd7be,0xd7bf,0xd7c0,0xd7c1,0xd7c3,// 劉柳榴流溜琉瑠留瘤硫謬類六戮陸倫 + 0xd7c4,0xd7c5,0xd7c6,0xd7c7,0xd7c8,0xd7c9,0xd7ca,0xd7cb,0x0000,0xd7cc,0xd7ce,0xd7cd,0x0000,0x0000,0xd7d0,0x0000,// 崙淪綸輪律慄栗率 隆肋勒 凌 + // 0x5640 - 0x56ff + 0x0000,0xd7d1,0xd7d2,0xd7d3,0xd7d4,0xd7d5,0xd7d6,0xd7d7,0xd7d8,0xd7d9,0xd7db,0xd7dc,0x0000,0xd7dd,0xd7de,0x0000,// 楞稜綾菱陵俚利厘吏履悧 李梨 + 0xd7e0,0xd7e1,0xd7e2,0xd7e3,0xd7e5,0x0000,0xd7e7,0xd7e6,0x0000,0xd7ea,0xd7ec,0xd7ed,0xd7ee,0x0000,0xd7ef,0xd7f0,// 犁狸理璃痢 罹籬 裏里釐離 鯉吝 + 0xd7f2,0xd7f3,0xd7f4,0xd7f5,0xd7f6,0xd7f7,0xd7f8,0xd7f9,0xd7fa,0xd7fb,0x0000,0xd7fc,0xd7fd,0x0000,0xd7fe,0xd8a1,// 燐璘藺躪隣鱗麟林淋琳 臨霖 砬立 + 0xd8a2,0xd8a3,0x0000,0xd8a4,0xd8a5,0xd8a6,0xd8a8,0x0000,0xd8a9,0xd8aa,0xd8ab,0xd8ac,0xd8ad,0xd8ae,0xd8af,0xd8b0,// 笠粒 摩瑪痲磨 馬魔麻寞幕漠膜莫 + 0xd8b4,0xd8b5,0xd8b6,0xd8b7,0xd8b8,0xd8b9,0xd8ba,0xd8bb,0xd8bc,0xd8bd,0xd8be,0xd8bf,0xd8c0,0xd8c1,0x0000,0xd8c2,// 娩巒彎慢挽晩曼滿漫灣瞞萬蔓蠻 輓 + 0x0000,0xd8c3,0x0000,0xd8c4,0xd8c6,0xd8c7,0xd8c8,0xd8ca,0xd8cb,0xd8cc,0xd8cd,0xd8ce,0xd8cf,0xd8d0,0xd8d1,0xd8d2,// 饅 鰻抹末沫襪靺亡妄忘忙望網罔 + 0xd8d3,0xd8d4,0xd8d5,0xd8d7,0x0000,0xd8d8,0xd8d9,0xd8da,0xd8db,0xd8dc,0xd8dd,0xd8de,0xd8df,0xd8e0,0x0000,0xd8e1,// 芒茫莽邙 埋妹媒寐昧枚梅每煤 罵 + 0x0000,0xd8e2,0xd8e3,0xd8e4,0xd8e5,0xd8e6,0x0000,0xd8e7,0xd8e8,0xd8e9,0xd8ea,0xd8eb,0xd8ec,0xd8ed,0xd8ef,0xd8ee,// 買賣邁魅脈 貊陌驀麥孟氓猛盟盲 + 0xd8f0,0xd8f1,0xd8f2,0x0000,0xd8f3,0xd8f5,0xd8f4,0xd8f6,0xd8f8,0xd8f9,0xd8fa,0xd8fb,0xd8fc,0xd8fd,0xd8fe,0xd9a1,// 萌冪覓 免勉冕棉眄眠綿緬面麵滅蔑 + 0xd9a4,0xd9a2,0xd9a3,0xd9b0,0xd9a5,0xd9a6,0xd9a8,0xd9a9,0xd9ab,0xd9ad,0xd9ae,0xd9af,0xd9b1,0xd9b2,0xd9b4,0xd9b6,// 命冥名鳴明暝溟皿茗螟酩銘袂侮募帽 + 0xd9b5,0xd9b7,0xd9b8,0xd9ba,0xd9b3,0xd9bb,0xd9bc,0xd9bd,0xd9be,0xd9bf,0xd9c0,0xd9c2,0xd9c3,0x0000,0xd9c4,0xd9c6,// 姆慕摸暮冒某模母毛牟牡眸矛 耗茅 + 0xd9c7,0xd9c8,0xd9c9,0x0000,0xd9ca,0xd9cb,0xd9cc,0xd9cd,0xd9ce,0xd9cf,0xd9d1,0xd9d2,0xd9d3,0xd9d4,0x0000,0x0000,// 謀謨貌 木沐牧目睦穆歿沒夢朦 + // 0x5740 - 0x57ff + 0x0000,0x0000,0xd9d5,0xd9d6,0xd9d7,0xd9d8,0xd9d9,0xd9da,0xd9db,0xd9dc,0xd9dd,0xd9de,0xd9e0,0xd9e1,0xd9e2,0xd9e3,// 蒙卯墓妙廟描昴杳渺猫苗錨務巫 + 0xd9e5,0xd9e6,0xd9e7,0xd9e8,0xd9e9,0xd9eb,0xd9ec,0xd9ed,0xd9ef,0xd9f0,0xd9f1,0xd9f2,0xd9f3,0xd9f4,0xd9f5,0xd9f6,// 懋戊拇撫无武毋無畝繆舞茂蕪誣貿霧 + 0xd9f7,0xd9f8,0xd9f9,0xd9fb,0xd9fc,0xd9fe,0xdaa1,0xdaa3,0xdaa2,0xdaa5,0xdaa6,0xd9fd,0xdaa4,0xdaa8,0xdaaa,0xdaab,// 鵡墨默刎吻文汶紋紊蚊門問聞勿物味 + 0xdaac,0xdaad,0xdaae,0xdabc,0xdaaf,0xdab0,0xdab1,0xdab4,0x0000,0xdab6,0xdab7,0x0000,0xdab8,0xdab9,0xdaba,0xdabb,// 媚尾嵋靡彌微未渼 眉米 美薇謎迷 + 0xdabf,0xdac0,0xdac1,0xdac2,0xdac4,0xdac3,0xdac5,0xdac6,0xdac7,0xdac8,0xdaca,0x0000,0xdacb,0xdacc,0xdacd,0x0000,// 悶愍憫敏旼旻民泯玟珉閔 密蜜謐 + 0xdace,0xdacf,0xdad0,0xdad1,0xdad2,0xdad3,0xdad4,0x0000,0xdad5,0x0000,0xdad6,0xdad7,0xdad8,0xdada,0xdad9,0xdadb,// 剝博拍搏撲朴樸 泊 珀璞箔縛粕膊 + 0xdadc,0xdadd,0xdade,0xdadf,0xdae0,0xdae1,0xdae2,0xdae3,0xdae4,0xdae5,0xdae6,0xdae7,0xdae8,0xdae9,0xdaeb,0xdaea,// 舶薄迫雹駁伴半反叛拌搬攀斑槃潘泮 + 0xdaec,0xdaed,0xdaef,0xdaf2,0xdaf3,0xdaf4,0x0000,0xdaf6,0xdaf5,0xdaf7,0xdaf8,0xdaf9,0xdafa,0xdafb,0xdafe,0xdafc,// 班畔盤磻礬絆 蟠般返頒飯勃拔潑撥 + 0xdba1,0xdba2,0xdba3,0xdba4,0xdba5,0xdba6,0xdba7,0xdba8,0xdba9,0xdbaa,0xdbab,0xdbac,0xdbad,0xdbae,0xdbaf,0xdbb0,// 發跋醱鉢髮魃倣傍坊妨尨幇彷房放方 + 0xdbb1,0xdbb2,0xdbb4,0xdbb7,0xdbb8,0xdbb9,0xdbba,0xdbbb,0xdbbc,0xdbbd,0xdbbe,0xdbbf,0xdbc0,0xdbc1,0x0000,0x0000,// 旁昉榜紡肪膀舫芳蒡蚌訪謗邦防 + 0xdbc2,0xdbc4,0xdbc3,0xdbc5,0xdbc6,0xdbc7,0xdbc8,0xdbc9,0xdbca,0xdbcb,0xdbcd,0xdbcf,0xdbce,0xdbd1,0xdbd0,0xdbd2,// 龐俳倍北培徘拜排杯湃盃胚背裵裴褙 + 0xdbd3,0xdbd4,0xdbd5,0xdbd6,0xdbd7,0xdbd8,0xdbd9,0xdbda,0xdbdb,0xdbdc,0xdbdd,0xdbde,0xdbe0,0x0000,0xdbe1,0x0000,// 賠輩配陪伯佰帛柏栢白百魄樊 煩 + // 0x5840 - 0x58ff + 0x0000,0xdbe3,0xdbe4,0xdbe5,0x0000,0xdbe6,0xdbe7,0xdbe8,0xdbe9,0xdbea,0xdbeb,0xdbec,0xdbed,0xdbee,0xdbef,0xdbf0,// 番磻繁 蕃藩飜伐筏罰閥凡帆梵氾 + 0xdbf1,0xdbf2,0xdbf3,0xdbf4,0xdbf5,0xdbf6,0xdbf7,0xdbf8,0xdbf9,0xdbfa,0xdbfb,0xdbfd,0xdbfe,0xdca1,0x0000,0xdca3,// 汎泛犯範范法琺僻劈壁擘璧癖碧 闢 + 0xdca4,0xdca5,0xdca6,0xdca7,0x0000,0x0000,0xdca8,0xdca9,0xdcaa,0x0000,0xdcab,0x0000,0xdcac,0x0000,0xdcad,0xdcae,// 霹便卞弁 變辨辯 邊 別 瞥鱉 + 0xdcaf,0xdcb0,0xdcb1,0xdcb2,0xdcb3,0xdcb4,0xdcb5,0xdcb6,0xdcb7,0xdcb9,0xdcba,0xdcbb,0xdcbd,0xdcbc,0xdcbe,0x0000,// 鼈丙倂兵屛幷昞昺柄炳甁病竝秉輧 + 0xdcbf,0xdcc1,0xdcc2,0xdcc3,0xdcc4,0xdcc5,0xdcc6,0xdcc8,0xdcc7,0xdcc9,0xdccb,0xdccd,0xdcce,0xdccf,0xdcd0,0x0000,// 餠保堡報寶普步湺洑潽甫補褓譜輔 + 0x0000,0xdcd1,0xdcd2,0xdcd3,0xdcd4,0xdcd5,0xdcd6,0xdcd8,0xdcd7,0xdcd9,0xdcda,0xdcdb,0xdcdd,0x0000,0xdcdc,0xdcdf,// 伏僕匐卜宓復福服腹茯蔔覆 複輻 + 0xdce0,0xdce1,0xdce2,0xdce3,0x0000,0xdce4,0xdce5,0xdce6,0xdce8,0xdce7,0xdce9,0xdced,0xdcea,0xdceb,0xdcee,0x0000,// 馥鰒本乶 俸奉封峰峯捧琫棒烽縫 + 0xdcef,0xdcf0,0xdcf1,0xdcf2,0xdcf3,0x0000,0xdcf5,0xdcf7,0xdcf8,0xdcf9,0xdcfa,0xdcfc,0xdcfd,0xdcfe,0xdda2,0xdda3,// 蓬蜂逢鋒鳳 付傅剖副否埠夫婦孵富 + 0xdda4,0xdda5,0xdda6,0xdda7,0xdda8,0xdda9,0xddaa,0xddab,0xddad,0xddae,0xddac,0x0000,0xddb0,0xddaf,0xddb1,0xddb3,// 府復扶敷斧浮溥父簿缶符 腑腐膚芙 + 0x0000,0x0000,0xddb5,0xddb6,0xddb7,0xddb8,0xddb9,0xddba,0xddbb,0xddbc,0xddbd,0xddbe,0x0000,0xddbf,0x0000,0xddc0,// 訃負賦賻赴趺部釜阜附 駙 鳧 + 0xddc1,0xddc2,0xddc4,0x0000,0xddc5,0xddc6,0xddc7,0xddc8,0xddc9,0xddca,0xddcc,0xddcd,0xddce,0xddcf,0xddd0,0xddd1,// 北分噴 墳奔奮忿憤扮汾焚盆粉糞紛 + 0xddd2,0x0000,0xddd4,0xddd5,0xddd6,0x0000,0xddd7,0xddd9,0x0000,0x0000,0xddda,0xdddb,0xdddc,0xdddd,0xddde,0x0000,// 芬 雰不佛 弗拂 崩朋棚硼繃 + // 0x5940 - 0x59ff + 0x0000,0xdddf,0xdde0,0xdde1,0xdde2,0xdde3,0xdde4,0xdde5,0x0000,0xdde6,0xdde7,0xdde8,0xdde9,0xddea,0xddeb,0xddec,// 鵬丕備匕匪卑妃 婢庇悲憊扉批斐 + 0x0000,0xddee,0x0000,0xddf4,0xddf3,0xddef,0xddf2,0xddf5,0xddf6,0x0000,0xddf7,0xddf8,0xddfa,0x0000,0xddfc,0xddfd,// 榧 泌沸比毘琵痺 砒碑秘 緋翡 + 0xddfe,0x0000,0xdea1,0xdea2,0xdea3,0xdea4,0xdea5,0xdea6,0xdea7,0xdea8,0x0000,0xdea9,0xdeaa,0xdeab,0x0000,0xdeac,// 肥 脾臂菲蜚裨誹譬費 鄙非飛 鼻 + 0xdeae,0xdeb9,0xdeaf,0x0000,0xdeb0,0xdeb1,0xdeb2,0xdeb4,0xdeb5,0xdeb6,0x0000,0xdeb8,0x0000,0xdeba,0x0000,0x0000,// 嬪賓彬 斌檳殯濱瀕牝 貧 頻 + 0xdebb,0xdebc,0xdebd,0xdebe,0xdebf,0xdec0,0xdec1,0xdec2,0xdec4,0xdec3,0xdeec,0xdec5,0xdec7,0xdec8,0xdec9,0xdecc,// 憑氷聘騁乍事些仕似伺舍使僿史司四 + 0xdeca,0xdecb,0xdecd,0xdece,0x0000,0xdecf,0xded0,0xded1,0xded3,0xded4,0x0000,0xded5,0xded6,0xded7,0xdef5,0xded9,// 唆嗣士奢 娑寫寺巳師 徙思捨赦斯 + 0xded8,0xdedb,0xdedc,0x0000,0x0000,0xdede,0xdedf,0xdee0,0xdee1,0xdef7,0xdee2,0xdee5,0xdee4,0xdee6,0xdedd,0xdee3,// 斜査梭 沙泗渣瀉邪獅祀社祠死砂 + 0xdee7,0x0000,0xdee8,0xdeee,0xdee9,0xdeea,0xdeed,0xdeef,0xdef0,0xdef1,0xdef2,0xdef3,0xdef4,0xded2,0xdef6,0xdeeb,// 私 篩蓑紗絲莎蛇裟詐詞謝賜射辭肆 + 0xdef8,0xdef9,0xdefb,0xdefc,0x0000,0xdefd,0xdefe,0x0000,0xdfa1,0xdfa2,0xdfa3,0xdfa4,0xdfa5,0xdfa6,0xdfa7,0xdfa8,// 飼駟削數 朔索 傘刪山散汕珊産疝 + 0xdfa9,0xdfaa,0xdfab,0xdfae,0xdfaf,0xdfad,0xdfb1,0xdfb2,0xdfb3,0xdfb4,0xdfb5,0xdfb6,0xdfb9,0xdfb7,0xdfb8,0x0000,// 算蒜酸撒殺乷薩三參杉森渗衫芟蔘 + 0xdfba,0xdfbb,0xdfbd,0x0000,0x0000,0xdfbe,0xdfbf,0xdfc0,0xdfc1,0xdfc2,0xdfc3,0xdfc4,0xdfd0,0xdfc5,0xdfc6,0xdfc9,// 揷澁颯 上傷像償商喪嘗爽孀尙床 + 0xdfca,0xdfcb,0xdfc8,0xdfcc,0xdfd3,0xdfcd,0xdfce,0x0000,0xdfcf,0xdfd2,0xdfd1,0xdfd4,0xdfd5,0xdfd6,0xdfd7,0x0000,// 庠廂常想相桑橡 湘狀牀祥箱翔裳 + // 0x5a40 - 0x5aff + 0x0000,0xdfd8,0xdfda,0xdfdb,0xdfd9,0xdfdc,0xdfdd,0xdfde,0xdfdf,0x0000,0xdfe1,0xdfe2,0xdfe3,0xdfe4,0xdfe5,0xdfe6,// 觴象賞詳霜塞璽賽 塞穡索色牲生 + 0xdfe7,0xdfe8,0xdfe9,0x0000,0xdfeb,0xdfea,0x0000,0xdff9,0xdfec,0xdfed,0xdfee,0xdfef,0xdff0,0xdff1,0xdff3,0xdff4,// 甥省笙 壻墅 犀嶼序庶徐恕抒敍暑 + 0xdff5,0xdff6,0xdff7,0xdff8,0xdffa,0xdffc,0xdffd,0xdffe,0xe0a1,0xe0a2,0xe0a3,0xe0a4,0xe0a5,0xe0a7,0xe0a6,0xe0a8,// 曙書栖棲瑞絮緖署胥舒薯西誓鋤逝黍 + 0x0000,0xe0a9,0xe0aa,0xe0ab,0x0000,0xe0ac,0xe0ad,0xe0ae,0xe0af,0xe0b0,0xe0b1,0xe0b2,0xe0b3,0xe0b4,0xe0b5,0xe0b6,// 鼠夕奭 席惜昔晳析汐淅潟石碩蓆 + 0xe0b7,0xe0b8,0xe0bb,0xe0b9,0xe0ba,0x0000,0xe0bc,0xe0be,0x0000,0x0000,0xe0bf,0xe0c1,0x0000,0xe0c3,0x0000,0xe0c9,// 釋錫先仙僊 善宣 扇旋 煽 禪 + 0xe0c5,0xe0c6,0xe0c7,0xe0c8,0xe0ca,0xe0cb,0xe0cc,0xe0cd,0xe0ce,0xe0cf,0xe0d0,0xe0d1,0xe0d2,0xe0d3,0xe0d4,0xe0d5,// 瑄璇璿癬線繕羨腺膳船蘚蟬詵跣選銑 + 0x0000,0xe0d8,0x0000,0xe0d9,0xe0df,0x0000,0xe0da,0x0000,0xe0db,0xe0dd,0xe0de,0xe0e0,0xe0e2,0xe0e3,0xe0e4,0xe0e8,// 鮮 卨舌 屑 楔洩渫薛設說雪殲 + 0xe0e9,0xe0ea,0xe0eb,0xe0e7,0xe0ec,0xe0f0,0xe0ee,0xe0ef,0xe0f1,0xe0f2,0xe0f3,0xe0f5,0xe0f6,0xe0f7,0xe0f8,0xe0f9,// 纖蟾贍暹閃燮攝涉葉城姓性惺成星晟 + 0xe0fa,0xe0fc,0xe0fd,0xe0fe,0xe1a1,0xe1a2,0xe1a3,0xe1a4,0xe1a5,0xe1a6,0xe1a7,0xe1a8,0xe1a9,0xe1aa,0xe1ab,0xe1ac,// 猩盛省筬聖聲腥誠醒世勢歲洗稅笹細 + 0xe1ad,0xe1ae,0xe1af,0xe1b0,0xe1b1,0xe1b3,0xe1b4,0xe1b2,0xe1b5,0xe1b7,0xe1b8,0xe1b6,0xe1b9,0xe1ba,0xe1bb,0xe1bc,// 說貰召嘯塑小少宵巢掃搔所昭梳沼消 + 0xe1bd,0xe1be,0xe1bf,0xe1c0,0xe1c1,0xe1c3,0xe1c2,0xe1c5,0xe1c7,0xe1c8,0xe1c9,0x0000,0xe1ca,0xe1cb,0xe1cc,0xe1cd,// 溯瀟炤燒甦疎疏笑簫素紹 蔬蕭蘇訴 + 0xe1ce,0xe1cf,0xe1d0,0xe1d1,0x0000,0xe1d2,0xe1d3,0xe1d4,0xe1d5,0xe1d6,0xe1d8,0xe1d9,0xe1dc,0xe1dd,0xe1df,0x0000,// 逍遡邵銷 韶騷俗屬束粟續速孫損 + // 0x5b40 - 0x5bff + 0x0000,0xe1e1,0xe1e3,0x0000,0xe1e4,0xe1e6,0xe1e8,0xe1e9,0xe1ea,0xe1eb,0xe1ec,0xe1ed,0xe1ee,0x0000,0xe1ef,0xe1f0,// 遜率 宋松訟誦送頌刷殺灑 碎鎖 + 0xe1f1,0xe1f2,0xe1f3,0xe1f4,0x0000,0xe1f6,0xe1f5,0xe1f7,0xe1f8,0xe1f9,0xe1fa,0x0000,0xe1fb,0xe1fd,0xe2a1,0xe1fe,// 衰釗修受 囚嗽垂壽嫂守 岫帥戍愁 + 0xe2a2,0xe2a3,0xe2a4,0xe2a5,0xe2a6,0x0000,0xe2a7,0xe2a8,0xe2ac,0xe2a9,0xe2aa,0x0000,0xe2ab,0xe2ad,0xe2ae,0x0000,// 手授搜收數 樹殊燧水洙 漱狩獸 + 0xe2b1,0xe2b2,0x0000,0xe2b3,0xe2b4,0xe2b5,0xe2b6,0xe2b7,0xe2b8,0xe2b9,0xe2ba,0xe2bb,0xe2bc,0xe2bd,0xe2be,0xe2bf,// 瘦睡 秀穗竪粹綏綬繡羞脩茱蒐蓚藪 + 0xe2c0,0xe2c1,0xe2c3,0xe2c4,0xe2c5,0xe2c6,0xe2c7,0xe2c8,0xe2c9,0xe2cb,0xe2cc,0xe2cd,0xe2ce,0xe2cf,0xe2d0,0xe2d1,// 袖誰輸遂邃酬銖銹隋隨雖需須首髓鬚 + 0xe2d2,0xe2d3,0xe2d4,0xe2d5,0xe2d6,0xe2d7,0xe2d9,0xe2dc,0xe2dd,0xe2e0,0xe2e1,0xe2e2,0xe2e4,0xe2e6,0xe2e7,0xe2e8,// 叔塾夙孰宿淑熟肅菽循恂旬楯殉洵淳 + 0xe2e9,0xe2ea,0xe2eb,0xe2ec,0xe2ed,0xe2ee,0xe2ef,0xe2f0,0xe2f3,0xe2de,0xe2f5,0xe2f6,0xe2f7,0xe2f8,0x0000,0xe2f9,// 珣盾瞬筍純脣舜荀詢巡醇錞順馴 戌 + 0xe2fa,0xe2fb,0xe2fd,0xe2fe,0xe3a1,0xe3a2,0xe3a3,0x0000,0xe3a4,0xe3a6,0xe3a5,0xe3a7,0xe3a8,0xe3a9,0xe3aa,0xe3ab,// 術述崇崧嵩瑟膝 蝨拾濕習褶襲丞乘 + 0xe3ac,0xe3ae,0xe3af,0xe3b0,0xe3ad,0xe3b1,0xe3b2,0xe3b3,0xe3b4,0xe3b5,0x0000,0xe3b6,0xe3b7,0xe3b8,0x0000,0xe3b9,// 僧升承昇勝繩蠅陞侍匙 嘶始媤 尸 + 0xe3bb,0xe3bc,0xe3bd,0xe3be,0xe3bf,0xe3c0,0xe3c1,0xe3c2,0xe3c3,0xe3c4,0xe3c5,0xe3c6,0xe3ca,0x0000,0xe3c7,0xe3c8,// 屍市弑恃施是時枾柴猜矢示視 翅蒔 + 0xe3c9,0xe3cc,0xe3cb,0xe3cd,0xe3cf,0xe3d0,0xe3d1,0xe3d2,0xe3d3,0xe3d4,0xe3d5,0xe3d6,0xe3d7,0xe3d8,0xe3db,0xe3dc,// 蓍詩試諡豺埴寔式息拭植殖湜熄識軾 + 0xe3dd,0xe3de,0xe3df,0xe3e1,0xe3e2,0xe3e3,0xe3e4,0xe3e5,0xe3e6,0xe3e7,0xe3e8,0xe3e9,0x0000,0xe3ea,0xe3eb,0x0000,// 食飾伸信呻娠宸愼新晨燼申 神紳 + // 0x5c40 - 0x5cff + 0x0000,0xe3ec,0xe3ed,0xe3ee,0xe3ef,0xe3f1,0xe3f2,0xe3f3,0xe3f4,0xe3f5,0xe3f6,0xe3f7,0xe3f8,0xe3f9,0xe3fa,0x0000,// 腎臣莘薪蜃訊身辛辰迅失室實悉 + 0xe3fb,0xe3fc,0xe3fd,0xe4a1,0xe3fe,0xe4a2,0xe4a3,0xe4a4,0xe4a5,0xe4a7,0xe4a8,0xe4a9,0xe4aa,0xe4ab,0xe4ac,0xe4ad,// 審尋心沈沁深瀋甚芯什十拾雙氏亞俄 + 0xe4ae,0xe4b0,0xe4b1,0xe4b2,0xe4b3,0xe4b4,0xe4b6,0xe4b7,0xe4b8,0xe4b9,0xe4ba,0xe4bb,0xe4bc,0xe4bd,0xe4be,0xe4bf,// 兒娥峨我牙芽蛾衙訝阿雅餓鴉鵝堊岳 + 0xe4c0,0xe4c3,0xe4c2,0xe4c4,0xe4c5,0xe4c6,0x0000,0xe4c9,0xe4cb,0xe4cc,0xe4cd,0xe4ce,0xe4cf,0xe4d0,0xe4d1,0xe4d2,// 嶽愕惡握樂渥 顎齷安岸按晏案眼雁 + 0x0000,0xe4d3,0xe4d4,0x0000,0x0000,0xe4d6,0xe4d7,0xe4d8,0x0000,0xe4d9,0x0000,0xe4dc,0xe4dd,0xe4de,0xe4df,0xe4e0,// 鞍顔 斡謁軋 閼 巖庵暗癌菴 + 0x0000,0xe4e1,0x0000,0xe4e2,0xe4e3,0xe4e4,0xe4e5,0xe4e6,0xe4e7,0xe4e8,0xe4e9,0xe4ea,0xe4eb,0x0000,0xe4ec,0xe4ed,// 闇 壓押狎鴨仰央怏昻殃秧 鴦厓 + 0xe4ef,0xe4f0,0xe4f1,0x0000,0xe4f3,0x0000,0xe4f2,0xe4f4,0x0000,0xe4f5,0xe4ee,0xe4f6,0xe4f7,0x0000,0xe4f8,0xe4fa,// 埃崖愛 涯 曖碍 艾哀隘靄 厄掖 + 0xe4fb,0xe4fd,0x0000,0xe4fe,0xe5a1,0xe5a2,0xe5a3,0xe5a4,0xe5a5,0xe5a6,0xe5a7,0xe5a8,0x0000,0xe5aa,0xe5ab,0xe5ac,// 液腋 額櫻罌鶯鸚也倻冶夜 揶椰爺 + 0xe5ad,0xe5ae,0xe5a9,0xe5af,0xe5b0,0x0000,0x0000,0xe5b3,0xe5b4,0xe5b5,0xe5b7,0xe5b8,0xe5ba,0xe5bd,0xe5be,0xe5bf,// 耶若惹野弱 約若葯藥躍佯壤孃恙 + 0xe5c0,0xe5c1,0xe5c2,0xe5c3,0xe5c5,0xe5c6,0xe5c7,0xe5c8,0xe5c9,0xe5cd,0xe5ca,0xe5cb,0xe5cf,0x0000,0xe5d1,0xe5d3,// 揚攘敭暘楊樣洋瀁煬穰痒瘍羊 襄讓 + 0xe5d4,0xe5d5,0xe5d7,0xe5d8,0xe5d9,0x0000,0xe5da,0xe5db,0xe5dd,0xe5de,0xe5df,0xe5e0,0xe5e1,0xe5e2,0xe5e3,0xe5e4,// 釀陽養圄御 於漁禦語馭魚齬億憶抑 + 0xe5e5,0xe5e6,0xe5e7,0xe5e8,0xe5e9,0xe5ea,0xe5eb,0xe5ec,0xe5ed,0xe5f0,0xe5f1,0xe5f2,0xe5f3,0xe5f4,0xe5f5,0x0000,// 檍臆偃堰彦焉言諺孼儼嚴奄掩淹嶪 + // 0x5d40 - 0x5dff + 0x0000,0xe5f6,0x0000,0xe5f8,0xe5f9,0xe5fd,0xe6a2,0xe6a3,0xe6a8,0xe6ae,0xe6b2,0xe6b4,0x0000,0xe6b5,0xe6b6,0xe6b9,// 業 予余如歟汝與餘亦域 役易疫 + 0xe6ba,0xe6bb,0xe6bd,0xe6be,0xe6bf,0xe6c0,0xe6c1,0xe6c2,0xe6c3,0xe6c5,0xe6c8,0xe6ca,0xe6cb,0xe6cd,0xe6cf,0xe6ce,// 繹譯逆驛嚥堧姸娟宴延捐撚椽沿涓涎 + 0xe6d0,0xe6d1,0xe6d3,0xe6d4,0xe6d5,0xe6d7,0xe6d8,0xe6da,0xe6db,0xe6dd,0xe6de,0x0000,0x0000,0x0000,0xe6e2,0x0000,// 淵演烟然煙燃燕硏硯筵緣 衍 + 0xe6e3,0xe6e7,0xe6e9,0xe6ec,0xe6ed,0xe6ee,0xe6f0,0xe6f2,0xe6f3,0xe6f4,0x0000,0xe6f8,0xe6fa,0xe6fb,0xe7a4,0xe6fe,// 軟鉛鳶咽悅涅熱說閱厭 染炎焰鹽苒 + 0xe6fd,0xe7a2,0x0000,0xe7a3,0xe7a5,0xe7a7,0xe7a8,0xe7ab,0x0000,0xe7af,0xe7b1,0xe7b2,0xe7b3,0xe7b4,0xe7b5,0xe7b6,// 艶閻 髥曄燁葉塋 影映暎楹榮永泳 + 0xe7b8,0xe7ba,0xe7bd,0xe7c0,0xe7c1,0xe7c2,0xe7c3,0xe7c5,0xe7c8,0xe7c9,0xe7ca,0xe7d2,0xe7d4,0xe7d5,0xe7d6,0xe7d8,// 潁瀛營瑛瑩瓔盈纓英詠迎倪刈叡曳濊 + 0xe7d9,0x0000,0xe7da,0x0000,0xe7dc,0x0000,0xe7dd,0xe7de,0xe7e0,0xe7e1,0xe7e2,0xe7e3,0xe7e5,0xe7e7,0xe7e8,0xe7e9,// 猊 睿 芮 藝蘂裔詣譽豫銳霓預五 + 0xe7ea,0xe7ec,0xe7ed,0xe7ef,0xe7f0,0xe7f2,0xe7f3,0xe7f4,0xe7f5,0xe7f6,0xe7f7,0xe7fa,0xe7fb,0xe7fc,0xe7fd,0xe8a1,// 伍傲午吳嗚墺奧娛寤悟惡旿晤梧汚烏 + 0xe8a3,0xe8a5,0xe8a6,0x0000,0xe7ee,0xe8a9,0xe8aa,0xe8ab,0xe8ac,0xe8ad,0x0000,0xe8ae,0xe8af,0xe8b0,0xe8b1,0x0000,// 獒蜈誤 吾屋沃獄玉鈺 溫瑥瘟穩 + 0xe8b3,0x0000,0xe8b4,0xe8b5,0xe8b7,0xe8b9,0xe8b6,0xe8b8,0xe8ba,0xe8bb,0xe8bc,0xe8be,0xe8bf,0xe8c0,0xe8c3,0xe8c4,// 蘊 兀壅瓮癰擁甕翁邕雍渦瓦窩蛙蝸 + 0xe8c5,0xe8c2,0xe8c6,0xe8c7,0xe8c8,0xe8cb,0xe8cc,0xe8ce,0xe8cf,0xe8d0,0xe8d1,0xe8d3,0xe8d4,0xe8d5,0xe8d6,0xe8d7,// 訛臥婉完宛浣玩琬碗緩翫腕莞豌阮頑 + 0xe8d8,0xe8d9,0xe8da,0xe8db,0xe8dc,0xe8dd,0xe8de,0xe8e0,0xe8e1,0xe8e2,0xe8e4,0xe8e5,0xe8e6,0xe8e9,0xe8ea,0x0000,// 曰往旺枉汪王倭歪矮外巍猥畏僥凹 + // 0x5e40 - 0x5eff + 0x0000,0xe8eb,0xe8ec,0xe8ed,0xe8ee,0xe8f2,0xe8f3,0xe8f4,0xe8f6,0xe8f8,0xe9a6,0xe8f9,0xe8fa,0xe8fd,0xe9a1,0xe9a2,// 堯夭妖姚嶢拗搖擾曜腰樂橈瑤窈窯 + 0xe9a3,0xe9a4,0xe9a5,0x0000,0xe9a8,0xe9a9,0xe9aa,0xe9ab,0xe9ad,0xe9ae,0xe9b4,0xe9af,0xe9b0,0xe9b1,0xe9b3,0xe9b6,// 繇繞耀 蟯要謠遙邀饒辱慾欲浴褥傭 + 0xe9b8,0xe9bb,0xe9bc,0xe9b7,0xe9be,0xe9c0,0xe9c1,0xe9c2,0xe9c3,0xe9c4,0xe9c6,0x0000,0xe9c7,0xe9c8,0x0000,0xe9c9,// 勇容庸冗榕湧溶熔瑢用聳 茸蓉 踊 + 0xe9ca,0xe9cb,0xe9ce,0xe9cf,0xe9d0,0xe9d1,0xe9d2,0xe9d3,0x0000,0xe9d4,0xe9d5,0xe9d6,0xe9cd,0xe9d7,0xe9d8,0xe9da,// 鎔鏞佑偶優又友右 宇寓尤于愚憂牛 + 0xe9dd,0xe9de,0xe9df,0xe9e0,0xe9e2,0xe9e3,0xe9e5,0xe9e6,0xe9e7,0xe9e8,0xe9ea,0xe9eb,0xe9ec,0xe9ef,0xe9f0,0xe9f2,// 盂祐禑禹羽芋虞迂遇郵隅雨雩旭昱煜 + 0xe9f3,0xe9f4,0xe9f5,0xe9f6,0xe9f7,0xe9f9,0xe9fc,0xe9fd,0xeaa1,0xeaa2,0xeaa3,0xeaa4,0x0000,0xeaa5,0xeaa6,0xeaa8,// 稶郁頊云暈殞耘芸運隕雲韻 蔚鬱熊 + 0xeaa9,0xeaaa,0xeaab,0xeaac,0xeaae,0xeaad,0xeaba,0xeaaf,0xeab0,0xeab2,0xeab3,0xeab4,0xeab5,0xeab9,0xeabb,0xeabc,// 雄元原員園圓爰垣媛寃怨愿援源猿瑗 + 0xeabd,0x0000,0xeabe,0xeabf,0xeac0,0xeac2,0xeac3,0xeac4,0xeac5,0xeac6,0xeac7,0xeac8,0xeac9,0xeaca,0xeacb,0xeacc,// 苑 袁轅遠院願鴛月越鉞位偉僞危圍 + 0xeacd,0xeacf,0x0000,0xead0,0xeace,0xead2,0xead3,0xead4,0xead5,0xead6,0xead7,0xead8,0xeada,0xeadb,0x0000,0xeadd,// 委尉 慰威渭爲瑋緯胃萎葦蝟衛 謂 + 0xeade,0xeadf,0xeae0,0xeae1,0xeaf2,0xeae2,0xeae3,0xeae4,0xeaea,0xeae6,0xeae7,0x0000,0xeae8,0xeae9,0x0000,0xeaeb,// 違韋魏乳攸侑儒兪幼唯喩 孺宥 幽 + 0xeaec,0xeaed,0xeaee,0xeaf0,0xeaef,0xeaf1,0xeaf3,0xeaf5,0xeaf6,0xeaf8,0xeafa,0xeafd,0xeba1,0xeba2,0xeba5,0xeba6,// 庾悠惟愉愈揄有柔柚楡油游濡猶瑜由 + 0xeba8,0xebab,0xebac,0xebad,0x0000,0xebae,0xebaf,0xebb0,0xebb1,0xebb3,0xebb2,0xebb4,0xebb5,0xebb6,0xebb7,0x0000,// 癒維臾萸 裕誘諛諭蹂踰遊逾遺酉 + // 0x5f40 - 0x5fff + 0x0000,0xebb8,0xebb9,0x0000,0xebbe,0xebbf,0xebc0,0x0000,0xebc3,0xebc4,0xebc5,0xebc8,0xebc9,0xebca,0xebce,0xebd3,// 釉鍮 毓肉育 允奫尹潤玧胤閏聿 + 0xebd4,0xebd6,0xebd7,0xebd9,0xebda,0xebdb,0x0000,0xebdc,0x0000,0xebde,0xebdd,0xebdf,0x0000,0xebe0,0xebe1,0xebe2,// 戎絨融垠恩慇 殷 銀誾隱 乙吟淫 + 0xebe3,0xebe4,0xebe6,0xebe5,0x0000,0xebe7,0xebe8,0xebe9,0xebea,0xebeb,0xebec,0xebed,0xebee,0xebef,0xebf0,0xebf7,// 蔭陰飮音 揖泣邑凝應膺鷹依倚儀疑 + 0xebf8,0xebf1,0xebf2,0xebf3,0xebf4,0xebf6,0xebf9,0xebfa,0xebfc,0xebfd,0xebfe,0xeca1,0xeca2,0xeca3,0xeca4,0xeca5,// 矣宜意懿擬毅義艤蟻衣誼議醫二以伊 + 0xeca8,0xeca9,0xecab,0xecc3,0xecac,0xecad,0xecae,0xecaf,0x0000,0xecb3,0xecb4,0xecb6,0xecb7,0xecb9,0xecbb,0xecbc,// 夷姨已貳弛彛怡易 爾珥異痍移而耳 + 0xecbf,0xecc7,0xecc8,0x0000,0xeccb,0xeccf,0xeccc,0xeccd,0xecce,0xecd1,0xecd2,0x0000,0xecd3,0xecd4,0xecd6,0xecd7,// 荑飴餌 瀷翼益翊翌人仁 刃印咽因 + 0xecd8,0xecd9,0xecda,0xecdb,0xecdc,0xece3,0xece5,0xece6,0xece9,0xeceb,0xecec,0xeced,0xecee,0xecef,0xecf0,0xecf1,// 姻寅引忍湮認靭靷一佾壹日溢逸鎰馹 + 0xecf2,0xecf3,0xecf4,0xecf5,0xecf9,0xecfb,0xecfc,0xecfd,0xeda4,0xeda6,0xeda5,0xeda8,0xeda9,0xedaa,0xedab,0xedac,// 任壬妊姙稔荏賃入仍孕剩仔刺咨姉姿 + 0xedad,0xedaf,0xedae,0xedb0,0xedb1,0xedb2,0xedb3,0xedb4,0xedb5,0xedb6,0xedb7,0x0000,0xedb8,0x0000,0xedb9,0xedba,// 子孜字恣慈滋炙煮玆瓷疵 磁 紫者 + 0x0000,0xedbb,0xedbd,0xedbe,0x0000,0xedbf,0xedc0,0x0000,0xedc1,0xedc2,0xedc3,0xedc4,0xedc5,0xedc6,0x0000,0xedc7,// 自蔗藉 諮資 雌作勺嚼斫昨 灼 + 0xedc8,0xedc9,0xedca,0xedcb,0xedcc,0xedcd,0xedce,0xedd0,0xedd1,0xedd2,0xedd3,0xedd4,0xedd5,0xedd6,0x0000,0xedd7,// 炸爵綽芍酌雀鵲棧殘潺盞岑暫潛 箴 + 0xedd8,0x0000,0xedd9,0xedda,0xeddb,0xeddc,0xeddd,0xedde,0xeddf,0xede1,0x0000,0xede3,0xede4,0xede5,0xede6,0x0000,// 簪 蠶雜丈仗匠場墻奬 帳庄張掌 + // 0x6040 - 0x60ff + 0x0000,0xede7,0xede8,0xede9,0xedea,0xedeb,0xedec,0xede0,0xede2,0xeded,0xedee,0xedef,0xedf0,0x0000,0xedf1,0xedf2,// 暲杖樟檣欌漿壯將牆狀獐璋 章粧 + 0xedf3,0xedf4,0xedf6,0xedf7,0xedf8,0xedf9,0xedfa,0x0000,0xedfb,0xedfc,0xedfd,0xedfe,0xeea1,0xeea2,0xeea3,0xeea4,// 腸臟莊葬蔣薔藏 裝贓醬長障再哉在 + 0xeea5,0xeea6,0xeea7,0xeea8,0xeea9,0xeeab,0xeeac,0x0000,0xeeae,0xeeaf,0xeeb0,0xeeb1,0xeeb2,0xeeb3,0xeeb4,0xeeb5,// 宰才材栽梓滓災 裁財載齋齎爭箏諍 + 0xeeb6,0xeeb8,0xeeb7,0xeeb9,0xeeba,0xeebb,0xeebc,0xeebd,0xeebe,0x0000,0xeebf,0xeec0,0xeec1,0xeec2,0xeec3,0xeec4,// 錚低佇儲咀姐底抵杵 楮樗沮渚狙猪 + 0xeec5,0xeec6,0xeec8,0xeeca,0xeecb,0x0000,0xeecc,0x0000,0xeecd,0xeece,0xeecf,0xeed0,0xeed3,0xeed5,0xeed6,0xeed7,// 疽箸苧著藷 詛 貯躇這邸勣嫡寂摘 + 0xeed8,0xeed9,0xeeda,0xeedc,0xeedd,0xeede,0xeedf,0x0000,0xeee0,0xeee2,0xeee3,0xeee4,0xeee5,0xeee6,0xeee7,0xeee8,// 敵滴狄的積笛籍 績荻謫賊赤跡蹟迪 + 0xeee9,0xeeea,0xeeee,0xeeef,0xeef0,0xeef1,0xeef2,0x0000,0xeef3,0xeef5,0xeef6,0xeef7,0x0000,0xeef8,0xeef9,0xeefa,// 迹適傳全典前剪 塡奠專展 廛悛戰 + 0xeefb,0xeefc,0xeefd,0xeefe,0xefa1,0xefa3,0xefa4,0xefa6,0x0000,0xefa8,0xefa9,0xefaa,0xefab,0x0000,0xefac,0xefad,// 栓殿氈澱煎田甸癲 箋箭篆纏 詮輾 + 0xefae,0xefaf,0xefb0,0xefb1,0xefb3,0xefb4,0xefb5,0xefb6,0xefb7,0xefb8,0xefb9,0xefba,0x0000,0xefbc,0xefbd,0xefbe,// 轉鈿銓錢電顚顫餞切截折浙 竊節絶 + 0xefbf,0xefc0,0xefc1,0xefc2,0xefc3,0xefc7,0xefc4,0xefc5,0xefc8,0xefc9,0x0000,0xefca,0xefcb,0xefcc,0xefcd,0xefce,// 占岾店漸点點粘霑接摺 蝶丁井亭停 + 0xefcf,0xefd0,0xefd1,0xefd3,0xefd5,0xefd6,0xefd2,0xefd4,0xefd7,0xefd8,0xefd9,0xefda,0xefdb,0xefdc,0xefdd,0x0000,// 偵呈姃幀廷征定庭情挺政整旌晶晸 + 0xefdf,0xefe1,0xefe2,0xefe4,0xefe5,0xefeb,0xefec,0xefed,0xefee,0xefef,0xeff0,0xeffe,0xeff1,0xeff3,0xeff4,0x0000,// 楨正汀淨渟町睛碇禎程穽靖精艇訂 + // 0x6140 - 0x61ff + 0x0000,0xeff5,0xeff6,0xeff7,0xeff8,0xeff9,0xeffa,0xeffc,0xeffd,0xf0a1,0xf0a2,0xf0a3,0xf0a4,0xf0a5,0xf0a6,0xf0a7,// 諪貞鄭酊釘鉦錠霆靜頂鼎制劑啼堤 + 0xf0a8,0xf0a9,0xf0aa,0xf0ab,0x0000,0xf0ac,0xf0ad,0x0000,0xf0b0,0xf0ae,0xf0af,0xf0b1,0xf0b2,0xf0b3,0x0000,0xf0b4,// 帝弟悌提 梯濟 臍祭第薺製諸 蹄 + 0xf0b5,0xf0b6,0xf0b7,0xf0b8,0xf0b9,0xf0ba,0xf0bb,0xf0bd,0xf0bc,0xf0be,0x0000,0xf0bf,0x0000,0xf0c0,0xf0c1,0xf0c2,// 醍除際霽題齊俎凋兆助 嘲 弔彫措 + 0xf0c3,0xf0c4,0xf0c5,0xf0c6,0xf0c7,0xf0c8,0xf0c9,0xf0ca,0xf0cb,0xf0cc,0xf0cd,0xf0ce,0xf0cf,0xf0d0,0x0000,0xf0d2,// 操早晁曺曹朝條棗槽漕潮照燥爪 眺 + 0xf0d3,0xf0d4,0xf0d5,0xf0d6,0xf0d7,0x0000,0x0000,0xf0d8,0xf0d9,0x0000,0xf0da,0x0000,0xf0db,0xf0dc,0xf0dd,0xf0de,// 祖祚租稠窕 粗糟 組 繰肇藻蚤 + 0xf0df,0xf0e0,0xf0e1,0xf0e2,0xf0e3,0xf0e4,0xf0e5,0xf0e6,0x0000,0xf0e8,0xf0e9,0xf0ea,0xf0eb,0xf0ec,0xf0ed,0xf0ee,// 詔調趙躁造遭釣阻 鳥族簇足鏃存尊 + 0xf0ef,0xf0f0,0xf0f1,0xf0f2,0xf0f3,0xf0f4,0xf0f6,0xf0f7,0x0000,0xf0f8,0xf0f9,0xf0fa,0xf0fb,0xf0fc,0xf0fd,0xf0fe,// 卒拙猝倧宗從慫棕 淙琮種終綜縱腫 + 0xf1a2,0x0000,0xf1a3,0xf1a4,0xf1a5,0xf1a6,0xf1a7,0xf1a8,0xf1a9,0xf1aa,0xf1ab,0xf1ac,0xf1ad,0xf1ae,0xf1b7,0xf1b1,// 踵 鍾鐘佐坐左座挫罪主住侏做廚呪 + 0xf1b2,0xf1b3,0xf1b4,0xf1b5,0xf1b6,0xf1b8,0xf1b9,0xf1ba,0xf1bb,0xf1c0,0xf1bc,0xf1bd,0xf1d0,0xf1c1,0xf1c2,0x0000,// 周嗾奏宙州晝朱柱株炷注洲酒珠疇 + 0xf1c3,0xf1c4,0xf1c5,0xf1c6,0x0000,0xf1b0,0xf1c7,0xf1c8,0xf1c9,0xf1ca,0xf1cb,0xf1cc,0xf1cd,0xf1cf,0xf1ce,0xf1d1,// 籌紂紬綢 胄舟蛛註誅走躊輳酎週鑄 + 0xf1d2,0xf1d3,0xf1d4,0xf1d5,0xf1d6,0xf1d7,0xf1d8,0xf1da,0xf1db,0xf1dc,0xf1dd,0xf1de,0xf1df,0xf1e1,0xf1e2,0xf1e3,// 駐竹粥俊儁准埈峻晙樽浚準濬畯竣蠢 + 0xf1e4,0xf1e5,0x0000,0xf1e7,0xf1e8,0xf1e9,0xf1ea,0xf1eb,0xf1ec,0x0000,0xf1ed,0xf1ee,0xf1ef,0xf1f0,0xf1f1,0x0000,// 逡遵 駿茁中仲衆重 卽櫛楫汁葺 + // 0x6240 - 0x62ff + 0x0000,0xf1f2,0xf1f3,0xf1f5,0xf1f6,0xf1f4,0xf1f7,0xf1f8,0xf1fa,0x0000,0xf1fb,0xf1fc,0xf1fd,0xf1fe,0xf2a1,0xf2a2,// 增憎拯烝曾甑症蒸 證贈之只咫地 + 0xf2a3,0xf2a4,0xf2a5,0xf2a6,0xf2a7,0xf2a8,0xf2a9,0xf2aa,0xf2ab,0xf2ac,0xf2ad,0xf2ae,0xf2b0,0x0000,0xf2b1,0xf2b2,// 址志持指摯支旨智枝枳止池漬 知砥 + 0xf2b4,0xf2b3,0xf2b5,0xf2b6,0xf2b7,0xf2b8,0xf2b9,0xf2bb,0xf2bc,0xf2bd,0xf2be,0xf2bf,0xf2c0,0xf2c1,0xf2c2,0xf2c3,// 祗祉紙肢脂至芝蜘誌識贄趾遲直稙稷 + 0xf2c4,0xf2c5,0xf2e3,0xf2c7,0xf2c8,0xf2c9,0xf2cb,0xf2ce,0xf2d0,0xf2d1,0xf2d2,0xf2d3,0xf2d4,0xf2d6,0xf2d7,0xf2d8,// 織職辰嗔塵振晉榛津溱珍瑨璡疹盡眞 + 0xf2d9,0xf2da,0xf2db,0xf2e0,0xf2e1,0xf2e2,0xf2e4,0xf2e5,0xf2e6,0xf2e7,0xf2e8,0xf2ea,0xf2f2,0xf2eb,0xf2ec,0xf2ed,// 瞋秦縉診賑軫進鎭陣陳震叱窒姪嫉帙 + 0xf2ee,0xf2f0,0xf2f1,0xf2f3,0xf2f4,0xf2f5,0xf2f6,0xf2f7,0xf2f8,0xf2f9,0xf2fb,0xf3a2,0xf2fd,0xf2fe,0xf3a3,0xf3a4,// 桎疾秩膣蛭質跌迭斟朕執集緝輯徵懲 + 0xf3a5,0xf3a6,0xf3a8,0xf3b0,0xf3a9,0xf3aa,0xf3ac,0xf3ab,0xf3ad,0xf3ae,0xf3af,0xf3b1,0xf3b2,0xf3b4,0xf3b3,0xf3b5,// 澄且借箚叉嗟差嵯次此磋茶蹉遮車捉 + 0xf3b6,0xf3b7,0xf3b8,0xf3b9,0xf3ba,0xf3bb,0xf3bc,0xf3bd,0xf3be,0xf3bf,0xf3c0,0xf3c1,0xf3c3,0xf3c4,0xf3c5,0xf3c6,// 搾着窄錯鑿齪撰澯燦璨瓚竄纂粲纘讚 + 0xf3c7,0xf3c8,0x0000,0xf3c9,0xf3ca,0xf3cb,0xf3cc,0xf3cd,0xf3ce,0xf3d0,0xf3d1,0xf3d2,0xf3d3,0xf3d4,0x0000,0xf3d5,// 贊鑽 餐饌刹察擦札僭參塹慘慙 懺 + 0xf3d6,0xf3d7,0xf3d8,0xf3db,0xf3da,0x0000,0xf3dc,0xf3dd,0xf3de,0xf3df,0xf3e0,0x0000,0xf3e2,0xf3e3,0xf3e4,0xf3e5,// 斬站讒倡倉 創唱娼廠彰 敞昌昶暢 + 0xf3e6,0x0000,0xf3e7,0xf3e8,0xf3ea,0xf3eb,0xf3ec,0xf3ed,0xf3ee,0xf3ef,0xf3f0,0xf3f1,0xf3f4,0xf3f5,0xf3f6,0xf3f7,// 槍 滄漲瘡窓脹艙菖蒼債埰彩採砦綵 + 0xf3f8,0xf3f9,0xf3fa,0xf3fb,0xf3fc,0xf3fd,0xf3fe,0x0000,0xf4a1,0xf4a2,0xf4a3,0xf4a4,0xf4a5,0xf4a7,0xf4a8,0x0000,// 菜蔡采釵冊柵策 責凄妻悽處刺剔 + // 0x6340 - 0x63ff + 0x0000,0xf4a9,0xf4aa,0xf4ab,0xf4ac,0xf4ad,0xf4ae,0xf4af,0xf4b0,0xf4b1,0x0000,0x0000,0xf4b3,0xf4b4,0xf4b5,0xf4b6,// 尺慽戚拓擲斥滌瘠脊 陟隻仟千 + 0xf4b7,0xf4b8,0xf4b9,0xf4ba,0xf4bb,0xf4bc,0x0000,0xf4be,0xf4bf,0xf4c0,0xf4c1,0xf4c2,0xf4c3,0xf4c4,0xf4c5,0xf4c6,// 喘天川擅泉淺 穿舛薦賤踐遷釧闡阡 + 0xf4c7,0xf4c8,0xf4cb,0xf4c9,0xf4ca,0xf4cc,0xf4cd,0xf4ce,0xf4d0,0xf4d1,0xf4d2,0xf4d3,0xf4d4,0xf4d5,0xf4d6,0xf4d7,// 韆凸徹哲喆撤澈綴轍鐵僉尖沾添甛瞻 + 0x0000,0xf4d9,0xf4db,0xf4dd,0xf4de,0xf4df,0xf4e0,0xf4e1,0xf4e2,0xf4e3,0xf4e4,0xf4e5,0xf4e6,0xf4e7,0xf4e8,0xf4e9,// 籤諂妾帖捷牒疊睫諜貼輒廳晴淸聽 + 0xf4ea,0x0000,0xf4eb,0xf4ec,0xf4ed,0xf4ee,0xf4ef,0xf4f0,0xf4f1,0xf4f2,0x0000,0xf4f3,0xf4f4,0xf4f5,0xf4f6,0x0000,// 菁 請靑鯖切剃替涕滯 締諦逮遞 + 0xf4f7,0xf4f8,0xf4fa,0x0000,0xf4fb,0xf4fc,0xf4fd,0xf4fe,0xf5a1,0xf5a2,0xf5a3,0xf5a4,0xf5a5,0xf5a6,0xf5a7,0xf5a8,// 體初哨 憔抄招梢椒楚樵炒焦硝礁礎 + 0xf5a9,0xf5aa,0x0000,0xf5ab,0xf5ae,0xf5af,0xf5b0,0xf5b1,0xf5b2,0xf5b3,0xf5b4,0x0000,0x0000,0xf5b5,0xf5b6,0x0000,// 秒稍 肖草蕉貂超酢醋醮 促囑 + 0xf5b7,0xf5b8,0xf5b9,0xf5ba,0x0000,0x0000,0xf5bb,0xf5bc,0xf5bd,0xf5bf,0xf5c0,0xf5c1,0x0000,0xf5c4,0xf5c5,0xf5c6,// 燭矗蜀觸 寸忖村叢塚寵 摠總聰 + 0x0000,0xf5c8,0xf5c9,0xf5ca,0xf5cb,0x0000,0xf5cc,0xf5cd,0xf5ce,0xf5cf,0xf5d0,0xf5d1,0x0000,0xf5d2,0xf5d3,0x0000,// 銃撮催崔 最墜抽推椎楸 樞湫 + 0xf5d4,0xf5d5,0x0000,0xf5d6,0xf5d7,0xf5d9,0xf5da,0xf5db,0xf5dc,0xf5dd,0xf5df,0xf5de,0xf5e1,0x0000,0xf5e3,0x0000,// 皺秋 芻萩趨追鄒酋醜錘錐雛 鰍 + 0x0000,0xf5e4,0x0000,0xf5e6,0xf5e5,0xf5e7,0xf5e8,0xf5e9,0xf5ea,0x0000,0xf5eb,0xf5ed,0xf5ee,0xf5ef,0xf5f0,0xf5f1,// 丑 祝畜竺筑築縮 蓄蹴軸逐春椿 + 0xf5f3,0xf5f5,0xf5f6,0x0000,0xf5f7,0xf5f8,0xf5f9,0xf5fa,0xf5fb,0xf5fc,0xf5fd,0xf5fe,0xf6a2,0xf6a3,0xf6a4,0x0000,// 出黜充 忠沖蟲衝衷悴膵萃取吹嘴 + // 0x6440 - 0x64ff + 0x0000,0xf6a5,0xf6a6,0x0000,0xf6a7,0xf6a8,0xf6a9,0xf6aa,0xf6ab,0x0000,0xf6ac,0xf6ad,0xf6ae,0xf6af,0xf6b1,0xf6b0,// 娶就 炊翠聚脆臭 趣醉驟鷲仄側 + 0xf6b3,0xf6b4,0xf6b5,0xf6b6,0xf6b7,0xf6b8,0xf6b9,0x0000,0xf6ba,0x0000,0xf6bc,0xf6bd,0xf6be,0xf6bf,0xf6c0,0xf6c1,// 惻測層侈値嗤峙 幟 梔治淄熾痔痴 + 0xf6c2,0xf6cb,0xf6c3,0xf6c5,0xf6c6,0xf6c7,0xf6bb,0xf6c8,0xf6ca,0xf6cc,0x0000,0xf6cd,0xf6ce,0xf6cf,0xf6d0,0xf6d1,// 癡雉稚緇緻置恥致輜馳 齒則勅飭親 + 0xf6d2,0xf6d3,0xf6d4,0xf6d5,0xf6d6,0x0000,0xf6d7,0xf6d8,0xf6d9,0xf6db,0xf6dc,0xf6dd,0xf6de,0xf6df,0xf6e0,0xf6e1,// 七柒漆侵寢 枕沈浸砧針鍼蟄秤稱快 + 0xf6e2,0xf6e4,0xf6e5,0xf6e6,0xf6e7,0xf6e8,0xf6ea,0xf6eb,0xf6ec,0xf6ed,0xf6ef,0xf6f0,0xf6f1,0xf6f2,0xf6f4,0xf6f5,// 他唾墮妥惰打朶楕舵陀駝倬卓啄度托 + 0x0000,0xf6f6,0xf6f7,0xf6f9,0x0000,0xf6fa,0xf6fb,0xf6fc,0xf6fe,0xf7a1,0xf7a2,0xf7a3,0xf7a4,0xf7a5,0xf7a6,0xf7a7,// 拓擢柝 濁濯琢託鐸呑嘆坦彈憚歎 + 0xf7a8,0xf7a9,0xf7aa,0xf7ab,0xf7ac,0xf7ad,0xf7ae,0xf7b0,0xf7b1,0xf7b2,0xf7b3,0xf7b4,0xf7b5,0xf7b6,0xf7b7,0xf7b9,// 灘炭綻誕奪脫探耽貪塔搭榻宕帑湯蕩 + 0xf7ba,0xf7bb,0xf7bc,0xf7bd,0xf7be,0xf7bf,0xf7c0,0xf7c1,0xf7c2,0xf7c3,0xf7c4,0xf7c5,0xf7c6,0xf7c7,0x0000,0xf7c8,// 兌台太怠態殆汰泰笞胎苔跆邰颱 宅 + 0xf7c9,0xf7ca,0x0000,0xf7cb,0xf7cc,0xf7cd,0xf7ce,0xf7cf,0xf7d0,0xf7d1,0xf7d2,0xf7d3,0xf7d4,0xf7d5,0xf7d6,0xf7d7,// 擇澤 撑攄兎吐土討慟桶洞痛筒統通 + 0xf7d8,0xf7da,0xf7db,0xf7dc,0xf7dd,0xf7de,0xf7df,0xf7e0,0xf7e1,0xf7e2,0xf7e3,0xf7e4,0xf7e5,0xf7e8,0xf7e7,0xf7e9,// 堆腿褪退頹偸套妬投透鬪慝特婆坡巴 + 0xf7ea,0xf7eb,0xf7ed,0xf7ee,0xf7ef,0xf7f0,0xf7f1,0xf7f2,0xf7f3,0xf7f4,0xf7f5,0xf7f6,0xf7f8,0xf7f7,0xf7f9,0xf7fa,// 把播杷波派爬琶破罷芭跛頗坂判板版 + 0xf7fc,0xf7fd,0xf7fb,0xf8a1,0xf8a2,0xf8a3,0xf8a4,0xf8a5,0xf8a6,0xf8a7,0xf8a9,0xf8aa,0xf8ab,0xf8ac,0xf8ad,0x0000,// 販辦瓣阪八叭捌佩唄悖沛浿牌狽稗 + // 0x6540 - 0x65ff + 0x0000,0xf8af,0xf8a8,0xf8ae,0xf8b0,0xf8b1,0xf8b2,0xf8b3,0xf8b4,0xf8b5,0xf8b6,0xf8b7,0xf8b8,0xf8b9,0xf8ba,0xf8bb,// 貝敗覇彭澎烹膨愎便偏扁片篇編翩 + 0x0000,0xf8bc,0xf8bd,0xf8bf,0xf8c0,0xf8c1,0xf8c3,0xf8c4,0xf8c5,0xf8c6,0xf8c7,0xf8c8,0xf8c9,0xf8ca,0xf8cb,0xf8cc,// 遍鞭貶坪平萍評吠嬖幣廢弊斃肺蔽 + 0xf8cd,0xf8ce,0xf8cf,0xf8d0,0xf8d1,0xf8d2,0xf8d3,0xf8d4,0xf8d5,0x0000,0xf8d6,0xf8d7,0xf8d9,0xf8d8,0xf8da,0xf8dc,// 閉陛佈包匍匏咆哺圃 布怖抱抛捕泡 + 0xf8dd,0x0000,0xf8de,0xf8df,0xf8e0,0xf8e1,0x0000,0xf8e3,0xf8e4,0xf8e5,0xf8e6,0x0000,0xf8e8,0x0000,0xf8e9,0xf8ea,// 浦 疱砲胞脯 葡蒲袍褒 鋪 飽鮑 + 0xf8eb,0xf8ec,0xf8ee,0xf8ef,0xf8f1,0xf8f2,0xf8f3,0xf8f4,0xf8f5,0xf8f6,0xf8f7,0xf8f8,0xf8f9,0xf8fa,0xf8fb,0xf8fd,// 幅暴瀑爆俵剽彪慓杓標漂瓢票表豹飄 + 0x0000,0xf9a1,0xf9a2,0xf9a7,0xf9a3,0xf9a4,0xf9a5,0xf9a6,0xf9a8,0xf9a9,0xf9aa,0xf9ab,0x0000,0xf9ac,0xf9ad,0xf9af,// 品稟馮楓諷豊風彼披疲皮 被避匹 + 0xf9b0,0xf9b1,0xf9b2,0xf9b4,0xf9b5,0xf9b6,0x0000,0xf9b9,0xf9ba,0xf9bb,0xf9bc,0xf9be,0xf9bf,0xf9c0,0xf9c1,0xf9c2,// 弼必泌畢疋筆 乏逼下何夏廈昰河瑕 + 0xf9c4,0xf9c3,0xf9c5,0xf9c6,0xf9c7,0xf9c8,0xf9c9,0xf9ca,0x0000,0xf9cb,0xf9cc,0xf9cd,0xf9ce,0xf9cf,0xf9d0,0xf9d1,// 蝦荷賀遐霞鰕壑學 虐謔鶴寒恨悍旱 + 0xf9d2,0xf9d3,0xf9d4,0xf9d6,0xf9d7,0x0000,0xf9d9,0xf9d8,0xf9da,0xf9db,0x0000,0xf9dc,0xf9dd,0xf9de,0xf9df,0xf9e0,// 汗漢澣罕翰 閒閑限韓 割轄函含咸 + 0xf9e1,0xf9e2,0xf9e3,0xf9e4,0xf9e5,0xf9e6,0xf9e8,0xf9ea,0xf9eb,0xf9ec,0xf9ed,0xf9ee,0xf9f0,0xf9f1,0xf9f2,0xf9f3,// 啣喊檻涵緘艦陷合哈盒蛤閤陜亢伉姮 + 0xf9f5,0xf9f6,0xf9f7,0xf9f8,0xf9f9,0xf9fa,0xf9fb,0x0000,0xf9fc,0xf9fd,0xf9fe,0xfaa2,0xfaa3,0xfaa4,0xfaa5,0xfaa6,// 巷恒抗杭桁沆港 缸肛航降項亥偕咳 + 0xfaa8,0xfaa7,0xfaa9,0xfaaa,0x0000,0xfaab,0xfaac,0xfaad,0xfaaf,0xfab0,0xfab1,0xfab2,0xfab3,0xfab4,0xfab5,0x0000,// 奚垓孩害 懈楷海蟹解該諧邂駭骸 + // 0x6640 - 0x66ff + 0x0000,0xfab6,0xfab7,0xfab8,0xfab9,0xfaba,0xfabc,0xfabd,0xfabe,0xfabf,0xfac1,0xfac0,0xfac2,0xfac3,0xfac4,0xfac5,// 劾核倖幸杏行享向嚮鄕珦響餉饗香 + 0xfac6,0xfac7,0xfac8,0xfac9,0xfaca,0xfacd,0xfacc,0xface,0xfacf,0xfad0,0xfad1,0xfad2,0xfad3,0xfad4,0xfad6,0xfad7,// 噓墟虛許憲軒獻歇險驗奕爀赫革峴弦 + 0xfad8,0xfadb,0xfade,0xfadc,0xfadf,0xfae1,0xfae2,0xfae3,0xfae4,0xfae5,0xfae6,0xfae7,0xfae8,0xfae9,0xfaea,0xfaeb,// 懸炫現玄眩絃絢縣舷衒見賢鉉顯孑穴 + 0xfaec,0xfaed,0xfaee,0x0000,0xfaef,0xfaf0,0xfaf1,0xfaf2,0xfaf3,0xfaf4,0xfaf5,0x0000,0xfaf7,0xfaf6,0xfaf8,0x0000,// 血頁嫌 俠協夾峽挾浹狹 脇脅莢 + 0xfaf9,0xfafa,0xfafb,0xfafd,0xfafe,0xfba1,0xfafc,0xfba4,0xfba6,0xfba8,0xfbaa,0xfbab,0xfbac,0xfbae,0xfbaf,0xfbb0,// 鋏頰亨刑型形兄瀅炯珩荊螢衡邢鎣馨 + 0xfbb1,0xfbb2,0xfbb3,0xfbb4,0xfbb6,0xfbb8,0xfbb9,0xfbba,0xfbbb,0xfbdf,0xfbbc,0xfbbe,0xfbbd,0xfbbf,0xfbc1,0xfbc4,// 兮彗惠慧蕙醯鞋乎互豪呼壺壕好弧昊 + 0xfbc2,0xfbc6,0xfbc7,0xfbc8,0xfbc9,0xfbca,0xfbcb,0xfbcd,0xfbcc,0xfbce,0xfbcf,0xfbd1,0xfbd2,0xfbd3,0x0000,0xfbd4,// 戶毫浩淏湖滸澔濩濠灝狐瑚瓠皓 祜 + 0xfbd5,0xfbd6,0xfbd7,0xfbd9,0xfbdb,0xfbdc,0xfbdd,0xfbde,0xfbc3,0x0000,0xfbe0,0xfbe1,0xfbe2,0xfbe3,0xfbe4,0xfbe5,// 糊縞胡葫虎號蝴護扈 鎬頀顥惑或酷 + 0xfbe6,0xfbe7,0xfbe8,0xfbe9,0xfbea,0xfbeb,0xfbec,0xfbed,0xfbee,0x0000,0xfbf0,0xfbef,0xfbf1,0xfbf2,0xfbf3,0xfbf8,// 婚昏混渾琿魂忽惚笏 弘哄汞泓洪鴻 + 0xfbf5,0xfbf6,0xfbf7,0xfbf9,0xfbfb,0xfbfc,0xfbfd,0xfca1,0xfbfe,0xfca2,0xfbfa,0xfca3,0xfca4,0xfca5,0xfca8,0xfca7,// 紅虹訌化嬅樺火禍畵禾和花華話靴貨 + 0xfca9,0xfcaa,0xfcab,0xfcac,0xfcad,0xfcae,0x0000,0xfcaf,0xfcb0,0x0000,0xfcb2,0xfcb3,0xfcb4,0x0000,0xfcb5,0xfcb8,// 廓擴攫確碻穫 丸喚 宦幻患 換桓 + 0xfcb6,0xfcb9,0xfcba,0xfcbb,0xfcbc,0xfcbd,0xfcbe,0xfcbf,0x0000,0xfcc0,0xfcc1,0xfcc2,0xfcc3,0xfcc4,0xfcc5,0x0000,// 歡渙煥環紈還驩鰥 活滑猾豁闊凰 + // 0x6740 - 0x67ff + 0x0000,0x0000,0xfcc7,0x0000,0xfcc8,0xfccb,0xfcc9,0xfccc,0xfccf,0xfcd1,0xfcd3,0xfcd5,0xfcd6,0xfcd8,0xfcd9,0xfcda,// 徨 恍慌惶晃況滉煌皇篁荒蝗遑 + 0xfcdb,0xfcdc,0xfcde,0xfcdf,0xfce0,0xfce1,0xfce2,0xfce3,0xfce4,0xfce5,0xfce6,0xfce7,0xfce8,0xfce9,0xfcea,0xfceb,// 隍黃回廻徊恢悔懷晦會檜淮澮灰獪繪 + 0xfcec,0xfcee,0xfcef,0xfcf0,0xfcf1,0xfcf2,0xfcf4,0xfcf6,0xfcf7,0x0000,0xfcf8,0xfcf9,0xfcfb,0xfcfc,0xfda1,0xfda2,// 膾蛔誨賄劃獲橫哮嚆 孝效曉梟爻肴 + 0xfda3,0xfda5,0xfda6,0xfda7,0xfda8,0xfda9,0xfdaa,0xfdab,0xfdad,0xfdae,0x0000,0xfdb1,0x0000,0xfdb3,0xfdb4,0xfdb5,// 酵侯候厚后吼喉嗅後朽 逅 勳塤壎 + 0xfdbb,0xfdb6,0xfdb7,0xfdb8,0xfdb9,0xfdba,0xfdbc,0xfdbd,0xfdc0,0xfdc1,0xfdc2,0xfdc3,0xfdc4,0xfdc5,0xfdc6,0xfdc7,// 暈焄熏燻薰訓薨喧萱卉喙毁彙徽揮暉 + 0xfdc8,0xfdc9,0xfdca,0xfdcb,0xfdcc,0xfdcd,0xfdce,0xfdcf,0xfdd0,0xfdd1,0xfdd2,0xfdd3,0xfdd5,0xfdd6,0xfdd4,0xfdd7,// 煇諱輝麾休携烋畦虧恤譎鷸凶匈兇洶 + 0xfdd8,0xfdd9,0x0000,0xfdda,0xfddb,0xfddd,0xfdde,0xfddf,0xfde0,0x0000,0xfde2,0xfde4,0xfde3,0xfde5,0xfde6,0xfde7,// 胸黑 昕欣痕吃屹紇 欠歆欽吸恰洽 + 0xfde9,0xfdea,0xfdec,0xfded,0xfdef,0xfdf0,0xfdf1,0xfdf6,0xfdf2,0xfdf4,0xfdfa,0xfdf7,0xfdeb,0xfdf8,0xfdfb,0xfdfc,// 興僖喜噫姬嬉希曦憙戱犧熙凞熹禧稀 + 0xfdfd,0xfdfe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 羲詰 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x6840 - 0x68ff + 0x0000,0xcaae,0xcab1,0xcab2,0xcac2,0xcac9,0xcad3,0xcad4,0xcad8,0xcae9,0xcaf1,0xcaf9,0xcafb,0xcafd,0xcba8,0xcbb1,// 枷珂痂慤侃柬桿磵蝎戡瞰邯鑒堈畺 + 0xcbb4,0xcbb6,0xcbb8,0xcbbe,0xcbc3,0xcbd0,0xcbd1,0xcbd3,0xcbda,0xcbe4,0xcbe6,0xcbe9,0xcbf1,0xcbf2,0xcbfa,0xcbfd,// 絳羌舡鱇塏豈鎧喀倨祛踞鉅楗腱桀劒 + 0xcca2,0xcca6,0xccae,0xccbc,0xccc6,0xccc9,0xccca,0xcccc,0xccd0,0xccd5,0xccde,0xcce0,0xccf7,0xcda1,0xcdb6,0xcdbc,// 鈐迲膈抉鉗俓倞儆坰憬烱璥堺棨尻暠 + 0xcdbe,0xcdc4,0xcdc9,0xcdca,0xcde4,0xcde6,0xcdf5,0xcdf7,0xcdf9,0xcdfa,0xcea5,0xcea7,0xceb5,0xcec2,0xcec9,0xcfa6,// 槁羔苽菰琨鯤珙蚣鞏串跨鍋琯侊炚坵 + 0xcfbe,0xcfca,0xcfd4,0xcfd9,0xcfe4,0xcfec,0xcfee,0xcff1,0xcff2,0xcffb,0xcffc,0xd0a7,0xd0ab,0xd0b2,0xd0b4,0xd0c2,// 耉銶鞫裙芎捲淃獗蕨句晷槻竅勻畇劤 + 0xd0d2,0xd0d4,0xd0d9,0xd0df,0xd0f2,0xd1ac,0xd1af,0xd1b5,0xd1bc,0xd1c5,0xd1d4,0xd1d5,0xd1d6,0xd1d8,0xd1db,0xd1dc,// 妗昑芩伋埼玘璂祁羈錤喇奈娜懶癩羅 + 0xd1dd,0xd1de,0xd1df,0xd1e0,0xd1e2,0xd1e3,0xd1e4,0xd1e5,0xd1e6,0xd1e8,0xd1e9,0xd1ea,0xd1eb,0xd1ed,0xd1ef,0xd1f0,// 蘿螺裸邏樂洛烙珞落酪駱亂卵欄爛蘭 + 0xd1f2,0xd1f6,0xd1f7,0xd1f8,0xd1f9,0xd1fa,0xd1fc,0xd1fd,0xd1fe,0xd2a2,0xd2a3,0xd2a4,0xd2a7,0xd2a8,0xd2a9,0xd2aa,// 鸞嵐枏楠湳濫藍襤拉臘蠟衲廊朗浪狼 + 0xd2ab,0xd2ad,0xd2b2,0xd2b5,0xd2bc,0xd2be,0xd2c2,0xd2c3,0xd2c4,0xd2c6,0xd2c7,0xd2c8,0xd2c9,0xd2ca,0xd2cb,0xd2cc,// 郎來冷撚寗勞擄櫓爐盧老蘆虜路露駑 + 0xd2cd,0xd2ce,0xd2cf,0xd2d0,0xd2d1,0xd2d2,0xd2d3,0xd2d4,0xd2d5,0xd2d6,0xd2d7,0xd2d9,0xd2da,0xd2de,0xd2df,0xd2e1,// 魯鷺碌祿綠菉錄鹿論壟弄籠聾牢磊賂 + 0xd2e2,0xd2e4,0xd2e5,0xd2e6,0xd2e7,0xd2e8,0xd2e9,0xd2ea,0xd2eb,0xd2ee,0xd2f0,0xd2f1,0xd2f2,0xd2f3,0xd2f4,0xd2f5,// 雷壘屢樓淚漏累縷陋杻勒肋凜凌稜綾 + 0xd2f7,0xd2f8,0xd3a2,0xd3a7,0xd3b6,0xd3bb,0xd3bc,0xd3c0,0xd3c6,0xd3ca,0xd3cc,0xd3d4,0xd3d9,0xd3dd,0xd3f7,0x0000,// 菱陵亶彖澾坍憺湛蕁錟畓戇螳坮嶋 + // 0x6940 - 0x69ff + 0x0000,0xd3fc,0xd4a2,0xd4ad,0xd4c5,0xd4c8,0xd4e8,0xd4ec,0xd4f1,0xd4fc,0xd5ab,0xd5ae,0xd5cf,0xd5d0,0xd5e3,0xd6a2,// 掉櫂覩旽焞逗芚嶝拏諾丹崍徠儷璉 + 0xd6b8,0xd6b9,0xd6bd,0xd6c0,0xd6c8,0xd6cd,0xd6cf,0xd6d1,0xd6df,0xd6e1,0xd6ee,0xd6f2,0xd7a2,0xd7a5,0xd7aa,0xd7ad,// 寧岺笭聆澧怒擄潞祿菉瀨賚鬧婁瘻蔞 + 0xd7af,0xd7b2,0xd7b7,0xd7c2,0xd7cf,0xd7da,0xd7df,0xd7e4,0xd7e8,0xd7e9,0xd7eb,0xd7f1,0xd8a7,0xd8b1,0xd8b2,0xd8b3,// 鏤旒瀏侖凜唎浬異羸莉裡潾碼邈万卍 + 0xd8c5,0xd8c9,0xd8d6,0xd8f7,0xd9a7,0xd9aa,0xd9ac,0xd9b9,0xd9c1,0xd9c5,0xd9d0,0xd9df,0xd9e4,0xd9ea,0xd9ee,0xd9fa,// 唜茉輞沔椧瞑蓂摹瑁芼鶩竗憮楙珷們 + 0xdaa7,0xdaa9,0xdab2,0xdab3,0xdab5,0xdabd,0xdabe,0xdac9,0xdaee,0xdaf0,0xdaf1,0xdafd,0xdbb3,0xdbb5,0xdbb6,0xdbcc,// 雯沕梶楣湄黴岷緡瘢盼磐渤枋滂磅焙 + 0xdbdf,0xdbe2,0xdbfc,0xdca2,0xdcb8,0xdcc0,0xdcca,0xdccc,0xdcde,0xdcec,0xdcf4,0xdcf6,0xdcfb,0xdda1,0xddb2,0xddb4,// 幡燔檗蘗棅騈珤菩輹熢不俯咐孚艀莩 + 0xddc3,0xddcb,0xddd3,0xddd8,0xdded,0xddf0,0xddf1,0xddf9,0xddfb,0xdead,0xdeb3,0xdeb7,0xdec6,0xdeda,0xdefa,0xdfac,// 吩昐賁彿枇毖毗秕粃嚬浜玭俟柶麝霰 + 0xdfb0,0xdfbc,0xdfc7,0xdfe0,0xdff2,0xdffb,0xe0bd,0xe0c0,0xe0c2,0xe0c4,0xe0d6,0xe0d7,0xe0dc,0xe0e1,0xe0e5,0xe0e6,// 煞鈒峠嗇捿筮嬋敾渲琁鐥饍泄褻齧剡 + 0xe0ed,0xe0f4,0xe0fb,0xe1c4,0xe1c6,0xe1d7,0xe1da,0xe1db,0xe1de,0xe1e0,0xe1e2,0xe1e5,0xe1e7,0xe1fc,0xe2af,0xe2b0,// 陝宬珹瘙篠涑謖贖巽蓀飡悚淞峀琇璲 + 0xe2c2,0xe2ca,0xe2d8,0xe2da,0xe2db,0xe2df,0xe2e3,0xe2e5,0xe2f1,0xe2f2,0xe2f4,0xe2fc,0xe3ba,0xe3ce,0xe3d9,0xe3da,// 讐隧潚琡璹徇栒橓蓴蕣諄鉥屎豕篒蝕 + 0xe3e0,0xe3f0,0xe4a6,0xe4af,0xe4b5,0xe4c1,0xe4c7,0xe4c8,0xe4ca,0xe4d5,0xe4da,0xe4db,0xe4f9,0xe4fc,0xe5b1,0xe5b2,// 侁藎諶啞莪幄鄂鍔鰐鮟唵岩扼縊掠略 + 0xe5b6,0xe5b9,0xe5bb,0xe5bc,0xe5c4,0xe5cc,0xe5ce,0xe5d0,0xe5d2,0xe5d6,0xe5dc,0xe5ee,0xe5ef,0xe5f7,0xe5fa,0x0000,// 蒻亮兩凉梁禳糧良諒量瘀蘖俺円勵 + // 0x6a40 - 0x6aff + 0x0000,0xe5fb,0xe5fc,0xe5fe,0xe6a1,0xe6a4,0xe6a5,0xe6a6,0xe6a7,0xe6a9,0xe6aa,0xe6ab,0xe6ac,0xe6ad,0xe6af,0xe6b0,// 呂女廬旅濾璵礖礪艅茹輿轝閭驪麗 + 0xe6b1,0xe6b3,0xe6b7,0xe6b8,0xe6bc,0xe6c4,0xe6c6,0xe6c7,0xe6c9,0xe6cc,0xe6d2,0xe6d6,0xe6d9,0xe6dc,0xe6df,0xe6e0,// 黎力曆歷轢年憐戀挻沇漣煉璉秊練縯 + 0xe6e1,0xe6e4,0xe6e5,0xe6e6,0xe6e8,0xe6ea,0xe6eb,0xe6ef,0xe6f1,0xe6f5,0xe6f6,0xe6f7,0xe6f9,0xe6fc,0xe7a1,0xe7a6,// 聯輦蓮連鍊列劣烈裂廉念捻殮琰簾獵 + 0xe7a9,0xe7aa,0xe7ac,0xe7ad,0xe7ae,0xe7b0,0xe7b7,0xe7b9,0xe7bb,0xe7bc,0xe7be,0xe7bf,0xe7c4,0xe7c6,0xe7c7,0xe7cb,// 令囹寧嶺嶸怜渶濚瀯煐獰玲穎羚聆鈴 + 0xe7cc,0xe7cd,0xe7ce,0xe7cf,0xe7d0,0xe7d1,0xe7d3,0xe7d7,0xe7db,0xe7df,0xe7e4,0xe7e6,0xe7eb,0xe7f1,0xe7f8,0xe7f9,// 鍈零霙靈領乂例汭穢禮醴隸俉塢懊敖 + 0xe7fe,0xe8a2,0xe8a4,0xe8a7,0xe8a8,0xe8b2,0xe8bd,0xe8c1,0xe8c9,0xe8ca,0xe8cd,0xe8d2,0xe8df,0xe8e3,0xe8e7,0xe8e8,// 澳熬筽鰲鼇縕饔窪梡椀琓脘娃嵬了僚 + 0xe8ef,0xe8f0,0xe8f1,0xe8f5,0xe8f7,0xe8fb,0xe8fc,0xe8fe,0xe9a7,0xe9ac,0xe9b2,0xe9b5,0xe9b9,0xe9ba,0xe9bd,0xe9bf,// 寥寮尿撓料燎燿療蓼遼縟俑埇墉慂涌 + 0xe9c5,0xe9cc,0xe9d9,0xe9db,0xe9dc,0xe9e1,0xe9e4,0xe9e9,0xe9ed,0xe9ee,0xe9f1,0xe9f8,0xe9fa,0xe9fb,0xe9fe,0xeaa7,// 甬龍旴玗瑀紆藕釪勖彧栯橒澐熉蕓亐 + 0xeab1,0xeab6,0xeab7,0xeab8,0xeac1,0xead1,0xead9,0xeadc,0xeae5,0xeaf4,0xeaf7,0xeaf9,0xeafb,0xeafc,0xeafe,0xeba3,// 嫄沅洹湲阮暐蔿褘劉杻柳楢洧流溜猷 + 0xeba4,0xeba7,0xeba9,0xebaa,0xebba,0xebbb,0xebbc,0xebbd,0xebc1,0xebc2,0xebc6,0xebc7,0xebcb,0xebcc,0xebcd,0xebcf,// 琉留硫紐類六堉戮陸倫崙淪贇輪鈗律 + 0xebd0,0xebd1,0xebd2,0xebd5,0xebd8,0xebf5,0xebfb,0xeca6,0xeca7,0xecaa,0xecb0,0xecb1,0xecb2,0xecb5,0xecb8,0xecba,// 慄栗率瀜隆椅薏利吏履李梨泥理痢罹 + 0xecbd,0xecbe,0xecc0,0xecc1,0xecc2,0xecc4,0xecc5,0xecc6,0xecc9,0xecca,0xecd0,0xecd5,0xecdd,0xecde,0xecdf,0x0000,// 肄苡裏裡貽邇里離匿溺謚吝燐璘絪 + // 0x6b40 - 0x6bff + 0x0000,0xece0,0xece1,0xece2,0xece4,0xece7,0xece8,0xecea,0xecf6,0xecf7,0xecf8,0xecfa,0xecfe,0xeda1,0xeda2,0xeda3,// 茵藺蚓隣鱗麟佚恁林淋臨卄立笠粒 + 0xeda7,0xedbc,0xedcf,0xedf5,0xeeaa,0xeead,0xeec7,0xeec9,0xeed1,0xeed2,0xeed4,0xeedb,0xeee1,0xeeeb,0xeeec,0xeeed,// 芿茨孱臧渽縡紵菹雎齟吊炙翟鏑佃佺 + 0xeef4,0xefa2,0xefa5,0xefa7,0xefb2,0xefbb,0xefc6,0xefde,0xefe0,0xefe3,0xefe6,0xefe7,0xefe8,0xefe9,0xefea,0xeff2,// 塼琠畑筌鐫癤鮎柾檉淀湞瀞炡玎珽綎 + 0xeffb,0xf0d1,0xf0e7,0xf0f5,0xf1a1,0xf1af,0xf1be,0xf1bf,0xf1d9,0xf1e0,0xf1e6,0xf1f9,0xf2af,0xf2ba,0xf2c6,0xf2ca,// 鋌璪雕悰踪姝湊澍寯焌雋繒沚芷唇搢 + 0xf2cc,0xf2cd,0xf2cf,0xf2d5,0xf2dc,0xf2dd,0xf2de,0xf2df,0xf2e9,0xf2ef,0xf2fa,0xf2fc,0xf3a1,0xf3a7,0xf3c2,0xf3cf,// 晋桭殄畛縝臻蔯袗侄瓆什潗鏶侘簒紮 + 0xf3d9,0xf3e1,0xf3e9,0xf3f2,0xf3f3,0xf4a6,0xf4b2,0xf4bd,0xf4cf,0xf4d8,0xf4da,0xf4dc,0xf4f9,0xf5ac,0xf5ad,0xf5be,// 讖愴猖寀寨倜蹠玔輟簽詹堞剿艸苕邨 + 0xf5c2,0xf5c3,0xf5c7,0xf5d8,0xf5e0,0xf5e2,0xf5ec,0xf5f2,0xf5f4,0xf6a1,0xf6b2,0xf6c4,0xf6c9,0xf6da,0xf6e3,0xf6e9,// 悤憁蔥諏鎚騶蹙瑃朮贅厠穉蚩琛咤拖 + 0xf6ee,0xf6f3,0xf6f8,0xf6fd,0xf7af,0xf7b8,0xf7d9,0xf7e6,0xf7ec,0xf7fe,0xf8be,0xf8c2,0xf8db,0xf8e2,0xf8e7,0xf8ed,// 馱坼晫琸眈糖槌闖擺鈑騙枰暴苞逋曝 + 0xf8f0,0xf8fc,0xf8fe,0xf9ae,0xf9b3,0xf9b7,0xf9b8,0xf9bd,0xf9d5,0xf9e7,0xf9e9,0xf9ef,0xf9f4,0xfaa1,0xfaae,0xfabb,// 輻飇驃陂珌苾馝厦瀚銜鹹闔嫦行瀣荇 + 0xfacb,0xfad5,0xfae0,0xfada,0xfadd,0xfad9,0xfba2,0xfba3,0xfba5,0xfba7,0xfba9,0xfbad,0xfbb5,0xfbb7,0xfbc0,0xfbc5,// 櫶俔睍泫玹晛泂滎灐熒瑩逈暳蹊岵晧 + 0xfbd0,0xfbd8,0xfbda,0xfbf4,0xfca6,0xfcb1,0xfcb7,0xfcc6,0xfcca,0xfccd,0xfcce,0xfcd0,0xfcd2,0xfcd4,0xfcd7,0xfcdd,// 琥芦蒿烘譁奐晥幌愰晄榥湟潢璜簧匯 + 0xfced,0xfcf3,0xfcf5,0xfcfa,0xfcfd,0xfcfe,0xfda4,0xfdac,0xfdaf,0xfdb0,0xfdb2,0xfdbe,0xfdbf,0xfddc,0xfde1,0x0000,// 茴宖鐄斅涍淆驍帿煦珝勛暄煊炘訖 + // 0x6c40 - 0x6cff + 0x0000,0xfde8,0xfdee,0xfdf3,0xfdf5,0xfdf9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 翕囍憘晞熺 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// +}; + + public Ebc2Ksc1() + { + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc2.java b/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc2.java new file mode 100644 index 0000000..18de2da --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc2.java @@ -0,0 +1,596 @@ +package com.eactive.eai.adapter.wca.util; + +public class Ebc2Ksc2 { + protected static char EBC2KSC[] = { + // 0x6d40 - 0x6dff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x6e40 - 0x6eff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x6f40 - 0x6fff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7040 - 0x70ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7140 - 0x71ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7240 - 0x72ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7340 - 0x73ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7440 - 0x74ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7540 - 0x75ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7640 - 0x76ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7740 - 0x77ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7840 - 0x78ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7940 - 0x79ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7a40 - 0x7aff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7b40 - 0x7bff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7c40 - 0x7cff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7d40 - 0x7dff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7e40 - 0x7eff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x7f40 - 0x7fff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8040 - 0x80ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8140 - 0x81ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8240 - 0x82ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8340 - 0x83ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8440 - 0x84ff + 0x0000,0xa4d4,0x0000,0x0000,0xa4a3,0x0000,0xa4a5,0xa4a6,0x0000,0x0000,0xa4aa,0xa4ab,0xa4ac,0xa4ad,0xa4ae,0xa4af,// ㅤ ㄳ ㄵㄶ ㄺㄻㄼㄽㄾㄿ + 0xa4b0,0x0000,0x0000,0x0000,0xa4b4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅀ ㅄ + 0x0000,0xa4bf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅏ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅐ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4c1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅑ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4c2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅒ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅓ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8540 - 0x85ff + 0x0000,0xa4c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅔ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4c5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅕ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4c6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅖ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4c7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅗ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4c8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅘ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅙ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8640 - 0x86ff + 0x0000,0xa4ca,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅚ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4cb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅛ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4cc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅜ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4cd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅝ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅞ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4cf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅟ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8740 - 0x87ff + 0x0000,0xa4d0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅠ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4d1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅡ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4d2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅢ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xa4d3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅣ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8840 - 0x88ff + 0x0000,0xa4a1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㄱ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb0a1,0xb0a2,0x0000,0x0000,0xb0a3,0x0000,0x0000,0xb0a4,0xb0a5,0xb0a6,0xb0a7,0x0000,0x0000,0x0000,0x0000,// 가각 간 갇갈갉갊 + 0x0000,0xb0a8,0x0000,0xb0a9,0xb0aa,0xb0ab,0xb0ac,0xb0ad,0xb0ae,0xb0af,0x0000,0xb0b0,0xb0b1,0xb0b2,0x0000,0x0000,// 감 갑값갓갔강갖갗 같갚갛 + 0x0000,0xb0b3,0xb0b4,0x0000,0x0000,0xb0b5,0x0000,0x0000,0x0000,0xb0b6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 개객 갠 갤 + 0x0000,0xb0b7,0x0000,0xb0b8,0x0000,0xb0b9,0xb0ba,0xb0bb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 갬 갭 갯갰갱 + 0x0000,0xb0bc,0xb0bd,0x0000,0x0000,0xb0be,0x0000,0x0000,0x0000,0xb0bf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 갸갹 갼 걀 + 0x0000,0x0000,0x0000,0x0000,0x0000,0xb0c0,0x0000,0xb0c1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 걋 걍 + 0x0000,0xb0c2,0x0000,0x0000,0x0000,0xb0c3,0x0000,0x0000,0x0000,0xb0c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 걔 걘 걜 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb0c5,0xb0c6,0x0000,0x0000,0xb0c7,0x0000,0x0000,0xb0c8,0xb0c9,0x0000,0xb0ca,0x0000,0x0000,0x0000,0x0000,// 거걱 건 걷걸 걺 + 0x0000,0xb0cb,0x0000,0xb0cc,0x0000,0xb0cd,0xb0ce,0xb0cf,0xb0d0,0x0000,0x0000,0xb0d1,0xb0d2,0xb0d3,0x0000,0x0000,// 검 겁 것겄겅겆 겉겊겋 + // 0x8940 - 0x89ff + 0x0000,0xb0d4,0x0000,0x0000,0x0000,0xb0d5,0x0000,0x0000,0x0000,0xb0d6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 게 겐 겔 + 0x0000,0xb0d7,0x0000,0xb0d8,0x0000,0xb0d9,0xb0da,0xb0db,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 겜 겝 겟겠겡 + 0x0000,0xb0dc,0xb0dd,0xb0de,0x0000,0xb0df,0x0000,0x0000,0xb0e0,0xb0e1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 겨격겪 견 겯결 + 0x0000,0xb0e2,0x0000,0xb0e3,0x0000,0xb0e4,0xb0e5,0xb0e6,0x0000,0x0000,0x0000,0xb0e7,0x0000,0x0000,0x0000,0x0000,// 겸 겹 겻겼경 곁 + 0x0000,0xb0e8,0x0000,0x0000,0x0000,0xb0e9,0x0000,0x0000,0x0000,0xb0ea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 계 곈 곌 + 0x0000,0x0000,0x0000,0xb0eb,0x0000,0xb0ec,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 곕 곗 + 0x0000,0xb0ed,0xb0ee,0x0000,0x0000,0xb0ef,0x0000,0x0000,0xb0f0,0xb0f1,0x0000,0xb0f2,0x0000,0xb0f3,0x0000,0x0000,// 고곡 곤 곧골 곪 곬 + 0xb0f4,0xb0f5,0x0000,0xb0f6,0x0000,0xb0f7,0x0000,0xb0f8,0xb0f9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 곯곰 곱 곳 공곶 + 0x0000,0xb0fa,0xb0fb,0x0000,0x0000,0xb0fc,0x0000,0x0000,0x0000,0xb0fd,0x0000,0xb0fe,0x0000,0x0000,0x0000,0x0000,// 과곽 관 괄 괆 + 0x0000,0xb1a1,0x0000,0xb1a2,0x0000,0xb1a3,0x0000,0xb1a4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 괌 괍 괏 광 + 0x0000,0xb1a5,0x0000,0x0000,0x0000,0xb1a6,0x0000,0x0000,0x0000,0xb1a7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 괘 괜 괠 + 0x0000,0x0000,0x0000,0xb1a8,0x0000,0x0000,0xb1a9,0xb1aa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 괩 괬괭 + // 0x8a40 - 0x8aff + 0x0000,0xb1ab,0xb1ac,0x0000,0x0000,0xb1ad,0x0000,0x0000,0x0000,0xb1ae,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 괴괵 괸 괼 + 0x0000,0xb1af,0x0000,0xb1b0,0x0000,0xb1b1,0x0000,0xb1b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 굄 굅 굇 굉 + 0x0000,0xb1b3,0x0000,0x0000,0x0000,0xb1b4,0x0000,0x0000,0x0000,0xb1b5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 교 굔 굘 + 0x0000,0x0000,0x0000,0xb1b6,0x0000,0xb1b7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 굡 굣 + 0x0000,0xb1b8,0xb1b9,0x0000,0x0000,0xb1ba,0x0000,0x0000,0xb1bb,0xb1bc,0xb1bd,0xb1be,0x0000,0x0000,0x0000,0x0000,// 구국 군 굳굴굵굶 + 0xb1bf,0xb1c0,0x0000,0xb1c1,0x0000,0xb1c2,0x0000,0xb1c3,0xb1c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 굻굼 굽 굿 궁궂 + 0x0000,0xb1c5,0xb1c6,0x0000,0x0000,0xb1c7,0x0000,0x0000,0x0000,0xb1c8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 궈궉 권 궐 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb1c9,0xb1ca,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 궜궝 + 0x0000,0xb1cb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 궤 + 0x0000,0x0000,0x0000,0x0000,0x0000,0xb1cc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 궷 + 0x0000,0xb1cd,0xb1ce,0x0000,0x0000,0xb1cf,0x0000,0x0000,0x0000,0xb1d0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 귀귁 귄 귈 + 0x0000,0xb1d1,0x0000,0xb1d2,0x0000,0xb1d3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 귐 귑 귓 + // 0x8b40 - 0x8bff + 0x0000,0xb1d4,0x0000,0x0000,0x0000,0xb1d5,0x0000,0x0000,0x0000,0xb1d6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 규 균 귤 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb1d7,0xb1d8,0x0000,0x0000,0xb1d9,0x0000,0x0000,0xb1da,0xb1db,0xb1dc,0x0000,0x0000,0x0000,0x0000,0x0000,// 그극 근 귿글긁 + 0x0000,0xb1dd,0x0000,0xb1de,0x0000,0xb1df,0x0000,0xb1e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 금 급 긋 긍 + 0x0000,0xb1e1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 긔 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb1e2,0xb1e3,0x0000,0x0000,0xb1e4,0x0000,0x0000,0xb1e5,0xb1e6,0x0000,0xb1e7,0x0000,0x0000,0x0000,0x0000,// 기긱 긴 긷길 긺 + 0x0000,0xb1e8,0x0000,0xb1e9,0x0000,0xb1ea,0x0000,0xb1eb,0xb1ec,0x0000,0x0000,0x0000,0xb1ed,0x0000,0x0000,0x0000,// 김 깁 깃 깅깆 깊 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x8c40 - 0x8cff + 0x0000,0xa4a2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㄲ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb1ee,0xb1ef,0xb1f0,0x0000,0xb1f1,0x0000,0x0000,0x0000,0xb1f2,0x0000,0xb1f3,0x0000,0x0000,0x0000,0x0000,// 까깍깎 깐 깔 깖 + 0x0000,0xb1f4,0x0000,0xb1f5,0x0000,0xb1f6,0xb1f7,0xb1f8,0x0000,0x0000,0x0000,0xb1f9,0x0000,0x0000,0x0000,0x0000,// 깜 깝 깟깠깡 깥 + 0x0000,0xb1fa,0xb1fb,0x0000,0x0000,0xb1fc,0x0000,0x0000,0x0000,0xb1fd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 깨깩 깬 깰 + 0x0000,0xb1fe,0x0000,0xb2a1,0x0000,0xb2a2,0xb2a3,0xb2a4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 깸 깹 깻깼깽 + 0x0000,0xb2a5,0xb2a6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb2a7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꺄꺅 꺌 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb2a8,0xb2a9,0xb2aa,0x0000,0xb2ab,0x0000,0x0000,0x0000,0xb2ac,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꺼꺽꺾 껀 껄 + 0x0000,0xb2ad,0x0000,0xb2ae,0x0000,0xb2af,0xb2b0,0xb2b1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 껌 껍 껏껐껑 + // 0x8d40 - 0x8dff + 0x0000,0xb2b2,0xb2b3,0x0000,0x0000,0xb2b4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 께껙 껜 + 0x0000,0xb2b5,0x0000,0x0000,0x0000,0xb2b6,0x0000,0xb2b7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 껨 껫 껭 + 0x0000,0xb2b8,0x0000,0x0000,0x0000,0xb2b9,0x0000,0x0000,0x0000,0xb2ba,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 껴 껸 껼 + 0x0000,0x0000,0x0000,0x0000,0x0000,0xb2bb,0xb2bc,0x0000,0x0000,0x0000,0x0000,0xb2bd,0x0000,0x0000,0x0000,0x0000,// 꼇꼈 꼍 + 0x0000,0xb2be,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꼐 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb2bf,0xb2c0,0x0000,0x0000,0xb2c1,0x0000,0xb2c2,0x0000,0xb2c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꼬꼭 꼰 꼲 꼴 + 0x0000,0xb2c4,0x0000,0xb2c5,0x0000,0xb2c6,0x0000,0xb2c7,0xb2c8,0xb2c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꼼 꼽 꼿 꽁꽂꽃 + 0x0000,0xb2ca,0xb2cb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb2cc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꽈꽉 꽐 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb2cd,0xb2ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꽜꽝 + 0x0000,0xb2cf,0xb2d0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꽤꽥 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb2d1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꽹 + // 0x8e40 - 0x8eff + 0x0000,0xb2d2,0x0000,0x0000,0x0000,0xb2d3,0x0000,0x0000,0x0000,0xb2d4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꾀 꾄 꾈 + 0x0000,0xb2d5,0x0000,0xb2d6,0x0000,0x0000,0x0000,0xb2d7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꾐 꾑 꾕 + 0x0000,0xb2d8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꾜 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb2d9,0xb2da,0x0000,0x0000,0xb2db,0x0000,0x0000,0x0000,0xb2dc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꾸꾹 꾼 꿀 + 0xb2dd,0xb2de,0x0000,0xb2df,0x0000,0xb2e0,0x0000,0xb2e1,0xb2e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꿇꿈 꿉 꿋 꿍꿎 + 0x0000,0xb2e3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb2e4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꿔 꿜 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb2e5,0xb2e6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꿨꿩 + 0x0000,0xb2e7,0xb2e8,0x0000,0x0000,0xb2e9,0x0000,0x0000,0x0000,0xb2ea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 꿰꿱 꿴 꿸 + 0x0000,0xb2eb,0x0000,0xb2ec,0x0000,0x0000,0xb2ed,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뀀 뀁 뀄 + 0x0000,0xb2ee,0x0000,0x0000,0x0000,0xb2ef,0x0000,0x0000,0x0000,0xb2f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뀌 뀐 뀔 + 0x0000,0xb2f1,0x0000,0xb2f2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뀜 뀝 + // 0x8f40 - 0x8fff + 0x0000,0xb2f3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뀨 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb2f4,0xb2f5,0x0000,0x0000,0xb2f6,0x0000,0xb2f7,0x0000,0xb2f8,0x0000,0xb2f9,0x0000,0x0000,0x0000,0x0000,// 끄끅 끈 끊 끌 끎 + 0xb2fa,0xb2fb,0x0000,0xb2fc,0x0000,0xb2fd,0x0000,0xb2fe,0x0000,0x0000,0x0000,0xb3a1,0x0000,0x0000,0x0000,0x0000,// 끓끔 끕 끗 끙 끝 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb3a2,0xb3a3,0x0000,0x0000,0xb3a4,0x0000,0x0000,0x0000,0xb3a5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 끼끽 낀 낄 + 0x0000,0xb3a6,0x0000,0xb3a7,0x0000,0xb3a8,0x0000,0xb3a9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 낌 낍 낏 낑 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x9040 - 0x90ff + 0x0000,0xa4a4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㄴ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb3aa,0xb3ab,0xb3ac,0x0000,0xb3ad,0x0000,0x0000,0xb3ae,0xb3af,0xb3b0,0xb3b1,0x0000,0x0000,0x0000,0x0000,// 나낙낚 난 낟날낡낢 + 0x0000,0xb3b2,0x0000,0xb3b3,0x0000,0xb3b4,0xb3b5,0xb3b6,0xb3b7,0xb3b8,0x0000,0xb3b9,0x0000,0xb3ba,0x0000,0x0000,// 남 납 낫났낭낮낯 낱 낳 + 0x0000,0xb3bb,0xb3bc,0x0000,0x0000,0xb3bd,0x0000,0x0000,0x0000,0xb3be,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 내낵 낸 낼 + 0x0000,0xb3bf,0x0000,0xb3c0,0x0000,0xb3c1,0xb3c2,0xb3c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 냄 냅 냇냈냉 + 0x0000,0xb3c4,0xb3c5,0x0000,0x0000,0xb3c6,0x0000,0x0000,0x0000,0xb3c7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 냐냑 냔 냘 + 0x0000,0xb3c8,0x0000,0x0000,0x0000,0x0000,0x0000,0xb3c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 냠 냥 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb3ca,0xb3cb,0x0000,0xb3cc,0xb3cd,0x0000,0x0000,0x0000,0xb3ce,0x0000,0xb3cf,0xb3d0,0x0000,0x0000,0x0000,// 너넉 넋넌 널 넒넓 + 0x0000,0xb3d1,0x0000,0xb3d2,0x0000,0xb3d3,0xb3d4,0xb3d5,0x0000,0x0000,0x0000,0x0000,0x0000,0xb3d6,0x0000,0x0000,// 넘 넙 넛넜넝 넣 + // 0x9140 - 0x91ff + 0x0000,0xb3d7,0xb3d8,0x0000,0x0000,0xb3d9,0x0000,0x0000,0x0000,0xb3da,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 네넥 넨 넬 + 0x0000,0xb3db,0x0000,0xb3dc,0x0000,0xb3dd,0xb3de,0xb3df,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 넴 넵 넷넸넹 + 0x0000,0xb3e0,0xb3e1,0x0000,0x0000,0xb3e2,0x0000,0x0000,0x0000,0xb3e3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 녀녁 년 녈 + 0x0000,0xb3e4,0x0000,0xb3e5,0x0000,0x0000,0xb3e6,0xb3e7,0x0000,0x0000,0xb3e8,0x0000,0x0000,0x0000,0x0000,0x0000,// 념 녑 녔녕 녘 + 0x0000,0xb3e9,0x0000,0x0000,0x0000,0xb3ea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 녜 녠 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb3eb,0xb3ec,0x0000,0x0000,0xb3ed,0x0000,0x0000,0x0000,0xb3ee,0x0000,0xb3ef,0x0000,0x0000,0x0000,0x0000,// 노녹 논 놀 놂 + 0x0000,0xb3f0,0x0000,0xb3f1,0x0000,0xb3f2,0x0000,0xb3f3,0x0000,0x0000,0x0000,0x0000,0xb3f4,0xb3f5,0x0000,0x0000,// 놈 놉 놋 농 높놓 + 0x0000,0xb3f6,0x0000,0x0000,0x0000,0xb3f7,0x0000,0x0000,0x0000,0xb3f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 놔 놘 놜 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb3f9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 놨 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x9240 - 0x92ff + 0x0000,0xb3fa,0x0000,0x0000,0x0000,0xb3fb,0x0000,0x0000,0x0000,0xb3fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뇌 뇐 뇔 + 0x0000,0xb3fd,0x0000,0xb3fe,0x0000,0xb4a1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뇜 뇝 뇟 + 0x0000,0xb4a2,0xb4a3,0x0000,0x0000,0xb4a4,0x0000,0x0000,0x0000,0xb4a5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뇨뇩 뇬 뇰 + 0x0000,0x0000,0x0000,0xb4a6,0x0000,0xb4a7,0x0000,0xb4a8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뇹 뇻 뇽 + 0x0000,0xb4a9,0xb4aa,0x0000,0x0000,0xb4ab,0x0000,0x0000,0xb4ac,0xb4ad,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 누눅 눈 눋눌 + 0x0000,0xb4ae,0x0000,0xb4af,0x0000,0xb4b0,0x0000,0xb4b1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 눔 눕 눗 눙 + 0x0000,0xb4b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 눠 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb4b3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 눴 + 0x0000,0xb4b4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 눼 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb4b5,0x0000,0x0000,0x0000,0xb4b6,0x0000,0x0000,0x0000,0xb4b7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뉘 뉜 뉠 + 0x0000,0xb4b8,0x0000,0xb4b9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뉨 뉩 + // 0x9340 - 0x93ff + 0x0000,0xb4ba,0xb4bb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb4bc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뉴뉵 뉼 + 0x0000,0xb4bd,0x0000,0xb4be,0x0000,0x0000,0x0000,0xb4bf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 늄 늅 늉 + 0x0000,0xb4c0,0xb4c1,0x0000,0x0000,0xb4c2,0x0000,0x0000,0x0000,0xb4c3,0xb4c4,0xb4c5,0x0000,0x0000,0x0000,0x0000,// 느늑 는 늘늙늚 + 0x0000,0xb4c6,0x0000,0xb4c7,0x0000,0xb4c8,0x0000,0xb4c9,0xb4ca,0x0000,0x0000,0x0000,0xb4cb,0x0000,0x0000,0x0000,// 늠 늡 늣 능늦 늪 + 0x0000,0xb4cc,0x0000,0x0000,0x0000,0xb4cd,0x0000,0x0000,0x0000,0xb4ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 늬 늰 늴 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb4cf,0xb4d0,0x0000,0x0000,0xb4d1,0x0000,0x0000,0x0000,0xb4d2,0x0000,0xb4d3,0x0000,0x0000,0x0000,0x0000,// 니닉 닌 닐 닒 + 0x0000,0xb4d4,0x0000,0xb4d5,0x0000,0xb4d6,0x0000,0xb4d7,0x0000,0x0000,0x0000,0x0000,0xb4d8,0x0000,0x0000,0x0000,// 님 닙 닛 닝 닢 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x9440 - 0x94ff + 0x0000,0xa4a7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㄷ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb4d9,0xb4da,0xb4db,0x0000,0xb4dc,0x0000,0x0000,0xb4dd,0xb4de,0xb4df,0xb4e0,0xb4e1,0x0000,0x0000,0x0000,// 다닥닦 단 닫달닭닮닯 + 0xb4e2,0xb4e3,0x0000,0xb4e4,0x0000,0xb4e5,0xb4e6,0xb4e7,0xb4e8,0xb4e9,0x0000,0x0000,0x0000,0xb4ea,0x0000,0x0000,// 닳담 답 닷닸당닺닻 닿 + 0x0000,0xb4eb,0xb4ec,0x0000,0x0000,0xb4ed,0x0000,0x0000,0x0000,0xb4ee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 대댁 댄 댈 + 0x0000,0xb4ef,0x0000,0xb4f0,0x0000,0xb4f1,0xb4f2,0xb4f3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 댐 댑 댓댔댕 + 0x0000,0xb4f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 댜 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb4f5,0xb4f6,0xb4f7,0x0000,0xb4f8,0x0000,0x0000,0xb4f9,0xb4fa,0x0000,0xb4fb,0xb4fc,0x0000,0x0000,0x0000,// 더덕덖 던 덛덜 덞덟 + 0x0000,0xb4fd,0x0000,0xb4fe,0x0000,0xb5a1,0x0000,0xb5a2,0x0000,0xb5a3,0x0000,0x0000,0xb5a4,0x0000,0x0000,0x0000,// 덤 덥 덧 덩 덫 덮 + // 0x9540 - 0x95ff + 0x0000,0xb5a5,0xb5a6,0x0000,0x0000,0xb5a7,0x0000,0x0000,0x0000,0xb5a8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 데덱 덴 델 + 0x0000,0xb5a9,0x0000,0xb5aa,0x0000,0xb5ab,0xb5ac,0xb5ad,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뎀 뎁 뎃뎄뎅 + 0x0000,0xb5ae,0x0000,0x0000,0x0000,0xb5af,0x0000,0x0000,0x0000,0xb5b0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뎌 뎐 뎔 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb5b1,0xb5b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뎠뎡 + 0x0000,0xb5b3,0x0000,0x0000,0x0000,0xb5b4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뎨 뎬 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb5b5,0xb5b6,0x0000,0x0000,0xb5b7,0x0000,0x0000,0xb5b8,0xb5b9,0x0000,0xb5ba,0x0000,0xb5bb,0x0000,0x0000,// 도독 돈 돋돌 돎 돐 + 0x0000,0xb5bc,0x0000,0xb5bd,0x0000,0xb5be,0x0000,0xb5bf,0x0000,0xb5c0,0x0000,0xb5c1,0x0000,0x0000,0x0000,0x0000,// 돔 돕 돗 동 돛 돝 + 0x0000,0xb5c2,0x0000,0x0000,0x0000,0xb5c3,0x0000,0x0000,0x0000,0xb5c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 돠 돤 돨 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb5c5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 돼 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb5c6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 됐 + // 0x9640 - 0x96ff + 0x0000,0xb5c7,0x0000,0x0000,0x0000,0xb5c8,0x0000,0x0000,0x0000,0xb5c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 되 된 될 + 0x0000,0xb5ca,0x0000,0xb5cb,0x0000,0xb5cc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 됨 됩 됫 + 0x0000,0xb5cd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 됴 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb5ce,0xb5cf,0x0000,0x0000,0xb5d0,0x0000,0x0000,0x0000,0xb5d1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 두둑 둔 둘 + 0x0000,0xb5d2,0x0000,0xb5d3,0x0000,0xb5d4,0x0000,0xb5d5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 둠 둡 둣 둥 + 0x0000,0xb5d6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 둬 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb5d7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뒀 + 0x0000,0xb5d8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뒈 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb5d9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뒝 + 0x0000,0xb5da,0x0000,0x0000,0x0000,0xb5db,0x0000,0x0000,0x0000,0xb5dc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뒤 뒨 뒬 + 0x0000,0x0000,0x0000,0xb5dd,0x0000,0xb5de,0x0000,0xb5df,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뒵 뒷 뒹 + // 0x9740 - 0x97ff + 0x0000,0xb5e0,0x0000,0x0000,0x0000,0xb5e1,0x0000,0x0000,0x0000,0xb5e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 듀 듄 듈 + 0x0000,0xb5e3,0x0000,0x0000,0x0000,0x0000,0x0000,0xb5e4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 듐 듕 + 0x0000,0xb5e5,0xb5e6,0x0000,0x0000,0xb5e7,0x0000,0x0000,0xb5e8,0xb5e9,0x0000,0xb5ea,0x0000,0x0000,0x0000,0x0000,// 드득 든 듣들 듦 + 0x0000,0xb5eb,0x0000,0xb5ec,0x0000,0xb5ed,0x0000,0xb5ee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 듬 듭 듯 등 + 0x0000,0xb5ef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 듸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb5f0,0xb5f1,0x0000,0x0000,0xb5f2,0x0000,0x0000,0xb5f3,0xb5f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 디딕 딘 딛딜 + 0x0000,0xb5f5,0x0000,0xb5f6,0x0000,0xb5f7,0xb5f8,0xb5f9,0xb5fa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 딤 딥 딧딨딩딪 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x9840 - 0x98ff + 0x0000,0xa4a8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㄸ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb5fb,0xb5fc,0x0000,0x0000,0xb5fd,0x0000,0x0000,0x0000,0xb5fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 따딱 딴 딸 + 0x0000,0xb6a1,0x0000,0xb6a2,0x0000,0xb6a3,0xb6a4,0xb6a5,0x0000,0x0000,0x0000,0x0000,0x0000,0xb6a6,0x0000,0x0000,// 땀 땁 땃땄땅 땋 + 0x0000,0xb6a7,0xb6a8,0x0000,0x0000,0xb6a9,0x0000,0x0000,0x0000,0xb6aa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 때땍 땐 땔 + 0x0000,0xb6ab,0x0000,0xb6ac,0x0000,0xb6ad,0xb6ae,0xb6af,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 땜 땝 땟땠땡 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb6b0,0xb6b1,0x0000,0x0000,0xb6b2,0x0000,0x0000,0x0000,0xb6b3,0x0000,0xb6b4,0xb6b5,0x0000,0x0000,0x0000,// 떠떡 떤 떨 떪떫 + 0x0000,0xb6b6,0x0000,0xb6b7,0x0000,0xb6b8,0xb6b9,0xb6ba,0x0000,0x0000,0x0000,0x0000,0x0000,0xb6bb,0x0000,0x0000,// 떰 떱 떳떴떵 떻 + // 0x9940 - 0x99ff + 0x0000,0xb6bc,0xb6bd,0x0000,0x0000,0xb6be,0x0000,0x0000,0x0000,0xb6bf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 떼떽 뗀 뗄 + 0x0000,0xb6c0,0x0000,0xb6c1,0x0000,0xb6c2,0xb6c3,0xb6c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뗌 뗍 뗏뗐뗑 + 0x0000,0xb6c5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뗘 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb6c6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뗬 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb6c7,0xb6c8,0x0000,0x0000,0xb6c9,0x0000,0x0000,0x0000,0xb6ca,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 또똑 똔 똘 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb6cb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 똥 + 0x0000,0xb6cc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb6cd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 똬 똴 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb6ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뙈 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// +}; + + public Ebc2Ksc2() + { + + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc3.java b/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc3.java new file mode 100644 index 0000000..836e31d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc3.java @@ -0,0 +1,596 @@ +package com.eactive.eai.adapter.wca.util; + +public class Ebc2Ksc3 { + protected static char EBC2KSC[] = { + // 0x9a40 - 0x9aff + 0x0000,0xb6cf,0x0000,0x0000,0x0000,0xb6d0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뙤 뙨 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb6d1,0xb6d2,0x0000,0x0000,0xb6d3,0x0000,0x0000,0x0000,0xb6d4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뚜뚝 뚠 뚤 + 0xb6d5,0xb6d6,0x0000,0x0000,0x0000,0x0000,0x0000,0xb6d7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뚫뚬 뚱 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb6d8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뛔 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb6d9,0x0000,0x0000,0x0000,0xb6da,0x0000,0x0000,0x0000,0xb6db,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뛰 뛴 뛸 + 0x0000,0xb6dc,0x0000,0xb6dd,0x0000,0x0000,0x0000,0xb6de,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뜀 뜁 뜅 + // 0x9b40 - 0x9bff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb6df,0xb6e0,0x0000,0x0000,0xb6e1,0x0000,0x0000,0xb6e2,0xb6e3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뜨뜩 뜬 뜯뜰 + 0x0000,0xb6e4,0x0000,0xb6e5,0x0000,0xb6e6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뜸 뜹 뜻 + 0x0000,0xb6e7,0x0000,0x0000,0x0000,0xb6e8,0x0000,0x0000,0x0000,0xb6e9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 띄 띈 띌 + 0x0000,0xb6ea,0x0000,0xb6eb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 띔 띕 + 0x0000,0xb6ec,0x0000,0x0000,0x0000,0xb6ed,0x0000,0x0000,0x0000,0xb6ee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 띠 띤 띨 + 0x0000,0xb6ef,0x0000,0xb6f0,0x0000,0xb6f1,0x0000,0xb6f2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 띰 띱 띳 띵 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0x9c40 - 0x9cff + 0x0000,0xa4a9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㄹ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb6f3,0xb6f4,0x0000,0x0000,0xb6f5,0x0000,0x0000,0x0000,0xb6f6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 라락 란 랄 + 0x0000,0xb6f7,0x0000,0xb6f8,0x0000,0xb6f9,0xb6fa,0xb6fb,0xb6fc,0x0000,0x0000,0x0000,0xb6fd,0xb6fe,0x0000,0x0000,// 람 랍 랏랐랑랒 랖랗 + 0x0000,0xb7a1,0xb7a2,0x0000,0x0000,0xb7a3,0x0000,0x0000,0x0000,0xb7a4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 래랙 랜 랠 + 0x0000,0xb7a5,0x0000,0xb7a6,0x0000,0xb7a7,0xb7a8,0xb7a9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 램 랩 랫랬랭 + 0x0000,0xb7aa,0xb7ab,0x0000,0x0000,0xb7ac,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 랴략 랸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0xb7ad,0x0000,0xb7ae,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 럇 량 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb7af,0xb7b0,0x0000,0x0000,0xb7b1,0x0000,0x0000,0x0000,0xb7b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 러럭 런 럴 + 0x0000,0xb7b3,0x0000,0xb7b4,0x0000,0xb7b5,0xb7b6,0xb7b7,0x0000,0x0000,0x0000,0x0000,0x0000,0xb7b8,0x0000,0x0000,// 럼 럽 럿렀렁 렇 + // 0x9d40 - 0x9dff + 0x0000,0xb7b9,0xb7ba,0x0000,0x0000,0xb7bb,0x0000,0x0000,0x0000,0xb7bc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 레렉 렌 렐 + 0x0000,0xb7bd,0x0000,0xb7be,0x0000,0xb7bf,0x0000,0xb7c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 렘 렙 렛 렝 + 0x0000,0xb7c1,0xb7c2,0x0000,0x0000,0xb7c3,0x0000,0x0000,0x0000,0xb7c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 려력 련 렬 + 0x0000,0xb7c5,0x0000,0xb7c6,0x0000,0xb7c7,0xb7c8,0xb7c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 렴 렵 렷렸령 + 0x0000,0xb7ca,0x0000,0x0000,0x0000,0xb7cb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 례 롄 + 0x0000,0x0000,0x0000,0xb7cc,0x0000,0xb7cd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 롑 롓 + 0x0000,0xb7ce,0xb7cf,0x0000,0x0000,0xb7d0,0x0000,0x0000,0x0000,0xb7d1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 로록 론 롤 + 0x0000,0xb7d2,0x0000,0xb7d3,0x0000,0xb7d4,0x0000,0xb7d5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 롬 롭 롯 롱 + 0x0000,0xb7d6,0x0000,0x0000,0x0000,0xb7d7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 롸 롼 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb7d8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뢍 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb7d9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뢨 + // 0x9e40 - 0x9eff + 0x0000,0xb7da,0x0000,0x0000,0x0000,0xb7db,0x0000,0x0000,0x0000,0xb7dc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뢰 뢴 뢸 + 0x0000,0xb7dd,0x0000,0xb7de,0x0000,0xb7df,0x0000,0xb7e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 룀 룁 룃 룅 + 0x0000,0xb7e1,0x0000,0x0000,0x0000,0xb7e2,0x0000,0x0000,0x0000,0xb7e3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 료 룐 룔 + 0x0000,0x0000,0x0000,0xb7e4,0x0000,0xb7e5,0x0000,0xb7e6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 룝 룟 룡 + 0x0000,0xb7e7,0xb7e8,0x0000,0x0000,0xb7e9,0x0000,0x0000,0x0000,0xb7ea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 루룩 룬 룰 + 0x0000,0xb7eb,0x0000,0xb7ec,0x0000,0xb7ed,0x0000,0xb7ee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 룸 룹 룻 룽 + 0x0000,0xb7ef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뤄 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb7f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뤘 + 0x0000,0xb7f1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뤠 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb7f2,0xb7f3,0x0000,0x0000,0xb7f4,0x0000,0x0000,0x0000,0xb7f5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뤼뤽 륀 륄 + 0x0000,0xb7f6,0x0000,0x0000,0x0000,0xb7f7,0x0000,0xb7f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 륌 륏 륑 + // 0x9f40 - 0x9fff + 0x0000,0xb7f9,0xb7fa,0x0000,0x0000,0xb7fb,0x0000,0x0000,0x0000,0xb7fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 류륙 륜 률 + 0x0000,0xb7fd,0x0000,0xb7fe,0x0000,0xb8a1,0x0000,0xb8a2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 륨 륩 륫 륭 + 0x0000,0xb8a3,0xb8a4,0x0000,0x0000,0xb8a5,0x0000,0x0000,0x0000,0xb8a6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 르륵 른 를 + 0x0000,0xb8a7,0x0000,0xb8a8,0x0000,0xb8a9,0x0000,0xb8aa,0xb8ab,0x0000,0x0000,0xb8ac,0xb8ad,0x0000,0x0000,0x0000,// 름 릅 릇 릉릊 릍릎 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb8ae,0xb8af,0x0000,0x0000,0xb8b0,0x0000,0x0000,0x0000,0xb8b1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 리릭 린 릴 + 0x0000,0xb8b2,0x0000,0xb8b3,0x0000,0xb8b4,0x0000,0xb8b5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 림 립 릿 링 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xa040 - 0xa0ff + 0x0000,0xa4b1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅁ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb8b6,0xb8b7,0x0000,0x0000,0xb8b8,0x0000,0xb8b9,0xb8ba,0xb8bb,0xb8bc,0xb8bd,0x0000,0x0000,0x0000,0x0000,// 마막 만 많맏말맑맒 + 0x0000,0xb8be,0x0000,0xb8bf,0x0000,0xb8c0,0x0000,0xb8c1,0xb8c2,0x0000,0x0000,0xb8c3,0x0000,0xb8c4,0x0000,0x0000,// 맘 맙 맛 망맞 맡 맣 + 0x0000,0xb8c5,0xb8c6,0x0000,0x0000,0xb8c7,0x0000,0x0000,0x0000,0xb8c8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 매맥 맨 맬 + 0x0000,0xb8c9,0x0000,0xb8ca,0x0000,0xb8cb,0xb8cc,0xb8cd,0xb8ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 맴 맵 맷맸맹맺 + 0x0000,0xb8cf,0xb8d0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb8d1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 먀먁 먈 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb8d2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 먕 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb8d3,0xb8d4,0x0000,0x0000,0xb8d5,0x0000,0x0000,0x0000,0xb8d6,0x0000,0xb8d7,0x0000,0x0000,0x0000,0x0000,// 머먹 먼 멀 멂 + 0x0000,0xb8d8,0x0000,0xb8d9,0x0000,0xb8da,0x0000,0xb8db,0xb8dc,0x0000,0x0000,0x0000,0x0000,0xb8dd,0x0000,0x0000,// 멈 멉 멋 멍멎 멓 + // 0xa140 - 0xa1ff + 0x0000,0xb8de,0xb8df,0x0000,0x0000,0xb8e0,0x0000,0x0000,0x0000,0xb8e1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 메멕 멘 멜 + 0x0000,0xb8e2,0x0000,0xb8e3,0x0000,0xb8e4,0xb8e5,0xb8e6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 멤 멥 멧멨멩 + 0x0000,0xb8e7,0xb8e8,0x0000,0x0000,0xb8e9,0x0000,0x0000,0x0000,0xb8ea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 며멱 면 멸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0xb8eb,0xb8ec,0xb8ed,0x0000,0xb8ee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 몃몄명 몇 + 0x0000,0xb8ef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 몌 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb8f0,0xb8f1,0x0000,0xb8f2,0xb8f3,0x0000,0x0000,0x0000,0xb8f4,0x0000,0xb8f5,0x0000,0x0000,0x0000,0x0000,// 모목 몫몬 몰 몲 + 0x0000,0xb8f6,0x0000,0xb8f7,0x0000,0xb8f8,0x0000,0xb8f9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 몸 몹 못 몽 + 0x0000,0xb8fa,0x0000,0x0000,0x0000,0xb8fb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뫄 뫈 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xb8fc,0xb8fd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뫘뫙 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xa240 - 0xa2ff + 0x0000,0xb8fe,0x0000,0x0000,0x0000,0xb9a1,0x0000,0x0000,0x0000,0xb9a2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뫼 묀 묄 + 0x0000,0x0000,0x0000,0xb9a3,0x0000,0xb9a4,0x0000,0xb9a5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 묍 묏 묑 + 0x0000,0xb9a6,0x0000,0x0000,0x0000,0xb9a7,0x0000,0x0000,0x0000,0xb9a8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 묘 묜 묠 + 0x0000,0x0000,0x0000,0xb9a9,0x0000,0xb9aa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 묩 묫 + 0x0000,0xb9ab,0xb9ac,0xb9ad,0x0000,0xb9ae,0x0000,0x0000,0xb9af,0xb9b0,0xb9b1,0xb9b2,0x0000,0x0000,0x0000,0x0000,// 무묵묶 문 묻물묽묾 + 0x0000,0xb9b3,0x0000,0xb9b4,0x0000,0xb9b5,0x0000,0xb9b6,0x0000,0x0000,0x0000,0xb9b7,0x0000,0xb9b8,0x0000,0x0000,// 뭄 뭅 뭇 뭉 뭍 뭏 + 0x0000,0xb9b9,0x0000,0x0000,0x0000,0xb9ba,0x0000,0x0000,0x0000,0xb9bb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뭐 뭔 뭘 + 0x0000,0x0000,0x0000,0xb9bc,0x0000,0xb9bd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뭡 뭣 + 0x0000,0xb9be,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뭬 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb9bf,0x0000,0x0000,0x0000,0xb9c0,0x0000,0x0000,0x0000,0xb9c1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뮈 뮌 뮐 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xa340 - 0xa3ff + 0x0000,0xb9c2,0x0000,0x0000,0x0000,0xb9c3,0x0000,0x0000,0x0000,0xb9c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뮤 뮨 뮬 + 0x0000,0xb9c5,0x0000,0x0000,0x0000,0xb9c6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뮴 뮷 + 0x0000,0xb9c7,0x0000,0x0000,0x0000,0xb9c8,0x0000,0x0000,0x0000,0xb9c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 므 믄 믈 + 0x0000,0xb9ca,0x0000,0x0000,0x0000,0xb9cb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 믐 믓 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb9cc,0xb9cd,0x0000,0x0000,0xb9ce,0x0000,0x0000,0xb9cf,0xb9d0,0x0000,0xb9d1,0x0000,0x0000,0x0000,0x0000,// 미믹 민 믿밀 밂 + 0x0000,0xb9d2,0x0000,0xb9d3,0x0000,0xb9d4,0xb9d5,0xb9d6,0x0000,0xb9d7,0x0000,0xb9d8,0x0000,0x0000,0x0000,0x0000,// 밈 밉 밋밌밍 및 밑 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xa440 - 0xa4ff + 0x0000,0xa4b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅂ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb9d9,0xb9da,0xb9db,0xb9dc,0xb9dd,0x0000,0x0000,0xb9de,0xb9df,0xb9e0,0xb9e1,0xb9e2,0x0000,0x0000,0x0000,// 바박밖밗반 받발밝밞밟 + 0x0000,0xb9e3,0x0000,0xb9e4,0x0000,0xb9e5,0x0000,0xb9e6,0x0000,0x0000,0x0000,0xb9e7,0x0000,0x0000,0x0000,0x0000,// 밤 밥 밧 방 밭 + 0x0000,0xb9e8,0xb9e9,0x0000,0x0000,0xb9ea,0x0000,0x0000,0x0000,0xb9eb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 배백 밴 밸 + 0x0000,0xb9ec,0x0000,0xb9ed,0x0000,0xb9ee,0xb9ef,0xb9f0,0x0000,0x0000,0x0000,0xb9f1,0x0000,0x0000,0x0000,0x0000,// 뱀 뱁 뱃뱄뱅 뱉 + 0x0000,0xb9f2,0xb9f3,0x0000,0x0000,0xb9f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뱌뱍 뱐 + 0x0000,0x0000,0x0000,0xb9f5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뱝 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xb9f6,0xb9f7,0x0000,0x0000,0xb9f8,0x0000,0x0000,0xb9f9,0xb9fa,0x0000,0xb9fb,0x0000,0x0000,0x0000,0x0000,// 버벅 번 벋벌 벎 + 0x0000,0xb9fc,0x0000,0xb9fd,0x0000,0xb9fe,0x0000,0xbaa1,0xbaa2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 범 법 벗 벙벚 + // 0xa540 - 0xa5ff + 0x0000,0xbaa3,0xbaa4,0x0000,0x0000,0xbaa5,0x0000,0x0000,0xbaa6,0xbaa7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 베벡 벤 벧벨 + 0x0000,0xbaa8,0x0000,0xbaa9,0x0000,0xbaaa,0xbaab,0xbaac,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 벰 벱 벳벴벵 + 0x0000,0xbaad,0xbaae,0x0000,0x0000,0xbaaf,0x0000,0x0000,0x0000,0xbab0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 벼벽 변 별 + 0x0000,0x0000,0x0000,0xbab1,0x0000,0xbab2,0xbab3,0xbab4,0x0000,0x0000,0x0000,0xbab5,0x0000,0x0000,0x0000,0x0000,// 볍 볏볐병 볕 + 0x0000,0xbab6,0x0000,0x0000,0x0000,0xbab7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 볘 볜 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbab8,0xbab9,0xbaba,0x0000,0xbabb,0x0000,0x0000,0x0000,0xbabc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 보복볶 본 볼 + 0x0000,0xbabd,0x0000,0xbabe,0x0000,0xbabf,0x0000,0xbac0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 봄 봅 봇 봉 + 0x0000,0xbac1,0x0000,0x0000,0x0000,0xbac2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 봐 봔 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbac3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 봤 + 0x0000,0xbac4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 봬 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbac5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뵀 + // 0xa640 - 0xa6ff + 0x0000,0xbac6,0xbac7,0x0000,0x0000,0xbac8,0x0000,0x0000,0x0000,0xbac9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뵈뵉 뵌 뵐 + 0x0000,0xbaca,0x0000,0xbacb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뵘 뵙 + 0x0000,0xbacc,0x0000,0x0000,0x0000,0xbacd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뵤 뵨 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbace,0xbacf,0x0000,0x0000,0xbad0,0x0000,0x0000,0xbad1,0xbad2,0xbad3,0xbad4,0x0000,0x0000,0x0000,0x0000,// 부북 분 붇불붉붊 + 0x0000,0xbad5,0x0000,0xbad6,0x0000,0xbad7,0x0000,0xbad8,0x0000,0x0000,0x0000,0xbad9,0xbada,0x0000,0x0000,0x0000,// 붐 붑 붓 붕 붙붚 + 0x0000,0xbadb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbadc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 붜 붤 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbadd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 붰 + 0x0000,0xbade,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 붸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbadf,0xbae0,0x0000,0x0000,0xbae1,0x0000,0x0000,0x0000,0xbae2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뷔뷕 뷘 뷜 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbae3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뷩 + // 0xa740 - 0xa7ff + 0x0000,0xbae4,0x0000,0x0000,0x0000,0xbae5,0x0000,0x0000,0x0000,0xbae6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뷰 뷴 뷸 + 0x0000,0xbae7,0x0000,0x0000,0x0000,0xbae8,0x0000,0xbae9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 븀 븃 븅 + 0x0000,0xbaea,0xbaeb,0x0000,0x0000,0xbaec,0x0000,0x0000,0x0000,0xbaed,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 브븍 븐 블 + 0x0000,0xbaee,0x0000,0xbaef,0x0000,0xbaf0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 븜 븝 븟 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbaf1,0xbaf2,0x0000,0x0000,0xbaf3,0x0000,0x0000,0x0000,0xbaf4,0x0000,0xbaf5,0x0000,0x0000,0x0000,0x0000,// 비빅 빈 빌 빎 + 0x0000,0xbaf6,0x0000,0xbaf7,0x0000,0xbaf8,0x0000,0xbaf9,0xbafa,0xbafb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 빔 빕 빗 빙빚빛 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xa840 - 0xa8ff + 0x0000,0xa4b3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅃ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbafc,0xbafd,0x0000,0x0000,0xbafe,0x0000,0x0000,0x0000,0xbba1,0x0000,0xbba2,0x0000,0x0000,0x0000,0x0000,// 빠빡 빤 빨 빪 + 0x0000,0xbba3,0x0000,0xbba4,0x0000,0xbba5,0xbba6,0xbba7,0x0000,0x0000,0x0000,0x0000,0x0000,0xbba8,0x0000,0x0000,// 빰 빱 빳빴빵 빻 + 0x0000,0xbba9,0xbbaa,0x0000,0x0000,0xbbab,0x0000,0x0000,0x0000,0xbbac,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 빼빽 뺀 뺄 + 0x0000,0xbbad,0x0000,0xbbae,0x0000,0xbbaf,0xbbb0,0xbbb1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뺌 뺍 뺏뺐뺑 + 0x0000,0xbbb2,0xbbb3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뺘뺙 + 0x0000,0xbbb4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뺨 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbbb5,0xbbb6,0x0000,0x0000,0xbbb7,0x0000,0x0000,0xbbb8,0xbbb9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뻐뻑 뻔 뻗뻘 + 0x0000,0xbbba,0x0000,0x0000,0x0000,0xbbbb,0xbbbc,0xbbbd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뻠 뻣뻤뻥 + // 0xa940 - 0xa9ff + 0x0000,0xbbbe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뻬 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbbbf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뼁 + 0x0000,0xbbc0,0xbbc1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뼈뼉 + 0x0000,0xbbc2,0x0000,0xbbc3,0x0000,0xbbc4,0xbbc5,0xbbc6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뼘 뼙 뼛뼜뼝 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbbc7,0xbbc8,0x0000,0x0000,0xbbc9,0x0000,0x0000,0x0000,0xbbca,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뽀뽁 뽄 뽈 + 0x0000,0xbbcb,0x0000,0xbbcc,0x0000,0x0000,0x0000,0xbbcd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뽐 뽑 뽕 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xaa40 - 0xaaff + 0x0000,0xbbce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뾔 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbbcf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뾰 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbbd0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뿅 + 0x0000,0xbbd1,0xbbd2,0x0000,0x0000,0xbbd3,0x0000,0x0000,0x0000,0xbbd4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뿌뿍 뿐 뿔 + 0x0000,0xbbd5,0x0000,0x0000,0x0000,0xbbd6,0x0000,0xbbd7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 뿜 뿟 뿡 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xab40 - 0xabff + 0x0000,0xbbd8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쀼 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbbd9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쁑 + 0x0000,0xbbda,0x0000,0x0000,0x0000,0xbbdb,0x0000,0x0000,0x0000,0xbbdc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쁘 쁜 쁠 + 0x0000,0xbbdd,0x0000,0xbbde,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쁨 쁩 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbbdf,0xbbe0,0x0000,0x0000,0xbbe1,0x0000,0x0000,0x0000,0xbbe2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 삐삑 삔 삘 + 0x0000,0xbbe3,0x0000,0xbbe4,0x0000,0xbbe5,0x0000,0xbbe6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 삠 삡 삣 삥 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xac40 - 0xacff + 0x0000,0xa4b5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅅ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbbe7,0xbbe8,0x0000,0xbbe9,0xbbea,0x0000,0x0000,0xbbeb,0xbbec,0xbbed,0xbbee,0x0000,0x0000,0x0000,0x0000,// 사삭 삯산 삳살삵삶 + 0x0000,0xbbef,0x0000,0xbbf0,0x0000,0xbbf1,0xbbf2,0xbbf3,0x0000,0x0000,0x0000,0xbbf4,0x0000,0x0000,0x0000,0x0000,// 삼 삽 삿샀상 샅 + 0x0000,0xbbf5,0xbbf6,0x0000,0x0000,0xbbf7,0x0000,0x0000,0x0000,0xbbf8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 새색 샌 샐 + 0x0000,0xbbf9,0x0000,0xbbfa,0x0000,0xbbfb,0xbbfc,0xbbfd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 샘 샙 샛샜생 + 0x0000,0xbbfe,0xbca1,0x0000,0x0000,0xbca2,0x0000,0x0000,0x0000,0xbca3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 샤샥 샨 샬 + 0x0000,0xbca4,0x0000,0xbca5,0x0000,0xbca6,0x0000,0xbca7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 샴 샵 샷 샹 + 0x0000,0xbca8,0x0000,0x0000,0x0000,0xbca9,0x0000,0x0000,0x0000,0xbcaa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 섀 섄 섈 + 0x0000,0xbcab,0x0000,0x0000,0x0000,0x0000,0x0000,0xbcac,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 섐 섕 + 0x0000,0xbcad,0xbcae,0xbcaf,0xbcb0,0xbcb1,0x0000,0x0000,0xbcb2,0xbcb3,0x0000,0xbcb4,0xbcb5,0x0000,0x0000,0x0000,// 서석섞섟선 섣설 섦섧 + 0x0000,0xbcb6,0x0000,0xbcb7,0x0000,0xbcb8,0xbcb9,0xbcba,0x0000,0x0000,0x0000,0x0000,0xbcbb,0x0000,0x0000,0x0000,// 섬 섭 섯섰성 섶 + // 0xad40 - 0xadff + 0x0000,0xbcbc,0xbcbd,0x0000,0x0000,0xbcbe,0x0000,0x0000,0x0000,0xbcbf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 세섹 센 셀 + 0x0000,0xbcc0,0x0000,0xbcc1,0x0000,0xbcc2,0xbcc3,0xbcc4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 셈 셉 셋셌셍 + 0x0000,0xbcc5,0xbcc6,0x0000,0x0000,0xbcc7,0x0000,0x0000,0x0000,0xbcc8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 셔셕 션 셜 + 0x0000,0xbcc9,0x0000,0xbcca,0x0000,0xbccb,0xbccc,0xbccd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 셤 셥 셧셨셩 + 0x0000,0xbcce,0x0000,0x0000,0x0000,0xbccf,0x0000,0x0000,0x0000,0xbcd0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 셰 셴 셸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbcd1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 솅 + 0x0000,0xbcd2,0xbcd3,0xbcd4,0x0000,0xbcd5,0x0000,0x0000,0x0000,0xbcd6,0x0000,0xbcd7,0x0000,0x0000,0x0000,0x0000,// 소속솎 손 솔 솖 + 0x0000,0xbcd8,0x0000,0xbcd9,0x0000,0xbcda,0x0000,0xbcdb,0x0000,0x0000,0x0000,0xbcdc,0x0000,0x0000,0x0000,0x0000,// 솜 솝 솟 송 솥 + 0x0000,0xbcdd,0xbcde,0x0000,0x0000,0xbcdf,0x0000,0x0000,0x0000,0xbce0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 솨솩 솬 솰 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbce1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 솽 + 0x0000,0xbce2,0x0000,0x0000,0x0000,0xbce3,0x0000,0x0000,0x0000,0xbce4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쇄 쇈 쇌 + 0x0000,0xbce5,0x0000,0x0000,0x0000,0xbce6,0xbce7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쇔 쇗쇘 + // 0xae40 - 0xaeff + 0x0000,0xbce8,0x0000,0x0000,0x0000,0xbce9,0x0000,0x0000,0x0000,0xbcea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쇠 쇤 쇨 + 0x0000,0xbceb,0x0000,0xbcec,0x0000,0xbced,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쇰 쇱 쇳 + 0x0000,0xbcee,0xbcef,0x0000,0x0000,0xbcf0,0x0000,0x0000,0x0000,0xbcf1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쇼쇽 숀 숄 + 0x0000,0xbcf2,0x0000,0xbcf3,0x0000,0xbcf4,0x0000,0xbcf5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 숌 숍 숏 숑 + 0x0000,0xbcf6,0xbcf7,0x0000,0x0000,0xbcf8,0x0000,0x0000,0xbcf9,0xbcfa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 수숙 순 숟술 + 0x0000,0xbcfb,0x0000,0xbcfc,0x0000,0xbcfd,0x0000,0xbcfe,0x0000,0xbda1,0x0000,0xbda2,0xbda3,0x0000,0x0000,0x0000,// 숨 숩 숫 숭 숯 숱숲 + 0x0000,0xbda4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 숴 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbda5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쉈 + 0x0000,0xbda6,0xbda7,0x0000,0x0000,0xbda8,0x0000,0x0000,0x0000,0xbda9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쉐쉑 쉔 쉘 + 0x0000,0xbdaa,0x0000,0x0000,0x0000,0x0000,0x0000,0xbdab,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쉠 쉥 + 0x0000,0xbdac,0xbdad,0x0000,0x0000,0xbdae,0x0000,0x0000,0x0000,0xbdaf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쉬쉭 쉰 쉴 + 0x0000,0xbdb0,0x0000,0xbdb1,0x0000,0xbdb2,0x0000,0xbdb3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쉼 쉽 쉿 슁 + // 0xaf40 - 0xafff + 0x0000,0xbdb4,0xbdb5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbdb6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 슈슉 슐 + 0x0000,0xbdb7,0x0000,0x0000,0x0000,0xbdb8,0x0000,0xbdb9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 슘 슛 슝 + 0x0000,0xbdba,0xbdbb,0x0000,0x0000,0xbdbc,0x0000,0x0000,0x0000,0xbdbd,0xbdbe,0x0000,0x0000,0x0000,0x0000,0x0000,// 스슥 슨 슬슭 + 0x0000,0xbdbf,0x0000,0xbdc0,0x0000,0xbdc1,0x0000,0xbdc2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 슴 습 슷 승 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbdc3,0xbdc4,0x0000,0x0000,0xbdc5,0x0000,0x0000,0xbdc6,0xbdc7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 시식 신 싣실 + 0xbdc8,0xbdc9,0x0000,0xbdca,0x0000,0xbdcb,0x0000,0xbdcc,0x0000,0x0000,0x0000,0x0000,0xbdcd,0x0000,0x0000,0x0000,// 싫심 십 싯 싱 싶 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xb040 - 0xb0ff + 0x0000,0xa4b6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅆ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbdce,0xbdcf,0x0000,0xbdd0,0xbdd1,0x0000,0x0000,0x0000,0xbdd2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 싸싹 싻싼 쌀 + 0x0000,0xbdd3,0x0000,0xbdd4,0x0000,0x0000,0xbdd5,0xbdd6,0x0000,0x0000,0x0000,0x0000,0x0000,0xbdd7,0x0000,0x0000,// 쌈 쌉 쌌쌍 쌓 + 0x0000,0xbdd8,0xbdd9,0x0000,0x0000,0xbdda,0x0000,0x0000,0x0000,0xbddb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쌔쌕 쌘 쌜 + 0x0000,0xbddc,0x0000,0xbddd,0x0000,0x0000,0xbdde,0xbddf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쌤 쌥 쌨쌩 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbde0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 썅 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbde1,0xbde2,0x0000,0x0000,0xbde3,0x0000,0x0000,0x0000,0xbde4,0x0000,0xbde5,0x0000,0x0000,0x0000,0x0000,// 써썩 썬 썰 썲 + 0x0000,0xbde6,0x0000,0xbde7,0x0000,0x0000,0xbde8,0xbde9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 썸 썹 썼썽 + // 0xb140 - 0xb1ff + 0x0000,0xbdea,0x0000,0x0000,0x0000,0xbdeb,0x0000,0x0000,0x0000,0xbdec,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쎄 쎈 쎌 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0xbded,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쏀 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbdee,0xbdef,0x0000,0x0000,0xbdf0,0x0000,0x0000,0xbdf1,0xbdf2,0x0000,0xbdf3,0x0000,0x0000,0x0000,0x0000,// 쏘쏙 쏜 쏟쏠 쏢 + 0x0000,0xbdf4,0x0000,0xbdf5,0x0000,0x0000,0x0000,0xbdf6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쏨 쏩 쏭 + 0x0000,0xbdf7,0xbdf8,0x0000,0x0000,0xbdf9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쏴쏵 쏸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbdfa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쐈 + 0x0000,0xbdfb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쐐 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbdfc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쐤 + // 0xb240 - 0xb2ff + 0x0000,0xbdfd,0x0000,0x0000,0x0000,0xbdfe,0x0000,0x0000,0x0000,0xbea1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쐬 쐰 쐴 + 0x0000,0xbea2,0x0000,0xbea3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쐼 쐽 + 0x0000,0xbea4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쑈 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbea5,0xbea6,0x0000,0x0000,0xbea7,0x0000,0x0000,0x0000,0xbea8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쑤쑥 쑨 쑬 + 0x0000,0xbea9,0x0000,0xbeaa,0x0000,0x0000,0x0000,0xbeab,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쑴 쑵 쑹 + 0x0000,0xbeac,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쒀 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbead,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쒔 + 0x0000,0xbeae,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쒜 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbeaf,0x0000,0x0000,0x0000,0xbeb0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쒸 쒼 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xb340 - 0xb3ff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xbeb1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쓩 + 0x0000,0xbeb2,0xbeb3,0x0000,0x0000,0xbeb4,0x0000,0x0000,0x0000,0xbeb5,0x0000,0xbeb6,0x0000,0x0000,0x0000,0x0000,// 쓰쓱 쓴 쓸 쓺 + 0xbeb7,0xbeb8,0x0000,0xbeb9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쓿씀 씁 + 0x0000,0xbeba,0x0000,0x0000,0x0000,0xbebb,0x0000,0x0000,0x0000,0xbebc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 씌 씐 씔 + 0x0000,0xbebd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 씜 + 0x0000,0xbebe,0xbebf,0x0000,0x0000,0xbec0,0x0000,0x0000,0x0000,0xbec1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 씨씩 씬 씰 + 0x0000,0xbec2,0x0000,0xbec3,0x0000,0xbec4,0x0000,0xbec5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 씸 씹 씻 씽 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xb440 - 0xb4ff + 0x0000,0xa4b7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅇ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xbec6,0xbec7,0x0000,0x0000,0xbec8,0xbec9,0xbeca,0x0000,0xbecb,0xbecc,0xbecd,0x0000,0x0000,0x0000,0x0000,// 아악 안앉않 알앍앎 + 0xbece,0xbecf,0x0000,0xbed0,0x0000,0xbed1,0xbed2,0xbed3,0x0000,0x0000,0x0000,0xbed4,0xbed5,0x0000,0x0000,0x0000,// 앓암 압 앗았앙 앝앞 + 0x0000,0xbed6,0xbed7,0x0000,0x0000,0xbed8,0x0000,0x0000,0x0000,0xbed9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 애액 앤 앨 + 0x0000,0xbeda,0x0000,0xbedb,0x0000,0xbedc,0xbedd,0xbede,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 앰 앱 앳앴앵 + 0x0000,0xbedf,0xbee0,0x0000,0x0000,0xbee1,0x0000,0x0000,0x0000,0xbee2,0x0000,0x0000,0xbee3,0x0000,0x0000,0x0000,// 야약 얀 얄 얇 + 0x0000,0xbee4,0x0000,0xbee5,0x0000,0xbee6,0x0000,0xbee7,0x0000,0x0000,0x0000,0xbee8,0x0000,0xbee9,0x0000,0x0000,// 얌 얍 얏 양 얕 얗 + 0x0000,0xbeea,0x0000,0x0000,0x0000,0xbeeb,0x0000,0x0000,0x0000,0xbeec,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 얘 얜 얠 + 0x0000,0x0000,0x0000,0xbeed,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 얩 + 0x0000,0xbeee,0xbeef,0x0000,0x0000,0xbef0,0xbef1,0x0000,0xbef2,0xbef3,0xbef4,0xbef5,0x0000,0x0000,0x0000,0x0000,// 어억 언얹 얻얼얽얾 + 0x0000,0xbef6,0x0000,0xbef7,0xbef8,0xbef9,0xbefa,0xbefb,0xbefc,0x0000,0xbefd,0x0000,0xbefe,0x0000,0x0000,0x0000,// 엄 업없엇었엉엊 엌 엎 + // 0xb540 - 0xb5ff + 0x0000,0xbfa1,0xbfa2,0x0000,0x0000,0xbfa3,0x0000,0x0000,0x0000,0xbfa4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 에엑 엔 엘 + 0x0000,0xbfa5,0x0000,0xbfa6,0x0000,0xbfa7,0x0000,0xbfa8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 엠 엡 엣 엥 + 0x0000,0xbfa9,0xbfaa,0xbfab,0x0000,0xbfac,0x0000,0x0000,0x0000,0xbfad,0x0000,0xbfae,0xbfaf,0x0000,0x0000,0x0000,// 여역엮 연 열 엶엷 + 0x0000,0xbfb0,0x0000,0xbfb1,0xbfb2,0xbfb3,0xbfb4,0xbfb5,0x0000,0x0000,0x0000,0xbfb6,0xbfb7,0xbfb8,0x0000,0x0000,// 염 엽엾엿였영 옅옆옇 + 0x0000,0xbfb9,0x0000,0x0000,0x0000,0xbfba,0x0000,0x0000,0x0000,0xbfbb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 예 옌 옐 + 0x0000,0xbfbc,0x0000,0xbfbd,0x0000,0xbfbe,0xbfbf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 옘 옙 옛옜 + 0x0000,0xbfc0,0xbfc1,0x0000,0x0000,0xbfc2,0x0000,0x0000,0x0000,0xbfc3,0xbfc4,0xbfc5,0x0000,0xbfc6,0x0000,0x0000,// 오옥 온 올옭옮 옰 + 0xbfc7,0xbfc8,0x0000,0xbfc9,0x0000,0xbfca,0x0000,0xbfcb,0x0000,0xbfcc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 옳옴 옵 옷 옹 옻 + 0x0000,0xbfcd,0xbfce,0x0000,0x0000,0xbfcf,0x0000,0x0000,0x0000,0xbfd0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 와왁 완 왈 + 0x0000,0xbfd1,0x0000,0xbfd2,0x0000,0xbfd3,0xbfd4,0xbfd5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 왐 왑 왓왔왕 + 0x0000,0xbfd6,0xbfd7,0x0000,0x0000,0xbfd8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 왜왝 왠 + 0x0000,0xbfd9,0x0000,0x0000,0x0000,0xbfda,0x0000,0xbfdb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 왬 왯 왱 + // 0xb640 - 0xb6ff + 0x0000,0xbfdc,0xbfdd,0x0000,0x0000,0xbfde,0x0000,0x0000,0x0000,0xbfdf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 외왹 왼 욀 + 0x0000,0xbfe0,0x0000,0xbfe1,0x0000,0xbfe2,0x0000,0xbfe3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 욈 욉 욋 욍 + 0x0000,0xbfe4,0xbfe5,0x0000,0x0000,0xbfe6,0x0000,0x0000,0x0000,0xbfe7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 요욕 욘 욜 + 0x0000,0xbfe8,0x0000,0xbfe9,0x0000,0xbfea,0x0000,0xbfeb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 욤 욥 욧 용 + 0x0000,0xbfec,0xbfed,0x0000,0x0000,0xbfee,0x0000,0x0000,0x0000,0xbfef,0xbff0,0xbff1,0x0000,0x0000,0x0000,0x0000,// 우욱 운 울욹욺 + 0x0000,0xbff2,0x0000,0xbff3,0x0000,0xbff4,0x0000,0xbff5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 움 웁 웃 웅 + 0x0000,0xbff6,0xbff7,0x0000,0x0000,0xbff8,0x0000,0x0000,0x0000,0xbff9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 워웍 원 월 + 0x0000,0xbffa,0x0000,0xbffb,0x0000,0x0000,0xbffc,0xbffd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 웜 웝 웠웡 + 0x0000,0xbffe,0xc0a1,0x0000,0x0000,0xc0a2,0x0000,0x0000,0x0000,0xc0a3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 웨웩 웬 웰 + 0x0000,0xc0a4,0x0000,0xc0a5,0x0000,0x0000,0x0000,0xc0a6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 웸 웹 웽 + 0x0000,0xc0a7,0xc0a8,0x0000,0x0000,0xc0a9,0x0000,0x0000,0x0000,0xc0aa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 위윅 윈 윌 + 0x0000,0xc0ab,0x0000,0xc0ac,0x0000,0xc0ad,0x0000,0xc0ae,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 윔 윕 윗 윙 + // 0xb740 - 0xb7ff + 0x0000,0xc0af,0xc0b0,0x0000,0x0000,0xc0b1,0x0000,0x0000,0x0000,0xc0b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 유육 윤 율 + 0x0000,0xc0b3,0x0000,0xc0b4,0x0000,0xc0b5,0x0000,0xc0b6,0x0000,0xc0b7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 윰 윱 윳 융 윷 + 0x0000,0xc0b8,0xc0b9,0x0000,0x0000,0xc0ba,0x0000,0x0000,0x0000,0xc0bb,0x0000,0x0000,0x0000,0x0000,0x0000,0xc0bc,// 으윽 은 을 읊 + 0x0000,0xc0bd,0x0000,0xc0be,0x0000,0xc0bf,0x0000,0xc0c0,0xc0c1,0xc0c2,0xc0c3,0xc0c4,0xc0c5,0xc0c6,0x0000,0x0000,// 음 읍 읏 응읒읓읔읕읖읗 + 0x0000,0xc0c7,0x0000,0x0000,0x0000,0xc0c8,0x0000,0x0000,0x0000,0xc0c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 의 읜 읠 + 0x0000,0xc0ca,0x0000,0x0000,0x0000,0xc0cb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 읨 읫 + 0x0000,0xc0cc,0xc0cd,0x0000,0x0000,0xc0ce,0x0000,0x0000,0x0000,0xc0cf,0xc0d0,0xc0d1,0x0000,0x0000,0x0000,0x0000,// 이익 인 일읽읾 + 0xc0d2,0xc0d3,0x0000,0xc0d4,0x0000,0xc0d5,0xc0d6,0xc0d7,0xc0d8,0x0000,0x0000,0x0000,0xc0d9,0x0000,0x0000,0x0000,// 잃임 입 잇있잉잊 잎 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xb840 - 0xb8ff + 0x0000,0xa4b8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅈ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc0da,0xc0db,0x0000,0x0000,0xc0dc,0x0000,0xc0dd,0xc0de,0xc0df,0x0000,0xc0e0,0x0000,0x0000,0x0000,0x0000,// 자작 잔 잖잗잘 잚 + 0x0000,0xc0e1,0x0000,0xc0e2,0x0000,0xc0e3,0xc0e4,0xc0e5,0xc0e6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 잠 잡 잣잤장잦 + 0x0000,0xc0e7,0xc0e8,0x0000,0x0000,0xc0e9,0x0000,0x0000,0x0000,0xc0ea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 재잭 잰 잴 + 0x0000,0xc0eb,0x0000,0xc0ec,0x0000,0xc0ed,0xc0ee,0xc0ef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 잼 잽 잿쟀쟁 + 0x0000,0xc0f0,0xc0f1,0x0000,0x0000,0xc0f2,0x0000,0xc0f3,0x0000,0xc0f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쟈쟉 쟌 쟎 쟐 + 0x0000,0xc0f5,0x0000,0x0000,0x0000,0x0000,0x0000,0xc0f6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쟘 쟝 + 0x0000,0xc0f7,0x0000,0x0000,0x0000,0xc0f8,0x0000,0x0000,0x0000,0xc0f9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쟤 쟨 쟬 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc0fa,0xc0fb,0x0000,0x0000,0xc0fc,0x0000,0x0000,0x0000,0xc0fd,0x0000,0xc0fe,0x0000,0x0000,0x0000,0x0000,// 저적 전 절 젊 + 0x0000,0xc1a1,0x0000,0xc1a2,0x0000,0xc1a3,0x0000,0xc1a4,0xc1a5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 점 접 젓 정젖 + // 0xb940 - 0xb9ff + 0x0000,0xc1a6,0xc1a7,0x0000,0x0000,0xc1a8,0x0000,0x0000,0x0000,0xc1a9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 제젝 젠 젤 + 0x0000,0xc1aa,0x0000,0xc1ab,0x0000,0xc1ac,0x0000,0xc1ad,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 젬 젭 젯 젱 + 0x0000,0xc1ae,0x0000,0x0000,0x0000,0xc1af,0x0000,0x0000,0x0000,0xc1b0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 져 젼 졀 + 0x0000,0xc1b1,0x0000,0xc1b2,0x0000,0x0000,0xc1b3,0xc1b4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 졈 졉 졌졍 + 0x0000,0xc1b5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 졔 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc1b6,0xc1b7,0x0000,0x0000,0xc1b8,0x0000,0x0000,0x0000,0xc1b9,0x0000,0xc1ba,0x0000,0x0000,0x0000,0x0000,// 조족 존 졸 졺 + 0x0000,0xc1bb,0x0000,0xc1bc,0x0000,0xc1bd,0x0000,0xc1be,0xc1bf,0xc1c0,0x0000,0x0000,0x0000,0xc1c1,0x0000,0x0000,// 좀 좁 좃 종좆좇 좋 + 0x0000,0xc1c2,0xc1c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc1c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 좌좍 좔 + 0x0000,0x0000,0x0000,0xc1c5,0x0000,0xc1c6,0x0000,0xc1c7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 좝 좟 좡 + 0x0000,0xc1c8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 좨 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc1c9,0xc1ca,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 좼좽 + // 0xba40 - 0xbaff + 0x0000,0xc1cb,0x0000,0x0000,0x0000,0xc1cc,0x0000,0x0000,0x0000,0xc1cd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 죄 죈 죌 + 0x0000,0xc1ce,0x0000,0xc1cf,0x0000,0xc1d0,0x0000,0xc1d1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 죔 죕 죗 죙 + 0x0000,0xc1d2,0xc1d3,0x0000,0x0000,0xc1d4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 죠죡 죤 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc1d5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 죵 + 0x0000,0xc1d6,0xc1d7,0x0000,0x0000,0xc1d8,0x0000,0x0000,0x0000,0xc1d9,0xc1da,0xc1db,0x0000,0x0000,0x0000,0x0000,// 주죽 준 줄줅줆 + 0x0000,0xc1dc,0x0000,0xc1dd,0x0000,0xc1de,0x0000,0xc1df,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 줌 줍 줏 중 + 0x0000,0xc1e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 줘 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc1e1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 줬 + 0x0000,0xc1e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 줴 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc1e3,0xc1e4,0x0000,0x0000,0xc1e5,0x0000,0x0000,0x0000,0xc1e6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쥐쥑 쥔 쥘 + 0x0000,0xc1e7,0x0000,0xc1e8,0x0000,0xc1e9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쥠 쥡 쥣 + // 0xbb40 - 0xbbff + 0x0000,0xc1ea,0x0000,0x0000,0x0000,0xc1eb,0x0000,0x0000,0x0000,0xc1ec,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쥬 쥰 쥴 + 0x0000,0xc1ed,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쥼 + 0x0000,0xc1ee,0xc1ef,0x0000,0x0000,0xc1f0,0x0000,0x0000,0x0000,0xc1f1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 즈즉 즌 즐 + 0x0000,0xc1f2,0x0000,0xc1f3,0x0000,0xc1f4,0x0000,0xc1f5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 즘 즙 즛 증 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc1f6,0xc1f7,0x0000,0x0000,0xc1f8,0x0000,0x0000,0xc1f9,0xc1fa,0x0000,0xc1fb,0x0000,0x0000,0x0000,0x0000,// 지직 진 짇질 짊 + 0x0000,0xc1fc,0x0000,0xc1fd,0x0000,0xc1fe,0x0000,0xc2a1,0xc2a2,0x0000,0x0000,0xc2a3,0xc2a4,0x0000,0x0000,0x0000,// 짐 집 짓 징짖 짙짚 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xbc40 - 0xbcff + 0x0000,0xa4b9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅉ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc2a5,0xc2a6,0x0000,0x0000,0xc2a7,0x0000,0xc2a8,0x0000,0xc2a9,0x0000,0x0000,0xc2aa,0x0000,0x0000,0x0000,// 짜짝 짠 짢 짤 짧 + 0x0000,0xc2ab,0x0000,0xc2ac,0x0000,0xc2ad,0xc2ae,0xc2af,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 짬 짭 짯짰짱 + 0x0000,0xc2b0,0xc2b1,0x0000,0x0000,0xc2b2,0x0000,0x0000,0x0000,0xc2b3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 째짹 짼 쨀 + 0x0000,0xc2b4,0x0000,0xc2b5,0x0000,0xc2b6,0xc2b7,0xc2b8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쨈 쨉 쨋쨌쨍 + 0x0000,0xc2b9,0x0000,0x0000,0x0000,0xc2ba,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쨔 쨘 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc2bb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쨩 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc2bc,0xc2bd,0x0000,0x0000,0xc2be,0x0000,0x0000,0x0000,0xc2bf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쩌쩍 쩐 쩔 + 0x0000,0xc2c0,0x0000,0xc2c1,0x0000,0xc2c2,0xc2c3,0xc2c4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쩜 쩝 쩟쩠쩡 + // 0xbd40 - 0xbdff + 0x0000,0xc2c5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쩨 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc2c6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쩽 + 0x0000,0xc2c7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쪄 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc2c8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쪘 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc2c9,0xc2ca,0x0000,0x0000,0xc2cb,0x0000,0x0000,0x0000,0xc2cc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쪼쪽 쫀 쫄 + 0x0000,0xc2cd,0x0000,0xc2ce,0x0000,0xc2cf,0x0000,0xc2d0,0x0000,0xc2d1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쫌 쫍 쫏 쫑 쫓 + 0x0000,0xc2d2,0xc2d3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc2d4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쫘쫙 쫠 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc2d5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쫬 + 0x0000,0xc2d6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쫴 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc2d7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쬈 + // 0xbe40 - 0xbeff + 0x0000,0xc2d8,0x0000,0x0000,0x0000,0xc2d9,0x0000,0x0000,0x0000,0xc2da,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쬐 쬔 쬘 + 0x0000,0xc2db,0x0000,0xc2dc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쬠 쬡 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc2dd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쭁 + 0x0000,0xc2de,0xc2df,0x0000,0x0000,0xc2e0,0x0000,0x0000,0x0000,0xc2e1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쭈쭉 쭌 쭐 + 0x0000,0xc2e2,0x0000,0xc2e3,0x0000,0x0000,0x0000,0xc2e4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쭘 쭙 쭝 + 0x0000,0xc2e5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쭤 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc2e6,0xc2e7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쭸쭹 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc2e8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쮜 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xbf40 - 0xbfff + 0x0000,0xc2e9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쮸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc2ea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쯔 + 0x0000,0xc2eb,0x0000,0x0000,0x0000,0xc2ec,0x0000,0xc2ed,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쯤 쯧 쯩 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc2ee,0xc2ef,0x0000,0x0000,0xc2f0,0x0000,0x0000,0x0000,0xc2f1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 찌찍 찐 찔 + 0x0000,0xc2f2,0x0000,0xc2f3,0x0000,0x0000,0x0000,0xc2f4,0xc2f5,0x0000,0x0000,0x0000,0x0000,0xc2f6,0x0000,0x0000,// 찜 찝 찡찢 찧 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xc040 - 0xc0ff + 0x0000,0xa4ba,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅊ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc2f7,0xc2f8,0x0000,0x0000,0xc2f9,0x0000,0xc2fa,0x0000,0xc2fb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 차착 찬 찮 찰 + 0x0000,0xc2fc,0x0000,0xc2fd,0x0000,0xc2fe,0xc3a1,0xc3a2,0xc3a3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 참 찹 찻찼창찾 + 0x0000,0xc3a4,0xc3a5,0x0000,0x0000,0xc3a6,0x0000,0x0000,0x0000,0xc3a7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 채책 챈 챌 + 0x0000,0xc3a8,0x0000,0xc3a9,0x0000,0xc3aa,0xc3ab,0xc3ac,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 챔 챕 챗챘챙 + 0x0000,0xc3ad,0x0000,0x0000,0x0000,0xc3ae,0x0000,0xc3af,0x0000,0xc3b0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 챠 챤 챦 챨 + 0x0000,0xc3b1,0x0000,0x0000,0x0000,0x0000,0x0000,0xc3b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 챰 챵 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc3b3,0xc3b4,0x0000,0x0000,0xc3b5,0x0000,0x0000,0x0000,0xc3b6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 처척 천 철 + 0x0000,0xc3b7,0x0000,0xc3b8,0x0000,0xc3b9,0xc3ba,0xc3bb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 첨 첩 첫첬청 + // 0xc140 - 0xc1ff + 0x0000,0xc3bc,0xc3bd,0x0000,0x0000,0xc3be,0x0000,0x0000,0x0000,0xc3bf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 체첵 첸 첼 + 0x0000,0xc3c0,0x0000,0xc3c1,0x0000,0xc3c2,0x0000,0xc3c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쳄 쳅 쳇 쳉 + 0x0000,0xc3c4,0x0000,0x0000,0x0000,0xc3c5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쳐 쳔 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc3c6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쳤 + 0x0000,0xc3c7,0x0000,0x0000,0x0000,0xc3c8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쳬 쳰 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc3c9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 촁 + 0x0000,0xc3ca,0xc3cb,0x0000,0x0000,0xc3cc,0x0000,0x0000,0x0000,0xc3cd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 초촉 촌 촐 + 0x0000,0xc3ce,0x0000,0xc3cf,0x0000,0xc3d0,0x0000,0xc3d1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 촘 촙 촛 총 + 0x0000,0xc3d2,0x0000,0x0000,0x0000,0xc3d3,0x0000,0x0000,0x0000,0xc3d4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 촤 촨 촬 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc3d5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 촹 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xc240 - 0xc2ff + 0x0000,0xc3d6,0x0000,0x0000,0x0000,0xc3d7,0x0000,0x0000,0x0000,0xc3d8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 최 쵠 쵤 + 0x0000,0xc3d9,0x0000,0xc3da,0x0000,0xc3db,0x0000,0xc3dc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쵬 쵭 쵯 쵱 + 0x0000,0xc3dd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쵸 + 0x0000,0xc3de,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 춈 + 0x0000,0xc3df,0xc3e0,0x0000,0x0000,0xc3e1,0x0000,0x0000,0x0000,0xc3e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 추축 춘 출 + 0x0000,0xc3e3,0x0000,0xc3e4,0x0000,0xc3e5,0x0000,0xc3e6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 춤 춥 춧 충 + 0x0000,0xc3e7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 춰 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc3e8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 췄 + 0x0000,0xc3e9,0x0000,0x0000,0x0000,0xc3ea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 췌 췐 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc3eb,0x0000,0x0000,0x0000,0xc3ec,0x0000,0x0000,0x0000,0xc3ed,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 취 췬 췰 + 0x0000,0xc3ee,0x0000,0xc3ef,0x0000,0xc3f0,0x0000,0xc3f1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 췸 췹 췻 췽 + // 0xc340 - 0xc3ff + 0x0000,0xc3f2,0x0000,0x0000,0x0000,0xc3f3,0x0000,0x0000,0x0000,0xc3f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 츄 츈 츌 + 0x0000,0xc3f5,0x0000,0x0000,0x0000,0x0000,0x0000,0xc3f6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 츔 츙 + 0x0000,0xc3f7,0xc3f8,0x0000,0x0000,0xc3f9,0x0000,0x0000,0x0000,0xc3fa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 츠측 츤 츨 + 0x0000,0xc3fb,0x0000,0xc3fc,0x0000,0xc3fd,0x0000,0xc3fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 츰 츱 츳 층 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc4a1,0xc4a2,0x0000,0x0000,0xc4a3,0x0000,0x0000,0xc4a4,0xc4a5,0xc4a6,0x0000,0x0000,0x0000,0x0000,0x0000,// 치칙 친 칟칠칡 + 0x0000,0xc4a7,0x0000,0xc4a8,0x0000,0xc4a9,0x0000,0xc4aa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 침 칩 칫 칭 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xc440 - 0xc4ff + 0x0000,0xa4bb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅋ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc4ab,0xc4ac,0x0000,0x0000,0xc4ad,0x0000,0x0000,0x0000,0xc4ae,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 카칵 칸 칼 + 0x0000,0xc4af,0x0000,0xc4b0,0x0000,0xc4b1,0x0000,0xc4b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 캄 캅 캇 캉 + 0x0000,0xc4b3,0xc4b4,0x0000,0x0000,0xc4b5,0x0000,0x0000,0x0000,0xc4b6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 캐캑 캔 캘 + 0x0000,0xc4b7,0x0000,0xc4b8,0x0000,0xc4b9,0xc4ba,0xc4bb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 캠 캡 캣캤캥 + 0x0000,0xc4bc,0xc4bd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 캬캭 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc4be,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 컁 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc4bf,0xc4c0,0x0000,0x0000,0xc4c1,0x0000,0x0000,0xc4c2,0xc4c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 커컥 컨 컫컬 + 0x0000,0xc4c4,0x0000,0xc4c5,0x0000,0xc4c6,0xc4c7,0xc4c8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 컴 컵 컷컸컹 + // 0xc540 - 0xc5ff + 0x0000,0xc4c9,0xc4ca,0x0000,0x0000,0xc4cb,0x0000,0x0000,0x0000,0xc4cc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 케켁 켄 켈 + 0x0000,0xc4cd,0x0000,0xc4ce,0x0000,0xc4cf,0x0000,0xc4d0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 켐 켑 켓 켕 + 0x0000,0xc4d1,0x0000,0x0000,0x0000,0xc4d2,0x0000,0x0000,0x0000,0xc4d3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 켜 켠 켤 + 0x0000,0xc4d4,0x0000,0xc4d5,0x0000,0xc4d6,0xc4d7,0xc4d8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 켬 켭 켯켰켱 + 0x0000,0xc4d9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 켸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc4da,0xc4db,0x0000,0x0000,0xc4dc,0x0000,0x0000,0x0000,0xc4dd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 코콕 콘 콜 + 0x0000,0xc4de,0x0000,0xc4df,0x0000,0xc4e0,0x0000,0xc4e1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 콤 콥 콧 콩 + 0x0000,0xc4e2,0xc4e3,0x0000,0x0000,0xc4e4,0x0000,0x0000,0x0000,0xc4e5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 콰콱 콴 콸 + 0x0000,0xc4e6,0x0000,0x0000,0x0000,0x0000,0x0000,0xc4e7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쾀 쾅 + 0x0000,0xc4e8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쾌 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc4e9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쾡 + // 0xc640 - 0xc6ff + 0x0000,0xc4ea,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc4eb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쾨 쾰 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc4ec,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쿄 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc4ed,0xc4ee,0x0000,0x0000,0xc4ef,0x0000,0x0000,0x0000,0xc4f0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쿠쿡 쿤 쿨 + 0x0000,0xc4f1,0x0000,0xc4f2,0x0000,0xc4f3,0x0000,0xc4f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쿰 쿱 쿳 쿵 + 0x0000,0xc4f5,0x0000,0x0000,0x0000,0xc4f6,0x0000,0x0000,0x0000,0xc4f7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 쿼 퀀 퀄 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc4f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퀑 + 0x0000,0xc4f9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퀘 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc4fa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퀭 + 0x0000,0xc4fb,0xc4fc,0x0000,0x0000,0xc4fd,0x0000,0x0000,0x0000,0xc4fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퀴퀵 퀸 퀼 + 0x0000,0xc5a1,0x0000,0xc5a2,0x0000,0xc5a3,0x0000,0xc5a4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 큄 큅 큇 큉 +}; + + public Ebc2Ksc3() + { + + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc4.java b/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc4.java new file mode 100644 index 0000000..b456ded --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/Ebc2Ksc4.java @@ -0,0 +1,193 @@ +package com.eactive.eai.adapter.wca.util; + +public class Ebc2Ksc4 { + protected static char EBC2KSC[] = { + // 0xc740 - 0xc7ff + 0x0000,0xc5a5,0x0000,0x0000,0x0000,0xc5a6,0x0000,0x0000,0x0000,0xc5a7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 큐 큔 큘 + 0x0000,0xc5a8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 큠 + 0x0000,0xc5a9,0xc5aa,0x0000,0x0000,0xc5ab,0x0000,0x0000,0x0000,0xc5ac,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 크큭 큰 클 + 0x0000,0xc5ad,0x0000,0xc5ae,0x0000,0x0000,0x0000,0xc5af,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 큼 큽 킁 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc5b0,0xc5b1,0x0000,0x0000,0xc5b2,0x0000,0x0000,0x0000,0xc5b3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 키킥 킨 킬 + 0x0000,0xc5b4,0x0000,0xc5b5,0x0000,0xc5b6,0x0000,0xc5b7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 킴 킵 킷 킹 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xc840 - 0xc8ff + 0x0000,0xa4bc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅌ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc5b8,0xc5b9,0x0000,0x0000,0xc5ba,0x0000,0x0000,0x0000,0xc5bb,0xc5bc,0x0000,0x0000,0x0000,0x0000,0x0000,// 타탁 탄 탈탉 + 0x0000,0xc5bd,0x0000,0xc5be,0x0000,0xc5bf,0xc5c0,0xc5c1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 탐 탑 탓탔탕 + 0x0000,0xc5c2,0xc5c3,0x0000,0x0000,0xc5c4,0x0000,0x0000,0x0000,0xc5c5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 태택 탠 탤 + 0x0000,0xc5c6,0x0000,0xc5c7,0x0000,0xc5c8,0xc5c9,0xc5ca,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 탬 탭 탯탰탱 + 0x0000,0xc5cb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 탸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc5cc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 턍 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc5cd,0xc5ce,0x0000,0x0000,0xc5cf,0x0000,0x0000,0x0000,0xc5d0,0x0000,0xc5d1,0x0000,0x0000,0x0000,0x0000,// 터턱 턴 털 턺 + 0x0000,0xc5d2,0x0000,0xc5d3,0x0000,0xc5d4,0xc5d5,0xc5d6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 텀 텁 텃텄텅 + // 0xc940 - 0xc9ff + 0x0000,0xc5d7,0xc5d8,0x0000,0x0000,0xc5d9,0x0000,0x0000,0x0000,0xc5da,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 테텍 텐 텔 + 0x0000,0xc5db,0x0000,0xc5dc,0x0000,0xc5dd,0x0000,0xc5de,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 템 텝 텟 텡 + 0x0000,0xc5df,0x0000,0x0000,0x0000,0xc5e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 텨 텬 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc5e1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 텼 + 0x0000,0xc5e2,0x0000,0x0000,0x0000,0xc5e3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 톄 톈 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc5e4,0xc5e5,0x0000,0x0000,0xc5e6,0x0000,0x0000,0x0000,0xc5e7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 토톡 톤 톨 + 0x0000,0xc5e8,0x0000,0xc5e9,0x0000,0xc5ea,0x0000,0xc5eb,0x0000,0x0000,0x0000,0x0000,0xc5ec,0x0000,0x0000,0x0000,// 톰 톱 톳 통 톺 + 0x0000,0xc5ed,0x0000,0x0000,0x0000,0xc5ee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 톼 퇀 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc5ef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퇘 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xca40 - 0xcaff + 0x0000,0xc5f0,0x0000,0x0000,0x0000,0xc5f1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퇴 퇸 + 0x0000,0x0000,0x0000,0x0000,0x0000,0xc5f2,0x0000,0xc5f3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 툇 툉 + 0x0000,0xc5f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 툐 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc5f5,0xc5f6,0x0000,0x0000,0xc5f7,0x0000,0x0000,0x0000,0xc5f8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 투툭 툰 툴 + 0x0000,0xc5f9,0x0000,0xc5fa,0x0000,0xc5fb,0x0000,0xc5fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 툼 툽 툿 퉁 + 0x0000,0xc5fd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퉈 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc5fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퉜 + 0x0000,0xc6a1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퉤 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc6a2,0xc6a3,0x0000,0x0000,0xc6a4,0x0000,0x0000,0x0000,0xc6a5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 튀튁 튄 튈 + 0x0000,0xc6a6,0x0000,0xc6a7,0x0000,0x0000,0x0000,0xc6a8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 튐 튑 튕 + // 0xcb40 - 0xcbff + 0x0000,0xc6a9,0x0000,0x0000,0x0000,0xc6aa,0x0000,0x0000,0x0000,0xc6ab,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 튜 튠 튤 + 0x0000,0xc6ac,0x0000,0x0000,0x0000,0x0000,0x0000,0xc6ad,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 튬 튱 + 0x0000,0xc6ae,0xc6af,0x0000,0x0000,0xc6b0,0x0000,0x0000,0xc6b1,0xc6b2,0x0000,0xc6b3,0x0000,0x0000,0x0000,0x0000,// 트특 튼 튿틀 틂 + 0x0000,0xc6b4,0x0000,0xc6b5,0x0000,0xc6b6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 틈 틉 틋 + 0x0000,0xc6b7,0x0000,0x0000,0x0000,0xc6b8,0x0000,0x0000,0x0000,0xc6b9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 틔 틘 틜 + 0x0000,0xc6ba,0x0000,0xc6bb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 틤 틥 + 0x0000,0xc6bc,0xc6bd,0x0000,0x0000,0xc6be,0x0000,0x0000,0x0000,0xc6bf,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 티틱 틴 틸 + 0x0000,0xc6c0,0x0000,0xc6c1,0x0000,0xc6c2,0x0000,0xc6c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 팀 팁 팃 팅 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xcc40 - 0xccff + 0x0000,0xa4bd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅍ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc6c4,0xc6c5,0xc6c6,0x0000,0xc6c7,0x0000,0x0000,0x0000,0xc6c8,0x0000,0xc6c9,0x0000,0x0000,0x0000,0x0000,// 파팍팎 판 팔 팖 + 0x0000,0xc6ca,0x0000,0xc6cb,0x0000,0xc6cc,0xc6cd,0xc6ce,0x0000,0x0000,0x0000,0xc6cf,0x0000,0x0000,0x0000,0x0000,// 팜 팝 팟팠팡 팥 + 0x0000,0xc6d0,0xc6d1,0x0000,0x0000,0xc6d2,0x0000,0x0000,0x0000,0xc6d3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 패팩 팬 팰 + 0x0000,0xc6d4,0x0000,0xc6d5,0x0000,0xc6d6,0xc6d7,0xc6d8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 팸 팹 팻팼팽 + 0x0000,0xc6d9,0xc6da,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퍄퍅 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc6db,0xc6dc,0x0000,0x0000,0xc6dd,0x0000,0x0000,0x0000,0xc6de,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퍼퍽 펀 펄 + 0x0000,0xc6df,0x0000,0xc6e0,0x0000,0xc6e1,0xc6e2,0xc6e3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 펌 펍 펏펐펑 + // 0xcd40 - 0xcdff + 0x0000,0xc6e4,0xc6e5,0x0000,0x0000,0xc6e6,0x0000,0x0000,0x0000,0xc6e7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 페펙 펜 펠 + 0x0000,0xc6e8,0x0000,0xc6e9,0x0000,0xc6ea,0x0000,0xc6eb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 펨 펩 펫 펭 + 0x0000,0xc6ec,0x0000,0x0000,0x0000,0xc6ed,0x0000,0x0000,0x0000,0xc6ee,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 펴 편 펼 + 0x0000,0xc6ef,0x0000,0xc6f0,0x0000,0x0000,0xc6f1,0xc6f2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 폄 폅 폈평 + 0x0000,0xc6f3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc6f4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 폐 폘 + 0x0000,0x0000,0x0000,0xc6f5,0x0000,0xc6f6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 폡 폣 + 0x0000,0xc6f7,0xc6f8,0x0000,0x0000,0xc6f9,0x0000,0x0000,0x0000,0xc6fa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 포폭 폰 폴 + 0x0000,0xc6fb,0x0000,0xc6fc,0x0000,0xc6fd,0x0000,0xc6fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 폼 폽 폿 퐁 + 0x0000,0xc7a1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퐈 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc7a2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퐝 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xce40 - 0xceff + 0x0000,0xc7a3,0x0000,0x0000,0x0000,0xc7a4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 푀 푄 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc7a5,0x0000,0x0000,0x0000,0xc7a6,0x0000,0x0000,0x0000,0xc7a7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 표 푠 푤 + 0x0000,0x0000,0x0000,0xc7a8,0x0000,0xc7a9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 푭 푯 + 0x0000,0xc7aa,0xc7ab,0x0000,0x0000,0xc7ac,0x0000,0x0000,0xc7ad,0xc7ae,0x0000,0xc7af,0x0000,0x0000,0x0000,0x0000,// 푸푹 푼 푿풀 풂 + 0x0000,0xc7b0,0x0000,0xc7b1,0x0000,0xc7b2,0x0000,0xc7b3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 품 풉 풋 풍 + 0x0000,0xc7b4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 풔 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc7b5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 풩 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc7b6,0x0000,0x0000,0x0000,0xc7b7,0x0000,0x0000,0x0000,0xc7b8,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퓌 퓐 퓔 + 0x0000,0xc7b9,0x0000,0x0000,0x0000,0xc7ba,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퓜 퓟 + // 0xcf40 - 0xcfff + 0x0000,0xc7bb,0x0000,0x0000,0x0000,0xc7bc,0x0000,0x0000,0x0000,0xc7bd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퓨 퓬 퓰 + 0x0000,0xc7be,0x0000,0x0000,0x0000,0xc7bf,0x0000,0xc7c0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 퓸 퓻 퓽 + 0x0000,0xc7c1,0x0000,0x0000,0x0000,0xc7c2,0x0000,0x0000,0x0000,0xc7c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 프 픈 플 + 0x0000,0xc7c4,0x0000,0xc7c5,0x0000,0xc7c6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 픔 픕 픗 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc7c7,0xc7c8,0x0000,0x0000,0xc7c9,0x0000,0x0000,0x0000,0xc7ca,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 피픽 핀 필 + 0x0000,0xc7cb,0x0000,0xc7cc,0x0000,0xc7cd,0x0000,0xc7ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 핌 핍 핏 핑 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xd040 - 0xd0ff + 0x0000,0xa4be,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ㅎ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc7cf,0xc7d0,0x0000,0x0000,0xc7d1,0x0000,0x0000,0x0000,0xc7d2,0x0000,0x0000,0x0000,0x0000,0xc7d3,0x0000,// 하학 한 할 핥 + 0x0000,0xc7d4,0x0000,0xc7d5,0x0000,0xc7d6,0x0000,0xc7d7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 함 합 핫 항 + 0x0000,0xc7d8,0xc7d9,0x0000,0x0000,0xc7da,0x0000,0x0000,0x0000,0xc7db,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 해핵 핸 핼 + 0x0000,0xc7dc,0x0000,0xc7dd,0x0000,0xc7de,0xc7df,0xc7e0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 햄 햅 햇했행 + 0x0000,0xc7e1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 햐 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc7e2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 향 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0xc7e3,0xc7e4,0x0000,0x0000,0xc7e5,0x0000,0x0000,0x0000,0xc7e6,0x0000,0xc7e7,0x0000,0x0000,0x0000,0x0000,// 허헉 헌 헐 헒 + 0x0000,0xc7e8,0x0000,0xc7e9,0x0000,0xc7ea,0x0000,0xc7eb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 험 헙 헛 헝 + // 0xd140 - 0xd1ff + 0x0000,0xc7ec,0xc7ed,0x0000,0x0000,0xc7ee,0x0000,0x0000,0x0000,0xc7ef,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 헤헥 헨 헬 + 0x0000,0xc7f0,0x0000,0xc7f1,0x0000,0xc7f2,0x0000,0xc7f3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 헴 헵 헷 헹 + 0x0000,0xc7f4,0xc7f5,0x0000,0x0000,0xc7f6,0x0000,0x0000,0x0000,0xc7f7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 혀혁 현 혈 + 0x0000,0xc7f8,0x0000,0xc7f9,0x0000,0xc7fa,0xc7fb,0xc7fc,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 혐 협 혓혔형 + 0x0000,0xc7fd,0x0000,0x0000,0x0000,0xc7fe,0x0000,0x0000,0x0000,0xc8a1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 혜 혠 혤 + 0x0000,0x0000,0x0000,0xc8a2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 혭 + 0x0000,0xc8a3,0xc8a4,0x0000,0x0000,0xc8a5,0x0000,0x0000,0x0000,0xc8a6,0x0000,0x0000,0x0000,0x0000,0xc8a7,0x0000,// 호혹 혼 홀 홅 + 0x0000,0xc8a8,0x0000,0xc8a9,0x0000,0xc8aa,0x0000,0xc8ab,0x0000,0x0000,0x0000,0xc8ac,0x0000,0x0000,0x0000,0x0000,// 홈 홉 홋 홍 홑 + 0x0000,0xc8ad,0xc8ae,0x0000,0x0000,0xc8af,0x0000,0x0000,0x0000,0xc8b0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 화확 환 활 + 0x0000,0x0000,0x0000,0x0000,0x0000,0xc8b1,0x0000,0xc8b2,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 홧 황 + 0x0000,0xc8b3,0xc8b4,0x0000,0x0000,0xc8b5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 홰홱 홴 + 0x0000,0x0000,0x0000,0x0000,0x0000,0xc8b6,0x0000,0xc8b7,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 횃 횅 + // 0xd240 - 0xd2ff + 0x0000,0xc8b8,0xc8b9,0x0000,0x0000,0xc8ba,0x0000,0x0000,0x0000,0xc8bb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 회획 횐 횔 + 0x0000,0x0000,0x0000,0xc8bc,0x0000,0xc8bd,0x0000,0xc8be,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 횝 횟 횡 + 0x0000,0xc8bf,0x0000,0x0000,0x0000,0xc8c0,0x0000,0x0000,0x0000,0xc8c1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 효 횬 횰 + 0x0000,0x0000,0x0000,0xc8c2,0x0000,0xc8c3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 횹 횻 + 0x0000,0xc8c4,0xc8c5,0x0000,0x0000,0xc8c6,0x0000,0x0000,0x0000,0xc8c7,0x0000,0x0000,0x0000,0x0000,0xc8c8,0x0000,// 후훅 훈 훌 훑 + 0x0000,0xc8c9,0x0000,0x0000,0x0000,0xc8ca,0x0000,0xc8cb,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 훔 훗 훙 + 0x0000,0xc8cc,0x0000,0x0000,0x0000,0xc8cd,0x0000,0x0000,0x0000,0xc8ce,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 훠 훤 훨 + 0x0000,0xc8cf,0x0000,0x0000,0x0000,0x0000,0x0000,0xc8d0,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 훰 훵 + 0x0000,0xc8d1,0xc8d2,0x0000,0x0000,0xc8d3,0x0000,0x0000,0x0000,0xc8d4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 훼훽 휀 휄 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0xc8d5,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 휑 + 0x0000,0xc8d6,0xc8d7,0x0000,0x0000,0xc8d8,0x0000,0x0000,0x0000,0xc8d9,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 휘휙 휜 휠 + 0x0000,0xc8da,0x0000,0xc8db,0x0000,0xc8dc,0x0000,0xc8dd,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 휨 휩 휫 휭 + // 0xd340 - 0xd3ff + 0x0000,0xc8de,0xc8df,0x0000,0x0000,0xc8e0,0x0000,0x0000,0x0000,0xc8e1,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 휴휵 휸 휼 + 0x0000,0xc8e2,0x0000,0x0000,0x0000,0xc8e3,0x0000,0xc8e4,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 흄 흇 흉 + 0x0000,0xc8e5,0xc8e6,0x0000,0x0000,0xc8e7,0x0000,0xc8e8,0xc8e9,0xc8ea,0xc8eb,0x0000,0x0000,0x0000,0x0000,0x0000,// 흐흑 흔 흖흗흘흙 + 0x0000,0xc8ec,0x0000,0xc8ed,0x0000,0xc8ee,0x0000,0xc8ef,0x0000,0x0000,0x0000,0xc8f0,0x0000,0x0000,0x0000,0x0000,// 흠 흡 흣 흥 흩 + 0x0000,0xc8f1,0x0000,0x0000,0x0000,0xc8f2,0x0000,0x0000,0x0000,0xc8f3,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 희 흰 흴 + 0x0000,0xc8f4,0x0000,0xc8f5,0x0000,0x0000,0x0000,0xc8f6,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 흼 흽 힁 + 0x0000,0xc8f7,0xc8f8,0x0000,0x0000,0xc8f9,0x0000,0x0000,0x0000,0xc8fa,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 히힉 힌 힐 + 0x0000,0xc8fb,0x0000,0xc8fc,0x0000,0xc8fd,0x0000,0xc8fe,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// 힘 힙 힛 힝 + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xd440 - 0xd4ff + 0x0000,0xc9a1,0xc9a2,0xc9a3,0xc9a4,0xc9a5,0xc9a6,0xc9a7,0xc9a8,0xc9a9,0xc9aa,0xc9ab,0xc9ac,0xc9ad,0xc9ae,0xc9af,//  + 0xc9b0,0xc9b1,0xc9b2,0xc9b3,0xc9b4,0xc9b5,0xc9b6,0xc9b7,0xc9b8,0xc9b9,0xc9ba,0xc9bb,0xc9bc,0xc9bd,0xc9be,0xc9bf,//  + 0xc9c0,0xc9c1,0xc9c2,0xc9c3,0xc9c4,0xc9c5,0xc9c6,0xc9c7,0xc9c8,0xc9c9,0xc9ca,0xc9cb,0xc9cc,0xc9cd,0xc9ce,0xc9cf,//  + 0xc9d0,0xc9d1,0xc9d2,0xc9d3,0xc9d4,0xc9d5,0xc9d6,0xc9d7,0xc9d8,0xc9d9,0xc9da,0xc9db,0xc9dc,0xc9dd,0xc9de,0xc9df,//  + 0x0000,0xc9e0,0xc9e1,0xc9e2,0xc9e3,0xc9e4,0xc9e5,0xc9e6,0xc9e7,0xc9e8,0xc9e9,0xc9ea,0xc9eb,0xc9ec,0xc9ed,0xc9ee,//  + 0xc9ef,0xc9f0,0xc9f1,0xc9f2,0xc9f3,0xc9f4,0xc9f5,0xc9f6,0xc9f7,0xc9f8,0xc9f9,0xc9fa,0xc9fb,0xc9fc,0xc9fd,0xc9fe,//  + 0xfea1,0xfea2,0xfea3,0xfea4,0xfea5,0xfea6,0xfea7,0xfea8,0xfea9,0xfeaa,0xfeab,0xfeac,0xfead,0xfeae,0xfeaf,0xfeb0,//  + 0xfeb1,0xfeb2,0xfeb3,0xfeb4,0xfeb5,0xfeb6,0xfeb7,0xfeb8,0xfeb9,0xfeba,0xfebb,0xfebc,0xfebd,0xfebe,0xfebf,0xfec0,//  + 0xfec1,0xfec2,0xfec3,0xfec4,0xfec5,0xfec6,0xfec7,0xfec8,0xfec9,0xfeca,0xfecb,0xfecc,0xfecd,0xfece,0xfecf,0xfed0,//  + 0xfed1,0xfed2,0xfed3,0xfed4,0xfed5,0xfed6,0xfed7,0xfed8,0xfed9,0xfeda,0xfedb,0xfedc,0xfedd,0xfede,0xfedf,0xfee0,//  + 0xfee1,0xfee2,0xfee3,0xfee4,0xfee5,0xfee6,0xfee7,0xfee8,0xfee9,0xfeea,0xfeeb,0xfeec,0xfeed,0xfeee,0xfeef,0xfef0,//  + 0xfef1,0xfef2,0xfef3,0xfef4,0xfef5,0xfef6,0xfef7,0xfef8,0xfef9,0xfefa,0xfefb,0xfefc,0xfefd,0xfefe,0x0000,0x0000,//  +}; + + public Ebc2Ksc4() + { + + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/Ksc2Ebc1.java b/src/main/java/com/eactive/eai/adapter/wca/util/Ksc2Ebc1.java new file mode 100644 index 0000000..075d56f --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/Ksc2Ebc1.java @@ -0,0 +1,360 @@ +package com.eactive.eai.adapter.wca.util; + +public class Ksc2Ebc1 { + protected static char KSC2EBC[] = { + // 0xa1a0 - 0xa1ff + 0x0000,0x4040,0x4141,0x4142,0x4143,0x4144,0x4145,0x4146,0x4147,0x4148,0x4149,0x414a,0x414b,0x42a1,0x414d,0x414e,//  、。·‥…¨〃­―∥\∼‘’ + 0x414f,0x4150,0x4151,0x4152,0x4153,0x4154,0x4155,0x4156,0x4157,0x4158,0x4159,0x415a,0x415b,0x415c,0x415d,0x415e,// “”〔〕〈〉《》「」『』【】±× + 0x415f,0x418d,0x418e,0x418f,0x4163,0x4164,0x4165,0x4166,0x4167,0x4168,0x4190,0x424a,0x416b,0x416c,0x4191,0x4192,// ÷≠≤≥∞∴°′″℃Å¢£¥♂♀ + 0x4193,0x4194,0x4195,0x4196,0x4197,0x4198,0x4199,0x4176,0x4177,0x4178,0x4179,0x417a,0x417b,0x417c,0x417d,0x417e,// ∠⊥⌒∂∇≡≒§※☆★○●◎◇◆ + 0x417f,0x4180,0x4181,0x4182,0x4183,0x4184,0x4185,0x4186,0x4187,0x4188,0x4189,0x418a,0x419a,0x419b,0x419c,0x419d,// □■△▲▽▼→←↑↓↔〓≪≫√∽ + 0x4941,0x4942,0x4943,0x4944,0x4945,0x4946,0x4947,0x4948,0x4949,0x494a,0x494b,0x494c,0x494d,0x494e,0x425f,0x0000,// ∝∵∫∬∈∋⊆⊇⊂⊃∪∩∧∨¬ + // 0xa2a0 - 0xa2ff + 0x0000,0x494f,0x4950,0x4951,0x4952,0x4953,0x4954,0x4955,0x4956,0x4957,0x4958,0x4959,0x495a,0x495b,0x495c,0x495d,// ⇒⇔∀∃´~ˇ˘˝˚˙¸˛¡¿ + 0x495e,0x495f,0x4960,0x4961,0x4962,0x4963,0x4964,0x4965,0x4966,0x4967,0x4968,0x4969,0x496a,0x496b,0x496c,0x496d,// ː∮∑∏¤℉‰◁◀▷▶♤♠♡♥♧ + 0x496e,0x496f,0x4970,0x4971,0x4972,0x4973,0x4974,0x4975,0x4976,0x4977,0x4978,0x4979,0x497a,0x497b,0x497c,0x497d,// ♣⊙◈▣◐◑▒▤▥▨▧▦▩♨☏☎ + 0x497e,0x497f,0x4980,0x4981,0x4982,0x4983,0x4984,0x4985,0x4986,0x4987,0x4988,0x4989,0x498a,0x498b,0x498c,0x498d,// ☜☞¶†‡↕↗↙↖↘♭♩♪♬㉿㈜ + 0x498e,0x498f,0x4990,0x4991,0x4992,0x4993,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// №㏇™㏂㏘℡ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xa3a0 - 0xa3ff + 0x0000,0x425a,0x427f,0x427b,0x425b,0x426c,0x4250,0x427d,0x424d,0x425d,0x425c,0x424e,0x426b,0x4260,0x424b,0x4261,// !"#$%&'()*+,-./ + 0x42f0,0x42f1,0x42f2,0x42f3,0x42f4,0x42f5,0x42f6,0x42f7,0x42f8,0x42f9,0x427a,0x425e,0x424c,0x427e,0x426e,0x426f,// 0123456789:;<=>? + 0x427c,0x42c1,0x42c2,0x42c3,0x42c4,0x42c5,0x42c6,0x42c7,0x42c8,0x42c9,0x42d1,0x42d2,0x42d3,0x42d4,0x42d5,0x42d6,// @ABCDEFGHIJKLMNO + 0x42d7,0x42d8,0x42d9,0x42e2,0x42e3,0x42e4,0x42e5,0x42e6,0x42e7,0x42e8,0x42e9,0x418b,0x42e0,0x418c,0x416a,0x426d,// PQRSTUVWXYZ[₩]^_ + 0x4279,0x4281,0x4282,0x4283,0x4284,0x4285,0x4286,0x4287,0x4288,0x4289,0x4291,0x4292,0x4293,0x4294,0x4295,0x4296,// `abcdefghijklmno + 0x4297,0x4298,0x4299,0x42a2,0x42a3,0x42a4,0x42a5,0x42a6,0x42a7,0x42a8,0x42a9,0x42c0,0x424f,0x42d0,0x414c,0x0000,// pqrstuvwxyz{|} ̄ + // 0xa4a0 - 0xa4ff + 0x0000,0x8841,0x8c41,0x8444,0x9041,0x8446,0x8447,0x9441,0x9841,0x9c41,0x844a,0x844b,0x844c,0x844d,0x844e,0x844f,// ㄱㄲㄳㄴㄵㄶㄷㄸㄹㄺㄻㄼㄽㄾㄿ + 0x8450,0xa041,0xa441,0xa841,0x8454,0xac41,0xb041,0xb441,0xb841,0xbc41,0xc041,0xc441,0xc841,0xcc41,0xd041,0x8461,// ㅀㅁㅂㅃㅄㅅㅆㅇㅈㅉㅊㅋㅌㅍㅎㅏ + 0x8481,0x84a1,0x84c1,0x84e1,0x8541,0x8561,0x8581,0x85a1,0x85c1,0x85e1,0x8641,0x8661,0x8681,0x86a1,0x86c1,0x86e1,// ㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟ + 0x8741,0x8761,0x8781,0x87a1,0x8441,0x4341,0x4342,0x4343,0x4344,0x4345,0x4346,0x4347,0x4348,0x4349,0x434a,0x434b,// ㅠㅡㅢㅣㅤㅥㅦㅧㅨㅩㅪㅫㅬㅭㅮㅯ + 0x434c,0x434d,0x434e,0x434f,0x4350,0x4351,0x4352,0x4353,0x4354,0x4355,0x4356,0x4357,0x4358,0x4359,0x435a,0x435b,// ㅰㅱㅲㅳㅴㅵㅶㅷㅸㅹㅺㅻㅼㅽㅾㅿ + 0x435c,0x435d,0x435e,0x435f,0x4360,0x4361,0x4362,0x4363,0x4364,0x4365,0x4366,0x4367,0x4368,0x4369,0x436a,0x0000,// ㆀㆁㆂㆃㆄㆅㆆㆇㆈㆉㆊㆋㆌㆍㆎ + // 0xa5a0 - 0xa5ff + 0x0000,0x4641,0x4642,0x4643,0x4644,0x4645,0x4646,0x4647,0x4648,0x4649,0x464a,0x0000,0x0000,0x0000,0x0000,0x0000,// ⅰⅱⅲⅳⅴⅵⅶⅷⅸⅹ + 0x4650,0x4651,0x4652,0x4653,0x4654,0x4655,0x4656,0x4657,0x4658,0x4659,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ + 0x0000,0x4661,0x4662,0x4663,0x4664,0x4665,0x4666,0x4667,0x4668,0x4669,0x466a,0x466b,0x466c,0x466d,0x466e,0x466f,// ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟ + 0x4670,0x4671,0x4672,0x4673,0x4674,0x4675,0x4676,0x4677,0x4678,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ΠΡΣΤΥΦΧΨΩ + 0x0000,0x4681,0x4682,0x4683,0x4684,0x4685,0x4686,0x4687,0x4688,0x4689,0x468a,0x468b,0x468c,0x468d,0x468e,0x468f,// αβγδεζηθικλμνξο + 0x4690,0x4691,0x4692,0x4693,0x4694,0x4695,0x4696,0x4697,0x4698,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// πρστυφχψω + // 0xa6a0 - 0xa6ff + 0x0000,0x4741,0x4742,0x4743,0x4744,0x4745,0x4746,0x4747,0x4748,0x4749,0x474a,0x474b,0x474c,0x474d,0x474e,0x474f,// ─│┌┐┘└├┬┤┴┼━┃┏┓ + 0x4750,0x4751,0x4752,0x4753,0x4754,0x4755,0x4756,0x4757,0x4758,0x4759,0x475a,0x475b,0x475c,0x475d,0x475e,0x475f,// ┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸ + 0x4760,0x4761,0x4762,0x4763,0x4764,0x4765,0x4766,0x4767,0x4768,0x4769,0x476a,0x476b,0x476c,0x476d,0x476e,0x476f,// ╂┒┑┚┙┖┕┎┍┞┟┡┢┦┧┩ + 0x4770,0x4771,0x4772,0x4773,0x4774,0x4775,0x4776,0x4777,0x4778,0x4779,0x477a,0x477b,0x477c,0x477d,0x477e,0x477f,// ┪┭┮┱┲┵┶┹┺┽┾╀╁╃╄╅ + 0x4780,0x4781,0x4782,0x4783,0x4784,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ╆╇╈╉╊ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xa7a0 - 0xa7ff + 0x0000,0x4841,0x416d,0x416e,0x416f,0x4842,0x4170,0x4843,0x4844,0x4845,0x4846,0x4847,0x4848,0x4849,0x4171,0x4172,// ㎕㎖㎗ℓ㎘㏄㎣㎤㎥㎦㎙㎚㎛㎜㎝ + 0x4173,0x484a,0x484b,0x484c,0x484d,0x484e,0x484f,0x4174,0x4175,0x4850,0x4851,0x4852,0x4853,0x4854,0x4855,0x4856,// ㎞㎟㎠㎡㎢㏊㎍㎎㎏㏏㎈㎉㏈㎧㎨㎰ + 0x4857,0x4858,0x4859,0x485a,0x485b,0x485c,0x485d,0x485e,0x485f,0x4860,0x4861,0x4862,0x4863,0x4864,0x4865,0x4866,// ㎱㎲㎳㎴㎵㎶㎷㎸㎹㎀㎁㎂㎃㎄㎺㎻ + 0x4867,0x4868,0x4869,0x486a,0x486b,0x486c,0x486d,0x486e,0x486f,0x4870,0x4871,0x4872,0x4873,0x4874,0x4875,0x4876,// ㎼㎽㎾㎿㎐㎑㎒㎓㎔Ω㏀㏁㎊㎋㎌㏖ + 0x4877,0x4878,0x4879,0x487a,0x487b,0x487c,0x487d,0x487e,0x487f,0x4880,0x4881,0x4882,0x4883,0x4884,0x4885,0x4886,// ㏅㎭㎮㎯㏛㎩㎪㎫㎬㏝㏐㏓㏃㏉㏜㏆ + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xa8a0 - 0xa8ff + 0x0000,0x4b41,0x4b42,0x4b43,0x4b44,0x0000,0x4b46,0x0000,0x4b48,0x4b49,0x4b4a,0x4b4b,0x4b4c,0x4b4d,0x4b4e,0x4b4f,// ÆÐªĦ IJ ĿŁØŒºÞŦŊ + 0x0000,0x4b51,0x4b52,0x4b53,0x4b54,0x4b55,0x4b56,0x4b57,0x4b58,0x4b59,0x4b5a,0x4b5b,0x4b5c,0x4b5d,0x4b5e,0x4b5f,// ㉠㉡㉢㉣㉤㉥㉦㉧㉨㉩㉪㉫㉬㉭㉮ + 0x4b60,0x4b61,0x4b62,0x4b63,0x4b64,0x4b65,0x4b66,0x4b67,0x4b68,0x4b69,0x4b6a,0x4b6b,0x4b6c,0x4b6d,0x4b6e,0x4b6f,// ㉯㉰㉱㉲㉳㉴㉵㉶㉷㉸㉹㉺㉻ⓐⓑⓒ + 0x4b70,0x4b71,0x4b72,0x4b73,0x4b74,0x4b75,0x4b76,0x4b77,0x4b78,0x4b79,0x4b7a,0x4b7b,0x4b7c,0x4b7d,0x4b7e,0x4b7f,// ⓓⓔⓕⓖⓗⓘⓙⓚⓛⓜⓝⓞⓟⓠⓡⓢ + 0x4b80,0x4b81,0x4b82,0x4b83,0x4b84,0x4b85,0x4b86,0x4b87,0x4b88,0x4b89,0x4b8a,0x4b8b,0x4b8c,0x4b8d,0x4b8e,0x4b8f,// ⓣⓤⓥⓦⓧⓨⓩ①②③④⑤⑥⑦⑧⑨ + 0x4b90,0x4b91,0x4b92,0x4b93,0x4b94,0x4b95,0x4b96,0x4b97,0x4b98,0x4b99,0x4b9a,0x4b9b,0x4b9c,0x4b9d,0x4b9e,0x0000,// ⑩⑪⑫⑬⑭⑮½⅓⅔¼¾⅛⅜⅝⅞ + // 0xa9a0 - 0xa9ff + 0x0000,0x4ba0,0x4ba1,0x4ba2,0x4ba3,0x4ba4,0x4ba5,0x4ba6,0x4ba7,0x4ba8,0x4ba9,0x4baa,0x4bab,0x4bac,0x4bad,0x4bae,// æđðħıijĸŀłøœßþŧŋ + 0x4baf,0x4bb0,0x4bb1,0x4bb2,0x4bb3,0x4bb4,0x4bb5,0x4bb6,0x4bb7,0x4bb8,0x4bb9,0x4bba,0x4bbb,0x4bbc,0x4bbd,0x4bbe,// ʼn㈀㈁㈂㈃㈄㈅㈆㈇㈈㈉㈊㈋㈌㈍㈎ + 0x4bbf,0x4bc0,0x4bc1,0x4bc2,0x4bc3,0x4bc4,0x4bc5,0x4bc6,0x4bc7,0x4bc8,0x4bc9,0x4bca,0x4bcb,0x4bcc,0x4bcd,0x4bce,// ㈏㈐㈑㈒㈓㈔㈕㈖㈗㈘㈙㈚㈛⒜⒝⒞ + 0x4bcf,0x4bd0,0x4bd1,0x4bd2,0x4bd3,0x4bd4,0x4bd5,0x4bd6,0x4bd7,0x4bd8,0x4bd9,0x4bda,0x4bdb,0x4bdc,0x4bdd,0x4bde,// ⒟⒠⒡⒢⒣⒤⒥⒦⒧⒨⒩⒪⒫⒬⒭⒮ + 0x4bdf,0x4be0,0x4be1,0x4be2,0x4be3,0x4be4,0x4be5,0x4be6,0x4be7,0x4be8,0x4be9,0x4bea,0x4beb,0x4bec,0x4bed,0x4bee,// ⒯⒰⒱⒲⒳⒴⒵⑴⑵⑶⑷⑸⑹⑺⑻⑼ + 0x4bef,0x4bf0,0x4bf1,0x4bf2,0x4bf3,0x4bf4,0x4bf5,0x4bf6,0x4bf7,0x4bf8,0x4bf9,0x4bfa,0x4bfb,0x4bfc,0x4bfd,0x0000,// ⑽⑾⑿⒀⒁⒂¹²³⁴ⁿ₁₂₃₄ + // 0xaaa0 - 0xaaff + 0x0000,0x4441,0x4442,0x4443,0x4444,0x4445,0x4446,0x4447,0x4448,0x4449,0x444a,0x444b,0x444c,0x444d,0x444e,0x444f,// ぁあぃいぅうぇえぉおかがきぎく + 0x4450,0x4451,0x4452,0x4453,0x4454,0x4455,0x4456,0x4457,0x4458,0x4459,0x445a,0x445b,0x445c,0x445d,0x445e,0x445f,// ぐけげこごさざしじすずせぜそぞた + 0x4460,0x4461,0x4462,0x4463,0x4464,0x4465,0x4466,0x4467,0x4468,0x4469,0x446a,0x446b,0x446c,0x446d,0x446e,0x446f,// だちぢっつづてでとどなにぬねのは + 0x4470,0x4471,0x4472,0x4473,0x4474,0x4475,0x4476,0x4477,0x4478,0x4479,0x447a,0x447b,0x447c,0x447d,0x447e,0x447f,// ばぱひびぴふぶぷへべぺほぼぽまみ + 0x4480,0x4481,0x4482,0x4483,0x4484,0x4485,0x4486,0x4487,0x4488,0x4489,0x448a,0x448b,0x448c,0x448d,0x448e,0x448f,// むめもゃやゅゆょよらりるれろゎわ + 0x4490,0x4491,0x4492,0x4493,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ゐゑをん + // 0xaba0 - 0xabff + 0x0000,0x4541,0x4542,0x4543,0x4544,0x4545,0x4546,0x4547,0x4548,0x4549,0x454a,0x454b,0x454c,0x454d,0x454e,0x454f,// ァアィイゥウェエォオカガキギク + 0x4550,0x4551,0x4552,0x4553,0x4554,0x4555,0x4556,0x4557,0x4558,0x4559,0x455a,0x455b,0x455c,0x455d,0x455e,0x455f,// グケゲコゴサザシジスズセゼソゾタ + 0x4560,0x4561,0x4562,0x4563,0x4564,0x4565,0x4566,0x4567,0x4568,0x4569,0x456a,0x456b,0x456c,0x456d,0x456e,0x456f,// ダチヂッツヅテデトドナニヌネノハ + 0x4570,0x4571,0x4572,0x4573,0x4574,0x4575,0x4576,0x4577,0x4578,0x4579,0x457a,0x457b,0x457c,0x457d,0x457e,0x457f,// バパヒビピフブプヘベペホボポマミ + 0x4580,0x4581,0x4582,0x4583,0x4584,0x4585,0x4586,0x4587,0x4588,0x4589,0x458a,0x458b,0x458c,0x458d,0x458e,0x458f,// ムメモャヤュユョヨラリルレロヮワ + 0x4590,0x4591,0x4592,0x4593,0x4594,0x4595,0x4596,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ヰヱヲンヴヵヶ + // 0xaca0 - 0xacff + 0x0000,0x4a41,0x4a42,0x4a43,0x4a44,0x4a45,0x4a46,0x4a47,0x4a48,0x4a49,0x4a4a,0x4a4b,0x4a4c,0x4a4d,0x4a4e,0x4a4f,// АБВГДЕЁЖЗИЙКЛМН + 0x4a50,0x4a51,0x4a52,0x4a53,0x4a54,0x4a55,0x4a56,0x4a57,0x4a58,0x4a59,0x4a5a,0x4a5b,0x4a5c,0x4a5d,0x4a5e,0x4a5f,// ОПРСТУФХЦЧШЩЪЫЬЭ + 0x4a60,0x4a61,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// ЮЯ + 0x0000,0x4a62,0x4a63,0x4a64,0x4a65,0x4a66,0x4a67,0x4a68,0x4a69,0x4a6a,0x4a6b,0x4a6c,0x4a6d,0x4a6e,0x4a6f,0x4a70,// абвгдеёжзийклмн + 0x4a71,0x4a72,0x4a73,0x4a74,0x4a75,0x4a76,0x4a77,0x4a78,0x4a79,0x4a7a,0x4a7b,0x4a7c,0x4a7d,0x4a7e,0x4a7f,0x4a80,// опрстуфхцчшщъыьэ + 0x4a81,0x4a82,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// юя + // 0xada0 - 0xadff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xaea0 - 0xaeff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xafa0 - 0xafff + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,// + // 0xb0a0 - 0xb0ff + 0x0000,0x8861,0x8862,0x8865,0x8868,0x8869,0x886a,0x886b,0x8871,0x8873,0x8874,0x8875,0x8876,0x8877,0x8878,0x8879,// 가각간갇갈갉갊감갑값갓갔강갖갗 + 0x887b,0x887c,0x887d,0x8881,0x8882,0x8885,0x8889,0x8891,0x8893,0x8895,0x8896,0x8897,0x88a1,0x88a2,0x88a5,0x88a9,// 같갚갛개객갠갤갬갭갯갰갱갸갹갼걀 + 0x88b5,0x88b7,0x88c1,0x88c5,0x88c9,0x88e1,0x88e2,0x88e5,0x88e8,0x88e9,0x88eb,0x88f1,0x88f3,0x88f5,0x88f6,0x88f7,// 걋걍걔걘걜거걱건걷걸걺검겁것겄겅 + 0x88f8,0x88fb,0x88fc,0x88fd,0x8941,0x8945,0x8949,0x8951,0x8953,0x8955,0x8956,0x8957,0x8961,0x8962,0x8963,0x8965,// 겆겉겊겋게겐겔겜겝겟겠겡겨격겪견 + 0x8968,0x8969,0x8971,0x8973,0x8975,0x8976,0x8977,0x897b,0x8981,0x8985,0x8989,0x8993,0x8995,0x89a1,0x89a2,0x89a5,// 겯결겸겹겻겼경곁계곈곌곕곗고곡곤 + 0x89a8,0x89a9,0x89ab,0x89ad,0x89b0,0x89b1,0x89b3,0x89b5,0x89b7,0x89b8,0x89c1,0x89c2,0x89c5,0x89c9,0x89cb,0x0000,// 곧골곪곬곯곰곱곳공곶과곽관괄괆 + // 0xb1a0 - 0xb1ff + 0x0000,0x89d1,0x89d3,0x89d5,0x89d7,0x89e1,0x89e5,0x89e9,0x89f3,0x89f6,0x89f7,0x8a41,0x8a42,0x8a45,0x8a49,0x8a51,// 괌괍괏광괘괜괠괩괬괭괴괵괸괼굄 + 0x8a53,0x8a55,0x8a57,0x8a61,0x8a65,0x8a69,0x8a73,0x8a75,0x8a81,0x8a82,0x8a85,0x8a88,0x8a89,0x8a8a,0x8a8b,0x8a90,// 굅굇굉교굔굘굡굣구국군굳굴굵굶굻 + 0x8a91,0x8a93,0x8a95,0x8a97,0x8a98,0x8aa1,0x8aa2,0x8aa5,0x8aa9,0x8ab6,0x8ab7,0x8ac1,0x8ad5,0x8ae1,0x8ae2,0x8ae5,// 굼굽굿궁궂궈궉권궐궜궝궤궷귀귁귄 + 0x8ae9,0x8af1,0x8af3,0x8af5,0x8b41,0x8b45,0x8b49,0x8b61,0x8b62,0x8b65,0x8b68,0x8b69,0x8b6a,0x8b71,0x8b73,0x8b75,// 귈귐귑귓규균귤그극근귿글긁금급긋 + 0x8b77,0x8b81,0x8ba1,0x8ba2,0x8ba5,0x8ba8,0x8ba9,0x8bab,0x8bb1,0x8bb3,0x8bb5,0x8bb7,0x8bb8,0x8bbc,0x8c61,0x8c62,// 긍긔기긱긴긷길긺김깁깃깅깆깊까깍 + 0x8c63,0x8c65,0x8c69,0x8c6b,0x8c71,0x8c73,0x8c75,0x8c76,0x8c77,0x8c7b,0x8c81,0x8c82,0x8c85,0x8c89,0x8c91,0x0000,// 깎깐깔깖깜깝깟깠깡깥깨깩깬깰깸 + // 0xb2a0 - 0xb2ff + 0x0000,0x8c93,0x8c95,0x8c96,0x8c97,0x8ca1,0x8ca2,0x8ca9,0x8ce1,0x8ce2,0x8ce3,0x8ce5,0x8ce9,0x8cf1,0x8cf3,0x8cf5,// 깹깻깼깽꺄꺅꺌꺼꺽꺾껀껄껌껍껏 + 0x8cf6,0x8cf7,0x8d41,0x8d42,0x8d45,0x8d51,0x8d55,0x8d57,0x8d61,0x8d65,0x8d69,0x8d75,0x8d76,0x8d7b,0x8d81,0x8da1,// 껐껑께껙껜껨껫껭껴껸껼꼇꼈꼍꼐꼬 + 0x8da2,0x8da5,0x8da7,0x8da9,0x8db1,0x8db3,0x8db5,0x8db7,0x8db8,0x8db9,0x8dc1,0x8dc2,0x8dc9,0x8dd6,0x8dd7,0x8de1,// 꼭꼰꼲꼴꼼꼽꼿꽁꽂꽃꽈꽉꽐꽜꽝꽤 + 0x8de2,0x8df7,0x8e41,0x8e45,0x8e49,0x8e51,0x8e53,0x8e57,0x8e61,0x8e81,0x8e82,0x8e85,0x8e89,0x8e90,0x8e91,0x8e93,// 꽥꽹꾀꾄꾈꾐꾑꾕꾜꾸꾹꾼꿀꿇꿈꿉 + 0x8e95,0x8e97,0x8e98,0x8ea1,0x8ea9,0x8eb6,0x8eb7,0x8ec1,0x8ec2,0x8ec5,0x8ec9,0x8ed1,0x8ed3,0x8ed6,0x8ee1,0x8ee5,// 꿋꿍꿎꿔꿜꿨꿩꿰꿱꿴꿸뀀뀁뀄뀌뀐 + 0x8ee9,0x8ef1,0x8ef3,0x8f41,0x8f61,0x8f62,0x8f65,0x8f67,0x8f69,0x8f6b,0x8f70,0x8f71,0x8f73,0x8f75,0x8f77,0x0000,// 뀔뀜뀝뀨끄끅끈끊끌끎끓끔끕끗끙 + // 0xb3a0 - 0xb3ff + 0x0000,0x8f7b,0x8fa1,0x8fa2,0x8fa5,0x8fa9,0x8fb1,0x8fb3,0x8fb5,0x8fb7,0x9061,0x9062,0x9063,0x9065,0x9068,0x9069,// 끝끼끽낀낄낌낍낏낑나낙낚난낟날 + 0x906a,0x906b,0x9071,0x9073,0x9075,0x9076,0x9077,0x9078,0x9079,0x907b,0x907d,0x9081,0x9082,0x9085,0x9089,0x9091,// 낡낢남납낫났낭낮낯낱낳내낵낸낼냄 + 0x9093,0x9095,0x9096,0x9097,0x90a1,0x90a2,0x90a5,0x90a9,0x90b1,0x90b7,0x90e1,0x90e2,0x90e4,0x90e5,0x90e9,0x90eb,// 냅냇냈냉냐냑냔냘냠냥너넉넋넌널넒 + 0x90ec,0x90f1,0x90f3,0x90f5,0x90f6,0x90f7,0x90fd,0x9141,0x9142,0x9145,0x9149,0x9151,0x9153,0x9155,0x9156,0x9157,// 넓넘넙넛넜넝넣네넥넨넬넴넵넷넸넹 + 0x9161,0x9162,0x9165,0x9169,0x9171,0x9173,0x9176,0x9177,0x917a,0x9181,0x9185,0x91a1,0x91a2,0x91a5,0x91a9,0x91ab,// 녀녁년녈념녑녔녕녘녜녠노녹논놀놂 + 0x91b1,0x91b3,0x91b5,0x91b7,0x91bc,0x91bd,0x91c1,0x91c5,0x91c9,0x91d6,0x9241,0x9245,0x9249,0x9251,0x9253,0x0000,// 놈놉놋농높놓놔놘놜놨뇌뇐뇔뇜뇝 + // 0xb4a0 - 0xb4ff + 0x0000,0x9255,0x9261,0x9262,0x9265,0x9269,0x9273,0x9275,0x9277,0x9281,0x9282,0x9285,0x9288,0x9289,0x9291,0x9293,// 뇟뇨뇩뇬뇰뇹뇻뇽누눅눈눋눌눔눕 + 0x9295,0x9297,0x92a1,0x92b6,0x92c1,0x92e1,0x92e5,0x92e9,0x92f1,0x92f3,0x9341,0x9342,0x9349,0x9351,0x9353,0x9357,// 눗눙눠눴눼뉘뉜뉠뉨뉩뉴뉵뉼늄늅늉 + 0x9361,0x9362,0x9365,0x9369,0x936a,0x936b,0x9371,0x9373,0x9375,0x9377,0x9378,0x937c,0x9381,0x9385,0x9389,0x93a1,// 느늑는늘늙늚늠늡늣능늦늪늬늰늴니 + 0x93a2,0x93a5,0x93a9,0x93ab,0x93b1,0x93b3,0x93b5,0x93b7,0x93bc,0x9461,0x9462,0x9463,0x9465,0x9468,0x9469,0x946a,// 닉닌닐닒님닙닛닝닢다닥닦단닫달닭 + 0x946b,0x946c,0x9470,0x9471,0x9473,0x9475,0x9476,0x9477,0x9478,0x9479,0x947d,0x9481,0x9482,0x9485,0x9489,0x9491,// 닮닯닳담답닷닸당닺닻닿대댁댄댈댐 + 0x9493,0x9495,0x9496,0x9497,0x94a1,0x94e1,0x94e2,0x94e3,0x94e5,0x94e8,0x94e9,0x94eb,0x94ec,0x94f1,0x94f3,0x0000,// 댑댓댔댕댜더덕덖던덛덜덞덟덤덥 + // 0xb5a0 - 0xb5ff + 0x0000,0x94f5,0x94f7,0x94f9,0x94fc,0x9541,0x9542,0x9545,0x9549,0x9551,0x9553,0x9555,0x9556,0x9557,0x9561,0x9565,// 덧덩덫덮데덱덴델뎀뎁뎃뎄뎅뎌뎐 + 0x9569,0x9576,0x9577,0x9581,0x9585,0x95a1,0x95a2,0x95a5,0x95a8,0x95a9,0x95ab,0x95ad,0x95b1,0x95b3,0x95b5,0x95b7,// 뎔뎠뎡뎨뎬도독돈돋돌돎돐돔돕돗동 + 0x95b9,0x95bb,0x95c1,0x95c5,0x95c9,0x95e1,0x95f6,0x9641,0x9645,0x9649,0x9651,0x9653,0x9655,0x9661,0x9681,0x9682,// 돛돝돠돤돨돼됐되된될됨됩됫됴두둑 + 0x9685,0x9689,0x9691,0x9693,0x9695,0x9697,0x96a1,0x96b6,0x96c1,0x96d7,0x96e1,0x96e5,0x96e9,0x96f3,0x96f5,0x96f7,// 둔둘둠둡둣둥둬뒀뒈뒝뒤뒨뒬뒵뒷뒹 + 0x9741,0x9745,0x9749,0x9751,0x9757,0x9761,0x9762,0x9765,0x9768,0x9769,0x976b,0x9771,0x9773,0x9775,0x9777,0x9781,// 듀듄듈듐듕드득든듣들듦듬듭듯등듸 + 0x97a1,0x97a2,0x97a5,0x97a8,0x97a9,0x97b1,0x97b3,0x97b5,0x97b6,0x97b7,0x97b8,0x9861,0x9862,0x9865,0x9869,0x0000,// 디딕딘딛딜딤딥딧딨딩딪따딱딴딸 + // 0xb6a0 - 0xb6ff + 0x0000,0x9871,0x9873,0x9875,0x9876,0x9877,0x987d,0x9881,0x9882,0x9885,0x9889,0x9891,0x9893,0x9895,0x9896,0x9897,// 땀땁땃땄땅땋때땍땐땔땜땝땟땠땡 + 0x98e1,0x98e2,0x98e5,0x98e9,0x98eb,0x98ec,0x98f1,0x98f3,0x98f5,0x98f6,0x98f7,0x98fd,0x9941,0x9942,0x9945,0x9949,// 떠떡떤떨떪떫떰떱떳떴떵떻떼떽뗀뗄 + 0x9951,0x9953,0x9955,0x9956,0x9957,0x9961,0x9976,0x99a1,0x99a2,0x99a5,0x99a9,0x99b7,0x99c1,0x99c9,0x99e1,0x9a41,// 뗌뗍뗏뗐뗑뗘뗬또똑똔똘똥똬똴뙈뙤 + 0x9a45,0x9a81,0x9a82,0x9a85,0x9a89,0x9a90,0x9a91,0x9a97,0x9ac1,0x9ae1,0x9ae5,0x9ae9,0x9af1,0x9af3,0x9af7,0x9b61,// 뙨뚜뚝뚠뚤뚫뚬뚱뛔뛰뛴뛸뜀뜁뜅뜨 + 0x9b62,0x9b65,0x9b68,0x9b69,0x9b71,0x9b73,0x9b75,0x9b81,0x9b85,0x9b89,0x9b91,0x9b93,0x9ba1,0x9ba5,0x9ba9,0x9bb1,// 뜩뜬뜯뜰뜸뜹뜻띄띈띌띔띕띠띤띨띰 + 0x9bb3,0x9bb5,0x9bb7,0x9c61,0x9c62,0x9c65,0x9c69,0x9c71,0x9c73,0x9c75,0x9c76,0x9c77,0x9c78,0x9c7c,0x9c7d,0x0000,// 띱띳띵라락란랄람랍랏랐랑랒랖랗 + // 0xb7a0 - 0xb7ff + 0x0000,0x9c81,0x9c82,0x9c85,0x9c89,0x9c91,0x9c93,0x9c95,0x9c96,0x9c97,0x9ca1,0x9ca2,0x9ca5,0x9cb5,0x9cb7,0x9ce1,// 래랙랜랠램랩랫랬랭랴략랸럇량러 + 0x9ce2,0x9ce5,0x9ce9,0x9cf1,0x9cf3,0x9cf5,0x9cf6,0x9cf7,0x9cfd,0x9d41,0x9d42,0x9d45,0x9d49,0x9d51,0x9d53,0x9d55,// 럭런럴럼럽럿렀렁렇레렉렌렐렘렙렛 + 0x9d57,0x9d61,0x9d62,0x9d65,0x9d69,0x9d71,0x9d73,0x9d75,0x9d76,0x9d77,0x9d81,0x9d85,0x9d93,0x9d95,0x9da1,0x9da2,// 렝려력련렬렴렵렷렸령례롄롑롓로록 + 0x9da5,0x9da9,0x9db1,0x9db3,0x9db5,0x9db7,0x9dc1,0x9dc5,0x9dd7,0x9df6,0x9e41,0x9e45,0x9e49,0x9e51,0x9e53,0x9e55,// 론롤롬롭롯롱롸롼뢍뢨뢰뢴뢸룀룁룃 + 0x9e57,0x9e61,0x9e65,0x9e69,0x9e73,0x9e75,0x9e77,0x9e81,0x9e82,0x9e85,0x9e89,0x9e91,0x9e93,0x9e95,0x9e97,0x9ea1,// 룅료룐룔룝룟룡루룩룬룰룸룹룻룽뤄 + 0x9eb6,0x9ec1,0x9ee1,0x9ee2,0x9ee5,0x9ee9,0x9ef1,0x9ef5,0x9ef7,0x9f41,0x9f42,0x9f45,0x9f49,0x9f51,0x9f53,0x0000,// 뤘뤠뤼뤽륀륄륌륏륑류륙륜률륨륩 + // 0xb8a0 - 0xb8ff + 0x0000,0x9f55,0x9f57,0x9f61,0x9f62,0x9f65,0x9f69,0x9f71,0x9f73,0x9f75,0x9f77,0x9f78,0x9f7b,0x9f7c,0x9fa1,0x9fa2,// 륫륭르륵른를름릅릇릉릊릍릎리릭 + 0x9fa5,0x9fa9,0x9fb1,0x9fb3,0x9fb5,0x9fb7,0xa061,0xa062,0xa065,0xa067,0xa068,0xa069,0xa06a,0xa06b,0xa071,0xa073,// 린릴림립릿링마막만많맏말맑맒맘맙 + 0xa075,0xa077,0xa078,0xa07b,0xa07d,0xa081,0xa082,0xa085,0xa089,0xa091,0xa093,0xa095,0xa096,0xa097,0xa098,0xa0a1,// 맛망맞맡맣매맥맨맬맴맵맷맸맹맺먀 + 0xa0a2,0xa0a9,0xa0b7,0xa0e1,0xa0e2,0xa0e5,0xa0e9,0xa0eb,0xa0f1,0xa0f3,0xa0f5,0xa0f7,0xa0f8,0xa0fd,0xa141,0xa142,// 먁먈먕머먹먼멀멂멈멉멋멍멎멓메멕 + 0xa145,0xa149,0xa151,0xa153,0xa155,0xa156,0xa157,0xa161,0xa162,0xa165,0xa169,0xa175,0xa176,0xa177,0xa179,0xa181,// 멘멜멤멥멧멨멩며멱면멸몃몄명몇몌 + 0xa1a1,0xa1a2,0xa1a4,0xa1a5,0xa1a9,0xa1ab,0xa1b1,0xa1b3,0xa1b5,0xa1b7,0xa1c1,0xa1c5,0xa1d6,0xa1d7,0xa241,0x0000,// 모목몫몬몰몲몸몹못몽뫄뫈뫘뫙뫼 + // 0xb9a0 - 0xb9ff + 0x0000,0xa245,0xa249,0xa253,0xa255,0xa257,0xa261,0xa265,0xa269,0xa273,0xa275,0xa281,0xa282,0xa283,0xa285,0xa288,// 묀묄묍묏묑묘묜묠묩묫무묵묶문묻 + 0xa289,0xa28a,0xa28b,0xa291,0xa293,0xa295,0xa297,0xa29b,0xa29d,0xa2a1,0xa2a5,0xa2a9,0xa2b3,0xa2b5,0xa2c1,0xa2e1,// 물묽묾뭄뭅뭇뭉뭍뭏뭐뭔뭘뭡뭣뭬뮈 + 0xa2e5,0xa2e9,0xa341,0xa345,0xa349,0xa351,0xa355,0xa361,0xa365,0xa369,0xa371,0xa375,0xa3a1,0xa3a2,0xa3a5,0xa3a8,// 뮌뮐뮤뮨뮬뮴뮷므믄믈믐믓미믹민믿 + 0xa3a9,0xa3ab,0xa3b1,0xa3b3,0xa3b5,0xa3b6,0xa3b7,0xa3b9,0xa3bb,0xa461,0xa462,0xa463,0xa464,0xa465,0xa468,0xa469,// 밀밂밈밉밋밌밍및밑바박밖밗반받발 + 0xa46a,0xa46b,0xa46c,0xa471,0xa473,0xa475,0xa477,0xa47b,0xa481,0xa482,0xa485,0xa489,0xa491,0xa493,0xa495,0xa496,// 밝밞밟밤밥밧방밭배백밴밸뱀뱁뱃뱄 + 0xa497,0xa49b,0xa4a1,0xa4a2,0xa4a5,0xa4b3,0xa4e1,0xa4e2,0xa4e5,0xa4e8,0xa4e9,0xa4eb,0xa4f1,0xa4f3,0xa4f5,0x0000,// 뱅뱉뱌뱍뱐뱝버벅번벋벌벎범법벗 + // 0xbaa0 - 0xbaff + 0x0000,0xa4f7,0xa4f8,0xa541,0xa542,0xa545,0xa548,0xa549,0xa551,0xa553,0xa555,0xa556,0xa557,0xa561,0xa562,0xa565,// 벙벚베벡벤벧벨벰벱벳벴벵벼벽변 + 0xa569,0xa573,0xa575,0xa576,0xa577,0xa57b,0xa581,0xa585,0xa5a1,0xa5a2,0xa5a3,0xa5a5,0xa5a9,0xa5b1,0xa5b3,0xa5b5,// 별볍볏볐병볕볘볜보복볶본볼봄봅봇 + 0xa5b7,0xa5c1,0xa5c5,0xa5d6,0xa5e1,0xa5f6,0xa641,0xa642,0xa645,0xa649,0xa651,0xa653,0xa661,0xa665,0xa681,0xa682,// 봉봐봔봤봬뵀뵈뵉뵌뵐뵘뵙뵤뵨부북 + 0xa685,0xa688,0xa689,0xa68a,0xa68b,0xa691,0xa693,0xa695,0xa697,0xa69b,0xa69c,0xa6a1,0xa6a9,0xa6b6,0xa6c1,0xa6e1,// 분붇불붉붊붐붑붓붕붙붚붜붤붰붸뷔 + 0xa6e2,0xa6e5,0xa6e9,0xa6f7,0xa741,0xa745,0xa749,0xa751,0xa755,0xa757,0xa761,0xa762,0xa765,0xa769,0xa771,0xa773,// 뷕뷘뷜뷩뷰뷴뷸븀븃븅브븍븐블븜븝 + 0xa775,0xa7a1,0xa7a2,0xa7a5,0xa7a9,0xa7ab,0xa7b1,0xa7b3,0xa7b5,0xa7b7,0xa7b8,0xa7b9,0xa861,0xa862,0xa865,0x0000,// 븟비빅빈빌빎빔빕빗빙빚빛빠빡빤 + // 0xbba0 - 0xbbff + 0x0000,0xa869,0xa86b,0xa871,0xa873,0xa875,0xa876,0xa877,0xa87d,0xa881,0xa882,0xa885,0xa889,0xa891,0xa893,0xa895,// 빨빪빰빱빳빴빵빻빼빽뺀뺄뺌뺍뺏 + 0xa896,0xa897,0xa8a1,0xa8a2,0xa8b1,0xa8e1,0xa8e2,0xa8e5,0xa8e8,0xa8e9,0xa8f1,0xa8f5,0xa8f6,0xa8f7,0xa941,0xa957,// 뺐뺑뺘뺙뺨뻐뻑뻔뻗뻘뻠뻣뻤뻥뻬뼁 + 0xa961,0xa962,0xa971,0xa973,0xa975,0xa976,0xa977,0xa9a1,0xa9a2,0xa9a5,0xa9a9,0xa9b1,0xa9b3,0xa9b7,0xaa41,0xaa61,// 뼈뼉뼘뼙뼛뼜뼝뽀뽁뽄뽈뽐뽑뽕뾔뾰 + 0xaa77,0xaa81,0xaa82,0xaa85,0xaa89,0xaa91,0xaa95,0xaa97,0xab41,0xab57,0xab61,0xab65,0xab69,0xab71,0xab73,0xaba1,// 뿅뿌뿍뿐뿔뿜뿟뿡쀼쁑쁘쁜쁠쁨쁩삐 + 0xaba2,0xaba5,0xaba9,0xabb1,0xabb3,0xabb5,0xabb7,0xac61,0xac62,0xac64,0xac65,0xac68,0xac69,0xac6a,0xac6b,0xac71,// 삑삔삘삠삡삣삥사삭삯산삳살삵삶삼 + 0xac73,0xac75,0xac76,0xac77,0xac7b,0xac81,0xac82,0xac85,0xac89,0xac91,0xac93,0xac95,0xac96,0xac97,0xaca1,0x0000,// 삽삿샀상샅새색샌샐샘샙샛샜생샤 + // 0xbca0 - 0xbcff + 0x0000,0xaca2,0xaca5,0xaca9,0xacb1,0xacb3,0xacb5,0xacb7,0xacc1,0xacc5,0xacc9,0xacd1,0xacd7,0xace1,0xace2,0xace3,// 샥샨샬샴샵샷샹섀섄섈섐섕서석섞 + 0xace4,0xace5,0xace8,0xace9,0xaceb,0xacec,0xacf1,0xacf3,0xacf5,0xacf6,0xacf7,0xacfc,0xad41,0xad42,0xad45,0xad49,// 섟선섣설섦섧섬섭섯섰성섶세섹센셀 + 0xad51,0xad53,0xad55,0xad56,0xad57,0xad61,0xad62,0xad65,0xad69,0xad71,0xad73,0xad75,0xad76,0xad77,0xad81,0xad85,// 셈셉셋셌셍셔셕션셜셤셥셧셨셩셰셴 + 0xad89,0xad97,0xada1,0xada2,0xada3,0xada5,0xada9,0xadab,0xadb1,0xadb3,0xadb5,0xadb7,0xadbb,0xadc1,0xadc2,0xadc5,// 셸솅소속솎손솔솖솜솝솟송솥솨솩솬 + 0xadc9,0xadd7,0xade1,0xade5,0xade9,0xadf1,0xadf5,0xadf6,0xae41,0xae45,0xae49,0xae51,0xae53,0xae55,0xae61,0xae62,// 솰솽쇄쇈쇌쇔쇗쇘쇠쇤쇨쇰쇱쇳쇼쇽 + 0xae65,0xae69,0xae71,0xae73,0xae75,0xae77,0xae81,0xae82,0xae85,0xae88,0xae89,0xae91,0xae93,0xae95,0xae97,0x0000,// 숀숄숌숍숏숑수숙순숟술숨숩숫숭 + // 0xbda0 - 0xbdff + 0x0000,0xae99,0xae9b,0xae9c,0xaea1,0xaeb6,0xaec1,0xaec2,0xaec5,0xaec9,0xaed1,0xaed7,0xaee1,0xaee2,0xaee5,0xaee9,// 숯숱숲숴쉈쉐쉑쉔쉘쉠쉥쉬쉭쉰쉴 + 0xaef1,0xaef3,0xaef5,0xaef7,0xaf41,0xaf42,0xaf49,0xaf51,0xaf55,0xaf57,0xaf61,0xaf62,0xaf65,0xaf69,0xaf6a,0xaf71,// 쉼쉽쉿슁슈슉슐슘슛슝스슥슨슬슭슴 + 0xaf73,0xaf75,0xaf77,0xafa1,0xafa2,0xafa5,0xafa8,0xafa9,0xafb0,0xafb1,0xafb3,0xafb5,0xafb7,0xafbc,0xb061,0xb062,// 습슷승시식신싣실싫심십싯싱싶싸싹 + 0xb064,0xb065,0xb069,0xb071,0xb073,0xb076,0xb077,0xb07d,0xb081,0xb082,0xb085,0xb089,0xb091,0xb093,0xb096,0xb097,// 싻싼쌀쌈쌉쌌쌍쌓쌔쌕쌘쌜쌤쌥쌨쌩 + 0xb0b7,0xb0e1,0xb0e2,0xb0e5,0xb0e9,0xb0eb,0xb0f1,0xb0f3,0xb0f6,0xb0f7,0xb141,0xb145,0xb149,0xb185,0xb1a1,0xb1a2,// 썅써썩썬썰썲썸썹썼썽쎄쎈쎌쏀쏘쏙 + 0xb1a5,0xb1a8,0xb1a9,0xb1ab,0xb1b1,0xb1b3,0xb1b7,0xb1c1,0xb1c2,0xb1c5,0xb1d6,0xb1e1,0xb1f6,0xb241,0xb245,0x0000,// 쏜쏟쏠쏢쏨쏩쏭쏴쏵쏸쐈쐐쐤쐬쐰 + // 0xbea0 - 0xbeff + 0x0000,0xb249,0xb251,0xb253,0xb261,0xb281,0xb282,0xb285,0xb289,0xb291,0xb293,0xb297,0xb2a1,0xb2b6,0xb2c1,0xb2e1,// 쐴쐼쐽쑈쑤쑥쑨쑬쑴쑵쑹쒀쒔쒜쒸 + 0xb2e5,0xb357,0xb361,0xb362,0xb365,0xb369,0xb36b,0xb370,0xb371,0xb373,0xb381,0xb385,0xb389,0xb391,0xb3a1,0xb3a2,// 쒼쓩쓰쓱쓴쓸쓺쓿씀씁씌씐씔씜씨씩 + 0xb3a5,0xb3a9,0xb3b1,0xb3b3,0xb3b5,0xb3b7,0xb461,0xb462,0xb465,0xb466,0xb467,0xb469,0xb46a,0xb46b,0xb470,0xb471,// 씬씰씸씹씻씽아악안앉않알앍앎앓암 + 0xb473,0xb475,0xb476,0xb477,0xb47b,0xb47c,0xb481,0xb482,0xb485,0xb489,0xb491,0xb493,0xb495,0xb496,0xb497,0xb4a1,// 압앗았앙앝앞애액앤앨앰앱앳앴앵야 + 0xb4a2,0xb4a5,0xb4a9,0xb4ac,0xb4b1,0xb4b3,0xb4b5,0xb4b7,0xb4bb,0xb4bd,0xb4c1,0xb4c5,0xb4c9,0xb4d3,0xb4e1,0xb4e2,// 약얀얄얇얌얍얏양얕얗얘얜얠얩어억 + 0xb4e5,0xb4e6,0xb4e8,0xb4e9,0xb4ea,0xb4eb,0xb4f1,0xb4f3,0xb4f4,0xb4f5,0xb4f6,0xb4f7,0xb4f8,0xb4fa,0xb4fc,0x0000,// 언얹얻얼얽얾엄업없엇었엉엊엌엎 + // 0xbfa0 - 0xbfff + 0x0000,0xb541,0xb542,0xb545,0xb549,0xb551,0xb553,0xb555,0xb557,0xb561,0xb562,0xb563,0xb565,0xb569,0xb56b,0xb56c,// 에엑엔엘엠엡엣엥여역엮연열엶엷 + 0xb571,0xb573,0xb574,0xb575,0xb576,0xb577,0xb57b,0xb57c,0xb57d,0xb581,0xb585,0xb589,0xb591,0xb593,0xb595,0xb596,// 염엽엾엿였영옅옆옇예옌옐옘옙옛옜 + 0xb5a1,0xb5a2,0xb5a5,0xb5a9,0xb5aa,0xb5ab,0xb5ad,0xb5b0,0xb5b1,0xb5b3,0xb5b5,0xb5b7,0xb5b9,0xb5c1,0xb5c2,0xb5c5,// 오옥온올옭옮옰옳옴옵옷옹옻와왁완 + 0xb5c9,0xb5d1,0xb5d3,0xb5d5,0xb5d6,0xb5d7,0xb5e1,0xb5e2,0xb5e5,0xb5f1,0xb5f5,0xb5f7,0xb641,0xb642,0xb645,0xb649,// 왈왐왑왓왔왕왜왝왠왬왯왱외왹왼욀 + 0xb651,0xb653,0xb655,0xb657,0xb661,0xb662,0xb665,0xb669,0xb671,0xb673,0xb675,0xb677,0xb681,0xb682,0xb685,0xb689,// 욈욉욋욍요욕욘욜욤욥욧용우욱운울 + 0xb68a,0xb68b,0xb691,0xb693,0xb695,0xb697,0xb6a1,0xb6a2,0xb6a5,0xb6a9,0xb6b1,0xb6b3,0xb6b6,0xb6b7,0xb6c1,0x0000,// 욹욺움웁웃웅워웍원월웜웝웠웡웨 + // 0xc0a0 - 0xc0ff + 0x0000,0xb6c2,0xb6c5,0xb6c9,0xb6d1,0xb6d3,0xb6d7,0xb6e1,0xb6e2,0xb6e5,0xb6e9,0xb6f1,0xb6f3,0xb6f5,0xb6f7,0xb741,// 웩웬웰웸웹웽위윅윈윌윔윕윗윙유 + 0xb742,0xb745,0xb749,0xb751,0xb753,0xb755,0xb757,0xb759,0xb761,0xb762,0xb765,0xb769,0xb76f,0xb771,0xb773,0xb775,// 육윤율윰윱윳융윷으윽은을읊음읍읏 + 0xb777,0xb778,0xb779,0xb77a,0xb77b,0xb77c,0xb77d,0xb781,0xb785,0xb789,0xb791,0xb795,0xb7a1,0xb7a2,0xb7a5,0xb7a9,// 응읒읓읔읕읖읗의읜읠읨읫이익인일 + 0xb7aa,0xb7ab,0xb7b0,0xb7b1,0xb7b3,0xb7b5,0xb7b6,0xb7b7,0xb7b8,0xb7bc,0xb861,0xb862,0xb865,0xb867,0xb868,0xb869,// 읽읾잃임입잇있잉잊잎자작잔잖잗잘 + 0xb86b,0xb871,0xb873,0xb875,0xb876,0xb877,0xb878,0xb881,0xb882,0xb885,0xb889,0xb891,0xb893,0xb895,0xb896,0xb897,// 잚잠잡잣잤장잦재잭잰잴잼잽잿쟀쟁 + 0xb8a1,0xb8a2,0xb8a5,0xb8a7,0xb8a9,0xb8b1,0xb8b7,0xb8c1,0xb8c5,0xb8c9,0xb8e1,0xb8e2,0xb8e5,0xb8e9,0xb8eb,0x0000,// 쟈쟉쟌쟎쟐쟘쟝쟤쟨쟬저적전절젊 + // 0xc1a0 - 0xc1ff + 0x0000,0xb8f1,0xb8f3,0xb8f5,0xb8f7,0xb8f8,0xb941,0xb942,0xb945,0xb949,0xb951,0xb953,0xb955,0xb957,0xb961,0xb965,// 점접젓정젖제젝젠젤젬젭젯젱져젼 + 0xb969,0xb971,0xb973,0xb976,0xb977,0xb981,0xb9a1,0xb9a2,0xb9a5,0xb9a9,0xb9ab,0xb9b1,0xb9b3,0xb9b5,0xb9b7,0xb9b8,// 졀졈졉졌졍졔조족존졸졺좀좁좃종좆 + 0xb9b9,0xb9bd,0xb9c1,0xb9c2,0xb9c9,0xb9d3,0xb9d5,0xb9d7,0xb9e1,0xb9f6,0xb9f7,0xba41,0xba45,0xba49,0xba51,0xba53,// 좇좋좌좍좔좝좟좡좨좼좽죄죈죌죔죕 + 0xba55,0xba57,0xba61,0xba62,0xba65,0xba77,0xba81,0xba82,0xba85,0xba89,0xba8a,0xba8b,0xba91,0xba93,0xba95,0xba97,// 죗죙죠죡죤죵주죽준줄줅줆줌줍줏중 + 0xbaa1,0xbab6,0xbac1,0xbae1,0xbae2,0xbae5,0xbae9,0xbaf1,0xbaf3,0xbaf5,0xbb41,0xbb45,0xbb49,0xbb51,0xbb61,0xbb62,// 줘줬줴쥐쥑쥔쥘쥠쥡쥣쥬쥰쥴쥼즈즉 + 0xbb65,0xbb69,0xbb71,0xbb73,0xbb75,0xbb77,0xbba1,0xbba2,0xbba5,0xbba8,0xbba9,0xbbab,0xbbb1,0xbbb3,0xbbb5,0x0000,// 즌즐즘즙즛증지직진짇질짊짐집짓 + // 0xc2a0 - 0xc2ff + 0x0000,0xbbb7,0xbbb8,0xbbbb,0xbbbc,0xbc61,0xbc62,0xbc65,0xbc67,0xbc69,0xbc6c,0xbc71,0xbc73,0xbc75,0xbc76,0xbc77,// 징짖짙짚짜짝짠짢짤짧짬짭짯짰짱 + 0xbc81,0xbc82,0xbc85,0xbc89,0xbc91,0xbc93,0xbc95,0xbc96,0xbc97,0xbca1,0xbca5,0xbcb7,0xbce1,0xbce2,0xbce5,0xbce9,// 째짹짼쨀쨈쨉쨋쨌쨍쨔쨘쨩쩌쩍쩐쩔 + 0xbcf1,0xbcf3,0xbcf5,0xbcf6,0xbcf7,0xbd41,0xbd57,0xbd61,0xbd76,0xbda1,0xbda2,0xbda5,0xbda9,0xbdb1,0xbdb3,0xbdb5,// 쩜쩝쩟쩠쩡쩨쩽쪄쪘쪼쪽쫀쫄쫌쫍쫏 + 0xbdb7,0xbdb9,0xbdc1,0xbdc2,0xbdc9,0xbdd6,0xbde1,0xbdf6,0xbe41,0xbe45,0xbe49,0xbe51,0xbe53,0xbe77,0xbe81,0xbe82,// 쫑쫓쫘쫙쫠쫬쫴쬈쬐쬔쬘쬠쬡쭁쭈쭉 + 0xbe85,0xbe89,0xbe91,0xbe93,0xbe97,0xbea1,0xbeb6,0xbeb7,0xbee1,0xbf41,0xbf61,0xbf71,0xbf75,0xbf77,0xbfa1,0xbfa2,// 쭌쭐쭘쭙쭝쭤쭸쭹쮜쮸쯔쯤쯧쯩찌찍 + 0xbfa5,0xbfa9,0xbfb1,0xbfb3,0xbfb7,0xbfb8,0xbfbd,0xc061,0xc062,0xc065,0xc067,0xc069,0xc071,0xc073,0xc075,0x0000,// 찐찔찜찝찡찢찧차착찬찮찰참찹찻 + // 0xc3a0 - 0xc3ff + 0x0000,0xc076,0xc077,0xc078,0xc081,0xc082,0xc085,0xc089,0xc091,0xc093,0xc095,0xc096,0xc097,0xc0a1,0xc0a5,0xc0a7,// 찼창찾채책챈챌챔챕챗챘챙챠챤챦 + 0xc0a9,0xc0b1,0xc0b7,0xc0e1,0xc0e2,0xc0e5,0xc0e9,0xc0f1,0xc0f3,0xc0f5,0xc0f6,0xc0f7,0xc141,0xc142,0xc145,0xc149,// 챨챰챵처척천철첨첩첫첬청체첵첸첼 + 0xc151,0xc153,0xc155,0xc157,0xc161,0xc165,0xc176,0xc181,0xc185,0xc197,0xc1a1,0xc1a2,0xc1a5,0xc1a9,0xc1b1,0xc1b3,// 쳄쳅쳇쳉쳐쳔쳤쳬쳰촁초촉촌촐촘촙 + 0xc1b5,0xc1b7,0xc1c1,0xc1c5,0xc1c9,0xc1d7,0xc241,0xc245,0xc249,0xc251,0xc253,0xc255,0xc257,0xc261,0xc271,0xc281,// 촛총촤촨촬촹최쵠쵤쵬쵭쵯쵱쵸춈추 + 0xc282,0xc285,0xc289,0xc291,0xc293,0xc295,0xc297,0xc2a1,0xc2b6,0xc2c1,0xc2c5,0xc2e1,0xc2e5,0xc2e9,0xc2f1,0xc2f3,// 축춘출춤춥춧충춰췄췌췐취췬췰췸췹 + 0xc2f5,0xc2f7,0xc341,0xc345,0xc349,0xc351,0xc357,0xc361,0xc362,0xc365,0xc369,0xc371,0xc373,0xc375,0xc377,0x0000,// 췻췽츄츈츌츔츙츠측츤츨츰츱츳층 + // 0xc4a0 - 0xc4ff + 0x0000,0xc3a1,0xc3a2,0xc3a5,0xc3a8,0xc3a9,0xc3aa,0xc3b1,0xc3b3,0xc3b5,0xc3b7,0xc461,0xc462,0xc465,0xc469,0xc471,// 치칙친칟칠칡침칩칫칭카칵칸칼캄 + 0xc473,0xc475,0xc477,0xc481,0xc482,0xc485,0xc489,0xc491,0xc493,0xc495,0xc496,0xc497,0xc4a1,0xc4a2,0xc4b7,0xc4e1,// 캅캇캉캐캑캔캘캠캡캣캤캥캬캭컁커 + 0xc4e2,0xc4e5,0xc4e8,0xc4e9,0xc4f1,0xc4f3,0xc4f5,0xc4f6,0xc4f7,0xc541,0xc542,0xc545,0xc549,0xc551,0xc553,0xc555,// 컥컨컫컬컴컵컷컸컹케켁켄켈켐켑켓 + 0xc557,0xc561,0xc565,0xc569,0xc571,0xc573,0xc575,0xc576,0xc577,0xc581,0xc5a1,0xc5a2,0xc5a5,0xc5a9,0xc5b1,0xc5b3,// 켕켜켠켤켬켭켯켰켱켸코콕콘콜콤콥 + 0xc5b5,0xc5b7,0xc5c1,0xc5c2,0xc5c5,0xc5c9,0xc5d1,0xc5d7,0xc5e1,0xc5f7,0xc641,0xc649,0xc661,0xc681,0xc682,0xc685,// 콧콩콰콱콴콸쾀쾅쾌쾡쾨쾰쿄쿠쿡쿤 + 0xc689,0xc691,0xc693,0xc695,0xc697,0xc6a1,0xc6a5,0xc6a9,0xc6b7,0xc6c1,0xc6d7,0xc6e1,0xc6e2,0xc6e5,0xc6e9,0x0000,// 쿨쿰쿱쿳쿵쿼퀀퀄퀑퀘퀭퀴퀵퀸퀼 + // 0xc5a0 - 0xc5ff + 0x0000,0xc6f1,0xc6f3,0xc6f5,0xc6f7,0xc741,0xc745,0xc749,0xc751,0xc761,0xc762,0xc765,0xc769,0xc771,0xc773,0xc777,// 큄큅큇큉큐큔큘큠크큭큰클큼큽킁 + 0xc7a1,0xc7a2,0xc7a5,0xc7a9,0xc7b1,0xc7b3,0xc7b5,0xc7b7,0xc861,0xc862,0xc865,0xc869,0xc86a,0xc871,0xc873,0xc875,// 키킥킨킬킴킵킷킹타탁탄탈탉탐탑탓 + 0xc876,0xc877,0xc881,0xc882,0xc885,0xc889,0xc891,0xc893,0xc895,0xc896,0xc897,0xc8a1,0xc8b7,0xc8e1,0xc8e2,0xc8e5,// 탔탕태택탠탤탬탭탯탰탱탸턍터턱턴 + 0xc8e9,0xc8eb,0xc8f1,0xc8f3,0xc8f5,0xc8f6,0xc8f7,0xc941,0xc942,0xc945,0xc949,0xc951,0xc953,0xc955,0xc957,0xc961,// 털턺텀텁텃텄텅테텍텐텔템텝텟텡텨 + 0xc965,0xc976,0xc981,0xc985,0xc9a1,0xc9a2,0xc9a5,0xc9a9,0xc9b1,0xc9b3,0xc9b5,0xc9b7,0xc9bc,0xc9c1,0xc9c5,0xc9e1,// 텬텼톄톈토톡톤톨톰톱톳통톺톼퇀퇘 + 0xca41,0xca45,0xca55,0xca57,0xca61,0xca81,0xca82,0xca85,0xca89,0xca91,0xca93,0xca95,0xca97,0xcaa1,0xcab6,0x0000,// 퇴퇸툇툉툐투툭툰툴툼툽툿퉁퉈퉜 + // 0xc6a0 - 0xc6ff + 0x0000,0xcac1,0xcae1,0xcae2,0xcae5,0xcae9,0xcaf1,0xcaf3,0xcaf7,0xcb41,0xcb45,0xcb49,0xcb51,0xcb57,0xcb61,0xcb62,// 퉤튀튁튄튈튐튑튕튜튠튤튬튱트특 + 0xcb65,0xcb68,0xcb69,0xcb6b,0xcb71,0xcb73,0xcb75,0xcb81,0xcb85,0xcb89,0xcb91,0xcb93,0xcba1,0xcba2,0xcba5,0xcba9,// 튼튿틀틂틈틉틋틔틘틜틤틥티틱틴틸 + 0xcbb1,0xcbb3,0xcbb5,0xcbb7,0xcc61,0xcc62,0xcc63,0xcc65,0xcc69,0xcc6b,0xcc71,0xcc73,0xcc75,0xcc76,0xcc77,0xcc7b,// 팀팁팃팅파팍팎판팔팖팜팝팟팠팡팥 + 0xcc81,0xcc82,0xcc85,0xcc89,0xcc91,0xcc93,0xcc95,0xcc96,0xcc97,0xcca1,0xcca2,0xcce1,0xcce2,0xcce5,0xcce9,0xccf1,// 패팩팬팰팸팹팻팼팽퍄퍅퍼퍽펀펄펌 + 0xccf3,0xccf5,0xccf6,0xccf7,0xcd41,0xcd42,0xcd45,0xcd49,0xcd51,0xcd53,0xcd55,0xcd57,0xcd61,0xcd65,0xcd69,0xcd71,// 펍펏펐펑페펙펜펠펨펩펫펭펴편펼폄 + 0xcd73,0xcd76,0xcd77,0xcd81,0xcd89,0xcd93,0xcd95,0xcda1,0xcda2,0xcda5,0xcda9,0xcdb1,0xcdb3,0xcdb5,0xcdb7,0x0000,// 폅폈평폐폘폡폣포폭폰폴폼폽폿퐁 + // 0xc7a0 - 0xc7ff + 0x0000,0xcdc1,0xcdd7,0xce41,0xce45,0xce61,0xce65,0xce69,0xce73,0xce75,0xce81,0xce82,0xce85,0xce88,0xce89,0xce8b,// 퐈퐝푀푄표푠푤푭푯푸푹푼푿풀풂 + 0xce91,0xce93,0xce95,0xce97,0xcea1,0xceb7,0xcee1,0xcee5,0xcee9,0xcef1,0xcef5,0xcf41,0xcf45,0xcf49,0xcf51,0xcf55,// 품풉풋풍풔풩퓌퓐퓔퓜퓟퓨퓬퓰퓸퓻 + 0xcf57,0xcf61,0xcf65,0xcf69,0xcf71,0xcf73,0xcf75,0xcfa1,0xcfa2,0xcfa5,0xcfa9,0xcfb1,0xcfb3,0xcfb5,0xcfb7,0xd061,// 퓽프픈플픔픕픗피픽핀필핌핍핏핑하 + 0xd062,0xd065,0xd069,0xd06e,0xd071,0xd073,0xd075,0xd077,0xd081,0xd082,0xd085,0xd089,0xd091,0xd093,0xd095,0xd096,// 학한할핥함합핫항해핵핸핼햄햅햇했 + 0xd097,0xd0a1,0xd0b7,0xd0e1,0xd0e2,0xd0e5,0xd0e9,0xd0eb,0xd0f1,0xd0f3,0xd0f5,0xd0f7,0xd141,0xd142,0xd145,0xd149,// 행햐향허헉헌헐헒험헙헛헝헤헥헨헬 + 0xd151,0xd153,0xd155,0xd157,0xd161,0xd162,0xd165,0xd169,0xd171,0xd173,0xd175,0xd176,0xd177,0xd181,0xd185,0x0000,// 헴헵헷헹혀혁현혈혐협혓혔형혜혠 + // 0xc8a0 - 0xc8ff + 0x0000,0xd189,0xd193,0xd1a1,0xd1a2,0xd1a5,0xd1a9,0xd1ae,0xd1b1,0xd1b3,0xd1b5,0xd1b7,0xd1bb,0xd1c1,0xd1c2,0xd1c5,// 혤혭호혹혼홀홅홈홉홋홍홑화확환 + 0xd1c9,0xd1d5,0xd1d7,0xd1e1,0xd1e2,0xd1e5,0xd1f5,0xd1f7,0xd241,0xd242,0xd245,0xd249,0xd253,0xd255,0xd257,0xd261,// 활홧황홰홱홴횃횅회획횐횔횝횟횡효 + 0xd265,0xd269,0xd273,0xd275,0xd281,0xd282,0xd285,0xd289,0xd28e,0xd291,0xd295,0xd297,0xd2a1,0xd2a5,0xd2a9,0xd2b1,// 횬횰횹횻후훅훈훌훑훔훗훙훠훤훨훰 + 0xd2b7,0xd2c1,0xd2c2,0xd2c5,0xd2c9,0xd2d7,0xd2e1,0xd2e2,0xd2e5,0xd2e9,0xd2f1,0xd2f3,0xd2f5,0xd2f7,0xd341,0xd342,// 훵훼훽휀휄휑휘휙휜휠휨휩휫휭휴휵 + 0xd345,0xd349,0xd351,0xd355,0xd357,0xd361,0xd362,0xd365,0xd367,0xd368,0xd369,0xd36a,0xd371,0xd373,0xd375,0xd377,// 휸휼흄흇흉흐흑흔흖흗흘흙흠흡흣흥 + 0xd37b,0xd381,0xd385,0xd389,0xd391,0xd393,0xd397,0xd3a1,0xd3a2,0xd3a5,0xd3a9,0xd3b1,0xd3b3,0xd3b5,0xd3b7,0x0000,// 흩희흰흴흼흽힁히힉힌힐힘힙힛힝 + // 0xc9a0 - 0xc9ff + 0x0000,0xd441,0xd442,0xd443,0xd444,0xd445,0xd446,0xd447,0xd448,0xd449,0xd44a,0xd44b,0xd44c,0xd44d,0xd44e,0xd44f,//  + 0xd450,0xd451,0xd452,0xd453,0xd454,0xd455,0xd456,0xd457,0xd458,0xd459,0xd45a,0xd45b,0xd45c,0xd45d,0xd45e,0xd45f,//  + 0xd460,0xd461,0xd462,0xd463,0xd464,0xd465,0xd466,0xd467,0xd468,0xd469,0xd46a,0xd46b,0xd46c,0xd46d,0xd46e,0xd46f,//  + 0xd470,0xd471,0xd472,0xd473,0xd474,0xd475,0xd476,0xd477,0xd478,0xd479,0xd47a,0xd47b,0xd47c,0xd47d,0xd47e,0xd47f,//  + 0xd481,0xd482,0xd483,0xd484,0xd485,0xd486,0xd487,0xd488,0xd489,0xd48a,0xd48b,0xd48c,0xd48d,0xd48e,0xd48f,0xd490,//  + 0xd491,0xd492,0xd493,0xd494,0xd495,0xd496,0xd497,0xd498,0xd499,0xd49a,0xd49b,0xd49c,0xd49d,0xd49e,0xd49f,0x0000,//  + // 0xcaa0 - 0xcaff + 0x0000,0x5041,0x5042,0x5043,0x5044,0x5045,0x5046,0x5047,0x5048,0x5049,0x504a,0x504b,0x504c,0x504e,0x6841,0x504d,// 伽佳假價加可呵哥嘉嫁家暇架枷柯 + 0x504f,0x6842,0x6843,0x5050,0x5051,0x5052,0x5053,0x5054,0x5055,0x5056,0x5057,0x5058,0x5059,0x505a,0x505b,0x505c,// 歌珂痂稼苛茄街袈訶賈跏軻迦駕刻却 + 0x505d,0x505f,0x6844,0x5061,0x5062,0x5063,0x5064,0x5065,0x5066,0x6845,0x5067,0x5068,0x5069,0x506a,0x506b,0x506c,// 各恪慤殼珏脚覺角閣侃刊墾奸姦干幹 + 0x506d,0x506e,0x506f,0x6846,0x6847,0x5070,0x5071,0x5072,0x6848,0x5073,0x5074,0x5075,0x5078,0x5076,0x5077,0x5079,// 懇揀杆柬桿澗癎看磵稈竿簡肝艮艱諫 + 0x507a,0x507b,0x507c,0x507d,0x507e,0x507f,0x5080,0x5083,0x5081,0x6849,0x5084,0x5085,0x5086,0x5087,0x5088,0x5089,// 間乫喝曷渴碣竭葛褐蝎鞨勘坎堪嵌感 + 0x508a,0x684a,0x508b,0x508c,0x508d,0x508e,0x508f,0x5090,0x5091,0x684b,0x5092,0x684c,0x5094,0x684d,0x5095,0x0000,// 憾戡敢柑橄減甘疳監瞰紺邯鑑鑒龕 + // 0xcba0 - 0xcbff + 0x0000,0x5096,0x5097,0x5098,0x5099,0x509a,0x509b,0x509d,0x684e,0x509e,0x509c,0x509f,0x50a0,0x50a1,0x50a2,0x50a3,// 匣岬甲胛鉀閘剛堈姜岡崗康强彊慷 + 0x50a4,0x684f,0x50a5,0x50a8,0x6850,0x50a6,0x6851,0x50a9,0x6852,0x50aa,0x50a7,0x50ab,0x50ac,0x50ad,0x6853,0x50ae,// 江畺疆糠絳綱羌腔舡薑襁講鋼降鱇介 + 0x50af,0x50b0,0x50b1,0x6854,0x50b2,0x50b3,0x50b4,0x50b5,0x50b6,0x50b7,0x50b8,0x50b9,0x50ba,0x50bb,0x50bc,0x50bd,// 价個凱塏愷愾慨改槪漑疥皆盖箇芥蓋 + 0x6855,0x6856,0x50be,0x6857,0x50bf,0x50c0,0x50c1,0x50c2,0x50c3,0x50c4,0x6858,0x50c5,0x50c6,0x50c7,0x50c8,0x50c9,// 豈鎧開喀客坑更粳羹醵倨去居巨拒据 + 0x50ca,0x50cd,0x50cb,0x50cc,0x6859,0x50ce,0x685a,0x50d0,0x50cf,0x685b,0x50d2,0x50d3,0x50d4,0x50d5,0x50d6,0x50d7,// 據擧渠炬祛距踞車遽鉅鋸乾件健巾建 + 0x50d8,0x685c,0x685d,0x50d9,0x50da,0x50db,0x50dc,0x50dd,0x50de,0x50df,0x685e,0x50e0,0x50e1,0x685f,0x50e2,0x0000,// 愆楗腱虔蹇鍵騫乞傑杰桀儉劍劒檢 + // 0xcca0 - 0xccff + 0x0000,0x50e3,0x6860,0x50e4,0x50e5,0x50e6,0x6861,0x50e7,0x50e8,0x50e9,0x50ea,0x50eb,0x50ec,0x50ed,0x6862,0x50ee,// 瞼鈐黔劫怯迲偈憩揭擊格檄激膈覡 + 0x50ef,0x50f1,0x50f3,0x50f4,0x50f5,0x50f6,0x50f7,0x50f2,0x50f8,0x50f9,0x50fa,0x50fb,0x6863,0x50fd,0x50fc,0x50fe,// 隔堅牽犬甄絹繭肩見譴遣鵑抉決潔結 + 0x5141,0x5142,0x5143,0x5144,0x5145,0x5147,0x6864,0x5148,0x5149,0x6865,0x6866,0x514a,0x6867,0x514b,0x514c,0x514d,// 缺訣兼慊箝謙鉗鎌京俓倞傾儆勁勍卿 + 0x6868,0x514f,0x5150,0x5151,0x5152,0x6869,0x5155,0x5156,0x5157,0x5153,0x5158,0x5159,0x515b,0x515c,0x686a,0x515e,// 坰境庚徑慶憬擎敬景暻更梗涇炅烱璟 + 0x686b,0x515f,0x5161,0x5162,0x5163,0x5164,0x5165,0x5166,0x5167,0x5168,0x5169,0x516a,0x516b,0x516c,0x516d,0x516e,// 璥瓊痙硬磬竟競絅經耕耿脛莖警輕逕 + 0x516f,0x5170,0x5171,0x5172,0x5173,0x5174,0x5175,0x686c,0x5176,0x5177,0x5178,0x5179,0x517a,0x517b,0x517c,0x0000,// 鏡頃頸驚鯨係啓堺契季屆悸戒桂械 + // 0xcda0 - 0xcdff + 0x0000,0x686d,0x517d,0x517e,0x517f,0x5180,0x5182,0x5183,0x5184,0x5185,0x5186,0x5187,0x5189,0x5188,0x518b,0x518d,// 棨溪界癸磎稽系繫繼計誡谿階鷄古 + 0x518c,0x518e,0x518f,0x5190,0x5191,0x5192,0x686e,0x5193,0x5194,0x5195,0x5196,0x5197,0x686f,0x5198,0x6870,0x519a,// 叩告呱固姑孤尻庫拷攷故敲暠枯槁沽 + 0x519b,0x519c,0x51a0,0x519f,0x6871,0x51a1,0x51a2,0x51a3,0x51a4,0x6872,0x6873,0x51a5,0x519d,0x51a6,0x51a8,0x51a9,// 痼皐睾稿羔考股膏苦苽菰藁蠱袴誥賈 + 0x51aa,0x51ab,0x51ac,0x51ad,0x51ae,0x51af,0x51b0,0x51b1,0x51b2,0x51b3,0x51b4,0x51b5,0x51b6,0x51b7,0x51b8,0x51b9,// 辜錮雇顧高鼓哭斛曲梏穀谷鵠困坤崑 + 0x51ba,0x51bb,0x51bc,0x51bd,0x6874,0x51be,0x6875,0x51bf,0x51c0,0x51c1,0x51c2,0x51c3,0x51c4,0x51c5,0x51c6,0x51c7,// 昆梱棍滾琨袞鯤汨滑骨供公共功孔工 + 0x51ca,0x51c9,0x51cb,0x51cc,0x51cd,0x6876,0x51d0,0x6877,0x51c8,0x6878,0x6879,0x51d2,0x51d3,0x51d4,0x51d5,0x0000,// 恐恭拱控攻珙空蚣貢鞏串寡戈果瓜 + // 0xcea0 - 0xceff + 0x0000,0x51d6,0x51d7,0x51d9,0x51da,0x687a,0x51db,0x687b,0x51dc,0x51dd,0x51de,0x51df,0x51e0,0x51e2,0x51e3,0x51e4,// 科菓誇課跨過鍋顆廓槨藿郭串冠官 + 0x51e5,0x51e6,0x51e7,0x51e9,0x51ea,0x687c,0x51e8,0x51ec,0x51ed,0x51ee,0x51ef,0x51f0,0x51f1,0x51f2,0x51f4,0x51f5,// 寬慣棺款灌琯瓘管罐菅觀貫關館刮恝 + 0x51f6,0x51f7,0x687d,0x51f8,0x51f9,0x51fa,0x51fb,0x51fc,0x51fd,0x687e,0x51fe,0x5241,0x5242,0x5243,0x5244,0x5245,// 括适侊光匡壙廣曠洸炚狂珖筐胱鑛卦 + 0x5246,0x5247,0x5248,0x5249,0x524a,0x524b,0x524c,0x524d,0x524e,0x524f,0x5250,0x5251,0x5252,0x5253,0x5254,0x5255,// 掛罫乖傀塊壞怪愧拐槐魁宏紘肱轟交 + 0x5256,0x5257,0x5258,0x5259,0x525a,0x525b,0x525d,0x525c,0x525e,0x525f,0x5260,0x5261,0x5262,0x5263,0x5264,0x5265,// 僑咬喬嬌嶠巧攪敎校橋狡皎矯絞翹膠 + 0x5266,0x5267,0x5268,0x5269,0x526a,0x526c,0x526d,0x526e,0x526f,0x5270,0x5271,0x5272,0x5274,0x5276,0x5277,0x0000,// 蕎蛟較轎郊餃驕鮫丘久九仇俱具勾 + // 0xcfa0 - 0xcfff + 0x0000,0x5278,0x5279,0x527a,0x527b,0x527c,0x687f,0x527d,0x5280,0x5281,0x5282,0x5283,0x5284,0x5285,0x5287,0x5288,// 區口句咎嘔坵垢寇嶇廐懼拘救枸柩 + 0x5289,0x528a,0x528b,0x528c,0x528d,0x528e,0x528f,0x5290,0x5291,0x5292,0x5294,0x5295,0x5296,0x5297,0x6880,0x5299,// 構歐毆毬求溝灸狗玖球瞿矩究絿耉臼 + 0x529a,0x529b,0x529c,0x529d,0x529f,0x5298,0x52a0,0x52a1,0x52a2,0x52a3,0x6881,0x52a5,0x52a6,0x52a7,0x52a8,0x52a9,// 舅舊苟衢謳購軀逑邱鉤銶駒驅鳩鷗龜 + 0x52aa,0x52ab,0x52ad,0x52ae,0x6882,0x52af,0x52b3,0x52b0,0x52b1,0x6883,0x52b2,0x52b4,0x52b5,0x52b6,0x52b7,0x52b8,// 國局菊鞠鞫麴君窘群裙軍郡堀屈掘窟 + 0x52b9,0x52ba,0x52bb,0x52bc,0x6884,0x52bd,0x52be,0x52bf,0x52c0,0x52c1,0x52c2,0x52c3,0x6885,0x52c4,0x6886,0x52c5,// 宮弓穹窮芎躬倦券勸卷圈拳捲權淃眷 + 0x52c6,0x6887,0x6888,0x52c7,0x52c8,0x52c9,0x52ca,0x52cb,0x52cc,0x52ce,0x52cf,0x6889,0x688a,0x52d0,0x52d1,0x0000,// 厥獗蕨蹶闕机櫃潰詭軌饋句晷歸貴 + // 0xd0a0 - 0xd0ff + 0x0000,0x52d2,0x52d3,0x52d4,0x52d5,0x52d6,0x52d7,0x688b,0x52d8,0x52d9,0x52da,0x688c,0x52dc,0x52db,0x52dd,0x52de,// 鬼龜叫圭奎揆槻珪硅窺竅糾葵規赳 + 0x52df,0x52e0,0x688d,0x52e1,0x688e,0x52e2,0x52e3,0x52e4,0x52e5,0x52e6,0x52e7,0x52e8,0x52e9,0x52ea,0x52ec,0x52eb,// 逵閨勻均畇筠菌鈞龜橘克剋劇戟棘極 + 0x52ed,0x52ee,0x688f,0x52ef,0x52f1,0x52f2,0x52f3,0x52f4,0x52f6,0x52f7,0x52f8,0x52f9,0x52fa,0x52fb,0x52fc,0x52fd,// 隙僅劤勤懃斤根槿瑾筋芹菫覲謹近饉 + 0x52fe,0x5341,0x6890,0x5342,0x6891,0x5343,0x5344,0x5345,0x5346,0x6892,0x5348,0x5347,0x5349,0x534a,0x534b,0x6893,// 契今妗擒昑檎琴禁禽芩衾衿襟金錦伋 + 0x534c,0x534e,0x534f,0x5350,0x5352,0x5353,0x5354,0x5355,0x5356,0x5357,0x5358,0x5359,0x535a,0x535b,0x535c,0x535d,// 及急扱汲級給亘兢矜肯企伎其冀嗜器 + 0x535e,0x535f,0x6894,0x5360,0x5361,0x5362,0x5363,0x5364,0x5366,0x5368,0x5367,0x5369,0x536a,0x536b,0x536c,0x0000,// 圻基埼夔奇妓寄岐崎己幾忌技旗旣 + // 0xd1a0 - 0xd1ff + 0x0000,0x5388,0x536d,0x536e,0x536f,0x5370,0x5371,0x5372,0x5373,0x5374,0x5375,0x5376,0x6895,0x5377,0x5378,0x6896,// 朞期杞棋棄機欺氣汽沂淇玘琦琪璂 + 0x5379,0x537a,0x537b,0x537c,0x537d,0x6897,0x537e,0x537f,0x5380,0x5381,0x5382,0x5383,0x6898,0x5385,0x5386,0x5387,// 璣畸畿碁磯祁祇祈祺箕紀綺羈耆耭肌 + 0x5389,0x538a,0x5365,0x538b,0x538c,0x6899,0x538d,0x538e,0x538f,0x5390,0x5391,0x5393,0x5394,0x5395,0x5396,0x5397,// 記譏豈起錡錤飢饑騎騏驥麒緊佶吉拮 + 0x5398,0x5399,0x539b,0x539c,0x689a,0x689b,0x689c,0x539d,0x689d,0x539e,0x539f,0x689e,0x689f,0x68a0,0x68a1,0x68a2,// 桔金喫儺喇奈娜懦懶拏拿癩羅蘿螺裸 + 0x68a3,0x53a1,0x68a4,0x68a5,0x68a6,0x68a7,0x68a8,0x53a2,0x68a9,0x68aa,0x68ab,0x68ac,0x53a3,0x68ad,0x53a4,0x68ae,// 邏那樂洛烙珞落諾酪駱亂卵暖欄煖爛 + 0x68af,0x53a5,0x68b0,0x53a7,0x53a6,0x53a8,0x68b1,0x68b2,0x68b3,0x68b4,0x68b5,0x53aa,0x68b6,0x68b7,0x68b8,0x0000,// 蘭難鸞捏捺南嵐枏楠湳濫男藍襤拉 + // 0xd2a0 - 0xd2ff + 0x0000,0x53ab,0x68b9,0x68ba,0x68bb,0x53ac,0x53ad,0x68bc,0x68bd,0x68be,0x68bf,0x68c0,0x53af,0x68c1,0x53b0,0x53b1,// 納臘蠟衲囊娘廊朗浪狼郎乃來內奈 + 0x53b2,0x53b3,0x68c2,0x53b5,0x53b6,0x68c3,0x53b7,0x53b8,0x53b9,0x53ba,0x53bb,0x53bd,0x68c4,0x53bf,0x68c5,0x53c0,// 柰耐冷女年撚秊念恬拈捻寧寗努勞奴 + 0x53c2,0x53c3,0x68c6,0x68c7,0x68c8,0x53c4,0x68c9,0x68ca,0x68cb,0x68cc,0x68cd,0x68ce,0x68cf,0x68d0,0x68d1,0x68d2,// 弩怒擄櫓爐瑙盧老蘆虜路露駑魯鷺碌 + 0x68d3,0x68d4,0x68d5,0x68d6,0x68d7,0x68d8,0x68d9,0x68da,0x53c5,0x68db,0x68dc,0x53c6,0x53c7,0x53c8,0x68dd,0x68de,// 祿綠菉錄鹿論壟弄濃籠聾膿農惱牢磊 + 0x53c9,0x68df,0x68e0,0x53ca,0x68e1,0x68e2,0x68e3,0x68e4,0x68e5,0x68e6,0x68e7,0x68e8,0x53cc,0x53cd,0x68e9,0x53ce,// 腦賂雷尿壘屢樓淚漏累縷陋嫩訥杻紐 + 0x68ea,0x68eb,0x68ec,0x68ed,0x68ee,0x68ef,0x53cf,0x68f0,0x68f1,0x53d0,0x53d1,0x53d2,0x53d3,0x53d4,0x53d5,0x0000,// 勒肋凜凌稜綾能菱陵尼泥匿溺多茶 + }; + + public Ksc2Ebc1() + { + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/Ksc2Ebc2.java b/src/main/java/com/eactive/eai/adapter/wca/util/Ksc2Ebc2.java new file mode 100644 index 0000000..5d543d7 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/Ksc2Ebc2.java @@ -0,0 +1,318 @@ +package com.eactive.eai.adapter.wca.util; + +public class Ksc2Ebc2 { + protected static char KSC2EBC[] = { + // 0xd3a0 - 0xd3ff + 0x0000,0x53d6,0x68f2,0x53d7,0x53d8,0x53d9,0x53da,0x68f3,0x53db,0x53dc,0x53dd,0x53de,0x53df,0x53e0,0x53e1,0x53e2,// 丹亶但單團壇彖斷旦檀段湍短端簞 + 0x53e3,0x53e4,0x53e5,0x53e6,0x53e7,0x53ea,0x68f4,0x53eb,0x53ec,0x53ed,0x53f0,0x68f5,0x68f6,0x53f1,0x53f2,0x53f3,// 緞蛋袒鄲鍛撻澾獺疸達啖坍憺擔曇淡 + 0x68f7,0x53f4,0x53f5,0x53f6,0x53f7,0x53f8,0x68f8,0x53f9,0x53fa,0x53fb,0x68f9,0x53fc,0x68fa,0x53fd,0x53fe,0x5441,// 湛潭澹痰聃膽蕁覃談譚錟沓畓答踏遝 + 0x5446,0x5443,0x5444,0x5445,0x68fb,0x5447,0x5448,0x5449,0x544a,0x68fc,0x544c,0x544d,0x544e,0x68fd,0x544f,0x5450,// 唐堂塘幢戇撞棠當糖螳黨代垈坮大對 + 0x5451,0x5452,0x5453,0x5454,0x5455,0x5456,0x5458,0x5459,0x545a,0x545b,0x545c,0x545d,0x545e,0x545f,0x5460,0x5461,// 岱帶待戴擡玳臺袋貸隊黛宅德悳倒刀 + 0x5462,0x5463,0x5464,0x5465,0x5466,0x5467,0x5468,0x68fe,0x5469,0x546a,0x546b,0x546c,0x6941,0x546d,0x546e,0x0000,// 到圖堵塗導屠島嶋度徒悼挑掉搗桃 + // 0xd4a0 - 0xd4ff + 0x0000,0x546f,0x6942,0x5470,0x5471,0x5472,0x5473,0x5474,0x5475,0x5476,0x5477,0x5478,0x5479,0x6943,0x547b,0x547c,// 棹櫂淘渡滔濤燾盜睹禱稻萄覩賭跳 + 0x547d,0x547e,0x547f,0x5480,0x5481,0x5482,0x5483,0x5484,0x5485,0x5486,0x5487,0x5488,0x5489,0x548a,0x548b,0x548c,// 蹈逃途道都鍍陶韜毒瀆牘犢獨督禿篤 + 0x548d,0x548e,0x548f,0x5490,0x5491,0x6944,0x5492,0x5493,0x6945,0x5494,0x5495,0x5496,0x5498,0x5499,0x549a,0x549b,// 纛讀墩惇敦旽暾沌焞燉豚頓乭突仝冬 + 0x549c,0x549d,0x549e,0x54a0,0x54a1,0x54a2,0x54a3,0x54a4,0x54a5,0x54a7,0x54a8,0x54a6,0x54aa,0x54a9,0x54ab,0x54ac,// 凍動同憧東桐棟洞潼疼瞳童胴董銅兜 + 0x54ad,0x54ae,0x54af,0x54b0,0x54b1,0x54b2,0x54b5,0x54b6,0x6946,0x54b7,0x54b8,0x54b9,0x6947,0x54ba,0x54bb,0x54bc,// 斗杜枓痘竇荳讀豆逗頭屯臀芚遁遯鈍 + 0x54bd,0x6948,0x54be,0x54c1,0x54c2,0x54c3,0x54c4,0x54c5,0x54c6,0x54c8,0x54c9,0x54ca,0x6949,0x54cb,0x54cc,0x0000,// 得嶝橙燈登等藤謄鄧騰喇懶拏癩羅 + // 0xd5a0 - 0xd5ff + 0x0000,0x54cd,0x54ce,0x54cf,0x54d0,0x54d1,0x54d2,0x54d3,0x54d5,0x54d6,0x54d7,0x694a,0x54d8,0x54d9,0x694b,0x54da,// 蘿螺裸邏樂洛烙珞絡落諾酪駱丹亂 + 0x54db,0x54dd,0x54de,0x54df,0x54e0,0x54e1,0x54e2,0x54e3,0x54e5,0x54e6,0x54e7,0x54e8,0x54e9,0x54ea,0x54eb,0x54ec,// 卵欄欒瀾爛蘭鸞剌辣嵐擥攬欖濫籃纜 + 0x54ed,0x54ee,0x54ef,0x54f0,0x54f1,0x54f2,0x54f3,0x54f4,0x54f6,0x54f7,0x54f8,0x54f9,0x54fa,0x54fb,0x54fc,0x694c,// 藍襤覽拉臘蠟廊朗浪狼琅瑯螂郞來崍 + 0x694d,0x54fd,0x54fe,0x5541,0x5542,0x5543,0x5545,0x5544,0x5546,0x5547,0x5549,0x554a,0x554b,0x554c,0x554d,0x554e,// 徠萊冷掠略亮倆兩凉梁樑粮粱糧良諒 + 0x554f,0x5550,0x5552,0x694e,0x5553,0x5554,0x5555,0x555e,0x5556,0x5557,0x5558,0x5559,0x555b,0x555d,0x555f,0x5562,// 輛量侶儷勵呂廬慮戾旅櫚濾礪藜蠣閭 + 0x5563,0x5564,0x5565,0x5566,0x5567,0x5569,0x5568,0x556b,0x556c,0x556d,0x556e,0x556f,0x5570,0x5571,0x5572,0x0000,// 驢驪麗黎力曆歷瀝礫轢靂憐戀攣漣 + // 0xd6a0 - 0xd6ff + 0x0000,0x5573,0x694f,0x5574,0x5575,0x5576,0x5577,0x5578,0x5579,0x557a,0x557c,0x557b,0x557d,0x557e,0x557f,0x5580,// 煉璉練聯蓮輦連鍊冽列劣洌烈裂廉 + 0x5581,0x5582,0x5583,0x5584,0x5585,0x5587,0x5588,0x5589,0x6950,0x6951,0x558a,0x558b,0x558e,0x6952,0x558f,0x5590,// 斂殮濂簾獵令伶囹寧岺嶺怜玲笭羚翎 + 0x6953,0x5593,0x5596,0x5594,0x5595,0x5597,0x5598,0x5599,0x6954,0x559a,0x559b,0x559c,0x559d,0x6955,0x559e,0x6956,// 聆逞鈴零靈領齡例澧禮醴隷勞怒撈擄 + 0x559f,0x6957,0x55a2,0x55a1,0x55a3,0x55a4,0x55a6,0x55a7,0x55a8,0x55a9,0x55ab,0x55ac,0x55ad,0x55ae,0x55b0,0x6958,// 櫓潞瀘爐盧老蘆虜路輅露魯鷺鹵碌祿 + 0x55b2,0x6959,0x55b4,0x55b6,0x55b5,0x55b7,0x55b8,0x55b9,0x55ba,0x55bb,0x55bc,0x55bd,0x55be,0x55bf,0x695a,0x55c0,// 綠菉錄鹿麓論壟弄朧瀧瓏籠聾儡瀨牢 + 0x55c1,0x55c6,0x695b,0x55c5,0x55c7,0x55c8,0x55c9,0x55cb,0x55cc,0x55d0,0x55cd,0x55ce,0x55cf,0x55d1,0x55d2,0x0000,// 磊賂賚賴雷了僚寮廖料燎療瞭聊蓼 + // 0xd7a0 - 0xd7ff + 0x0000,0x55d3,0x695c,0x55d4,0x55d6,0x695d,0x55d7,0x55d8,0x55d9,0x55da,0x695e,0x55db,0x55dc,0x695f,0x55dd,0x6960,// 遼鬧龍壘婁屢樓淚漏瘻累縷蔞褸鏤 + 0x55de,0x55e0,0x6961,0x55e1,0x55e2,0x55e3,0x55e4,0x6962,0x55e5,0x55e6,0x55e7,0x55e8,0x55e9,0x55ea,0x55eb,0x55ec,// 陋劉旒柳榴流溜瀏琉瑠留瘤硫謬類六 + 0x55ed,0x55ee,0x6963,0x55ef,0x55f0,0x55f1,0x55f2,0x55f3,0x55f4,0x55f5,0x55f6,0x55f7,0x55f9,0x55fb,0x55fa,0x6964,// 戮陸侖倫崙淪綸輪律慄栗率隆勒肋凜 + 0x55fe,0x5641,0x5642,0x5643,0x5644,0x5645,0x5646,0x5647,0x5648,0x5649,0x6965,0x564a,0x564b,0x564d,0x564e,0x6966,// 凌楞稜綾菱陵俚利厘吏唎履悧李梨浬 + 0x5650,0x5651,0x5652,0x5653,0x6967,0x5654,0x5657,0x5656,0x6968,0x6969,0x5659,0x696a,0x565a,0x565b,0x565c,0x565e,// 犁狸理璃異痢籬罹羸莉裏裡里釐離鯉 + 0x565f,0x696b,0x5660,0x5661,0x5662,0x5663,0x5664,0x5665,0x5666,0x5667,0x5668,0x5669,0x566b,0x566c,0x566e,0x0000,// 吝潾燐璘藺躪隣鱗麟林淋琳臨霖砬 + // 0xd8a0 - 0xd8ff + 0x0000,0x566f,0x5670,0x5671,0x5673,0x5674,0x5675,0x696c,0x5676,0x5678,0x5679,0x567a,0x567b,0x567c,0x567d,0x567e,// 立笠粒摩瑪痲碼磨馬魔麻寞幕漠膜 + 0x567f,0x696d,0x696e,0x696f,0x5680,0x5681,0x5682,0x5683,0x5684,0x5685,0x5686,0x5687,0x5688,0x5689,0x568a,0x568b,// 莫邈万卍娩巒彎慢挽晩曼滿漫灣瞞萬 + 0x568c,0x568d,0x568f,0x5691,0x5693,0x6970,0x5694,0x5695,0x5696,0x6971,0x5697,0x5698,0x5699,0x569a,0x569b,0x569c,// 蔓蠻輓饅鰻唜抹末沫茉襪靺亡妄忘忙 + 0x569d,0x569e,0x569f,0x56a0,0x56a1,0x56a2,0x6972,0x56a3,0x56a5,0x56a6,0x56a7,0x56a8,0x56a9,0x56aa,0x56ab,0x56ac,// 望網罔芒茫莽輞邙埋妹媒寐昧枚梅每 + 0x56ad,0x56af,0x56b1,0x56b2,0x56b3,0x56b4,0x56b5,0x56b7,0x56b8,0x56b9,0x56ba,0x56bb,0x56bc,0x56bd,0x56bf,0x56be,// 煤罵買賣邁魅脈貊陌驀麥孟氓猛盲盟 + 0x56c0,0x56c1,0x56c2,0x56c4,0x56c6,0x56c5,0x56c7,0x6973,0x56c8,0x56c9,0x56ca,0x56cb,0x56cc,0x56cd,0x56ce,0x0000,// 萌冪覓免冕勉棉沔眄眠綿緬面麵滅 + // 0xd9a0 - 0xd9ff + 0x0000,0x56cf,0x56d1,0x56d2,0x56d0,0x56d4,0x56d5,0x6974,0x56d6,0x56d7,0x6975,0x56d8,0x6976,0x56d9,0x56da,0x56db,// 蔑冥名命明暝椧溟皿瞑茗蓂螟酩銘 + 0x56d3,0x56dc,0x56dd,0x56e4,0x56de,0x56e0,0x56df,0x56e1,0x56e2,0x6977,0x56e3,0x56e5,0x56e6,0x56e7,0x56e8,0x56e9,// 鳴袂侮冒募姆帽慕摸摹暮某模母毛牟 + 0x56ea,0x6978,0x56eb,0x56ec,0x56ee,0x6979,0x56ef,0x56f0,0x56f1,0x56f2,0x56f4,0x56f5,0x56f6,0x56f7,0x56f8,0x56f9,// 牡瑁眸矛耗芼茅謀謨貌木沐牧目睦穆 + 0x697a,0x56fa,0x56fb,0x56fc,0x56fd,0x5742,0x5743,0x5744,0x5745,0x5746,0x5747,0x5748,0x5749,0x574a,0x574b,0x697b,// 鶩歿沒夢朦蒙卯墓妙廟描昴杳渺猫竗 + 0x574c,0x574d,0x574e,0x574f,0x697c,0x5750,0x5751,0x5752,0x5753,0x5754,0x697d,0x5755,0x5756,0x5757,0x697e,0x5758,// 苗錨務巫憮懋戊拇撫无楙武毋無珷畝 + 0x5759,0x575a,0x575b,0x575c,0x575d,0x575e,0x575f,0x5760,0x5761,0x5762,0x697f,0x5763,0x5764,0x576b,0x5765,0x0000,// 繆舞茂蕪誣貿霧鵡墨默們刎吻問文 + // 0xdaa0 - 0xdaff + 0x0000,0x5766,0x5768,0x5767,0x576c,0x5769,0x576a,0x6980,0x576d,0x6981,0x576e,0x576f,0x5770,0x5771,0x5772,0x5774,// 汶紊紋聞蚊門雯勿沕物味媚尾嵋彌 + 0x5775,0x5776,0x6982,0x6983,0x5777,0x6984,0x5779,0x577a,0x577c,0x577d,0x577e,0x577f,0x5773,0x6985,0x6986,0x5780,// 微未梶楣渼湄眉米美薇謎迷靡黴岷悶 + 0x5781,0x5782,0x5783,0x5785,0x5784,0x5786,0x5787,0x5788,0x5789,0x6987,0x578a,0x578c,0x578d,0x578e,0x5790,0x5791,// 愍憫敏旻旼民泯玟珉緡閔密蜜謐剝博 + 0x5792,0x5793,0x5794,0x5795,0x5796,0x5798,0x579a,0x579b,0x579c,0x579e,0x579d,0x579f,0x57a0,0x57a1,0x57a2,0x57a3,// 拍搏撲朴樸泊珀璞箔粕縛膊舶薄迫雹 + 0x57a4,0x57a5,0x57a6,0x57a7,0x57a8,0x57a9,0x57aa,0x57ab,0x57ac,0x57ad,0x57af,0x57ae,0x57b0,0x57b1,0x6988,0x57b2,// 駁伴半反叛拌搬攀斑槃泮潘班畔瘢盤 + 0x6989,0x698a,0x57b3,0x57b4,0x57b5,0x57b8,0x57b7,0x57b9,0x57ba,0x57bb,0x57bc,0x57bd,0x57bf,0x698b,0x57be,0x0000,// 盼磐磻礬絆般蟠返頒飯勃拔撥渤潑 + // 0xdba0 - 0xdbff + 0x0000,0x57c0,0x57c1,0x57c2,0x57c3,0x57c4,0x57c5,0x57c6,0x57c7,0x57c8,0x57c9,0x57ca,0x57cb,0x57cc,0x57cd,0x57ce,// 發跋醱鉢髮魃倣傍坊妨尨幇彷房放 + 0x57cf,0x57d0,0x57d1,0x698c,0x57d2,0x698d,0x698e,0x57d3,0x57d4,0x57d5,0x57d6,0x57d7,0x57d8,0x57d9,0x57da,0x57db,// 方旁昉枋榜滂磅紡肪膀舫芳蒡蚌訪謗 + 0x57dc,0x57dd,0x57e0,0x57e2,0x57e1,0x57e3,0x57e4,0x57e5,0x57e6,0x57e7,0x57e8,0x57e9,0x698f,0x57ea,0x57ec,0x57eb,// 邦防龐倍俳北培徘拜排杯湃焙盃背胚 + 0x57ee,0x57ed,0x57ef,0x57f0,0x57f1,0x57f2,0x57f3,0x57f4,0x57f5,0x57f6,0x57f7,0x57f8,0x57f9,0x57fa,0x57fb,0x6990,// 裴裵褙賠輩配陪伯佰帛柏栢白百魄幡 + 0x57fc,0x57fe,0x6991,0x5841,0x5842,0x5843,0x5845,0x5846,0x5847,0x5848,0x5849,0x584a,0x584b,0x584c,0x584d,0x584e,// 樊煩燔番磻繁蕃藩飜伐筏罰閥凡帆梵 + 0x584f,0x5850,0x5851,0x5852,0x5853,0x5854,0x5855,0x5856,0x5857,0x5858,0x5859,0x585a,0x6992,0x585b,0x585c,0x0000,// 氾汎泛犯範范法琺僻劈壁擘檗璧癖 + // 0xdca0 - 0xdcff + 0x0000,0x585d,0x6993,0x585f,0x5860,0x5861,0x5862,0x5863,0x5866,0x5867,0x5868,0x586a,0x586c,0x586e,0x586f,0x5870,// 碧蘗闢霹便卞弁變辨辯邊別瞥鱉鼈 + 0x5871,0x5872,0x5873,0x5874,0x5875,0x5876,0x5877,0x5878,0x6994,0x5879,0x587a,0x587b,0x587d,0x587c,0x587e,0x5880,// 丙倂兵屛幷昞昺柄棅炳甁病秉竝輧餠 + 0x6995,0x5881,0x5882,0x5883,0x5884,0x5885,0x5886,0x5888,0x5887,0x5889,0x6996,0x588a,0x6997,0x588b,0x588c,0x588d,// 騈保堡報寶普步洑湺潽珤甫菩補褓譜 + 0x588e,0x5891,0x5892,0x5893,0x5894,0x5895,0x5896,0x5898,0x5897,0x5899,0x589a,0x589b,0x589e,0x589c,0x6998,0x589f,// 輔伏僕匐卜宓復服福腹茯蔔複覆輹輻 + 0x58a0,0x58a1,0x58a2,0x58a3,0x58a5,0x58a6,0x58a7,0x58a9,0x58a8,0x58aa,0x58ac,0x58ad,0x6999,0x58ab,0x58ae,0x58b0,// 馥鰒本乶俸奉封峯峰捧棒烽熢琫縫蓬 + 0x58b1,0x58b2,0x58b3,0x58b4,0x699a,0x58b6,0x699b,0x58b7,0x58b8,0x58b9,0x58ba,0x699c,0x58bb,0x58bc,0x58bd,0x0000,// 蜂逢鋒鳳不付俯傅剖副否咐埠夫婦 + // 0xdda0 - 0xddff + 0x0000,0x699d,0x58be,0x58bf,0x58c0,0x58c1,0x58c2,0x58c3,0x58c4,0x58c5,0x58c6,0x58c7,0x58ca,0x58c8,0x58c9,0x58cd,// 孚孵富府復扶敷斧浮溥父符簿缶腐 + 0x58cc,0x58ce,0x699e,0x58cf,0x699f,0x58d2,0x58d3,0x58d4,0x58d5,0x58d6,0x58d7,0x58d8,0x58d9,0x58da,0x58db,0x58dd,// 腑膚艀芙莩訃負賦賻赴趺部釜阜附駙 + 0x58df,0x58e0,0x58e1,0x69a0,0x58e2,0x58e4,0x58e5,0x58e6,0x58e7,0x58e8,0x58e9,0x69a1,0x58ea,0x58eb,0x58ec,0x58ed,// 鳧北分吩噴墳奔奮忿憤扮昐汾焚盆粉 + 0x58ee,0x58ef,0x58f0,0x69a2,0x58f2,0x58f3,0x58f4,0x58f6,0x69a3,0x58f7,0x58fa,0x58fb,0x58fc,0x58fd,0x58fe,0x5941,// 糞紛芬賁雰不佛弗彿拂崩朋棚硼繃鵬 + 0x5942,0x5943,0x5944,0x5945,0x5946,0x5947,0x5949,0x594a,0x594b,0x594c,0x594d,0x594e,0x594f,0x69a4,0x5951,0x5955,// 丕備匕匪卑妃婢庇悲憊扉批斐枇榧比 + 0x69a5,0x69a6,0x5956,0x5954,0x5953,0x5957,0x5958,0x595a,0x595b,0x69a7,0x595c,0x69a8,0x595e,0x595f,0x5960,0x0000,// 毖毗毘沸泌琵痺砒碑秕秘粃緋翡肥 + // 0xdea0 - 0xdeff + 0x0000,0x5962,0x5963,0x5964,0x5965,0x5966,0x5967,0x5968,0x5969,0x596b,0x596c,0x596d,0x596f,0x69a9,0x5970,0x5972,// 脾臂菲蜚裨誹譬費鄙非飛鼻嚬嬪彬 + 0x5974,0x5975,0x5976,0x69aa,0x5977,0x5978,0x5979,0x69ab,0x597b,0x5971,0x597d,0x5980,0x5981,0x5982,0x5983,0x5984,// 斌檳殯浜濱瀕牝玭貧賓頻憑氷聘騁乍 + 0x5985,0x5986,0x5987,0x5989,0x5988,0x598b,0x69ac,0x598c,0x598d,0x598e,0x5990,0x5991,0x598f,0x5992,0x5993,0x5995,// 事些仕伺似使俟僿史司唆嗣四士奢娑 + 0x5996,0x5997,0x59bd,0x5998,0x5999,0x599b,0x599c,0x599d,0x59a0,0x599f,0x69ad,0x59a1,0x59a2,0x59ae,0x59a5,0x59a6,// 寫寺射巳師徙思捨斜斯柶査梭死沙泗 + 0x59a7,0x59a8,0x59aa,0x59af,0x59ac,0x59ab,0x59ad,0x59b0,0x59b2,0x59b4,0x59b5,0x59bf,0x598a,0x59b6,0x59b3,0x59b7,// 渣瀉獅砂社祀祠私篩紗絲肆舍莎蓑蛇 + 0x59b8,0x59b9,0x59ba,0x59bb,0x59bc,0x599e,0x59be,0x59a9,0x59c0,0x59c1,0x69ae,0x59c2,0x59c3,0x59c5,0x59c6,0x0000,// 裟詐詞謝賜赦辭邪飼駟麝削數朔索 + // 0xdfa0 - 0xdfff + 0x0000,0x59c8,0x59c9,0x59ca,0x59cb,0x59cc,0x59cd,0x59ce,0x59cf,0x59d0,0x59d1,0x59d2,0x69af,0x59d5,0x59d3,0x59d4,// 傘刪山散汕珊産疝算蒜酸霰乷撒殺 + 0x69b0,0x59d6,0x59d7,0x59d8,0x59d9,0x59da,0x59db,0x59dd,0x59de,0x59dc,0x59e0,0x59e1,0x69b1,0x59e2,0x59e5,0x59e6,// 煞薩三參杉森渗芟蔘衫揷澁鈒颯上傷 + 0x59e7,0x59e8,0x59e9,0x59ea,0x59eb,0x59ed,0x59ee,0x69b2,0x59f2,0x59ef,0x59f0,0x59f1,0x59f3,0x59f5,0x59f6,0x59f8,// 像償商喪嘗孀尙峠常床庠廂想桑橡湘 + 0x59ec,0x59fa,0x59f9,0x59f4,0x59fb,0x59fc,0x59fd,0x59fe,0x5a41,0x5a44,0x5a42,0x5a43,0x5a45,0x5a46,0x5a47,0x5a48,// 爽牀狀相祥箱翔裳觴詳象賞霜塞璽賽 + 0x69b3,0x5a4a,0x5a4b,0x5a4c,0x5a4d,0x5a4e,0x5a4f,0x5a50,0x5a51,0x5a52,0x5a55,0x5a54,0x5a58,0x5a59,0x5a5a,0x5a5b,// 嗇塞穡索色牲生甥省笙墅壻嶼序庶徐 + 0x5a5c,0x5a5d,0x69b4,0x5a5e,0x5a5f,0x5a60,0x5a61,0x5a62,0x5a63,0x5a57,0x5a64,0x69b5,0x5a65,0x5a66,0x5a67,0x0000,// 恕抒捿敍暑曙書栖棲犀瑞筮絮緖署 + // 0xe0a0 - 0xe0ff + 0x0000,0x5a68,0x5a69,0x5a6a,0x5a6b,0x5a6c,0x5a6e,0x5a6d,0x5a6f,0x5a71,0x5a72,0x5a73,0x5a75,0x5a76,0x5a77,0x5a78,// 胥舒薯西誓逝鋤黍鼠夕奭席惜昔晳 + 0x5a79,0x5a7a,0x5a7b,0x5a7c,0x5a7d,0x5a7e,0x5a7f,0x5a80,0x5a81,0x5a83,0x5a84,0x5a82,0x5a86,0x69b6,0x5a87,0x5a8a,// 析汐淅潟石碩蓆釋錫仙僊先善嬋宣扇 + 0x69b7,0x5a8b,0x69b8,0x5a8d,0x69b9,0x5a90,0x5a91,0x5a92,0x5a93,0x5a8f,0x5a94,0x5a95,0x5a96,0x5a97,0x5a98,0x5a99,// 敾旋渲煽琁瑄璇璿癬禪線繕羨腺膳船 + 0x5a9a,0x5a9b,0x5a9c,0x5a9d,0x5a9e,0x5a9f,0x69ba,0x69bb,0x5aa1,0x5aa3,0x5aa6,0x5aa8,0x69bc,0x5aa9,0x5aaa,0x5aa4,// 蘚蟬詵跣選銑鐥饍鮮卨屑楔泄洩渫舌 + 0x5aab,0x69bd,0x5aac,0x5aad,0x5aae,0x69be,0x69bf,0x5ab3,0x5aaf,0x5ab0,0x5ab1,0x5ab2,0x5ab4,0x69c0,0x5ab6,0x5ab7,// 薛褻設說雪齧剡暹殲纖蟾贍閃陝攝涉 + 0x5ab5,0x5ab8,0x5ab9,0x5aba,0x69c1,0x5abb,0x5abc,0x5abd,0x5abe,0x5abf,0x5ac0,0x69c2,0x5ac1,0x5ac2,0x5ac3,0x0000,// 燮葉城姓宬性惺成星晟猩珹盛省筬 + // 0xe1a0 - 0xe1ff + 0x0000,0x5ac4,0x5ac5,0x5ac6,0x5ac7,0x5ac8,0x5ac9,0x5aca,0x5acb,0x5acc,0x5acd,0x5ace,0x5acf,0x5ad0,0x5ad1,0x5ad2,// 聖聲腥誠醒世勢歲洗稅笹細說貰召 + 0x5ad3,0x5ad4,0x5ad7,0x5ad5,0x5ad6,0x5ad8,0x5adb,0x5ad9,0x5ada,0x5adc,0x5add,0x5ade,0x5adf,0x5ae0,0x5ae1,0x5ae2,// 嘯塑宵小少巢所掃搔昭梳沼消溯瀟炤 + 0x5ae3,0x5ae4,0x5ae6,0x5ae5,0x69c3,0x5ae7,0x69c4,0x5ae8,0x5ae9,0x5aea,0x5aec,0x5aed,0x5aee,0x5aef,0x5af0,0x5af1,// 燒甦疏疎瘙笑篠簫素紹蔬蕭蘇訴逍遡 + 0x5af2,0x5af3,0x5af5,0x5af6,0x5af7,0x5af8,0x5af9,0x69c5,0x5afa,0x5afb,0x69c6,0x69c7,0x5afc,0x5afd,0x69c8,0x5afe,// 邵銷韶騷俗屬束涑粟續謖贖速孫巽損 + 0x69c9,0x5b41,0x69ca,0x5b42,0x5b44,0x69cb,0x5b45,0x69cc,0x5b46,0x5b47,0x5b48,0x5b49,0x5b4a,0x5b4b,0x5b4c,0x5b4e,// 蓀遜飡率宋悚松淞訟誦送頌刷殺灑碎 + 0x5b4f,0x5b50,0x5b51,0x5b52,0x5b53,0x5b56,0x5b55,0x5b57,0x5b58,0x5b59,0x5b5a,0x5b5c,0x69cd,0x5b5d,0x5b5f,0x0000,// 鎖衰釗修受嗽囚垂壽嫂守岫峀帥愁 + // 0xe2a0 - 0xe2ff + 0x0000,0x5b5e,0x5b60,0x5b61,0x5b62,0x5b63,0x5b64,0x5b66,0x5b67,0x5b69,0x5b6a,0x5b6c,0x5b68,0x5b6d,0x5b6e,0x69ce,// 戍手授搜收數樹殊水洙漱燧狩獸琇 + 0x69cf,0x5b70,0x5b71,0x5b73,0x5b74,0x5b75,0x5b76,0x5b77,0x5b78,0x5b79,0x5b7a,0x5b7b,0x5b7c,0x5b7d,0x5b7e,0x5b7f,// 璲瘦睡秀穗竪粹綏綬繡羞脩茱蒐蓚藪 + 0x5b80,0x5b81,0x69d0,0x5b82,0x5b83,0x5b84,0x5b85,0x5b86,0x5b87,0x5b88,0x69d1,0x5b89,0x5b8a,0x5b8b,0x5b8c,0x5b8d,// 袖誰讐輸遂邃酬銖銹隋隧隨雖需須首 + 0x5b8e,0x5b8f,0x5b90,0x5b91,0x5b92,0x5b93,0x5b94,0x5b95,0x69d2,0x5b96,0x69d3,0x69d4,0x5b97,0x5b98,0x5ba9,0x69d5,// 髓鬚叔塾夙孰宿淑潚熟琡璹肅菽巡徇 + 0x5b99,0x5b9a,0x5b9b,0x69d6,0x5b9c,0x69d7,0x5b9d,0x5b9e,0x5b9f,0x5ba0,0x5ba1,0x5ba2,0x5ba3,0x5ba4,0x5ba5,0x5ba6,// 循恂旬栒楯橓殉洵淳珣盾瞬筍純脣舜 + 0x5ba7,0x69d8,0x69d9,0x5ba8,0x69da,0x5baa,0x5bab,0x5bac,0x5bad,0x5baf,0x5bb0,0x5bb1,0x69db,0x5bb2,0x5bb3,0x0000,// 荀蓴蕣詢諄醇錞順馴戌術述鉥崇崧 + // 0xe3a0 - 0xe3ff + 0x0000,0x5bb4,0x5bb5,0x5bb6,0x5bb8,0x5bba,0x5bb9,0x5bbb,0x5bbc,0x5bbd,0x5bbe,0x5bbf,0x5bc0,0x5bc4,0x5bc1,0x5bc2,// 嵩瑟膝蝨濕拾習褶襲丞乘僧勝升承 + 0x5bc3,0x5bc5,0x5bc6,0x5bc7,0x5bc8,0x5bc9,0x5bcb,0x5bcc,0x5bcd,0x5bcf,0x69dc,0x5bd0,0x5bd1,0x5bd2,0x5bd3,0x5bd4,// 昇繩蠅陞侍匙嘶始媤尸屎屍市弑恃施 + 0x5bd5,0x5bd6,0x5bd7,0x5bd8,0x5bd9,0x5bda,0x5bdb,0x5bde,0x5bdf,0x5be0,0x5bdc,0x5be2,0x5be1,0x5be3,0x69dd,0x5be4,// 是時枾柴猜矢示翅蒔蓍視試詩諡豕豺 + 0x5be5,0x5be6,0x5be7,0x5be8,0x5be9,0x5bea,0x5beb,0x5bec,0x5bed,0x69de,0x69df,0x5bee,0x5bef,0x5bf0,0x5bf1,0x5bf2,// 埴寔式息拭植殖湜熄篒蝕識軾食飾伸 + 0x69e0,0x5bf3,0x5bf4,0x5bf5,0x5bf6,0x5bf7,0x5bf8,0x5bf9,0x5bfa,0x5bfb,0x5bfd,0x5bfe,0x5c41,0x5c42,0x5c43,0x5c44,// 侁信呻娠宸愼新晨燼申神紳腎臣莘薪 + 0x69e1,0x5c45,0x5c46,0x5c47,0x5c48,0x5c49,0x5c4a,0x5c4b,0x5c4c,0x5c4d,0x5c4e,0x5c50,0x5c51,0x5c52,0x5c54,0x0000,// 藎蜃訊身辛辰迅失室實悉審尋心沁 + // 0xe4a0 - 0xe4ff + 0x0000,0x5c53,0x5c55,0x5c56,0x5c57,0x5c58,0x69e2,0x5c59,0x5c5a,0x5c5b,0x5c5c,0x5c5d,0x5c5e,0x5c5f,0x5c60,0x69e3,// 沈深瀋甚芯諶什十拾雙氏亞俄兒啞 + 0x5c61,0x5c62,0x5c63,0x5c64,0x5c65,0x69e4,0x5c66,0x5c67,0x5c68,0x5c69,0x5c6a,0x5c6b,0x5c6c,0x5c6d,0x5c6e,0x5c6f,// 娥峨我牙芽莪蛾衙訝阿雅餓鴉鵝堊岳 + 0x5c70,0x69e5,0x5c72,0x5c71,0x5c73,0x5c74,0x5c75,0x69e6,0x69e7,0x5c77,0x69e8,0x5c78,0x5c79,0x5c7a,0x5c7b,0x5c7c,// 嶽幄惡愕握樂渥鄂鍔顎鰐齷安岸按晏 + 0x5c7d,0x5c7e,0x5c7f,0x5c81,0x5c82,0x69e9,0x5c85,0x5c86,0x5c87,0x5c89,0x69ea,0x69eb,0x5c8b,0x5c8c,0x5c8d,0x5c8e,// 案眼雁鞍顔鮟斡謁軋閼唵岩巖庵暗癌 + 0x5c8f,0x5c91,0x5c93,0x5c94,0x5c95,0x5c96,0x5c97,0x5c98,0x5c99,0x5c9a,0x5c9b,0x5c9c,0x5c9e,0x5c9f,0x5caa,0x5ca0,// 菴闇壓押狎鴨仰央怏昻殃秧鴦厓哀埃 + 0x5ca1,0x5ca2,0x5ca6,0x5ca4,0x5ca7,0x5ca9,0x5cab,0x5cac,0x5cae,0x69ec,0x5caf,0x5cb0,0x69ed,0x5cb1,0x5cb3,0x0000,// 崖愛曖涯碍艾隘靄厄扼掖液縊腋額 + // 0xe5a0 - 0xe5ff + 0x0000,0x5cb4,0x5cb5,0x5cb6,0x5cb7,0x5cb8,0x5cb9,0x5cba,0x5cbb,0x5cc2,0x5cbd,0x5cbe,0x5cbf,0x5cc0,0x5cc1,0x5cc3,// 櫻罌鶯鸚也倻冶夜惹揶椰爺耶若野 + 0x5cc4,0x69ee,0x69ef,0x5cc7,0x5cc8,0x5cc9,0x69f0,0x5cca,0x5ccb,0x69f1,0x5ccc,0x69f2,0x69f3,0x5ccd,0x5cce,0x5ccf,// 弱掠略約若葯蒻藥躍亮佯兩凉壤孃恙 + 0x5cd0,0x5cd1,0x5cd2,0x5cd3,0x69f4,0x5cd4,0x5cd5,0x5cd6,0x5cd7,0x5cd8,0x5cda,0x5cdb,0x69f5,0x5cd9,0x69f6,0x5cdc,// 揚攘敭暘梁楊樣洋瀁煬痒瘍禳穰糧羊 + 0x69f7,0x5cde,0x69f8,0x5cdf,0x5ce0,0x5ce1,0x69f9,0x5ce2,0x5ce3,0x5ce4,0x5ce6,0x5ce7,0x69fa,0x5ce8,0x5ce9,0x5cea,// 良襄諒讓釀陽量養圄御於漁瘀禦語馭 + 0x5ceb,0x5cec,0x5ced,0x5cee,0x5cef,0x5cf0,0x5cf1,0x5cf2,0x5cf3,0x5cf4,0x5cf5,0x5cf6,0x5cf7,0x5cf8,0x69fb,0x69fc,// 魚齬億憶抑檍臆偃堰彦焉言諺孼蘖俺 + 0x5cf9,0x5cfa,0x5cfb,0x5cfc,0x5cfd,0x5cfe,0x5d41,0x69fd,0x5d43,0x5d44,0x69fe,0x6a41,0x6a42,0x5d45,0x6a43,0x0000,// 儼嚴奄掩淹嶪業円予余勵呂女如廬 + // 0xe6a0 - 0xe6ff + 0x0000,0x6a44,0x5d46,0x5d47,0x6a45,0x6a46,0x6a47,0x6a48,0x5d48,0x6a49,0x6a4a,0x6a4b,0x6a4c,0x6a4d,0x5d49,0x6a4e,// 旅歟汝濾璵礖礪與艅茹輿轝閭餘驪 + 0x6a4f,0x6a50,0x5d4a,0x6a51,0x5d4b,0x5d4d,0x5d4e,0x6a52,0x6a53,0x5d4f,0x5d50,0x5d51,0x6a54,0x5d52,0x5d53,0x5d54,// 麗黎亦力域役易曆歷疫繹譯轢逆驛嚥 + 0x5d55,0x5d56,0x5d57,0x5d58,0x6a55,0x5d59,0x6a56,0x6a57,0x5d5a,0x6a58,0x5d5b,0x5d5c,0x6a59,0x5d5d,0x5d5f,0x5d5e,// 堧姸娟宴年延憐戀捐挻撚椽沇沿涎涓 + 0x5d60,0x5d61,0x6a5a,0x5d62,0x5d63,0x5d64,0x6a5b,0x5d65,0x5d66,0x6a5c,0x5d67,0x5d68,0x6a5d,0x5d69,0x5d6a,0x6a5e,// 淵演漣烟然煙煉燃燕璉硏硯秊筵緣練 + 0x6a5f,0x6a60,0x5d6e,0x5d70,0x6a61,0x6a62,0x6a63,0x5d71,0x6a64,0x5d72,0x6a65,0x6a66,0x5d73,0x5d74,0x5d75,0x6a67,// 縯聯衍軟輦蓮連鉛鍊鳶列劣咽悅涅烈 + 0x5d76,0x6a68,0x5d77,0x5d78,0x5d79,0x6a69,0x6a6a,0x6a6b,0x5d7b,0x6a6c,0x5d7c,0x5d7d,0x6a6d,0x5d80,0x5d7f,0x0000,// 熱裂說閱厭廉念捻染殮炎焰琰艶苒 + // 0xe7a0 - 0xe7ff + 0x0000,0x6a6e,0x5d81,0x5d83,0x5d7e,0x5d84,0x6a6f,0x5d85,0x5d86,0x6a70,0x6a71,0x5d87,0x6a72,0x6a73,0x6a74,0x5d89,// 簾閻髥鹽曄獵燁葉令囹塋寧嶺嶸影 + 0x6a75,0x5d8a,0x5d8b,0x5d8c,0x5d8d,0x5d8e,0x5d8f,0x6a76,0x5d90,0x6a77,0x5d91,0x6a78,0x6a79,0x5d92,0x6a7a,0x6a7b,// 怜映暎楹榮永泳渶潁濚瀛瀯煐營獰玲 + 0x5d93,0x5d94,0x5d95,0x5d96,0x6a7c,0x5d97,0x6a7d,0x6a7e,0x5d98,0x5d99,0x5d9a,0x6a7f,0x6a80,0x6a81,0x6a82,0x6a83,// 瑛瑩瓔盈穎纓羚聆英詠迎鈴鍈零霙靈 + 0x6a84,0x6a85,0x5d9b,0x6a86,0x5d9c,0x5d9d,0x5d9e,0x6a87,0x5d9f,0x5da0,0x5da2,0x6a88,0x5da4,0x5da6,0x5da7,0x6a89,// 領乂倪例刈叡曳汭濊猊睿穢芮藝蘂禮 + 0x5da8,0x5da9,0x5daa,0x5dab,0x6a8a,0x5dac,0x6a8b,0x5dad,0x5dae,0x5daf,0x5db0,0x6a8c,0x5db1,0x5db2,0x5dc4,0x5db3,// 裔詣譽豫醴銳隸霓預五伍俉傲午吾吳 + 0x5db4,0x6a8d,0x5db5,0x5db6,0x5db7,0x5db8,0x5db9,0x5dba,0x6a8e,0x6a8f,0x5dbb,0x5dbc,0x5dbd,0x5dbe,0x6a90,0x0000,// 嗚塢墺奧娛寤悟惡懊敖旿晤梧汚澳 + // 0xe8a0 - 0xe8ff + 0x0000,0x5dbf,0x6a91,0x5dc0,0x6a92,0x5dc1,0x5dc2,0x6a93,0x6a94,0x5dc5,0x5dc6,0x5dc7,0x5dc8,0x5dc9,0x5dcb,0x5dcc,// 烏熬獒筽蜈誤鰲鼇屋沃獄玉鈺溫瑥 + 0x5dcd,0x5dce,0x6a95,0x5dd0,0x5dd2,0x5dd3,0x5dd6,0x5dd4,0x5dd7,0x5dd5,0x5dd8,0x5dd9,0x5dda,0x6a96,0x5ddb,0x5ddc,// 瘟穩縕蘊兀壅擁瓮甕癰翁邕雍饔渦瓦 + 0x5ddd,0x6a97,0x5de1,0x5dde,0x5ddf,0x5de0,0x5de2,0x5de3,0x5de4,0x6a98,0x6a99,0x5de5,0x5de6,0x6a9a,0x5de7,0x5de8,// 窩窪臥蛙蝸訛婉完宛梡椀浣玩琓琬碗 + 0x5de9,0x5dea,0x6a9b,0x5deb,0x5dec,0x5ded,0x5dee,0x5def,0x5df0,0x5df1,0x5df2,0x5df3,0x5df4,0x5df5,0x5df6,0x6a9c,// 緩翫脘腕莞豌阮頑曰往旺枉汪王倭娃 + 0x5df7,0x5df8,0x5df9,0x6a9d,0x5dfa,0x5dfb,0x5dfc,0x6a9e,0x6a9f,0x5dfd,0x5dfe,0x5e41,0x5e42,0x5e43,0x5e44,0x6aa0,// 歪矮外嵬巍猥畏了僚僥凹堯夭妖姚寥 + 0x6aa1,0x6aa2,0x5e45,0x5e46,0x5e47,0x6aa3,0x5e48,0x6aa4,0x5e49,0x5e4b,0x5e4c,0x6aa5,0x6aa6,0x5e4d,0x6aa7,0x0000,// 寮尿嶢拗搖撓擾料曜樂橈燎燿瑤療 + // 0xe9a0 - 0xe9ff + 0x0000,0x5e4e,0x5e4f,0x5e50,0x5e51,0x5e52,0x5e4a,0x6aa8,0x5e54,0x5e55,0x5e56,0x5e57,0x6aa9,0x5e58,0x5e59,0x5e5b,// 窈窯繇繞耀腰蓼蟯要謠遙遼邀饒慾 + 0x5e5c,0x5e5d,0x6aaa,0x5e5e,0x5e5a,0x6aab,0x5e5f,0x5e63,0x5e60,0x6aac,0x6aad,0x5e61,0x5e62,0x6aae,0x5e64,0x6aaf,// 欲浴縟褥辱俑傭冗勇埇墉容庸慂榕涌 + 0x5e65,0x5e66,0x5e67,0x5e68,0x5e69,0x6ab0,0x5e6a,0x5e6c,0x5e6d,0x5e6f,0x5e70,0x5e71,0x6ab1,0x5e7c,0x5e72,0x5e73,// 湧溶熔瑢用甬聳茸蓉踊鎔鏞龍于佑偶 + 0x5e74,0x5e75,0x5e76,0x5e77,0x5e79,0x5e7a,0x5e7b,0x5e7d,0x5e7e,0x6ab2,0x5e7f,0x6ab3,0x6ab4,0x5e80,0x5e81,0x5e82,// 優又友右宇寓尤愚憂旴牛玗瑀盂祐禑 + 0x5e83,0x6ab5,0x5e84,0x5e85,0x6ab6,0x5e86,0x5e87,0x5e88,0x5e89,0x6ab7,0x5e8a,0x5e8b,0x5e8c,0x6ab8,0x6ab9,0x5e8d,// 禹紆羽芋藕虞迂遇郵釪隅雨雩勖彧旭 + 0x5e8e,0x6aba,0x5e8f,0x5e90,0x5e91,0x5e92,0x5e93,0x5e94,0x6abb,0x5e95,0x6abc,0x6abd,0x5e96,0x5e97,0x6abe,0x0000,// 昱栯煜稶郁頊云暈橒殞澐熉耘芸蕓 + // 0xeaa0 - 0xeaff + 0x0000,0x5e98,0x5e99,0x5e9a,0x5e9b,0x5e9d,0x5e9e,0x6abf,0x5e9f,0x5ea0,0x5ea1,0x5ea2,0x5ea3,0x5ea5,0x5ea4,0x5ea7,// 運隕雲韻蔚鬱亐熊雄元原員圓園垣 + 0x5ea8,0x6ac0,0x5ea9,0x5eaa,0x5eab,0x5eac,0x6ac1,0x6ac2,0x6ac3,0x5ead,0x5ea6,0x5eae,0x5eaf,0x5eb0,0x5eb2,0x5eb3,// 媛嫄寃怨愿援沅洹湲源爰猿瑗苑袁轅 + 0x5eb4,0x6ac4,0x5eb5,0x5eb6,0x5eb7,0x5eb8,0x5eb9,0x5eba,0x5ebb,0x5ebc,0x5ebd,0x5ebe,0x5ebf,0x5ec0,0x5ec4,0x5ec1,// 遠阮院願鴛月越鉞位偉僞危圍委威尉 + 0x5ec3,0x6ac5,0x5ec5,0x5ec6,0x5ec7,0x5ec8,0x5ec9,0x5eca,0x5ecb,0x6ac6,0x5ecc,0x5ecd,0x6ac7,0x5ecf,0x5ed0,0x5ed1,// 慰暐渭爲瑋緯胃萎葦蔿蝟衛褘謂違韋 + 0x5ed2,0x5ed3,0x5ed5,0x5ed6,0x5ed7,0x6ac8,0x5ed9,0x5eda,0x5edc,0x5edd,0x5ed8,0x5edf,0x5ee0,0x5ee1,0x5ee2,0x5ee4,// 魏乳侑儒兪劉唯喩孺宥幼幽庾悠惟愈 + 0x5ee3,0x5ee5,0x5ed4,0x5ee6,0x6ac9,0x5ee7,0x5ee8,0x6aca,0x5ee9,0x6acb,0x5eea,0x6acc,0x6acd,0x5eeb,0x6ace,0x0000,// 愉揄攸有杻柔柚柳楡楢油洧流游溜 + // 0xeba0 - 0xebff + 0x0000,0x5eec,0x5eed,0x6acf,0x6ad0,0x5eee,0x5eef,0x6ad1,0x5ef0,0x6ad2,0x6ad3,0x5ef1,0x5ef2,0x5ef3,0x5ef5,0x5ef6,// 濡猶猷琉瑜由留癒硫紐維臾萸裕誘 + 0x5ef7,0x5ef8,0x5efa,0x5ef9,0x5efb,0x5efc,0x5efd,0x5efe,0x5f41,0x5f42,0x6ad4,0x6ad5,0x6ad6,0x6ad7,0x5f44,0x5f45,// 諛諭踰蹂遊逾遺酉釉鍮類六堉戮毓肉 + 0x5f46,0x6ad8,0x6ad9,0x5f48,0x5f49,0x5f4a,0x6ada,0x6adb,0x5f4b,0x5f4c,0x5f4d,0x6adc,0x6add,0x6ade,0x5f4e,0x6adf,// 育陸倫允奫尹崙淪潤玧胤贇輪鈗閏律 + 0x6ae0,0x6ae1,0x6ae2,0x5f4f,0x5f50,0x6ae3,0x5f51,0x5f52,0x6ae4,0x5f53,0x5f54,0x5f55,0x5f57,0x5f5a,0x5f59,0x5f5b,// 慄栗率聿戎瀜絨融隆垠恩慇殷誾銀隱 + 0x5f5d,0x5f5e,0x5f5f,0x5f60,0x5f61,0x5f63,0x5f62,0x5f65,0x5f66,0x5f67,0x5f68,0x5f69,0x5f6a,0x5f6b,0x5f6c,0x5f6d,// 乙吟淫蔭陰音飮揖泣邑凝應膺鷹依倚 + 0x5f6e,0x5f71,0x5f72,0x5f73,0x5f74,0x6ae5,0x5f75,0x5f6f,0x5f70,0x5f76,0x5f77,0x6ae6,0x5f78,0x5f79,0x5f7a,0x0000,// 儀宜意懿擬椅毅疑矣義艤薏蟻衣誼 + // 0xeca0 - 0xecff + 0x0000,0x5f7b,0x5f7c,0x5f7d,0x5f7e,0x5f7f,0x6ae7,0x6ae8,0x5f80,0x5f81,0x6ae9,0x5f82,0x5f84,0x5f85,0x5f86,0x5f87,// 議醫二以伊利吏夷姨履已弛彛怡易 + 0x6aea,0x6aeb,0x6aec,0x5f89,0x5f8a,0x6aed,0x5f8b,0x5f8c,0x6aee,0x5f8d,0x6aef,0x5f8e,0x5f8f,0x6af0,0x6af1,0x5f90,// 李梨泥爾珥理異痍痢移罹而耳肄苡荑 + 0x6af2,0x6af3,0x6af4,0x5f83,0x6af5,0x6af6,0x6af7,0x5f91,0x5f92,0x6af8,0x6af9,0x5f94,0x5f96,0x5f97,0x5f98,0x5f95,// 裏裡貽貳邇里離飴餌匿溺瀷益翊翌翼 + 0x6afa,0x5f99,0x5f9a,0x5f9c,0x5f9d,0x6afb,0x5f9e,0x5f9f,0x5fa0,0x5fa1,0x5fa2,0x5fa3,0x5fa4,0x6afc,0x6afd,0x6afe,// 謚人仁刃印吝咽因姻寅引忍湮燐璘絪 + 0x6b41,0x6b42,0x6b43,0x5fa5,0x6b44,0x5fa6,0x5fa7,0x6b45,0x6b46,0x5fa8,0x6b47,0x5fa9,0x5faa,0x5fab,0x5fac,0x5fad,// 茵藺蚓認隣靭靷鱗麟一佚佾壹日溢逸 + 0x5fae,0x5faf,0x5fb0,0x5fb1,0x5fb2,0x5fb3,0x6b48,0x6b49,0x6b4a,0x5fb4,0x6b4b,0x5fb5,0x5fb6,0x5fb7,0x6b4c,0x0000,// 鎰馹任壬妊姙恁林淋稔臨荏賃入卄 + // 0xeda0 - 0xedff + 0x0000,0x6b4d,0x6b4e,0x6b4f,0x5fb8,0x5fba,0x5fb9,0x6b50,0x5fbb,0x5fbc,0x5fbd,0x5fbe,0x5fbf,0x5fc0,0x5fc2,0x5fc1,// 立笠粒仍剩孕芿仔刺咨姉姿子字孜 + 0x5fc3,0x5fc4,0x5fc5,0x5fc6,0x5fc7,0x5fc8,0x5fc9,0x5fca,0x5fcc,0x5fce,0x5fcf,0x5fd1,0x6b51,0x5fd2,0x5fd3,0x5fd5,// 恣慈滋炙煮玆瓷疵磁紫者自茨蔗藉諮 + 0x5fd6,0x5fd8,0x5fd9,0x5fda,0x5fdb,0x5fdc,0x5fdd,0x5fdf,0x5fe0,0x5fe1,0x5fe2,0x5fe3,0x5fe4,0x5fe5,0x5fe6,0x6b52,// 資雌作勺嚼斫昨灼炸爵綽芍酌雀鵲孱 + 0x5fe7,0x5fe8,0x5fe9,0x5fea,0x5feb,0x5fec,0x5fed,0x5fef,0x5ff0,0x5ff2,0x5ff3,0x5ff4,0x5ff5,0x5ff6,0x5ff7,0x5ff8,// 棧殘潺盞岑暫潛箴簪蠶雜丈仗匠場墻 + 0x6047,0x5ff9,0x6048,0x5ffb,0x5ffc,0x5ffd,0x5ffe,0x6041,0x6042,0x6043,0x6044,0x6045,0x6046,0x6049,0x604a,0x604b,// 壯奬將帳庄張掌暲杖樟檣欌漿牆狀獐 + 0x604c,0x604e,0x604f,0x6050,0x6051,0x6b53,0x6052,0x6053,0x6054,0x6055,0x6056,0x6058,0x6059,0x605a,0x605b,0x0000,// 璋章粧腸臟臧莊葬蔣薔藏裝贓醬長 + // 0xeea0 - 0xeeff + 0x0000,0x605c,0x605d,0x605e,0x605f,0x6060,0x6061,0x6062,0x6063,0x6064,0x6b54,0x6065,0x6066,0x6b55,0x6068,0x6069,// 障再哉在宰才材栽梓渽滓災縡裁財 + 0x606a,0x606b,0x606c,0x606d,0x606e,0x606f,0x6070,0x6072,0x6071,0x6073,0x6074,0x6075,0x6076,0x6077,0x6078,0x607a,// 載齋齎爭箏諍錚佇低儲咀姐底抵杵楮 + 0x607b,0x607c,0x607d,0x607e,0x607f,0x6080,0x6081,0x6b56,0x6082,0x6b57,0x6083,0x6084,0x6086,0x6088,0x6089,0x608a,// 樗沮渚狙猪疽箸紵苧菹著藷詛貯躇這 + 0x608b,0x6b58,0x6b59,0x608c,0x6b5a,0x608d,0x608e,0x608f,0x6090,0x6091,0x6092,0x6b5b,0x6093,0x6094,0x6095,0x6096,// 邸雎齟勣吊嫡寂摘敵滴狄炙的積笛籍 + 0x6098,0x6b5c,0x6099,0x609a,0x609b,0x609c,0x609d,0x609e,0x609f,0x60a0,0x60a1,0x6b5d,0x6b5e,0x6b5f,0x60a2,0x60a3,// 績翟荻謫賊赤跡蹟迪迹適鏑佃佺傳全 + 0x60a4,0x60a5,0x60a6,0x60a8,0x6b60,0x60a9,0x60aa,0x60ab,0x60ad,0x60ae,0x60af,0x60b0,0x60b1,0x60b2,0x60b3,0x0000,// 典前剪塡塼奠專展廛悛戰栓殿氈澱 + // 0xefa0 - 0xefff + 0x0000,0x60b4,0x6b61,0x60b5,0x60b6,0x6b62,0x60b7,0x6b63,0x60b9,0x60ba,0x60bb,0x60bc,0x60be,0x60bf,0x60c0,0x60c1,// 煎琠田甸畑癲筌箋箭篆纏詮輾轉鈿 + 0x60c2,0x60c3,0x6b64,0x60c4,0x60c5,0x60c6,0x60c7,0x60c8,0x60c9,0x60ca,0x60cb,0x6b65,0x60cd,0x60ce,0x60cf,0x60d0,// 銓錢鐫電顚顫餞切截折浙癤竊節絶占 + 0x60d1,0x60d2,0x60d3,0x60d4,0x60d6,0x60d7,0x6b66,0x60d5,0x60d8,0x60d9,0x60db,0x60dc,0x60dd,0x60de,0x60df,0x60e0,// 岾店漸点粘霑鮎點接摺蝶丁井亭停偵 + 0x60e1,0x60e2,0x60e6,0x60e3,0x60e7,0x60e4,0x60e5,0x60e8,0x60e9,0x60ea,0x60eb,0x60ec,0x60ed,0x60ee,0x6b67,0x60f0,// 呈姃定幀庭廷征情挺政整旌晶晸柾楨 + 0x6b68,0x60f1,0x60f2,0x6b69,0x60f3,0x60f4,0x6b6a,0x6b6b,0x6b6c,0x6b6d,0x6b6e,0x60f5,0x60f6,0x60f7,0x60f8,0x60f9,// 檉正汀淀淨渟湞瀞炡玎珽町睛碇禎程 + 0x60fa,0x60fc,0x6b6f,0x60fd,0x60fe,0x6141,0x6142,0x6143,0x6144,0x6145,0x6146,0x6b70,0x6147,0x6148,0x60fb,0x0000,// 穽精綎艇訂諪貞鄭酊釘鉦鋌錠霆靖 + // 0xf0a0 - 0xf0ff + 0x0000,0x6149,0x614a,0x614b,0x614c,0x614d,0x614e,0x614f,0x6150,0x6151,0x6152,0x6153,0x6155,0x6156,0x6159,0x615a,// 靜頂鼎制劑啼堤帝弟悌提梯濟祭第 + 0x6158,0x615b,0x615c,0x615d,0x615f,0x6160,0x6161,0x6162,0x6163,0x6164,0x6165,0x6166,0x6168,0x6167,0x6169,0x616b,// 臍薺製諸蹄醍除際霽題齊俎兆凋助嘲 + 0x616d,0x616e,0x616f,0x6170,0x6171,0x6172,0x6173,0x6174,0x6175,0x6176,0x6177,0x6178,0x6179,0x617a,0x617b,0x617c,// 弔彫措操早晁曺曹朝條棗槽漕潮照燥 + 0x617d,0x6b71,0x617f,0x6180,0x6181,0x6182,0x6183,0x6184,0x6187,0x6188,0x618a,0x618c,0x618d,0x618e,0x618f,0x6190,// 爪璪眺祖祚租稠窕粗糟組繰肇藻蚤詔 + 0x6191,0x6192,0x6193,0x6194,0x6195,0x6196,0x6197,0x6b72,0x6199,0x619a,0x619b,0x619c,0x619d,0x619e,0x619f,0x61a0,// 調趙躁造遭釣阻雕鳥族簇足鏃存尊卒 + 0x61a1,0x61a2,0x61a3,0x61a4,0x61a5,0x6b73,0x61a6,0x61a7,0x61a9,0x61aa,0x61ab,0x61ac,0x61ad,0x61ae,0x61af,0x0000,// 拙猝倧宗從悰慫棕淙琮種終綜縱腫 + // 0xf1a0 - 0xf1ff + 0x0000,0x6b74,0x61b0,0x61b2,0x61b3,0x61b4,0x61b5,0x61b6,0x61b7,0x61b8,0x61b9,0x61ba,0x61bb,0x61bc,0x61bd,0x6b75,// 踪踵鍾鐘佐坐左座挫罪主住侏做姝 + 0x61d5,0x61bf,0x61c0,0x61c1,0x61c2,0x61c3,0x61c4,0x61be,0x61c5,0x61c6,0x61c7,0x61c8,0x61ca,0x61cb,0x6b76,0x6b77,// 胄呪周嗾奏宙州廚晝朱柱株注洲湊澍 + 0x61c9,0x61cd,0x61ce,0x61d0,0x61d1,0x61d2,0x61d3,0x61d6,0x61d7,0x61d8,0x61d9,0x61da,0x61db,0x61dc,0x61de,0x61dd,// 炷珠疇籌紂紬綢舟蛛註誅走躊輳週酎 + 0x61cc,0x61df,0x61e0,0x61e1,0x61e2,0x61e3,0x61e4,0x61e5,0x61e6,0x6b78,0x61e7,0x61e8,0x61e9,0x61ea,0x61eb,0x61ec,// 酒鑄駐竹粥俊儁准埈寯峻晙樽浚準濬 + 0x6b79,0x61ed,0x61ee,0x61ef,0x61f0,0x61f1,0x6b7a,0x61f3,0x61f4,0x61f5,0x61f6,0x61f7,0x61f8,0x61fa,0x61fb,0x61fc,// 焌畯竣蠢逡遵雋駿茁中仲衆重卽櫛楫 + 0x61fd,0x61fe,0x6241,0x6242,0x6245,0x6243,0x6244,0x6246,0x6247,0x6b7b,0x6248,0x624a,0x624b,0x624c,0x624d,0x0000,// 汁葺增憎曾拯烝甑症繒蒸證贈之只 + // 0xf2a0 - 0xf2ff + 0x0000,0x624e,0x624f,0x6250,0x6251,0x6252,0x6253,0x6254,0x6255,0x6256,0x6257,0x6258,0x6259,0x625a,0x625b,0x6b7c,// 咫地址志持指摯支旨智枝枳止池沚 + 0x625c,0x625e,0x625f,0x6261,0x6260,0x6262,0x6263,0x6264,0x6265,0x6266,0x6b7d,0x6267,0x6268,0x6269,0x626a,0x626b,// 漬知砥祉祗紙肢脂至芝芷蜘誌識贄趾 + 0x626c,0x626d,0x626e,0x626f,0x6270,0x6271,0x6b7e,0x6273,0x6274,0x6275,0x6b7f,0x6276,0x6b80,0x6b81,0x6277,0x6b82,// 遲直稙稷織職唇嗔塵振搢晉晋桭榛殄 + 0x6278,0x6279,0x627a,0x627b,0x627c,0x6b83,0x627d,0x627e,0x627f,0x6280,0x6281,0x6282,0x6b84,0x6b85,0x6b86,0x6b87,// 津溱珍瑨璡畛疹盡眞瞋秦縉縝臻蔯袗 + 0x6283,0x6284,0x6285,0x6272,0x6286,0x6287,0x6288,0x6289,0x628a,0x6b88,0x628b,0x628d,0x628e,0x628f,0x6290,0x6b89,// 診賑軫辰進鎭陣陳震侄叱姪嫉帙桎瓆 + 0x6291,0x6292,0x628c,0x6293,0x6294,0x6295,0x6296,0x6297,0x6298,0x6299,0x6b8a,0x629a,0x6b8b,0x629c,0x629d,0x0000,// 疾秩窒膣蛭質跌迭斟朕什執潗緝輯 + // 0xf3a0 - 0xf3ff + 0x0000,0x6b8c,0x629b,0x629e,0x629f,0x62a0,0x62a1,0x6b8d,0x62a2,0x62a4,0x62a5,0x62a7,0x62a6,0x62a8,0x62a9,0x62aa,// 鏶集徵懲澄且侘借叉嗟嵯差次此磋 + 0x62a3,0x62ab,0x62ac,0x62ae,0x62ad,0x62af,0x62b0,0x62b1,0x62b2,0x62b3,0x62b4,0x62b5,0x62b6,0x62b7,0x62b8,0x62b9,// 箚茶蹉車遮捉搾着窄錯鑿齪撰澯燦璨 + 0x62ba,0x62bb,0x6b8e,0x62bc,0x62bd,0x62be,0x62bf,0x62c0,0x62c1,0x62c3,0x62c4,0x62c5,0x62c6,0x62c7,0x62c8,0x6b8f,// 瓚竄簒纂粲纘讚贊鑽餐饌刹察擦札紮 + 0x62c9,0x62ca,0x62cb,0x62cc,0x62cd,0x62cf,0x62d0,0x62d1,0x62d2,0x6b90,0x62d4,0x62d3,0x62d6,0x62d7,0x62d8,0x62d9,// 僭參塹慘慙懺斬站讒讖倉倡創唱娼廠 + 0x62da,0x6b91,0x62dc,0x62dd,0x62de,0x62df,0x62e0,0x62e2,0x62e3,0x6b92,0x62e4,0x62e5,0x62e6,0x62e7,0x62e8,0x62e9,// 彰愴敞昌昶暢槍滄漲猖瘡窓脹艙菖蒼 + 0x62ea,0x62eb,0x6b93,0x6b94,0x62ec,0x62ed,0x62ee,0x62ef,0x62f0,0x62f1,0x62f2,0x62f3,0x62f4,0x62f5,0x62f6,0x0000,// 債埰寀寨彩採砦綵菜蔡采釵冊柵策 + // 0xf4a0 - 0xf4ff + 0x0000,0x62f8,0x62f9,0x62fa,0x62fb,0x62fc,0x6b95,0x62fd,0x62fe,0x6341,0x6342,0x6343,0x6344,0x6345,0x6346,0x6347,// 責凄妻悽處倜刺剔尺慽戚拓擲斥滌 + 0x6348,0x6349,0x6b96,0x634c,0x634d,0x634e,0x634f,0x6350,0x6351,0x6352,0x6353,0x6354,0x6355,0x6b97,0x6357,0x6358,// 瘠脊蹠陟隻仟千喘天川擅泉淺玔穿舛 + 0x6359,0x635a,0x635b,0x635c,0x635d,0x635e,0x635f,0x6360,0x6361,0x6363,0x6364,0x6362,0x6365,0x6366,0x6367,0x6b98,// 薦賤踐遷釧闡阡韆凸哲喆徹撤澈綴輟 + 0x6368,0x6369,0x636a,0x636b,0x636c,0x636d,0x636e,0x636f,0x6b99,0x6371,0x6b9a,0x6372,0x6b9b,0x6373,0x6374,0x6375,// 轍鐵僉尖沾添甛瞻簽籤詹諂堞妾帖捷 + 0x6376,0x6377,0x6378,0x6379,0x637a,0x637b,0x637c,0x637d,0x637e,0x637f,0x6380,0x6382,0x6383,0x6384,0x6385,0x6386,// 牒疊睫諜貼輒廳晴淸聽菁請靑鯖切剃 + 0x6387,0x6388,0x6389,0x638b,0x638c,0x638d,0x638e,0x6390,0x6391,0x6b9c,0x6392,0x6394,0x6395,0x6396,0x6397,0x0000,// 替涕滯締諦逮遞體初剿哨憔抄招梢 + // 0xf5a0 - 0xf5ff + 0x0000,0x6398,0x6399,0x639a,0x639b,0x639c,0x639d,0x639e,0x639f,0x63a0,0x63a1,0x63a3,0x6b9d,0x6b9e,0x63a4,0x63a5,// 椒楚樵炒焦硝礁礎秒稍肖艸苕草蕉 + 0x63a6,0x63a7,0x63a8,0x63a9,0x63aa,0x63ad,0x63ae,0x63b0,0x63b1,0x63b2,0x63b3,0x63b6,0x63b7,0x63b8,0x6b9f,0x63b9,// 貂超酢醋醮促囑燭矗蜀觸寸忖村邨叢 + 0x63ba,0x63bb,0x6ba0,0x6ba1,0x63bd,0x63be,0x63bf,0x6ba2,0x63c1,0x63c2,0x63c3,0x63c4,0x63c6,0x63c7,0x63c8,0x63c9,// 塚寵悤憁摠總聰蔥銃撮催崔最墜抽推 + 0x63ca,0x63cb,0x63cd,0x63ce,0x63d0,0x63d1,0x63d3,0x63d4,0x6ba3,0x63d5,0x63d6,0x63d7,0x63d8,0x63d9,0x63db,0x63da,// 椎楸樞湫皺秋芻萩諏趨追鄒酋醜錐錘 + 0x6ba4,0x63dc,0x6ba5,0x63de,0x63e1,0x63e4,0x63e3,0x63e5,0x63e6,0x63e7,0x63e8,0x63ea,0x6ba6,0x63eb,0x63ec,0x63ed,// 鎚雛騶鰍丑畜祝竺筑築縮蓄蹙蹴軸逐 + 0x63ee,0x63ef,0x6ba7,0x63f0,0x6ba8,0x63f1,0x63f2,0x63f4,0x63f5,0x63f6,0x63f7,0x63f8,0x63f9,0x63fa,0x63fb,0x0000,// 春椿瑃出朮黜充忠沖蟲衝衷悴膵萃 + // 0xf6a0 - 0xf6ff + 0x0000,0x6ba9,0x63fc,0x63fd,0x63fe,0x6441,0x6442,0x6444,0x6445,0x6446,0x6447,0x6448,0x644a,0x644b,0x644c,0x644d,// 贅取吹嘴娶就炊翠聚脆臭趣醉驟鷲 + 0x644f,0x644e,0x6baa,0x6450,0x6451,0x6452,0x6453,0x6454,0x6455,0x6456,0x6458,0x6466,0x645a,0x645b,0x645c,0x645d,// 側仄厠惻測層侈値嗤峙幟恥梔治淄熾 + 0x645e,0x645f,0x6460,0x6462,0x6bab,0x6463,0x6464,0x6465,0x6467,0x6bac,0x6468,0x6461,0x6469,0x646b,0x646c,0x646d,// 痔痴癡稚穉緇緻置致蚩輜雉馳齒則勅 + 0x646e,0x646f,0x6470,0x6471,0x6472,0x6473,0x6474,0x6476,0x6477,0x6478,0x6bad,0x6479,0x647a,0x647b,0x647c,0x647d,// 飭親七柒漆侵寢枕沈浸琛砧針鍼蟄秤 + 0x647e,0x647f,0x6480,0x6bae,0x6481,0x6482,0x6483,0x6484,0x6485,0x6baf,0x6486,0x6487,0x6488,0x6489,0x6bb0,0x648a,// 稱快他咤唾墮妥惰打拖朶楕舵陀馱駝 + 0x648b,0x648c,0x648d,0x6bb1,0x648e,0x648f,0x6491,0x6492,0x6bb2,0x6493,0x6495,0x6496,0x6497,0x6bb3,0x6498,0x0000,// 倬卓啄坼度托拓擢晫柝濁濯琢琸託 + // 0xf7a0 - 0xf7ff + 0x0000,0x6499,0x649a,0x649b,0x649c,0x649d,0x649e,0x649f,0x64a0,0x64a1,0x64a2,0x64a3,0x64a4,0x64a5,0x64a6,0x6bb4,// 鐸呑嘆坦彈憚歎灘炭綻誕奪脫探眈 + 0x64a7,0x64a8,0x64a9,0x64aa,0x64ab,0x64ac,0x64ad,0x64ae,0x6bb5,0x64af,0x64b0,0x64b1,0x64b2,0x64b3,0x64b4,0x64b5,// 耽貪塔搭榻宕帑湯糖蕩兌台太怠態殆 + 0x64b6,0x64b7,0x64b8,0x64b9,0x64ba,0x64bb,0x64bc,0x64bd,0x64bf,0x64c0,0x64c1,0x64c3,0x64c4,0x64c5,0x64c6,0x64c7,// 汰泰笞胎苔跆邰颱宅擇澤撑攄兎吐土 + 0x64c8,0x64c9,0x64ca,0x64cb,0x64cc,0x64cd,0x64ce,0x64cf,0x64d0,0x6bb6,0x64d1,0x64d2,0x64d3,0x64d4,0x64d5,0x64d6,// 討慟桶洞痛筒統通堆槌腿褪退頹偸套 + 0x64d7,0x64d8,0x64d9,0x64da,0x64db,0x64dc,0x6bb7,0x64de,0x64dd,0x64df,0x64e0,0x64e1,0x6bb8,0x64e2,0x64e3,0x64e4,// 妬投透鬪慝特闖坡婆巴把播擺杷波派 + 0x64e5,0x64e6,0x64e7,0x64e8,0x64e9,0x64ea,0x64eb,0x64ed,0x64ec,0x64ee,0x64ef,0x64f2,0x64f0,0x64f1,0x6bb9,0x0000,// 爬琶破罷芭跛頗判坂板版瓣販辦鈑 + // 0xf8a0 - 0xf8ff + 0x0000,0x64f3,0x64f4,0x64f5,0x64f6,0x64f7,0x64f8,0x64f9,0x6542,0x64fa,0x64fb,0x64fc,0x64fd,0x64fe,0x6543,0x6541,// 阪八叭捌佩唄悖敗沛浿牌狽稗覇貝 + 0x6544,0x6545,0x6546,0x6547,0x6548,0x6549,0x654a,0x654b,0x654c,0x654d,0x654e,0x654f,0x6551,0x6552,0x6bba,0x6553,// 彭澎烹膨愎便偏扁片篇編翩遍鞭騙貶 + 0x6554,0x6555,0x6bbb,0x6556,0x6557,0x6558,0x6559,0x655a,0x655b,0x655c,0x655d,0x655e,0x655f,0x6560,0x6561,0x6562,// 坪平枰萍評吠嬖幣廢弊斃肺蔽閉陛佈 + 0x6563,0x6564,0x6565,0x6566,0x6567,0x6568,0x656a,0x656b,0x656d,0x656c,0x656e,0x6bbc,0x656f,0x6570,0x6572,0x6573,// 包匍匏咆哺圃布怖抛抱捕暴泡浦疱砲 + 0x6574,0x6575,0x6bbd,0x6577,0x6578,0x6579,0x657a,0x6bbe,0x657c,0x657e,0x657f,0x6580,0x6581,0x6bbf,0x6582,0x6583,// 胞脯苞葡蒲袍褒逋鋪飽鮑幅暴曝瀑爆 + 0x6bc0,0x6584,0x6585,0x6586,0x6587,0x6588,0x6589,0x658a,0x658b,0x658c,0x658d,0x658e,0x6bc1,0x658f,0x6bc2,0x0000,// 輻俵剽彪慓杓標漂瓢票表豹飇飄驃 + // 0xf9a0 - 0xf9ff + 0x0000,0x6591,0x6592,0x6594,0x6595,0x6596,0x6597,0x6593,0x6598,0x6599,0x659a,0x659b,0x659d,0x659e,0x6bc3,0x659f,// 品稟楓諷豊風馮彼披疲皮被避陂匹 + 0x65a0,0x65a1,0x65a2,0x6bc4,0x65a3,0x65a4,0x65a5,0x6bc5,0x6bc6,0x65a7,0x65a8,0x65a9,0x65aa,0x6bc7,0x65ab,0x65ac,// 弼必泌珌畢疋筆苾馝乏逼下何厦夏廈 + 0x65ad,0x65ae,0x65af,0x65b1,0x65b0,0x65b2,0x65b3,0x65b4,0x65b5,0x65b6,0x65b7,0x65b9,0x65ba,0x65bb,0x65bc,0x65bd,// 昰河瑕荷蝦賀遐霞鰕壑學虐謔鶴寒恨 + 0x65be,0x65bf,0x65c0,0x65c1,0x65c2,0x6bc8,0x65c3,0x65c4,0x65c7,0x65c6,0x65c8,0x65c9,0x65cb,0x65cc,0x65cd,0x65ce,// 悍旱汗漢澣瀚罕翰閑閒限韓割轄函含 + 0x65cf,0x65d0,0x65d1,0x65d2,0x65d3,0x65d4,0x65d5,0x6bc9,0x65d6,0x6bca,0x65d7,0x65d8,0x65d9,0x65da,0x65db,0x6bcb,// 咸啣喊檻涵緘艦銜陷鹹合哈盒蛤閤闔 + 0x65dc,0x65dd,0x65de,0x65df,0x6bcc,0x65e0,0x65e1,0x65e2,0x65e3,0x65e4,0x65e5,0x65e6,0x65e8,0x65e9,0x65ea,0x0000,// 陜亢伉姮嫦巷恒抗杭桁沆港缸肛航 + // 0xfaa0 - 0xfaff + 0x0000,0x6bcd,0x65eb,0x65ec,0x65ed,0x65ee,0x65ef,0x65f1,0x65f0,0x65f2,0x65f3,0x65f5,0x65f6,0x65f7,0x6bce,0x65f8,// 行降項亥偕咳垓奚孩害懈楷海瀣蟹 + 0x65f9,0x65fa,0x65fb,0x65fc,0x65fd,0x65fe,0x6641,0x6642,0x6643,0x6644,0x6645,0x6bcf,0x6646,0x6647,0x6648,0x6649,// 解該諧邂駭骸劾核倖幸杏荇行享向嚮 + 0x664b,0x664a,0x664c,0x664d,0x664e,0x664f,0x6650,0x6651,0x6652,0x6653,0x6654,0x6bd0,0x6656,0x6655,0x6657,0x6658,// 珦鄕響餉饗香噓墟虛許憲櫶獻軒歇險 + 0x6659,0x665a,0x665b,0x665c,0x665d,0x6bd1,0x665e,0x665f,0x6660,0x6bd5,0x6bd3,0x6661,0x6663,0x6bd4,0x6662,0x6664,// 驗奕爀赫革俔峴弦懸晛泫炫玄玹現眩 + 0x6bd2,0x6665,0x6666,0x6667,0x6668,0x6669,0x666a,0x666b,0x666c,0x666d,0x666e,0x666f,0x6670,0x6671,0x6672,0x6674,// 睍絃絢縣舷衒見賢鉉顯孑穴血頁嫌俠 + 0x6675,0x6676,0x6677,0x6678,0x6679,0x667a,0x667d,0x667c,0x667e,0x6680,0x6681,0x6682,0x6686,0x6683,0x6684,0x0000,// 協夾峽挾浹狹脅脇莢鋏頰亨兄刑型 + // 0xfba0 - 0xfbff + 0x0000,0x6685,0x6bd6,0x6bd7,0x6687,0x6bd8,0x6688,0x6bd9,0x6689,0x6bda,0x668a,0x668b,0x668c,0x6bdb,0x668d,0x668e,// 形泂滎瀅灐炯熒珩瑩荊螢衡逈邢鎣 + 0x668f,0x6690,0x6691,0x6692,0x6693,0x6bdc,0x6694,0x6bdd,0x6695,0x6696,0x6697,0x6698,0x669a,0x669c,0x669b,0x669d,// 馨兮彗惠慧暳蕙蹊醯鞋乎互呼壕壺好 + 0x6bde,0x669e,0x66a0,0x66b8,0x669f,0x6bdf,0x66a1,0x66a2,0x66a3,0x66a4,0x66a5,0x66a6,0x66a8,0x66a7,0x66a9,0x66aa,// 岵弧戶扈昊晧毫浩淏湖滸澔濠濩灝狐 + 0x6be0,0x66ab,0x66ac,0x66ad,0x66af,0x66b0,0x66b1,0x66b2,0x6be1,0x66b3,0x6be2,0x66b4,0x66b5,0x66b6,0x66b7,0x6699,// 琥瑚瓠皓祜糊縞胡芦葫蒿虎號蝴護豪 + 0x66ba,0x66bb,0x66bc,0x66bd,0x66be,0x66bf,0x66c0,0x66c1,0x66c2,0x66c3,0x66c4,0x66c5,0x66c6,0x66c7,0x66c8,0x66cb,// 鎬頀顥惑或酷婚昏混渾琿魂忽惚笏哄 + 0x66ca,0x66cc,0x66cd,0x66ce,0x6be3,0x66d0,0x66d1,0x66d2,0x66cf,0x66d3,0x66da,0x66d4,0x66d5,0x66d6,0x66d8,0x0000,// 弘汞泓洪烘紅虹訌鴻化和嬅樺火畵 + // 0xfca0 - 0xfcff + 0x0000,0x66d7,0x66d9,0x66db,0x66dc,0x66dd,0x6be4,0x66df,0x66de,0x66e0,0x66e1,0x66e2,0x66e3,0x66e4,0x66e5,0x66e7,// 禍禾花華話譁貨靴廓擴攫確碻穫丸 + 0x66e8,0x6be5,0x66ea,0x66eb,0x66ec,0x66ee,0x66f0,0x6be6,0x66ef,0x66f1,0x66f2,0x66f3,0x66f4,0x66f5,0x66f6,0x66f7,// 喚奐宦幻患換歡晥桓渙煥環紈還驩鰥 + 0x66f9,0x66fa,0x66fb,0x66fc,0x66fd,0x66fe,0x6be7,0x6742,0x6744,0x6746,0x6be8,0x6745,0x6747,0x6be9,0x6bea,0x6748,// 活滑猾豁闊凰幌徨恍惶愰慌晃晄榥況 + 0x6beb,0x6749,0x6bec,0x674a,0x6bed,0x674b,0x674c,0x6bee,0x674d,0x674e,0x674f,0x6750,0x6751,0x6bef,0x6752,0x6753,// 湟滉潢煌璜皇篁簧荒蝗遑隍黃匯回廻 + 0x6754,0x6755,0x6756,0x6757,0x6758,0x6759,0x675a,0x675b,0x675c,0x675d,0x675e,0x675f,0x6760,0x6bf0,0x6761,0x6762,// 徊恢悔懷晦會檜淮澮灰獪繪膾茴蛔誨 + 0x6763,0x6764,0x6765,0x6bf1,0x6766,0x6bf2,0x6767,0x6768,0x676a,0x676b,0x6bf3,0x676c,0x676d,0x6bf4,0x6bf5,0x0000,// 賄劃獲宖橫鐄哮嚆孝效斅曉梟涍淆 + // 0xfda0 - 0xfdff + 0x0000,0x676e,0x676f,0x6770,0x6bf6,0x6771,0x6772,0x6773,0x6774,0x6775,0x6776,0x6777,0x6bf7,0x6778,0x6779,0x6bf8,// 爻肴酵驍侯候厚后吼喉嗅帿後朽煦 + 0x6bf9,0x677b,0x6bfa,0x677d,0x677e,0x677f,0x6781,0x6782,0x6783,0x6784,0x6785,0x6780,0x6786,0x6787,0x6bfb,0x6bfc,// 珝逅勛勳塤壎焄熏燻薰訓暈薨喧暄煊 + 0x6788,0x6789,0x678a,0x678b,0x678c,0x678d,0x678e,0x678f,0x6790,0x6791,0x6792,0x6793,0x6794,0x6795,0x6796,0x6797,// 萱卉喙毁彙徽揮暉煇諱輝麾休携烋畦 + 0x6798,0x6799,0x679a,0x679b,0x679e,0x679c,0x679d,0x679f,0x67a0,0x67a1,0x67a3,0x67a4,0x6bfd,0x67a5,0x67a6,0x67a7,// 虧恤譎鷸兇凶匈洶胸黑昕欣炘痕吃屹 + 0x67a8,0x6bfe,0x67aa,0x67ac,0x67ab,0x67ad,0x67ae,0x67af,0x6c41,0x67b0,0x67b1,0x67bc,0x67b2,0x67b3,0x6c42,0x67b4,// 紇訖欠欽歆吸恰洽翕興僖凞喜噫囍姬 + 0x67b5,0x67b6,0x67b8,0x6c43,0x67b9,0x6c44,0x67b7,0x67bb,0x67bd,0x6c45,0x67ba,0x67be,0x67bf,0x67c0,0x67c1,0x0000,// 嬉希憙憘戱晞曦熙熹熺犧禧稀羲詰 + // 0xfea0 - 0xfeff + 0x0000,0xd4a0,0xd4a1,0xd4a2,0xd4a3,0xd4a4,0xd4a5,0xd4a6,0xd4a7,0xd4a8,0xd4a9,0xd4aa,0xd4ab,0xd4ac,0xd4ad,0xd4ae,//  + 0xd4af,0xd4b0,0xd4b1,0xd4b2,0xd4b3,0xd4b4,0xd4b5,0xd4b6,0xd4b7,0xd4b8,0xd4b9,0xd4ba,0xd4bb,0xd4bc,0xd4bd,0xd4be,//  + 0xd4bf,0xd4c0,0xd4c1,0xd4c2,0xd4c3,0xd4c4,0xd4c5,0xd4c6,0xd4c7,0xd4c8,0xd4c9,0xd4ca,0xd4cb,0xd4cc,0xd4cd,0xd4ce,//  + 0xd4cf,0xd4d0,0xd4d1,0xd4d2,0xd4d3,0xd4d4,0xd4d5,0xd4d6,0xd4d7,0xd4d8,0xd4d9,0xd4da,0xd4db,0xd4dc,0xd4dd,0xd4de,//  + 0xd4df,0xd4e0,0xd4e1,0xd4e2,0xd4e3,0xd4e4,0xd4e5,0xd4e6,0xd4e7,0xd4e8,0xd4e9,0xd4ea,0xd4eb,0xd4ec,0xd4ed,0xd4ee,//  + 0xd4ef,0xd4f0,0xd4f1,0xd4f2,0xd4f3,0xd4f4,0xd4f5,0xd4f6,0xd4f7,0xd4f8,0xd4f9,0xd4fa,0xd4fb,0xd4fc,0xd4fd,0x0000,//  + }; + + public Ksc2Ebc2() + { + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/MyLog.java b/src/main/java/com/eactive/eai/adapter/wca/util/MyLog.java new file mode 100644 index 0000000..243b102 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/MyLog.java @@ -0,0 +1,583 @@ +package com.eactive.eai.adapter.wca.util; + + +import com.eactive.eai.adapter.wca.global.WCADefine; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 1. 기능 : + * 2. 처리 개요 : + * - + * 3. 주의사항 + * - + * + * @author : Administrator + * @version : 2005. 6. 16. + * @see : + * @since : 2005. 6. 16. 오후 4:04:20 + */ +public class MyLog { + private String[] saLogLevelMsg = null; + DateUtil dateUtil = new DateUtil(); + + private void setLogLevelMsg() { + saLogLevelMsg = new String[7]; + saLogLevelMsg[0] = "DE"; + saLogLevelMsg[1] = "IN"; + saLogLevelMsg[2] = "NO"; + saLogLevelMsg[3] = "WA"; + saLogLevelMsg[4] = "ER"; + saLogLevelMsg[5] = "CR"; + saLogLevelMsg[6] = "EM"; + + return; + } + + /* Log Level 정의 */ + public static final int DEBUG = 1; + public static final int INFO = 2; + public static final int NOTICE = 3; + public static final int WARN = 4; + public static final int ERROR = 5; + public static final int ALERT = 6; + public static final int EMERGENCY = 7; + + /* Trace On/Off 정의 */ + public static final boolean TRC_ON = true; + public static final boolean TRC_ONFF = false; + + /* 현재 설정 정보 */ + private boolean bTrcFlag = true; + private int nLogLevel = 1; + + + public static final int CHECK_LOG_CNT = 1000; + + // Maximum log file size(MB) + private int MAX_LOG_FILE_SIZE = 4; + + // Default log directory name + private String DEFAULT_LOG_DIR = "C:\\app\\Log"; + + // Default log file name + private String DEFAULT_LOG_FILE = "mylog.log"; + + // If logfile is opened, true + boolean isLogFileOpen = false; + +// private String logFilePath = null; // 로그 파일의 Path를 저장할 String Object +// private File logFile = null; // 로그 파일의 Name를 저장할 File Class Object + private File logDir = null; // 로그 파일의 Directory를 저장할 File Class Object + private File logPath = null; // 로그 파일의 Path를 저장할 File Class Object + + private boolean isOK = false; // 각종 함수의 리턴값을 저장할 변수 + + // 로그 파일에 데이터를 저장할 때 사용하는 BufferedWriter Class Object + public BufferedWriter myWriter = null; + + int nLogCnt = 0; + + /** + * 메세지 및 바이너리 데이터를 파일에 로깅하기 위해 LogWrite 클래스를 생성한다.
+ * 최대 로그 파일 크기와 로그 파일 패스는 디폴트 값으로 설정된다.
+ * 메세지나 데이터를 로그 파일에 로깅하다가 로그 파일 크기가 최대 로그 파일 크기를 넘어서면 + * 현재 로그 파일을 백업하고 새로운 파일을 만들어서 계속 로깅한다. + *

+ * 디폴트 최대 로그 파일 크기 : 4M
+ * 디폴트 로그 파일 패스 : "C:\LogWrite.log" + */ + public MyLog() { + try { + nLogCnt = 0; + setLogLevelMsg(); + logDir = new File(DEFAULT_LOG_DIR); + logPath = new File(logDir, DEFAULT_LOG_FILE); + + isOK = initLogDir(logDir); + + isOK = initLogFile(logPath); + } + catch (Exception e) { + nLogCnt = 0; + } + + return; + } + + /** + * 메세지 및 바이너리 데이터를 파일에 로깅하기 위해 LogWrite 클래스를 생성한다.
+ * logFilePath에 포함되는 디렉토리가 없을 경우에는 새로 생성된다.
+ * 메세지나 데이터를 로그 파일에 로깅하다가 로그 파일 크기가 최대 로그 파일 크기를 넘어서면 + * 현재 로그 파일을 백업하고 새로운 파일을 만들어서 계속 로깅한다. + * 로그 파일 패스 파라미터는 절대 패스나 상대 패스를 모두 지원한다. + * @param nMaxLogFileSize 로그 파일 최대 크기 + * @param logFilePath 로그 파일 패스(예 : "C:\kab@iTeller\Log\LogWrite.log" or "Log\LogWrite.log" or "LogWrite.Log") + */ + public MyLog(boolean bLogYN, int nLogLevel, int nMaxLogFileSize, String logFilePath) { + try { + nLogCnt = 0; + setLogLevelMsg(); + this.setTraceOnOff(bLogYN); + this.setLogLevel(nLogLevel); + + MAX_LOG_FILE_SIZE = nMaxLogFileSize; + File tempLogPath = new File(logFilePath); + + logPath = new File(tempLogPath.getAbsolutePath()); + logDir = new File(logPath.getParent()); + + isOK = initLogDir(logDir); + + isOK = initLogFile(logPath); + } + catch (Exception e) { + nLogCnt = 0; + } + + return; + } + // 현재 사용되는 로그 파일의 크기가 로그 파일 최대 크기를 넘었는지 + // 검사하고, 넘었을 경우에 기존의 로그 파일을 백업하고, 새로운 + // 로그 파일을 생성한다. + private void checkLogFileSize() { + File backupLogPath = null; + + try { + isOK = isOverMaxFileSize(logPath); + if (!isOK) { + return; + } + + backupLogPath = new File(logPath.toString() + "-"); + if (backupLogPath.exists()) { + backupLogPath.delete(); + } + + myWriter.close(); + myWriter = null; + + isLogFileOpen = false; + + // 기존에 파일이 이미 있으면 Fail + logPath.renameTo(backupLogPath); + + logPath.createNewFile(); + + openLogStream(logPath); + } + catch (Exception e) { + return; + } + } + + /** + * 버퍼에 들어있는 내용을 로그파일에 기록하고 로그 파일을 닫는다. + */ + protected void finalize() { + try { + if (isLogFileOpen) { + if (myWriter != null) { + myWriter.close(); + myWriter = null; + } + } + } + catch(Exception e) { + return; + } + } + + /** + * 현재 사둉되는 로그 파일의 절대 패스를 리턴 + * @return 로그 파일의 절대 패스 + */ + public String getLogFilePath() { + return logPath.toString(); + } + + /** + * 현재 사용되는 로그 파일의 최대 크기를 리턴(단위 : MB) + * @return 로그 파일 최대 크기 + */ + public int getMaxLogFileSize() { + return MAX_LOG_FILE_SIZE; + } + + public void setMaxLogFileSize(int nMaxLogFileSize) { + MAX_LOG_FILE_SIZE = nMaxLogFileSize; + } + + // 로그 파일이 저장될 디렉토리를 초기화 + private boolean initLogDir(File logDir) { + try { + return logDir.mkdirs(); + } + catch (Exception e) { + return false; + } + } + + // 바이너리 데이터및 메세리를 로깅하기 위해서 사용되는 + // 로그 파일 및 관련 클래스 초기화 + private boolean initLogFile(File logPath) { + File backupLogPath = null; + + try { + if (logPath.exists()) { + /* + isOK = isOverMaxFileSize(logPath); + if (isOK) { + backupLogPath = new File(logPath.toString() + "-"); + if (backupLogPath.exists()) { + backupLogPath.delete(); + } + + // 기존에 파일이 이미 있으면 Fail + logPath.renameTo(backupLogPath); + } + */ + backupLogPath = new File(logPath.toString() + "-"); + if (backupLogPath.exists()) { + backupLogPath.delete(); + } + + // 기존에 파일이 이미 있으면 Fail + logPath.renameTo(backupLogPath); + logPath.createNewFile(); + } + else { + logPath.createNewFile(); + } + + openLogStream(logPath); + } + catch(Exception e) { + return false; + } + + return true; + } + + // 현재 사용되는 로그 파일의 크기가 로그 파일 최대 크기를 넘는지 검사 + private boolean isOverMaxFileSize(File logPath) { + try { + // Throw SecurityException + if (logPath.length() > (1024 * 1024 * MAX_LOG_FILE_SIZE)) { + return true; + } + else { + return false; + } + } + catch (Exception e) { + return false; + } + } + + /** + * 바이너리 데이터를 로그 파일에 로깅 + * @param cFlag bDataBuff 파라미터에 들어있는 데이터의 문자 코드 + * @param nDataLen bDataBuff 파라미터에 들어있는 데이터 길이 + * @param bDataBuff 로깅할 바이너리 데이터가 들어있는 바이트 어레이 + */ + // 20030804 hslee 화면번호 Parameter 추가 + public void logData(char cFlag, int nDataLen, byte[] bDataBuff) { + + int i, j; + int end_flag; // 출력할 라인 수 + int rem_flag; // 맨 마지막줄의 출력할 데이터 길이 + int nRemainDataLen = 0; + byte[] tempData = null; + int tempLen = 0; + + if (bTrcFlag == false) { + return; + } + + if (!isLogFileOpen) { + return; + } + + tempData = new byte[16]; + + try { + checkLogFileSize(); + + // 파일이 존재하지 않으면 생성 + createNewFile(); + + if (myWriter == null) { return; } + + myWriter.write("\r\n====================================================================\r\n"); + + // Format the current time. + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd=HH:mm:ss.SSS"); + String dateString = formatter.format(ZonedDateTime.now()); + + myWriter.write(dateString + " : " + "Data Length = " + nDataLen + "\r\n"); + + // 출력할 라인 수 계산 + end_flag = nDataLen / 16; + if ((nDataLen % 16) != 0) { + end_flag++; + } + + // 맨 마지막줄의 출력할 데이터 길이 계산 + rem_flag = nDataLen - (16 * (end_flag - 1)); + + nRemainDataLen = nDataLen; + + // 매 라인마다 인쇄루틴 For 루프 + for (i = 0; i < end_flag; i++) { + int nTempLen = i * 16; + + // 데이터 수를 문자열로 변환 + String strLength = Integer.toString(nTempLen); + int strLen = strLength.length(); + + strLen = 6 - strLen; + + for (int x = 0; x < strLen; x++) { + myWriter.write("0"); + } + + myWriter.write(strLength); + + // 넘겨받은 데이터에서 16바이씩 잘라서 복사 + // Bug!!! + if (nRemainDataLen > 16) { + MyUtil.memcpy(tempData, bDataBuff, 0, i * 16, 16); + tempLen = 16; + nRemainDataLen -= 16; + } + else { + MyUtil.memcpy(tempData, bDataBuff, 0, i * 16, nRemainDataLen); + tempLen = nRemainDataLen; + } + + for (j = 0; j < 16; j++) { + if ((j % 4) == 0) { + myWriter.write(" "); + } + + // 인쇄할 라인이 마지막 라인이 아니거나 + // 인쇄할 데이터 위치가 마지막 바이트가 아닐 경우 + if ((i != (end_flag - 1)) || (j < rem_flag)) { + myWriter.write(MyUtil.toHex3(tempData[j])); + } + else { + myWriter.write(" "); + } + } + + myWriter.write(" |"); + + // 라인별로 데이터에 해당하는 문자열 인쇄 + for (j = 0; j < 16; j++) { + // 인쇄할 라인이 마지막 라인이 아니거나 + // 인쇄할 데이터 위치가 마지막 바이트가 아닐 경우 + if ((i != end_flag - 1) || (j < rem_flag)) { + // cFlag값은 'a'값(ASCII)일 경우, ASCII 문자로 인쇄 + if (cFlag == WCADefine.ASCII_CODE) { + // 데이터가 인쇄할 수 있는 범위안에 있으면, + // Character형으로 인쇄하고, 아니면 "." 문자로 대체하여 인쇄 + if ((tempData[j] > 0x1f) && (tempData[j] < 0x7e)) { + myWriter.write(tempData[j]); + } + else { + myWriter.write("."); + } + } + // cFlag값은 'e'값(EBCDIC)일 경우, EBCDIC 문자를 변환하여 인쇄 + else if (cFlag == WCADefine.EBCDIC_CODE) { + byte xx = CodeCvrt.cvrtEbc2Ksc2(tempData[j]); + if ((xx <= 0x1f) || (xx >= 0x7e)) { + myWriter.write("."); + } + else { + myWriter.write(xx); + } + } + } + // 인쇄할 마지막 라인의 마지막 데이터를 넘겼을 경우,공백으로 인쇄 + else { + myWriter.write(" "); + } + } + + // 구분선 인쇄 + myWriter.write("|\r\n"); + } + + myWriter.write("====================================================================\r\n\r\n"); + myWriter.flush(); + + return; + } + catch (Exception e) { + return; + } + } + + private void createNewFile() + { + /* + try { + if (!logPath.exists()) { + logPath.createNewFile(); + openLogStream(logPath); + } + } + catch(Exception e) { } + */ + } + + /** + * 메세지를 로그 파일에 기록(시간 정보가 포함됨) + * @param logMsg 로그 파일에 기록할 메세지 + */ + public void logMsg(String logMsg) { + if (!isLogFileOpen) { + return; + } + + try { + // 파일이 존재하지 않으면 생성 + createNewFile(); + + if (myWriter == null) { return; } + + // Format the current time. + + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd=HH:mm:ss.SSS"); + String dateString = formatter.format(ZonedDateTime.now()); + + myWriter.write(dateString + " : " + logMsg + "\r\n"); + myWriter.flush(); + } + catch (Exception e) { + return; + } + } + + /** + * 메세지를 로그 파일에 기록(시간 정보가 포함됨) + * @param logMsg 로그 파일에 기록할 메세지 + */ + public void logMsg(int nLogLevel, String logMsg) { + if ((nLogLevel < this.nLogLevel) || (nLogLevel > EMERGENCY)) { + return; + } + + if (!isLogFileOpen) { + return; + } + + nLogCnt++; + if (nLogCnt > CHECK_LOG_CNT) { + nLogCnt = 0; + checkLogFileSize(); + } + + try { + // 파일이 존재하지 않으면 생성 + createNewFile(); + + if (myWriter == null) { return; } + + // Format the current time + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd=HH:mm:ss.SSS"); + String dateString = formatter.format(ZonedDateTime.now()); + + myWriter.write("[" + saLogLevelMsg[nLogLevel - 1] + "] " + dateString + " : " + logMsg + "\r\n"); + myWriter.flush(); + } + catch (Exception e) { + return; + } + } + + /** + * 메세지를 로그 파일에 기록(시간 정보가 포함되지 않음) + * @param logMsg 로그 파일에 기록할 메세지 + */ + public void logMsg2(String logMsg) { + if (!isLogFileOpen) { + return; + } + + try { + // 파일이 존재하지 않으면 생성 + createNewFile(); + + if (myWriter == null) { return; } + + myWriter.write(logMsg + "\r\n"); + myWriter.flush(); + } + catch (Exception e) { + return; + } + } + + // 로그 파일과 연결된 BufferedWriter 클래스 오브젝트 생성 + private void openLogStream(File logPath) { + try { + if (isLogFileOpen) { + if (myWriter != null) { + myWriter.close(); + myWriter = null; + } + + isLogFileOpen = false; + } + + myWriter = new BufferedWriter(new FileWriter(logPath.toString(), true)); + isLogFileOpen = true; + + logMsg("TRACE ON/OFF = " + bTrcFlag); + logMsg("LOG LEVLE = " + nLogLevel + ", LOG SIZE = " + MAX_LOG_FILE_SIZE + "M"); + } + catch (Exception e) { + System.out.println("openLogStream error -"+e.toString()); + } + } + + public void closeLogStream() { + try { + if (isLogFileOpen) { + isLogFileOpen = false; + if (myWriter != null) { + myWriter.close(); + myWriter = null; + } + } + } + catch (Exception e) { + System.out.println("closeLogStream error -"+e.toString()); + } + } + + public void setTraceOnOff(boolean bOnOff) { + bTrcFlag = bOnOff; + return; + } + + public boolean getTraceOnOff() { + return bTrcFlag; + } + + public void setLogLevel(int nLogLevel) { + this.nLogLevel = nLogLevel; + return; + } + + public int getLogLevel() { + return nLogLevel; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/MyUtil.java b/src/main/java/com/eactive/eai/adapter/wca/util/MyUtil.java new file mode 100644 index 0000000..b40807d --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/MyUtil.java @@ -0,0 +1,444 @@ +package com.eactive.eai.adapter.wca.util; + +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.common.server.EAIServerManager; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; + +/** + * 1. 기능 : + * 2. 처리 개요 : + * - + * 3. 주의사항 + * - + * + * @author : Administrator + * @version : 2005. 6. 20. + * @see : + * @since : 2005. 6. 20. 오후 1:40:39 + */ +public class MyUtil { + + public synchronized static String rightPadString(String inputStr, int nDataLen, String pasStr) { + StringBuffer returnStrBuff = new StringBuffer(); +// int nInputStrLen = inputStr.length(); + + returnStrBuff.append(inputStr); + for(int i = 0; i < (nDataLen - inputStr.length()); i++) + { + returnStrBuff.append(pasStr); + } + + return returnStrBuff.toString(); + } + + public static String leftPadString(String src, int cnt, String padStr) { + String tmpValue = ""; + + src = src.trim(); + + for (int i = 0; i < (cnt - src.length()); i++) { + tmpValue += padStr; + + } + return tmpValue + src; + } + // dataLen에 해당하는 길이 필드 byte 어레이를 조립하여 리턴 + public synchronized static byte[] getLenBuff(int nDataLen, int nBuffLen) + { + StringBuffer lenBuff = new StringBuffer(); + String tempDataLenStr = String.valueOf(nDataLen); + + for(int i = 0; i < (nBuffLen - tempDataLenStr.length()); i++) + { + lenBuff.append("0"); + } + + lenBuff.append(String.valueOf(nDataLen)); + + return lenBuff.toString().getBytes(); + } + + /** + * str에서 rep에 해당하는 String을 tok로 replace한다. + * + * @param str 문자열 + * @param rep 찾는 문자열 + * @param tok 변환할 문자열 + * @return String 변환된 문자열 + */ + public static String replaceString(String str, String rep, String tok) { + String retStr = ""; + + if (str == null || "".equals(str)) { + return ""; + } + + for (int i = 0, j = 0; (j = str.indexOf(rep, i)) > -1; i = j + rep.length()) { + retStr += (str.substring(i, j) + tok); + } + return (str.indexOf(rep) == -1) ? str : + retStr + str.substring(str.lastIndexOf(rep) + rep.length(), str.length()); + } + + + /** + * 년월일 변환(yyyy/MM/dd) + * + * @param s_chkValue 변환할 문자열 + * @return 변환된 문자열 + */ + public static String formatDate(String s_chkValue) + { + String s_rtnValue = ""; + String s_tmpValue = ""; + + if (s_chkValue == null) { + return ""; + } + + s_tmpValue = s_chkValue.trim(); + + if (s_tmpValue.equals("")) { + return ""; + } + + if (s_tmpValue.length() == 8 || s_tmpValue.length() == 12 || + s_tmpValue.length() == 14) { + s_rtnValue = s_tmpValue.substring(0, 4) + "/" + s_tmpValue.substring(4, 6) + + "/" + + s_tmpValue.substring(6, 8); + return s_rtnValue.trim(); + } + + return s_tmpValue; + } + + /** + * 년월일 변환(yyyy.MM.dd) + * + * @param s_chkValue 변환할 문자열 + * @return 변환된 문자열 + */ + public String formatDateD(String s_chkValue) + { + String s_rtnValue = ""; + String s_tmpValue = ""; + + if (s_chkValue == null) { + return ""; + } + + s_tmpValue = s_chkValue.trim(); + + if (s_tmpValue.equals("")) { + return ""; + } + + if (s_tmpValue.length() == 8 || s_tmpValue.length() == 12 || + s_tmpValue.length() == 14) { + s_rtnValue = s_tmpValue.substring(0, 4) + "." + s_tmpValue.substring(4, 6) + + "." + + s_tmpValue.substring(6, 8); + return s_rtnValue.trim(); + } + + return s_tmpValue; + } + + public static String formatTime(String s_chkValue) + { + String s_rtnValue = ""; + String s_tmpValue = ""; + + if (s_chkValue == null) { + return ""; + } + + s_tmpValue = s_chkValue.trim(); + + if (s_tmpValue.equals("")) { + return ""; + } + + if (s_tmpValue.length() == 6) { + s_rtnValue = s_tmpValue.substring(0, 2) + ":" + s_tmpValue.substring(2, 4) + + ":" + s_tmpValue.substring(4, 6); + return s_rtnValue.trim(); + } + + return s_tmpValue; + } + + public static String formatMilliTime(String s_chkValue) + { + String s_rtnValue = ""; + String s_tmpValue = ""; + + if (s_chkValue == null) { + return ""; + } + + s_tmpValue = s_chkValue.trim(); + + if (s_tmpValue.equals("")) { + return ""; + } + + if (s_tmpValue.length() == 8) { + s_rtnValue = s_tmpValue.substring(0, 2) + ":" + s_tmpValue.substring(2, 4) + + ":" + s_tmpValue.substring(4, 6) + "." + s_tmpValue.substring(6, 8); + return s_rtnValue.trim(); + } + + return s_tmpValue; + } + + // 바이트값을 헥사 스트링으로 변환할때 자리수를 맞추기 위해 "0"을 패딩 + public static String pad0(String str, int size) + { + char[] zeros = new char[size - str.length()]; + + for(int i = 0; i < zeros.length; i++ ) + { + zeros[i] = '0'; + } + + return new String(zeros) + str; + } + + // 바이트값을 헥사 스트링으로 변환 + public static String toHex(byte[] codes) + { + if(codes.length == 0) + return ""; + + String hex = pad0(Integer.toHexString(codes[0] & 0xff), 2); + + for( int i = 1; i < codes.length; i++ ) + hex += " " + pad0( Integer.toHexString(codes[i] & 0xff), 2); + return hex; + } + + // 바이트값을 헥사 스트링으로 변환 + public static String toHex3(byte codes) + { + String hex = pad0(Integer.toHexString(codes & 0xff), 2); + return hex; + } + + // 바이트 어레이를 복사 + public static void memcpy(byte[] dst, byte[] src, int a, int b, int len) + { + for(int i = 0; i < len; i++) + { + dst[i + a] = src[i + b]; + } + } + + /** + * 1. 기능 : 호스트 이름이 같은지 판단 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param sHostName 호스트 이름 + * @return 로컬 호스트 여부 (true/false) + **/ + public static boolean isLocalHostName(String sHostName) + { + try{ + String sLocalHostName = EAIServerManager.getInstance().getLocalServerHostName(); + if (sHostName.equals(sLocalHostName)) + return true; + else + return false; + }catch (Exception e){ +// System.out.println("isLocalHostName error - " + sHostName); + return false; + } + } + + public static String printBytes(char cFlag, int nDataLen, byte[] bDataBuff) + { + int i, j; + int end_flag; // 출력할 라인 수 + int rem_flag; // 맨 마지막줄의 출력할 데이터 길이 + int nRemainDataLen = 0; + byte[] tempData = null; + int tempLen = 0; + + StringBuffer sb_print = new StringBuffer(); + + tempData = new byte[16]; + + try { + + + sb_print.append("\r\n====================================================================\r\n"); + + // Format the current time. + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy.MM.dd=hh:mm:ss"); + String dateString = formatter.format(ZonedDateTime.now()); + + + sb_print.append(dateString + " : " + "Data Length = " + nDataLen + "\r\n"); + + // 출력할 라인 수 계산 + end_flag = nDataLen / 16; + if((nDataLen % 16) != 0) + { + end_flag++; + } + + // 맨 마지막줄의 출력할 데이터 길이 계산 + rem_flag = nDataLen - (16 * (end_flag - 1)); + + nRemainDataLen = nDataLen; + + // 매 라인마다 인쇄루틴 For 루프 + for(i = 0; i < end_flag; i++) + { + int nTempLen = i * 16; + + // 데이터 수를 문자열로 변환 + String strLength = Integer.toString(nTempLen); + int strLen = strLength.length(); + + strLen = 6 - strLen; + + for(int x = 0; x < strLen; x++) + sb_print.append("0"); + + sb_print.append(strLength); + + // 넘겨받은 데이터에서 16바이씩 잘라서 복사 + // Bug!!! + if(nRemainDataLen > 16) + { + memcpy(tempData, bDataBuff, 0, i * 16, 16); + tempLen = 16; + nRemainDataLen -= 16; + } + else + { + memcpy(tempData, bDataBuff, 0, i * 16, nRemainDataLen); + tempLen = nRemainDataLen; + } + + for(j = 0; j < 16; j++) + { + if((j % 4) == 0) + { + sb_print.append(" "); + } + + // 인쇄할 라인이 마지막 라인이 아니거나 + // 인쇄할 데이터 위치가 마지막 바이트가 아닐 경우 + if((i != (end_flag - 1)) || (j < rem_flag)) + { + sb_print.append(toHex3(tempData[j])); + } + else + { + sb_print.append(" "); + } + } + + sb_print.append(" |"); + + // 라인별로 데이터에 해당하는 문자열 인쇄 + for(j = 0; j < 16; j++) + { + // 인쇄할 라인이 마지막 라인이 아니거나 + // 인쇄할 데이터 위치가 마지막 바이트가 아닐 경우 + if((i != end_flag - 1) || (j < rem_flag)) + { + // cFlag값은 'a'값(ASCII)일 경우, ASCII 문자로 인쇄 + if(cFlag == WCADefine.ASCII_CODE) + { + // 데이터가 인쇄할 수 있는 범위안에 있으면, + // Character형으로 인쇄하고, 아니면 "." 문자로 대체하여 인쇄 + if((tempData[j] > 0x1f) && (tempData[j] < 0x7e)) + { + sb_print.append(tempData[j]); + } + else + { + sb_print.append("."); + } + } + // cFlag값은 'e'값(EBCDIC)일 경우, EBCDIC 문자를 변환하여 인쇄 + else if(cFlag == WCADefine.EBCDIC_CODE) + { + byte xx = CodeCvrt.cvrtEbc2Ksc2(tempData[j]); + if((xx <= 0x1f) || (xx >= 0x7e)) + sb_print.append("."); + else + sb_print.append(xx); + } + } + // 인쇄할 마지막 라인의 마지막 데이터를 넘겼을 경우,공백으로 인쇄 + else + { + sb_print.append(" "); + } + } + + // 구분선 인쇄 + sb_print.append("|\r\n"); + } + + sb_print.append("====================================================================\r\n\r\n"); + + return sb_print.toString(); + } + catch(Exception e) + { + return ""; + } + } + + // 20090810 Start + /** + * s_data를 s_delim 으로 파싱하여 ArrayList에 저장 + */ + public static ArrayList stringTokenizer(String s_data, String s_delim) + { + int i_pos = 0; + int i_strt = 0; + ArrayList al_token = new ArrayList(); + String s_temp_str = null; + + if(s_data.equals("")) + return null; + + for(i_strt = 0; i_strt < s_data.length(); ) + { + if ( (i_pos += s_data.substring(i_strt).indexOf(s_delim)) > 0 ) //s_delim 위치 값 구하기 + { + if (i_strt > i_pos) break;// overflow + + + s_temp_str = s_data.substring(i_strt, i_pos); + if (s_temp_str == null) s_temp_str = ""; + + al_token.add(s_temp_str); + + i_pos += s_delim.length(); + i_strt = i_pos ; + } + else + break; + } + + // 구분자가 끝에 없을 경우 + s_temp_str = s_data.substring(i_strt); + if(s_temp_str != null && !s_temp_str.equals("")) + al_token.add(s_temp_str); + + return al_token; + } + // 20090810 End +} diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/RuntimeUtil.java b/src/main/java/com/eactive/eai/adapter/wca/util/RuntimeUtil.java new file mode 100644 index 0000000..7fa7f3b --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/RuntimeUtil.java @@ -0,0 +1,387 @@ +package com.eactive.eai.adapter.wca.util; + +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.servlet.TableInfoEx; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; + +import java.io.BufferedReader; +import java.io.IOException; + +/** + * 1. 기능 : 프로세스를 생성하여 명령어 실행 + * 2. 처리 개요 : + * - 독립적인 프로세스로 명령어를 실행한다. + * 3. 주의사항 + * + * @author : + * @version : + * @see : + * @since : + */ +public class RuntimeUtil +{ + /** + * RuntimeUtil Single Instance + */ + static RuntimeUtil instance = new RuntimeUtil(); + + Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + /** + * 1. 기능 : RuntimeUtil Singleton Object 반환 + * 2. 처리 개요 : RuntimeUtil Singleton Object 반환한다. + * 3. 주의사항 + * + * @return RuntimeUtil Singleton object + **/ + public static RuntimeUtil getInstance(){ + return instance; + } + + /** + * 1. 기능 : Softman과 command 전송을 위해 프로세스를 생성하여 command를 실행 + * 2. 처리 개요 : + * - 파라미터로 받은 명령어를 실행한다. + * - 실행결과가 "정상"이 아닐경우만 결과를 반환한다. + * --> 호출하고 실행결과는 받지 않도록 수정. + * 3. 주의사항 + * + * @param shell 명령어 + * @return 실행 결과 + **/ + public String runTimeProcEx(String shell) throws IOException + { + StringBuffer sbResult = new StringBuffer(); + BufferedReader br = null; + BufferedReader errBr = null; +// String sResultData; + + Runtime rt = Runtime.getRuntime(); + Process o_process = null; + + try { + o_process = rt.exec(shell); + rt.runFinalization(); + return sbResult.toString(); + } + catch(IOException e) + { +// System.out.println("runTimeProcEx> Exception Msg = " + e.toString()); +// e.printStackTrace(); + throw e; + } + /* + catch(java.lang.InterruptedException i) + { + throw new WCAException(WCAException.E_PROCESS_CALL, i.toString()); + } + */ + finally { + try { + if (br != null) br.close(); + if (errBr != null) errBr.close(); + //if (o_process != null) o_process.destroy(); + } catch(Exception e) {} + } + } + + /** + * 1. 기능 : Softman과 command 전송을 위해 프로세스를 생성하여 command를 실행 + * 2. 처리 개요 : + * - 파라미터로 받은 명령어를 실행한다. + * - 실행결과가 "정상"이 아닐경우만 결과를 반환한다. + * --> 호출하고 실행결과는 받지 않도록 수정. + * 3. 주의사항 + * + * @param shell 명령어 + * @return 실행 결과 + **/ + public String runTimeProc(String shell) throws WCAException + { + StringBuffer sbResult = new StringBuffer(); + BufferedReader br = null; + BufferedReader errBr = null; +// String sResultData; + + Runtime rt = Runtime.getRuntime(); + Process o_process = null; + + try { + o_process = rt.exec(shell); + /* (2005/12/01) + * 호출만하고 실행결과는 받지 않도록 수정 + * (softman에서 다른 프로세스를 fork 시키므로 결과 return 안함) + */ + /* + errBr = new BufferedReader(new InputStreamReader(o_process.getErrorStream())); + while (errBr.ready()) + { + sResultData = errBr.readLine(); + if(trc_logger.isDebug()) trc_logger.debug("error recv data : " + sResultData); + sbResult.append(sResultData + "\n"); + } + int exitVal = o_process.waitFor(); + if(trc_logger.isDebug()) trc_logger.debug("Process Exit Value : " + exitVal); + if (exitVal == 0) + { + br = new BufferedReader(new InputStreamReader(o_process.getInputStream())); + while((sResultData = br.readLine()) != null) + { + if (!sResultData.trim().equals("")) + { + if(trc_logger.isDebug()) trc_logger.debug("recv data : " + sResultData); + if(sResultData.indexOf("정상") == -1) // 정상처리가 아닌경우 + sbResult.append(sResultData + "\n"); + } + } + } + */ + rt.runFinalization(); + return sbResult.toString(); + } + catch(IOException e) + { + throw new WCAException(WCAException.E_PROCESS_CALL, e.toString()); + } + /* + catch(java.lang.InterruptedException i) + { + throw new WCAException(WCAException.E_PROCESS_CALL, i.toString()); + } + */ + finally { + try { + if (br != null) br.close(); + if (errBr != null) errBr.close(); + //if (o_process != null) o_process.destroy(); + } catch(Exception e) {} + } + } + + // 20080612 Start + /** + * 1. 기능 : 특정 노드의 Softlink 전체 설정 정보 디시 로드 + * 2. 처리 개요 : + * - 프로퍼티 정보에서 softlink 홈디렉토리 get하여 명령어 수행 (SnaUpdateCfg -a) + * - 에러 발생시 그 메세지를 exception으로 발생시킨다. + * 3. 주의사항 + * + * @exception WCAException + **/ + public void notifyAllSoftlink(String sSoftlinkHome, String sIP) throws IOException + { + try { + StringBuffer sbCommand = new StringBuffer(); + + // String sSoftlinkHome = PropManager.getInstance().getProperty(TableInfo.T_SNAADPTER_PROP_GROUP_NAME, "softlink.home"); + + sbCommand.append(sSoftlinkHome + "/bin" + WCADefine.SOFTLINK_CFG_UPDATE_COMMAND + " -a -host " + sIP); + + // if(trc_logger.isInfo()) trc_logger.info(sbCommand.toString() + " is excuting"); +// System.out.println("notifyAllSoftlink> Command = " + sbCommand.toString()); + runTimeProcEx(sbCommand.toString()); + } + catch(IOException e) { +// System.out.println("notifyAllSoftlink> Exception Msg = " + e.toString()); +// e.printStackTrace(); + throw e; + } + } + // 20080612 End + + // 20080827 Start + /** + * 1. 기능 : 특정 노드의 Softlink 전체 설정 정보 디시 로드 + * 2. 처리 개요 : + * - 프로퍼티 정보에서 softlink 홈디렉토리 get하여 명령어 수행 (SnaUpdateCfg -a) + * - 에러 발생시 그 메세지를 exception으로 발생시킨다. + * 3. 주의사항 + * + * @exception WCAException + **/ + public void notifyAllSoftlink(String sSoftlinkHome, String sIP, String sAdapterGroupName, String sLuGroupName) throws IOException + { + try { + StringBuffer sbCommand = new StringBuffer(); + + // String sSoftlinkHome = PropManager.getInstance().getProperty(TableInfo.T_SNAADPTER_PROP_GROUP_NAME, "softlink.home"); + + sbCommand.append(sSoftlinkHome + "/bin" + WCADefine.SOFTLINK_CFG_UPDATE_COMMAND + " -t " + sAdapterGroupName + " -g " + sLuGroupName + " -host " + sIP); + + // if(trc_logger.isInfo()) trc_logger.info(sbCommand.toString() + " is excuting"); +// System.out.println("notifyAllSoftlink> Command = " + sbCommand.toString()); + runTimeProcEx(sbCommand.toString()); + } + catch(IOException e) { +// System.out.println("notifyAllSoftlink> Exception Msg = " + e.toString()); + throw e; + } + } + // 20080827 End + + + /** + * 1. 기능 : Softlink 전체 설정 정보 디시 로드 + * 2. 처리 개요 : + * - 프로퍼티 정보에서 softlink 홈디렉토리 get하여 명령어 수행 (SnaUpdateCfg -a) + * - 에러 발생시 그 메세지를 exception으로 발생시킨다. + * 3. 주의사항 + * + * @exception WCAException + **/ + public void notifyAllSoftlink() throws WCAException + { + String sResult; + + try + { + StringBuffer sbCommand = new StringBuffer(); + String sSoftlinkHome = PropManager.getInstance().getProperty(TableInfoEx.T_SNAADPTER_PROP_GROUP_NAME, "softlink.home"); + + sbCommand.append(sSoftlinkHome + "/bin" + WCADefine.SOFTLINK_CFG_UPDATE_COMMAND + " -a"); + + if(trc_logger.isInfo()) trc_logger.info(sbCommand.toString() + " is excuting"); + sResult = runTimeProc(sbCommand.toString()); + if(trc_logger.isDebug()) trc_logger.debug(sResult); + } + catch(WCAException e) + { + //e.printStackTrace(); + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + throw exception; + } + + if (sResult.length()>0) // 정상이 아닐경우 + { + WCAException exception = new WCAException(); + exception.setMessage(sResult); + throw exception; + } + } + + /** + * 1. 기능 : Softlink 해당 그룹에 설정 정보 디시 로드 + * 2. 처리 개요 : + * - 프로퍼티 정보에서 softlink 홈디렉토리 get하여 명령어 수행 + * (SnaUpdateCfg -a -t 어댑터 그룹 이름 -g LU 그룹 이름) + * - 에러 발생시 그 메세지를 exception으로 발생시킨다. + * 3. 주의사항 + * + * @param sAdapterGrpName 어댑터 그룹 이름 + * @param sGroupCode LU 그룹 이름 + * @exception WCAException + **/ + public void notifySoftlink(String sAdapterGrpName, String sGroupCode) throws WCAException + { + String sResult; + + try + { + StringBuffer sbCommand = new StringBuffer(); + String sSoftlinkHome = PropManager.getInstance().getProperty(TableInfoEx.T_SNAADPTER_PROP_GROUP_NAME, "softlink.home"); + + sbCommand.append(sSoftlinkHome + "/bin" + WCADefine.SOFTLINK_CFG_UPDATE_COMMAND) + .append(" -t " + sAdapterGrpName + " -g " + sGroupCode); + if(trc_logger.isInfo()) trc_logger.info(sbCommand.toString() + " is excuting"); + sResult = runTimeProc(sbCommand.toString()); + if(trc_logger.isDebug()) trc_logger.debug(sResult); + } + catch(WCAException e) + { + //e.printStackTrace(); + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + throw exception; + } + + if (sResult.length()>0) // 정상이 아닐경우 + { + WCAException exception = new WCAException(); + exception.setMessage(sResult); + throw exception; + } + } + + /** + * 1. 기능 : Softlink 시작 + * 2. 처리 개요 : + * - 프로퍼티 정보에서 softlink 홈디렉토리 get하여 명령어 수행 + * (SnaStart -a) + * - 에러 발생시 그 메세지를 exception으로 발생시킨다. + * 3. 주의사항 + * + * @exception WCAException + **/ + public void startSoftlink() throws WCAException + { + String sResult; + + try + { + StringBuffer sbCommand = new StringBuffer(); + String sSoftlinkHome = PropManager.getInstance().getProperty(TableInfoEx.T_SNAADPTER_PROP_GROUP_NAME, "softlink.home"); + + sbCommand.append(sSoftlinkHome + "/bin" + WCADefine.SOFTLINK_START_COMMAND); + if(trc_logger.isInfo()) trc_logger.info(sbCommand.toString() + " is excuting"); + sResult = runTimeProc(sbCommand.toString()); + if(trc_logger.isDebug()) trc_logger.debug(sResult); + } + catch(WCAException e) + { + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + throw exception; + } + + if (sResult.length()>0) // 정상이 아닐경우 + { + WCAException exception = new WCAException(); + exception.setMessage(sResult); + throw exception; + } + } + + /** + * 1. 기능 : Softlink 종료 + * 2. 처리 개요 : + * - 프로퍼티 정보에서 softlink 홈디렉토리 get하여 명령어 수행 + * (SnaStop -a) + * - 에러 발생시 그 메세지를 exception으로 발생시킨다. + * 3. 주의사항 + * + * @exception WCAException + **/ + public void stopSoftlink() throws WCAException + { + String sResult; + + try + { + StringBuffer sbCommand = new StringBuffer(); + String sSoftlinkHome = PropManager.getInstance().getProperty(TableInfoEx.T_SNAADPTER_PROP_GROUP_NAME, "softlink.home"); + + sbCommand.append(sSoftlinkHome + "/bin" + WCADefine.SOFTLINK_STOP_COMMAND + " -a "); + if(trc_logger.isInfo()) trc_logger.info(sbCommand.toString() + " is excuting"); + sResult = runTimeProc(sbCommand.toString()); + if(trc_logger.isDebug()) trc_logger.debug(sResult); + } + catch(WCAException e) + { + //e.printStackTrace(); + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + throw exception; + } + + if (sResult.length()>0) // 정상이 아닐경우 + { + WCAException exception = new WCAException(); + exception.setMessage(sResult); + throw exception; + } + } +} + diff --git a/src/main/java/com/eactive/eai/adapter/wca/util/SNAAgentUtil.java b/src/main/java/com/eactive/eai/adapter/wca/util/SNAAgentUtil.java new file mode 100644 index 0000000..9f334dc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/wca/util/SNAAgentUtil.java @@ -0,0 +1,431 @@ +package com.eactive.eai.adapter.wca.util; + +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.adapter.wca.global.WCADefine; +import com.eactive.eai.adapter.wca.jdbc.CommonJDBC; +import com.eactive.eai.adapter.wca.jdbc.JDBCFactory; +import com.eactive.eai.adapter.wca.jdbc.SQLData; +import com.eactive.eai.adapter.wca.servlet.TableInfoEx; +import com.eactive.eai.common.util.Logger; + +import java.util.HashMap; +import java.util.Iterator; + +public class SNAAgentUtil { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static Logger trc_logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + /** + * SNAAdapter critical한 정보 로깅을 위한 logger + */ + static Logger adapter_logger = Logger.getLogger(WCADefine.ADAPTER_LOGGER_NAME); + + /** + * 1. 기능 : Softlink 전체 설정 정보 디시 로드 + * 2. 처리 개요 : + * - 프로퍼티 정보에서 softlink 홈디렉토리 get하여 명령어 수행 (SnaUpdateCfg -a) + * - 에러 발생시 그 메세지를 exception으로 발생시킨다. + * 3. 주의사항 + * + * @exception WCAException + **/ + public static void notifyAllSoftlinkNode() throws WCAException + { +// String sResult; + HashMap nodes = null; + String sSoftLinkHome = null; + try + { + nodes = getAllSoftlinkNodeInfo(); + if(nodes == null) { + logger.info("notifyAllSoftlinkNode> getAllSoftlinkNodeInfo Return NULL, So Return"); + return; + } + + sSoftLinkHome = getSoftLinkHome(); + logger.info("notifyAllSoftlinkNode> SoftLink Home = " + sSoftLinkHome); + + if(nodes.isEmpty() == true) { + logger.info("notifyAllSoftlinkNode> SoftLink Node Info HashMap is Empty, So Return"); + return; + } + + Iterator it = nodes.keySet().iterator(); + + String svrName = ""; + String svrIP = ""; + + while(it.hasNext()){ + svrName = (String)it.next(); + svrIP = (String) nodes.get(svrName); + + try { + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("notifyAllSoftlinkNode> Notify : " + svrName + ", " + svrIP); + */ + logger.info("notifyAllSoftlinkNode> Notify : " + svrName + ", " + svrIP); + + RuntimeUtil.getInstance().notifyAllSoftlink(sSoftLinkHome, svrIP); + } + catch (Exception e) { + logger.info("SNAAgentUtil] broadcast Excpetion - " + svrName + "(" + svrIP + ") : "+ e.toString()); + /* + logger.error("SNAAgentUtil] broadcast Excpetion - "+svrName + "(" + svrIP + ") : "+ e.toString()); + if(adapter_logger.isWarn()) + adapter_logger.warn("notifyAllSoftlinkNode> Notify : " + svrName + ", " + svrIP + ", Msg = " + e.toString()); + */ + } + } + } + catch(WCAException e) { + logger.info("notifyAllSoftlinkNode> Exception Msg = " + e.toString()); +// e.printStackTrace(); + /* + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + + if(adapter_logger.isWarn()) + adapter_logger.warn("notifyAllSoftlinkNode> Exception Msg = " + e.toString()); + throw exception; + */ + } + catch(Exception e) { + logger.info("notifyAllSoftlinkNode> Exception Msg = " + e.toString()); +// e.printStackTrace(); + /* + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + if(adapter_logger.isWarn()) + adapter_logger.warn("notifyAllSoftlinkNode> Exception Msg = " + e.toString()); + throw exception; + */ + } + } + + /** + * 1. 기능 : Softlink 전체 설정 정보 디시 로드 + * 2. 처리 개요 : + * - 프로퍼티 정보에서 softlink 홈디렉토리 get하여 명령어 수행 (SnaUpdateCfg -a) + * - 에러 발생시 그 메세지를 exception으로 발생시킨다. + * 3. 주의사항 + * + * @exception WCAException + **/ + public static void notifySoftlinkNode(String sHostName) throws WCAException + { +// String sResult; + HashMap nodes = null; + String sSoftLinkHome = null; + try + { + nodes = getSoftlinkNodeInfo(sHostName); + if(nodes == null) { + logger.info("notifySoftlinkNode> getAllSoftlinkNodeInfo Return NULL, So Return"); + return; + } + + sSoftLinkHome = getSoftLinkHome(); + logger.info("notifySoftlinkNode> SoftLink Home = " + sSoftLinkHome); + + if(nodes.isEmpty() == true) { + logger.info("notifySoftlinkNode> SoftLink Node Info HashMap is Empty, So Return"); + return; + } + + Iterator it = nodes.keySet().iterator(); + + String svrName = ""; + String svrIP = ""; + + while(it.hasNext()){ + svrName = (String)it.next(); + svrIP = (String) nodes.get(svrName); + + try { + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("notifySoftlinkNode> Notify : " + svrName + ", " + svrIP); + */ + logger.info("notifySoftlinkNode> Notify : " + svrName + ", " + svrIP); + + RuntimeUtil.getInstance().notifyAllSoftlink(sSoftLinkHome, svrIP); + } + catch (Exception e) { + logger.error("SNAAgentUtil] broadcast Excpetion - ", e); + logger.info("SNAAgentUtil] broadcast Excpetion - " + svrName + "(" + svrIP + ") : "); + /* + logger.error("SNAAgentUtil] broadcast Excpetion - "+svrName + "(" + svrIP + ") : "+ e.toString()); + if(adapter_logger.isWarn()) + adapter_logger.warn("notifySoftlinkNode> Notify : " + svrName + ", " + svrIP + ", Msg = " + e.toString()); + */ + } + } + } + catch(WCAException e) { + logger.info("notifySoftlinkNode> Exception Msg = " + e.toString()); +// e.printStackTrace(); + /* + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + + if(adapter_logger.isWarn()) + adapter_logger.warn("notifySoftlinkNode> Exception Msg = " + e.toString()); + throw exception; + */ + } + catch(Exception e) { + logger.info("notifySoftlinkNode> Exception Msg = " + e.toString()); +// e.printStackTrace(); + /* + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + if(adapter_logger.isWarn()) + adapter_logger.warn("notifyAllSoftlinkNode> Exception Msg = " + e.toString()); + throw exception; + */ + } + } + + // 20080827 Start + /** + * 1. 기능 : Softlink 전체 설정 정보 디시 로드 + * 2. 처리 개요 : + * - 프로퍼티 정보에서 softlink 홈디렉토리 get하여 명령어 수행 (SnaUpdateCfg -a) + * - 에러 발생시 그 메세지를 exception으로 발생시킨다. + * 3. 주의사항 + * + * @exception WCAException + **/ + public static void notifySoftlinkNode(String sHostName, String sAdapterGroupName, String sLuGroupName) throws WCAException + { +// String sResult; + HashMap nodes = null; + String sSoftLinkHome = null; + try + { + nodes = getSoftlinkNodeInfo(sHostName); + if(nodes == null) { + logger.info("notifySoftlinkNode> getAllSoftlinkNodeInfo Return NULL, So Return"); + return; + } + + sSoftLinkHome = getSoftLinkHome(); + logger.info("notifySoftlinkNode> SoftLink Home = " + sSoftLinkHome); + + if(nodes.isEmpty() == true) { + logger.info("notifySoftlinkNode> SoftLink Node Info HashMap is Empty, So Return"); + return; + } + + Iterator it = nodes.keySet().iterator(); + + String svrName = ""; + String svrIP = ""; + + while(it.hasNext()){ + svrName = (String)it.next(); + svrIP = (String) nodes.get(svrName); + + try { + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("notifySoftlinkNode> Notify : " + svrName + ", " + svrIP); + */ + logger.info("notifySoftlinkNode> Notify : " + svrName + ", " + svrIP); + + RuntimeUtil.getInstance().notifyAllSoftlink(sSoftLinkHome, svrIP, sAdapterGroupName, sLuGroupName); + } + catch (Exception e) { + logger.info("SNAAgentUtil] broadcast Excpetion - " + svrName + "(" + svrIP + ") : "+ e.toString()); + /* + logger.error("SNAAgentUtil] broadcast Excpetion - "+svrName + "(" + svrIP + ") : "+ e.toString()); + if(adapter_logger.isWarn()) + adapter_logger.warn("notifySoftlinkNode> Notify : " + svrName + ", " + svrIP + ", Msg = " + e.toString()); + */ + } + } + } + catch(WCAException e) { + logger.info("notifySoftlinkNode> Exception Msg = " + e.toString()); +// e.printStackTrace(); + /* + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + + if(adapter_logger.isWarn()) + adapter_logger.warn("notifySoftlinkNode> Exception Msg = " + e.toString()); + throw exception; + */ + } + catch(Exception e) { + logger.info("notifySoftlinkNode> Exception Msg = " + e.toString()); + /* + WCAException exception = new WCAException(); + exception.setMessage(e.toString()); + if(adapter_logger.isWarn()) + adapter_logger.warn("notifyAllSoftlinkNode> Exception Msg = " + e.toString()); + throw exception; + */ + } + } + // 2080827 End + + private static String getSoftLinkHome() throws Exception { + StringBuffer sbQuery = new StringBuffer(); + String sSoftLinkHome = "/fsapp/eai/SNAAdapter"; + try { + sbQuery.append( "SELECT PRPTY2VAL " + + " FROM " + TableInfoEx.T_LU_PROPS + + " WHERE PRPTYGROUPNAME = '"+ TableInfoEx.T_SOFTLINK_PROP_GRP_NAME + "' AND " + + " PRPTYNAME = 'softlink.home'"); + + logger.info("getSoftLinkHome> Query =" + sbQuery.toString()); + + JDBCFactory factory = JDBCFactory.newInstance(); + CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); + SQLData data = common.select(sbQuery.toString()); + + int nRsltCnt = 0; + if(data != null) { + nRsltCnt = data.getDispDatasCount(); + } + logger.info("getSoftLinkHome> Record Count =" + nRsltCnt); + + if(nRsltCnt > 0) { + for(int nIndx = 0 ; nIndx < nRsltCnt; nIndx++) { + sSoftLinkHome = data.getSQLStringData("PRPTY2VAL" + nIndx); + logger.info("getSoftLinkHome> Record : " + sSoftLinkHome); + } + } + return sSoftLinkHome; + } + catch(Exception e) { + logger.info("getAllSoftlinkNodeInfo> Exception Msg = " + e.toString()); + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("getAllSoftlinkNodeInfo> Exception Msg = " + e.toString()); + */ + return sSoftLinkHome; + } + } + + private static HashMap getAllSoftlinkNodeInfo() throws Exception { + HashMap nodes = new HashMap(); + StringBuffer sbQuery = new StringBuffer(); + + try { + sbQuery.append( "select SNAADPTRSEVRNAME, SNAADPTRSEVRIPNAME, SNAADPTRSEVRCTNT " + + " FROM " + TableInfoEx.T_LU_HOST + + " WHERE 1=1 "); + + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("getAllSoftlinkNodeInfo> Query =" + sbQuery.toString()); + */ + logger.info("getAllSoftlinkNodeInfo> Query =" + sbQuery.toString()); + + JDBCFactory factory = JDBCFactory.newInstance(); + CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); + SQLData data = common.select(sbQuery.toString()); + + int nRsltCnt = 0; + if(data != null) { + nRsltCnt = data.getDispDatasCount(); + } + + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("getAllSoftlinkNodeInfo> Record Count =" + nRsltCnt); + */ + logger.info("getAllSoftlinkNodeInfo> Record Count =" + nRsltCnt); + + if(nRsltCnt > 0) { + String sSNAAdptrSevrName = ""; + String sSNAAdptrSevrIPName = ""; + + for(int nIndx = 0 ; nIndx < nRsltCnt; nIndx++) + { + sSNAAdptrSevrName = data.getSQLStringData("SNAADPTRSEVRNAME" + nIndx); + sSNAAdptrSevrIPName = data.getSQLStringData("SNAADPTRSEVRIPNAME" + nIndx); + + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("getAllSoftlinkNodeInfo> Record : " + sSNAAdptrSevrName + ", " + sSNAAdptrSevrIPName); + */ + logger.info("getAllSoftlinkNodeInfo> Record : " + sSNAAdptrSevrName + ", " + sSNAAdptrSevrIPName); + + nodes.put(sSNAAdptrSevrName, sSNAAdptrSevrIPName); + } + } + return nodes; + } + catch(Exception e) { + logger.info("getAllSoftlinkNodeInfo> Exception Msg = " + e.toString()); + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("getAllSoftlinkNodeInfo> Exception Msg = " + e.toString()); + */ + return null; + } + } + + private static HashMap getSoftlinkNodeInfo(String sHostName) throws Exception { + HashMap nodes = new HashMap(); + StringBuffer sbQuery = new StringBuffer(); + + try { + sbQuery.append( "SELECT SNAADPTRSEVRNAME, SNAADPTRSEVRIPNAME, SNAADPTRSEVRCTNT " + + " FROM " + TableInfoEx.T_LU_HOST + + " WHERE SNAADPTRSEVRNAME='" + sHostName + "' "); + + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("getAllSoftlinkNodeInfo> Query =" + sbQuery.toString()); + */ + logger.info("getAllSoftlinkNodeInfo> Query =" + sbQuery.toString()); + + JDBCFactory factory = JDBCFactory.newInstance(); + CommonJDBC common = (CommonJDBC)factory.create(CommonJDBC.class); + SQLData data = common.select(sbQuery.toString()); + + int nRsltCnt = 0; + if(data != null) { + nRsltCnt = data.getDispDatasCount(); + } + + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("getAllSoftlinkNodeInfo> Record Count =" + nRsltCnt); + */ + logger.info("getAllSoftlinkNodeInfo> Record Count =" + nRsltCnt); + + if(nRsltCnt > 0) { + String sSNAAdptrSevrName = ""; + String sSNAAdptrSevrIPName = ""; + + for(int nIndx = 0 ; nIndx < nRsltCnt; nIndx++) + { + sSNAAdptrSevrName = data.getSQLStringData("SNAADPTRSEVRNAME" + nIndx); + sSNAAdptrSevrIPName = data.getSQLStringData("SNAADPTRSEVRIPNAME" + nIndx); + + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("getAllSoftlinkNodeInfo> Record : " + sSNAAdptrSevrName + ", " + sSNAAdptrSevrIPName); + */ + logger.info("getAllSoftlinkNodeInfo> Record : " + sSNAAdptrSevrName + ", " + sSNAAdptrSevrIPName); + + nodes.put(sSNAAdptrSevrName, sSNAAdptrSevrIPName); + } + } + return nodes; + } + catch(Exception e) { + logger.info("getAllSoftlinkNodeInfo> Exception Msg = " + e.toString()); + /* + if(adapter_logger.isWarn()) + adapter_logger.warn("getAllSoftlinkNodeInfo> Exception Msg = " + e.toString()); + */ + return null; + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterException.java b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterException.java new file mode 100644 index 0000000..21aa7f0 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterException.java @@ -0,0 +1,11 @@ +package com.eactive.eai.adapter.websocket; + +public class WebSocketAdapterException extends Exception { + public WebSocketAdapterException() { + super("WebSocketAdapterException is occured."); + } + + public WebSocketAdapterException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterFacade.java b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterFacade.java new file mode 100644 index 0000000..37cac67 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterFacade.java @@ -0,0 +1,76 @@ +package com.eactive.eai.adapter.websocket; + +import java.nio.charset.Charset; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; +import org.java_websocket.WebSocket; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.ElinkDefaultAdapter; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.Logger; + +public class WebSocketAdapterFacade extends ElinkDefaultAdapter { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + private static WebSocketAdapterFacade instance = new WebSocketAdapterFacade(); + + public static final String ADAPTER_GORUP_NAME = "ADAPTER_GROUP_NAME"; + + public static WebSocketAdapterFacade getInstance() { + return instance; + } + + public Object execute(Properties prop, Object message, Properties tempProp) throws Exception { + String adapterGroupName = tempProp.getProperty(ADAPTER_GORUP_NAME); + if (logger.isDebug()) + logger.debug("[WebSocketAdapterFacade] | Outbound Adapter Group is " + adapterGroupName); + + byte[] request = null; + if (message instanceof byte[]) { + request = (byte[]) message; + } else { + throw new Exception(adapterGroupName + " | [WebSocketAdapterFacade] cannot send object type : " + + message.getClass().getName()); + } + + AdapterManager manager = AdapterManager.getInstance(); + AdapterGroupVO agv = manager.getAdapterGroupVO(adapterGroupName); + String encode = StringUtils.defaultIfBlank(agv.getMessageEncode(), Charset.defaultCharset().name()); +// String encode = "utf-8"; +// if (MessageType.UJSON.equals(agv.getMessageType()) || MessageType.JSON.equals(agv.getMessageType())){ + if (MessageType.JSON.equals(agv.getMessageType())) { + +// if (MessageType.JSON.equals(agv.getMessageType())) { +// encode = "ms949"; +// } + +// String id = ExtMessageConverter.getTellerId(message, agv.getMessageType()); + // BID와 책임자승인 거래에 따라 추출해야 할 위치가 다르고 + // Group BID일 경우까지 고려하여 Outboud에서 추출하여 설정하도록 함 (2021-03-26) + String receiverId = tempProp.getProperty("RECEIVER_ID"); + + if (receiverId == null) { + logger.warn("[WebSocketAdapterFacade] | RECEIVER_ID is NULL " + new String(request, encode)); + return null; + } + WebSocket webSocket = WebSocketSessionManager.getInstance().getSession(adapterGroupName, receiverId); + if (logger.isDebug()) { + logger.debug("[WebSocketAdapterFacade] | receiverId=" + receiverId); + logger.debug("[WebSocketAdapterFacade] | adapterGroupName=" + adapterGroupName); + logger.debug("[WebSocketAdapterFacade] | websocket=" + webSocket.getRemoteSocketAddress()); + logger.debug("[WebSocketAdapterFacade] | request=" + new String(request, encode)); + } + + if (webSocket == null) { + logger.warn("[WebSocketAdapterFacade] | WebSocket Session is NULL receiverId" + receiverId); + return null; + } else { + webSocket.send(new String(request, encode)); + } + } + return null; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterListener.java b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterListener.java new file mode 100644 index 0000000..08aa1e6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterListener.java @@ -0,0 +1,55 @@ +package com.eactive.eai.adapter.websocket; + +import java.util.Properties; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListenerSupport; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; + +public class WebSocketAdapterListener extends AdapterListenerSupport { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public void start() throws AdapterException { + WebSocketAdapterManager manager = WebSocketAdapterManager.getInstance(); + + AdapterPropManager pmanager = AdapterPropManager.getInstance(); + Properties prop = pmanager.getProperties(info.getPropGroupName()); + + try { + if (info == null) + throw new Exception("WebSocketAdapterListener | AdapterVO is NULL."); + WebSocketHandler adapter = new WebSocketHandler(info, prop); + info.setStatus(true); + adapter.start(); + manager.addAdapter(info, adapter); + } catch (Exception e) { + logger.error("WebSocketAdapterListener] start failed - " + (info == null ? info : info.getPropGroupName()), + e); + ; + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIOIA008"); + throw new AdapterException(errCode); + } + } + + public void stop() throws AdapterException { + WebSocketAdapterManager manager = WebSocketAdapterManager.getInstance(); + try { + WebSocketHandler adapter = manager.getAdapter(info); + if (adapter == null) + throw new Exception(info.getName() + " | [WebSocketAdapterListener] AdapterVO is NULL."); + if (logger.isWarn()) + logger.warn("WebSocketAdapterListener] stop - " + (info == null ? info : info.getPropGroupName())); + ; + adapter.stop(10 * 1000); + } catch (Exception e) { + logger.error("WebSocketAdapterListener] stop failed - " + (info == null ? info : info.getPropGroupName()), + e); + ; + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIOIA009"); + throw new AdapterException(errCode); + } + + } +} diff --git a/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterManager.java b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterManager.java new file mode 100644 index 0000000..6a27a57 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketAdapterManager.java @@ -0,0 +1,143 @@ +package com.eactive.eai.adapter.websocket; + +import java.util.Enumeration; +import java.util.Iterator; +import java.util.Vector; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.util.Logger; + +public class WebSocketAdapterManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + private static WebSocketAdapterManager instance = new WebSocketAdapterManager(); + private ConcurrentHashMap> adapterGroups; + + public WebSocketAdapterManager() { + try { + adapterGroups = new ConcurrentHashMap<>(); + } catch (Exception e) { + String code = ExceptionUtil.getErrorCode(e, "RECEAIOIA002"); + throw new RuntimeException(code); + } + } + + public static WebSocketAdapterManager getInstance() { + if (instance == null) { + instance = new WebSocketAdapterManager(); + } + return instance; + } + + public void stop() { + for (Enumeration> e = adapterGroups.elements(); e + .hasMoreElements();) { + ConcurrentHashMap group = e.nextElement(); + for (Enumeration ee = group.elements(); ee.hasMoreElements();) { + WebSocketHandler adapter = ee.nextElement(); + try { + adapter.stop(); + } catch (Exception ex) { + logger.error(adapter.getAdapterVO().getName() + " | " + ex.getMessage(), ex); + } + } + } + } + + public ConcurrentMap> getAdapterGroups() { + return this.adapterGroups; + } + + public WebSocketHandler[] getAdapter(String adapterFullName) { + String adapterGroupName = adapterFullName; + String adapterName = null; + if (adapterFullName.indexOf('.') != -1) { + adapterGroupName = adapterFullName.substring(0, adapterFullName.indexOf('.')); + adapterName = adapterFullName.substring(adapterFullName.indexOf('.') + 1); + } + AdapterVO vo = new AdapterVO(); + vo.setAdapterGroupName(adapterGroupName); + vo.setName(adapterName); + ConcurrentHashMap adapters = adapterGroups.get(vo.getAdapterGroupName()); + Vector started = new Vector<>(); + for (Iterator iter = adapters.values().iterator(); iter.hasNext();) { + WebSocketHandler adapter = iter.next(); + started.add(adapter); + } + WebSocketHandler[] array = (WebSocketHandler[]) started.toArray(); + if (array == null || array.length == 0) + return null; + return array; + + } + + public WebSocketHandler getAdapter(AdapterVO vo) { + ConcurrentHashMap adapters = adapterGroups.get(vo.getAdapterGroupName()); + if (adapters == null) + return null; + + if (vo.getName() != null) { + return adapters.get(vo.getName()); + } + return null; + } + + public void addAdapter(AdapterVO vo, WebSocketHandler adapter) throws Exception { + ConcurrentHashMap adapters = adapterGroups.get(vo.getAdapterGroupName()); + if (adapters == null) { + adapterGroups.put(vo.getAdapterGroupName(), new ConcurrentHashMap<>()); + } else { + if (adapters.get(vo.getName()) != null) { + if (logger.isWarn()) + logger.warn(vo.getName() + " | WebSocketAdapterManager - socket adapter already exist -> replace [" + + vo.getAdapterGroupName() + ", " + vo.getName() + "]"); + try { + adapters.get(vo.getName()).stop(); + } catch (Exception e) { + // adapter.addRecentError(adapter.getContext().getAdapterName() + " | old + // adapter stop error.", e); + } finally { + // sleep 1 second to avoid BindException + try { + Thread.sleep(1000L); + } catch (Exception e) { + if (logger.isWarnEnabled()) + logger.warn("sleep error", e); + } + } + } + } + adapterGroups.get(vo.getAdapterGroupName()).put(vo.getName(), adapter); + } + + @Override + public void addLifecycleListener(LifecycleListener listener) { + // empty + } + + @Override + public LifecycleListener[] findLifecycleListeners() { + return null; + } + + @Override + public void removeLifecycleListener(LifecycleListener listener) { + // empty + } + + @Override + public void start() throws LifecycleException { + // empty + } + + @Override + public boolean isStarted() { + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/websocket/WebSocketExpiringMap.java b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketExpiringMap.java new file mode 100644 index 0000000..e423377 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketExpiringMap.java @@ -0,0 +1,664 @@ +package com.eactive.eai.adapter.websocket; + +import java.util.Collection; +import java.util.Map; +import java.util.Set; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +import org.apache.mina.util.ExpirationListener; +import org.java_websocket.WebSocket; + +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; + +public class WebSocketExpiringMap implements Map { + + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** The Constant DEFAULT_TIME_TO_LIVE. */ + public static final int DEFAULT_TIME_TO_LIVE = 60; + + /** The Constant DEFAULT_EXPIRATION_INTERVAL. */ + public static final int DEFAULT_EXPIRATION_INTERVAL = 1; + + /** The expirer count. */ + private static volatile int expirerCount = 1; + + /** The delegate. */ + private final ConcurrentHashMap delegate; + + /** The expiration listeners. */ + private final CopyOnWriteArrayList expirationListeners; + + /** The expirer. */ + private final Expirer expirer; + + /** + * Instantiates a new expiring map. + */ + public WebSocketExpiringMap() { + this(DEFAULT_TIME_TO_LIVE, DEFAULT_EXPIRATION_INTERVAL); + } + + /** + * Instantiates a new expiring map. + * + * @param timeToLive the time to live + */ + public WebSocketExpiringMap(int timeToLive) { + this(timeToLive, DEFAULT_EXPIRATION_INTERVAL); + } + + /** + * Instantiates a new expiring map. + * + * @param timeToLive the time to live + * @param expirationInterval the expiration interval + */ + public WebSocketExpiringMap(int timeToLive, int expirationInterval) { + this(new ConcurrentHashMap(), new CopyOnWriteArrayList(), timeToLive, + expirationInterval); + } + + /** + * Instantiates a new expiring map. + * + * @param delegate the delegate + * @param expirationListeners the expiration listeners + * @param timeToLive the time to live + * @param expirationInterval the expiration interval + */ + private WebSocketExpiringMap(ConcurrentHashMap delegate, + CopyOnWriteArrayList expirationListeners, int timeToLive, int expirationInterval) { + this.delegate = delegate; + this.expirationListeners = expirationListeners; + + this.expirer = new Expirer(); + expirer.setExpirationInterval(expirationInterval); + expirer.setTimeToLive(timeToLive); + expirer.startExpiring(); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#put(java.lang.Object, java.lang.Object) + */ + public V put(K key, V value) { + ExpiringObject answer = delegate.put(key, new ExpiringObject(key, value, System.currentTimeMillis())); + if (answer == null) { + return null; + } + + return answer.getValue(); + } + + /** + * Put. + * + * @param key the key + * @param value the value + * @param timeToLive the time to live + * + * @return the v + */ + public V put(K key, V value, int timeToLive) { + ExpiringObject answer = delegate.put(key, + new ExpiringObject(key, value, System.currentTimeMillis(), timeToLive)); + if (answer == null) { + return null; + } + + return answer.getValue(); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#get(java.lang.Object) + */ + public V get(Object key) { + ExpiringObject object = delegate.get(key); + if (object != null) { + return object.getValue(); + } + return null; + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#remove(java.lang.Object) + */ + public V remove(Object key) { + ExpiringObject answer = delegate.remove(key); + if (answer == null) { + return null; + } + + return answer.getValue(); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#containsKey(java.lang.Object) + */ + public boolean containsKey(Object key) { + return delegate.containsKey(key); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#containsValue(java.lang.Object) + */ + public boolean containsValue(Object value) { + return delegate.containsValue(value); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#size() + */ + public int size() { + return delegate.size(); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#isEmpty() + */ + public boolean isEmpty() { + return delegate.isEmpty(); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#clear() + */ + public void clear() { + delegate.clear(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return delegate.hashCode(); + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#keySet() + */ + public Set keySet() { + return delegate.keySet(); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return delegate.equals(obj); + } + + /* (non-Javadoc) + * @see java.util.Map#putAll(java.util.Map) + */ + public void putAll(Map inMap) { + for (Entry e : inMap.entrySet()) { + if(e != null){ //취약점 소스 수정 + this.put(e.getKey(), e.getValue()); + } + } + } + + /* + * (non-Javadoc) + * + * @see java.util.Map#values() + */ + public Collection values() { + throw new UnsupportedOperationException(); + } + + /* (non-Javadoc) + * @see java.util.Map#entrySet() + */ + public Set> entrySet() { + throw new UnsupportedOperationException(); + } + + /** + * Adds the expiration listener. + * + * @param listener the listener + */ +// public void addExpirationListener(ExpirationListener listener) { +// expirationListeners.add(listener); +// } +// +// /** +// * Removes the expiration listener. +// * +// * @param listener the listener +// */ +// public void removeExpirationListener( +// ExpirationListener listener) { +// expirationListeners.remove(listener); +// } + + /** + * Gets the expirer. + * + * @return the expirer + */ + public Expirer getExpirer() { + return expirer; + } + + /** + * Gets the expiration interval. + * + * @return the expiration interval + */ + public int getExpirationInterval() { + return expirer.getExpirationInterval(); + } + + /** + * Gets the time to live. + * + * @return the time to live + */ + public int getTimeToLive() { + return expirer.getTimeToLive(); + } + + /** + * Sets the expiration interval. + * + * @param expirationInterval the new expiration interval + */ + public void setExpirationInterval(int expirationInterval) { + expirer.setExpirationInterval(expirationInterval); + } + + /** + * Sets the time to live. + * + * @param timeToLive the new time to live + */ + public void setTimeToLive(int timeToLive) { + expirer.setTimeToLive(timeToLive); + } + + /** + * The Class ExpiringObject. + *

    + *
  • 1. Function :
  • + *
  • 2. Summary :
  • + *
  • 3. Notification :
  • + *
+ * + * @author : $Author: + * @version : $Revision: 1.4 $ + */ + private class ExpiringObject { + + /** The key. */ + private K key; + + /** The value. */ + private V value; + + /** The access time. */ + private long accessTime; + + /** The time to live millis. */ + private long timeToLiveMillis; + + /** + * Instantiates a new expiring object. + * + * @param key the key + * @param value the value + * @param accessTime the access time + */ + ExpiringObject(K key, V value, long accessTime) { + this(key, value, accessTime, 0); + } + + /** + * Instantiates a new expiring object. + * + * @param key the key + * @param value the value + * @param accessTime the access time + * @param timeToLiveMillis the time to live millis + */ + ExpiringObject(K key, V value, long accessTime, int timeToLiveMillis) { + + if (value == null) { + throw new IllegalArgumentException("An expiring object cannot be null."); + } + + this.key = key; + this.value = value; + this.accessTime = accessTime; + this.timeToLiveMillis = timeToLiveMillis * 1000; + } + + /** + * Gets the time to live millis. + * + * @return the time to live millis + */ + public long getTimeToLiveMillis() { + return timeToLiveMillis; + } + + /** + * Sets the time to live millis. + * + * @param timeToLiveMillis the new time to live millis + */ + public void setTimeToLiveMillis(long timeToLiveMillis) { + this.timeToLiveMillis = timeToLiveMillis; + } + + /** + * Gets the access time. + * + * @return the access time + */ + public long getAccessTime() { + return accessTime; + } + + /** + * Sets the access time. + * + * @param lastAccessTime the new access time + */ + public void setAccessTime(long lastAccessTime) { + this.accessTime = lastAccessTime; + } + + /** + * Gets the key. + * + * @return the key + */ + public K getKey() { + return key; + } + + /** + * Gets the value. + * + * @return the value + */ + public V getValue() { + return value; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + return value.equals(obj); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + return value.hashCode(); + } + } + + /** + * The Class Expirer. + *
    + *
  • 1. Function :
  • + *
  • 2. Summary :
  • + *
  • 3. Notification :
  • + *
+ * + * @author : $Author: + * @version : $Revision: 1.4 $ + */ + public class Expirer implements Runnable { + + /** The state lock. */ + private ReadWriteLock stateLock = new ReentrantReadWriteLock(); + + /** The time to live millis. */ + private long timeToLiveMillis; + + /** The expiration interval millis. */ + private long expirationIntervalMillis; + + /** The running. */ + private boolean running = false; + + /** The expirer thread. */ + private final Thread expirerThread; + + /** + * Instantiates a new expirer. + */ + public Expirer() { + expirerThread = new Thread(this, "ExpiringMapExpirer-" + (expirerCount++)); + expirerThread.setDaemon(true); + } + + /* + * (non-Javadoc) + * + * @see java.lang.Runnable#run() + */ + public void run() { + while (running) { + processExpires(); + + try { + Thread.sleep(expirationIntervalMillis); + } catch (InterruptedException e) { + logger.warn("sleep error", e); + } + } + } + + /** + * Process expires. + * expire 조건 : timeNow >= expireTime + * expireTime = accessTime + timeToLive + */ + private void processExpires() { + long timeNow = System.currentTimeMillis(); +// logger.debug("WebSocketExpiringMap] processExpires START"); + + long timeToLiveMillis = 0; + + for (ExpiringObject o : delegate.values()) { + + if (o.getTimeToLiveMillis() > 0) { + timeToLiveMillis = o.getTimeToLiveMillis(); + } else { + timeToLiveMillis = this.timeToLiveMillis; + } + + if (timeToLiveMillis <= 0) + continue; + + long expireTime = o.getAccessTime() + timeToLiveMillis; + + if (timeNow >= expireTime) { + ExpiringObject object = delegate.remove(o.getKey()); + if (object != null) { + Object co = object.getValue(); + if (co instanceof WebSocket) { + logger.warn("WebSocketExpiringMap] processExpires Close WebSocket - " + + ((WebSocket) co).getRemoteSocketAddress()); + ((WebSocket) co).close(); + } + } + } + } + } + + /** + * Start expiring. + */ + public void startExpiring() { + stateLock.writeLock().lock(); + + try { + if (!running) { + running = true; + expirerThread.start(); + } + } finally { + stateLock.writeLock().unlock(); + } + } + + /** + * Start expiring if not started. + */ + public void startExpiringIfNotStarted() { + stateLock.readLock().lock(); + try { + if (running) { + return; + } + } finally { + stateLock.readLock().unlock(); + } + + stateLock.writeLock().lock(); + try { + if (!running) { + running = true; + expirerThread.start(); + } + } finally { + stateLock.writeLock().unlock(); + } + } + + /** + * Stop expiring. + */ + public void stopExpiring() { + stateLock.writeLock().lock(); + + try { + if (running) { + running = false; + expirerThread.interrupt(); + } + } finally { + stateLock.writeLock().unlock(); + } + } + + /** + * Checks if is running. + * + * @return true, if is running + */ + public boolean isRunning() { + stateLock.readLock().lock(); + + try { + return running; + } finally { + stateLock.readLock().unlock(); + } + } + + /** + * Gets the time to live. + * + * @return the time to live + */ + public int getTimeToLive() { + stateLock.readLock().lock(); + + try { + return (int) timeToLiveMillis / 1000; + } finally { + stateLock.readLock().unlock(); + } + } + + /** + * Sets the time to live. + * + * @param timeToLive the new time to live + */ + public void setTimeToLive(long timeToLive) { + stateLock.writeLock().lock(); + + try { + this.timeToLiveMillis = timeToLive * 1000; + } finally { + stateLock.writeLock().unlock(); + } + } + + /** + * Gets the expiration interval. + * + * @return the expiration interval + */ + public int getExpirationInterval() { + stateLock.readLock().lock(); + + try { + return (int) expirationIntervalMillis / 1000; + } finally { + stateLock.readLock().unlock(); + } + } + + /** + * Sets the expiration interval. + * + * @param expirationInterval the new expiration interval + */ + public void setExpirationInterval(long expirationInterval) { + stateLock.writeLock().lock(); + + try { + this.expirationIntervalMillis = expirationInterval * 1000; + } finally { + stateLock.writeLock().unlock(); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/websocket/WebSocketHandler.java b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketHandler.java new file mode 100644 index 0000000..f49283a --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketHandler.java @@ -0,0 +1,323 @@ +package com.eactive.eai.adapter.websocket; + +import java.net.InetSocketAddress; +import java.util.Properties; + +import org.java_websocket.WebSocket; +import org.java_websocket.handshake.ClientHandshake; +import org.java_websocket.server.WebSocketServer; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.session.ChannelSessionFacade; +import com.eactive.eai.common.util.Logger; + +public class WebSocketHandler extends WebSocketServer { + + private Properties prop; + private AdapterVO adapterVO; + + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + private static String PORT_NUMBER = "port.number"; + private static String POLLING_REQUEST = "polling.request"; + private static String POLLING_RESPONSE = "polling.response"; + + private boolean useConnectionIdle = false; + private int DEFAULT_CONNECTION_IDLEOUT= 60; + private int DEFAULT_CONNECTION_IDLEINTERVAL= 10; + private static String CONNECTION_IDLETIME_USE = "connection.idletime.use"; + private static String CONNECTION_IDLETIME = "connection.idletime"; + private static String CONNECTION_IDLEINTERVAL= "connection.idleintervals"; + + private String pollingRequest = "POLLREQ@@"; + private String pollingResponse = "POLLRES@@"; +// private boolean testMode = false; + + private String logPrefix = "WebSocketHandler] "; + + // connect and do nothing + private WebSocketExpiringMap connectionMap = null; + /** + * Creates a new WebSocketServer with the wildcard IP accepting all connections. + */ + public WebSocketHandler(AdapterVO adapterVO, Properties prop) { + super(new InetSocketAddress(Integer.parseInt(prop.getProperty(PORT_NUMBER)))); + + logPrefix = logPrefix + "[" + adapterVO.getAdapterGroupName() + "] "; + + String pollingReq = prop.getProperty(POLLING_REQUEST); + if (pollingReq != null) + pollingRequest = pollingReq; + String pollingRes = prop.getProperty(POLLING_RESPONSE); + if (pollingRes != null) + pollingResponse = pollingRes; + + String sConnectionIdleTimeUse = prop.getProperty(CONNECTION_IDLETIME_USE); + if (sConnectionIdleTimeUse != null && "Y".contentEquals(sConnectionIdleTimeUse)) { + useConnectionIdle = true; + } + + String sConnectionIdleTime = prop.getProperty(CONNECTION_IDLETIME); + int connectionIdleTime = 60; + if (sConnectionIdleTime != null) { + try { + connectionIdleTime = Integer.parseInt(sConnectionIdleTime); + } catch (Exception ex) { + connectionIdleTime = DEFAULT_CONNECTION_IDLEOUT; + } + } + + String sConnectionIdleInterval = prop.getProperty(CONNECTION_IDLEINTERVAL); + int connectionIdleInterval = 10; + if (sConnectionIdleInterval != null) { + try { + connectionIdleInterval = Integer.parseInt(sConnectionIdleInterval); + } catch (Exception ex) { + connectionIdleInterval = DEFAULT_CONNECTION_IDLEINTERVAL; + } + } + + if(logger.isInfo()) { + logger.info(logPrefix + "- port : " + prop.getProperty(PORT_NUMBER)); + logger.info(logPrefix + "- pollingRequest : " + pollingRequest); + logger.info(logPrefix + "- pollingResponse : " + pollingResponse); + + logger.info(logPrefix + "- useConnectionIdle : " + useConnectionIdle); + logger.info(logPrefix + "- connectionIdleTime : " + connectionIdleTime); + logger.info(logPrefix + "- connectionIdleInterval : " + connectionIdleInterval); + } + + this.adapterVO = adapterVO; + this.prop = prop; + + if (useConnectionIdle) { + connectionMap = new WebSocketExpiringMap<>(connectionIdleTime, connectionIdleInterval); + } + } + + /** + * Method handler when a new connection has been opened. + */ + @Override + public void onOpen(WebSocket conn, ClientHandshake handshake) { + WebSocketSessionManager.getInstance().sessionOpen(adapterVO.getAdapterGroupName(), conn); + if(logger.isDebug()) logger.debug(logPrefix + "New connection from " + conn.getRemoteSocketAddress()); + if (useConnectionIdle) { + connectionMap.put(conn.getRemoteSocketAddress().toString(), conn); + } + } + + /** + * Method handler when a connection has been closed. + */ + @Override + public void onClose(WebSocket conn, int code, String reason, boolean remote) { + + if (logger.isDebug()) { + logger.debug(logPrefix + "Closed connection to " + conn.getRemoteSocketAddress()); + } + + ChannelSessionFacade.getInstance().onDetachWebSocketSession(adapterVO.getAdapterGroupName(), conn); + + if(useConnectionIdle) { + connectionMap.remove(conn.getRemoteSocketAddress().toString()); + + } + } + + private void send(WebSocket conn, String message) { + conn.send(message); + } + + private void sendAndClose(WebSocket conn, String message) { + conn.send(message); + if(logger.isWarn()) logger.warn(logPrefix + "close websocket - " + conn.getRemoteSocketAddress()); + conn.close(); + } + + /** + * Method handler when a message has been received from the client. + */ + @Override + public void onMessage(WebSocket conn, String message) { + + if (logger.isDebug()) { + logger.debug(logPrefix + "Received: " + message + " : " + conn.getRemoteSocketAddress().toString()); + } + +// String adapterGroupName = adapterVO.getAdapterGroupName(); +// String response = ""; +// if (message.startsWith("ICONREQ") && message.length() == 57) { +// // 57 bytes +// // ICON(4) + REQ/RES(3) + 정상여부(1) + 사용자 ID(9) + UUID(40) +// String id = message.substring(8, 8 + 9); +// String uuid = message.substring(8 + 9, 57); +// String trimingId = StringUtils.trim(id); +// SessionVO sessionVo = null; +// String isAsync = PropManager.getInstance().getProperty("LOGIN", "IS_ASYNC", "false"); +// if ("false".equals(isAsync)){ +// sessionVo = SessionManager.getInstance().getLogin(trimingId); +// }else{ +// int i=0; +// while(true){ +// sessionVo = SessionManager.getInstance().getLogin(trimingId); +// if ( sessionVo != null || i > 100){ +// if (i > 100 ){ +// logger.error("WebSocketHandler] onMessage sessionVo = "+sessionVo + ",count="+i); +// }else if (100 >= i && i > 0){ +// logger.info("WebSocketHandler] onMessage sessionVo = "+sessionVo + ",count="+i); +// } +// break; +// } +// try { +// Thread.sleep(20L); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// i++; +// } +// } +// +// if (sessionVo == null) { +// logger.error(logPrefix + "ICONREQ HTTP login session not found - loginId=(" + trimingId + ") " + conn.getRemoteSocketAddress() + " uuid=" + uuid); +// response = "ICONRESN" + id + uuid; +// +// SessionHistoryLogger.getInstance().log( +// new SessionHistoryDTO(message, SessionHistoryVO.HISTORYDSTCD_WEBSOCKET, "E", uuid, conn.getRemoteSocketAddress().toString(), false)); +// +// if (logger.isDebug()) { +// logger.debug(logPrefix + "ICONREQ response loginId=(" + trimingId + ") " + conn.getRemoteSocketAddress() + " response=" + response); +// } +// sendAndClose(conn, response); +// return; +// } else { +// String sid = sessionVo.getUuid(); +// if (logger.isDebug()) { +// logger.debug(logPrefix + "ICONREQ loginId=(" + trimingId + ") " + conn.getRemoteSocketAddress() + " uuid=" + uuid + " sid=" + sid); +// } +// +// if (sid != null && sid.equals(uuid)) { +// // websocket 인증 +// if (logger.isDebug()) { +// logger.debug(logPrefix + "ICONREQ confirm loginId=(" + trimingId + ") " + conn.getRemoteSocketAddress() + " uuid=" + uuid +" sid="+sid); +// } +// +// ChannelSessionFacade.getInstance().onAttachWebSocketSession(adapterGroupName, conn, trimingId); +// +// SessionHistoryLogger.getInstance().log( +// new SessionHistoryDTO(message, SessionHistoryVO.HISTORYDSTCD_WEBSOCKET, "N", uuid, conn.getRemoteSocketAddress().toString(), false)); +// +// if(useConnectionIdle) { +// connectionMap.remove(conn.getRemoteSocketAddress()); +// } +// +// response = "ICONRESY" + id + uuid; +// if (logger.isDebug()) { +// logger.debug(logPrefix + "ICONREQ response loginId=(" + trimingId + ") " + conn.getRemoteSocketAddress() + " response=" + response); +// } +// send(conn, response); +// return; +// } else { +// if (logger.isDebug()) { +// logger.debug(logPrefix + "ICONREQ uuid not match loginId=(" + trimingId + ") " + conn.getRemoteSocketAddress() + " uuid=" + uuid +" sid="+sid); +// } +// response = "ICONRESN" + id + uuid; +// if (logger.isDebug()) { +// logger.debug(logPrefix + "ICONREQ response loginId=(" + trimingId + ") " + conn.getRemoteSocketAddress() + " response=" + response); +// } +// +// sendAndClose(conn, response); +// return; +// } +// } +// } else if (message.startsWith(pollingRequest)) { +// // Check polling session id and refresh cache +// String connectionId = null; +// +// // TODO : 로그인정보가 없는 경우에 에러로 처리할 것인지 확인 필요. +// // 현재 비정상 접속은 강제 종료함(close) +// try { +// connectionId = WebSocketSessionManager.getInstance().getWebSocketConnectionId(adapterGroupName, conn); +// String trimingConnectionId = StringUtils.trim(connectionId); +// SessionVO sVo = SessionManager.getInstance().getLogin(trimingConnectionId); +// PropManager pManager = PropManager.getInstance(); +// String cacheType = pManager.getProperty(SessionManager.SESSION_MANAGER_GROUPNAME, SessionManager.SESSION_MANAGER_CACHETYPE, "EHCACHE"); +//// if ("EHCACHE".equals(cacheType)){ +// logger.info(logPrefix + "POLL loginId=("+ connectionId +") " + conn.getRemoteSocketAddress() + "] refresh LOGIN"); +// ChannelSessionFacade.getInstance().refreshLoginCache(sVo.getLoginUserId(), sVo); +// +//// }else{ +//// logger.info(logPrefix + "POLL loginId=("+ connectionId +") " + conn.getRemoteSocketAddress() + "] skip LOGIN"); +//// } +// response = pollingResponse; +// if (logger.isDebug()) { +// logger.debug(logPrefix + "POLL loginId=(" + connectionId + ") " + conn.getRemoteSocketAddress() + ", response=" + response); +// } +// send(conn, response); +// } catch (Exception ex) { +// logger.warn(logPrefix + "POLL Login Session not found, POLL conn=" + conn + ", loginId=(" + connectionId+") ", ex); +// conn.close(); +// logger.warn(logPrefix + "POLL Close websocket connection, POLL conn=" + conn + ", loginId=(" + connectionId+") ", ex); +// } +// } else { +// // 책임자 승인 응답거래 +// logger.error(logPrefix + "ApproveResponse message : " + message); +// // Send to JMSTopic or Ehcache response topic +// // TODO : 책임자 승인거래인지 확인 +// ExtMessage extMessage = null; +// try { +// extMessage = ExtMessageConverter.getExtMessageForStandard(message, ""); +// String traceKey = extMessage.getGuid(); +// ; // get from Message Header +//// SessionManager.getInstance().putResponseTopic(traceKey, message); +// // 동일 WebSocket으로 송수신하므로 불필요한 Cache 사용을 줄임. +// Future future = ResponseMap.getInstance().get(traceKey); +// if (future == null){ +// logger.warn(logPrefix + "ApproveResponse logPrefix setEvent["+traceKey+"] Future not found traceKey=" + traceKey); +// } +// else { +// logger.debug(logPrefix + "ApproveResponse logPrefix setEvent["+traceKey+"] put to Future traceKey=" + traceKey); +// future.getSlot().put(message); +// } +// } catch (Exception e) { +// response = "Invalid message - format error"; +// logger.error(logPrefix + "ApproveResponse Parsing error " + conn.getRemoteSocketAddress() + " response=" + response, e); +// sendAndClose(conn, response); +// } +// } + } + + /** + * Method handler when an error has occured. + */ + @Override + public void onError(WebSocket conn, Exception ex) { + if (conn != null) { + WebSocketSessionManager.getInstance().sessionError(adapterVO.getAdapterGroupName(), conn); + if (logger.isError()) { + logger.error(logPrefix + "ERROR from " + conn.getRemoteSocketAddress(), ex); + } + } else { + if (logger.isError()) { + logger.error(logPrefix + "ERROR " + ex.getMessage(), ex); + } + } + } + + public AdapterVO getAdapterVO() { + return this.adapterVO; + } + + public Properties getProp() { + return this.prop; + } + + @Override + public String toString() { + return "WebSocketHandler [adapterVO=" + adapterVO + ", prop=" + prop + "]"; + } + + public void onStart() { + // TODO Auto-generated method stub + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/adapter/websocket/WebSocketSessionListener.java b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketSessionListener.java new file mode 100644 index 0000000..2429fdf --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketSessionListener.java @@ -0,0 +1,35 @@ +package com.eactive.eai.adapter.websocket; + +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +public class WebSocketSessionListener implements HttpSessionListener { + + @Override + public void sessionCreated(HttpSessionEvent sessionEvent) { +// HttpSession session = sessionEvent.getSession(); +// Object obj = session.getAttribute("tlogin"); +// if (obj != null){ +// HashMap tlogin = (HashMap)session.getAttribute("tlogin"); +// +// SessionVO sessionObj = new SessionVO(); +// EAIServerManager mgr = EAIServerManager.getInstance(); +//// EAIServerVO localServer = mgr.getEAIServer( mgr.getLocalServerName()); +// sessionObj.setLoginInstId(mgr.getLocalServerName()); +// sessionObj.setLoginUserId( (String)tlogin.get("USER_ID") ); +// sessionObj.setUuid((String)tlogin.get("UUID")); +// +// SessionManager.getInstance().putLogin((String)tlogin.get("USER_ID"),sessionObj ); +// } + } + + @Override + public void sessionDestroyed(HttpSessionEvent sessionEvent) { +// HttpSession session = sessionEvent.getSession(); +// Object obj = session.getAttribute("tlogin"); +// if (obj != null){ +// HashMap tlogin = (HashMap)session.getAttribute("tlogin"); +// SessionManager.getInstance().removeLogin((String)tlogin.get("USER_ID")); +// } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/websocket/WebSocketSessionManager.java b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketSessionManager.java new file mode 100644 index 0000000..ccae5a6 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/websocket/WebSocketSessionManager.java @@ -0,0 +1,355 @@ +package com.eactive.eai.adapter.websocket; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import org.apache.commons.lang3.StringUtils; +import org.java_websocket.WebSocket; + +import com.eactive.eai.common.session.ChannelSessionFacade; +import com.eactive.eai.common.session.SessionManager; +import com.eactive.eai.common.session.SessionStatusManager; +import com.eactive.eai.common.session.SessionVO; +import com.eactive.eai.common.session.ChannelSessionFacade.LogoutType; +import com.eactive.eai.common.sessioninfo.SessionInfoVO; +import com.eactive.eai.common.util.Logger; + +public class WebSocketSessionManager { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static WebSocketSessionManager instance; + + private ConcurrentHashMap adapterGroup; + + private WebSocketSessionManager() { + this.adapterGroup = new ConcurrentHashMap(); + } + + public static WebSocketSessionManager getInstance() { + if (instance == null) { + instance = new WebSocketSessionManager(); + } + return instance; + } + + public HashMap> getAdapterGroupConnections() { + HashMap> adapterMap = new HashMap>(); + Iterator i = adapterGroup.keySet().iterator(); + while (i.hasNext()) { + String key = i.next(); + WebSocketPool pool = adapterGroup.get(key); + ConcurrentHashMap conMap = pool.getList(); + adapterMap.put(key, conMap); + } + return adapterMap; + } + + public ConcurrentHashMap getSessionList(String adapterGroupName) { + WebSocketPool p = adapterGroup.get(adapterGroupName); + if (p == null) + return new ConcurrentHashMap(); + else + return p.getList(); + } + + public synchronized void sessionOpen(String adapterGroupName, WebSocket conn) { + if (!adapterGroup.containsKey(adapterGroupName)) { + adapterGroup.put(adapterGroupName, new WebSocketPool()); + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + p.sessionOpen(conn); + } + + public synchronized void sessionLogin(String adapterGroupName, WebSocket conn, String id) { + if (!adapterGroup.containsKey(adapterGroupName)) { + adapterGroup.put(adapterGroupName, new WebSocketPool()); + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + p.sessionLogin(conn, id); + } + + public String getWebSocketConnectionId(String adapterGroupName, WebSocket conn) { + if (!adapterGroup.containsKey(adapterGroupName)) { + adapterGroup.put(adapterGroupName, new WebSocketPool()); + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + return p.getId(conn); + } + + public void onCloseEvent(String adapterGroupName, WebSocket conn) { + try { + + logger.warn("WebSocketSessionManager] onCloseEvent websocket =" + conn.getRemoteSocketAddress()); + + if (!adapterGroup.containsKey(adapterGroupName)) { + adapterGroup.put(adapterGroupName, new WebSocketPool()); + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + + String key = p.getId(conn); + + if (key == null) { + + logger.warn("WebSocketSessionManager] id not found websocket - " + conn.getRemoteSocketAddress()); + + } else { + + logger.warn("WebSocketSessionManager] removeLogin key=" + key); + + SessionVO sessionVo = SessionManager.getInstance().getLogin(key); + if (sessionVo == null) { + logger.warn("WebSocketSessionManager] LOGOUT Login Session Not found userId =" + key); + } else { + String uuid = sessionVo.getUuid(); + try { + ChannelSessionFacade.getInstance().logout(key, uuid, true, LogoutType.AutoLogout); + } catch (Exception e) { + logger.error("WebSocketSessionManager] Error Occured in removeLogin - key : " + key, e); + } + } + } + } catch (Exception e) { + logger.error("WebSocketSessionManager] Error Occured in Closing session - " + (conn == null ? "WebSocket is NULL" : conn.getRemoteSocketAddress()), e); + } finally { + try { + if (conn != null && !conn.isClosed()) + conn.close(); + } catch (Exception ex) { + logger.warn("WebSocketSessionManager] close connection error - " + conn); + } + } + } + + + public synchronized WebSocket getSession(String adapterGroupName, String id) { + if (!adapterGroup.containsKey(adapterGroupName)) { + adapterGroup.put(adapterGroupName, new WebSocketPool()); + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + return p.getSession(id); + } + + public synchronized Map getSessionMap(String adapterGroupName) { + if (!adapterGroup.containsKey(adapterGroupName)) { + adapterGroup.put(adapterGroupName, new WebSocketPool()); + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + return p.getSessionMap(); + } + + public synchronized boolean closeSession(String adapterGroupName, String id) { + if (adapterGroupName == null) { + logger.warn("WebSocketSessionManager] closeSession adapterGroupName is NULL - " + adapterGroupName); + return false; + } + if (!adapterGroup.containsKey(adapterGroupName)) { + logger.warn("WebSocketSessionManager] closeSession adapterGroupName not found - " + adapterGroupName); + return false; + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + if (p == null) { + logger.warn("WebSocketSessionManager] WebSocket is empty, WebSocketPool is NULL - " + adapterGroupName); + return false; + } + WebSocket conn = p.getSession(id); + if (conn == null) { + logger.warn("WebSocketSessionManager] WebSocket Session not found - adapterGroupName : " + adapterGroupName + + ", loginId : " + id); + return false; + } else { + logger.warn( + "WebSocketSessionManager] WebSocket close session - " + + "adapterGroupName : " + adapterGroupName + ", " + + "loginId : " + id + ", " + + "remoteSocketAddress : " + conn.getRemoteSocketAddress()); + p.sessionClose(conn); + return true; + } + } + + public synchronized void sessionError(String adapterGroupName, WebSocket conn) { + // 에러발생시 웹소켓 연결이 끊기지 않음 + try { + if (!adapterGroup.containsKey(adapterGroupName)) { + adapterGroup.put(adapterGroupName, new WebSocketPool()); + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + p.sessionError(conn); + } catch (Exception e) { + logger.error("WebSocketSessionManager] Error Occured in handling session Error", e); + } + } + + public boolean isContainKeys(String adapterGroupName, WebSocket conn) { + if (!adapterGroup.containsKey(adapterGroupName)) { + adapterGroup.put(adapterGroupName, new WebSocketPool()); + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + return p.isContainKeys(conn); + } + + public boolean isContainKeys(String adapterGroupName, String id) { + if (!adapterGroup.containsKey(adapterGroupName)) { + adapterGroup.put(adapterGroupName, new WebSocketPool()); + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + return p.isContainKeys(id); + } + + public List getAdapterGroupNames() { + List groups = new ArrayList(); + Enumeration keys = this.adapterGroup.keys(); + while (keys.hasMoreElements()) { + String key = (String) keys.nextElement(); + groups.add(key); + } + return groups; + } + + /** + * 일자전환관련 - 단말 WebSocket 어댑터를 끊기 위해서 생성 + */ + public synchronized void sessionCloseAdapter(String adapterGroupName) { + if(adapterGroupName == null) { + logger.warn("WebSocketSessionManager] closeSession adapterGroupName is NULL - " + adapterGroupName); + return; + } + if (!adapterGroup.containsKey(adapterGroupName)) { + logger.warn("WebSocketSessionManager] closeSession adapterGroupName not found - " + adapterGroupName); + return; + } + WebSocketPool p = adapterGroup.get(adapterGroupName); + if (p == null) { + logger.warn("WebSocketSessionManager] WebSocket is empty, WebSocketPool is NULL - " + adapterGroupName); + return; + } + p.closeAll(); + logger.warn("WebSocketSessionManager] WebSocket Session close all - adapterGroupName : " + adapterGroupName); + } + + public void closeSessionAll() { + logger.debug("closeSessionAll] Start"); + for (String adapterGroupName : getAdapterGroupNames()) { + try { + /** Upsert DB WebSocket Session Info **/ + getSessionList(adapterGroupName).forEach((k, conn) -> { + String key = getWebSocketConnectionId(adapterGroupName, conn); + if (StringUtils.isNotBlank(key)) { + SessionStatusManager.getInstance().manageWebSocketStatus(key, SessionInfoVO.Status.inactive); + } + }); + + sessionCloseAdapter(adapterGroupName); + logger.debug("closeSessionAll] sessionCloseAdapter -> adapterGroupName["+adapterGroupName+"] closed."); + } catch (Exception e) { + // Logging And Skip + logger.error("closeSessionAll Error : " + e.getMessage(), e); + continue; + } + } + } +} + +class WebSocketPool { + private Set conns; + private Map websockets; + private Map ids; + + public WebSocketPool() { + this.conns = Collections.synchronizedSet(new HashSet()); + this.websockets = new ConcurrentHashMap(); + this.ids = new ConcurrentHashMap(); + } + + public void sessionOpen(WebSocket conn) { + conns.add(conn); + } + + public void sessionLogin(WebSocket conn, String id) { + this.websockets.put(conn, id); + this.ids.put(id, conn); + } + + public void sessionClose(WebSocket conn) { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + String id = this.websockets.get(conn); + this.conns.remove(conn); + this.websockets.remove(conn); + if (id != null) { + this.ids.remove(id); + } + try { + if (conn != null) + conn.close(); + } catch (Exception e) { + logger.error("WebSocketSessionManager] Error Occured in sessionClose", e); + } + } + + public WebSocket getSession(String id) { + if (this.ids.containsKey(id)) { + return this.ids.get(id); + } else { + return null; + } + } + + public Map getSessionMap() { + return ids; + } + + public String getId(WebSocket ws) { + if (this.websockets.containsKey(ws)) { + return this.websockets.get(ws); + } else { + return null; + } + } + + public void sessionError(WebSocket conn) { + String id = this.websockets.get(conn); + this.conns.remove(conn); + this.websockets.remove(conn); + this.ids.remove(id); + } + + public boolean isContainKeys(WebSocket conn) { + return this.websockets.containsKey(conn); + } + + public boolean isContainKeys(String id) { + return this.ids.containsKey(id); + } + + public ConcurrentHashMap getList() { + if (this.ids == null) + return new ConcurrentHashMap(); + return (ConcurrentHashMap) this.ids; + } + + public void closeAll() { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + logger.info("WebSocketPool] closeAll" ); + for(WebSocket conn : this.websockets.keySet()){ + String id = this.websockets.get(conn); + this.conns.remove(conn); + this.websockets.remove(conn); + if (id != null) { + this.ids.remove(id); + } + try { + if(conn != null) conn.close(); + } + catch(Exception e) { + logger.error("WebSocketPool] closeAll Error Occured in sessionClose" + conn, e); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/websocket/servlet/WebSocketAdaptersServlet.java b/src/main/java/com/eactive/eai/adapter/websocket/servlet/WebSocketAdaptersServlet.java new file mode 100644 index 0000000..ad8ed17 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/websocket/servlet/WebSocketAdaptersServlet.java @@ -0,0 +1,128 @@ +package com.eactive.eai.adapter.websocket.servlet; + +import java.net.URLDecoder; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.java_websocket.WebSocket; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.adapter.websocket.WebSocketAdapterManager; +import com.eactive.eai.adapter.websocket.WebSocketHandler; +import com.eactive.eai.adapter.websocket.WebSocketSessionManager; +import com.eactive.eai.common.util.Logger; + + +public class WebSocketAdaptersServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String filter = request.getContext(); + filter = filter.substring(filter.indexOf('/')+1); + if ("websocket".equals(filter)) { + filter = null; + } + + String result = ""; + try { + result = list(filter); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + if (!"".equals(request.getParameter("refresh"))) { + response.appendBody("\n\n"); + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + private String list(String filter) { + boolean verbose = false; + StringBuffer sb = new StringBuffer(); + try{ + filter = URLDecoder.decode(filter,"UTF-8"); + }catch(Exception e){ + + } + + ConcurrentHashMap> adapterGroups = (ConcurrentHashMap)WebSocketAdapterManager.getInstance().getAdapterGroups(); + + String prevAdapterGroupName = ""; + for (Enumeration e = adapterGroups.keys(); e.hasMoreElements();) { + String adapterGroupName = e.nextElement(); + ConcurrentHashMap adapters = adapterGroups.get(adapterGroupName); + + + for (Enumeration ee = adapters.elements() ; ee.hasMoreElements() ;) { + WebSocketHandler adapter = ee.nextElement(); + + if (filter != null + && adapterGroupName.toLowerCase().indexOf(filter.toLowerCase()) == -1 + && String.valueOf(adapter.getPort()).toLowerCase().indexOf(filter.toLowerCase()) == -1 + && adapter.getAdapterVO().getDescription().indexOf(filter.toLowerCase()) == -1 + ) + continue; + + if (!adapterGroupName.equals(prevAdapterGroupName)) { + sb.append("ⓖ " + adapterGroupName); + sb.append("\n"); + } + + //sb.append(" ⓐ "); + sb.append(" ⓐ "); + sb.append(adapter.getAdapterVO().getName()); + sb.append(""); + + sb.append("\n "); + sb.append(""); + sb.append(""); + sb.append(" ServerPort : "+adapter.getPort()); + sb.append(""); + sb.append(""); + + sb.append("\n"); + WebSocketSessionManager manager = WebSocketSessionManager.getInstance(); + ConcurrentHashMap pool = manager.getSessionList(adapterGroupName); + + for (Iterator iii = pool.keySet().iterator() ; iii.hasNext(); ) { + + String key = (String) iii.next(); + WebSocket session = pool.get(key); + + sb.append(" "); + sb.append("⊙ id="+key+" Session :"+session.getLocalSocketAddress() +" <- "+session.getRemoteSocketAddress()); + sb.append("\n"); + } + sb.append(""); + + sb.append("\n"); + + prevAdapterGroupName = adapterGroupName; + } + } + + return "
" + sb.toString() + "
"; + } + + protected boolean getAdapterStatus(String adapterGroupName, String adapterName) { + AdapterManager manager = AdapterManager.getInstance(); + AdapterVO vo = manager.getAdapterVO(adapterGroupName, adapterName); + if (vo != null) { + return vo.isStatus(); + } + return false; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/webt/CustomJTmaxNJGMessageHandler.java b/src/main/java/com/eactive/eai/adapter/webt/CustomJTmaxNJGMessageHandler.java new file mode 100644 index 0000000..3f462d5 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/webt/CustomJTmaxNJGMessageHandler.java @@ -0,0 +1,253 @@ +package com.eactive.eai.adapter.webt; + +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Properties; + +import javax.resource.NotSupportedException; +import javax.transaction.xa.XAException; +import javax.transaction.xa.XAResource; +import javax.transaction.xa.Xid; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.RequestDispatcher; +import com.eactive.eai.common.util.Logger; +import com.tmax.nio.jtmax.JTmaxNJGMessageHandler; +import com.tmax.nio.jtmax.JTmaxNServer; +import com.tmax.nio.jtmax.JTmaxNServiceHandler; +import com.tmax.nio.util.TmaxAliveInfo; + +import jeus.transaction.TxHelper; +import tmax.webt.WebtBuffer; +import tmax.webt.io.WebtStringBuffer; +import tmax.webt.jeus.TmaxXid; + +public class CustomJTmaxNJGMessageHandler implements JTmaxNJGMessageHandler { + private AdapterVO vo; + private Properties prop; + private JTmaxNServer server; + private String serverName; + private int port; + + public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public CustomJTmaxNJGMessageHandler(AdapterVO vo, Properties prop) { + this.vo = vo; + this.prop = prop; + this.serverName = vo.getAdapterGroupName() + "." + vo.getName(); + try { + this.port = Integer.parseInt(prop.getProperty("port.number", "-1")); + } catch (Exception e) { + this.port = -1; + } + } + + private String getJTmaxServerSimpeInfo() { + StringBuilder sb = new StringBuilder(); + sb.append("JTmaxNServer = [").append(serverName).append(":").append(port).append("]"); + return sb.toString(); + } + + private XAResource getXAResource() { + return TxHelper.getTMXAResource(); + } + + @Override + public void bulkRecover(Xid[] xids) throws NotSupportedException { + if (logger.isDebug()) { + logger.debug("bulkRecover start " + getJTmaxServerSimpeInfo()); + } + + if (xids == null) { + logger.debug("xids is null"); + return; + } + + TmaxXid tmaxXid = null; + for (int i = 0; i < xids.length; i++) { + tmaxXid = (TmaxXid) xids[i]; + int decision = tmaxXid.getDecision(); + + if (logger.isDebug()) { + logger.debug("xids[" + i + "] = " + xids[i] + ", decision = " + decision + ", isRecover = " + + tmaxXid.isRecover()); + } + + switch (decision) { + case tmax.webt.io.Webt.TM_XA_COMMIT: + case tmax.webt.io.Webt.TM_XA_COMMIT2: + xaCommit(-1, xids[i], false, null); + break; + case tmax.webt.io.Webt.TM_XA_RBACK: + case tmax.webt.io.Webt.TM_XA_RBACK2: + xaRollback(-1, xids[i], null); + break; + default: + if (logger.isDebug()) { + logger.debug("decision is invalid"); + } + break; + } + } + if (logger.isDebug()) { + logger.debug("bulkRecover end"); + } + } + + @Override + public void closeSession(int sessionId) { + if (logger.isDebug()) { + logger.debug("closeSession start " + getJTmaxServerSimpeInfo()); + logger.debug("closed sessionId = " + sessionId); + logger.debug("closeSession end"); + } + } + + @Override + public void closeTrunk(TmaxAliveInfo info) { + if (logger.isDebug()) { + logger.debug("closeTrunk start " + getJTmaxServerSimpeInfo()); + } + + for (int i = 0; i < info.getTrunkSize(); i++) { + Hashtable table = info.getTrunk(i); + Iterator it = table.keySet().iterator(); + + while (it.hasNext()) { + Integer key = it.next(); + String ip = table.get(key); + if (logger.isDebug()) { + logger.debug("client index = " + key + ", ip = " + ip); + } + } + } + if (logger.isDebug()) { + logger.debug("closeTrunk end"); + } + + } + + @Override + public Xid[] recover() { + if (logger.isDebug()) { + logger.debug("recover start " + getJTmaxServerSimpeInfo()); + } + Xid[] xids = null; + try { + xids = getXAResource().recover(XAResource.TMSTARTRSCAN); + if (xids != null && xids.length == 0) { + xids = getXAResource().recover(XAResource.TMNOFLAGS); + if (logger.isDebug()) + logger.debug("[TMNOFLAGS] recover xids = " + xids); + } + if (xids != null && xids.length == 0) { + xids = getXAResource().recover(XAResource.TMFAIL); + if (logger.isDebug()) + logger.debug("[TMFAIL] recover xids = " + xids); + } + if (xids != null && xids.length == 0) { + xids = getXAResource().recover(XAResource.TMSUSPEND); + if (logger.isDebug()) + logger.debug("[TMSUSPEND] recover xids = " + xids); + } + } catch (XAException e) { + e.printStackTrace(); + return null; + } + + if (logger.isDebug()) + logger.debug("recover xids = " + xids); + + if (xids != null) { + if (logger.isDebug()) { + logger.debug("recover xids length = " + xids.length); + for (int i = 0; i < xids.length; i++) { + logger.debug("xid[" + i + "] = " + xids[i]); + } + } + } + + if (logger.isDebug()) + logger.debug("recover end"); + + return xids; + } + + @Override + public void serviceExecute(int sessionId, String serviceName, WebtBuffer receiveBuffer) { + if (logger.isDebug()) { + logger.debug("serviceExcute(int, String, WebtBuffer) " + "start " + getJTmaxServerSimpeInfo()); + + StringBuilder sb = new StringBuilder(); + sb.append("\nsessionId = ").append(sessionId); + sb.append("\nserviceName = ").append(serviceName); + sb.append("\nreceiveBuffer = ").append(receiveBuffer); + logger.debug(sb.toString()); + + logger.debug("tpacall with TPNOREPLY flag"); + } + + serviceExecute(sessionId, null, serviceName, receiveBuffer, null); + + if (logger.isDebug()) + logger.debug("serviceExcute(int, String, WebtBuffer) end"); + } + + @Override + public void serviceExecute(int sessionId, Xid xid, String serviceName, WebtBuffer receiveBuffer, + JTmaxNServiceHandler serviceHandler) { + if (logger.isDebug()) { + // "FIELD_TYPE", "STRING_TYPE", "CARRAY_TYPE" + logger.debug("@@@@@@@Service Name=" + serviceName + " : BufferTypeString = " + + receiveBuffer.getBufferTypeString()); + logger.debug("@@@@@@@Service Name=" + serviceName + new String(receiveBuffer.getBytes())); + logger.debug("======= serviceExcute(int, String, WebtBuffer, JTmaxNServiceHandler) " + "start =======" + + getJTmaxServerSimpeInfo()); + } + + // 서비스 처리 로직 부분 + byte[] request = receiveBuffer.getBytes(); + byte[] response = request; + try { + RequestDispatcher dispatcher = RequestDispatcher.getRequestDispatcher(vo.getAdapterGroupName()); + response = (byte[]) dispatcher.handle(vo.getName(), request, prop); + } catch (Exception e) { + logger.error("RequestDispatcher call error", e); + } + + WebtBuffer sendBuffer = new WebtStringBuffer(); + sendBuffer.setBytes(response); + if (serviceHandler != null) { + serviceHandler.serviceFinished(JTmaxNServiceHandler.TPSUCCESS, 0, sendBuffer); + } + } + + @Override + public void xaCommit(int sessionId, Xid xid, boolean flag, JTmaxNServiceHandler jtmaxnservicehandler) { + if (logger.isDebug()) { + logger.debug("xaCommit start " + getJTmaxServerSimpeInfo()); + logger.debug("xaCommit end"); + } + } + + @Override + public void xaPrepare(int sessionId, Xid xid, JTmaxNServiceHandler jtmaxnservicehandler) { + if (logger.isDebug()) { + logger.debug("xaPrepare start " + getJTmaxServerSimpeInfo()); + logger.debug("xaPrepare end"); + } + } + + @Override + public void xaRollback(int sessionId, Xid xid, JTmaxNServiceHandler jtmaxnservicehandler) { + if (logger.isDebug()) { + logger.debug("xaRollback start " + getJTmaxServerSimpeInfo()); + // new Thread(new XARollbackWorker(sessionId, xid, serviceHandler)).start(); + logger.debug("xaRollback end"); + } + } + + public void setJTmaxNServer(JTmaxNServer server) { + this.server = server; + } +} diff --git a/src/main/java/com/eactive/eai/adapter/webt/WebTAsyncServerAdapterListener.java b/src/main/java/com/eactive/eai/adapter/webt/WebTAsyncServerAdapterListener.java new file mode 100644 index 0000000..5c10a3e --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/webt/WebTAsyncServerAdapterListener.java @@ -0,0 +1,94 @@ +package com.eactive.eai.adapter.webt; + +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListenerSupport; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.tmax.nio.jtmax.JTmaxNServer; +import com.tmax.nio.jtmax.impl.JTmaxNServerImpl; + +public class WebTAsyncServerAdapterListener extends AdapterListenerSupport { + private static ConcurrentHashMap adapters = new ConcurrentHashMap<>(); + + private static final String PORT_NUMBER = "port.number"; + + @Override + public void start() throws AdapterException { + AdapterPropManager pmanager = AdapterPropManager.getInstance(); + Properties prop = pmanager.getProperties(info.getPropGroupName()); + int portNumber = -1; + int maxConnection = -1; + int maxThread = -1; + try { + if (info == null) { + throw new Exception("WebTAsyncServerAdapterListener | AdapterVO가 NULL입니다."); + } + + try { + portNumber = Integer.parseInt(prop.getProperty(PORT_NUMBER)); + } catch (Exception e) { + throw new Exception( + "WebTAsyncServerAdapterListener | port.number 설정 오류 : " + prop.getProperty("port.number")); + } + + try { + maxConnection = Integer.parseInt(prop.getProperty("max.connection")); + } catch (Exception e) { + maxConnection = 10; + if (logger.isInfo()) + logger.info("set default maxConnection = " + maxConnection); + } + + try { + maxThread = Integer.parseInt(prop.getProperty("max.thread")); + } catch (Exception e) { + maxThread = 10; + if (logger.isInfo()) + logger.info("set default maxThread = " + maxThread); + } + + String name = info.getAdapterGroupName() + "." + info.getName(); + CustomJTmaxNJGMessageHandler handler = new CustomJTmaxNJGMessageHandler(info, prop); + JTmaxNServer server = new JTmaxNServerImpl(name, portNumber, maxConnection, maxThread, + new CustomJTmaxNJGMessageHandler(info, prop)); + handler.setJTmaxNServer(server); + server.setRegister(true); +// server.setThreadPoolQSzie(10); + server.startServer(); + adapters.put(name, server); + + } catch (Exception e) { + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIOIA008"); + logger.error("Start Failed", e); + throw new AdapterException(errCode); + } catch (Throwable t) { + String errCode = ExceptionUtil.getErrorCode(t, "RECEAIOIA008"); + logger.error("Start Failed", t); + throw new AdapterException(errCode); + } + } + + @Override + public void stop() throws AdapterException { + try { + if (info == null) + throw new Exception("WebTAsyncServerAdapterListener | AdapterVO가 NULL입니다."); + String name = info.getAdapterGroupName() + "." + info.getName(); + JTmaxNServer server = null; + if (adapters.containsKey(name)) { + server = adapters.get(name); + server.stopServer(); + adapters.remove(name); + } + } catch (Exception e) { + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIOIA009"); + throw new AdapterException(errCode); + } catch (Throwable t) { + String errCode = ExceptionUtil.getErrorCode(t, "RECEAIOIA009"); + throw new AdapterException(errCode); + } + } +} diff --git a/src/main/java/com/eactive/eai/adapter/webt/WebTClientAdapter.java b/src/main/java/com/eactive/eai/adapter/webt/WebTClientAdapter.java new file mode 100644 index 0000000..6488073 --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/webt/WebTClientAdapter.java @@ -0,0 +1,114 @@ + +package com.eactive.eai.adapter.webt; + +import com.eactive.eai.adapter.ElinkDefaultAdapter; +import com.eactive.eai.adapter.socket2.common.SMSLogger; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.Logger; +import tmax.webt.*; + +import java.util.Properties; + +public class WebTClientAdapter extends ElinkDefaultAdapter { + public static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + public static final String ADAPTER_GORUP_NAME = "ADAPTER_GROUP_NAME"; + + public static final String POOL_NAME = "pool.name"; + public static final String SERVICE_NAME = "service.name"; + public static final String RESPONSE_TYPE = "response.type"; + public static final String HOST_NAME = "host.name"; + public static final String PORT_NUMBER = "port.number"; + public static final String MAX_CONNECTION = "max.connection"; + + public WebTClientAdapter() { + // empty + } + + // -Dwebt.properties= + public Object execute(Properties prop, Object message) throws Exception { + String adapterGroupName = prop.getProperty(ADAPTER_GORUP_NAME); + String adapterName = prop.getProperty("adapterName"); + + byte[] data = null; + if (message instanceof byte[]) { + data = (byte[]) message; + } else if (message instanceof String) { + data = ((String) message).getBytes(); + } else { + throw new Exception("RECEAIAHA011"); + } + + String serviceName = prop.getProperty(SERVICE_NAME, "SEAIRECV"); + String responseType = prop.getProperty(RESPONSE_TYPE, "ASYNC"); + + WebtConnection connection = null; + try { + connection = WebtConnectionPool.getConnection(adapterGroupName + "." + adapterName, 100); + if (logger.isDebug()) { + logger.debug("WebTClientAdapter] ServiceName " + "[" + serviceName + "]"); + } + + WebtRemoteService service = new WebtRemoteService(serviceName, connection); + WebtBuffer request = service.createCarrayBuffer(); + request.setBytes(data); + if (logger.isDebug()) { + logger.debug("WebTClientAdapter] Send Data " + "[" + new String(data) + "]"); + logger.debug("WebTClientAdapter] Send Data dump " + CommonLib.getDumpMessage(data)); + } + + if ("ASYN".equals(responseType)) { + /************************************* + * 테스트 소스, 강제로 WebtIOException 발생 + *********************************** + * if("_OPB_OU_WBT_AsC{CBS_i111}".equals(prop.getProperty("adapterName")) || + * "_OPB_OU_WBT_AsC{CBS_i121}".equals(prop.getProperty("adapterName")) || + * "_OPB_OU_WBT_AsC{CBS_i211}".equals(prop.getProperty("adapterName")) || + * "_OPB_OU_WBT_AsC{CBS_i221}".equals(prop.getProperty("adapterName"))){ throw + * new WebtIOException("Node 1 down, retry test exception throw"); } + * /////////////////////////////////////////////////////////////////////////////////////////// + */ + + WebtAttribute attr = new WebtAttribute(); + attr.setTPNOTIME(true); // 위에서 + attr.setTPNOTRAN(true); + attr.setTPNOREPLY(true); + attr.setTPBLOCK(true); + int response = service.tpacall(request, attr); + data = null; + if (logger.isDebug()) { + logger.debug("WebTClientAdapter] Recv Data Async " + "[" + response + "]"); + } + } else { + WebtAttribute attr = new WebtAttribute(); + attr.setTPNOTIME(true); + attr.setTPNOTRAN(true); + WebtBuffer response = service.tpcall(request, attr); + data = response.getBytes(); + if (logger.isDebug()) { + logger.debug("WebTClientAdapter] Recv Data Sync " + "[" + new String(data) + "]"); + logger.debug("WebTClientAdapter] Recv Data dump " + CommonLib.getDumpMessage(data)); + } + } + } catch (Exception e) { + try { + String errorCode = "RECEAIOWT001"; + String addMsg = ", " + e.getMessage() + ",[" + prop.getProperty(HOST_NAME) + ":" + + prop.getProperty(PORT_NUMBER) + "]"; + SMSLogger.loggingSMSWithCode(errorCode, addMsg); + } catch (Throwable t) { + logger.error("[EAIDEBUG] SMS logging Error occured. but ignore this. - " + t.toString()); + } + throw e; + } finally { + // WebtConnection 객체 반납 + // WebtConnectionPool.putConnection(connection); + if (connection != null) { + connection.close(); + } + } + + return data; + } + +} diff --git a/src/main/java/com/eactive/eai/adapter/webt/WebTClientAdapterListener.java b/src/main/java/com/eactive/eai/adapter/webt/WebTClientAdapterListener.java new file mode 100644 index 0000000..d35f1cc --- /dev/null +++ b/src/main/java/com/eactive/eai/adapter/webt/WebTClientAdapterListener.java @@ -0,0 +1,103 @@ +package com.eactive.eai.adapter.webt; + +import java.util.Properties; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.listener.AdapterException; +import com.eactive.eai.adapter.listener.AdapterListenerSupport; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; + +import tmax.webt.WebtConnectionGroup; +import tmax.webt.WebtConnectionPool; +import tmax.webt.io.WebtConnectionPoolInfo; + +public class WebTClientAdapterListener extends AdapterListenerSupport { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Override + public void start() throws AdapterException { + AdapterPropManager pmanager = AdapterPropManager.getInstance(); + Properties prop = pmanager.getProperties(info.getPropGroupName()); + int portNumber = -1; + int max = -1; + int inc = 2; + + String webtConnGroupLog = ""; + String webtConnInfoLog = ""; + + try { + if (info == null) + throw new Exception("WebTClientAdapterListener | AdapterVO가 NULL입니다."); + String hostName = prop.getProperty("host.name"); + try { + portNumber = Integer.parseInt(prop.getProperty("port.number")); + } catch (Exception e) { + throw new Exception( + "WebTClientAdapterListener | port.number error : " + prop.getProperty("port.number")); + } + try { + max = Integer.parseInt(prop.getProperty("max.connection")); + } catch (Exception e) { + max = 10; + if (logger.isInfo()) + logger.info("WebTClientAdapterListener | max = " + max); + } + + String name = info.getAdapterGroupName() + "." + info.getName(); + WebtConnectionPool.createGroup(name, hostName, portNumber, max, max, inc); + + WebtConnectionGroup webtConnGroup = WebtConnectionPool.getGroup(name); + WebtConnectionPool.startMonitor(5, true, false); // 가이드 필요, webt properties에 설정 + + if (logger.isInfo()) { + webtConnGroupLog = "########### Webt Connection Group Info ################ " + "\n[Name] " + + webtConnGroup.getName() + "\n[Type]" + webtConnGroup.getType() + "\n[Available conn]" + + webtConnGroup.available() + "\n[isActive]" + webtConnGroup.isActive() + "\n[size]" + + webtConnGroup.size() + "\n\n"; + } + + WebtConnectionPoolInfo webtConnInfo = webtConnGroup.getConnectionPoolInfo(); + + if (logger.isInfo()) { + webtConnInfoLog = "########### Webt ConnectionPool Info################ " + "\n[Active Connection Num]" + + webtConnInfo.getActiveConnectionNum() + "\n[Address Info]" + webtConnInfo.getAddressInfo() + + "\n[Init Capacity]" + webtConnInfo.getInitCapacity() + "\n[Max Capacity]" + + webtConnInfo.getMaxCapacity() + "\n[Current PoolSize]" + webtConnInfo.getCurrentPoolSize() + + "\n[Create Count]" + webtConnInfo.getCreateCount() + "\n[Waiting Count]" + + webtConnInfo.getWaitingCount() + "\n[Free Connection Num]" + + webtConnInfo.getFreeConnectionNum() + "\n\n"; + } + if (logger.isInfo()) + logger.info(webtConnGroupLog + webtConnInfoLog); + + info.setStatus(true); + } catch (Exception e) { + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIOIA008"); + logger.error("WebtConnectionPoolInfo Failed", e); + throw new AdapterException(errCode); + } catch (Throwable t) { + String errCode = ExceptionUtil.getErrorCode(t, "RECEAIOIA008"); + logger.error("WebtConnectionPoolInfo Failed", t); + throw new AdapterException(errCode); + } + } + + public void stop() throws AdapterException { + try { + if (info == null) + throw new Exception("WebTClientAdapterListener | AdapterVO가 NULL입니다."); + + String name = info.getAdapterGroupName() + "." + info.getName(); + WebtConnectionPool.destroyGroup(name); + WebtConnectionPool.removeGroup(new String[] { name }); + } catch (Exception e) { + String errCode = ExceptionUtil.getErrorCode(e, "RECEAIOIA009"); + throw new AdapterException(errCode); + } catch (Throwable t) { + String errCode = ExceptionUtil.getErrorCode(t, "RECEAIOIA009"); + logger.error("Start Failed", t); + throw new AdapterException(errCode); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/admin/AdminUtil.java b/src/main/java/com/eactive/eai/admin/AdminUtil.java new file mode 100644 index 0000000..22f7e5e --- /dev/null +++ b/src/main/java/com/eactive/eai/admin/AdminUtil.java @@ -0,0 +1,558 @@ +//package com.eactive.eai.admin; +// +// +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.Iterator; +//import java.util.LinkedHashMap; +//import java.util.Vector; +// +//import com.eactive.eai.common.b2badaptermapping.B2BAdapterMapDAO; +//import com.eactive.eai.common.b2bservice.B2BServiceDAO; +//import com.eactive.eai.common.dao.DAOException; +//import com.eactive.eai.common.dao.DAOFactory; +//import com.eactive.eai.common.property.PropertyDAO; +//import com.eactive.eai.common.server.EAIServerDAO; +//import com.eactive.eai.common.server.EAIServerVO; +// +// +//public class AdminUtil { +// /* +// /** +// * Common 생성자 주석. +// */ +// public AdminUtil() { +// super(); +// } +// /***************************************************************************** +// * 서버리스트 생성 +// *****************************************************************************/ +// public static String getServerList() throws Exception { +// +// Vector dv = new Vector(); +// try { +// +// DAOFactory daoFactory = DAOFactory.newInstance(); +// EAIServerDAO dao = null; +// EAIServerVO ev = null; +// dao = (EAIServerDAO)daoFactory.create(EAIServerDAO.class); +// dv = dao.getServerNm(); +// StringBuffer sb = new StringBuffer(); +// for(int i = 0; i < dv.size(); i++){ +// sb.append("\n"); +// } +// return sb.toString(); +// +// } catch(DAOException e) { +// System.out.println("This is Dao Exception!!!! \n"); +// throw new Exception(e.getMessage()); +// } +//} +// +// /***************************************************************************** +// * 서버리스트 생성 - ALL제외 +// *****************************************************************************/ +// public static String getServerListExceptALL() throws Exception { +// +// Vector dv = new Vector(); +// try { +// +// DAOFactory daoFactory = DAOFactory.newInstance(); +// EAIServerDAO dao = null; +// EAIServerVO ev = null; +// dao = (EAIServerDAO)daoFactory.create(EAIServerDAO.class); +// dv = dao.getServerNmExceptALL(); +// StringBuffer sb = new StringBuffer(); +// for(int i = 0; i < dv.size(); i++){ +// sb.append("\n"); +// } +// return sb.toString(); +// +// } catch(DAOException e) { +// System.out.println("This is Dao Exception!!!! \n"); +// throw new Exception(e.getMessage()); +// } +// } +// +// public static String getServerList(String selectBoxNm) throws Exception { +// +// Vector dv = new Vector(); +// try { +// +// DAOFactory daoFactory = DAOFactory.newInstance(); +// EAIServerDAO dao = null; +// EAIServerVO ev = null; +// dao = (EAIServerDAO)daoFactory.create(EAIServerDAO.class); +// dv = dao.getServerNm(); +// +// StringBuffer sb = new StringBuffer(); +// +// sb.append("\n"); +// return sb.toString(); +// +// } catch(DAOException e) { +// System.out.println("This is Dao Exception!!!! \n"); +// throw new Exception(e.getMessage()); +// } +// } +// +// public static String getServerList(String svrNm, String selectBoxNm) throws Exception { +// +// Vector dv = new Vector(); +// try { +// +// DAOFactory daoFactory = DAOFactory.newInstance(); +// EAIServerDAO dao = null; +// EAIServerVO ev = null; +// dao = (EAIServerDAO)daoFactory.create(EAIServerDAO.class); +// dv = dao.getServerNm(); +// +// StringBuffer sb = new StringBuffer(); +// sb.append("\n"); +// return sb.toString(); +// +// } catch(DAOException e) { +// System.out.println("This is Dao Exception!!!! \n"); +// throw new Exception(e.getMessage()); +// } +// } +// +// public static ArrayList getPropertyGroupList() throws Exception { +// try { +// DAOFactory daoFactory = DAOFactory.newInstance(); +// PropertyDAO dao = (PropertyDAO)daoFactory.create(PropertyDAO.class); +// return dao.getAllPropertyGroups(); +// } catch(DAOException e) { +// System.out.println("This is Dao Exception!!!! \n"); +// throw new Exception(e.getMessage()); +// } +// } +// +//// public static String getSvcSeq()throws Exception{ +//// try{ +//// DAOFactory daoFactory = DAOFactory.newInstance(); +//// CapHeaderDAO dao = (CapHeaderDAO)daoFactory.create(CapHeaderDAO.class); +//// HashMap hm = dao.getServiceSeq(); +//// +//// Iterator it = hm.keySet().iterator(); +//// String svc = ""; +//// ArrayList seq = null; +//// StringBuffer sb = new StringBuffer(); +//// String chk= "false"; +//// while(it.hasNext()){ +//// svc = (String)it.next(); +//// +//// if(chk.equals("false")){ +//// sb.append("if(obj == \"").append(svc).append("\") {\n"); +//// }else{ +//// sb.append("else if(obj == \"").append(svc).append("\") {\n"); +//// } +//// seq = (ArrayList)hm.get(svc); +//// for(int i = 0; i < seq.size(); i++){ +//// System.out.println("seq.get("+i+") >> " +seq.get(i)); +//// sb.append(" objTarget.length++;\n"); +//// sb.append(" objTarget.options[").append(i).append("].text = \"").append(seq.get(i)).append("\";\n"); +//// sb.append(" objTarget.options[").append(i).append("].value = \"").append(seq.get(i)).append("\";\n"); +//// } +//// sb.append("}"); +//// chk = "true"; +//// } +//// +//// return sb.toString(); +//// +//// }catch(DAOException e) { +//// System.out.println("This is DAO Exception \n"); +//// throw new Exception(e.getMessage()); +//// } +//// } +// +// /**** +// /* option에 "선택"을 추가 +// ****/ +//// public static String getSvcSeqWithChoice(String svcName, String seqNum)throws Exception{ +//// try{ +//// DAOFactory daoFactory = DAOFactory.newInstance(); +//// CapHeaderDAO dao = (CapHeaderDAO)daoFactory.create(CapHeaderDAO.class); +//// HashMap hm = dao.getServiceSeq(); +//// +//// Iterator it = hm.keySet().iterator(); +//// String svc = ""; +//// ArrayList seq = null; +//// StringBuffer sb = new StringBuffer(); +//// String chk= "false"; +//// sb.append("if(obj == \"\") {\n"); +//// sb.append(" objTarget.length++;\n"); +//// sb.append(" objTarget.options[0].text =\"선택\";\n"); +//// sb.append(" objTarget.options[0].value =\"\";\n"); +//// sb.append("}"); +//// +//// while(it.hasNext()){ +//// svc = (String)it.next(); +//// +//// sb.append("else if(obj == \"").append(svc).append("\") {\n"); +//// sb.append(" objTarget.length++;\n"); +//// sb.append(" objTarget.options[0].text =\"선택\";\n"); +//// sb.append(" objTarget.options[0].value =\"\";\n"); +//// seq = (ArrayList)hm.get(svc); +//// for(int i = 0; i < seq.size(); i++){ +//// sb.append(" objTarget.length++;\n"); +//// sb.append(" objTarget.options[").append(i+1).append("].text = \"").append(seq.get(i)).append("\";\n"); +//// sb.append(" objTarget.options[").append(i+1).append("].value = \"").append(seq.get(i)).append("\";\n"); +//// if(svcName.equals(svc) && seqNum.equals(seq.get(i))){ +//// sb.append(" objTarget.options[").append(i+1).append("].selected = \"selected\";\n"); +//// +//// } +//// } +//// sb.append("}"); +//// chk = "true"; +//// } +//// +//// return sb.toString(); +//// +//// }catch(DAOException e) { +//// System.out.println("This is DAO Exception \n"); +//// throw new Exception(e.getMessage()); +//// } +//// } +// +//// public static String getSvcSeq(String svcName, String seqNum)throws Exception{ +//// try{ +//// DAOFactory daoFactory = DAOFactory.newInstance(); +//// CapHeaderDAO dao = (CapHeaderDAO)daoFactory.create(CapHeaderDAO.class); +//// LinkedHashMap hm = dao.getServiceSeq(); +//// +//// Iterator it = hm.keySet().iterator(); +//// +//// ArrayList seq = null; +//// String svc = ""; +//// StringBuffer sb = new StringBuffer(); +//// String chk= "false"; +//// +//// while(it.hasNext()){ +//// svc = (String)it.next(); +//// +//// if(chk.equals("false")){ +//// sb.append("if(obj == \"").append(svc).append("\") {\n"); +//// }else{ +//// sb.append("else if(obj == \"").append(svc).append("\") {\n"); +//// } +//// seq = (ArrayList)hm.get(svc); +//// //EAI 서비스 코드 체크 +//// +//// for(int i = 0; i < seq.size(); i++){ +//// sb.append(" objTarget.length++;\n"); +//// sb.append(" objTarget.options[").append(i).append("].text = \"").append(seq.get(i)).append("\";\n"); +//// sb.append(" objTarget.options[").append(i).append("].value = \"").append(seq.get(i)).append("\";\n"); +//// if(svcName.equals(svc) && seqNum.equals(seq.get(i))){ +//// sb.append(" objTarget.options[").append(i).append("].selected = \"selected\";\n"); +//// } +//// } +//// +//// sb.append("}"); +//// chk = "true"; +//// } +//// +//// return sb.toString(); +//// +//// }catch(DAOException e) { +//// System.out.println("This is DAO Exception \n"); +//// throw new Exception(e.getMessage()); +//// } +//// } +// +// /**** +// * EAI서비스 코드를 조회하여 Select Box생성 +// ****/ +// public static String getSvcNameNInstiCd(String svcName)throws Exception{ +// try{ +// DAOFactory daoFactory = DAOFactory.newInstance(); +// B2BServiceDAO dao = (B2BServiceDAO)daoFactory.create(B2BServiceDAO.class); +// LinkedHashMap hm = dao.getB2BSvcNIdnfiName(); +// +// Iterator it = hm.keySet().iterator(); +// String svc = ""; +// ArrayList seq = null; +// StringBuffer sb = new StringBuffer(); +// sb.append("\n"); +// while(it.hasNext()){ +// svc = (String)it.next(); +// if(svc.equals(svcName)){ +// sb.append("\n"); +// }else{ +// sb.append("\n"); +// } +// +// } +// return sb.toString(); +// +// }catch(DAOException e) { +// System.out.println("This is DAO Exception \n"); +// throw new Exception(e.getMessage()); +// } +// } +// +// /**** +// /* EAI서비스 코드 인자를 조건으로 기관 코드를 조회하여 Select Box생성 +// ****/ +// public static String getIdnfiName(String svcName, String idnfiName)throws Exception{ +// try{ +// DAOFactory daoFactory = DAOFactory.newInstance(); +// B2BServiceDAO dao = (B2BServiceDAO)daoFactory.create(B2BServiceDAO.class); +// LinkedHashMap hm = dao.getSvcNIdnfiName(); +// +// Iterator it = hm.keySet().iterator(); +// String svc = ""; +// ArrayList seq = null; +// StringBuffer sb = new StringBuffer(); +// String chk= "false"; +// sb.append("if(obj == \"\") {\n"); +// sb.append(" objTarget.length++;\n"); +// sb.append(" objTarget.options[0].text =\"DEFAULT\";\n"); +// sb.append(" objTarget.options[0].value =\"DEFAULT\";\n"); +// sb.append("}"); +// +// while(it.hasNext()){ +// svc = (String)it.next(); +// +// sb.append("else if(obj == \"").append(svc).append("\") {\n"); +// sb.append(" objTarget.length++;\n"); +// sb.append(" objTarget.options[0].text =\"DEFAULT\";\n"); +// sb.append(" objTarget.options[0].value =\"DEFAULT\";\n"); +// seq = (ArrayList)hm.get(svc); +// for(int i = 0; i < seq.size(); i++){ +// if(! "DEFAULT".equals(seq.get(i))) { +// sb.append(" objTarget.length++;\n"); +// sb.append(" objTarget.options[").append(i+1).append("].text = \"").append(seq.get(i)).append("\";\n"); +// sb.append(" objTarget.options[").append(i+1).append("].value = \"").append(seq.get(i)).append("\";\n"); +// if(svcName.equals(svc) && idnfiName.equals(seq.get(i))){ +// sb.append(" objTarget.options[").append(i+1).append("].selected = \"selected\";\n"); +// } +// } +// } +// sb.append("}"); +// chk = "true"; +// } +// +// return sb.toString(); +// +// }catch(DAOException e) { +// System.out.println("This is DAO Exception \n"); +// throw new Exception(e.getMessage()); +// } +// } +// +// +// /**** +// * option에 "선택"을 추가 +// ****/ +//// public static String getSvcNameWithChoice(String svcName)throws Exception{ +//// try{ +//// DAOFactory daoFactory = DAOFactory.newInstance(); +//// CapHeaderDAO dao = (CapHeaderDAO)daoFactory.create(CapHeaderDAO.class); +//// LinkedHashMap hm = dao.getServiceSeq(); +//// +//// Iterator it = hm.keySet().iterator(); +//// String svc = ""; +//// ArrayList seq = null; +//// StringBuffer sb = new StringBuffer(); +//// sb.append("\n"); +//// while(it.hasNext()){ +//// svc = (String)it.next(); +//// if(svc.equals(svcName)){ +//// sb.append("\n"); +//// }else{ +//// sb.append("\n"); +//// } +//// +//// } +//// +//// return sb.toString(); +//// +//// }catch(DAOException e) { +//// System.out.println("This is DAO Exception \n"); +//// throw new Exception(e.getMessage()); +//// } +//// } +// +//// public static String getSvcName()throws Exception{ +//// try{ +//// DAOFactory daoFactory = DAOFactory.newInstance(); +//// CapHeaderDAO dao = (CapHeaderDAO)daoFactory.create(CapHeaderDAO.class); +//// LinkedHashMap hm = dao.getServiceSeq(); +//// +//// Iterator it = hm.keySet().iterator(); +//// String svc = ""; +//// ArrayList seq = null; +//// StringBuffer sb = new StringBuffer(); +//// String chk= "false"; +//// while(it.hasNext()){ +//// svc = (String)it.next(); +//// if(chk.equals("false")){ +//// sb.append("\n"); +//// }else{ +//// sb.append("\n"); +//// } +//// +//// } +//// +//// return sb.toString(); +//// +//// }catch(DAOException e) { +//// System.out.println("This is DAO Exception \n"); +//// throw new Exception(e.getMessage()); +//// } +//// } +// +// public static String getSvcMsgIDBox(ArrayList msgIDList, String parMsgID)throws Exception{ +// try{ +// +// +// StringBuffer sb = new StringBuffer(); +// +// if(parMsgID == null || parMsgID.equals("")){parMsgID = " _";} +// sb.append("\n"); +// if(msgIDList != null) { +// for(int i = 0; i < msgIDList.size(); i++){ +// +// if(parMsgID.equals(msgIDList.get(i))){ +// sb.append("\n"); +// }else{ +// sb.append("\n"); +// } +// } +// } +// return sb.toString(); +// +// }catch(Exception e) { +// throw new Exception(e.getMessage()); +// } +// } +// +// /**** +// * Adapter그룹및 업무이름을 가져와 Select Box 생성 +// ****/ +// public static String getAdptGrpBox(String adptGrp)throws Exception{ +// try{ +// DAOFactory daoFactory = DAOFactory.newInstance(); +// B2BAdapterMapDAO dao = (B2BAdapterMapDAO)daoFactory.create(B2BAdapterMapDAO.class); +// LinkedHashMap hm = dao.getAdptData(); +// +// Iterator it = hm.keySet().iterator(); +// String adpt = ""; +// ArrayList seq = null; +// StringBuffer sb = new StringBuffer(); +// sb.append("\n"); +// while(it.hasNext()){ +// adpt = (String)it.next(); +// if(adpt.equals(adptGrp)){ +// sb.append("\n"); +// }else{ +// sb.append("\n"); +// } +// +// } +// +// return sb.toString(); +// +// }catch(DAOException e) { +// System.out.println("This is DAO Exception \n"); +// throw new Exception(e.getMessage()); +// } +// } +// +// /**** +// * Adapter그룹및 업무이름을 가져와 Select Box 생성 +// ****/ +// public static String getAdptNameBox(String adptGrp, String adptNm)throws Exception{ +// try{ +// DAOFactory daoFactory = DAOFactory.newInstance(); +// B2BAdapterMapDAO dao = (B2BAdapterMapDAO)daoFactory.create(B2BAdapterMapDAO.class); +// HashMap hm = dao.getAdptData(); +// +// Iterator it = hm.keySet().iterator(); +// String adpt = ""; +// ArrayList nm = null; +// StringBuffer sb = new StringBuffer(); +// String chk= "false"; +// sb.append("if(obj == \"DEFAULT\") {\n"); +// sb.append(" objTarget.length++;\n"); +// sb.append(" objTarget.options[0].text =\"DEFAULT\";\n"); +// sb.append(" objTarget.options[0].value =\"DEFAULT\";\n"); +// sb.append("}"); +// +// while(it.hasNext()){ +// adpt = (String)it.next(); +// +// sb.append("else if(obj == \"").append(adpt).append("\") {\n"); +// sb.append(" objTarget.length++;\n"); +// sb.append(" objTarget.options[0].text =\"DEFAULT\";\n"); +// sb.append(" objTarget.options[0].value =\"DEFAULT\";\n"); +// nm = (ArrayList)hm.get(adpt); +// for(int i = 0; i < nm.size(); i++){ +// sb.append(" objTarget.length++;\n"); +// sb.append(" objTarget.options[").append(i+1).append("].text = \"").append(nm.get(i)).append("\";\n"); +// sb.append(" objTarget.options[").append(i+1).append("].value = \"").append(nm.get(i)).append("\";\n"); +// +// if(adptGrp.equals(adpt) && adptNm.equals(nm.get(i))){ +// sb.append(" objTarget.options[").append(i+1).append("].selected = \"selected\";\n"); +// +// } +// } +// sb.append("}"); +// chk = "true"; +// } +// +// return sb.toString(); +// +// }catch(DAOException e) { +// System.out.println("This is DAO Exception \n"); +// throw new Exception(e.getMessage()); +// } +// } +//} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/admin/FrontFilter.java b/src/main/java/com/eactive/eai/admin/FrontFilter.java new file mode 100644 index 0000000..b185eae --- /dev/null +++ b/src/main/java/com/eactive/eai/admin/FrontFilter.java @@ -0,0 +1,154 @@ +package com.eactive.eai.admin; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; + +public class FrontFilter implements Filter +{ + public static final String PROP_GROUP = "FrontFilter"; + public static final String PROP_KEY1 = "SERVER_LIST"; + public static final String PROP_KEY2 = "CLIENT_LIST"; + private FilterConfig config; + + public void destroy(){ + + } + + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) + throws IOException, ServletException{ + try { + HttpServletRequest request = (HttpServletRequest)req; + HttpServletResponse response = (HttpServletResponse)res; + PropManager manager = PropManager.getInstance(); + String serverList = manager.getProperty(PROP_GROUP,PROP_KEY1); + String clientList = manager.getProperty(PROP_GROUP,PROP_KEY2); + if(serverList==null) { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + logger.warn("FrontFilter] Cannot configure the "+PROP_GROUP+"."+PROP_KEY1+" property."); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"Cannot configure the "+PROP_GROUP+"."+PROP_KEY1+" property."); + return; + } + + if(clientList == null) clientList = ""; + + String[] serverIpList = serverList.split(","); + String[] clientIpList = clientList.split(","); + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + +// logger.warn("FrontFilter] Executed - " + request.getRequestURI()); + + //xecure adapter이여서 filtering pass 하기 위해서 + String requestUri = StringUtils.removeStart(request.getRequestURI(), request.getContextPath()); + if (request.getRequestURI().startsWith("/adapter/http/") + || request.getRequestURI().startsWith("/EAIProxy.jsp") + || request.getRequestURI().startsWith("/HTT/") + || request.getRequestURI().startsWith("/Adapter") + || StringUtils.startsWithIgnoreCase(requestUri, "/api/") + || StringUtils.startsWith(requestUri, "/oauth/") + || StringUtils.equals(requestUri, "/healthcheck.html")){ + if(logger.isDebug()) { + logger.debug("FrontFilter] HTTP anonymous Access allowed page - " + request.getRequestURI()); + } + } + else { + // 2009.04.02 + // Server 리스트와 Client 리스트를 분리하고 + // Pattern 등록 허용 (172.26.128.*) + String remoteAddr = request.getRemoteAddr(); + //String remoteAddr = getClientIP(request); + if( isAllowedIP(serverIpList, remoteAddr) ) { + if(logger.isDebug()) { + logger.debug("FrontFilter] HTTP Access. server IP - " + remoteAddr); + } + } + else if( isAllowedIP(clientIpList, remoteAddr) ) { + if(logger.isDebug()) { + logger.debug("FrontFilter] HTTP Access. client IP - " + remoteAddr); + } + } + else { + if(logger.isWarn()) { + logger.warn("FrontFilter] Invalid Access. - " + remoteAddr); + } + response.sendError(HttpServletResponse.SC_FORBIDDEN, "Invalid Access."); + return; + } + } + + chain.doFilter(req,res); + } catch(Exception e) { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + logger.error("FrontFilter] Error - " + e.getMessage(), e); + throw new ServletException(e.getMessage()); + + } + } + + private boolean isAllowedIP(String[] ipList, String remoteIp) { + + if(ipList == null || ipList.length == 0) { + return false; + } + + for( String allow : ipList ) { + if (allow.indexOf('*') == -1) { + if (allow.equals(remoteIp)) { + return true; + } + } else { + String allowRegexp = allow.replaceAll("\\*", "[0-9]+").trim(); + Matcher matcher = Pattern.compile(allowRegexp, Pattern.CASE_INSENSITIVE).matcher(remoteIp); + if (matcher.matches()) { + return true; + } + } + } + return false; + } + + public void init(FilterConfig config) throws ServletException{ + this.config = config; + if(this.config != null) { + this.config.getFilterName(); + } + } + private String getClientIP(HttpServletRequest request){ + String remoteAddr = request.getHeader("HTTP_X_FORWARDED_FOR"); + if (StringUtils.isBlank(remoteAddr) || !isIp(remoteAddr) ){ + remoteAddr = request.getHeader("Proxy-Client-IP"); + } + if (StringUtils.isBlank(remoteAddr) || !isIp(remoteAddr)){ + remoteAddr = request.getHeader("WL-Proxy-Client-IP"); + } + if (StringUtils.isBlank(remoteAddr) || !isIp(remoteAddr)){ + remoteAddr = request.getRemoteAddr(); + } + return remoteAddr; + } + + private boolean isIp(String ip) { + Matcher matcher = Pattern + .compile("(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)(\\.(25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]?\\d)){3}") + .matcher(ip.trim()); + if (matcher.matches()) { + return true; + } + return false; + } +} diff --git a/src/main/java/com/eactive/eai/agent/AgentUtil.java b/src/main/java/com/eactive/eai/agent/AgentUtil.java new file mode 100644 index 0000000..6dce636 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/AgentUtil.java @@ -0,0 +1,290 @@ + package com.eactive.eai.agent; + +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.ConnectException; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; +import java.util.Properties; +import java.net.ProtocolException; +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; +import java.util.Vector; +import javax.naming.Context; +import javax.naming.InitialContext; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.dao.DAOFactory; +import com.eactive.eai.common.server.EAIServerDAO; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : 등록된 EAI Server 에 Command를 broadcast +* 2. 처리 개요 : 등록된 EAI Server 에 Command를 broadcast +* 3. 주의사항 +* +* @author +* @version v 1.0.0 +* @see 관련 기능을 참조 +* @since +* +*/ +public class AgentUtil +{ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + final static String SERVLET_URL = "/ESBWeb/WebAgent"; + + private static HashMap returnValue; + + /** + * 1. 기능 : AgentUtil 기본 생성자 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param + * @return + * @exception + **/ + private AgentUtil(){ + returnValue = new HashMap(); + } + + /** + * 1. 기능 : 등록된 EAI Server 의 URL을 생성하여 반환 + * 2. 처리 개요 : EAIServerDAO를 통해 데이터베이스에 등록된 EAI Server의 URL을 생성하여 반환 + * 3. 주의사항 + * + * @param + * @return HashMap 등록된 EAI Server 의 URL. + * @exception Exception + **/ + private static HashMap getAllSvrUrl()throws Exception{ + + Map servers = new HashMap<>(); + HashMap urlLists = new HashMap(); + + servers = EAIServerManager.getInstance().getAllServer(false); + + Iterator it = servers.keySet().iterator(); + String svrName = ""; + while( it.hasNext()){ + svrName = (String)it.next(); + try{ + if(! ("ALL".equalsIgnoreCase(svrName))){ + StringBuffer urlBuf = new StringBuffer(); + EAIServerVO vo = (EAIServerVO)servers.get(svrName); + if(vo != null){ + urlBuf.append(vo.toURL(EAIServerVO.HTTP_PROTOCOL)); + urlBuf.append(SERVLET_URL); + logger.debug("AgentUtil] getAllSvrUrl - URL : "+urlBuf.toString()); + + urlLists.put(svrName, urlBuf.toString()); + } + else { + logger.error("AgentUtil] getAllSvrUrl - BroadCast할 서버 정보를 가져올 수 없습니다. "); + } + } + + }catch (Exception e){ + logger.error("AgentUtil] getAllSvrUrl Error. - "+e.getMessage()); + } + } + return urlLists; + + } + + /** + * temp code for test + */ +// private static HashMap getServerUrl() { +// +// HashMap urls = new HashMap(); +// +// urls.put("cgServer", "http://172.17.51.127:8001/ESBWeb/WebAgent"); +// // urls.put("cgServer2", "http://172.17.51.127:7001/ESBWeb/WebAgent"); +// return urls; +// +// } + + /** + * 1. 기능 : 등록된 EAI Server에 Command를 broadcast + * 2. 처리 개요 : 등록된 EAI Server의 URLConnection을 생성하여 Command broadcast하고 + * 전송된 결과값의 HashMap을 생성하여 반환 + * 3. 주의사항 + * + * @param svrName broadcast할 EAI Server명 + * @param url broadcast할 EAI Server의 url + * @param command broadcast할 Command + * @return HashMap broadcast후 전송된 결과값. + * 전송된 데이터가 success가 아니면 Exception이 전송된 것임. + * @exception Exception + **/ + public static HashMap broadcast(String svrName, String url, Command command)throws Exception{ + URLConnection urlCon; + String response = ""; + + if(returnValue == null){ + returnValue = new HashMap(); + } + + if(url !=null){ + urlCon = getURLConnection(url); + try{ + response = sendCommand(urlCon, command); + returnValue.put(svrName, response); + }catch (Exception e){ + logger.error("AgentUtil] broadcast Excpetion", e); + returnValue.put(svrName, e.getMessage()); + } + + }else{ + logger.error("AgentUtil] broadcast Error. - url is null"); + } + return returnValue; + } + + /** + * 1. 기능 : 등록된 EAI Server에 Command를 broadcast + * 2. 처리 개요 : 등록된 EAI Server의 URLConnection을 생성하여 Command broadcast하고 + * 전송된 결과값의 HashMap을 생성하여 반환 + * 3. 주의사항 + * + * @param command broadcast할 Command + * @return HashMap broadcast후 전송된 결과값. + * 전송된 데이터가 success가 아니면 Exception이 전송된 것임. + * @exception Exception + **/ + public static HashMap broadcast(Command command)throws Exception{ + URLConnection urlCon; + HashMap servers = getAllSvrUrl(); + // HashMap servers = getServerUrl(); + + if(returnValue == null){ + returnValue = new HashMap(); + } + + if(servers != null){ + Iterator it = servers.keySet().iterator(); + String svrName = ""; + String url = ""; + String response = ""; + + while( it.hasNext()){ + svrName = (String)it.next(); + url = (String) servers.get(svrName); + + urlCon = getURLConnection(url); + try{ + response = sendCommand(urlCon, command); + returnValue.put(svrName, response); + }catch (Exception e){ + logger.error("AgentUtil] broadcast Excpetion - "+url+ e.getMessage()); + returnValue.put(svrName, e.getMessage()); + } + } + }else{ + logger.error("AgentUtil] broadcast Error. - url is null"); + + } + return returnValue; + } + + + + /** + * 1. 기능 : 해당 URLConnection으로 command 전송 처리 결과를 반환 + * 2. 처리 개요 : 해당 URLConnection으로 command 전송하고 처리 결과를 반환 + * 3. 주의사항 + * + * @param urlCon 연결할 URLConnection + * @param command 전송할 Command + * @return String 처리된 결과 + * @exception Exception + **/ + public static String sendCommand(URLConnection urlCon, Command command)throws Exception{ + ObjectOutputStream oos = null; + ObjectInputStream ois = null; + String response = ""; + + try { + oos = new ObjectOutputStream(urlCon.getOutputStream()); + oos.writeObject(command); + oos.flush(); + logger.debug("AgentUtil] SendCommand - "+urlCon.getURL().toString()); + + ois = new ObjectInputStream(urlCon.getInputStream()); + response = (String)ois.readObject(); + + } catch (ConnectException e) { + logger.error("AgentUtil] sendCommand ConnectException. - "+urlCon.getURL()+ " can't Connect"+e.getMessage()); + throw e; + } catch (IOException e2) { + logger.error("AgentUtil] sendCommand IOException. - "+urlCon.getURL()+ " can't IO" +e2.getMessage()); + throw e2; + } catch (Exception e) { + logger.error("AgentUtil] sendCommand Exception. - "+urlCon.getURL()+e.getMessage()); + throw e; + } finally { + if (oos != null) try { oos.close(); } catch (Exception e) { oos = null; } + if (ois != null) try { ois.close(); } catch (Exception e) { ois = null; } + } + return response; + } + + /** + * 1. 기능 : 지정된 url의 URLConnection 생성 + * 2. 처리 개요 : 지정된 url의 URLConnection 생성 + * 3. 주의사항 + * + * @param url URLConnection을 생성을 위한 url + * @return URLConnection 생성된 URLConnection + * @exception + **/ + public static URLConnection getURLConnection(String url) { + URL u = null; + try { + u = new URL(url); + } catch (MalformedURLException e) { + logger.error("AgentUtil] getURLConnection ", e); + } + + HttpURLConnection conn = null; + + try { + conn = (HttpURLConnection) u.openConnection(); + } catch (Exception e) { + logger.error("openConnection error", e); + } + + if(conn != null){ + conn.setDoInput(true); + conn.setDoOutput(true); + conn.setUseCaches(false); + } + else{ + logger.error("AgentUtil] getURLConnection Error. - " + url +" 의 HttpURLConnection 을 생성할 수 없습니다."); + } + + try { + if(conn != null){ + conn.setRequestMethod("POST"); + } + } catch (ProtocolException pe) { + logger.error("AgentUtil] getURLConnection ", pe); + } + if(conn != null){ + conn.setRequestProperty("Content-type", "application/octet-stream"); + } + return conn; + } + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/agent/adapter/ReloadAdapterGroupCommand.java b/src/main/java/com/eactive/eai/agent/adapter/ReloadAdapterGroupCommand.java new file mode 100644 index 0000000..b039d15 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/adapter/ReloadAdapterGroupCommand.java @@ -0,0 +1,187 @@ +package com.eactive.eai.agent.adapter; + +import java.util.Iterator; +import java.util.Vector; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterManager; +import com.eactive.eai.adapter.http.healthcheck.HttpTargetMonitorManager; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadAdapterGroupCommand extends Command { + private static final long serialVersionUID = 1L; + + private static Object obj = new Object(); + + public ReloadAdapterGroupCommand() { + super("ReloadAdapterGroupCommand"); + } + + /** + * 1. 기능 : AdapterManager에 AdapterGroupVO를 제거 + * 2. 처리 개요 : AdapterGroupVO의 EAISvrInstNm이 DEFAULT_SERVER(ALL) 이거나 LocalServer인 경우 + * AdapterManager에 등록된 해당 AdapterGroupVO를 제거 + * 3. 주의사항 : 테스트용임 + * + * @exception CommandException Argument Type이 다르거나 Command 수행중 Exception이 발생할 경우 + **/ + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + AdapterManager manager = AdapterManager.getInstance(); + + String adapterGroupName = (String) args; + // Stop & Remove Adapter Group + synchronized (obj) { + try { + AdapterGroupVO gvo = manager.getAdapterGroupVO(adapterGroupName); + + if (gvo != null) { + try { + gvo.stop(); + if (logger.isInfo()) + logger.info("AdapterGroupVO[" + adapterGroupName + "] stop()"); + } catch (Exception e) { + if (logger.isInfo()) + logger.info("AdapterGroupVO[" + adapterGroupName + "] not started status- skip stop()"); + // if Error continue... + } + + manager.removeAdapterGroupVO(adapterGroupName); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + + // Load from DB and Start + AdapterGroupVO reloadGroupVO = null; + try { + reloadGroupVO = manager.loadAdapterGroup(adapterGroupName); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + + Vector vt = new Vector<>(); + + String localServerName = EAIServerManager.getInstance().getLocalServerName(); + for (Iterator it = reloadGroupVO.getAdapters(); it.hasNext();) { + AdapterVO avo = it.next(); + if (!com.eactive.eai.common.server.Keys.DEFAULT_SERVER.equals(avo.getEaiSevrInstncName()) + && !localServerName.equals(avo.getEaiSevrInstncName())) { + vt.add(avo.getName()); + } + } + for (int i = 0; i < vt.size(); i++) { + reloadGroupVO.removeAdapterVO(vt.get(i)); + } + + if (reloadGroupVO != null) { + try { + if (logger.isWarn()) + logger.warn("ReloadAdapterGroupCommand] execute. - UsedFlag = " + reloadGroupVO.isUsedFlag()); + if (reloadGroupVO.isUsedFlag()) { + // WCA 어댑터에서 start시 어댑터를 조회하므로 순서를 변경한다. + manager.addAdapterGroupVO(reloadGroupVO); + reloadGroupVO.start(); + } else { + if (logger.isDebug()) + logger.debug("AddAdapterGroupCommand] execute. - UsedFlag = " + reloadGroupVO.isUsedFlag()); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + + } + } else { + if (logger.isWarn()) { + logger.warn("ReloadAdapterGroupCommand] execute. - vo is null"); + } + } + + // HTTP, REST inbound Adapter PathMap reload + try { + reloadHttpPathMap(reloadGroupVO); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + + // HTTP, REST outbound adapter HealthCheck + try { + reloadHttpHealthChecker(reloadGroupVO); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + } + + return "success"; + } + + private void reloadHttpPathMap(AdapterGroupVO reloadGroupVO) throws Exception { + if (reloadGroupVO != null + && (StringUtils.equals(reloadGroupVO.getType(), Keys.TYPE_HTTP) + || StringUtils.equals(reloadGroupVO.getType(), Keys.TYPE_REST)) + && StringUtils.equals(reloadGroupVO.getGubun(), "I")) { + HttpDynamicInAdapterManager manager = HttpDynamicInAdapterManager.getInstance(); + manager.reloadAdapterUrl(reloadGroupVO); + } + } + + private void reloadHttpHealthChecker(AdapterGroupVO reloadGroupVO) { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + HttpTargetMonitorManager manager = HttpTargetMonitorManager.getInstance(); + if(manager == null || !manager.isStarted()) { + logger.info("HttpTargetMonitorManager not used or not started!"); + return; + } + + if (reloadGroupVO != null + && (StringUtils.equals(reloadGroupVO.getType(), Keys.TYPE_HTTP) + || StringUtils.equals(reloadGroupVO.getType(), Keys.TYPE_REST)) + && StringUtils.equals(reloadGroupVO.getGubun(), Keys.ADAPTER_OUT)) { + manager.addAdapterGroup(reloadGroupVO); + } + else { + if(logger.isInfo()) { + String adapterGroupName = (reloadGroupVO == null ? "" : reloadGroupVO.getName()); + logger.info("Not suitable for HttpTargetMonitorManager - " + adapterGroupName ); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/agent/adapter/ReloadAdapterPropGroupCommand.java b/src/main/java/com/eactive/eai/agent/adapter/ReloadAdapterPropGroupCommand.java new file mode 100644 index 0000000..1658e1d --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/adapter/ReloadAdapterPropGroupCommand.java @@ -0,0 +1,64 @@ +package com.eactive.eai.agent.adapter; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +public class ReloadAdapterPropGroupCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadAdapterPropGroupCommand() { + super("ReloadAdapterPropGroupCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + AdapterPropManager manager = AdapterPropManager.getInstance(); + + String keyName = (String) args; + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " is Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// Command command = new ReloadAdapterPropGroupCommand(); +// command.setArgs("ALL"); +// AgentUtil.broadcast(command); +// } +} diff --git a/src/main/java/com/eactive/eai/agent/adapter/RemoveAdapterGroupCommand.java b/src/main/java/com/eactive/eai/agent/adapter/RemoveAdapterGroupCommand.java new file mode 100644 index 0000000..8c147ac --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/adapter/RemoveAdapterGroupCommand.java @@ -0,0 +1,80 @@ +package com.eactive.eai.agent.adapter; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.dynamic.HttpDynamicInAdapterManager; +import com.eactive.eai.adapter.http.healthcheck.HttpTargetMonitorManager; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +public class RemoveAdapterGroupCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveAdapterGroupCommand() { + super("RemoveAdapterGroupCommand"); + } + + /** + * 1. 기능 : AdapterManager에 AdapterGroupVO를 제거 + * 2. 처리 개요 : AdapterGroupVO의 EAISvrInstNm이 DEFAULT_SERVER(ALL) 이거나 LocalServer인 경우 + * AdapterManager에 등록된 해당 AdapterGroupVO를 제거 + * 3. 주의사항 + * + * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 + **/ + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + AdapterManager manager = AdapterManager.getInstance(); + String adapterGroupName = null; + try { + adapterGroupName = (String) args; + AdapterGroupVO gvo = manager.getAdapterGroupVO(adapterGroupName); + if (gvo != null) { + gvo.stop(); + manager.removeAdapterGroupVO(adapterGroupName); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + + // HTTP, REST inbound Adapter PathMap remove + try { + HttpDynamicInAdapterManager dynamicManager = HttpDynamicInAdapterManager.getInstance(); + dynamicManager.removeAdptUriMapByAdapterGroupName(adapterGroupName); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + } + + try { + HttpTargetMonitorManager monitorManager = HttpTargetMonitorManager.getInstance(); + monitorManager.removeHttpHeacthCheckerWithGroupName(adapterGroupName); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + } + + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/agent/adapter/RemoveAdapterPropGroupCommand.java b/src/main/java/com/eactive/eai/agent/adapter/RemoveAdapterPropGroupCommand.java new file mode 100644 index 0000000..893a104 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/adapter/RemoveAdapterPropGroupCommand.java @@ -0,0 +1,82 @@ +package com.eactive.eai.agent.adapter; + +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.wca.util.RuntimeUtil; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +public class RemoveAdapterPropGroupCommand extends Command { + + private static final long serialVersionUID = 1L; + + public RemoveAdapterPropGroupCommand() { + super("RemoveAdapterPropGroupCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + String SNA_PROP_GROUP_NAME = "SNAAdapter{DEFAULT}"; + + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + AdapterPropManager manager = AdapterPropManager.getInstance(); + String key = null; + + if (args != null) { + key = (String) args; + manager.removeAdapterPropGroupVO(key); + + /** + * SNA Adapter notifyAllSoftlink + */ + if (SNA_PROP_GROUP_NAME.equals(key)) { + RuntimeUtil snaUtil = RuntimeUtil.getInstance(); + snaUtil.notifyAllSoftlink(); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + + // public static void main(String args[]) throws Exception { +// test(String args[]); +//} + +//private static void test(String args[]) throws Exception { +// String selectedName = null; +// +// if(args.length ==1) +// selectedName = args[0]; +// +// if(selectedName == null || selectedName.length() ==0){ +// selectedName = "ALL_TEST"; +// } +// +// if(selectedName != null){ +//// System.out.println("RemoveAdapterPropGroupCommand ] vo is not null.... remove start"); +// +// Command command = new RemoveAdapterPropGroupCommand(); +// command.setArgs(selectedName); +// AgentUtil.broadcast(command); +// } +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/authoutbound/ReloadOutboundOAuthCredentialCommand.java b/src/main/java/com/eactive/eai/agent/authoutbound/ReloadOutboundOAuthCredentialCommand.java new file mode 100644 index 0000000..7c6316c --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/authoutbound/ReloadOutboundOAuthCredentialCommand.java @@ -0,0 +1,40 @@ +package com.eactive.eai.agent.authoutbound; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.authoutbound.AccessTokenManagerByDB; +import com.eactive.eai.common.util.Logger; + +public class ReloadOutboundOAuthCredentialCommand extends Command { + private static final long serialVersionUID = 1L; + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Override + public Object execute() throws CommandException { + + if (logger.isInfo()) { + logger.info(this.name + " is executed"); + } + + if (!(args instanceof String)) { + throwCommandException("RECEAIMCM001", null); + } + + try { + String adapterGroupName = (String) args; + AccessTokenManagerByDB.getInstance().refresh(adapterGroupName); + } catch (Exception e) { + throwCommandException("RECEAIMCM002", e); + } + return "success"; + } + + private void throwCommandException(String errorCode, Exception exception) throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + String msg = makeException(errorCode, exception); + if (logger.isError()) { + logger.error(msg, exception); + } + throw new CommandException(msg); + } +} diff --git a/src/main/java/com/eactive/eai/agent/authoutbound/RemoveOutboundOAuthCredentialCommand.java b/src/main/java/com/eactive/eai/agent/authoutbound/RemoveOutboundOAuthCredentialCommand.java new file mode 100644 index 0000000..eb7dbd5 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/authoutbound/RemoveOutboundOAuthCredentialCommand.java @@ -0,0 +1,39 @@ +package com.eactive.eai.agent.authoutbound; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.authoutbound.AccessTokenManagerByDB; +import com.eactive.eai.common.util.Logger; + +public class RemoveOutboundOAuthCredentialCommand extends Command { + private static final long serialVersionUID = 1L; + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Override + public Object execute() throws CommandException { + if (logger.isInfo()) { + logger.info(this.name + " is executed"); + } + + if (!(args instanceof String)) { + throwCommandException("RECEAIMCM001", null); + } + + try { + String adapterGroupName = (String) args; + AccessTokenManagerByDB.getInstance().removeAccessTokenVO(adapterGroupName); + } catch (Exception e) { + throwCommandException("RECEAIMCM002", e); + } + return "success"; + } + + private void throwCommandException(String errorCode, Exception exception) throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + String msg = makeException(errorCode, exception); + if (logger.isError()) { + logger.error(msg, exception); + } + throw new CommandException(msg); + } +} diff --git a/src/main/java/com/eactive/eai/agent/authserver/ReloadApiScopeCommand.java b/src/main/java/com/eactive/eai/agent/authserver/ReloadApiScopeCommand.java new file mode 100644 index 0000000..4acfcad --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/authserver/ReloadApiScopeCommand.java @@ -0,0 +1,58 @@ +package com.eactive.eai.agent.authserver; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.common.util.Logger; +import java.util.Arrays; + +@SuppressWarnings("serial") +public class ReloadApiScopeCommand extends Command { + public static final String COMMAND_TYPE_API = "API"; + public static final String COMMAND_TYPE_SCOPE = "SCOPE"; + public static final String COMMAND_TYPE_API_SCOPE = "API-SCOPE"; + + public ReloadApiScopeCommand() { + super("ReloadApiScopeCommand"); + } + + /** + * args[0]: type(API, SCOPE, API-SCOPE)
+ * args[1]: apiId
+ * args[2]: scopeId + */ + @Override + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String[])) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + OAuth2Manager manager = OAuth2Manager.getInstance(); + + String[] keyName = (String[]) args; + + if (keyName != null) { + manager.reloadApiScopeRelation(keyName); + if (logger.isWarn()) { + logger.warn(this.name + "] " + Arrays.toString(keyName) + " Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/agent/authserver/ReloadClientCommand.java b/src/main/java/com/eactive/eai/agent/authserver/ReloadClientCommand.java new file mode 100644 index 0000000..8bcc648 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/authserver/ReloadClientCommand.java @@ -0,0 +1,49 @@ +package com.eactive.eai.agent.authserver; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.common.util.Logger; + +@SuppressWarnings("serial") +public class ReloadClientCommand extends Command { + + public ReloadClientCommand() { + super("ReloadClientCommand"); + } + + @Override + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + OAuth2Manager manager = OAuth2Manager.getInstance(); + + String keyName = (String) args; + + if (keyName != null) { + manager.reloadClient(keyName); + if (logger.isWarn()) { + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/agent/b2badaptermapping/ReloadB2BAdapterMapCommand.java b/src/main/java/com/eactive/eai/agent/b2badaptermapping/ReloadB2BAdapterMapCommand.java new file mode 100644 index 0000000..00c98f9 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/b2badaptermapping/ReloadB2BAdapterMapCommand.java @@ -0,0 +1,52 @@ +package com.eactive.eai.agent.b2badaptermapping; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.b2badaptermapping.B2BAdapterMapManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadB2BAdapterMapCommand extends Command { + + private static final long serialVersionUID = 1L; + + public ReloadB2BAdapterMapCommand() { + super("ReloadB2BAdapterMapCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + B2BAdapterMapManager manager = B2BAdapterMapManager.getInstance(); + String keyName = (String) args; + + if ("ALL".equals(keyName)) { + manager.reload(); + logger.warn(this.name + ": all rule Reload."); + } else { + manager.reload(keyName); + logger.warn(this.name + ": " + keyName + " Reload."); + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } +} diff --git a/src/main/java/com/eactive/eai/agent/b2badaptermapping/RemoveB2BAdapterMapCommand.java b/src/main/java/com/eactive/eai/agent/b2badaptermapping/RemoveB2BAdapterMapCommand.java new file mode 100644 index 0000000..8cd885b --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/b2badaptermapping/RemoveB2BAdapterMapCommand.java @@ -0,0 +1,42 @@ +package com.eactive.eai.agent.b2badaptermapping; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.b2badaptermapping.B2BAdapterMapManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveB2BAdapterMapCommand extends Command { + + private static final long serialVersionUID = 1L; + + public RemoveB2BAdapterMapCommand() { + super("RemoveB2BAdapterMapCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + B2BAdapterMapManager manager = B2BAdapterMapManager.getInstance(); + try { + String keyName = (String) args; + manager.remove(keyName); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/agent/b2bextractor/ReloadB2BExtractCommand.java b/src/main/java/com/eactive/eai/agent/b2bextractor/ReloadB2BExtractCommand.java new file mode 100644 index 0000000..ce13d85 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/b2bextractor/ReloadB2BExtractCommand.java @@ -0,0 +1,52 @@ +package com.eactive.eai.agent.b2bextractor; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.b2bextractor.B2BExtractManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadB2BExtractCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadB2BExtractCommand() { + super("ReloadB2BExtractCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + B2BExtractManager manager = B2BExtractManager.getInstance(); + String keyName = (String) args; + + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } +} diff --git a/src/main/java/com/eactive/eai/agent/b2bextractor/ReloadB2BExtractListCommand.java b/src/main/java/com/eactive/eai/agent/b2bextractor/ReloadB2BExtractListCommand.java new file mode 100644 index 0000000..81b29fd --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/b2bextractor/ReloadB2BExtractListCommand.java @@ -0,0 +1,58 @@ +package com.eactive.eai.agent.b2bextractor; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.b2bextractor.B2BExtractManager; +import com.eactive.eai.common.util.Logger; + +/** + * 라우팅필드 추출 서비스리스트 메모리 동기화 Command - 오픈뱅킹 EAIServiceLoader_312에서 사용 + * + * @author openbanking + * @since 2019.08 + */ +public class ReloadB2BExtractListCommand extends Command { + + private static final long serialVersionUID = 1L; + private static final Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public ReloadB2BExtractListCommand() { + super("ReloadB2BExtractListCommand"); + } + + @Override + public Object execute() throws CommandException { + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof Vector)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + B2BExtractManager manager = B2BExtractManager.getInstance(); + try { + Vector keyNameVt = (Vector) args; + String keyName = ""; + for (int i = 0; i < keyNameVt.size(); i++) { + keyName = (String) keyNameVt.get(i); + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/agent/b2bextractor/RemoveB2BExtractCommand.java b/src/main/java/com/eactive/eai/agent/b2bextractor/RemoveB2BExtractCommand.java new file mode 100644 index 0000000..776ba72 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/b2bextractor/RemoveB2BExtractCommand.java @@ -0,0 +1,45 @@ +package com.eactive.eai.agent.b2bextractor; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.b2bextractor.B2BExtractManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveB2BExtractCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveB2BExtractCommand() { + super("RemoveB2BExtractCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String key = null; + B2BExtractManager manager = B2BExtractManager.getInstance(); + try { + key = (String) args; + manager.removeB2BExtract(key); + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/b2bservice/ReloadB2BServiceCommand.java b/src/main/java/com/eactive/eai/agent/b2bservice/ReloadB2BServiceCommand.java new file mode 100644 index 0000000..b9d98b8 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/b2bservice/ReloadB2BServiceCommand.java @@ -0,0 +1,57 @@ +package com.eactive.eai.agent.b2bservice; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.b2bservice.B2BServiceManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadB2BServiceCommand extends Command { + + private static final long serialVersionUID = 1L; + private static final Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public ReloadB2BServiceCommand() { + super("ReloadB2BServiceCommand"); + } + + public Object execute() throws CommandException { + + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + B2BServiceManager manager = B2BServiceManager.getInstance(); + String keyName = (String) args; + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/b2bservice/ReloadB2BServiceListCommand.java b/src/main/java/com/eactive/eai/agent/b2bservice/ReloadB2BServiceListCommand.java new file mode 100644 index 0000000..36d16a3 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/b2bservice/ReloadB2BServiceListCommand.java @@ -0,0 +1,52 @@ +package com.eactive.eai.agent.b2bservice; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.b2bservice.B2BServiceManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadB2BServiceListCommand extends Command { + + private static final long serialVersionUID = 1L; + + public ReloadB2BServiceListCommand() { + super("ReloadB2BServiceListCommand"); + } + + @Override + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof Vector)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + B2BServiceManager manager = B2BServiceManager.getInstance(); + try { + Vector keyNameVt = (Vector) args; + String keyName = ""; + for (int i = 0; i < keyNameVt.size(); i++) { + keyName = (String) keyNameVt.get(i); + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/agent/b2bservice/RemoveB2BServiceCommand.java b/src/main/java/com/eactive/eai/agent/b2bservice/RemoveB2BServiceCommand.java new file mode 100644 index 0000000..a75b349 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/b2bservice/RemoveB2BServiceCommand.java @@ -0,0 +1,48 @@ +package com.eactive.eai.agent.b2bservice; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.b2bservice.B2BServiceManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveB2BServiceCommand extends Command { + + private static final long serialVersionUID = 1L; + + public RemoveB2BServiceCommand() { + super("RemoveB2BServiceCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String key = null; + B2BServiceManager manager = B2BServiceManager.getInstance(); + + try { + key = (String) args; + if (key != null) { + manager.removeB2BServiceVO(key); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/bizkey/ReloadBizKeyCommand.java b/src/main/java/com/eactive/eai/agent/bizkey/ReloadBizKeyCommand.java new file mode 100644 index 0000000..b5fd06c --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/bizkey/ReloadBizKeyCommand.java @@ -0,0 +1,63 @@ +package com.eactive.eai.agent.bizkey; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.bizkey.BizKeyManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadBizKeyCommand extends Command { + + private static final long serialVersionUID = 1L; + + public ReloadBizKeyCommand() { + super("ReloadBizKeyCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + BizKeyManager manager = BizKeyManager.getInstance(); + + String keyName = (String) args; + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + String[] keys = keyName.split(","); + manager.reload(keys[0], keys[1]); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String[] args)throws Exception{ +// Command command = new ReloadBizKeyCommand(); +// command.setArgs("ALL"); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/bizkey/ReloadBizKeyListCommand.java b/src/main/java/com/eactive/eai/agent/bizkey/ReloadBizKeyListCommand.java new file mode 100644 index 0000000..eb35ec7 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/bizkey/ReloadBizKeyListCommand.java @@ -0,0 +1,59 @@ +package com.eactive.eai.agent.bizkey; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.bizkey.BizKeyManager; +import com.eactive.eai.common.util.Logger; + +/** + * 업무필드 추출 서비스리스트 메모리 동기화 Command + * - 오픈뱅킹 EAIServiceLoader_312에서 사용 + * + * @author openbanking + * @since 2019.08 + */ +public class ReloadBizKeyListCommand extends Command { + + private static final long serialVersionUID = 1L; + + public ReloadBizKeyListCommand() { + super("ReloadBizKeyListCommand"); + } + + @Override + @SuppressWarnings("unchecked") + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) logger.info(this.name + " is executed"); + + if( !(args instanceof Vector) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) logger.error(msg); + throw new CommandException(msg); + } + + BizKeyManager manager = BizKeyManager.getInstance(); + try { + Vector keyNameVt = (Vector)args; + String keyName =""; + for(int i=0; i"; +// reqMessage = kbmsg.toXMLString(reqMessage); +// } +// else { +// reqMessage = orgMessage; +// } +// +// if (logger.isWarn()) { +// logger.warn(this.name + "] Event Message ["+reqMessage+"]"); +// } +// +// ElinkAdapter adapter = null; +// adapter = ElinkAdapterFactory.newInstance().getElinkAdapter(adptGrpVO.getType()); +// resBytes = (byte[])adapter.callService(vo.getAdptrBzwkGroupName(), adapterProp, reqMessage.getBytes()); +// if (logger.isWarn()) { +// if(resBytes != null) { +// resMessage = new String(resBytes); +// logger.warn(this.name + "] 응답메시지 ["+resMessage+"]"); +// +// if("K".equals(adptrMsgPtrnCd) && "XML".equals(adptrMsgType)) { +// //KBMessage resKbmsg = KBMessageUtil.convert(resMessage); +// STDMessageParser parser = STDMessageParserFactory.createPaserFactory(adptrMsgType); +// if(parser == null) throw new Exception("KBMessageParser not found - " + adptrMsgType); +// STDMessage resKbmsg = parser.convert(resMessage); +// +// String errCd = resKbmsg.getKBCommon().getErrcd(); +// +// if(errCd == null || errCd.trim().length() == 0) { +// result = "1"; +// } +// else { +// result = "0"; +// } +// logger.warn(this.name + "] " + vo.getEvntRecvSysName() + " 응답메시지 KB표준 에러코드 ["+errCd+"]"); +// } +// else { +// if(resMessage.startsWith("succeeded")) { +// result = "1"; +// } +// else { +// result = "0"; +// } +// } +// } +// else { +// logger.warn(this.name + "] 응답메시지 NULL"); +// result = "0"; +// } +// } +// +// } catch(Exception e) { +// if (logger.isError()) { +// logger.warn(this.name + "] 이벤트 송신어댑터("+vo.getAdptrBzwkGroupName()+")가 정상이 아닙니다. ", e); +// } +// result = "0"; +// } +// //-------------------------------------------------------------------- +// +// // 3. Event Result Logging +// recvDateTime = DatetimeUtil.getCurrentDateTime(); // getCurrentTimeMillis +// dao.addEventLog(vo.getEvntRecvSysName(), eventStatus, sendDateTime, recvDateTime, result); +// } +// if (logger.isWarn()) logger.warn(this.name + " Finished"); +// +// } catch (Exception e){ +// String rspErrorCode = "RECEAIMIM002"; +// String msg = makeException(rspErrorCode, e); +// if (logger.isError()) logger.error(msg, e); +// throw new CommandException(msg); +// } +// return "success"; +// } +// +// private STDMessage setKBMessageDefaultValue(STDMessage kbmessage) { +// +// String currDate = DatetimeUtil.getCurrentDate(); +// +// kbmessage.getKBHeader().setTranBaseYmd(currDate); +// +// String guid = UUIDGenerator.getGUID(kbmessage.getKBCommon().getGroupCoCd()); +// kbmessage.getKBHeader().setGuIdNo(guid); +// // 전문형식 - DEFAULT(1) +// kbmessage.getKBHeader().setTelgmFmatDstcd("1"); +// +// // 거래유형구분 - DEFAULT(1) +// kbmessage.getKBCommon().setTranPtrnDstcd("1"); +// // 리바운드 거래여부 - DEFAULT(0) +// kbmessage.getKBCommon().setRbndTranYn("0"); +// +// // 은행코드 - 004 +// kbmessage.getKBCommon().setBnkCd("004"); +// // 거래부점코드 - 1706 +// kbmessage.getKBCommon().setTranBrncd ("1706"); +// +// // 중계채널구분코드 - 02 (EAI) +// kbmessage.getKBCommon().setRelayChnlDstcd("02"); +// +// // 채널구분코드 +// String chnlDstcd = kbmessage.getKBCommon().getChnlDstcd(); +// if(chnlDstcd == null || chnlDstcd.trim().length() == 0) { +// kbmessage.getKBCommon().setChnlDstcd ("06"); +// } +// +// // 채널세부업무구분코드 +// String chnlDBzwkDstcd = kbmessage.getKBCommon().getChnlDBzwkDstcd(); +// if(chnlDBzwkDstcd == null || chnlDBzwkDstcd.trim().length() == 0) { +// kbmessage.getKBCommon().setChnlDBzwkDstcd ("00"); +// } +// +// // 매체구분코드 +// String mdiaDstcd = kbmessage.getKBCommon().getMdiaDstcd(); +// if(mdiaDstcd == null || mdiaDstcd.trim().length() == 0) { +// kbmessage.getKBCommon().setMdiaDstcd ("00"); +// } +// //--------------------------------------- +// +// // 언어구분코드 - KOR : 2008.07.16 +// kbmessage.getKBCommon().setLangDstcd ("KOR"); +// // 단말번호 - 000 +// kbmessage.getKBCommon().setTrmno ("000"); +// // 사용자직원번호 - 0000000 +// kbmessage.getKBCommon().setUserEmpid ("0000000"); +// +// //--------------------------------------------------- +// // KB메시지 입력메시지정보 Default +// //--------------------------------------------------- +// // 입력메시지유형구분코드 - DEFAULT(11) +// kbmessage.getKBCommon().setInptMsgPtrnDstcd("11"); +// +// // 2009.01.05 한진호대리 요청사항 +// kbmessage.getKBCommon().setInptMsgSerno("000"); // (3 ) 입력메시지일련번호 +// +// // 입력메시지 작성일시 (20)- 전문작성일시 +// kbmessage.getKBCommon().setInptMsgWritYms(DatetimeUtil.getCurrentTime()+"000"); +// +// //--------------------------------------------------- +// // KB메시지 승인정보 Default +// // 2008.05.21 강길수차장 요청 +// //--------------------------------------------------- +// // 승인완료구분코드 - 0 +// kbmessage.getKBCommon().setAthorFnshDstcd ("0"); +// // 책임자승인구분코드 - 0 +// kbmessage.getKBCommon().setSpvsrAthorDstcd ("0"); +// //--------------------------------------------------- +// +// //--------------------------------------------------- +// // KB메시지 전행업무공통부 Default +// // 2008.07.10 강길수차장 요청 +// //--------------------------------------------------- +// // (8 ) 기산년월일 +// kbmessage.getKBCommon().setIdtrek("00000000"); +// //(3 ) SOD영업점유형 +// kbmessage.getKBCommon().setSodBbrnPtrnDstcd("000") ; +// //(2 ) SOD사용자유형 +// kbmessage.getKBCommon().setSodUserPtrnDstcd("00"); +// //(1 ) 입출가능여부 +// kbmessage.getKBCommon().setInotAbilYn("0"); +// +// // (1 ) 무자원대체가능사용자여부 : 2008.07.16 +// kbmessage.getKBCommon().setNoRtaUserYn("0"); +// +// // (1 ) 거래중단요청여부 : 2008.07.16 +// kbmessage.getKBCommon().setTranDscnDmndYn("0"); +// +// // (1) 취소유형코드 : 2008.07.16 +// kbmessage.getKBCommon().setCnclPtrnDstcd("0"); +// +// // (1 ) 개별데이터편집여부 : 2008.07.16 +// kbmessage.getKBCommon().setIdiviDataEdtYn("1"); +// return kbmessage; +// +// } +// +//// public static void main(String args[]) throws Exception { +//// test(); +////} +// +//// private static void test() throws Exception { +//// String date = "prepare20090708"; +//// Command command = new CDEventCommand("ChangeDateCommand"); +//// command.setArgs(date); +//// AgentUtil.broadcast(command); +//// } +//} diff --git a/src/main/java/com/eactive/eai/agent/businessday/CDFinishCommand.java b/src/main/java/com/eactive/eai/agent/businessday/CDFinishCommand.java new file mode 100644 index 0000000..e818950 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/businessday/CDFinishCommand.java @@ -0,0 +1,72 @@ +//package com.eactive.eai.agent.businessday; +// +//import com.eactive.eai.agent.AgentUtil; +//import com.eactive.eai.agent.command.Command; +//import com.eactive.eai.agent.command.CommandException; +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.util.Logger; +//import com.kbstar.eai.common.businessday.BusinessDayManager; +//import com.kbstar.eai.common.businessday.BusinessDayVO; +// +///** +//* 1. 기능 : 일자전환 통지 Command +//* 2. 처리 개요 : EAI의 영업이랒를 변경 +//* 3. 주의사항 +//* +//* @author +//* @version v 1.0.0 +//* @see 관련 기능을 참조 +//* @since +//* +//*/ +//public class CDFinishCommand extends Command +//{ +// /** +// * +// */ +// private static final long serialVersionUID = 1L; +// +// /** +// * 1. 기능 : CDPrepareCommand 생성자 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// **/ +// public CDFinishCommand(String name) { +// super(name); +// } +// +// public CDFinishCommand() { +// super("CDFinishCommand"); +// } +// /** +// * 1. 기능 : 일자전환 통지 Command +// * 2. 처리 개요 : EAI의 일자전환상태를 Prepare로 변경 +// * 3. 주의사항 +// * +// * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 +// **/ +// public Object execute() throws CommandException +// { +// Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// if (logger.isWarn()) logger.warn(this.name + " is executed"); +// +// try{ +// PropManager pMan = PropManager.getInstance(); +// pMan.setProperty("BUSINESS_DAY_CHANGE", "CHANGE_STATUS", "F"); +// if (logger.isWarn()) logger.warn(this.name + "] 일자전환 : 일자변환상태[Finish]가 종료로 변경되었습니다."); +// }catch (Exception e){ +// String rspErrorCode = "RECEAIMIM002"; +// String msg = makeException(rspErrorCode, e); +// if (logger.isError()) logger.error(msg, e); +// throw new CommandException(msg); +// } +// return "success"; +// } +// +//// public static void main(String[] args) throws Exception +//// { +//// Command command = new CDFinishCommand("CDPrepareCommand"); +//// AgentUtil.broadcast(command); +//// } +//} diff --git a/src/main/java/com/eactive/eai/agent/businessday/CDPrepareCommand.java b/src/main/java/com/eactive/eai/agent/businessday/CDPrepareCommand.java new file mode 100644 index 0000000..1842e6a --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/businessday/CDPrepareCommand.java @@ -0,0 +1,75 @@ +//package com.eactive.eai.agent.businessday; +// +//import com.eactive.eai.agent.AgentUtil; +//import com.eactive.eai.agent.command.Command; +//import com.eactive.eai.agent.command.CommandException; +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.util.Logger; +//import com.kbstar.eai.common.businessday.BusinessDayManager; +//import com.kbstar.eai.common.businessday.BusinessDayVO; +// +///** +//* 1. 기능 : 일자전환 통지 Command +//* 2. 처리 개요 : EAI의 영업이랒를 변경 +//* 3. 주의사항 +//* +//* @author +//* @version v 1.0.0 +//* @see 관련 기능을 참조 +//* @since +//* +//*/ +//public class CDPrepareCommand extends Command +//{ +// /** +// * +// */ +// private static final long serialVersionUID = 1L; +// +// /** +// * 1. 기능 : CDPrepareCommand 생성자 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// **/ +// public CDPrepareCommand(String name) { +// super(name); +// } +// +// public CDPrepareCommand() { +// super("CDPrepareCommand"); +// } +// /** +// * 1. 기능 : 일자전환 통지 Command +// * 2. 처리 개요 : EAI의 일자전환상태를 Prepare로 변경 +// * 3. 주의사항 +// * +// * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 +// **/ +// public Object execute() throws CommandException +// { +// Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// if (logger.isWarn()) logger.warn(this.name + " is executed"); +// +// try{ +// PropManager pMan = PropManager.getInstance(); +// pMan.setProperty("BUSINESS_DAY_CHANGE", "CHANGE_STATUS", "P"); +// if (logger.isWarn()) logger.warn(this.name + "] 일자전환 : 일자변환상태[Prepare]가 준비로 변경되었습니다."); +// }catch (Exception e){ +// String rspErrorCode = "RECEAIMIM002"; +// String msg = makeException(rspErrorCode, e); +// if (logger.isError()) logger.error(msg, e); +// throw new CommandException(msg); +// } +// return "success"; +// } +// +//// public static void main(String args[]) throws Exception { +//// test(); +////} +// +//// private static void test() throws Exception { +//// Command command = new CDPrepareCommand("CDPrepareCommand"); +//// AgentUtil.broadcast(command); +//// } +//} diff --git a/src/main/java/com/eactive/eai/agent/businessday/CDStandbyCommand.java b/src/main/java/com/eactive/eai/agent/businessday/CDStandbyCommand.java new file mode 100644 index 0000000..581582c --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/businessday/CDStandbyCommand.java @@ -0,0 +1,76 @@ +//package com.eactive.eai.agent.businessday; +// +//import com.eactive.eai.agent.AgentUtil; +//import com.eactive.eai.agent.command.Command; +//import com.eactive.eai.agent.command.CommandException; +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.util.Logger; +//import com.kbstar.eai.common.businessday.BusinessDayManager; +//import com.kbstar.eai.common.businessday.BusinessDayVO; +// +///** +//* 1. 기능 : 일자전환 통지 Command +//* 2. 처리 개요 : EAI의 영업이랒를 변경 +//* 3. 주의사항 +//* +//* @author +//* @version v 1.0.0 +//* @see 관련 기능을 참조 +//* @since +//* +//*/ +//public class CDStandbyCommand extends Command +//{ +// /** +// * +// */ +// private static final long serialVersionUID = 1L; +// +// /** +// * 1. 기능 : CDPrepareCommand 생성자 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// **/ +// public CDStandbyCommand(String name) { +// super(name); +// } +// +// public CDStandbyCommand() { +// super("CDStandbyCommand"); +// } +// /** +// * 1. 기능 : 일자전환 통지 Command +// * 2. 처리 개요 : EAI의 일자전환상태를 Prepare로 변경 +// * 3. 주의사항 +// * +// * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 +// **/ +// public Object execute() throws CommandException +// { +// Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// if (logger.isWarn()) logger.warn(this.name + " is executed"); +// +// try{ +// PropManager pMan = PropManager.getInstance(); +// pMan.setProperty("BUSINESS_DAY_CHANGE", "CHANGE_STATUS", "S"); +// if (logger.isWarn()) logger.warn(this.name + "] 일자전환 : 일자변환상태[standby]가 사전변경으로 변경되었습니다."); +// }catch (Exception e){ +// String rspErrorCode = "RECEAIMIM002"; +// String msg = makeException(rspErrorCode, e); +// if (logger.isError()) logger.error(msg); +//// e.printStackTrace(); +// throw new CommandException(msg); +// } +// return "success"; +// } +// +// // public static void main(String args[]) throws Exception { +//// test(String args[]); +////} +// +////private static void test(String args[]) throws Exception { +//// Command command = new CDStandbyCommand("CDPrepareCommand"); +//// AgentUtil.broadcast(command); +//// } +//} diff --git a/src/main/java/com/eactive/eai/agent/businessday/ChangeDateCommand.java b/src/main/java/com/eactive/eai/agent/businessday/ChangeDateCommand.java new file mode 100644 index 0000000..c25c36b --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/businessday/ChangeDateCommand.java @@ -0,0 +1,86 @@ +//package com.eactive.eai.agent.businessday; +// +//import com.eactive.eai.agent.AgentUtil; +//import com.eactive.eai.agent.command.Command; +//import com.eactive.eai.agent.command.CommandException; +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.util.Logger; +//import com.kbstar.eai.common.businessday.BusinessDayManager; +//import com.kbstar.eai.common.businessday.BusinessDayVO; +// +///** +//* 1. 기능 : 일자전환 통지 Command +//* 2. 처리 개요 : EAI의 영업일자를 변경 +//* 3. 주의사항 +//* +//* @author +//* @version v 1.0.0 +//* @see 관련 기능을 참조 +//* @since +//* +//*/ +//public class ChangeDateCommand extends Command +//{ +// /** +// * +// */ +// private static final long serialVersionUID = 1L; +// +// /** +// * 1. 기능 : UpdateBusinessDayCommand 생성자 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// **/ +// public ChangeDateCommand(String name) { +// super(name); +// } +// +// public ChangeDateCommand() { +// super("ChangeDateCommand"); +// } +// /** +// * 1. 기능 : 일자전환 통지 Command +// * 2. 처리 개요 : EAI의 영업일자를 변경 +// * 3. 주의사항 +// * +// * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 +// **/ +// public Object execute() throws CommandException +// { +// Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// if (logger.isWarn()) logger.warn(this.name + " is executed"); +// +// if( !(args instanceof String) ) { +// String rspErrorCode = "RECEAIMIM001"; +// String msg = makeException(rspErrorCode, null); +// if (logger.isError()) logger.error(msg); +// throw new CommandException(msg); +// } +// +// String bzDate = (String) args; +// try{ +// PropManager pMan = PropManager.getInstance(); +// pMan.setProperty("BUSINESS_DAY_CHANGE", "BUSINESS_DAY", bzDate); +// pMan.setProperty("BUSINESS_DAY_CHANGE", "CHANGE_STATUS", "C"); +// if (logger.isWarn()) logger.warn(this.name + "] 일자전환 : 영업일자["+bzDate+"] 일자변환상태[Commit]가 시작으로 변경되었습니다."); +// }catch (Exception e){ +// String rspErrorCode = "RECEAIMIM002"; +// String msg = makeException(rspErrorCode, e); +// if (logger.isError()) logger.error(msg, e); +// throw new CommandException(msg); +// } +// return "success"; +// } +// +//// public static void main(String args[]) throws Exception { +//// test(); +////} +// +//// private static void test() throws Exception { +//// String date = "20090708"; +//// Command command = new ChangeDateCommand("ChangeDateCommand"); +//// command.setArgs(date); +//// AgentUtil.broadcast(command); +//// } +//} diff --git a/src/main/java/com/eactive/eai/agent/businessday/ReloadBusinessDayCommand.java b/src/main/java/com/eactive/eai/agent/businessday/ReloadBusinessDayCommand.java new file mode 100644 index 0000000..a03d409 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/businessday/ReloadBusinessDayCommand.java @@ -0,0 +1,64 @@ +//package com.eactive.eai.agent.businessday; +// +//import com.eactive.eai.agent.AgentUtil; +//import com.eactive.eai.agent.command.Command; +//import com.eactive.eai.agent.command.CommandException; +//import com.eactive.eai.common.util.Logger; +//import com.kbstar.eai.common.businessday.BusinessDayManager; +// +//public class ReloadBusinessDayCommand extends Command +//{ +// /** +// * +// */ +// private static final long serialVersionUID = 1L; +// +// /** +// * 1. 기능 : ReloadBusinessDayCommand 생성자 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param +// * @return +// * @exception +// **/ +// public ReloadBusinessDayCommand() { +// super("ReloadBusinessDayCommand"); +// } +// +// /** +// * 1. 기능 : BusinessDayManager의 데이터를 DB로부터 Reload +// * 2. 처리 개요 : BusinessDayManager의 reload메소드를 실행하여 DB로부터 Reload +// * 3. 주의사항 +// * +// * @param +// * @return +// * @exception CommandException +// **/ +// public Object execute() throws CommandException +// { +// Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// if (logger.isWarn()) logger.warn(this.name + " is executed"); +// +// try{ +// BusinessDayManager manager = BusinessDayManager.getInstance(); +// +// manager.reload(); +// if(logger.isWarn()) +// logger.warn(this.name + "] 모든 정보가 Reload 되었습니다."); +// }catch (Exception e){ +// String rspErrorCode = "RECEAIMCM002"; +// String msg = makeException(rspErrorCode, e); +// if (logger.isError()) logger.error(msg, e); +// throw new CommandException(msg); +// } +// return "success"; +// } +// +//// public static void main(String[] args)throws Exception{ +//// Command command = new ReloadBusinessDayCommand(); +//// command.setArgs("ALL"); +//// AgentUtil.broadcast(command); +//// +//// } +//} diff --git a/src/main/java/com/eactive/eai/agent/businessday/RemoveBusinessDayCommand.java b/src/main/java/com/eactive/eai/agent/businessday/RemoveBusinessDayCommand.java new file mode 100644 index 0000000..1f3fb91 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/businessday/RemoveBusinessDayCommand.java @@ -0,0 +1,85 @@ +//package com.eactive.eai.agent.businessday; +// +//import com.eactive.eai.agent.AgentUtil; +//import com.eactive.eai.agent.command.Command; +//import com.eactive.eai.agent.command.CommandException; +//import com.eactive.eai.common.util.Logger; +//import com.kbstar.eai.common.businessday.BusinessDayManager; +//import com.kbstar.eai.common.businessday.BusinessDayVO; +// +///** +//* 1. 기능 : Running중인 EAI Server의 메모리에 로딩된 BusinessDayManager의 정보 변경 +//* 2. 처리 개요 : BusinessDayManager에 BusinessDayVO제거 +//* 3. 주의사항 +//* +//* @author +//* @version v 1.0.0 +//* @see 관련 기능을 참조 +//* @since +//* +//*/ +//public class RemoveBusinessDayCommand extends Command +//{ +// /** +// * +// */ +// private static final long serialVersionUID = 1L; +// +// /** +// * 1. 기능 : RemoveBusinessDayCommand 생성자 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// **/ +// public RemoveBusinessDayCommand(String name) { +// super(name); +// } +// +// public RemoveBusinessDayCommand() { +// super("RemoveBusinessDayCommand"); +// } +// +// /** +// * 1. 기능 : BusinessDayManager에 BusinessDayVO제거 +// * 2. 처리 개요 : BusinessDayManager에 BusinessDayVO제거 +// * 3. 주의사항 +// * +// * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 +// **/ +// public Object execute() throws CommandException +// { +// Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// if (logger.isInfo()) logger.info(this.name + " is executed"); +// +// if( !(args instanceof BusinessDayVO) ) { +// String rspErrorCode = "RECEAIMIM001"; +// String msg = makeException(rspErrorCode, null); +// if (logger.isError()) logger.error(msg); +// throw new CommandException(msg); +// } +// +// BusinessDayVO vo = (BusinessDayVO) args; +// try{ +// BusinessDayManager manager = BusinessDayManager.getInstance(); +// manager.removeMessage(vo.getEAISvcName()); +// }catch (Exception e){ +// String rspErrorCode = "RECEAIMIM002"; +// String msg = makeException(rspErrorCode, e); +// if (logger.isError()) logger.error(msg, e); +// throw new CommandException(msg); +// } +// return "success"; +// +// } +// +// // public static void main(String args[]) throws Exception { +//// test(String args[]); +////} +// +////private static void test(String args[]) throws Exception { +//// BusinessDayVO vo = new BusinessDayVO(args[0]); +//// Command command = new RemoveBusinessDayCommand("RemoveBusinessDayCommand"); +//// command.setArgs(vo); +//// AgentUtil.broadcast(command); +//// } +//} diff --git a/src/main/java/com/eactive/eai/agent/businessday/UpdateBusinessDayCommand.java b/src/main/java/com/eactive/eai/agent/businessday/UpdateBusinessDayCommand.java new file mode 100644 index 0000000..4d261f3 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/businessday/UpdateBusinessDayCommand.java @@ -0,0 +1,80 @@ +//package com.eactive.eai.agent.businessday; +// +//import com.eactive.eai.agent.AgentUtil; +//import com.eactive.eai.agent.command.Command; +//import com.eactive.eai.agent.command.CommandException; +//import com.eactive.eai.common.util.Logger; +//import com.kbstar.eai.common.businessday.BusinessDayManager; +//import com.kbstar.eai.common.businessday.BusinessDayVO; +// +///** +//* 1. 기능 : Running중인 EAI Server의 메모리에 로딩된 BusinessDayManager의 정보 변경 +//* 2. 처리 개요 : BusinessDayManager에 BusinessDayVO 데이터 변경 +//* 3. 주의사항 +//* +//* @author +//* @version v 1.0.0 +//* @see 관련 기능을 참조 +//* @since +//* +//*/ +//public class UpdateBusinessDayCommand extends Command +//{ +// /** +// * +// */ +// private static final long serialVersionUID = 1L; +// +// /** +// * 1. 기능 : UpdateBusinessDayCommand 생성자 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// **/ +// public UpdateBusinessDayCommand(String name) { +// super(name); +// } +// +// public UpdateBusinessDayCommand() { +// super("UpdateBusinessDayCommand"); +// } +// /** +// * 1. 기능 : BusinessDayManager에 BusinessDayVO 데이터 변경 +// * 2. 처리 개요 : BusinessDayManager에 BusinessDayVO 데이터 변경 +// * 3. 주의사항 +// * +// * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 +// **/ +// public Object execute() throws CommandException +// { +// Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// if (logger.isInfo()) logger.info(this.name + " is executed"); +// +// if( !(args instanceof BusinessDayVO) ) { +// String rspErrorCode = "RECEAIMIM001"; +// String msg = makeException(rspErrorCode, null); +// if (logger.isError()) logger.error(msg); +// throw new CommandException(msg); +// } +// +// BusinessDayVO vo = (BusinessDayVO) args; +// try{ +// BusinessDayManager manager = BusinessDayManager.getInstance(); +// manager.setMessage(vo); +// }catch (Exception e){ +// String rspErrorCode = "RECEAIMIM002"; +// String msg = makeException(rspErrorCode, e); +// if (logger.isError()) logger.error(msg, e); +// throw new CommandException(msg); +// } +// return "success"; +// } +// +//// public static void main(String[] args) throws Exception +//// { +//// BusinessDayVO vo = new BusinessDayVO(args[0]); +//// Command command = new UpdateBusinessDayCommand("UpdateBusinessDayCommand"); +//// command.setArgs(vo); +//// AgentUtil.broadcast(command); +//// } +//} diff --git a/src/main/java/com/eactive/eai/agent/c2rservice/ReloadC2RServiceCommand.java b/src/main/java/com/eactive/eai/agent/c2rservice/ReloadC2RServiceCommand.java new file mode 100644 index 0000000..172d81d --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/c2rservice/ReloadC2RServiceCommand.java @@ -0,0 +1,55 @@ +package com.eactive.eai.agent.c2rservice; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.c2rservice.C2RServiceManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadC2RServiceCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadC2RServiceCommand() { + super("ReloadC2RServiceCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + C2RServiceManager manager = C2RServiceManager.getInstance(); + String keyName = (String) args; + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/c2rservice/ReloadC2RServiceListCommand.java b/src/main/java/com/eactive/eai/agent/c2rservice/ReloadC2RServiceListCommand.java new file mode 100644 index 0000000..3c47536 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/c2rservice/ReloadC2RServiceListCommand.java @@ -0,0 +1,54 @@ +package com.eactive.eai.agent.c2rservice; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.c2rservice.C2RServiceManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadC2RServiceListCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadC2RServiceListCommand() { + super("ReloadC2RServiceListCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof Vector)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + C2RServiceManager manager = C2RServiceManager.getInstance(); + try { + Vector messageVt = (Vector) args; + String key = ""; + for (int i = 0; i < messageVt.size(); i++) { + key = (String) messageVt.get(i); + + if (key != null) { + manager.reload(key); + if (logger.isWarn()) + logger.warn(this.name + "] " + key + " Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/c2rservice/RemoveC2RServiceCommand.java b/src/main/java/com/eactive/eai/agent/c2rservice/RemoveC2RServiceCommand.java new file mode 100644 index 0000000..7d7efda --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/c2rservice/RemoveC2RServiceCommand.java @@ -0,0 +1,48 @@ +package com.eactive.eai.agent.c2rservice; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.c2rservice.C2RServiceManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveC2RServiceCommand extends Command { + + private static final long serialVersionUID = 1L; + + public RemoveC2RServiceCommand() { + super("RemoveC2RServiceCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String key = null; + C2RServiceManager manager = C2RServiceManager.getInstance(); + + try { + key = (String) args; + if (key != null) { + manager.removeC2RServiceVO(key); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/circuitBreaker/ReloadCircuitBreakerCommand.java b/src/main/java/com/eactive/eai/agent/circuitBreaker/ReloadCircuitBreakerCommand.java new file mode 100644 index 0000000..20dc563 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/circuitBreaker/ReloadCircuitBreakerCommand.java @@ -0,0 +1,22 @@ +package com.eactive.eai.agent.circuitBreaker; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.circuitBreaker.CircuitBreakerManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadCircuitBreakerCommand extends Command { + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Override + public Object execute() throws CommandException { + CircuitBreakerManager circuitBreakerManager = CircuitBreakerManager.getInstance(); + try { + circuitBreakerManager.reload(); + }catch (Exception e) { + throw new CommandException(e.getMessage()); + } + return "success"; + } +} diff --git a/src/main/java/com/eactive/eai/agent/command/Command.java b/src/main/java/com/eactive/eai/agent/command/Command.java new file mode 100644 index 0000000..5342eb4 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/command/Command.java @@ -0,0 +1,84 @@ +package com.eactive.eai.agent.command; + +import java.io.Serializable; +import java.util.HashMap; + +/** +* 1. 기능 : Agent에 의해 실행될 Command 를 정의하기 위한 base class +* 2. 처리 개요 : Agent에 의해 실행될 Command 를 정의하기 위한 base class +* 3. 주의사항 +* +* @author +* @version v 1.0.0 +* @see 관련 기능을 참조 +* @since +* +*/ +public abstract class Command implements Serializable { + private static final long serialVersionUID = 1L; + /** Command object name */ + protected String name; + /** Command Arguments */ + protected Object args; + + private static HashMap errorCode ; + + static { + errorCode = new HashMap<>(); + errorCode.put("RECEAIMCM001", "Command name[{1}] invalid parameter type - {2}"); + errorCode.put("RECEAIMCM002", "Command name[{1}] execute method error - {2}"); + } + + public Command() { + this.name = this.getClass().getName(); + } + + public Command(String name) { + this.name = name; + } + + public void setArgs(Object args) { + this.args = args; + } + + + public abstract Object execute() throws CommandException; + + protected String makeException(String rspErrorCode, Throwable cause){ + String[] msgArgs = new String[2]; + msgArgs[0] = name; + if(cause == null){ + msgArgs[1] = args.toString(); + } + else{ + msgArgs[1] = cause.getMessage(); + } + String msg = makeMessage(errorCode.get(rspErrorCode),msgArgs) ; + + return msg; + } + + private static String makeMessage(String msg, String[] args) { + String keyword = null, head = null, tail = null; + int idx = -1; + for(int i=0;i +* 2. 처리 개요 : Command Logic을 실행하다 발생될 User Define 오류를 처리하기 위한 Exception class
+* 3. 주의사항 +* +* @author +* @version v 1.0.0 +* @see 관련 기능을 참조 +* @since +* +*/ +public class CommandException extends Exception { + + private static final long serialVersionUID = 1L; + + public CommandException() { + super("CommandException is occured."); + } + + /** + * 1. 기능 : Exception message를 초기화하는 Constructor + * 2. 처리 개요 : Exception message를 초기화하는 Constructor + * - + * 3. 주의사항 + * + * @param msg Exception message + **/ + public CommandException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/agent/command/CommonCommand.java b/src/main/java/com/eactive/eai/agent/command/CommonCommand.java new file mode 100644 index 0000000..20ded2e --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/command/CommonCommand.java @@ -0,0 +1,57 @@ +package com.eactive.eai.agent.command; + +import java.lang.reflect.Constructor; + +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : 공통 command +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author +* @version v 1.0.0 +* @see 관련 기능을 참조 +* @since +* +*/ +public class CommonCommand extends Command { + + private static final long serialVersionUID = 1L; + + + public CommonCommand(String name,Object args) { + this.name = name; + this.args = args; + } + + public CommonCommand(String name) { + this.name = name; + } + + public Object execute() throws CommandException + { + if (name.indexOf(".") >=0 ){ + try { + if(this.name != null) this.name = this.name.trim(); + @SuppressWarnings("rawtypes") + Class cl = Class.forName(this.name); + @SuppressWarnings({ "rawtypes", "unchecked" }) + Constructor constructor = cl.getConstructor(); + Object obj = constructor.newInstance(); + Command c = (Command)obj; + c.setArgs(args); + return c.execute(); + + } catch (Exception e) { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + logger.error("CommonCommand Exception "+e.getMessage(),e); + throw new CommandException(e.getMessage()); + } + }else{ + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + throw new CommandException(msg); + } + } +} diff --git a/src/main/java/com/eactive/eai/agent/eaimessage/ReloadEAIMessageCommand.java b/src/main/java/com/eactive/eai/agent/eaimessage/ReloadEAIMessageCommand.java new file mode 100644 index 0000000..d571b0d --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/eaimessage/ReloadEAIMessageCommand.java @@ -0,0 +1,74 @@ +package com.eactive.eai.agent.eaimessage; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.message.EAIMessageManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadEAIMessageCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadEAIMessageCommand() { + super("ReloadEAIMessageCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) { + logger.info(this.name + " is executed"); + } + + if (!(args instanceof String)) { + throwCommandException("RECEAIMCM001", null); + } + + try { + EAIMessageManager manager = EAIMessageManager.getInstance(); + String keyName = (String) args; + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) { + logger.warn(this.name + "] all rule Reload."); + } + } else { + if (keyName.contains(",")) { + reloadKeys(manager, keyName); + } else { + manager.reload(keyName.trim()); + if (logger.isWarn()) { + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + } + } + } catch (Exception e) { + throwCommandException("RECEAIMCM002", e); + } + return "success"; + } + + private void reloadKeys(EAIMessageManager manager, String keyName) throws Exception { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isWarn()) { + logger.warn(this.name + "] Array [" + keyName + "] Reload."); + } + + String[] keys = keyName.split(","); + for (String key : keys) { + if (key != null) { + manager.reload(key.trim()); + } + } + } + + private void throwCommandException(String errorCode, Exception exception) throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + String msg = makeException(errorCode, exception); + if (logger.isError()) { + logger.error(msg, exception); + } + throw new CommandException(msg); + } +} diff --git a/src/main/java/com/eactive/eai/agent/eaimessage/ReloadEAIMessageListCommand.java b/src/main/java/com/eactive/eai/agent/eaimessage/ReloadEAIMessageListCommand.java new file mode 100644 index 0000000..8824d43 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/eaimessage/ReloadEAIMessageListCommand.java @@ -0,0 +1,54 @@ +package com.eactive.eai.agent.eaimessage; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.message.EAIMessageManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadEAIMessageListCommand extends Command { + + private static final long serialVersionUID = 1L; + + public ReloadEAIMessageListCommand() { + super("ReloadEAIMessageListCommand"); + } + + public Object execute() throws CommandException { + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof Vector)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + EAIMessageManager manager = EAIMessageManager.getInstance(); + + Vector keyNameVt = (Vector) args; + String keyName = ""; + for (int i = 0; i < keyNameVt.size(); i++) { + keyName = (String) keyNameVt.get(i); + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } +} diff --git a/src/main/java/com/eactive/eai/agent/eaimessage/RemoveEAIMessageCommand.java b/src/main/java/com/eactive/eai/agent/eaimessage/RemoveEAIMessageCommand.java new file mode 100644 index 0000000..8e3c98f --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/eaimessage/RemoveEAIMessageCommand.java @@ -0,0 +1,52 @@ +package com.eactive.eai.agent.eaimessage; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.message.EAIMessageManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveEAIMessageCommand extends Command{ + private static final long serialVersionUID = 1L; + + public RemoveEAIMessageCommand() { + super("RemoveEAIMessageCommand"); + } + + /** + * 1. 기능 : EAIMessageManager의 EAIMessage 제거 + * 2. 처리 개요 : EAIMessage EAISvrInstNm이 DEFAULT_SERVER(ALL) 이거나 LocalServer인 경우 + * EAIMessageManager의 EAIMessage 제거 + * 3. 주의사항 + * + * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 + **/ + public Object execute() throws CommandException + { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) logger.info(this.name + " is executed"); + + if( !(args instanceof String ) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) logger.error(msg); + throw new CommandException(msg); + } + + try{ + EAIMessageManager manager = EAIMessageManager.getInstance(); + String key = (String)args; + if (key != null){ + manager.removeEAIMessage(key); + } + + }catch (Exception e){ + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) logger.error(msg,e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/eaimessage/RemoveEAIMessageListCommand.java b/src/main/java/com/eactive/eai/agent/eaimessage/RemoveEAIMessageListCommand.java new file mode 100644 index 0000000..7ebeba7 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/eaimessage/RemoveEAIMessageListCommand.java @@ -0,0 +1,64 @@ +package com.eactive.eai.agent.eaimessage; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.message.EAIMessageManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveEAIMessageListCommand extends Command { + + private static final long serialVersionUID = 1L; + + public RemoveEAIMessageListCommand() { + super("RemoveEAIMessageListCommand"); + } + + /** + * 1. 기능 : EAIMessageManager의 EAIMessage 제거 + * 2. 처리 개요 : EAIMessage EAISvrInstNm이 DEFAULT_SERVER(ALL) 이거나 LocalServer인 경우 + * EAIMessageManager의 EAIMessage 제거 + * 3. 주의사항 + * + * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 + **/ + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof Vector)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + EAIMessageManager manager = EAIMessageManager.getInstance(); + + Vector keyNameVt = (Vector) args; + String keyName = ""; + for (int i = 0; i < keyNameVt.size(); i++) { + keyName = (String) keyNameVt.get(i); + if (keyName != null) { + manager.removeEAIMessage(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Remove."); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/eaiserver/ReloadEAIServerCommand.java b/src/main/java/com/eactive/eai/agent/eaiserver/ReloadEAIServerCommand.java new file mode 100644 index 0000000..a1ad4d3 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/eaiserver/ReloadEAIServerCommand.java @@ -0,0 +1,48 @@ +package com.eactive.eai.agent.eaiserver; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadEAIServerCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadEAIServerCommand() { + super("ReloadEAIServerCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + EAIServerManager manager = EAIServerManager.getInstance(); + String name = null; + + name = (String) args; + if (name != null) { + manager.reloadEAIServer(name); + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/eaiserver/RemoveEAIServerCommand.java b/src/main/java/com/eactive/eai/agent/eaiserver/RemoveEAIServerCommand.java new file mode 100644 index 0000000..9857440 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/eaiserver/RemoveEAIServerCommand.java @@ -0,0 +1,46 @@ +package com.eactive.eai.agent.eaiserver; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveEAIServerCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveEAIServerCommand() { + super("RemoveEAIServerCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + EAIServerManager manager = EAIServerManager.getInstance(); + String name = (String) args; + if (name != null) { + manager.removeEAIServer(name); + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/encryption/EncryptionManager.java b/src/main/java/com/eactive/eai/agent/encryption/EncryptionManager.java new file mode 100644 index 0000000..e1e0f2d --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/encryption/EncryptionManager.java @@ -0,0 +1,102 @@ +package com.eactive.eai.agent.encryption; + +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class EncryptionManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static final String GROUP_NAME = "ENCRYPTION"; + + private String encryptYN = ""; + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private EncryptionManager() { + + } + + public static EncryptionManager getInstance() { + return ApplicationContextProvider.getContext().getBean(EncryptionManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICMM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICMM202")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + encryptYN = ""; + encryptYN = PropManager.getInstance().getProperty(GROUP_NAME, System.getProperty(Keys.SERVER_KEY)); + if (encryptYN == null) { + encryptYN = "N"; + } else { + if (encryptYN.trim().length() == 0) { + encryptYN = "N"; + } + } + + logger.warn("EncryptionManager] init :: encryption YN [ " + encryptYN + " ]"); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("EncryptionManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("EncryptionManager] reload all finished ..."); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICMM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + encryptYN = null; + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public String getEncryptYN() { + return encryptYN; + } +} diff --git a/src/main/java/com/eactive/eai/agent/encryption/ReloadEncryptionYNCommand.java b/src/main/java/com/eactive/eai/agent/encryption/ReloadEncryptionYNCommand.java new file mode 100644 index 0000000..3fce85c --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/encryption/ReloadEncryptionYNCommand.java @@ -0,0 +1,65 @@ +package com.eactive.eai.agent.encryption; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +public class ReloadEncryptionYNCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadEncryptionYNCommand() { + super("ReloadEncryptionYNCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "EAIINIT001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + EncryptionManager manager = EncryptionManager.getInstance(); + + String keyName = (String) args; + + if (keyName != null) { + if ("ENC".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] 암호화 여부가 Reload 되었습니다."); + } else { +// String rspErrorCode = "EAIINIT002"; + String msg = "EAIINIT002 암호화 여부 동기화중 keyName [" + keyName + "] 오류가 발생하였습니다. "; + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + } + } catch (Exception e) { + String rspErrorCode = "EAIINIT003"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// Command command = new ReloadEncryptionYNCommand(); +// command.setArgs("ENC"); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/errorcode/ReloadErrorCodeCommand.java b/src/main/java/com/eactive/eai/agent/errorcode/ReloadErrorCodeCommand.java new file mode 100644 index 0000000..1ffb7b9 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/errorcode/ReloadErrorCodeCommand.java @@ -0,0 +1,57 @@ +package com.eactive.eai.agent.errorcode; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.errorcode.ErrorCodeManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadErrorCodeCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadErrorCodeCommand(String name) { + super(name); + } + + public Object execute() throws CommandException { + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof java.lang.String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + ErrorCodeManager manager = ErrorCodeManager.getInstance(); + + String keyName = (String) args; + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/errorcode/RemoveErrorCodeommand.java b/src/main/java/com/eactive/eai/agent/errorcode/RemoveErrorCodeommand.java new file mode 100644 index 0000000..195b57e --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/errorcode/RemoveErrorCodeommand.java @@ -0,0 +1,43 @@ +package com.eactive.eai.agent.errorcode; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.errorcode.ErrorCodeManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveErrorCodeommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveErrorCodeommand(String name) { + super(name); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String msgKey = (String) args; + try { + ErrorCodeManager manager = ErrorCodeManager.getInstance(); + manager.removeMessage(msgKey); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/fcqueuereceiver/ReloadFCReceiverCommand.java b/src/main/java/com/eactive/eai/agent/fcqueuereceiver/ReloadFCReceiverCommand.java new file mode 100644 index 0000000..d2b8af9 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/fcqueuereceiver/ReloadFCReceiverCommand.java @@ -0,0 +1,50 @@ +package com.eactive.eai.agent.fcqueuereceiver; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.flowcontrol.jms.FCQueueReceiverManager; + +public class ReloadFCReceiverCommand extends Command { + + private static final long serialVersionUID = 1L; + + public ReloadFCReceiverCommand() { + super("ReloadFCReceiverCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + FCQueueReceiverManager manager = FCQueueReceiverManager.getInstance(); + + String queRcverName = (String) args; + if (logger.isInfo()) { + logger.info(this.name + " Reload[" + queRcverName + "]"); + } + + if (queRcverName != null) { + manager.loadFCQueueReceiver(queRcverName); + } + + } catch (Exception e) { + if (logger.isError()) + logger.error(e.getMessage(), e); + throw new CommandException(e.getMessage()); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/fcqueuereceiver/RemoveFCReceiverCommand.java b/src/main/java/com/eactive/eai/agent/fcqueuereceiver/RemoveFCReceiverCommand.java new file mode 100644 index 0000000..06eb4b5 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/fcqueuereceiver/RemoveFCReceiverCommand.java @@ -0,0 +1,50 @@ +package com.eactive.eai.agent.fcqueuereceiver; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.flowcontrol.jms.FCQueueReceiverManager; + +public class RemoveFCReceiverCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveFCReceiverCommand() { + super("RemoveFCReceiverCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + + String queRcverName = (String) args; + FCQueueReceiverManager manager = FCQueueReceiverManager.getInstance(); + + if (logger.isInfo()) { + logger.info(this.name + " Remove[" + queRcverName + "]"); + } + if (queRcverName != null) { + manager.removeFCQueueReceiver(queRcverName); + } else { + throw new CommandException("ReceiverName Error - " + queRcverName); + } + + } catch (Exception e) { + if (logger.isError()) + logger.error(e.getMessage(), e); + throw new CommandException(e.getMessage()); + } + return "success"; + + } +} diff --git a/src/main/java/com/eactive/eai/agent/firstaccount/RemoteFirstAccountCommand.java b/src/main/java/com/eactive/eai/agent/firstaccount/RemoteFirstAccountCommand.java new file mode 100644 index 0000000..1110306 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/firstaccount/RemoteFirstAccountCommand.java @@ -0,0 +1,35 @@ +package com.eactive.eai.agent.firstaccount; + +import java.util.HashMap; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +public class RemoteFirstAccountCommand extends Command { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static final long serialVersionUID = 1L; + + public RemoteFirstAccountCommand() { + super("RemoteFirstAccountCommand"); + } + + public Object execute() throws CommandException { + try { + logger.warn("Execute 실행중... "); + HashMap argMap = (HashMap) args; + String accNum = (String) argMap.get("accNum"); + logger.warn("정상적으로 호출되었습니다. accNum=[" + accNum + "]"); + ShareMemory sm = ShareMemory.getInstance(); + sm.setAccoutName(accNum); + + } catch (Exception e) { + String msg = makeException("Error Fist Account", e); + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/eactive/eai/agent/firstaccount/ShareMemory.java b/src/main/java/com/eactive/eai/agent/firstaccount/ShareMemory.java new file mode 100644 index 0000000..affad7d --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/firstaccount/ShareMemory.java @@ -0,0 +1,22 @@ +package com.eactive.eai.agent.firstaccount; + +public class ShareMemory { + private static ShareMemory SINGLETON_INSTANCE = new ShareMemory(); + private String AccoutName = "0000"; + + public static ShareMemory getInstance() { + if (SINGLETON_INSTANCE == null) { + SINGLETON_INSTANCE = new ShareMemory(); + } + return SINGLETON_INSTANCE; + } + + public String getAccoutName() { + return this.AccoutName; + } + + public void setAccoutName(String accoutName) { + this.AccoutName = accoutName; + } + +} diff --git a/src/main/java/com/eactive/eai/agent/httpouttlsinfo/ReloadHttpOutTlsInfoCommand.java b/src/main/java/com/eactive/eai/agent/httpouttlsinfo/ReloadHttpOutTlsInfoCommand.java new file mode 100644 index 0000000..2f73971 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/httpouttlsinfo/ReloadHttpOutTlsInfoCommand.java @@ -0,0 +1,49 @@ +package com.eactive.eai.agent.httpouttlsinfo; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager; + +@SuppressWarnings("serial") +public class ReloadHttpOutTlsInfoCommand extends Command { + + public ReloadHttpOutTlsInfoCommand() { + super("ReloadClientCommand"); + } + + @Override + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + HttpOutTlsInfoManager manager = HttpOutTlsInfoManager.getInstance(); + + String keyName = (String) args; + + if (keyName != null) { + manager.reload(keyName); + if (logger.isWarn()) { + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/agent/httpouttlsinfo/RemoveHttpOutTlsInfoCommand.java b/src/main/java/com/eactive/eai/agent/httpouttlsinfo/RemoveHttpOutTlsInfoCommand.java new file mode 100644 index 0000000..f0c70c0 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/httpouttlsinfo/RemoveHttpOutTlsInfoCommand.java @@ -0,0 +1,51 @@ +package com.eactive.eai.agent.httpouttlsinfo; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager; + +@SuppressWarnings("serial") +public class RemoveHttpOutTlsInfoCommand extends Command { + + public RemoveHttpOutTlsInfoCommand() { + super("ReloadClientCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + HttpOutTlsInfoManager manager = HttpOutTlsInfoManager.getInstance(); + + String keyName = (String) args; + + if (keyName != null && keyName.trim().length() > 0) { + manager.removeHttpOutTlsInfo(keyName); + if (logger.isWarn()) + logger.warn("ReloadLayoutCommand ] " + keyName + " 에 대한 Layout 정보가 메모리에서 삭제되었습니다."); + } else { + if (logger.isWarn()) + logger.warn("ReloadLayoutCommand ] Layout 명을 확인하세요 [" + keyName + "]"); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/agent/inflow/ReloadInflowAdapterControlCommand.java b/src/main/java/com/eactive/eai/agent/inflow/ReloadInflowAdapterControlCommand.java new file mode 100644 index 0000000..5506c0d --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/inflow/ReloadInflowAdapterControlCommand.java @@ -0,0 +1,55 @@ +package com.eactive.eai.agent.inflow; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadInflowAdapterControlCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadInflowAdapterControlCommand() { + super("ReloadInflowAdapterControlCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String keyName = (String) args; + try { + InflowControlManager manager = InflowControlManager.getInstance(); + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reloadAdapter(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reloadAdapter(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/inflow/ReloadInflowInterfaceControlCommand.java b/src/main/java/com/eactive/eai/agent/inflow/ReloadInflowInterfaceControlCommand.java new file mode 100644 index 0000000..ab9dc47 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/inflow/ReloadInflowInterfaceControlCommand.java @@ -0,0 +1,56 @@ +package com.eactive.eai.agent.inflow; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadInflowInterfaceControlCommand extends Command { + + private static final long serialVersionUID = 1L; + + public ReloadInflowInterfaceControlCommand() { + super("ReloadInflowInterfaceControlCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String keyName = (String) args; + try { + InflowControlManager manager = InflowControlManager.getInstance(); + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reloadInterface(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reloadInterface(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/inflow/RemoveInflowAdapterControlCommand.java b/src/main/java/com/eactive/eai/agent/inflow/RemoveInflowAdapterControlCommand.java new file mode 100644 index 0000000..cce81bb --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/inflow/RemoveInflowAdapterControlCommand.java @@ -0,0 +1,41 @@ +package com.eactive.eai.agent.inflow; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveInflowAdapterControlCommand extends Command { + + public RemoveInflowAdapterControlCommand() { + super("RemoveInflowAdapterControlCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String key = (String) args; + try { + InflowControlManager manager = InflowControlManager.getInstance(); + manager.removeAdapter(key); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/eactive/eai/agent/inflow/RemoveInflowInterfaceControlCommand.java b/src/main/java/com/eactive/eai/agent/inflow/RemoveInflowInterfaceControlCommand.java new file mode 100644 index 0000000..597e6fa --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/inflow/RemoveInflowInterfaceControlCommand.java @@ -0,0 +1,40 @@ +package com.eactive.eai.agent.inflow; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.inflow.InflowControlManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveInflowInterfaceControlCommand extends Command { + public RemoveInflowInterfaceControlCommand() { + super("RemoveInflowInterfaceControlCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String key = (String) args; + try { + InflowControlManager manager = InflowControlManager.getInstance(); + manager.removeInterface(key); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/eactive/eai/agent/jms/AddQueueMonitorCommand.java b/src/main/java/com/eactive/eai/agent/jms/AddQueueMonitorCommand.java new file mode 100644 index 0000000..6dcacb3 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/jms/AddQueueMonitorCommand.java @@ -0,0 +1,54 @@ +package com.eactive.eai.agent.jms; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.flowcontrol.jms.QueueMonitorManager; +import com.eactive.eai.flowcontrol.jms.QueueMonitorVO; + +public class AddQueueMonitorCommand extends Command { + private static final long serialVersionUID = 1L; + + public AddQueueMonitorCommand(String name) { + super(name); + } + + public AddQueueMonitorCommand() { + super("AddQueueMonitorCommand"); + } + + public Object execute() throws CommandException { + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof QueueMonitorVO)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + QueueMonitorVO vo = (QueueMonitorVO) args; + + try { + String localServerName = EAIServerManager.getInstance().getLocalServerName(); + // 추가시에는 인스턴스 정보를 확인한다. + if (localServerName != null && localServerName.equals(vo.getSevrInstncName())) { + QueueMonitorManager manager = QueueMonitorManager.getInstance(); + manager.setQueueMonitor(vo); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/eactive/eai/agent/jms/RemoveMessageCommand.java b/src/main/java/com/eactive/eai/agent/jms/RemoveMessageCommand.java new file mode 100644 index 0000000..a0e2a69 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/jms/RemoveMessageCommand.java @@ -0,0 +1,129 @@ +package com.eactive.eai.agent.jms; + +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.util.HashMap; + +import javax.jms.Message; +import javax.jms.ObjectMessage; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.QueueReceiver; +import javax.jms.QueueSession; +import javax.jms.Session; +import javax.naming.InitialContext; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.logger.EAILogSender; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; + +public class RemoveMessageCommand extends Command { + private static final long serialVersionUID = 1L; + public final static String JMS_FACTORY = "com.eactive.eai.common.FlowRouterConnectionFactory"; + + public RemoveMessageCommand() { + super("RemoveMessageCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof HashMap)) { + throw new CommandException("Invalid Args - " + args); + } + + try { + HashMap map = (HashMap) args; + String queueName = (String) map.get("queueName"); + String eaiSvcCd = (String) map.get("eaiSvcCd"); // EAISVCCD + String selector = ""; + + if (eaiSvcCd != null && eaiSvcCd.length() > 0) { + selector = "EAISVCCD='" + eaiSvcCd + "'"; + } + + purgeQueue(queueName, selector, true); + + } catch (Exception e) { + if (logger.isError()) + logger.error("execute", e); + throw new CommandException(e.getMessage()); + } + return "success"; + } + + public static int purgeQueue(String queueName, String mSelector, boolean isLogging) throws Exception { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + int count = 0; + InitialContext ctx = new InitialContext(); + + long sTime = System.currentTimeMillis(); + long cTime = 0; + int purgeCount = 0; + + try { + DateTimeFormatter DATE_FORMAT = DateTimeFormatter.ofPattern("yy/MM/dd kk:mm:ss"); + + QueueConnectionFactory qconFactory = (QueueConnectionFactory) ctx.lookup(JMS_FACTORY); + try (QueueConnection qcon = qconFactory.createQueueConnection(); + QueueSession qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); + QueueReceiver qreceiver = createQueueReceiver(qsession, queueName, ctx, mSelector)) { + qcon.start(); + + logger.warn("RemoveMessageCommand] " + queueName + " - Queued JMS Messages: " + + DATE_FORMAT.format(ZonedDateTime.now())); + cTime = System.currentTimeMillis() - sTime; + sTime = System.currentTimeMillis(); + + Message m = null; + while ((m = qreceiver.receiveNoWait()) != null) { + purgeCount++; + + if (isLogging && m instanceof ObjectMessage) { + processObjectMessage((ObjectMessage) m); + count++; + } + } + + if (logger.isWarn()) { + logger.warn("RemoveMessageCommand] Purge " + purgeCount + " messages completed : connect time(" + + cTime + ") ms, purge time (" + (System.currentTimeMillis() - sTime) + ") ms"); + } + + return count; + } + } catch (Exception e) { + throw e; + } + } + + private static QueueReceiver createQueueReceiver(QueueSession qsession, String queueName, InitialContext ctx, + String mSelector) throws Exception { + javax.jms.Queue queue = (javax.jms.Queue) ctx.lookup(queueName); + return (mSelector != null && mSelector.length() > 0) ? qsession.createReceiver(queue, mSelector) + : qsession.createReceiver(queue); + } + + private static void processObjectMessage(ObjectMessage objMessage) { + try { + EAIMessage eaiMsg = (EAIMessage) objMessage.getObject(); + String rspErrorCode = "RECEAIFQR100"; // 운영자에 의해 큐에서 삭제됨 + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, ""); +// eaiMsg.setRspErrCd(rspErrorCode); +// eaiMsg.setRspErrMsg(rspErrorMsg); + eaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + eaiMsg.setLogPssSno(eaiMsg.getLogPssSno() + 100); + EAILogSender.send(eaiMsg, null); + } catch (Exception e) { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isError()) { + logger.error("RemoveMessageCommand] DB Log 실패 - " + e.getMessage()); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/agent/jms/RemoveQueueMonitorCommand.java b/src/main/java/com/eactive/eai/agent/jms/RemoveQueueMonitorCommand.java new file mode 100644 index 0000000..69ab44b --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/jms/RemoveQueueMonitorCommand.java @@ -0,0 +1,49 @@ +package com.eactive.eai.agent.jms; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.flowcontrol.jms.QueueMonitorManager; +import com.eactive.eai.flowcontrol.jms.QueueMonitorVO; + +public class RemoveQueueMonitorCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveQueueMonitorCommand(String name) { + super(name); + } + + public RemoveQueueMonitorCommand() { + super("RemoveQueueMonitorCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof QueueMonitorVO)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + QueueMonitorVO vo = (QueueMonitorVO) args; + try { + // 삭제시에는 인스턴스 정보가 변경될 수 있으므로 인스턴스정보를 확인하지 않음 + QueueMonitorManager manager = QueueMonitorManager.getInstance(); + manager.removeQueueMonitor(vo.getQueueName()); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/jms/UpdateQueueMonitorCommand.java b/src/main/java/com/eactive/eai/agent/jms/UpdateQueueMonitorCommand.java new file mode 100644 index 0000000..6fa7007 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/jms/UpdateQueueMonitorCommand.java @@ -0,0 +1,54 @@ +package com.eactive.eai.agent.jms; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.flowcontrol.jms.QueueMonitorManager; +import com.eactive.eai.flowcontrol.jms.QueueMonitorVO; + +public class UpdateQueueMonitorCommand extends Command { + private static final long serialVersionUID = 1L; + + public UpdateQueueMonitorCommand(String name) { + super(name); + } + + public UpdateQueueMonitorCommand() { + super("UpdateQueueMonitorCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof QueueMonitorVO)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + QueueMonitorVO vo = (QueueMonitorVO) args; + try { + // 수정 시에는 인스턴스 정보가 변경될 수 있으므로 삭제 후 인스턴스정보를 확인하고 등록한다. + String localServerName = EAIServerManager.getInstance().getLocalServerName(); + + QueueMonitorManager manager = QueueMonitorManager.getInstance(); + manager.removeQueueMonitor(vo.getQueueName()); + if (localServerName != null && localServerName.equals(vo.getSevrInstncName())) { + manager.setQueueMonitor(vo); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/eactive/eai/agent/lifecycle/RemoveLifecycleCommand.java b/src/main/java/com/eactive/eai/agent/lifecycle/RemoveLifecycleCommand.java new file mode 100644 index 0000000..7e8e673 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/lifecycle/RemoveLifecycleCommand.java @@ -0,0 +1,61 @@ +package com.eactive.eai.agent.lifecycle; + +import com.eactive.eai.agent.AgentUtil; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.lifecycle.LifecycleManager; +import com.eactive.eai.common.lifecycle.LifecycleVO; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +public class RemoveLifecycleCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveLifecycleCommand(String name) { + super(name); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String keyName = (String) args; + + try { + LifecycleManager manager = ApplicationContextProvider.getContext().getBean(LifecycleManager.class); + if (manager != null || keyName != null) { + manager.removeLifecycle(keyName); + } else { + throw new Exception("keyName is null"); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + + // public static void main(String args[]) throws Exception { +// test(String args[]); +//} + +//private static void test(String args[]) throws Exception { +// LifecycleVO vo = new LifecycleVO(args[0], -1); +// Command command = new RemoveLifecycleCommand("RemoveLifecycleCommand"); +// command.setArgs(vo); +// AgentUtil.broadcast(command); +// } +} diff --git a/src/main/java/com/eactive/eai/agent/messagekey/ReloadMessageKeyCommand.java b/src/main/java/com/eactive/eai/agent/messagekey/ReloadMessageKeyCommand.java new file mode 100644 index 0000000..819cd14 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/messagekey/ReloadMessageKeyCommand.java @@ -0,0 +1,69 @@ +package com.eactive.eai.agent.messagekey; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.messagekey.MessageKeyManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadMessageKeyCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadMessageKeyCommand() { + super("ReloadMessageKeyCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + MessageKeyManager manager = MessageKeyManager.getInstance(); + String keyName = (String) args; + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + String[] keys = keyName.split(","); + manager.reload(keys[0], keys[1]); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + + } + } else { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// Command command = new ReloadMessageKeyCommand(); +// command.setArgs("ALL"); +// AgentUtil.broadcast(command); +// } +} diff --git a/src/main/java/com/eactive/eai/agent/messagekey/ReloadMessageKeyListCommand.java b/src/main/java/com/eactive/eai/agent/messagekey/ReloadMessageKeyListCommand.java new file mode 100644 index 0000000..5164e9c --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/messagekey/ReloadMessageKeyListCommand.java @@ -0,0 +1,61 @@ +package com.eactive.eai.agent.messagekey; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.messagekey.MessageKeyManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadMessageKeyListCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadMessageKeyListCommand() { + super("ReloadMessageKeyListCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof Vector)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + MessageKeyManager manager = MessageKeyManager.getInstance(); + Vector keyNameVt = (Vector) args; + String keyName = ""; + for (int i = 0; i < keyNameVt.size(); i++) { + keyName = (String) keyNameVt.get(i); + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// Command command = new ReloadMessageKeyListCommand(); +// command.setArgs("ALL"); +// AgentUtil.broadcast(command); +// } +} diff --git a/src/main/java/com/eactive/eai/agent/messagekey/RemoveMessageKeyCommand.java b/src/main/java/com/eactive/eai/agent/messagekey/RemoveMessageKeyCommand.java new file mode 100644 index 0000000..7291bb8 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/messagekey/RemoveMessageKeyCommand.java @@ -0,0 +1,74 @@ +package com.eactive.eai.agent.messagekey; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.messagekey.MessageKeyManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveMessageKeyCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveMessageKeyCommand() { + super("RemoveMessageKeyCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + String keyName = null; + MessageKeyManager manager = MessageKeyManager.getInstance(); + + keyName = (String) args; + if (keyName != null) { + String[] keys = keyName.split(","); + String keyCode = keys[0] + keys[1]; + manager.removeMessageKey(keyCode); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String[] args)throws Exception{ +// String selectedName = null; +// String updateData = null; +// +// if(args.length ==1) +// selectedName = args[0]; +// +// if(selectedName == null || selectedName.length() ==0){ +// selectedName = "HttpAdapter_STD_IN_TEST"; +// } +// +// MessageKeyManager manager = MessageKeyManager.getInstance(); +// MessageKeyVO vo = new MessageKeyVO(selectedName); +// +// if(vo != null){ +// System.out.println("RemoveMessageKeyCommand ] vo is not null.... remove start"); +// +// Command command = new RemoveMessageKeyCommand(); +// command.setArgs(vo); +// AgentUtil.broadcast(command); +// } +// else{ +// System.out.println("RemoveMessageKeyCommand ] main() vo is null"); +// } +// } +} diff --git a/src/main/java/com/eactive/eai/agent/property/ReloadPropertyCommand.java b/src/main/java/com/eactive/eai/agent/property/ReloadPropertyCommand.java new file mode 100644 index 0000000..23ae3f1 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/property/ReloadPropertyCommand.java @@ -0,0 +1,62 @@ +package com.eactive.eai.agent.property; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadPropertyCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadPropertyCommand() { + super("ReloadPropertyCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + PropManager manager = PropManager.getInstance(); + + String keyName = (String) args; + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reload(keyName); + + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String[] args)throws Exception{ +// Command command = new ReloadPropertyCommand(); +// command.setArgs("ALL"); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/property/RemovePropertyCommand.java b/src/main/java/com/eactive/eai/agent/property/RemovePropertyCommand.java new file mode 100644 index 0000000..7e1171d --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/property/RemovePropertyCommand.java @@ -0,0 +1,61 @@ +package com.eactive.eai.agent.property; + +import com.eactive.eai.adapter.wca.util.RuntimeUtil; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; + +public class RemovePropertyCommand extends Command { + + private static final long serialVersionUID = 1L; + + public RemovePropertyCommand() { + super("RemovePropertyCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + String SNA_PROP_GROUP_NAME = "SNAAdapter{DEFAULT}"; + + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + PropManager manager = PropManager.getInstance(); + String propertyName = null; + + if (args != null) { + propertyName = (String) args; + manager.removePropGroupVO(propertyName); + +// System.out.println("RemovePropertyCommand grpName ] "+propertyName); + + /** + * SNA Adapter notifyAllSoftlink + */ + if (SNA_PROP_GROUP_NAME.equals(propertyName)) { + RuntimeUtil snaUtil = RuntimeUtil.getInstance(); + snaUtil.notifyAllSoftlink(); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/restrict/ReloadRestrictInfoCommand.java b/src/main/java/com/eactive/eai/agent/restrict/ReloadRestrictInfoCommand.java new file mode 100644 index 0000000..c0c21ba --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/restrict/ReloadRestrictInfoCommand.java @@ -0,0 +1,53 @@ +package com.eactive.eai.agent.restrict; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.restrict.RestrictInfoManager; +import com.eactive.eai.common.util.Logger; + +/** + * 거래통제 Reload 커맨트 + * + * @Author : S010795 + * @Date : 2019. 5. 15. + * @Version : + */ +public class ReloadRestrictInfoCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadRestrictInfoCommand() { + super("ReloadRestrictInfoCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isWarn()) + logger.warn(this.name + " is executed"); + + try { + RestrictInfoManager manager = RestrictInfoManager.getInstance(); + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// Command command = new ReloadRestrictInfoCommand(); +// command.setArgs("ALL"); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/routing/ReloadRoutingCommand.java b/src/main/java/com/eactive/eai/agent/routing/ReloadRoutingCommand.java new file mode 100644 index 0000000..ff43445 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/routing/ReloadRoutingCommand.java @@ -0,0 +1,57 @@ +package com.eactive.eai.agent.routing; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.routing.RoutingManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadRoutingCommand extends Command { + + private static final long serialVersionUID = 1L; + + public ReloadRoutingCommand() { + super("ReloadRoutingCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + RoutingManager manager = RoutingManager.getInstance(); + String keyName = null; + + keyName = (String) args; + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/routing/RemoveRoutingCommand.java b/src/main/java/com/eactive/eai/agent/routing/RemoveRoutingCommand.java new file mode 100644 index 0000000..da48863 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/routing/RemoveRoutingCommand.java @@ -0,0 +1,78 @@ +package com.eactive.eai.agent.routing; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.routing.RoutingManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveRoutingCommand extends Command { + + private static final long serialVersionUID = 1L; + + public RemoveRoutingCommand() { + super("RemoveRoutingCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + RoutingManager manager = RoutingManager.getInstance(); + String key = null; + + key = (String) args; + if (key != null) { + manager.removeRoutingVO(key); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + + // public static void main(String args[]) throws Exception { +// test(String args[]); +//} + +//private static void test(String args[]) throws Exception { +// String selectedName = null; +//// String updateData = null; +// +// if(args.length ==1) +// selectedName = args[0]; +// +// if(selectedName == null || selectedName.length() ==0){ +// selectedName = "ALL_TEST"; +// } +// +// RoutingManager manager = RoutingManager.getInstance(); +// RoutingVO vo = new RoutingVO(); +// vo.setName(selectedName); +// +// if(vo != null){ +// System.out.println("RemoveRoutingCommand ] vo is not null.... remove start"); +// +// Command command = new RemoveRoutingCommand(); +// command.setArgs(vo); +// AgentUtil.broadcast(command); +// } +// else{ +// System.out.println("RemoveRoutingCommand ] main() vo is null"); +// } +// } +} diff --git a/src/main/java/com/eactive/eai/agent/testcall/TestCallCommand.java b/src/main/java/com/eactive/eai/agent/testcall/TestCallCommand.java new file mode 100644 index 0000000..f4c3107 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/testcall/TestCallCommand.java @@ -0,0 +1,113 @@ +package com.eactive.eai.agent.testcall; + +import java.util.Properties; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.testcall.TestCallManager; +import com.eactive.eai.common.util.Logger; + +/** + * 1. 기능 : TestCallManager를 시작 또는 종료 2. 처리 개요 : TestCallManager를 시작 또는 종료 3. + * 주의사항 + * + * @author + * @version v 1.0.0 + * @see 관련 기능을 참조 + * @since + * + */ +public class TestCallCommand extends Command { + + private static final long serialVersionUID = 1L; + + public TestCallCommand() { + super("TestCallCommand"); + } + + /** + * 1. 기능 : TestCallManager를 시작 또는 종료 2. 처리 개요 : arg로 전달된 Property의 값이 START이면 + * TestCallManager를 시작하고 STOP이면 TestCallManager 종료 3. 주의사항 + * + * @param + * @return + * @exception CommandException + **/ + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof Properties)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + Properties prop = new Properties(); + try { + TestCallManager manager = TestCallManager.getInstance(); + PropManager pmanager = PropManager.getInstance(); + + prop = (Properties) args; + + String run = ""; + String tmpperiod = ""; + + run = prop.getProperty("RUN"); + tmpperiod = prop.getProperty("PERIOD"); + + if (tmpperiod != null && tmpperiod.length() > 0) { + long period = Long.parseLong(tmpperiod); + pmanager.setProperty(manager.PROP_GROUP, manager.PROP_PERIOD, "" + period); + } + if (run != null && run.length() > 0) { + if ("START".equals(run)) { +// System.out.println("start.."); + manager.start(); + } else if ("STOP".equals(run)) { +// System.out.println("stop.."); + manager.stop(); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + + // public static void main(String args[]) throws Exception { +// test(String args[]); +//} + +//private static void test(String args[]) throws Exception { +// +// String run = ""; +// if(args.length >0 ) +// run = args[0]; +// else +// run = "START"; +// +// Properties prop = new Properties(); +// try{ +// +// prop.setProperty("RUN", run); +// +// Command command = new TestCallCommand(); +// command.setArgs(prop); +// AgentUtil.broadcast(command); +// }catch(Exception e){ +// System.out.println("error"); +//// e.printStackTrace(); +// } +// } + +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/ReloadLayoutCommand.java b/src/main/java/com/eactive/eai/agent/transformer/ReloadLayoutCommand.java new file mode 100644 index 0000000..4e9eace --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/ReloadLayoutCommand.java @@ -0,0 +1,66 @@ +package com.eactive.eai.agent.transformer; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.layout.LayoutManager; + +public class ReloadLayoutCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadLayoutCommand() { + super("ReloadLayoutCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + LayoutManager manager = LayoutManager.getManager(); + + String layoutName = (String) args; + + if (layoutName != null) { + if ("ALL".equals(layoutName)) { + manager.reload(); + manager.permanentReload(); + if (logger.isWarn()) + logger.warn("ReloadLayoutCommand ] all Layout info Reload."); + } else { + manager.reload(layoutName); + manager.permanentReload(layoutName); + if (logger.isWarn()) + logger.warn("ReloadLayoutCommand ] " + layoutName + " Layout info Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String[] args)throws Exception{ +// +// LayoutManager manager = LayoutManager.getManager(); +// +// Command command = new ReloadLayoutCommand(); +// command.setArgs(""); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/ReloadLayoutListCommand.java b/src/main/java/com/eactive/eai/agent/transformer/ReloadLayoutListCommand.java new file mode 100644 index 0000000..e4343c7 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/ReloadLayoutListCommand.java @@ -0,0 +1,68 @@ +package com.eactive.eai.agent.transformer; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.layout.LayoutManager; + +public class ReloadLayoutListCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadLayoutListCommand() { + super("ReloadLayoutListCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof Vector)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + LayoutManager manager = LayoutManager.getManager(); + + Vector layoutNameVt = (Vector) args; + String layoutName = ""; + for (int i = 0; i < layoutNameVt.size(); i++) { + layoutName = (String) layoutNameVt.get(i); + + if (layoutName != null) { + manager.reload(layoutName); + manager.permanentReload(layoutName); + if (logger.isWarn()) + logger.warn("ReloadLayoutListCommand ] " + layoutName + " Layout info Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// LayoutManager manager = LayoutManager.getManager(); +// Vector vt = new Vector(); +// Command command = new ReloadLayoutListCommand(); +// command.setArgs(vt); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/ReloadLayoutTypeCommand.java b/src/main/java/com/eactive/eai/agent/transformer/ReloadLayoutTypeCommand.java new file mode 100644 index 0000000..eb79ae8 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/ReloadLayoutTypeCommand.java @@ -0,0 +1,65 @@ +package com.eactive.eai.agent.transformer; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.layout.LayoutTypeManager; + +public class ReloadLayoutTypeCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadLayoutTypeCommand() { + super("ReloadLayoutTypeCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + LayoutTypeManager manager = LayoutTypeManager.getInstance(); + + String layoutTypeName = (String) args; + if (layoutTypeName != null) { + if ("ALL".equals(layoutTypeName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn("ReloadLayoutTypeCommand ] all LayoutType info Reload."); + } else { + manager.reload(layoutTypeName); + if (logger.isWarn()) + logger.warn("ReloadLayoutTypeCommand ] " + layoutTypeName + " LayoutType info Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// LayoutTypeManager manager = LayoutTypeManager.getInstance(); +// +// Command command = new ReloadLayoutTypeCommand(); +// command.setArgs(""); +// AgentUtil.broadcast(command); +// } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/ReloadPermanentLayoutCommand.java b/src/main/java/com/eactive/eai/agent/transformer/ReloadPermanentLayoutCommand.java new file mode 100644 index 0000000..c068f7c --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/ReloadPermanentLayoutCommand.java @@ -0,0 +1,64 @@ +package com.eactive.eai.agent.transformer; + +import com.eactive.eai.agent.AgentUtil; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.layout.LayoutManager; + +public class ReloadPermanentLayoutCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadPermanentLayoutCommand() { + super("ReloadPermanentLayoutCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "EAIINIT001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + LayoutManager manager = LayoutManager.getManager(); + + String keyName = (String) args; + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.permanentReload(); + if (logger.isWarn()) { + logger.warn(this.name + "] Permanent Cache가 Reload 되었습니다."); + } + } else { + throw new Exception("잘못된 파라미터입니다. : " + keyName); + } + } + } catch (Exception e) { + String rspErrorCode = "EAIINIT003"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg); + // e.printStackTrace(); + throw new CommandException(msg); + } + return "success"; + } + +// public static void main(String[] args)throws Exception{ +// test(); +// } + + public static void test() throws Exception { + Command command = new ReloadPermanentLayoutCommand(); + command.setArgs("ALL"); + AgentUtil.broadcast(command); + } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/ReloadTransformCommand.java b/src/main/java/com/eactive/eai/agent/transformer/ReloadTransformCommand.java new file mode 100644 index 0000000..8c2e61a --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/ReloadTransformCommand.java @@ -0,0 +1,63 @@ +package com.eactive.eai.agent.transformer; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.transform.TransformManager; + +public class ReloadTransformCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadTransformCommand() { + super("ReloadTransformCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + TransformManager manager = TransformManager.getManager(); + + String transformName = (String) args; + if (transformName != null) { + if ("ALL".equals(transformName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn("ReloadTransformCommand ] all Transform info Reload."); + } else { + manager.reload(transformName); + if (logger.isWarn()) + logger.warn("ReloadTransformCommand ] " + transformName + " Transform info Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String[] args)throws Exception{ +// +// TransformManager manager = TransformManager.getManager(); +// +// Command command = new ReloadTransformCommand(); +// command.setArgs(""); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/ReloadTransformFuncCommand.java b/src/main/java/com/eactive/eai/agent/transformer/ReloadTransformFuncCommand.java new file mode 100644 index 0000000..5448aee --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/ReloadTransformFuncCommand.java @@ -0,0 +1,67 @@ +package com.eactive.eai.agent.transformer; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.function.FunctionManager; + +public class ReloadTransformFuncCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadTransformFuncCommand() { + super("ReloadTransformFuncCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + FunctionManager manager = FunctionManager.getInstance(); + + String functionName = (String) args; + if (functionName != null) { + if ("ALL".equals(functionName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn("ReloadTransformFuncCommand ] all TransformFunction info Reload."); + } else { + manager.reload(functionName); + if (logger.isWarn()) + logger.warn("ReloadTransformFuncCommand ] " + functionName + " TransformFunction info Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// +// FunctionManager manager = FunctionManager.getInstance(); +// +// Command command = new ReloadTransformFuncCommand(); +// command.setArgs(""); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/ReloadTransformListCommand.java b/src/main/java/com/eactive/eai/agent/transformer/ReloadTransformListCommand.java new file mode 100644 index 0000000..8816018 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/ReloadTransformListCommand.java @@ -0,0 +1,65 @@ +package com.eactive.eai.agent.transformer; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.transform.TransformManager; + +public class ReloadTransformListCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadTransformListCommand() { + super("ReloadTransformListCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof Vector)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + TransformManager manager = TransformManager.getManager(); + + String transformName = ""; + Vector transformVt = (Vector) args; + +// String layoutName = ""; + for (int i = 0; i < transformVt.size(); i++) { + transformName = (String) transformVt.get(i); + if (transformName != null) { + manager.reload(transformName); + if (logger.isWarn()) + logger.warn("ReloadTransformListCommand ] " + transformName + " all Transform info Reload."); + } + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String[] args)throws Exception{ +// +// TransformManager manager = TransformManager.getManager(); +// +// Command command = new ReloadTransformListCommand(); +// command.setArgs(""); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/RemoveLayoutCommand.java b/src/main/java/com/eactive/eai/agent/transformer/RemoveLayoutCommand.java new file mode 100644 index 0000000..ab769f5 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/RemoveLayoutCommand.java @@ -0,0 +1,61 @@ +package com.eactive.eai.agent.transformer; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.layout.LayoutManager; + +public class RemoveLayoutCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveLayoutCommand() { + super("RemoveLayoutCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + LayoutManager manager = LayoutManager.getManager(); + + String layoutName = (String) args; + + if (layoutName != null && layoutName.trim().length() > 0) { + manager.remove(layoutName); + if (logger.isWarn()) + logger.warn("ReloadLayoutCommand ] " + layoutName + " 에 대한 Layout 정보가 메모리에서 삭제되었습니다."); + } else { + if (logger.isWarn()) + logger.warn("ReloadLayoutCommand ] Layout 명을 확인하세요 [" + layoutName + "]"); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String[] args)throws Exception{ +// +// LayoutManager manager = LayoutManager.getManager(); +// +// Command command = new RemoveLayoutCommand(); +// command.setArgs(""); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/RemoveLayoutTypeCommand.java b/src/main/java/com/eactive/eai/agent/transformer/RemoveLayoutTypeCommand.java new file mode 100644 index 0000000..6f6325b --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/RemoveLayoutTypeCommand.java @@ -0,0 +1,53 @@ +package com.eactive.eai.agent.transformer; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.layout.LayoutTypeManager; + +public class RemoveLayoutTypeCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveLayoutTypeCommand() { + super("RemoveLayoutTypeCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + LayoutTypeManager manager = LayoutTypeManager.getInstance(); + + String layoutTypeName = (String) args; + if (layoutTypeName != null) { + manager.remove(layoutTypeName); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String[] args)throws Exception{ +// LayoutTypeManager manager = LayoutTypeManager.getInstance(); +// +// Command command = new RemoveLayoutTypeCommand(); +// command.setArgs(""); +// AgentUtil.broadcast(command); +// } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/RemoveTransformCommand.java b/src/main/java/com/eactive/eai/agent/transformer/RemoveTransformCommand.java new file mode 100644 index 0000000..772d76a --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/RemoveTransformCommand.java @@ -0,0 +1,64 @@ +package com.eactive.eai.agent.transformer; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.transform.TransformManager; + +public class RemoveTransformCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveTransformCommand() { + super("RemoveTransformCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + TransformManager manager = TransformManager.getManager(); + + String transformName = (String) args; + if (transformName != null && transformName.trim().length() > 0) { + manager.remove(transformName); + if (logger.isWarn()) + logger.warn("RemoveTransformCommand ] " + transformName + " 에 대한 Transform 정보가 삭제되었습니다."); + } else { + if (logger.isWarn()) + logger.warn("ReloadLayoutCommand ] Transform 명을 확인하세요 [" + transformName + "]"); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// +// TransformManager manager = TransformManager.getManager(); +// +// Command command = new RemoveTransformCommand(); +// command.setArgs(""); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/transformer/RemoveTransformFuncCommand.java b/src/main/java/com/eactive/eai/agent/transformer/RemoveTransformFuncCommand.java new file mode 100644 index 0000000..8a9b3f5 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/transformer/RemoveTransformFuncCommand.java @@ -0,0 +1,59 @@ +package com.eactive.eai.agent.transformer; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.function.FunctionManager; + +public class RemoveTransformFuncCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveTransformFuncCommand() { + super("RemoveTransformFuncCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + try { + FunctionManager manager = FunctionManager.getInstance(); + + String functionName = (String) args; + if (functionName != null) { + manager.remove(functionName); + } + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// +// FunctionManager manager = FunctionManager.getInstance(); +// +// Command command = new RemoveTransformFuncCommand(); +// command.setArgs(""); +// AgentUtil.broadcast(command); +// +// } +} diff --git a/src/main/java/com/eactive/eai/agent/useDate/ReloadUseDateControlCommand.java b/src/main/java/com/eactive/eai/agent/useDate/ReloadUseDateControlCommand.java new file mode 100644 index 0000000..6455f97 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/useDate/ReloadUseDateControlCommand.java @@ -0,0 +1,62 @@ +package com.eactive.eai.agent.useDate; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.usedate.UseDateControlManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadUseDateControlCommand extends Command { + private static final long serialVersionUID = 1L; + + public ReloadUseDateControlCommand() { + super("ReloadUseDateControlCommand"); + } + + /** + * 1. 기능 : UseDateControlManager에 interface용 bucket을 리로드 + * 2. 처리 개요 : + * 3. 주의사항 : + * + * @exception CommandException Argument Type이 다르거나 Command 수행중 Excpetion이 발생할 경우 + **/ + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String keyName = (String) args; + try { + UseDateControlManager manager = UseDateControlManager.getInstance(); + + if (keyName != null) { + if ("ALL".equals(keyName)) { + manager.reload(); + if (logger.isWarn()) + logger.warn(this.name + "] all rule Reload."); + } else { + manager.reload(keyName); + if (logger.isWarn()) + logger.warn(this.name + "] " + keyName + " Reload."); + } + } + + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + + } + +} diff --git a/src/main/java/com/eactive/eai/agent/useDate/RemoveUseDateControlCommand.java b/src/main/java/com/eactive/eai/agent/useDate/RemoveUseDateControlCommand.java new file mode 100644 index 0000000..de23309 --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/useDate/RemoveUseDateControlCommand.java @@ -0,0 +1,42 @@ +package com.eactive.eai.agent.useDate; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.usedate.UseDateControlManager; +import com.eactive.eai.common.util.Logger; + +public class RemoveUseDateControlCommand extends Command { + private static final long serialVersionUID = 1L; + + public RemoveUseDateControlCommand() { + super("RemoveUseDateControlCommand"); + } + + public Object execute() throws CommandException { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) + logger.info(this.name + " is executed"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + String key = (String) args; + try { + UseDateControlManager manager = UseDateControlManager.getInstance(); + manager.remove(key); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/eactive/eai/agent/web/WebAgent.java b/src/main/java/com/eactive/eai/agent/web/WebAgent.java new file mode 100644 index 0000000..901ac5f --- /dev/null +++ b/src/main/java/com/eactive/eai/agent/web/WebAgent.java @@ -0,0 +1,122 @@ +package com.eactive.eai.agent.web; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.net.URLConnection; + +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import com.eactive.eai.agent.AgentUtil; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.common.util.Logger; + +/** + * 1. 기능 : AdapterGroupVO ADD + * 2. 처리 개요 : AdapterGroupVO를 manager에 add + * 3. 주의사항 + * + * @author + * @version v 1.0.0 + * @see 관련 기능을 참조 + * @since + * + */ +public class WebAgent extends HttpServlet { + static final String PARAMETER_MESSAGE = "_message_"; + public static final String FIELD_INST_NAME = "INST_NAME"; + public static final String FIELD_INTERNAL_URL = "INTERNAL_URL"; + public static final String FIELD_IS_CLOUD_PROXY = "IS_CLOUD_PROXY"; + public static final String INST_NAME = System.getProperty(Keys.SERVER_KEY); + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + protected void execute(Command command) throws CommandException { + try { + command.execute(); + + } catch (CommandException ce) { + // System.out.println("WebAgent Servlet] execute() occur CommandException :" + ce.toString()); + // ce.printStackTrace(); + throw ce; + } catch (Exception e) { + String errorMsg = ExceptionUtil.make(e, "RECEAIMCM010"); + if (logger.isError()) + logger.error(errorMsg, e); + throw new CommandException(errorMsg); + } + } + + /** + * 1. 기능 : 요청으로 전달된 Command 실행 + * 2. 처리 개요 : 요청으로 전달된 Command 실행하고 실행된 결과를 ObjectOutStream을 통해 전송 + * 3. 주의사항 + * + * @param request HttpServletRequest + * @param response HttpServletResponse + * @return + * @exception + **/ + @Override + public void service(HttpServletRequest request, HttpServletResponse response) { + + ObjectInputStream is = null; + ObjectOutputStream os = null; + try { + is = new ObjectInputStream(request.getInputStream()); + os = new ObjectOutputStream(response.getOutputStream()); + + Command command = (Command) is.readObject(); + + // 20220718 컨테이너 외부 EMS에서 커맨드 호출 시 다른컨테이너의 커맨드인 경우 전달 처리 + if ("true".equals(request.getHeader(FIELD_IS_CLOUD_PROXY)) + && !INST_NAME.equals(request.getHeader(FIELD_INST_NAME))) { + logger.info("Execute Command Proxy: " + command.getName() + ", TARGET_INST_NAME:" + + request.getHeader(FIELD_INST_NAME) + ", TARGET_URL:" + request.getHeader(FIELD_INTERNAL_URL)); + String iUrl = request.getHeader(FIELD_INTERNAL_URL); + URLConnection urlCon = AgentUtil.getURLConnection(iUrl); + urlCon.setConnectTimeout(3000); + urlCon.setReadTimeout(2000); + + AgentUtil.sendCommand(urlCon, command); + + String result = "success"; + os.writeObject(result); + } else { + logger.info("Execute Command Local: " + command.getName()); + execute(command); + + String result = "success"; + os.writeObject(result); + } + + } catch (Exception e) { + logger.error("WebAgent sync error " + e.getMessage(), e); + response.setStatus(500); + + try { + os.writeObject(e.getMessage()); + } catch (Exception ex) { + logger.warn("writeObject error", e); + } + + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception e) { + } + } + if (os != null) { + try { + os.close(); + } catch (Exception e) { + } + } + } + + } +} diff --git a/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupApiVO.java b/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupApiVO.java new file mode 100644 index 0000000..f231935 --- /dev/null +++ b/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupApiVO.java @@ -0,0 +1,11 @@ +package com.eactive.eai.apim.apigroup; + + +import lombok.Data; + +@Data +public class ApiGroupApiVO { + private String apiGroupId; + private String apiId; + private Integer displayOrder; +} diff --git a/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupDao.java b/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupDao.java new file mode 100644 index 0000000..b71259d --- /dev/null +++ b/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupDao.java @@ -0,0 +1,42 @@ +package com.eactive.eai.apim.apigroup; + +import com.eactive.eai.apim.apigroup.mapper.ApiGroupMapper; +import com.eactive.eai.data.entity.onl.apim.apigroup.ApiGroup; +import com.eactive.eai.apim.apigroup.loader.ApiGroupLoader; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.List; +import java.util.stream.Collectors; + +@Service +@Transactional +public class ApiGroupDao extends BaseDAO { + + @Autowired + ApiGroupLoader apiGroupLoader; + @Autowired + ApiGroupMapper apiGroupMapper; + + public List getAllApiGroups() throws DAOException { + try { + List adapterGroups = apiGroupLoader.selectAllGroups(); + return adapterGroups.stream().map(apiGroupMapper::toVo).collect(Collectors.toList()); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAAC001")); + } + } + + public ApiGroupVO getApiGroup(String apiGroupId) throws DAOException { + try { + ApiGroup apiGroup = apiGroupLoader.getById(apiGroupId); + return apiGroupMapper.toVo(apiGroup); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAAC001")); + } + } +} diff --git a/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupManager.java b/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupManager.java new file mode 100644 index 0000000..44d74fb --- /dev/null +++ b/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupManager.java @@ -0,0 +1,154 @@ +package com.eactive.eai.apim.apigroup; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.stream.Collectors; + +@Component +public class ApiGroupManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private boolean started; + + @Autowired + private ApiGroupDao dao; + + private Map apiGroupMap = new HashMap<>(); + private Map> apiGroupApiIndex = new HashMap<>(); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + public static ApiGroupManager getInstance() { + return ApplicationContextProvider.getContext().getBean(ApiGroupManager.class); + } + + @Override + public void addLifecycleListener(LifecycleListener listener) { + this.lifecycle.addLifecycleListener(listener); + } + + @Override + public LifecycleListener[] findLifecycleListeners() { + return this.lifecycle.findLifecycleListeners(); + } + + @Override + public void removeLifecycleListener(LifecycleListener listener) { + this.lifecycle.removeLifecycleListener(listener); + } + + public void reloadApiGroup(String apiGroupId) throws DAOException { + removeApiGroup(apiGroupId); + ApiGroupVO apiGroupVO = dao.getApiGroup(apiGroupId); + addApiGroup(apiGroupVO); + } + + protected void addApiGroup(ApiGroupVO apiGroupVO){ + apiGroupMap.put(apiGroupVO.getId(), apiGroupVO); + List apiList = apiGroupVO.getApiGroupApiList(); + if(apiList != null){ + for (ApiGroupApiVO apiGroupApiVO : apiList){ + String apiId = apiGroupApiVO.getApiId(); + String apiGroupId = apiGroupApiVO.getApiGroupId(); + apiGroupApiIndex.computeIfAbsent(apiId, k -> new HashSet<>()).add(apiGroupId); + } + } + } + + public void removeApiGroup(String apiGroupId) { + // apiGroupMap에서 ApiGroupVO 제거 + ApiGroupVO removedApiGroup = apiGroupMap.remove(apiGroupId); + + // 제거된 ApiGroupVO가 null이 아닌지 확인 + if (removedApiGroup != null) { + // 제거된 ApiGroupVO의 ApiGroupApiVO 리스트 가져오기 + List apiList = removedApiGroup.getApiGroupApiList(); + + // apiList가 null이 아닌 경우 + if (apiList != null) { + for (ApiGroupApiVO apiGroupApiVO : apiList) { + String apiId = apiGroupApiVO.getApiId(); + + // apiGroupApiIndex에서 apiId에 해당하는 Set 가져오기 + Set apiGroupIds = apiGroupApiIndex.get(apiId); + + // Set이 null이 아닌 경우 apiGroupId 제거 + if (apiGroupIds != null) { + apiGroupIds.remove(apiGroupId); + + // Set이 비어 있으면 apiGroupApiIndex에서 해당 apiId 삭제 + if (apiGroupIds.isEmpty()) { + apiGroupApiIndex.remove(apiId); + } + } + } + } + } + } + + + public List findApiGroup(String apiId) { + return Optional.ofNullable(apiGroupApiIndex.get(apiId)).orElse(Collections.emptySet()) + .stream() + .map(apiGroupMap::get) + .collect(Collectors.toList()); + } + + private void init() throws Exception { + try { + List apiGroups = dao.getAllApiGroups(); + for(ApiGroupVO apiGroupVO : apiGroups){ + addApiGroup(apiGroupVO); + } + } catch (DAOException e) { + logger.error(e); + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICPM201")); + } + } + + @Override + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICCM201"); + + this.lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICCM202")); + } + + this.started = true; + this.lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + @Override + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAIAAC020"); + + // Notify our interested LifecycleListeners + this.lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + this.apiGroupMap = new HashMap<>(); + + this.started = false; + // Notify our interested LifecycleListeners + this.lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + @Override + public boolean isStarted() { + return this.started; + } +} diff --git a/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupVO.java b/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupVO.java new file mode 100644 index 0000000..ae78071 --- /dev/null +++ b/src/main/java/com/eactive/eai/apim/apigroup/ApiGroupVO.java @@ -0,0 +1,21 @@ +package com.eactive.eai.apim.apigroup; + +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * GROUP 등록 정보로 거래제한, 유량제어등을 하기 위해 로딩 + * 개발자 포털에 노출할 CONTENT를 메모리에 로딩할 필요가 없어 해당 부분은 생략 + */ +@Data +public class ApiGroupVO { + private String id; + private String groupName; + private String groupDesc; + private String useYn; + + private List apiGroupApiList; +} diff --git a/src/main/java/com/eactive/eai/apim/apigroup/command/ReloadApiGroupCommand.java b/src/main/java/com/eactive/eai/apim/apigroup/command/ReloadApiGroupCommand.java new file mode 100644 index 0000000..36440d7 --- /dev/null +++ b/src/main/java/com/eactive/eai/apim/apigroup/command/ReloadApiGroupCommand.java @@ -0,0 +1,43 @@ +package com.eactive.eai.apim.apigroup.command; + +import com.eactive.eai.apim.apigroup.ApiGroupManager; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.util.Logger; + +public class ReloadApiGroupCommand extends Command { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public ReloadApiGroupCommand() { super("ReloadApiGroupCommand"); } + + @Override + public Object execute() throws CommandException { + if (logger.isInfo()) + logger.info(this.name + " is execute"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + ApiGroupManager manager = ApiGroupManager.getInstance(); + String apiGroupId = (String) args; + + try { + manager.reloadApiGroup(apiGroupId); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/eactive/eai/apim/apigroup/command/RemoveApiGroupCommand.java b/src/main/java/com/eactive/eai/apim/apigroup/command/RemoveApiGroupCommand.java new file mode 100644 index 0000000..d94c183 --- /dev/null +++ b/src/main/java/com/eactive/eai/apim/apigroup/command/RemoveApiGroupCommand.java @@ -0,0 +1,41 @@ +package com.eactive.eai.apim.apigroup.command; + +import com.eactive.eai.apim.apigroup.ApiGroupManager; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; + +public class RemoveApiGroupCommand extends Command { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public RemoveApiGroupCommand() { super("RemoveApiGroupCommand"); } + + @Override + public Object execute() throws CommandException { + if (logger.isInfo()) + logger.info(this.name + " is execute"); + + if (!(args instanceof String)) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) + logger.error(msg); + throw new CommandException(msg); + } + + ApiGroupManager manager = ApiGroupManager.getInstance(); + String apiGroupId = (String) args; + + try { + manager.removeApiGroup(apiGroupId); + } catch (Exception e) { + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) + logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/eactive/eai/apim/apigroup/mapper/ApiGroupApiMapper.java b/src/main/java/com/eactive/eai/apim/apigroup/mapper/ApiGroupApiMapper.java new file mode 100644 index 0000000..be6dcb9 --- /dev/null +++ b/src/main/java/com/eactive/eai/apim/apigroup/mapper/ApiGroupApiMapper.java @@ -0,0 +1,18 @@ +package com.eactive.eai.apim.apigroup.mapper; + +import com.eactive.eai.apim.apigroup.ApiGroupApiVO; +import com.eactive.eai.data.entity.onl.apim.apigroup.ApiGroupApi; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(config = BaseMapperConfig.class, uses = {}) +public interface ApiGroupApiMapper extends GenericMapper { + + @Mapping(source = "id.apiGroupId", target = "apiGroupId") + @Mapping(source = "id.apiId", target = "apiId") + @Mapping(source = "displayOrder", target = "displayOrder") + ApiGroupApiVO toVo(ApiGroupApi apiGroupApi); + +} diff --git a/src/main/java/com/eactive/eai/apim/apigroup/mapper/ApiGroupMapper.java b/src/main/java/com/eactive/eai/apim/apigroup/mapper/ApiGroupMapper.java new file mode 100644 index 0000000..8e3dac4 --- /dev/null +++ b/src/main/java/com/eactive/eai/apim/apigroup/mapper/ApiGroupMapper.java @@ -0,0 +1,16 @@ +package com.eactive.eai.apim.apigroup.mapper; + +import com.eactive.eai.apim.apigroup.ApiGroupVO; +import com.eactive.eai.data.entity.onl.apim.apigroup.ApiGroup; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(config = BaseMapperConfig.class, uses = { ApiGroupApiMapper.class }) +public interface ApiGroupMapper extends GenericMapper { + + @Mapping(source = "apiGroupApiList", target = "apiGroupApiList") + ApiGroupVO toVo(ApiGroup apiGroup); + +} diff --git a/src/main/java/com/eactive/eai/authoutbound/OutboundOAuthCredentialDao.java b/src/main/java/com/eactive/eai/authoutbound/OutboundOAuthCredentialDao.java new file mode 100644 index 0000000..32c9d3b --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/OutboundOAuthCredentialDao.java @@ -0,0 +1,66 @@ +package com.eactive.eai.authoutbound; + +import com.eactive.eai.authoutbound.mapper.OutboundOAuthCredentialMapper; +import com.eactive.eai.common.authoutbound.loader.OutboundOAuthCredentialLoader; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.LifecycleVO; +import com.eactive.eai.common.property.PropGroupVO; +import com.eactive.eai.common.seed.Seed; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.authoutbound.OutboundOAuthCredential; +import com.eactive.eai.data.entity.onl.lifecycle.LifeCycle; +import com.eactive.eai.data.entity.onl.property.PropGroup; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.ArrayList; +import java.util.List; + +@Service +@Transactional +public class OutboundOAuthCredentialDao extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + OutboundOAuthCredentialLoader outboundOAuthCredentialLoader ; + + @Autowired + OutboundOAuthCredentialMapper outboundOAuthCredentialMapper ; + + public List getAllOutboundOAuthCredentials() throws DAOException{ + List list = new ArrayList<>(); + try { + List outboundOAuthCredentials = outboundOAuthCredentialLoader.findAll(); + for (OutboundOAuthCredential outboundOAuthCredential : outboundOAuthCredentials) { + OutboundOAuthCredentialVo vo = outboundOAuthCredentialMapper.toVo(outboundOAuthCredential); + decryptClientSecret(vo); + list.add(vo); + } + } catch (Exception e) { + logger.error("dao", e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLC101")); + } + return list; + } + + public OutboundOAuthCredentialVo getOutboundOAuthCredential(String adapterGroupName) throws DAOException{ + try { + OutboundOAuthCredential outboundOAuthCredential = outboundOAuthCredentialLoader.getById(adapterGroupName); + OutboundOAuthCredentialVo vo = outboundOAuthCredentialMapper.toVo(outboundOAuthCredential); + decryptClientSecret(vo); + return vo; + } catch (Exception e) { + logger.error("dao", e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLC101")); + } + } + + public void decryptClientSecret(OutboundOAuthCredentialVo vo) throws Exception { + String clientSecret = vo.getClientSecret(); + String decrypted = Seed.decrypt(clientSecret); + vo.setClientSecret(decrypted); + } +} diff --git a/src/main/java/com/eactive/eai/authoutbound/OutboundOAuthCredentialVo.java b/src/main/java/com/eactive/eai/authoutbound/OutboundOAuthCredentialVo.java new file mode 100644 index 0000000..8ae4a65 --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/OutboundOAuthCredentialVo.java @@ -0,0 +1,32 @@ +package com.eactive.eai.authoutbound; + +import lombok.Data; +import org.hibernate.annotations.Comment; + +import javax.persistence.Column; +import java.time.LocalDateTime; + +@Data +public class OutboundOAuthCredentialVo { + private String adapterGroupName; + + private String grantType; + + private String url; + + private String clientId; + + private String clientSecret; + + private String scope; + + private String redirectUri; + + private int intervalSec; + + private String useYn; + + private LocalDateTime createdAt; + + private LocalDateTime updatedAt; +} diff --git a/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java b/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java new file mode 100644 index 0000000..40ac62a --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceByDB.java @@ -0,0 +1,36 @@ + +package com.eactive.eai.authoutbound.client; + +import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo; + +import java.util.Properties; + + +/** +* 1. 기능 : HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +* 2. 처리 개요 : +* * - 2009.11.24 retry 로직 제거 : 요청 +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +* @since : + +*/ +public interface HttpClientAccessTokenServiceByDB { + + /** + * 1. 기능 : 토큰발급 처리에 사용한다. + * 2. 처리 개요 : + * - 속성 정보를 설정 하고 토큰 발급 URL 호출 한다. + * 3. 주의사항 + * + * @param adapterProp Http Adapter 속성 정보 + * @param oAuthCredentialVo oauth 인증 정보 + * @return 반환 된 AccessTokenVO + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + public Object execute(String name, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) throws Exception ; + +} diff --git a/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceFactoryByDB.java b/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceFactoryByDB.java new file mode 100644 index 0000000..548b786 --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/client/HttpClientAccessTokenServiceFactoryByDB.java @@ -0,0 +1,43 @@ +package com.eactive.eai.authoutbound.client; + +import com.eactive.eai.common.util.Logger; + +import java.util.concurrent.ConcurrentHashMap; + +public class HttpClientAccessTokenServiceFactoryByDB { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + static private ConcurrentHashMap h = new ConcurrentHashMap<>(); + + /** + * + */ + public HttpClientAccessTokenServiceFactoryByDB() { + super(); + } + + /** + * 공통코드 HTTP_CLIENT_TOKEN_ISSUANCE_CLASS 에 정의된 구현체를 생성 한다. + * + * @param className + * @return + */ + @SuppressWarnings("rawtypes") + public static HttpClientAccessTokenServiceByDB createFactory(String className) { + if (h.containsKey(className)) { + return (HttpClientAccessTokenServiceByDB) h.get(className); + } + + HttpClientAccessTokenServiceByDB service = null; + try { + Class cl = Class.forName(className); + service = (HttpClientAccessTokenServiceByDB) cl.newInstance(); + if (service != null) { + h.put(className, service); + } + } catch (Exception e) { + logger.error("Cannot create a HttpClientAccessTokenService. - {}", className); + } + + return service; + } +} diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java new file mode 100644 index 0000000..c1aef65 --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithBase64Header.java @@ -0,0 +1,294 @@ + +package com.eactive.eai.authoutbound.client.impl; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.secure.HttpClient5SSLContextFactory; +import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo; +import com.eactive.eai.authoutbound.client.HttpClientAccessTokenServiceByDB; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; +import com.eactive.eai.util.TestModeChecker; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; +import org.apache.commons.lang3.StringUtils; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TrustAllStrategy; +import org.apache.hc.core5.http.ContentType; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.io.entity.StringEntity; +import org.apache.hc.core5.http.message.BasicNameValuePair; +import org.apache.hc.core5.ssl.SSLContextBuilder; +import org.apache.hc.core5.util.Timeout; +import org.springframework.security.web.util.UrlUtils; +import tcseed.base64; + +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.*; + +/** + * 1. 기능 : HTTP 웹 컴포넌트를 POST 방식으로 호출할 수 있는 기능을 제공한다. 2. 처리 개요 : * - 2009.11.24 + * retry 로직 제거 : 요청 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java + * @since : + * + */ +public class HttpClientAccessTokenServiceWithBase64Header implements HttpClientAccessTokenServiceByDB { + + public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static boolean testMode = TestModeChecker.isTestMode(); + + /** + * 1. 기능 : 법인검증 토큰 발급에 사용 2. 처리 개요 : - 속성 정보를 설정 하고 토큰 발급 URL 호출 한다. 3. 주의사항 + * - JSON 방식 + * - ( Header Authorization Basic ) 으로 구성 + * @param adapterProp Http Adapter 속성 정보 + * @return 반환 된 AccessTokenVO + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + public AccessTokenVO execute(String name, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) + throws Exception { + AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(name); + String adapterUrl = adapterProp.getProperty("URL"); + String encode = gvo.getMessageEncode(); + String timeoutTemp = adapterProp.getProperty("HTTP_TIME_OUT"); + if (StringUtils.isBlank(timeoutTemp)) { + timeoutTemp = "30000"; + } + String connectionTimeoutTemp = adapterProp.getProperty("CONNECTION_TIMEOUT"); + if (StringUtils.isBlank(connectionTimeoutTemp)) { + connectionTimeoutTemp = "30000"; + } + + int timeout = Integer.parseInt(timeoutTemp); + int connectionTimeout = Integer.parseInt(connectionTimeoutTemp); + long currentTime = System.currentTimeMillis(); + + String uri = oAuthCredentialVo.getUrl(); + + if (!UrlUtils.isAbsoluteUrl(uri)) { + uri = appendPath(adapterUrl, uri); + } + String contentType = "application/json;"; + + Charset charset; + if (StringUtils.isNotBlank(encode)) { + charset = Charset.forName(encode); + } else { + charset = Charset.defaultCharset(); + encode = charset.toString(); + } + + boolean useForwardProxy = StringUtils.equalsIgnoreCase(adapterProp.getProperty("FORWARD_PROXY_USE_YN"), "Y"); + String forwardProxyUrl = adapterProp.getProperty("FORWARD_PROXY_URL"); + + logger.debug( + "uri:{}, charset:{}, transactionTimeout:{}, connectionTimeout:{}, useForwardProxy:{}, forwardProxyUrl:{}", + uri, encode, timeout, connectionTimeout, useForwardProxy, forwardProxyUrl); + + + + + // mTLS config with default connection parameters + boolean useMtls = StringUtils.equalsIgnoreCase(adapterProp.getProperty(HttpClientAdapterServiceKey.USE_MTLS), + "Y"); + AdapterGroupVO adapterGroup = AdapterManager.getInstance().getAdapterGroup(name); + String clientId = adapterGroup.getClientId(); + + if (logger.isInfo()) { + logger.info("MTLS adapterGroupName. : {}, useMtls. : {}, clientId : {}", name, useMtls, clientId); + } + + int maxTotalConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_TOTAL_CONNECTIONS; + int maxHostConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_CONNECTION_PER_HOST; + + HttpOutTlsInfoVO mtlsInfo = null; + SSLContext sslContext = null; + PoolingHttpClientConnectionManagerBuilder cmBuilder = PoolingHttpClientConnectionManagerBuilder.create(); + PoolingHttpClientConnectionManager connectionManager = null; + + try { + if (useMtls) { + HttpOutTlsInfoManager tlsManager = HttpOutTlsInfoManager.getInstance(); + if (StringUtils.isNotEmpty(clientId)) { + mtlsInfo = tlsManager.getHttpOutTlsInfo(clientId); + } + } + + if (useMtls && mtlsInfo != null) { + String storeType = mtlsInfo.getStoreType(); + String keyStoreInfo = mtlsInfo.getKeystoreInfo(); + String keyStorePassword = mtlsInfo.getKeystorePassword(); + String trustStoreInfo = mtlsInfo.getTruststoreInfo(); + String trustStorePassword = mtlsInfo.getTruststorePassword(); + + String[] tlsVersions = null; + String[] cipherSuites = null; + + if (StringUtils.isAnyEmpty(keyStoreInfo, keyStorePassword)) { + throw new Exception("mTLS keyStore config error"); + } + + boolean skipTrust = false; + if (StringUtils.isAnyEmpty(trustStoreInfo, trustStorePassword)) { + if (logger.isWarn()) + logger.warn("Skip trustStore validation adapterGroupName : " + name); + skipTrust = true; + } + + sslContext = HttpClient5SSLContextFactory.createMTLSContextFromContent(storeType, keyStoreInfo, + keyStorePassword, trustStoreInfo, trustStorePassword, skipTrust, tlsVersions, cipherSuites); + + SSLConnectionSocketFactory sslSocketFactory = null; + if (testMode) { + sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); + } else { + sslSocketFactory = new SSLConnectionSocketFactory(sslContext); + } + cmBuilder.setSSLSocketFactory(sslSocketFactory); + } else { + sslContext = SSLContextBuilder.create().loadTrustMaterial(new TrustAllStrategy()).build(); + SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); + cmBuilder.setSSLSocketFactory(csf); + } + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException + | IOException | UnrecoverableKeyException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + + connectionManager = cmBuilder.build(); + connectionManager.setMaxTotal(maxTotalConnections); + connectionManager.setDefaultMaxPerRoute(maxHostConnections); + + //json body setting + Map jsonMap = new HashMap(); + jsonMap.put("scope",oAuthCredentialVo.getScope()); + jsonMap.put("grant_type",oAuthCredentialVo.getGrantType()); + ObjectMapper objMapper = new ObjectMapper(); + String authJsonBody = objMapper.writeValueAsString(jsonMap); + + try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();) { + HttpPost httpPost = new HttpPost(uri); + httpPost.setEntity(new StringEntity(authJsonBody)); + httpPost.setHeader("Content-Type", contentType+" charset=" + encode); + + //HTTP HEADER에 client id, client secret를 base64Encode 한 후 추가 + String cId = oAuthCredentialVo.getClientId(); + String cSecret = oAuthCredentialVo.getClientSecret(); + String authValue = cId + ":" + cSecret; + String encodedAuth = Base64.getEncoder().encodeToString(authValue.getBytes(StandardCharsets.UTF_8)); + httpPost.setHeader("Authorization","Basic "+ encodedAuth); + + + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + + if (useForwardProxy) { + java.net.URL url = new java.net.URL(forwardProxyUrl); + + // 프로토콜, 호스트, 포트 추출 + String protocol = url.getProtocol(); + String host = url.getHost(); + int port = url.getPort(); + HttpHost proxy = new HttpHost(protocol, host, port); + requestConfigBuilder.setProxy(proxy); + } + + RequestConfig requestConfig = requestConfigBuilder + .setConnectTimeout(Timeout.ofMilliseconds(connectionTimeout)) + .setResponseTimeout(Timeout.ofMilliseconds(timeout)).build(); + httpPost.setConfig(requestConfig); + + logger.debug("uri = [" + uri + "]"); + logger.debug("oauthClientId = [" + oAuthCredentialVo.getClientId() + "]"); + logger.debug("oauthClientSecret = [" + oAuthCredentialVo.getClientSecret() + "]"); + logger.debug("oauthScope = [" + oAuthCredentialVo.getScope() + "]"); + logger.debug("oauthGrantType = [" + oAuthCredentialVo.getGrantType() + "]"); + logger.debug("oauthauthValue = [" + authValue + "]"); + logger.debug("contentType = [" + contentType + "]"); + logger.debug("encode = [" + encode + "]"); + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + if (response.getCode() != 200) { + throw new Exception("OAuth token receive status fail value= " + response.getCode()); + } + + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity, encode); + logger.debug("oauthToken RECV = [" + responseString + "]"); + + if (StringUtils.isNotBlank(responseString)) { + OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode responseJSON = objectMapper.readTree(responseString); + + if (responseJSON.has("access_token") && responseJSON.has("token_type") + && responseJSON.has("expires_in") && responseJSON.has("scope")) { + accessToken.setAccessToken(responseJSON.get("access_token").asText()); + accessToken.setTokenType(responseJSON.get("token_type").asText()); + + long expiresIn = responseJSON.get("expires_in").asLong(); + accessToken.setExpiration(new Date(currentTime + expiresIn * 1000L)); + accessToken.setScope(responseJSON.get("scope").asText()); + } + + if (responseJSON.has("client_use_code")) { + accessToken.setClientUseCode(responseJSON.get("client_use_code").asText()); + } + + logger.debug("oauthToken =" + accessToken.toString()); + + return accessToken; + } else { + throw new Exception("oauth token return null"); + } + } + } + } + + /** + * URL에 경로를 추가합니다. 중복되는 슬래시를 방지합니다. + * + * @param baseUrl 기본 URL + * @param pathToAdd 추가할 경로 + * @return 완성된 URL 문자열 + */ + public static String appendPath(String baseUrl, String pathToAdd) { + if (!baseUrl.endsWith("/") && !pathToAdd.startsWith("/")) { + return baseUrl + "/" + pathToAdd; + } else if (baseUrl.endsWith("/") && pathToAdd.startsWith("/")) { + return baseUrl + pathToAdd.substring(1); + } else { + return baseUrl + pathToAdd; + } + } +} diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java new file mode 100644 index 0000000..3772406 --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParam.java @@ -0,0 +1,282 @@ + +package com.eactive.eai.authoutbound.client.impl; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Properties; + +import javax.net.ssl.SSLContext; + +import org.apache.commons.lang3.StringUtils; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TrustAllStrategy; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.message.BasicNameValuePair; +import org.apache.hc.core5.ssl.SSLContextBuilder; +import org.apache.hc.core5.util.Timeout; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.secure.HttpClient5SSLContextFactory; +import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo; +import com.eactive.eai.authoutbound.client.HttpClientAccessTokenServiceByDB; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; +import com.eactive.eai.util.TestModeChecker; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; +import org.springframework.security.web.util.UrlUtils; + +/** + * 1. 기능 : HTTP 웹 컴포넌트를 POST 방식으로 호출할 수 있는 기능을 제공한다. 2. 처리 개요 : * - 2009.11.24 + * retry 로직 제거 : 요청 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java + * @since : + * + */ +public class HttpClientAccessTokenServiceWithParam implements HttpClientAccessTokenServiceByDB { + + public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static boolean testMode = TestModeChecker.isTestMode(); + + /** + * 1. 기능 : 결제원 오픈뱅킹 토큰 발급에 사용 2. 처리 개요 : - 속성 정보를 설정 하고 토큰 발급 URL 호출 한다. 3. 주의사항 + * + * @param adapterProp Http Adapter 속성 정보 + * @return 반환 된 AccessTokenVO + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + public AccessTokenVO execute(String name, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) + throws Exception { + AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(name); + String adapterUrl = adapterProp.getProperty("URL"); + String encode = gvo.getMessageEncode(); + String timeoutTemp = adapterProp.getProperty("HTTP_TIME_OUT"); + if (StringUtils.isBlank(timeoutTemp)) { + timeoutTemp = "30000"; + } + String connectionTimeoutTemp = adapterProp.getProperty("CONNECTION_TIMEOUT"); + if (StringUtils.isBlank(connectionTimeoutTemp)) { + connectionTimeoutTemp = "30000"; + } + + int timeout = Integer.parseInt(timeoutTemp); + int connectionTimeout = Integer.parseInt(connectionTimeoutTemp); + long currentTime = System.currentTimeMillis(); + + String uri = oAuthCredentialVo.getUrl(); + + if (!UrlUtils.isAbsoluteUrl(uri)) { + uri = appendPath(adapterUrl, uri); + } + String contentType = "application/x-www-form-urlencoded"; + + Charset charset; + if (StringUtils.isNotBlank(encode)) { + charset = Charset.forName(encode); + } else { + charset = Charset.defaultCharset(); + encode = charset.toString(); + } + + boolean useForwardProxy = StringUtils.equalsIgnoreCase(adapterProp.getProperty("FORWARD_PROXY_USE_YN"), "Y"); + String forwardProxyUrl = adapterProp.getProperty("FORWARD_PROXY_URL"); + + logger.debug( + "uri:{}, charset:{}, transactionTimeout:{}, connectionTimeout:{}, useForwardProxy:{}, forwardProxyUrl:{}", + uri, encode, timeout, connectionTimeout, useForwardProxy, forwardProxyUrl); + + List formParams = new ArrayList<>(); + formParams.add(new BasicNameValuePair("client_id", oAuthCredentialVo.getClientId())); + formParams.add(new BasicNameValuePair("client_secret", oAuthCredentialVo.getClientSecret())); + formParams.add(new BasicNameValuePair("scope", oAuthCredentialVo.getScope())); + formParams.add(new BasicNameValuePair("grant_type", oAuthCredentialVo.getGrantType())); + + // mTLS config with default connection parameters + boolean useMtls = StringUtils.equalsIgnoreCase(adapterProp.getProperty(HttpClientAdapterServiceKey.USE_MTLS), + "Y"); + AdapterGroupVO adapterGroup = AdapterManager.getInstance().getAdapterGroup(name); + String clientId = adapterGroup.getClientId(); + + if (logger.isInfo()) { + logger.info("MTLS adapterGroupName. : {}, useMtls. : {}, clientId : {}", name, useMtls, clientId); + } + + int maxTotalConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_TOTAL_CONNECTIONS; + int maxHostConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_CONNECTION_PER_HOST; + + HttpOutTlsInfoVO mtlsInfo = null; + SSLContext sslContext = null; + PoolingHttpClientConnectionManagerBuilder cmBuilder = PoolingHttpClientConnectionManagerBuilder.create(); + PoolingHttpClientConnectionManager connectionManager = null; + + try { + if (useMtls) { + HttpOutTlsInfoManager tlsManager = HttpOutTlsInfoManager.getInstance(); + if (StringUtils.isNotEmpty(clientId)) { + mtlsInfo = tlsManager.getHttpOutTlsInfo(clientId); + } + } + + if (useMtls && mtlsInfo != null) { + String storeType = mtlsInfo.getStoreType(); + String keyStoreInfo = mtlsInfo.getKeystoreInfo(); + String keyStorePassword = mtlsInfo.getKeystorePassword(); + String trustStoreInfo = mtlsInfo.getTruststoreInfo(); + String trustStorePassword = mtlsInfo.getTruststorePassword(); + + String[] tlsVersions = null; + String[] cipherSuites = null; + + if (StringUtils.isAnyEmpty(keyStoreInfo, keyStorePassword)) { + throw new Exception("mTLS keyStore config error"); + } + + boolean skipTrust = false; + if (StringUtils.isAnyEmpty(trustStoreInfo, trustStorePassword)) { + if (logger.isWarn()) + logger.warn("Skip trustStore validation adapterGroupName : " + name); + skipTrust = true; + } + + sslContext = HttpClient5SSLContextFactory.createMTLSContextFromContent(storeType, keyStoreInfo, + keyStorePassword, trustStoreInfo, trustStorePassword, skipTrust, tlsVersions, cipherSuites); + + SSLConnectionSocketFactory sslSocketFactory = null; + if (testMode) { + sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); + } else { + sslSocketFactory = new SSLConnectionSocketFactory(sslContext); + } + cmBuilder.setSSLSocketFactory(sslSocketFactory); + } else { + sslContext = SSLContextBuilder.create().loadTrustMaterial(new TrustAllStrategy()).build(); + SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); + cmBuilder.setSSLSocketFactory(csf); + } + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException + | IOException | UnrecoverableKeyException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + + connectionManager = cmBuilder.build(); + connectionManager.setMaxTotal(maxTotalConnections); + connectionManager.setDefaultMaxPerRoute(maxHostConnections); + + try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();) { + HttpPost httpPost = new HttpPost(uri); + httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); + httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=" + encode); + + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + + if (useForwardProxy) { + java.net.URL url = new java.net.URL(forwardProxyUrl); + + // 프로토콜, 호스트, 포트 추출 + String protocol = url.getProtocol(); + String host = url.getHost(); + int port = url.getPort(); + HttpHost proxy = new HttpHost(protocol, host, port); + requestConfigBuilder.setProxy(proxy); + } + + RequestConfig requestConfig = requestConfigBuilder + .setConnectTimeout(Timeout.ofMilliseconds(connectionTimeout)) + .setResponseTimeout(Timeout.ofMilliseconds(timeout)).build(); + httpPost.setConfig(requestConfig); + + logger.debug("uri = [" + uri + "]"); + logger.debug("oauthClientId = [" + oAuthCredentialVo.getClientId() + "]"); + logger.debug("oauthClientSecret = [" + oAuthCredentialVo.getClientSecret() + "]"); + logger.debug("oauthScope = [" + oAuthCredentialVo.getScope() + "]"); + logger.debug("oauthGrantType = [" + oAuthCredentialVo.getGrantType() + "]"); + logger.debug("contentType = [" + contentType + "]"); + logger.debug("encode = [" + encode + "]"); + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + if (response.getCode() != 200) { + throw new Exception("OAuth token receive status fail value= " + response.getCode()); + } + + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity, encode); + logger.debug("oauthToken RECV = [" + responseString + "]"); + + if (StringUtils.isNotBlank(responseString)) { + OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode responseJSON = objectMapper.readTree(responseString); + + if (responseJSON.has("access_token") && responseJSON.has("token_type") + && responseJSON.has("expires_in") && responseJSON.has("scope")) { + accessToken.setAccessToken(responseJSON.get("access_token").asText()); + accessToken.setTokenType(responseJSON.get("token_type").asText()); + + long expiresIn = responseJSON.get("expires_in").asLong(); + accessToken.setExpiration(new Date(currentTime + expiresIn * 1000L)); + accessToken.setScope(responseJSON.get("scope").asText()); + } + + if (responseJSON.has("client_use_code")) { + accessToken.setClientUseCode(responseJSON.get("client_use_code").asText()); + } + + logger.debug("oauthToken =" + accessToken.toString()); + + return accessToken; + } else { + throw new Exception("oauth token return null"); + } + } + } + } + + /** + * URL에 경로를 추가합니다. 중복되는 슬래시를 방지합니다. + * + * @param baseUrl 기본 URL + * @param pathToAdd 추가할 경로 + * @return 완성된 URL 문자열 + */ + public static String appendPath(String baseUrl, String pathToAdd) { + if (!baseUrl.endsWith("/") && !pathToAdd.startsWith("/")) { + return baseUrl + "/" + pathToAdd; + } else if (baseUrl.endsWith("/") && pathToAdd.startsWith("/")) { + return baseUrl + pathToAdd.substring(1); + } else { + return baseUrl + pathToAdd; + } + } +} diff --git a/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParamAddBody.java b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParamAddBody.java new file mode 100644 index 0000000..af761af --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/client/impl/HttpClientAccessTokenServiceWithParamAddBody.java @@ -0,0 +1,323 @@ + +package com.eactive.eai.authoutbound.client.impl; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.secure.HttpClient5SSLContextFactory; +import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo; +import com.eactive.eai.authoutbound.client.HttpClientAccessTokenServiceByDB; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoManager; +import com.eactive.eai.httpouttlsinfo.HttpOutTlsInfoVO; +import com.eactive.eai.util.TestModeChecker; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; +import org.apache.commons.lang3.StringUtils; +import org.apache.hc.client5.http.classic.methods.HttpPost; +import org.apache.hc.client5.http.config.RequestConfig; +import org.apache.hc.client5.http.entity.UrlEncodedFormEntity; +import org.apache.hc.client5.http.impl.classic.CloseableHttpClient; +import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse; +import org.apache.hc.client5.http.impl.classic.HttpClients; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager; +import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder; +import org.apache.hc.client5.http.ssl.NoopHostnameVerifier; +import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory; +import org.apache.hc.client5.http.ssl.TrustAllStrategy; +import org.apache.hc.core5.http.HttpEntity; +import org.apache.hc.core5.http.HttpHost; +import org.apache.hc.core5.http.NameValuePair; +import org.apache.hc.core5.http.io.entity.EntityUtils; +import org.apache.hc.core5.http.message.BasicNameValuePair; +import org.apache.hc.core5.ssl.SSLContextBuilder; +import org.apache.hc.core5.util.Timeout; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.springframework.security.web.util.UrlUtils; + +import javax.net.ssl.SSLContext; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.security.KeyManagementException; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; +import java.util.*; + +/** + * 1. 기능 : HTTP 웹 컴포넌트를 POST 방식으로 호출할 수 있는 기능을 제공한다. 2. 처리 개요 : * - 2009.11.24 + * retry 로직 제거 : 요청 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java + * @since : + * + */ +public class HttpClientAccessTokenServiceWithParamAddBody implements HttpClientAccessTokenServiceByDB { + + public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static boolean testMode = TestModeChecker.isTestMode(); + + /** + * 1. 기능 : 결제원 오픈뱅킹 토큰 발급에 사용 2. 처리 개요 : - 속성 정보를 설정 하고 토큰 발급 URL 호출 한다. 3. 주의사항 + * + * @param adapterProp Http Adapter 속성 정보 + * @return 반환 된 AccessTokenVO + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + public AccessTokenVO execute(String name, Properties adapterProp, OutboundOAuthCredentialVo oAuthCredentialVo) + throws Exception { + AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(name); + String adapterUrl = adapterProp.getProperty("URL"); + String encode = gvo.getMessageEncode(); + String timeoutTemp = adapterProp.getProperty("HTTP_TIME_OUT"); + if (StringUtils.isBlank(timeoutTemp)) { + timeoutTemp = "30000"; + } + String connectionTimeoutTemp = adapterProp.getProperty("CONNECTION_TIMEOUT"); + if (StringUtils.isBlank(connectionTimeoutTemp)) { + connectionTimeoutTemp = "30000"; + } + + int timeout = Integer.parseInt(timeoutTemp); + int connectionTimeout = Integer.parseInt(connectionTimeoutTemp); + long currentTime = System.currentTimeMillis(); + + String uri = oAuthCredentialVo.getUrl(); + + if (!UrlUtils.isAbsoluteUrl(uri)) { + uri = appendPath(adapterUrl, uri); + } + String contentType = "application/x-www-form-urlencoded"; + + Charset charset; + if (StringUtils.isNotBlank(encode)) { + charset = Charset.forName(encode); + } else { + charset = Charset.defaultCharset(); + encode = charset.toString(); + } + + boolean useForwardProxy = StringUtils.equalsIgnoreCase(adapterProp.getProperty("FORWARD_PROXY_USE_YN"), "Y"); + String forwardProxyUrl = adapterProp.getProperty("FORWARD_PROXY_URL"); + + logger.debug( + "uri:{}, charset:{}, transactionTimeout:{}, connectionTimeout:{}, useForwardProxy:{}, forwardProxyUrl:{}", + uri, encode, timeout, connectionTimeout, useForwardProxy, forwardProxyUrl); + + List formParams = new ArrayList<>(); + + // 임시 코드 + String scopeArr=oAuthCredentialVo.getScope(); + String scopeStr; + //scope에 구분자 "|" 로 해서, body 추가내용 넣기. + //scope ex ) [ api,list|{"bankcd":"123","server_id":"456"} ] + if(scopeArr.contains("|")){ + String [] addBody = scopeArr.split("\\|"); + scopeStr = addBody[0]; + JSONParser parser = new JSONParser(); + JSONObject obj = (JSONObject) parser.parse(addBody[1]); + for (Object keyObj : obj.keySet()) { + String key = (String) keyObj; + String value = String.valueOf(obj.get(key)); + formParams.add(new BasicNameValuePair(key, value)); + } + }else{ + scopeStr=scopeArr; + } +// formParams.add(new BasicNameValuePair("client_id", client_id)); +// formParams.add(new BasicNameValuePair("client_secret", oAuthCredentialVo.getClientSecret())); +// formParams.add(new BasicNameValuePair("scope", oAuthCredentialVo.getScope())); +// formParams.add(new BasicNameValuePair("grant_type", grant_type)); + + // mTLS config with default connection parameters + boolean useMtls = StringUtils.equalsIgnoreCase(adapterProp.getProperty(HttpClientAdapterServiceKey.USE_MTLS), + "Y"); + AdapterGroupVO adapterGroup = AdapterManager.getInstance().getAdapterGroup(name); + String clientId = adapterGroup.getClientId(); + + if (logger.isInfo()) { + logger.info("MTLS adapterGroupName. : {}, useMtls. : {}, clientId : {}", name, useMtls, clientId); + } + + int maxTotalConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_TOTAL_CONNECTIONS; + int maxHostConnections = HttpClientAdapterServiceKey.DEFAULT_MAX_CONNECTION_PER_HOST; + + HttpOutTlsInfoVO mtlsInfo = null; + SSLContext sslContext = null; + PoolingHttpClientConnectionManagerBuilder cmBuilder = PoolingHttpClientConnectionManagerBuilder.create(); + PoolingHttpClientConnectionManager connectionManager = null; + + try { + if (useMtls) { + HttpOutTlsInfoManager tlsManager = HttpOutTlsInfoManager.getInstance(); + if (StringUtils.isNotEmpty(clientId)) { + mtlsInfo = tlsManager.getHttpOutTlsInfo(clientId); + } + } + + if (useMtls && mtlsInfo != null) { + String storeType = mtlsInfo.getStoreType(); + String keyStoreInfo = mtlsInfo.getKeystoreInfo(); + String keyStorePassword = mtlsInfo.getKeystorePassword(); + String trustStoreInfo = mtlsInfo.getTruststoreInfo(); + String trustStorePassword = mtlsInfo.getTruststorePassword(); + + String[] tlsVersions = null; + String[] cipherSuites = null; + + if (StringUtils.isAnyEmpty(keyStoreInfo, keyStorePassword)) { + throw new Exception("mTLS keyStore config error"); + } + + boolean skipTrust = false; + if (StringUtils.isAnyEmpty(trustStoreInfo, trustStorePassword)) { + if (logger.isWarn()) + logger.warn("Skip trustStore validation adapterGroupName : " + name); + skipTrust = true; + } + + sslContext = HttpClient5SSLContextFactory.createMTLSContextFromContent(storeType, keyStoreInfo, + keyStorePassword, trustStoreInfo, trustStorePassword, skipTrust, tlsVersions, cipherSuites); + + SSLConnectionSocketFactory sslSocketFactory = null; + if (testMode) { + sslSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE); + } else { + sslSocketFactory = new SSLConnectionSocketFactory(sslContext); + } + cmBuilder.setSSLSocketFactory(sslSocketFactory); + } else { + sslContext = SSLContextBuilder.create().loadTrustMaterial(new TrustAllStrategy()).build(); + SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext); + cmBuilder.setSSLSocketFactory(csf); + } + } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | CertificateException + | IOException | UnrecoverableKeyException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + + connectionManager = cmBuilder.build(); + connectionManager.setMaxTotal(maxTotalConnections); + connectionManager.setDefaultMaxPerRoute(maxHostConnections); + + try (CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(connectionManager).build();) { + HttpPost httpPost = new HttpPost(uri); + + //임시코드 + + String cientIdArr = oAuthCredentialVo.getClientId(); + String client_id ; + //client_id ex ) [ realClientId|BasicBase64 ] + if(cientIdArr.contains("BasicBase64")){ + String [] authBasic = cientIdArr.split("\\|"); + client_id = authBasic[0]; + //HTTP HEADER에 client id, client secret를 base64Encode 한 후 추가 + String cId = client_id; + String cSecret = oAuthCredentialVo.getClientSecret(); + String authValue = cId + ":" + cSecret; + String encodedAuth = Base64.getEncoder().encodeToString(authValue.getBytes(StandardCharsets.UTF_8)); + httpPost.setHeader("Authorization","Basic "+ encodedAuth); + }else{ + client_id=cientIdArr; + formParams.add(new BasicNameValuePair("client_id", client_id)); + formParams.add(new BasicNameValuePair("client_secret", oAuthCredentialVo.getClientSecret())); + formParams.add(new BasicNameValuePair("scope", scopeStr)); + } + formParams.add(new BasicNameValuePair("grant_type",oAuthCredentialVo.getGrantType())); + + httpPost.setEntity(new UrlEncodedFormEntity(formParams, charset)); + httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded; charset=" + encode); + + RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); + + if (useForwardProxy) { + java.net.URL url = new java.net.URL(forwardProxyUrl); + + // 프로토콜, 호스트, 포트 추출 + String protocol = url.getProtocol(); + String host = url.getHost(); + int port = url.getPort(); + HttpHost proxy = new HttpHost(protocol, host, port); + requestConfigBuilder.setProxy(proxy); + } + + RequestConfig requestConfig = requestConfigBuilder + .setConnectTimeout(Timeout.ofMilliseconds(connectionTimeout)) + .setResponseTimeout(Timeout.ofMilliseconds(timeout)).build(); + httpPost.setConfig(requestConfig); + + logger.debug("uri = [" + uri + "]"); + logger.debug("oauthClientId = [" + oAuthCredentialVo.getClientId() + "]"); + logger.debug("oauthClientSecret = [" + oAuthCredentialVo.getClientSecret() + "]"); + logger.debug("oauthScope = [" + scopeStr + "]"); + logger.debug("ScopeAddBodyStr = [" + scopeArr + "]"); + logger.debug("oauthGrantType = [" + oAuthCredentialVo.getGrantType() + "]"); + logger.debug("contentType = [" + contentType + "]"); + logger.debug("encode = [" + encode + "]"); + + try (CloseableHttpResponse response = httpClient.execute(httpPost)) { + if (response.getCode() != 200) { + throw new Exception("OAuth token receive status fail value= " + response.getCode()); + } + + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity, encode); + logger.debug("oauthToken RECV = [" + responseString + "]"); + + if (StringUtils.isNotBlank(responseString)) { + OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); + + ObjectMapper objectMapper = new ObjectMapper(); + JsonNode responseJSON = objectMapper.readTree(responseString); + + if (responseJSON.has("access_token") && responseJSON.has("token_type") + && responseJSON.has("expires_in") && responseJSON.has("scope")) { + accessToken.setAccessToken(responseJSON.get("access_token").asText()); + accessToken.setTokenType(responseJSON.get("token_type").asText()); + + long expiresIn = responseJSON.get("expires_in").asLong(); + accessToken.setExpiration(new Date(currentTime + expiresIn * 1000L)); + accessToken.setScope(responseJSON.get("scope").asText()); + } + + if (responseJSON.has("client_use_code")) { + accessToken.setClientUseCode(responseJSON.get("client_use_code").asText()); + } + + logger.debug("oauthToken =" + accessToken.toString()); + + return accessToken; + } else { + throw new Exception("oauth token return null"); + } + } + } + } + + /** + * URL에 경로를 추가합니다. 중복되는 슬래시를 방지합니다. + * + * @param baseUrl 기본 URL + * @param pathToAdd 추가할 경로 + * @return 완성된 URL 문자열 + */ + public static String appendPath(String baseUrl, String pathToAdd) { + if (!baseUrl.endsWith("/") && !pathToAdd.startsWith("/")) { + return baseUrl + "/" + pathToAdd; + } else if (baseUrl.endsWith("/") && pathToAdd.startsWith("/")) { + return baseUrl + pathToAdd.substring(1); + } else { + return baseUrl + pathToAdd; + } + } +} diff --git a/src/main/java/com/eactive/eai/authoutbound/mapper/OutboundOAuthCredentialMapper.java b/src/main/java/com/eactive/eai/authoutbound/mapper/OutboundOAuthCredentialMapper.java new file mode 100644 index 0000000..af6e303 --- /dev/null +++ b/src/main/java/com/eactive/eai/authoutbound/mapper/OutboundOAuthCredentialMapper.java @@ -0,0 +1,16 @@ +package com.eactive.eai.authoutbound.mapper; + +import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo; +import com.eactive.eai.common.pushinfo.PushInfoVO; +import com.eactive.eai.data.entity.onl.authoutbound.OutboundOAuthCredential; +import com.eactive.eai.data.entity.onl.pushinfo.PushInfo; +import com.eactive.eai.data.mapper.GenericMapper; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface OutboundOAuthCredentialMapper extends GenericMapper { + + @Override + OutboundOAuthCredentialVo toVo(OutboundOAuthCredential outboundOAuthCredential); +} diff --git a/src/main/java/com/eactive/eai/authserver/dao/ClientDAO.java b/src/main/java/com/eactive/eai/authserver/dao/ClientDAO.java new file mode 100644 index 0000000..2996c1c --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/dao/ClientDAO.java @@ -0,0 +1,144 @@ +package com.eactive.eai.authserver.dao; + +import java.time.format.DateTimeFormatter; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.mapper.EAIMessageMapper; +import com.eactive.eai.data.entity.onl.message.EAIMessageEntity; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.authserver.dao.ClientLoader; +import com.eactive.eai.authserver.vo.ClientVO; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.converter.LocalDateTimeFormatters; +import com.eactive.eai.data.entity.onl.authserver.ClientEntity; + +@Service +@Transactional +public class ClientDAO extends BaseDAO { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private ClientLoader clientService; + + @Autowired + private EAIMessageMapper eaiMessageMapper; + + public Map loadClientDetails() throws DAOException { + try { + Stream clientEntities = clientService.loadAll(); + Map clientDetailsMap = new HashMap<>(); + + clientEntities.forEach(clientEntity -> { + ClientVO clientVO = createClientVO(clientEntity); + clientDetailsMap.put(clientEntity.getClientid(), clientVO); + }); + return clientDetailsMap; + + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC001")); + } + } + + public ClientVO getClientById(String clientId) throws DAOException { + try { + Optional clientEntityOptional = clientService.findById(clientId); + ClientEntity clientEntity = clientEntityOptional + .orElseThrow(() -> new DAOException("ClientEntity not found for clientId: " + clientId)); + + return createClientVO(clientEntity); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC001")); + } + } + + private ClientVO createClientVO(ClientEntity clientEntity) { + ClientVO clientVO = new ClientVO(); + clientVO.setClientName(clientEntity.getClientname()); + clientVO.setClientId(clientEntity.getClientid()); + clientVO.setClientSecret(clientEntity.getClientsecret()); + clientVO.setScope(assignSet(clientEntity.getScope(), ",")); + clientVO.setAuthorizedGrantTypes(assignSet(clientEntity.getGranttypes(), ",")); + clientVO.setRegisteredRedirectUri(assignSet(clientEntity.getRedirecturi(), ",")); + clientVO.setAuthorities(assignAuthorities(clientEntity.getAuthorities())); + clientVO.setResourceIds(assignSet(clientEntity.getResourceids(), ",")); + if (NumberUtils.isParsable(clientEntity.getAccesstokenvalidityseconds())) { + clientVO.setAccessTokenValiditySeconds(Integer.parseInt(clientEntity.getAccesstokenvalidityseconds())); + } + if (NumberUtils.isParsable(clientEntity.getRefreshtokenvalidityseconds())) { + clientVO.setRefreshTokenValiditySeconds(Integer.parseInt(clientEntity.getRefreshtokenvalidityseconds())); + } + clientVO.setAutoApproveScopes(assignSet(clientEntity.getAutoapprove(), ",")); + clientVO.setAllowedIp(clientEntity.getAllowedips()); + clientVO.setSecurityKey(clientEntity.getSecuritykey()); + clientVO.setModifiedBy(clientEntity.getModifiedby()); + clientVO.setOrgId(clientEntity.getModifiedby()); + clientVO.setModifiedBy(clientEntity.getModifiedby()); + clientVO.setOrgId(clientEntity.getOrgid()); + clientVO.setOrgName(clientEntity.getOrgname()); + clientVO.setAppStatus(clientEntity.getAppstatus()); + clientVO.setDailyTokenLimit(clientEntity.getDailytokenlimit()); + + if(clientEntity.getModifiedon() != null) { + clientVO.setModifiedOn(clientEntity.getModifiedon().format(LocalDateTimeFormatters.FORMATTER_YYYYMMDDHHMMSS_14)); + } + + Map apiMap = new HashMap<>(); + + for (EAIMessageEntity eaiMessageEntity : clientEntity.getApiList()){ + EAIMessage eaiMessage = eaiMessageMapper.toVo(eaiMessageEntity); + apiMap.put(eaiMessage.getEAISvcCd(), eaiMessage); + } + + clientVO.setApiMap(apiMap); + + return clientVO; + } + + private Collection assignAuthorities(String roleStr) { + List authorities = new ArrayList<>(); + + if (StringUtils.isBlank(roleStr)) { + return authorities; + } + + for (String role : StringUtils.split(roleStr, ",")) { + authorities.add(new SimpleGrantedAuthority(role)); + } + + return authorities; + } + + private Set assignSet(String str, String delim) { + Set set = new HashSet<>(); + + if (StringUtils.isBlank(str)) { + return set; + } + + String[] arr = StringUtils.split(str, delim); + set.addAll(Arrays.asList(arr)); + + return set; + } +} diff --git a/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java b/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java new file mode 100644 index 0000000..83676f6 --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/dao/ScopeDAO.java @@ -0,0 +1,81 @@ +package com.eactive.eai.authserver.dao; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.authserver.ScopeEntity; + +@Service +@Transactional +public class ScopeDAO extends BaseDAO { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private ScopeLoader scopeLoader; + + public Map> loadApiScopeRelations() throws DAOException { + try { + Stream scopeEntities = scopeLoader.loadAll(); + Map> clientEntitymap = new HashMap<>(); + + scopeEntities.forEach(scopeEntity -> { + HashSet set = new HashSet<>(); + String scopeId = scopeEntity.getId().getBzwksvckeyname() + scopeEntity.getId().getScopeid(); + clientEntitymap.put(scopeId, set); + }); + return clientEntitymap; + + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC001")); + } + } + + public HashSet getApiScopeRelationsByApiId(String apiId) throws DAOException { + try { + HashSet scopeSet = new HashSet<>(); + + ScopeEntity scopeEntity = scopeLoader.findByIdBzwksvckeyname(apiId); + + scopeSet.add(scopeEntity.getId().getBzwksvckeyname()); + return scopeSet; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC001")); + } + + } + + public List getApiScopeRelationsByScopeId(String scopeId) throws DAOException { + try { + List apiList = new ArrayList<>(); + ScopeEntity scopeEntity = scopeLoader.findByIdScopeid(scopeId); + apiList.add(scopeEntity.getId().getBzwksvckeyname()); + + return apiList; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC001")); + } + + } + + public boolean hasApiScopeRelation(String apiId, String scopeId) throws DAOException { + try { + ScopeEntity scopeEntity = scopeLoader.findByIdBzwksvckeynameAndIdScopeid(apiId, scopeId); + return scopeEntity != null; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC001")); + } + + } +} diff --git a/src/main/java/com/eactive/eai/authserver/dao/TokenIssuanceLogDAO.java b/src/main/java/com/eactive/eai/authserver/dao/TokenIssuanceLogDAO.java new file mode 100644 index 0000000..3a678aa --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/dao/TokenIssuanceLogDAO.java @@ -0,0 +1,68 @@ +package com.eactive.eai.authserver.dao; + +import java.util.List; +import java.time.LocalDateTime; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.authserver.TokenIssuanceLog; + +@Service +@Transactional +public class TokenIssuanceLogDAO extends BaseDAO { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private TokenIssuanceLogLoader tokenIssuanceLogLoader; + + public TokenIssuanceLog saveTokenIssuanceLog(TokenIssuanceLog log) throws DAOException { + try { + return tokenIssuanceLogLoader.save(log); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC002")); + } + } + + public List findByClientId(String clientId) throws DAOException { + try { + return tokenIssuanceLogLoader.findByClientId(clientId); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC003")); + } + } + + public List findByAppName(String appName) throws DAOException { + try { + return tokenIssuanceLogLoader.findByAppName(appName); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC004")); + } + } + + public List findByIssuanceDateTimeBetween(LocalDateTime start, LocalDateTime end) throws DAOException { + try { + return tokenIssuanceLogLoader.findByIssuanceDateTimeBetween(start, end); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC005")); + } + } + + public List findBySuccessYn(String successYn) throws DAOException { + try { + return tokenIssuanceLogLoader.findBySuccessYn(successYn); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAUC006")); + } + } + + public int findRecentLogsForRestrictionCount( + String clientId, LocalDateTime startDateTime) { + return tokenIssuanceLogLoader.findRecentLogsForRestrictionCount(clientId, startDateTime); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/authserver/dao/UserDAO.java b/src/main/java/com/eactive/eai/authserver/dao/UserDAO.java new file mode 100644 index 0000000..7791884 --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/dao/UserDAO.java @@ -0,0 +1,56 @@ +package com.eactive.eai.authserver.dao; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.authserver.dao.UserLoader; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.authserver.UserEntity; + +@Service +@Transactional +public class UserDAO extends BaseDAO { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private UserLoader userLoader; + + public UserDetails getUserByUserId(String userId) throws DAOException { + try { + UserEntity userEntity = userLoader.getById(userId); + + if (userEntity != null) { + return new User(userId, userEntity.getPassword(), assignAuthorities(userEntity.getAuthorities())); + } + return null; + + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIAAC009")); + } + } + + public List assignAuthorities(String roleStr) { + List authorities = new ArrayList<>(); + + if (StringUtils.isBlank(roleStr)) { + return authorities; + } + + for (String role : StringUtils.split(roleStr, ",")) { + authorities.add(new SimpleGrantedAuthority(role)); + } + return authorities; + } +} diff --git a/src/main/java/com/eactive/eai/authserver/service/ElinkClientDetailsServiceImpl.java b/src/main/java/com/eactive/eai/authserver/service/ElinkClientDetailsServiceImpl.java new file mode 100644 index 0000000..0ee7742 --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/service/ElinkClientDetailsServiceImpl.java @@ -0,0 +1,20 @@ +package com.eactive.eai.authserver.service; + +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.security.oauth2.provider.ClientDetailsService; +import org.springframework.security.oauth2.provider.ClientRegistrationException; +import org.springframework.security.oauth2.provider.NoSuchClientException; +import org.springframework.stereotype.Service; + +@Service("eLinkClientDetailsService") +public class ElinkClientDetailsServiceImpl implements ClientDetailsService { + + @Override + public ClientDetails loadClientByClientId(String clientId) throws ClientRegistrationException { + ClientDetails details = OAuth2Manager.getInstance().getClientDeatilsStore().get(clientId); + if (details == null) { + throw new NoSuchClientException("No client with requested id: " + clientId); + } + return details; + } +} diff --git a/src/main/java/com/eactive/eai/authserver/service/OAuth2Manager.java b/src/main/java/com/eactive/eai/authserver/service/OAuth2Manager.java new file mode 100644 index 0000000..5ace2b2 --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/service/OAuth2Manager.java @@ -0,0 +1,221 @@ +package com.eactive.eai.authserver.service; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.oauth2.provider.ClientDetails; +import org.springframework.stereotype.Component; + +import com.eactive.eai.agent.authserver.ReloadApiScopeCommand; +import com.eactive.eai.authserver.dao.ClientDAO; +import com.eactive.eai.authserver.dao.ScopeDAO; +import com.eactive.eai.authserver.vo.ClientVO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.util.MemoryLogger; + +@Component +public class OAuth2Manager implements Lifecycle { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private Map clientDetailsStore = new HashMap<>(); + private Map> apiScopeMap = new HashMap<>(); + + private boolean started; + + @Autowired + private ClientDAO clientDAO; + + @Autowired + private ScopeDAO scopeDAO; + + public static OAuth2Manager getInstance() { + return ApplicationContextProvider.getContext().getBean(OAuth2Manager.class); + } + + public ClientVO getClientInfo(String clientId) throws DAOException { + ClientVO vo = clientDAO.getClientById(clientId); + logger.info("OAuth2Manager | getClientVO clientId=" + clientId + " - " + vo); + return vo; + } + + public Map getClientDeatilsStore() { + return clientDetailsStore; + } + + public Map> getApiScopeMap() { + return apiScopeMap; + } + + private void initAllClients() throws DAOException { + clientDetailsStore = clientDAO.loadClientDetails(); + + logger.info("OAuth2Manager | all clients are initialized"); + MemoryLogger.txlog("OAuth2Manager | all clients are initialized"); + } + + private void initAllApiScopeRelations() throws DAOException { + apiScopeMap = scopeDAO.loadApiScopeRelations(); + + logger.info("OAuth2Manager | all API-Scope Relation are initialized"); + MemoryLogger.txlog("OAuth2Manager | all API-Scope Relation are initialized"); + } + + @Override + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + @Override + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + @Override + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + @Override + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAIAAC015"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + // client 초기화 + clientDetailsStore.clear(); + initAllClients(); + + // api-scope 초기화 + apiScopeMap.clear(); + initAllApiScopeRelations(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICPM201")); + } + + started = true; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + @Override + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAIAAC020"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + clientDetailsStore = null; + apiScopeMap = null; + + started = false; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + @Override + public boolean isStarted() { + return this.started; + } + + public synchronized void reloadClient(String keyName) throws Exception { + // 1. Memory에서 제거 + clientDetailsStore.remove(keyName); + + // 2. DB에서 select + ClientVO client = clientDAO.getClientById(keyName); + if (client != null) { + // 3. DB에 있으면 Memory에 적재 + clientDetailsStore.put(keyName, client); + } + } + + public void reloadApiScopeRelation(String[] args) throws Exception { + if (args == null || args.length != 3) { + throw new Exception("Arguments 3 required"); + } + + String commandType = args[0]; + String apiId = args[1]; + String scopeId = args[2]; + + if (StringUtils.equals(commandType, ReloadApiScopeCommand.COMMAND_TYPE_API)) { + reloadApiScopeRelationForApi(apiId); + } else if (StringUtils.equals(commandType, ReloadApiScopeCommand.COMMAND_TYPE_SCOPE)) { + reloadApiScopeRelationForScope(scopeId); + } else if (StringUtils.equals(commandType, ReloadApiScopeCommand.COMMAND_TYPE_API_SCOPE)) { + reloadApiScopeRelationForApiScope(apiId, scopeId); + } else { + throw new IllegalArgumentException("Invalid command type: " + commandType); + } + } + + private void reloadApiScopeRelationForApi(String apiId) throws DAOException { + apiScopeMap.remove(apiId); + logger.debug(String.format("Type=%s, ID=%s removed", ReloadApiScopeCommand.COMMAND_TYPE_API, apiId)); + + HashSet scopeSet = scopeDAO.getApiScopeRelationsByApiId(apiId); + if (scopeSet != null) { + apiScopeMap.put(apiId, scopeSet); + logger.debug(String.format("Type=%s, ID=%s added", ReloadApiScopeCommand.COMMAND_TYPE_API, apiId)); + } + } + + private void reloadApiScopeRelationForScope(String scopeId) throws DAOException { + for (Set scopeSet : apiScopeMap.values()) { + scopeSet.remove(scopeId); + } + logger.debug(String.format("Type=%s, ID=%s removed", ReloadApiScopeCommand.COMMAND_TYPE_SCOPE, scopeId)); + + List apiList = scopeDAO.getApiScopeRelationsByScopeId(scopeId); + if (apiList != null) { + for (String apiId : apiList) { + Set scopeSet = apiScopeMap.computeIfAbsent(apiId, k -> new HashSet<>()); + scopeSet.add(scopeId); + logger.debug(String.format("Type=%s, ID=%s, %s added", ReloadApiScopeCommand.COMMAND_TYPE_SCOPE, apiId, + scopeId)); + } + } + } + + private void reloadApiScopeRelationForApiScope(String apiId, String scopeId) throws DAOException { + Set scopeSet = apiScopeMap.computeIfAbsent(apiId, key -> new HashSet()); + scopeSet.remove(scopeId); + logger.debug(String.format("Type=%s, ID=%s, %s removed", ReloadApiScopeCommand.COMMAND_TYPE_API_SCOPE, apiId, + scopeId)); + + if (scopeDAO.hasApiScopeRelation(apiId, scopeId)) { + scopeSet.add(scopeId); + logger.debug(String.format("Type=%s, ID=%s, %s added", ReloadApiScopeCommand.COMMAND_TYPE_API_SCOPE, apiId, + scopeId)); + } + } + + public ClientVO getClientVO(String clientId){ + ClientDetails clientDetails = clientDetailsStore.get(clientId); + + if(clientDetails instanceof ClientVO){ + return (ClientVO) clientDetails; + } + + return null; + } +} diff --git a/src/main/java/com/eactive/eai/authserver/service/UserDetailsServiceImpl.java b/src/main/java/com/eactive/eai/authserver/service/UserDetailsServiceImpl.java new file mode 100644 index 0000000..319100a --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/service/UserDetailsServiceImpl.java @@ -0,0 +1,37 @@ +package com.eactive.eai.authserver.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +import com.eactive.eai.authserver.dao.UserDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.util.Logger; + +@Service("eLinkUserDetailsService") +public class UserDetailsServiceImpl implements UserDetailsService { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private UserDAO userDAO; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + logger.debug("UserDetailsServiceImpl.loadUserByUsername :::: {}", username); + + UserDetails user = null; + try { + user = userDAO.getUserByUserId(username); + } catch (DAOException e) { + logger.error(e.getMessage()); + } + + if (user == null) { + throw new UsernameNotFoundException(username + " is not found."); + } + + return user; + } +} diff --git a/src/main/java/com/eactive/eai/authserver/util/BeanUtils.java b/src/main/java/com/eactive/eai/authserver/util/BeanUtils.java new file mode 100644 index 0000000..caa80bc --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/util/BeanUtils.java @@ -0,0 +1,13 @@ +package com.eactive.eai.authserver.util; + +import com.eactive.eai.common.util.ApplicationContextProvider; + +public class BeanUtils { + public static T getBean(String beanId, Class cls) { + return ApplicationContextProvider.getContext().getBean(beanId, cls); + } + + public static T getBean(Class cls) { + return ApplicationContextProvider.getContext().getBean(cls); + } +} diff --git a/src/main/java/com/eactive/eai/authserver/vo/ClientVO.java b/src/main/java/com/eactive/eai/authserver/vo/ClientVO.java new file mode 100644 index 0000000..869739d --- /dev/null +++ b/src/main/java/com/eactive/eai/authserver/vo/ClientVO.java @@ -0,0 +1,29 @@ +package com.eactive.eai.authserver.vo; + +import com.eactive.eai.common.message.EAIMessage; +import lombok.Data; +import org.hibernate.annotations.Comment; +import org.springframework.security.oauth2.provider.client.BaseClientDetails; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@SuppressWarnings("serial") +@Data +public class ClientVO extends BaseClientDetails { + private String clientName; + private String allowedIp; + private String modifiedOn; + private String modifiedBy; + private String issuer; + private String audience; + private String securityKey; + private String orgId; + private String orgName; + private String appStatus; + private int dailyTokenLimit; + + private Map apiMap = new HashMap<>(); +} diff --git a/src/main/java/com/eactive/eai/common/TransactionContextKeys.java b/src/main/java/com/eactive/eai/common/TransactionContextKeys.java new file mode 100644 index 0000000..89c19d7 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/TransactionContextKeys.java @@ -0,0 +1,11 @@ +package com.eactive.eai.common; + +/** + * 거래 별 Context 정보를 저장 할 상수 클래스 + */ +public interface TransactionContextKeys { + public static final String TRANSACTION_PROP = "TRANSACTION_PROP"; + public static final String GUID = "GUID"; + public static final String INTERFACE_ID = "INTERFACE_ID"; + public static final String TRANSACTION_UUID = "TRANSACTION_UUID"; +} diff --git a/src/main/java/com/eactive/eai/common/WarmupManager.java b/src/main/java/com/eactive/eai/common/WarmupManager.java new file mode 100644 index 0000000..b88a6dd --- /dev/null +++ b/src/main/java/com/eactive/eai/common/WarmupManager.java @@ -0,0 +1,91 @@ +package com.eactive.eai.common; + +import java.util.Iterator; +import java.util.Properties; + +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.routing.ElinkESBProcessProxy; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.routing.RoutingManager; +import com.eactive.eai.common.routing.RoutingVO; +import com.eactive.eai.common.util.Logger; + +public class WarmupManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static WarmupManager instance; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private boolean started; + + private WarmupManager() { + } + + public static synchronized WarmupManager getInstance() { + if (instance == null) { + instance = new WarmupManager(); + } + return instance; + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICWM001"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + RoutingManager manager = RoutingManager.getInstance(); + Iterator it = manager.getAllRoutingVOs(); + + if (it == null) { + logger.warn("RoutingManager getAllRoutingVOs is NULL"); + } else { + Properties p = new Properties(); + p.put(EAIKeys.CALL_MODE_KEY, EAIKeys.CALL_MODE_WARMUP); + p.setProperty(RouteKeys.ROUTING_TYPE, RouteKeys.ROUT_CALL); + while (it.hasNext()) { + RoutingVO vo = it.next(); + try { + if (vo == null) + continue; + if (vo.getSyncRoutingPath() != null) { + ElinkESBProcessProxy.callElinkESBProcess(vo.getSyncRoutingPath(), null, true, p); + } + } catch (Exception e) { + logger.warn("WarmupManager] warming up the routing process. - " + vo.getSyncRoutingPath()); + } + } + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICWM002"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } +} diff --git a/src/main/java/com/eactive/eai/common/activemq/AmqPooledConnectionFactory.java b/src/main/java/com/eactive/eai/common/activemq/AmqPooledConnectionFactory.java new file mode 100644 index 0000000..2206305 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/activemq/AmqPooledConnectionFactory.java @@ -0,0 +1,68 @@ +package com.eactive.eai.common.activemq; + +import java.util.Properties; + +import javax.jms.Connection; +import javax.jms.JMSException; + +import org.apache.activemq.ActiveMQConnectionFactory; +import org.apache.activemq.pool.PooledConnectionFactory; + +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.RouteKeys; + +public class AmqPooledConnectionFactory { + public static String CONNECTION_URI = "vm://localhost?broker.persistent=false&broker.useJmx=true&jms.useAsyncSend=true&jms.prefetchPolicy.all=0"; + + private static final AmqPooledConnectionFactory instance = new AmqPooledConnectionFactory(); + + private PooledConnectionFactory pooledConnectionFactory; + + public static AmqPooledConnectionFactory getInstance() { + return instance; + } + + private AmqPooledConnectionFactory() { + createNewFactory(); + } + + public Connection getConnection() throws JMSException { + return pooledConnectionFactory.createConnection(); + } + + private void createNewFactory() { + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(CONNECTION_URI); + connectionFactory.setTrustAllPackages(true); + + // Create a PooledConnectionFactory and set some configuration options + pooledConnectionFactory = new PooledConnectionFactory(); + pooledConnectionFactory.setConnectionFactory(connectionFactory); + + setConnectionProperties(); + + pooledConnectionFactory.start(); + } + + private PooledConnectionFactory setConnectionProperties() { + Properties props = PropManager.getInstance().getProperties(RouteKeys.GROUP_NAME); + int maxConnection = Integer + .parseInt(props.getProperty(RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY_MAXCONNECTION, "5")); + + long expiryTimeout = Long + .parseLong(props.getProperty(RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY_EXPIRYTIMEOUT, "0")); + + int idleTimeout = Integer + .parseInt(props.getProperty(RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY_IDLETIMEOUT, "30000")); + + pooledConnectionFactory.setMaxConnections(maxConnection); + pooledConnectionFactory.setIdleTimeout(idleTimeout); + pooledConnectionFactory.setExpiryTimeout(expiryTimeout); + + return pooledConnectionFactory; + } + + public PooledConnectionFactory reload() { + return setConnectionProperties(); + } + +} diff --git a/src/main/java/com/eactive/eai/common/activemq/AmqQueueProducer.java b/src/main/java/com/eactive/eai/common/activemq/AmqQueueProducer.java new file mode 100644 index 0000000..e3822e4 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/activemq/AmqQueueProducer.java @@ -0,0 +1,74 @@ +package com.eactive.eai.common.activemq; + +import java.io.Serializable; +import java.util.Properties; + +import javax.jms.Connection; +import javax.jms.DeliveryMode; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.ObjectMessage; +import javax.jms.Session; + +import com.eactive.eai.common.util.Logger; + +public class AmqQueueProducer { + + private Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private String queueName = null; + + public AmqQueueProducer(String connectionUrl, String queueName) { + this.queueName = queueName; + } + + public void sendMessage(Serializable object, Properties prop) throws JMSException { + Connection connection = null; + Session session = null; + MessageProducer producer = null; + + try { + // Create a Connection + connection = AmqPooledConnectionFactory.getInstance().getConnection(); + + // Create a Session + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Create the destination (Topic or Queue) + Destination destination = session.createQueue(queueName); + producer = session.createProducer(destination); + producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + ObjectMessage message = session.createObjectMessage(object); + if (prop != null) { + for(Object key : prop.keySet()) { + message.setObjectProperty(key.toString(), prop.get(key)); + } + } + producer.send(message); + } catch (JMSException ex) { + logger.error("Send Error = " + ex.getMessage(), ex); + throw ex; + } finally { + if (producer != null) { + try { + producer.close(); + } catch (Exception e) { + // ignored + } + } + if (session != null) + try { + session.close(); + } catch (JMSException e) { + // ignored + } + if (connection != null) + try { + connection.close(); + } catch (JMSException e) { + // ignored + } + } + } +} diff --git a/src/main/java/com/eactive/eai/common/activemq/AmqTopicProducer.java b/src/main/java/com/eactive/eai/common/activemq/AmqTopicProducer.java new file mode 100644 index 0000000..abae58b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/activemq/AmqTopicProducer.java @@ -0,0 +1,94 @@ +package com.eactive.eai.common.activemq; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.Properties; + +import javax.jms.Connection; +import javax.jms.DeliveryMode; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.MessageProducer; +import javax.jms.ObjectMessage; +import javax.jms.Session; + +import com.eactive.eai.common.util.Logger; + +public class AmqTopicProducer { + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + Connection connection = null; + Session session = null; + MessageProducer producer = null; + String connectionUrl = null; + String topicName = null; + String correlationID = null; + + public AmqTopicProducer(String connectionUrl, String topicName, String correlationID) { + this.connectionUrl = connectionUrl; + this.topicName = topicName; + this.correlationID = correlationID; + } + + @SuppressWarnings("rawtypes") + public void sendMessage(Serializable object, Properties prop, long ttl) throws JMSException { + try { + // Create a Connection + connection = AmqPooledConnectionFactory.getInstance().getConnection(); + + // Create a Session + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Create the destination (Topic or Queue) + Destination destination = session.createTopic(topicName); + producer = session.createProducer(destination); + producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + ObjectMessage message = session.createObjectMessage(object); + + if(ttl > 0) { + producer.setTimeToLive(ttl); + } + + if (correlationID != null) { + message.setJMSCorrelationID(correlationID); + } + + if (prop != null) { + Iterator it = prop.keySet().iterator(); + while (it.hasNext()) { + String key = (String) it.next(); + String value = prop.getProperty(key); + message.setStringProperty(key, value); + } + } + + producer.send(message); + } + catch(JMSException ex) { + logger.error("Send Error = " + ex.getMessage(), ex); + throw ex; + } + finally { + if (producer != null) { + try { + producer.close(); + } catch (Exception e) { + // ignored + } + } + if (session != null) + try { + session.close(); + } catch (JMSException e) { + // ignored + } + if (connection != null) + try { + connection.close(); + } catch (JMSException e) { + // ignored + } + } + } +} diff --git a/src/main/java/com/eactive/eai/common/authoutbound/AccessTokenManagerByDB.java b/src/main/java/com/eactive/eai/common/authoutbound/AccessTokenManagerByDB.java new file mode 100644 index 0000000..6383fe0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/authoutbound/AccessTokenManagerByDB.java @@ -0,0 +1,461 @@ +package com.eactive.eai.common.authoutbound; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.authoutbound.OutboundOAuthCredentialDao; +import com.eactive.eai.authoutbound.OutboundOAuthCredentialVo; +import com.eactive.eai.authoutbound.client.HttpClientAccessTokenServiceByDB; +import com.eactive.eai.authoutbound.client.HttpClientAccessTokenServiceFactoryByDB; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.openbanking.eai.common.token.AccessTokenVO; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.concurrent.*; + +/** +* 1. 기능 : Access 토큰 정보를 DB로 부터 로딩하고 만료시 재발급 정보를 메모리에 관리하는 Manager 클래스 +* 2. 처리 개요 : DB 프로퍼티 정보에 저장된 Access 토큰 정보를 메모리에 로딩하거나 재발급 관리한다. +* * - +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +@Component +public class AccessTokenManagerByDB implements Lifecycle { + /** + * Default Logger + */ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * AccessTokenManager Single Instance + */ + private static AccessTokenManagerByDB instance = new AccessTokenManagerByDB(); + + /** + * LifecyleSupport object + */ + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + /** + * 기동 여부 + */ + private boolean started; + + /** + * 토큰 정보를 저장하는 collection + */ + private HashMap tokens; + + /** + * 인증 정보를 저장하는 Map + */ + private Map outboundOAuthCredentialVos; + + @Autowired + OutboundOAuthCredentialDao outboundOAuthCredentialDao; + + private ScheduledExecutorService scheduler; + private Map> scheduledTasks; + private Set runningTasks; + private static final long TASK_TIMEOUT_SECONDS = 30; + + private static final int TOKEN_SCHEDULER_THREAD_POOL_SIZE = 30; + + public AccessTokenManagerByDB() { + tokens = new HashMap<>(); + scheduledTasks = new ConcurrentHashMap<>(); + outboundOAuthCredentialVos = new HashMap<>(); + runningTasks = Collections.newSetFromMap(new ConcurrentHashMap<>()); + scheduler = Executors.newScheduledThreadPool(TOKEN_SCHEDULER_THREAD_POOL_SIZE); + } + + /** + * 1. 기능 : AccessTokenManager Singleton Object를 반환하는 getter method + * 2. 처리 개요 : AccessTokenManager Singleton Object를 반환한다. + * - + * 3. 주의사항 + * + * @param + * @return + * @exception + **/ + public static AccessTokenManagerByDB getInstance() { + return ApplicationContextProvider.getContext().getBean(AccessTokenManagerByDB.class); + } + + /** + * 1. 기능 : AccessTokenManager의 초기화 여부를 반환하는 getter 메서드 + * 2. 처리 개요 : AccessTokenManager의 초기화 여부를 반환한다. + * 3. 주의사항 + * + * @return 초기화 여부 + **/ + public boolean isStarted() { + return this.started; + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICPM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + tokens.clear(); + init(); + } catch(Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e,"RECEAICPM201")); + } + + started = true; + if (logger.isWarn()){ + logger.warn("Service started successfully"); + } + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + List OutboundOAuthCredentialVos = outboundOAuthCredentialDao.getAllOutboundOAuthCredentials(); + logger.info("Initializing with {} credential configurations", OutboundOAuthCredentialVos.size()); + + for (OutboundOAuthCredentialVo outboundOAuthCredentialVo : OutboundOAuthCredentialVos) { + startToken(outboundOAuthCredentialVo); + outboundOAuthCredentialVos.put(outboundOAuthCredentialVo.getAdapterGroupName(), outboundOAuthCredentialVo); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICPM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + // 모든 스케줄된 작업 중지 + scheduledTasks.forEach((name, future) -> { + future.cancel(true); + logger.warn("Task stopped for adapter group: {}", name); + }); + scheduledTasks.clear(); + + // 실행 중인 작업 세트 클리어 + runningTasks.clear(); + + // 스케줄러 종료 + scheduler.shutdown(); + try { + if (!scheduler.awaitTermination(60, TimeUnit.SECONDS)) { + scheduler.shutdownNow(); + logger.warn("Forced shutdown of scheduler after timeout"); + } + } catch (InterruptedException e) { + scheduler.shutdownNow(); + logger.error("Scheduler shutdown interrupted", e); + } + + this.tokens = null; + started = false; + + if (logger.isWarn()){ + logger.warn("Service stopped successfully"); + } + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public synchronized void refresh(OutboundOAuthCredentialVo outboundOAuthCredentialVo) throws Exception { + String adapterGroupName = outboundOAuthCredentialVo.getAdapterGroupName(); + logger.info("Starting refresh for adapter group: {}", adapterGroupName); + + // 기존 스케줄러 작업 취소 + stopToken(adapterGroupName); + + // 인증 정보 갱신 + outboundOAuthCredentialVos.put(adapterGroupName, outboundOAuthCredentialVo); + + if("N".equals(outboundOAuthCredentialVo.getUseYn())) { + logger.info("Token task disabled for adapter group: {}", adapterGroupName); + return; + } + + // Y인 경우 새로운 스케줄러 작업 시작 + logger.info("Restarting token task for adapter group: {}", adapterGroupName); + startToken(outboundOAuthCredentialVo); + } + + public void startToken(final OutboundOAuthCredentialVo outboundOAuthCredentialVo) { + if (!"Y".equals(outboundOAuthCredentialVo.getUseYn())) { + logger.debug("Token task not started - disabled for adapter group: {}", + outboundOAuthCredentialVo.getAdapterGroupName()); + return; + } + + final String adapterGroupName = outboundOAuthCredentialVo.getAdapterGroupName(); + if (scheduledTasks.containsKey(adapterGroupName)) { + logger.warn("Token task not started - already scheduled for adapter group: {}", adapterGroupName); + return; + } + + long interval = outboundOAuthCredentialVo.getIntervalSec() > 0 ? + outboundOAuthCredentialVo.getIntervalSec() : 24 * 60 * 60; + + logger.info("Starting token task for adapter group: {} with interval: {} seconds", + adapterGroupName, interval); + + Runnable periodicTask = () -> executeTokenTask(adapterGroupName, outboundOAuthCredentialVo); + + ScheduledFuture scheduledTask = scheduler.scheduleAtFixedRate( + periodicTask, + 0, // 즉시 첫 실행 + interval, + TimeUnit.SECONDS + ); + + scheduledTasks.put(adapterGroupName, scheduledTask); + } + + private void executeTokenTask(String adapterGroupName, OutboundOAuthCredentialVo credential) { + if (!runningTasks.add(adapterGroupName)) { + logger.info("Task skipped - already running for adapter group: {}", adapterGroupName); + return; + } + + logger.debug("Starting token task for adapter group: {}", adapterGroupName); + try { + Future future = scheduler.submit(() -> { + try { + logger.debug("Executing token issuance for adapter group: {}", adapterGroupName); + + // 현재 토큰 가져오기 + AccessTokenVO accessToken = tokens.get(adapterGroupName); + + // 다음 스케줄 시간 계산 + long intervalTime = System.currentTimeMillis() + (credential.getIntervalSec() * 1000); + // 토큰이 없거나, 다음 스케줄 시간 전에 만료될 경우 재발급 + if (accessToken == null) { + issueToken(credential, false); + } else if(accessToken.getExpiration() != null) { + // 토큰이 있고 만료시간이 설정 된 경우 + if(accessToken.getExpiration().before(new Date(intervalTime))){ + // 다음 스케줄 전에 토큰이 만료되는 경우 재발급 + issueToken(credential, true); + } else { + // 토큰이 아직 유효한 경우 + logger.debug("Token still valid until next schedule for adapter group: {}, expiration date: {}", adapterGroupName, accessToken.getExpiration()); + } + } else { + //토큰이 있지만 만료 시간이 없는 경우 + logger.debug("Token exists but expiration time is null for adapter group: {}", adapterGroupName); + } + + logger.debug("Token issuance completed for adapter group: {}", adapterGroupName); + } catch (Exception e) { + logger.error("Token issuance failed for adapter group: {}", adapterGroupName, e); + } + }); + + try { + future.get(TASK_TIMEOUT_SECONDS, TimeUnit.SECONDS); + } catch (TimeoutException e) { + logger.error("Task timed out for adapter group: {}", adapterGroupName); + future.cancel(true); + } catch (Exception e) { + logger.error("Task execution failed for adapter group: {}", adapterGroupName, e); + } + } finally { + runningTasks.remove(adapterGroupName); + logger.debug("Token task completed for adapter group: {}", adapterGroupName); + } + } + + private void issueToken(OutboundOAuthCredentialVo outboundOAuthCredentialVo, boolean isTokenExpiredWithinInterval) throws Exception { + String adapterGroupName = outboundOAuthCredentialVo.getAdapterGroupName(); + boolean isExpired = true; + + if (tokens.containsKey(adapterGroupName)) { + AccessTokenVO accessToken = tokens.get(adapterGroupName); + isExpired = accessToken.isExpired(); + } + logger.debug("Token status for adapter group: {}, expired: {}, isTokenExpiredWithinInterval: {}", adapterGroupName, isExpired, isTokenExpiredWithinInterval); + + if (isExpired || isTokenExpiredWithinInterval) { + logger.info("Issuing new token for adapter group: {}", adapterGroupName); + tokens.remove(adapterGroupName); + + AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName); + + if (gvo != null && gvo.getAdapters().hasNext()) { + AdapterVO avo = gvo.getAdapters().next(); + Properties properties = AdapterPropManager.getInstance().getProperties(avo.getPropGroupName()); + String type = properties.getProperty("ADAPTER_TOKEN_ISSUING_CLIENT_TYPE"); + + HttpClientAccessTokenServiceByDB service = HttpClientAccessTokenServiceFactoryByDB.createFactory(type); + if(service != null) { + logger.debug("Executing token service of type: {} for adapter group: {}", type, adapterGroupName); + AccessTokenVO accessToken = (AccessTokenVO) service.execute(adapterGroupName, properties, outboundOAuthCredentialVo); + this.tokens.put(adapterGroupName, accessToken); + logger.info("New token issued successfully for adapter group: {}", adapterGroupName); + } else { + logger.warn("Token service not found for type: {} and adapter group: {}", type, adapterGroupName); + } + } else { + logger.warn("No valid adapter configuration found for adapter group: {}", adapterGroupName); + } + } + } + + public void stopToken(String adapterGroupName) { + ScheduledFuture task = scheduledTasks.remove(adapterGroupName); + if (task != null) { + task.cancel(true); + logger.warn("Token task stopped for adapter group: {}", adapterGroupName); + } + tokens.remove(adapterGroupName); + logger.debug("Token removed for adapter group: {}", adapterGroupName); + } + + public void refresh(String adapterGroupName) throws Exception { + refresh(outboundOAuthCredentialDao.getOutboundOAuthCredential(adapterGroupName)); + } + + /** + * 1. 기능 : LifecycleListener를 등록하는 메서드 + * 2. 처리 개요 : LifecycleListener를 등록한다. + * 3. 주의사항 + * + * @param listener LifecycleEvent를 수신한 LifecycleListener + **/ + public void addLifecycleListener(LifecycleListener listener) + { + lifecycle.addLifecycleListener(listener); + } + + /** + * 1. 기능 : 등록된 LifecycleListener 리스트를 반환하는 메서드 + * 2. 처리 개요 : 등록된 LifecycleListener 리스트를 반환하다. + * 3. 주의사항 + * + * @return 등록된 LifecycleListener 리스트 + **/ + public LifecycleListener[] findLifecycleListeners() + { + return lifecycle.findLifecycleListeners(); + } + + /** + * 1. 기능 : 등록된 LifecycleListener를 삭제하는 메서드 + * 2. 처리 개요 : 파라미터의 LifecycleListener를 삭제한다. + * 3. 주의사항 + * + * @param listener 삭제할 LifecycleListener + **/ + public void removeLifecycleListener(LifecycleListener listener) + { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isOAuthCredentialRegistered(String adapterGroupName){ + OutboundOAuthCredentialVo outboundOAuthCredentialVo = outboundOAuthCredentialVos.get(adapterGroupName); + return outboundOAuthCredentialVo != null && "Y".equals(outboundOAuthCredentialVo.getUseYn()); + } + + /** + * 1. 기능 : Access 토큰 정보를 반환하는 메서드 + * 2. 처리 개요 : Access 토큰 정보를 반환한다. + * - + * 3. 주의사항 + * + * @return Access 토큰 정보 + **/ + public AccessTokenVO getAccessTokenVO(String adapterGroupName) { + AccessTokenVO accessToken = null; + + try { + accessToken = tokens.get(adapterGroupName); + } catch(Exception e) { + if (logger.isError()) logger.error("토큰을 찾을 수 없습니다. ["+adapterGroupName+"] ", e); + } + + return accessToken; + } + + /** + * 1. 기능 : Access 토큰 값를 반환하는 메서드 + * 2. 처리 개요 : Access 토큰 값를 반환한다. + * - + * 3. 주의사항 + * + * @return accessToken 값 + **/ + public String getAccessToken(String adapterGroupName) { + String accessToken = null; + + try { + accessToken = tokens.get(adapterGroupName).getAccessToken(); + } catch(Exception e) { + if (logger.isError()) logger.error("토큰을 찾을 수 없습니다. ["+adapterGroupName+"] ", e); + } + + return accessToken; + } + + + /** + * 1. 기능 : Access 토큰를 삭제하는 메서드 + * 2. 처리 개요 : Access 토큰를 삭제한다. + * - + * 3. 주의사항 + * + **/ + public void removeAccessTokenVO(String adapterGroupName) { + // 스케줄러 작업 중지 및 토큰 제거 + stopToken(adapterGroupName); + // OAuth 인증 정보 제거 + outboundOAuthCredentialVos.remove(adapterGroupName); + } + + /** + * 1. 기능 : Access 토큰를 재발급하는 메서드 + * 2. 처리 개요 : Access 토큰를 재발급한다. + * - + * 3. 주의사항 + * + **/ + public synchronized AccessTokenVO retryAccessTokenVO(String adapterGroupName, Properties properties, String oldToken) throws Exception { + + AccessTokenVO accessToken = getAccessTokenVO(adapterGroupName); + + // 동시 요청이 발생할 경우 synchronized 처리를 했기때문에 토큰을 다시 한번 체크한다. + if (accessToken == null || accessToken.isExpired() + || StringUtils.equals(accessToken.getAccessToken(), oldToken)) { + + if(isOAuthCredentialRegistered(adapterGroupName) == false){ + throw new Exception("There is no OAuthCredentialRegistered information, or whether to use it is 'N'."); + } + String type = properties.getProperty("ADAPTER_TOKEN_ISSUING_CLIENT_TYPE"); + + HttpClientAccessTokenServiceByDB service = HttpClientAccessTokenServiceFactoryByDB.createFactory(type); + OutboundOAuthCredentialVo outboundOAuthCredentialVo = outboundOAuthCredentialVos.get(adapterGroupName); + if(service != null) { + accessToken = (AccessTokenVO) service.execute(adapterGroupName, properties, outboundOAuthCredentialVo); + } + tokens.put(adapterGroupName, accessToken); + } + + return accessToken; + } +} diff --git a/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapDAO.java b/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapDAO.java new file mode 100644 index 0000000..39af2e3 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapDAO.java @@ -0,0 +1,91 @@ +package com.eactive.eai.common.b2badaptermapping; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.b2badaptermapping.loader.B2BAdapterMapLoader; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.b2badaptermapping.B2BAdapterMap; + +@Service +@Transactional +public class B2BAdapterMapDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private B2BAdapterMapLoader b2bAdapterMapEntityService; + + public Map getAllB2BAdapterMaps(String eaiInstCd) throws DAOException { + try { + + List adapterMaps = b2bAdapterMapEntityService + .findByIdEaisevrinstncnameOrderByDefault(eaiInstCd); + Map msgKeys = new HashMap<>(); + logger.info("[ @@ Load B2BAdapterMap Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (B2BAdapterMap adapterMap : adapterMaps) { + B2BAdapterMapVO vo = new B2BAdapterMapVO(); + vo.setEaiInstCd(eaiInstCd); + vo.setEaiSvcCd(adapterMap.getId().getEaisvcname()); + + msgKeys.put(adapterMap.getId().getEaisvcname(), vo); + + vo.addB2BAdapterMapFld( adapterMap.getId().getExtnlinstiidnfiname(), + adapterMap.getId().getDmnddtalsbzwkdsticname(), + adapterMap.getPsvsysadptrbzwkgroupname(), + adapterMap.getAdptrbzwkname()); + + logger.info("B2BAdapterMapFldVO in getAllB2BAdapterMaps():"); + for (B2BAdapterMapFldVO fldVO : vo.getB2BAdapterMapFlds()) { + logger.info("@ B2BAdapterMapFld toString >> " + fldVO.toString()); + } + } + return msgKeys; + + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICBA101")); + } + } + + public Map getB2BAdapterMap(String eaiInstCd, String eaiSvcCd) throws DAOException { + try { + + HashMap msgKeys = new HashMap<>(); + Collection adapterMaps = b2bAdapterMapEntityService + .findByIdEaisevrinstncnameAndIdEaisvcname(eaiInstCd, eaiSvcCd); + logger.info("[ @@ Load B2BAdapterMap Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (B2BAdapterMap adapterMap : adapterMaps) { + B2BAdapterMapVO vo = new B2BAdapterMapVO(); + + msgKeys.put(eaiSvcCd, vo); + + vo.addB2BAdapterMapFld( adapterMap.getId().getExtnlinstiidnfiname(), + adapterMap.getId().getDmnddtalsbzwkdsticname(), + adapterMap.getPsvsysadptrbzwkgroupname(), + adapterMap.getAdptrbzwkname()); + + logger.info("B2BAdapterMapFldVO in getB2BAdapterMap():"); + for (B2BAdapterMapFldVO fldVO : vo.getB2BAdapterMapFlds()) { + logger.info("@ B2BAdapterMapFld getB2BAdapterMap >> " + fldVO.toString()); + } + } + + logger.info("[>>Load B2BAdapterMap Configuration - ended ]"); + return msgKeys; + + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICBA205")); + } + } + +} diff --git a/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapFldVO.java b/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapFldVO.java new file mode 100644 index 0000000..6622951 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapFldVO.java @@ -0,0 +1,51 @@ +package com.eactive.eai.common.b2badaptermapping; + +import java.io.Serializable; + +import lombok.Data; + +public class B2BAdapterMapFldVO implements Serializable { + private String b2bExtnlInstiCd; // id.extnlinstiidnfiname 외부기관식 별명 + private String bzwkVal; // id.dmnddtalsbzwkdsticname 요청 세부 업무 구분명 + private String adapterGroupName; // psvsysadptrbzwkgroupname 수동시스템어댑터업무그룹명 + private String adapterName; // adptrbzwkname 어댑터 이름 + + public B2BAdapterMapFldVO(String b2bExtnlInstiCd, String bzwkVal, String adapterGroupName, String adapterName) { + this.b2bExtnlInstiCd = b2bExtnlInstiCd; + this.bzwkVal = bzwkVal; + this.adapterGroupName = adapterGroupName; + this.adapterName = adapterName; + } + + public String getB2bExtnlInstiCd() { + return this.b2bExtnlInstiCd; + } + + public void setB2bExtnlInstiCd(String b2bExtnlInstiCd) { + this.b2bExtnlInstiCd = b2bExtnlInstiCd; + } + + public void setBzwkVal(String bzwkVal) { + this.bzwkVal = bzwkVal; + } + + public String getBzwkVal() { + return this.bzwkVal; + } + + public void setAdapterGroupName(String adapterGroupName) { + this.adapterGroupName = adapterGroupName; + } + + public String getAdapterGroupName() { + return this.adapterGroupName; + } + + public void setAdapterName(String adapterName) { + this.adapterName = adapterName; + } + + public String getAdapterName() { + return this.adapterName; + } +} diff --git a/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapManager.java b/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapManager.java new file mode 100644 index 0000000..0e8a328 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapManager.java @@ -0,0 +1,210 @@ +package com.eactive.eai.common.b2badaptermapping; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class B2BAdapterMapManager implements Lifecycle { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private boolean started; + + private Map messages = new HashMap<>(); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + @Autowired + private B2BAdapterMapDAO b2bAdapterMapDAO; + + public static B2BAdapterMapManager getInstance() { + return ApplicationContextProvider.getContext().getBean(B2BAdapterMapManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICBA201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICBA202")); + } + + started = true; + + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void init() throws DAOException { + String eaiInstCd = EAIServerManager.getInstance().getLocalServerName(); + messages = b2bAdapterMapDAO.getAllB2BAdapterMaps(eaiInstCd); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("B2BAdapterMapManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("B2BAdapterMapManager] reload all finished ..."); + } + } + + public synchronized void reload(String eaiSvcCd) throws Exception { + if (logger.isWarn()) { + logger.warn("B2BExtractManager] reload Started ..."); + } + Map map = b2bAdapterMapDAO + .getB2BAdapterMap(EAIServerManager.getInstance().getLocalServerName(), eaiSvcCd); + + if (map != null) { + Iterator it = map.keySet().iterator(); + String key = ""; + while (it.hasNext()) { + key = (String) it.next(); + messages.put(key, map.get(key)); + } + } + + if (logger.isWarn()) { + logger.warn("B2BExtractManager] reload finished ..."); + } + } + + public synchronized void remove(String eaiSvcCd) throws Exception { + if (logger.isWarn()) { + logger.warn("B2BExtractManager] remove Started ..."); + } + messages.remove(eaiSvcCd); + if (logger.isWarn()) { + logger.warn("B2BExtractManager] remove finished ..."); + } + } + + public void stop() throws LifecycleException { + + if (!started) + throw new LifecycleException("RECEAICBA203"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + messages.clear(); + + started = false; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public B2BAdapterMapVO getB2BAdapterMap(String eaiSvcCd) { + return messages.get(eaiSvcCd); + } + + public void setB2BAdapterMap(String eaiSvcCd, B2BAdapterMapVO msg) { + String currentInstCd = EAIServerManager.getInstance().getLocalServerName(); + + if (currentInstCd != null && currentInstCd.equals(msg.getEaiInstCd())) { + B2BAdapterMapVO current = messages.get(eaiSvcCd); + + if (current == null) { + messages.put(eaiSvcCd, msg); + } else { + String[] keys = msg.getAllKeyNames(); + for (int i = 0; i < keys.length; i++) { + B2BAdapterMapFldVO fvo = msg.getB2BAdapterMapFld(keys[i]); + if (fvo == null) + continue; + current.addB2BAdapterMapFld(fvo.getB2bExtnlInstiCd(), fvo.getBzwkVal(), fvo.getAdapterGroupName(), + fvo.getAdapterName()); + } + } + } + } + + public void updateB2BAdapterMap(String eaiSvcCd, B2BAdapterMapVO msg) { + String currentInstCd = EAIServerManager.getInstance().getLocalServerName(); + if (currentInstCd != null && currentInstCd.equals(msg.getEaiInstCd())) { + B2BAdapterMapVO current = messages.get(eaiSvcCd); + if (current == null) { + messages.put(eaiSvcCd, msg); + } else { + String[] keys = msg.getAllKeyNames(); + for (int i = 0; i < keys.length; i++) { + B2BAdapterMapFldVO fvo = msg.getB2BAdapterMapFld(keys[i]); + if (fvo == null) { + continue; + } + current.addB2BAdapterMapFld(fvo.getB2bExtnlInstiCd(), fvo.getBzwkVal(), fvo.getAdapterGroupName(), + fvo.getAdapterName()); + } + } + } + } + + public void removeB2BAdapterMap(String eaiSvcCd) { + messages.remove(eaiSvcCd); + } + + public void removeB2BAdapterMap(String eaiSvcCd, B2BAdapterMapVO msg) { + String currentInstCd = EAIServerManager.getInstance().getLocalServerName(); + if (currentInstCd != null && currentInstCd.equals(msg.getEaiInstCd())) { + B2BAdapterMapVO current = messages.get(eaiSvcCd); + if (current != null) { + String[] keys = msg.getAllKeyNames(); + for (int i = 0; i < keys.length; i++) { + B2BAdapterMapFldVO fvo = msg.getB2BAdapterMapFld(keys[i]); + if (fvo == null) { + logger.warn("B2BAdapterMapFldVO is null key=" + keys[i]); + continue; + } + current.deleteB2BAdapterMapFld(fvo.getB2bExtnlInstiCd(), fvo.getBzwkVal()); + } + + if (current.getB2BAdapterMapFldLength() == 0) { + messages.remove(eaiSvcCd); + } + } + } + } + + public String[] getAllKeyNames() { + Set keySet = this.messages.keySet(); + String[] name = keySet.toArray(new String[keySet.size()]); + Arrays.sort(name); + return name; + } +} diff --git a/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapVO.java b/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapVO.java new file mode 100644 index 0000000..f7074ed --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapVO.java @@ -0,0 +1,82 @@ +package com.eactive.eai.common.b2badaptermapping; + +import java.io.Serializable; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; + +public class B2BAdapterMapVO implements Serializable { + private static final long serialVersionUID = 1L; + + private String eaiInstCd; // EAI 서버인스턴스명 [TSEAIFR07.EAISevrInstncName] + private String eaiSvcCd; // EAI 서비스명 [TSEAIFR07.EAISvcName] + + private HashMap msgFlds; + + public B2BAdapterMapVO() { + this("", ""); + } + + public B2BAdapterMapVO(String eaiInstCd, String eaiSvcCd) { + this.eaiInstCd = eaiInstCd; + this.eaiSvcCd = eaiSvcCd; + this.msgFlds = new HashMap<>(); + } + + public void setEaiInstCd(String eaiInstCd) { + this.eaiInstCd = eaiInstCd; + } + + public String getEaiInstCd() { + return this.eaiInstCd; + } + + public void setEaiSvcCd(String eaiSvcCd) { + this.eaiSvcCd = eaiSvcCd; + } + + public String getEaiSvcCd() { + return this.eaiSvcCd; + } + + public B2BAdapterMapFldVO getB2BAdapterMapFld(String b2bExtnlInstiCd, String bzwkVal) { + return getB2BAdapterMapFld(b2bExtnlInstiCd + bzwkVal); + } + + public B2BAdapterMapFldVO getB2BAdapterMapFld(String key) { + B2BAdapterMapFldVO vo = msgFlds.get(key); + if (vo == null) + return null; + + return vo; + } + + public void addB2BAdapterMapFld(String b2bExtnlInstiCd, String bzwkVal, String adapterGroupName, + String adapterName) { + this.msgFlds.put(b2bExtnlInstiCd + bzwkVal, + new B2BAdapterMapFldVO(b2bExtnlInstiCd, bzwkVal, adapterGroupName, adapterName)); + } + + public void deleteB2BAdapterMapFld(String b2bExtnlInstiCd, String bzwkVal) { + this.msgFlds.remove(b2bExtnlInstiCd + bzwkVal); + } + + public int getB2BAdapterMapFldLength() { + return this.msgFlds.size(); + } + + public String[] getAllKeyNames() { + Iterator it = this.msgFlds.keySet().iterator(); + String[] name = new String[this.msgFlds.size()]; + for (int i = 0; it.hasNext(); i++) { + name[i] = it.next(); + } + Arrays.sort(name); + return name; + } + + public Collection getB2BAdapterMapFlds() { + return msgFlds.values(); + } +} diff --git a/src/main/java/com/eactive/eai/common/b2bextractor/B2BExtractDAO.java b/src/main/java/com/eactive/eai/common/b2bextractor/B2BExtractDAO.java new file mode 100644 index 0000000..c216a1e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2bextractor/B2BExtractDAO.java @@ -0,0 +1,68 @@ +package com.eactive.eai.common.b2bextractor; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.b2bextractor.loader.B2BExtractLoader; +import com.eactive.eai.common.b2bextractor.mapper.B2BExtractMapper; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.b2bextractor.B2BExtract; + +@Service +@Transactional +public class B2BExtractDAO extends BaseDAO { + + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private B2BExtractLoader b2bExtractEntityService; + @Autowired + private B2BExtractMapper b2bExtractMapper; + + public Map getAllB2BExtracts() throws DAOException { + + try { + HashMap b2bMap = new HashMap<>(); + List b2bExtracts = b2bExtractEntityService.findAllOrderByEaisvcname(); + logger.info("[ @@ Load B2BExtract Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (B2BExtract b2bExtract : b2bExtracts) { + B2BExtractVO vo = b2bExtractMapper.toVo(b2bExtract); + b2bMap.put(b2bExtract.getId().getEaisvcname() + b2bExtract.getId().getSvcprcssno(), vo); + } + logger.info("[>>Load B2BExtract Configuration - ended ]"); + return b2bMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICBM101")); + } + } + + public Map getB2BExtract(String eaisvcname) throws DAOException { + try { + HashMap map = new HashMap<>(); + B2BExtract b2bExtract = b2bExtractEntityService.findByIdEaisvcname(eaisvcname); + logger.info("[ @@ Load B2BExtract Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + if (b2bExtract != null) { + B2BExtractVO vo = b2bExtractMapper.toVo(b2bExtract); + String key = b2bExtract.getId().getEaisvcname() + b2bExtract.getId().getSvcprcssno(); + logger.info("@ " + vo.toString()); + map.put(key, vo); + } + + logger.info("[>>Load B2BExtract Configuration - ended ]"); + return map; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICBM205")); + } + } + +} diff --git a/src/main/java/com/eactive/eai/common/b2bextractor/B2BExtractManager.java b/src/main/java/com/eactive/eai/common/b2bextractor/B2BExtractManager.java new file mode 100644 index 0000000..de9acaa --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2bextractor/B2BExtractManager.java @@ -0,0 +1,136 @@ +package com.eactive.eai.common.b2bextractor; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class B2BExtractManager implements Lifecycle { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private Map messages = new HashMap<>(); + + private boolean started; + + @Autowired + B2BExtractDAO b2bExtractDAO; + + public static B2BExtractManager getInstance() { + return ApplicationContextProvider.getContext().getBean(B2BExtractManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICKM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICKM202")); + } + + started = true; + + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws DAOException { + messages = b2bExtractDAO.getAllB2BExtracts(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("B2BExtractManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("B2BExtractManager] reload all finished ..."); + } + } + + public synchronized void reload(String eaiSvcCd) throws Exception { + if (logger.isWarn()) { + logger.warn("B2BExtractManager] reload Started ..."); + } + Map map = b2bExtractDAO.getB2BExtract(eaiSvcCd);// eaiSvcCd + + Iterator it = map.keySet().iterator(); + String key = null; + + while (it.hasNext()) { + key = it.next(); + messages.put(key, map.get(key)); + } + + if (logger.isWarn()) { + logger.warn("B2BExtractManager] reload finished ..."); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICKM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + messages.clear(); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public B2BExtractVO getB2BExtract(String code) { + return messages.get(code); + } + + public void setB2BExtract(String code, B2BExtractVO msg) { + messages.put(code, msg); + } + + public void removeB2BExtract(String code) { + messages.remove(code); + } + + public String[] getAllKeyNames() { + Set keySet = this.messages.keySet(); + String[] names = keySet.toArray(new String[keySet.size()]); + Arrays.sort(names); + return names; + } + +} diff --git a/src/main/java/com/eactive/eai/common/b2bextractor/B2BExtractVO.java b/src/main/java/com/eactive/eai/common/b2bextractor/B2BExtractVO.java new file mode 100644 index 0000000..8967a16 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2bextractor/B2BExtractVO.java @@ -0,0 +1,49 @@ +package com.eactive.eai.common.b2bextractor; + +import java.io.Serializable; + +public class B2BExtractVO implements Serializable { + private String eaiSvcCd; // EAI 서비스명 : TSEAIFR06.EAISvcName + private int svcPssSeq; // 서비스처리번호[TSEAIFR06.SvcPrcssNo] + private String routeActionName; // RouteAction Class : TSEAIFR06.routeActionName + private String adapterActionName; // AdapterAction Class : TSEAIFR06.adapterActionName + + public B2BExtractVO(String eaiSvcCd, int svcPssSeq, String routeActionName, String adapterActionName) { + this.eaiSvcCd = eaiSvcCd; + this.svcPssSeq = svcPssSeq; + this.routeActionName = routeActionName; + this.adapterActionName = adapterActionName; + } + + public void setEaiSvcCd(String eaiSvcCd) { + this.eaiSvcCd = eaiSvcCd; + } + + public String getEaiSvcCd() { + return this.eaiSvcCd; + } + + public String getAdapterActionName() { + return adapterActionName; + } + + public void setAdapterActionName(String adapterActionName) { + this.adapterActionName = adapterActionName; + } + + public String getRouteActionName() { + return routeActionName; + } + + public void setRouteActionName(String routeActionName) { + this.routeActionName = routeActionName; + } + + public int getSvcPssSeq() { + return svcPssSeq; + } + + public void setSvcPssSeq(int svcPssSeq) { + this.svcPssSeq = svcPssSeq; + } +} diff --git a/src/main/java/com/eactive/eai/common/b2bextractor/mapper/B2BExtractMapper.java b/src/main/java/com/eactive/eai/common/b2bextractor/mapper/B2BExtractMapper.java new file mode 100644 index 0000000..0068260 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2bextractor/mapper/B2BExtractMapper.java @@ -0,0 +1,25 @@ +package com.eactive.eai.common.b2bextractor.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.b2bextractor.B2BExtractVO; +import com.eactive.eai.data.entity.onl.b2bextractor.B2BExtract; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface B2BExtractMapper extends GenericMapper { + + @Mapping(source = "id.eaisvcname", target = "eaiSvcCd") + @Mapping(source = "id.svcprcssno", target = "svcPssSeq") + @Mapping(source = "svcroutclsname", target = "routeActionName") + @Mapping(source = "adptrroutclsname", target = "adapterActionName") + @Override + B2BExtractVO toVo(B2BExtract entity); + + @InheritInverseConfiguration + @Override + B2BExtract toEntity(B2BExtractVO vo); +} diff --git a/src/main/java/com/eactive/eai/common/b2bservice/B2BServiceDAO.java b/src/main/java/com/eactive/eai/common/b2bservice/B2BServiceDAO.java new file mode 100644 index 0000000..88ea9f2 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2bservice/B2BServiceDAO.java @@ -0,0 +1,70 @@ +package com.eactive.eai.common.b2bservice; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.b2bservice.loader.B2BServiceLoader; +import com.eactive.eai.common.b2bservice.mapper.B2BServiceMapper; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.b2bservice.B2BService; + +@Service +@Transactional +public class B2BServiceDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private B2BServiceLoader b2bServiceEntityService; + + @Autowired + private B2BServiceMapper b2bServiceMapper; + + public Map getAllB2BServices() throws DAOException { + String useyn = "1"; + try { + HashMap b2bServiceMap = new HashMap<>(); // B2BService Table + List b2bServices = b2bServiceEntityService.findByUseynOrderByDefault(useyn); + logger.info("[ @@ Load B2BService Configuration - starting >>>>>>>>>>>>>>>>> ]"); + String key = null; + for (B2BService b2bService : b2bServices) { + B2BServiceVO vo = b2bServiceMapper.toVo(b2bService); + key = b2bService.getId().getExtnlinstiidnfiname() + b2bService.getId().getSvcprcssno(); + b2bServiceMap.put(key, vo); + } + logger.info("[>>Load B2BService Configuration - ended ]"); + return b2bServiceMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + public Map getB2BService(String b2bExtnlInstiCd) throws DAOException { + try { + HashMap map = new HashMap<>(); + Collection b2bServices = b2bServiceEntityService + .findByIdExtnlinstiidnfinameOrderByDefault(b2bExtnlInstiCd); + logger.info("[ @@ Load B2BService getB2BService Configuration - starting >>>>>>>>>>>>>>>>> ]"); + String key = null; + for (B2BService b2bService : b2bServices) { + B2BServiceVO vo = b2bServiceMapper.toVo(b2bService); + logger.debug("@ " + vo.toString()); + key = b2bService.getId().getExtnlinstiidnfiname() + b2bService.getId().getSvcprcssno(); + map.put(key, vo); + } + logger.info("[>>Load B2BService getB2BService Configuration - ended ]"); + return map; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + + } +} diff --git a/src/main/java/com/eactive/eai/common/b2bservice/B2BServiceManager.java b/src/main/java/com/eactive/eai/common/b2bservice/B2BServiceManager.java new file mode 100644 index 0000000..1dc0f80 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2bservice/B2BServiceManager.java @@ -0,0 +1,165 @@ +package com.eactive.eai.common.b2bservice; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ObjectUtil; + +@Component +public class B2BServiceManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private Map b2bsMsgs = new HashMap<>(); + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + @Autowired + private B2BServiceDAO b2bServiceDAO; + + public static synchronized B2BServiceManager getInstance() { + return ApplicationContextProvider.getContext().getBean(B2BServiceManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICMM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICMM202")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws DAOException { + b2bsMsgs = null; + b2bsMsgs = b2bServiceDAO.getAllB2BServices(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("B2BServiceManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("B2BServiceManager] reload all finished ..."); + } + } + + public synchronized void reload(String b2bExtnlInstiCd) throws Exception { + if (logger.isWarn()) { + logger.warn("B2BServiceManager] reload Started ..."); + } + Map map = b2bServiceDAO.getB2BService(b2bExtnlInstiCd); + if (map != null) { + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + B2BServiceVO vo = entry.getValue(); + if ("1".equals(vo.getUseYn())) { + b2bsMsgs.put(key, vo); + } else { + b2bsMsgs.remove(key); + logger.warn("B2BServiceManager] reload key[" + key + "] useYn[0] removed"); + } + } + } + + if (logger.isWarn()) { + logger.warn("B2BServiceManager] reload finished ..."); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICMM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + b2bsMsgs.clear(); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public B2BServiceVO getB2BServiceVO(String b2bExtnlInstiCd, int svcPssSeq) { + String key = b2bExtnlInstiCd + svcPssSeq; + return getB2BServiceVO(key); + } + + public B2BServiceVO getB2BServiceVO(String key) { + B2BServiceVO aMsg = b2bsMsgs.get(key); + if (aMsg != null) { + try { + return (B2BServiceVO) ObjectUtil.deepCopy(aMsg); + } catch (Exception e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICMM204")); + } + } else { + return aMsg; + } + } + + public String[] getAllKeys() { + Iterator it = this.b2bsMsgs.keySet().iterator(); + String[] svcCd = new String[this.b2bsMsgs.size()]; + for (int i = 0; it.hasNext(); i++) { + svcCd[i] = it.next(); + } + Arrays.sort(svcCd); + return svcCd; + } + + public void setB2BServiceVO(String code, B2BServiceVO msg) { + b2bsMsgs.put(code, msg); + } + + // db update 필요 + public void updateB2BServiceVO(String b2bExtnlInstiCd, int svcPssSeq, B2BServiceVO msg) { + String key = b2bExtnlInstiCd + svcPssSeq; + b2bsMsgs.put(key, msg); + } + + public void removeB2BServiceVO(String b2bExtnlInstiCd, int svcPssSeq, B2BServiceVO msg) { + String key = b2bExtnlInstiCd + svcPssSeq; + b2bsMsgs.remove(key); + } + + public void removeB2BServiceVO(String key) { + b2bsMsgs.remove(key); + } + +} diff --git a/src/main/java/com/eactive/eai/common/b2bservice/B2BServiceVO.java b/src/main/java/com/eactive/eai/common/b2bservice/B2BServiceVO.java new file mode 100644 index 0000000..0869263 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2bservice/B2BServiceVO.java @@ -0,0 +1,280 @@ +package com.eactive.eai.common.b2bservice; + +import java.io.Serializable; + +import com.eactive.eai.common.message.EAIMessageKeys; + +public class B2BServiceVO implements EAIMessageKeys, Serializable { + private static final long serialVersionUID = 1L; + + private String b2bExtnlInstiCd; // 기관코드[TSEAIHE03.ExtnlInstiIdnfiName] + private int svcPssSeq; // 서비스처리번호[TSEAIHE03.SvcPrcssNo] + private String psvItfTp; // 수동인터페이스구분명[TSEAIHE03.PsvIntfacDsticName] - PassiveInterfaceType - + // [SYNC|ASYN|AKON] + private String psvBwkSysNm; // 수동시스템업무구분코드[TSEAIHE03.PsvSysBzwkDstcd] - PassiveBusinessWorkSystemName - [ + // 3|4 자리 KB표준업무시스템명 사용 ] + private String psvSysID; // 수동시스템ID명[TSEAIHE03.PsvSysIDName] - PassiveSystemIdentifier - KB표준시스템ID Naming + // Rule을 따른다. + private String psvSysSvcCd; // 수동시스템서비스구분명[TSEAIHE03.PsvSysSvcDsticName] - PassiveSystemServiceCode - + private String psvSysItfTp; // 수동시스템어댑터업무그룹명[TSEAIHE03.PsvSysAdptrBzwkGroupName] - + // PassiveSystemInterfaceType -[Adapter_업무명_OUT] + private String flOvrCls; // 장애극복여부[TSEAIHE03.FlovrYn] - FailOverClassification -[Y|N] + private String cnvEn; // 변환유무[TSEAIHE03.ChngEonot] - ConversionExistenceOrNot -[Y|N] + private String cnvMsgID; // 변환메시지ID명[TSEAIHE03.ChngMsgIDName] - ConversionMessageIdentifier + private String bsRspMsgCprVl; // 기본응답메시지비교내용[TSEAIHE03.BascRspnsMsgCmprCtnt] - + // BasisResponseMessageCompareValue + private String bsRspCnvEn; // 기본응답변환유무[TSEAIHE03.BascRspnsChngEonot] - + // BasisResponseConversionExistenceOrNot -[Y|N] + private String bsRspCnvMsgID; // 기본응답변환메시지ID명[TSEAIHE03.BascRspnsChngMsgIDName] - + // BasisResponseConversionMessageIdentifier + private String errRspMsgCprVl; // 오류응답메시지비교내용[TSEAIHE03.ErrRspnsMsgCmprCtnt] - ErrorResponseMessageCompareValue + private String errRspCnvEn; // 오류응답변환유무[TSEAIHE03.ErrRspnsChngEonot] - ErrorResponseConversionExistenceOrNot + // -[Y|N] + private String errRspCnvMsgID; // 오류응답변환메시지ID명[TSEAIHE03.ErrRspnsChngMsgIDName] - + // ErrorResposneConversionIdentifier + private int nxtSvcPssSeq; // 다음서비스처리번호[TSEAIHE03.NextSvcPrcssNo] - NextServiceProcessSequence + private String outbRtnNm; // 아웃바운드라우팅명[TSEAIHE03.OutbndRoutName] - OutboundRoutingName + private int tmoVl; // 타임아웃값[TSEAIHE03.ToutVal] - TimeoutValue(단위: 초) + private String cpnsSvcPssCd; // 보상서비스처리구분명[TSEAIHE03.CmpenSvcPrcssDsticName] - CompensationServiceProcessCode + + // 추가됨 - ServiceMessage에 추가됨에 따라 수정 + private String supplDelYn; // 추가삭제여부[TSEAIHE03.SupplDelYn] -[Y/N] + private String hdrCtrlDstcd; // 헤더제어구분코드[TSEAIHE03.HdrCtrlDstcd] -[01/02]삭제제추가/추가삭제 + private String hdrRefClsName; // 참고틀래스명[TSEAIHE03.HdrRefClsName] -com.eactive.eai.common.header.PPSHeaderUtil + private String useYn; // 사용여부[TSEAIHE03.UseYn] -[1/0] + + public String getSupplDelYn() { + return supplDelYn; + } + + public void setSupplDelYn(String supplDelYn) { + this.supplDelYn = supplDelYn; + } + + public String getHdrCtrlDstcd() { + return hdrCtrlDstcd; + } + + public void setHdrCtrlDstcd(String hdrCtrlDstcd) { + this.hdrCtrlDstcd = hdrCtrlDstcd; + } + + public String getHdrRefClsName() { + return hdrRefClsName; + } + + public void setHdrRefClsName(String hdrRefClsName) { + this.hdrRefClsName = hdrRefClsName; + } + // END 추가됨 - ServiceMessage에 추가됨에 따라 수정 + + public String getB2bExtnlInstiCd() { + return this.b2bExtnlInstiCd; + } + + public void setB2bExtnlInstiCd(String b2bExtnlInstiCd) { + this.b2bExtnlInstiCd = b2bExtnlInstiCd; + } + + public String getBsRspCnvEn() { + return bsRspCnvEn; + } + + public boolean isBsRspCnvEn() { + return this.bsRspCnvEn.equals(YES_FLAG); + } + + public void setBsRspCnvEn(String bsRspCnvEn) { + this.bsRspCnvEn = bsRspCnvEn; + } + + public String getBsRspCnvMsgID() { + return bsRspCnvMsgID; + } + + public void setBsRspCnvMsgID(String bsRspCnvMsgID) { + this.bsRspCnvMsgID = bsRspCnvMsgID; + } + + public String getBsRspMsgCprVl() { + return bsRspMsgCprVl; + } + + public void setBsRspMsgCprVl(String bsRspMsgCprVl) { + this.bsRspMsgCprVl = bsRspMsgCprVl; + } + + public String getCnvEn() { + return cnvEn; + } + + public boolean isCnvEn() { + return this.cnvEn.equals(YES_FLAG); + } + + public void setCnvEn(String cnvEn) { + this.cnvEn = cnvEn; + } + + public String getCnvMsgID() { + return cnvMsgID; + } + + public void setCnvMsgID(String cnvMsgID) { + this.cnvMsgID = cnvMsgID; + } + + public String getCpnsSvcPssCd() { + return cpnsSvcPssCd; + } + + public void setCpnsSvcPssCd(String cpnsSvcPssCd) { + this.cpnsSvcPssCd = cpnsSvcPssCd; + } + + public String getErrRspCnvEn() { + return errRspCnvEn; + } + + public boolean isErrRspCnvEn() { + return this.errRspCnvEn.equals(YES_FLAG); + } + + public void setErrRspCnvEn(String errRspCnvEn) { + this.errRspCnvEn = errRspCnvEn; + } + + public String getErrRspCnvMsgID() { + return errRspCnvMsgID; + } + + public void setErrRspCnvMsgID(String errRspCnvMsgID) { + this.errRspCnvMsgID = errRspCnvMsgID; + } + + public String getErrRspMsgCprVl() { + return errRspMsgCprVl; + } + + public void setErrRspMsgCprVl(String errRspMsgCprVl) { + this.errRspMsgCprVl = errRspMsgCprVl; + } + + public String getFlOvrCls() { + return flOvrCls; + } + + public boolean hasFailOver() { + return this.flOvrCls.equals(YES_FLAG); + } + + public void setFlOvrCls(String flOvrCls) { + this.flOvrCls = flOvrCls; + } + + public int getNxtSvcPssSeq() { + return nxtSvcPssSeq; + } + + public void setNxtSvcPssSeq(int nxtSvcPssSeq) { + this.nxtSvcPssSeq = nxtSvcPssSeq; + } + + public String getOutbRtnNm() { + return outbRtnNm; + } + + public void setOutbRtnNm(String outbRtnNm) { + this.outbRtnNm = outbRtnNm; + } + + public String getPsvBwkSysNm() { + return psvBwkSysNm; + } + + public void setPsvBwkSysNm(String psvBwkSysNm) { + this.psvBwkSysNm = psvBwkSysNm; + } + + public String getPsvItfTp() { + return psvItfTp; + } + + public boolean isSyncItfTp() { + return this.psvItfTp.equals(SYNC_SVC); + } + + public boolean isAckItfTp() { + return this.psvItfTp.equals(ACKONLY_SVC); + } + + public void setPsvItfTp(String psvItfTp) { + this.psvItfTp = psvItfTp; + } + + public String getPsvSysID() { + return psvSysID; + } + + public void setPsvSysID(String psvSysID) { + this.psvSysID = psvSysID; + } + + public String getPsvSysItfTp() { + return psvSysItfTp; + } + + public void setPsvSysItfTp(String psvSysItfTp) { + this.psvSysItfTp = psvSysItfTp; + } + + public String getPsvSysSvcCd() { + return psvSysSvcCd; + } + + public void setPsvSysSvcCd(String psvSysSvcCd) { + this.psvSysSvcCd = psvSysSvcCd; + } + + public int getTmoVl() { + return tmoVl; + } + + public boolean hasTimeOut() { + return (this.tmoVl > 0); + } + + public void setTmoVl(int tmoVl) { + this.tmoVl = tmoVl; + } + + public int getSvcPssSeq() { + return svcPssSeq; + } + + public void setSvcPssSeq(int seq) { + svcPssSeq = seq; + } + + public String getUseYn() { + return useYn; + } + + public void setUseYn(String useYn) { + this.useYn = useYn; + } + + @Override + public String toString() { + return "B2BServiceVO [b2bExtnlInstiCd=" + b2bExtnlInstiCd + ", svcPssSeq=" + svcPssSeq + ", psvItfTp=" + + psvItfTp + ", psvBwkSysNm=" + psvBwkSysNm + ", psvSysID=" + psvSysID + ", psvSysSvcCd=" + psvSysSvcCd + + ", psvSysItfTp=" + psvSysItfTp + ", flOvrCls=" + flOvrCls + ", cnvEn=" + cnvEn + ", cnvMsgID=" + + cnvMsgID + ", bsRspMsgCprVl=" + bsRspMsgCprVl + ", bsRspCnvEn=" + bsRspCnvEn + ", bsRspCnvMsgID=" + + bsRspCnvMsgID + ", errRspMsgCprVl=" + errRspMsgCprVl + ", errRspCnvEn=" + errRspCnvEn + + ", errRspCnvMsgID=" + errRspCnvMsgID + ", nxtSvcPssSeq=" + nxtSvcPssSeq + ", outbRtnNm=" + outbRtnNm + + ", tmoVl=" + tmoVl + ", cpnsSvcPssCd=" + cpnsSvcPssCd + ", supplDelYn=" + supplDelYn + + ", hdrCtrlDstcd=" + hdrCtrlDstcd + ", hdrRefClsName=" + hdrRefClsName + ", useYn=" + useYn + "]"; + } + + +} diff --git a/src/main/java/com/eactive/eai/common/b2bservice/mapper/B2BServiceMapper.java b/src/main/java/com/eactive/eai/common/b2bservice/mapper/B2BServiceMapper.java new file mode 100644 index 0000000..49b0889 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/b2bservice/mapper/B2BServiceMapper.java @@ -0,0 +1,45 @@ +package com.eactive.eai.common.b2bservice.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.b2bservice.B2BServiceVO; +import com.eactive.eai.data.entity.onl.b2bservice.B2BService; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface B2BServiceMapper extends GenericMapper { + + @Mapping(source = "id.extnlinstiidnfiname", target = "b2bExtnlInstiCd") + @Mapping(source = "id.svcprcssno", target = "svcPssSeq") + @Mapping(source = "psvintfacdsticname", target = "psvItfTp") + @Mapping(source = "psvsysbzwkdstcd", target = "psvBwkSysNm") + @Mapping(source = "psvsysidname", target = "psvSysID") + @Mapping(source = "psvsyssvcdsticname", target = "psvSysSvcCd") + @Mapping(source = "psvsysadptrbzwkgroupname", target = "psvSysItfTp") + @Mapping(source = "flovryn", target = "flOvrCls") + @Mapping(source = "chngeonot", target = "cnvEn") + @Mapping(source = "chngmsgidname", target = "cnvMsgID") + @Mapping(source = "bascrspnsmsgcmprctnt", target = "bsRspMsgCprVl") + @Mapping(source = "bascrspnschngeonot", target = "bsRspCnvEn") + @Mapping(source = "bascrspnschngmsgidname", target = "bsRspCnvMsgID") + @Mapping(source = "errrspnsmsgcmprctnt", target = "errRspMsgCprVl") + @Mapping(source = "errrspnschngeonot", target = "errRspCnvEn") + @Mapping(source = "errrspnschngmsgidname", target = "errRspCnvMsgID") + @Mapping(source = "nextsvcprcssno", target = "nxtSvcPssSeq") + @Mapping(source = "outbndroutname", target = "outbRtnNm") + @Mapping(source = "toutval", target = "tmoVl") + @Mapping(source = "cmpensvcprcssdsticname", target = "cpnsSvcPssCd") + @Mapping(source = "suppldelyn", target = "supplDelYn") + @Mapping(source = "hdrctrldstcd", target = "hdrCtrlDstcd") + @Mapping(source = "hdrrefclsname", target = "hdrRefClsName") + @Mapping(source = "useyn", target = "useYn") + @Override + B2BServiceVO toVo(B2BService entity); + + @InheritInverseConfiguration + @Override + B2BService toEntity(B2BServiceVO vo); +} diff --git a/src/main/java/com/eactive/eai/common/bizkey/BizKeyDAO.java b/src/main/java/com/eactive/eai/common/bizkey/BizKeyDAO.java new file mode 100644 index 0000000..5482ad7 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/bizkey/BizKeyDAO.java @@ -0,0 +1,91 @@ +package com.eactive.eai.common.bizkey; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.bizkey.loader.BizKeyLoader; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.bizkey.BizKey; + +@Service +@Transactional +public class BizKeyDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private BizKeyLoader bizKeyLoader; + + public Map getAllBizKeys() throws Exception { + + try { + List bizKeys = bizKeyLoader.findAllOrderByDefault(); + Map msgKeys = new HashMap<>(); + if (logger.isInfoEnabled()) { + logger.info("[ @@ Load BizKey Configuration - starting >>>>>>>>>>>>>>>>> ]"); + } + for (BizKey bizKey : bizKeys) { + String key = bizKey.getId().getEaisvcname() + bizKey.getId().getEtractdstcd(); + BizKeyVO vo = msgKeys.get(key); + + if (vo == null) { + vo = new BizKeyVO(bizKey.getId().getEaisvcname(), bizKey.getId().getEtractdstcd()); + msgKeys.put(key, vo); + } + + vo.addBizKeyFld(bizKey.getMsgdstcd(), bizKey.getBzwkfldname()); + + } + if (logger.isInfoEnabled()) { + logger.info("[>>Load BizKey Configuration - ended ]"); + } + return msgKeys; + + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICBM101")); + } + } + + public Map getBizKey(String eaiSvcCd, String exrClsNm) throws Exception { + try { + Map msgKeys = new HashMap<>(); + Collection bizKeys = bizKeyLoader.findByIdEaisvcnameAndIdEtractdstcd(eaiSvcCd, exrClsNm); + logger.info("[ @@ Load BizKey getBizKey Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (BizKey bizKey : bizKeys) { + String key = bizKey.getId().getEaisvcname() + bizKey.getId().getEtractdstcd(); + BizKeyVO vo = msgKeys.get(key); + + if (vo == null) { + vo = new BizKeyVO(eaiSvcCd, exrClsNm); + msgKeys.put(key, vo); + } + + vo.addBizKeyFld(bizKey.getId().getFldprcssno(), bizKey.getMsgdstcd(), bizKey.getBzwkfldname()); + } + + if (logger.isInfoEnabled()) { + logger.info("BizKeyFldVO in getBizKey():"); + for (BizKeyVO vo : msgKeys.values()) { + for (BizKeyFldVO fldVO : vo.getAlMsgFlds()) { + logger.info("BizKeyFld getBizKey --->> " + fldVO.toString()); + } + } + logger.info("[>>Load BizKey getBizKey Configuration - ended ]"); + } + return msgKeys; + + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICBM205")); + } + } + +} diff --git a/src/main/java/com/eactive/eai/common/bizkey/BizKeyFldVO.java b/src/main/java/com/eactive/eai/common/bizkey/BizKeyFldVO.java new file mode 100644 index 0000000..2d3da2a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/bizkey/BizKeyFldVO.java @@ -0,0 +1,53 @@ +package com.eactive.eai.common.bizkey; + +import java.io.Serializable; + +public class BizKeyFldVO implements Serializable { + private static final long serialVersionUID = 1L; + + private int colPssSeq; // 순번 [TSEAIFR03.FldPrcssNo] + private String msgTp; // 메시지유형 [TSEAIFR03.MsgDstcd] + private String bwkColNm; // 업무필드명 [TSEAIFR03.BzwkFldName] + + public BizKeyFldVO(int colPssSeq, String msgTp, String bwkColNm) { + this.colPssSeq = colPssSeq; + this.msgTp = msgTp; + this.bwkColNm = bwkColNm; + } + + public void setColPssSeq(int colPssSeq) { + this.colPssSeq = colPssSeq; + } + + public int getColPssSeq() { + return this.colPssSeq; + } + + public void setMsgTp(String msgTp) { + this.msgTp = msgTp; + } + + public String getMsgTp() { + return this.msgTp; + } + + public void setBwkColNm(String bwkColNm) { + this.bwkColNm = bwkColNm; + } + + public String getBwkColNm() { + return this.bwkColNm; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("BizKeyFldVO {") + .append("colPssSeq=").append(colPssSeq).append(", ") + .append("msgTp='").append(msgTp).append("', ") + .append("bwkColNm='").append(bwkColNm).append("'") + .append("}"); + return sb.toString(); + } + +} diff --git a/src/main/java/com/eactive/eai/common/bizkey/BizKeyManager.java b/src/main/java/com/eactive/eai/common/bizkey/BizKeyManager.java new file mode 100644 index 0000000..7c2577e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/bizkey/BizKeyManager.java @@ -0,0 +1,139 @@ +package com.eactive.eai.common.bizkey; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class BizKeyManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private Map messages = new HashMap<>(); + private LifecycleSupport lifecycle = new LifecycleSupport(this); + private boolean started; + + @Autowired + private BizKeyDAO bizKeyDAO; + + public static BizKeyManager getInstance() { + return ApplicationContextProvider.getContext().getBean(BizKeyManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICBM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICBM202")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + messages = null; + messages = bizKeyDAO.getAllBizKeys(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("BizKeyManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("BizKeyManager] reload all finished ..."); + } + } + + public synchronized void reload(String eaiSvcCd, String exrClsNm) throws Exception { + Map map = bizKeyDAO.getBizKey(eaiSvcCd, exrClsNm); + if (map != null) { + Iterator it = map.keySet().iterator(); + + String key = ""; + while (it.hasNext()) { + key = it.next(); + messages.put(key, map.get(key)); + } + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICBM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + messages.clear(); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public BizKeyVO getBizKey(String code) { + return messages.get(code); + } + + public BizKeyVO getBizKey(String eaiSvcCd, String exrClsNm) { + return messages.get(eaiSvcCd + exrClsNm); + } + + public void setBizKey(String code, BizKeyVO msg) { + messages.put(code, msg); + } + + public void setBizKey(String eaiSvcCd, String exrClsNm, BizKeyVO vo) { + messages.put(eaiSvcCd + exrClsNm, vo); + } + + public void updateBizKey(String eaiSvcCd, String exrClsNm, BizKeyVO vo) { + messages.put(eaiSvcCd + exrClsNm, vo); + } + + public void removeBizKey(String code) { + messages.remove(code); + } + + public String[] getAllKeyNames() { + Iterator it = this.messages.keySet().iterator(); + String[] name = new String[this.messages.size()]; + for (int i = 0; it.hasNext(); i++) { + name[i] = it.next(); + } + Arrays.sort(name); + return name; + } +} diff --git a/src/main/java/com/eactive/eai/common/bizkey/BizKeyVO.java b/src/main/java/com/eactive/eai/common/bizkey/BizKeyVO.java new file mode 100644 index 0000000..0f32561 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/bizkey/BizKeyVO.java @@ -0,0 +1,81 @@ +package com.eactive.eai.common.bizkey; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +public class BizKeyVO implements Serializable { + private static final long serialVersionUID = 1L; + + private String eaiSvcCd; // EAI 서비스코드 [TSEAIFR03.EAISvcName] + private String exrClsNm; // 추출구분 [TSEAIFR03.EtractDstcd] (추적필드(TR) | ALT-KEY(AK)) + + private ArrayList alMsgFlds; + + public BizKeyVO() { + this(""); + } + + public BizKeyVO(String eaiSvcCd) { + this(eaiSvcCd, ""); + } + + public BizKeyVO(String eaiSvcCd, String exrClsNm) { + this.eaiSvcCd = eaiSvcCd; + this.exrClsNm = exrClsNm; + this.alMsgFlds = new ArrayList<>(); + } + + public void setEaiSvcCd(String eaiSvcCd) { + this.eaiSvcCd = eaiSvcCd; + } + + public String getEaiSvcCd() { + return this.eaiSvcCd; + } + + public void setExrClsNm(String exrClsNm) { + this.exrClsNm = exrClsNm; + } + + public String getExrClsNm() { + return this.exrClsNm; + } + + public BizKeyFldVO getBizKeyFld(int key) { + BizKeyFldVO vo = alMsgFlds.get(key); + if (vo == null) + return null; + + return vo; + } + + public void addBizKeyFld(String msgTp, String bwkColNm) { + int alSize = this.alMsgFlds.size(); + this.alMsgFlds.add(new BizKeyFldVO(alSize + 1, msgTp, bwkColNm)); + } + + public void addBizKeyFld(int colPssSeq, String msgTp, String bwkColNm) { + this.alMsgFlds.add(new BizKeyFldVO(colPssSeq, msgTp, bwkColNm)); + } + + public int getBizKeyFldLength() { + return this.alMsgFlds.size(); + } + + @Override + public String toString() { + return "BizKeyFldVO [alMsgFlds=" + printMessageFields() + "]"; + } + + private String printMessageFields() { + StringBuilder sb = new StringBuilder(); + alMsgFlds.forEach( field -> sb.append(field.toString()).append("\n | ") ); + return sb.toString(); + } + + public List getAlMsgFlds() { + return alMsgFlds; + } + +} diff --git a/src/main/java/com/eactive/eai/common/bpa/RuleManager.java b/src/main/java/com/eactive/eai/common/bpa/RuleManager.java new file mode 100644 index 0000000..26d50cc --- /dev/null +++ b/src/main/java/com/eactive/eai/common/bpa/RuleManager.java @@ -0,0 +1,139 @@ +package com.eactive.eai.common.bpa; + + +import java.util.List; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.CondPerRtgInfo; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.transformer.function.util.CodeConversion; +import com.eactive.eai.transformer.layout.Layout; +import com.eactive.eai.transformer.message.EbcdicMessage; +import com.eactive.eai.transformer.message.Message; +import com.eactive.eai.transformer.message.MessageFactory; +import com.eactive.eai.transformer.message.XMLMessage; +import com.eactive.eai.transformer.transform.Transform; +import com.eactive.eai.transformer.transform.TransformManager; + +/** +* 1. 기능 : 복합거래 FlowControl에서 +* EAI 서비스메시지에 등록된 조건부 라우팅 룰에 대한 제어(TRUE/FALSE)를 처리하는 기능을 담당한다 +* 2. 처리 개요 : +* - 응답메시지의 특정키갑을 정상값과 비교 +* - 정상인 경우 결과처리번호(다음처리순번), 오류인경우 -1을 리턴한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public final class RuleManager { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private RuleManager() { + + } + + /** + * 1. 기능 : 업무메시지에서 추적필드를 추출하는 함수 2. 처리 개요 : - BizKeyManager에서 Rule정보를 조회 - 조회된 + * Rule을 기반으로 기능 처리 3. 주의사항 + * + * @param eaiSvcCd EAI서비스코드 + * @param messageID EAI 헤더에 정의된 메시지ID + * @param message 업무메시지 Object + * @return 결과 String 값(추적필드값) + * @exception Exception + */ + public static int getNextServieSeq(EAIMessage eaiMsg) throws Exception { + try { + String transformName = eaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID(); + Object message = eaiMsg.getStandardMessage().getBizData(); + + if (message == null) { + logger.error("RoutingRuleManager] 응답메시지가 NULL입니다 - " + message); + throw new Exception("RECEAICRR003"); + } + + logger.debug("RoutingRuleManager] 서비스메시지 [ " + eaiMsg.getCurrentSvcMsg().getSvcPssSeq() + " ] 에 대한 변환명은 [ " + + transformName + " ]입니다."); + + // ---------------------------------------------------- + // Message Object 생성 + // ---------------------------------------------------- + TransformManager manager = TransformManager.getManager(); + Transform info = manager.getTransform(transformName); + if (info == null) + throw new Exception("변환 정보를 찾을 수 없습니다.. - " + transformName); + Layout l = info.getTargetLayout(); + String messageID = l.getName(); + if (messageID == null) { + logger.error("RoutingRuleManager] Message ID is null."); + throw new RuntimeException("RECEAICRR004"); + } + + Message msg = MessageFactory.getFactory().getMessage(messageID); + logger.debug("RoutingRuleManager] layoutType [ " + l.getLayoutType().getName() + " ]"); + if (l.getLayoutType().getName().equals("XML")) { + + String xmlString = ""; + if (message instanceof byte[]) { + xmlString = new String((byte[]) message); + } else { + xmlString = (String) message; + } + String rootItemName = ((XMLMessage) msg).getLayout().getRootItem().getName(); + + xmlString = MessageUtil.removeXMLHeader(xmlString); + xmlString = "<" + rootItemName + ">" + xmlString + ""; + msg.setData(xmlString); + } else if (l.getLayoutType().getName().equals("BYTES") || l.getLayoutType().getName().equals("EBCDIC")) { + msg.setData(message); + } else { + msg.setData(message); + } + + // Routing Rule 조회 + List condPerRtgInfoList = eaiMsg.getCurrentSvcMsg().getCondPerRtgInfo(); + + String prcssNo = "-1"; + if (condPerRtgInfoList != null) { + int ruleSize = condPerRtgInfoList.size(); + + for (int i = 0; i < ruleSize; i++) { + CondPerRtgInfo rtnInfo = condPerRtgInfoList.get(i); + + prcssNo = rtnInfo.getRsultPrcssNo(); + + String defVal = rtnInfo.getRuleCprTxt(); // 비교내용 + String colName = rtnInfo.getRuleColNm(); // 규칙필드명 + String keyVal = ""; + if (msg instanceof EbcdicMessage) { + keyVal = new String(CodeConversion.seToAsc(msg.getByteArray(colName))); + } else { + keyVal = msg.getString(colName); + } + + if (!defVal.equals(keyVal)) { + logger.info("RoutingRuleManager] FALSE RETURN[" + keyVal + " : " + defVal + " ]"); + return (-1); + } + } + } + // 정상 Routing Rule 리턴 + int iprcssNo = -1; + + try { + iprcssNo = Integer.parseInt(prcssNo); + } catch (Exception nfe) { + logger.error("RoutingRuleManager] Invalid RsultPrcssNo [" + prcssNo + "]" + nfe.getMessage()); + throw new Exception("RECEAICRR002"); + } + return iprcssNo; + } catch (Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICRR001")); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/c2rservice/C2RServiceDAO.java b/src/main/java/com/eactive/eai/common/c2rservice/C2RServiceDAO.java new file mode 100644 index 0000000..0b426fc --- /dev/null +++ b/src/main/java/com/eactive/eai/common/c2rservice/C2RServiceDAO.java @@ -0,0 +1,69 @@ +package com.eactive.eai.common.c2rservice; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.c2rservice.loader.C2RServiceLoader; +import com.eactive.eai.common.c2rservice.mapper.C2RServiceMapper; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.c2rservice.C2RService; + +@Service +@Transactional +public class C2RServiceDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + C2RServiceLoader c2rServiceEntityService; + + @Autowired + C2RServiceMapper c2rServiceMapper; + + public Map getAllC2RServices() throws DAOException { + try { + HashMap c2rMap = new HashMap<>(); + List c2rServices = c2rServiceEntityService.findByUseynOrderByDefault("1"); + logger.info("[ @@ Load C2RService Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (C2RService c2rService : c2rServices) { + C2RServiceVO vo = c2rServiceMapper.toVo(c2rService); + logger.info("@ " + vo.toString()); + String key = c2rService.getId().getExtnlinstiidnfiname() + c2rService.getId().getSvcprcssno(); + c2rMap.put(key, vo); + } + logger.info("[>>Load C2RService Configuration - ended ]"); + return c2rMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + public Map getC2RService(String c2rExtnlInstiCd) throws DAOException { + try { + HashMap c2rMap = new HashMap<>(); + C2RService c2rService = c2rServiceEntityService.findByIdExtnlinstiidnfinameOrderByDefault(c2rExtnlInstiCd); + logger.info("[ @@ Load C2RService getC2RService Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + if (c2rService != null) { + C2RServiceVO vo = c2rServiceMapper.toVo(c2rService); + logger.info("@ " + vo.toString()); + String key = c2rService.getId().getExtnlinstiidnfiname() + c2rService.getId().getSvcprcssno(); + c2rMap.put(key, vo); + } + + logger.info("[>>Load C2RService getC2RService Configuration - ended ]"); + return c2rMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + +} diff --git a/src/main/java/com/eactive/eai/common/c2rservice/C2RServiceManager.java b/src/main/java/com/eactive/eai/common/c2rservice/C2RServiceManager.java new file mode 100644 index 0000000..fcf3430 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/c2rservice/C2RServiceManager.java @@ -0,0 +1,169 @@ +package com.eactive.eai.common.c2rservice; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ObjectUtil; + +@Component +public class C2RServiceManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + C2RServiceDAO c2rServiceDAO; + + private Map c2rsMsgs = new HashMap<>(); + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + public static synchronized C2RServiceManager getInstance() { + return ApplicationContextProvider.getContext().getBean(C2RServiceManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICMM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICMM202")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws DAOException { + c2rsMsgs = null; + c2rsMsgs = c2rServiceDAO.getAllC2RServices(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("C2RExtractManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("C2RExtractManager] reload all finished ..."); + } + } + + public synchronized void reload(String c2rExtnlInstiCd) throws Exception { + if (logger.isWarn()) { + logger.warn("C2RExtractManager] reload Started ..."); + } + Map map = c2rServiceDAO.getC2RService(c2rExtnlInstiCd); + if (map != null) { + Iterator it = map.keySet().iterator(); + String key = ""; + + while (it.hasNext()) { + key = it.next(); + C2RServiceVO vo = map.get(key); + if ("1".equals(vo.getUseYn())) { + c2rsMsgs.put(key, map.get(key)); + } else { + c2rsMsgs.remove(key); + logger.warn("C2RServiceManager] reload key[" + key + "] useYn[0] removed"); + } + } + } + if (logger.isWarn()) { + logger.warn("C2RExtractManager] reload finished ..."); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICMM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + c2rsMsgs.clear(); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public C2RServiceVO getC2RServiceVO(String c2rExtnlInstiCd, int svcPssSeq) { + String key = c2rExtnlInstiCd + svcPssSeq; + return getC2RServiceVO(key); + } + + public C2RServiceVO getC2RServiceVO(String key) { + C2RServiceVO aMsg = c2rsMsgs.get(key); + if (aMsg != null) { + try { + return (C2RServiceVO) ObjectUtil.deepCopy(aMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(e.getMessage(), e); + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICMM204")); + } + } else { + return aMsg; + } + } + + public String[] getAllKeys() { + Iterator it = this.c2rsMsgs.keySet().iterator(); + String[] svcCd = new String[this.c2rsMsgs.size()]; + + for (int i = 0; it.hasNext(); i++) { + svcCd[i] = it.next(); + } + Arrays.sort(svcCd); + return svcCd; + } + + public void setC2RServiceVO(String code, C2RServiceVO vo) { + c2rsMsgs.put(code, vo); + } + + // db update 필요 + public void updateC2RServiceVO(String c2rExtnlInstiCd, int svcPssSeq, C2RServiceVO vo) { + String key = c2rExtnlInstiCd + svcPssSeq; + c2rsMsgs.put(key, vo); + } + + public void removeC2RServiceVO(String c2rExtnlInstiCd, int svcPssSeq, C2RServiceVO vo) { + String key = c2rExtnlInstiCd + svcPssSeq; + c2rsMsgs.remove(key); + } + + public void removeC2RServiceVO(String key) { + c2rsMsgs.remove(key); + } +} diff --git a/src/main/java/com/eactive/eai/common/c2rservice/C2RServiceVO.java b/src/main/java/com/eactive/eai/common/c2rservice/C2RServiceVO.java new file mode 100644 index 0000000..b471bac --- /dev/null +++ b/src/main/java/com/eactive/eai/common/c2rservice/C2RServiceVO.java @@ -0,0 +1,259 @@ +package com.eactive.eai.common.c2rservice; + +import java.io.Serializable; + +import com.eactive.eai.common.message.EAIMessageKeys; + + +public class C2RServiceVO implements EAIMessageKeys, Serializable { + private static final long serialVersionUID = 1L; + + private String c2rExtnlInstiCd; // 외부기관식별명 [TSEAIHE04.extnlinstiidnfiname] + private int svcPssSeq; // 서비스처리순서 [TSEAIHE04.svcprcssno] + private String psvItfTp; // 수동인터페이스유형 [TSEAIHE04.psvintfacdsticname] + private String psvBwkSysNm; // 수동업무시스템명 [TSEAIHE04.psvsysbzwkdstcd] + private String psvSysID; // 수동시스템ID [TSEAIHE04.psvsysidname] + private String psvSysSvcCd; // 수동시스템서비스코드 [TSEAIHE04.psvsyssvcdsticname] + private String psvSysItfTp; // 수동시스템어댑터업무그룹명 [TSEAIHE04.psvsysadptrbzwkgroupname] + private String flOvrCls; // FailOver여부 [TSEAIHE04.flovryn] + private String cnvEn; // 변환유무 [TSEAIHE04.chngeonot] + private String cnvMsgID; // 변환메시지ID [TSEAIHE04.chngmsgidname] + private String bsRspMsgCprVl; // 기본응답메시지비교값 [TSEAIHE04.bascrspnsmsgcmprctnt] + private String bsRspCnvEn; // 기본응답변환유무 [TSEAIHE04.bascrspnschngeonot] + private String bsRspCnvMsgID; // 기본응답변환메시지ID [TSEAIHE04.bascrspnschngmsgidname] + private String errRspMsgCprVl; // 오류응답메시지비교값 [TSEAIHE04.errrspnsmsgcmprctnt] + private String errRspCnvEn; // 오류응답변환유무 [TSEAIHE04.errrspnschngeonot] + private String errRspCnvMsgID; // 오류응답변환메시지ID [TSEAIHE04.errrspnschngmsgidname] + private int nxtSvcPssSeq; // 다음서비스처리번호 [TSEAIHE04.nextsvcprcssno] + private String outbRtnNm; // Outbound라우팅명 [TSEAIHE04.outbndroutname] + private int tmoVl; // 타임아웃값 [TSEAIHE04.toutval] + private String cpnsSvcPssCd; // 보상서비스처리코드 [TSEAIHE04.cmpensvcprcssdsticname] + + private String supplDelYn; // 추가삭제여부 [TSEAIHE04.suppldelyn] + private String hdrCtrlDstcd; // 헤더제어구분코드 [TSEAIHE04.hdrctrldstcd] + private String hdrRefClsName; // 참고클래스명 [TSEAIHE04.hdrrefclsname] + private String useYn; // 사용여부 [TSEAIHE04.useyn] + + public String getSupplDelYn() { + return supplDelYn; + } + + public void setSupplDelYn(String supplDelYn) { + this.supplDelYn = supplDelYn; + } + + public String getHdrCtrlDstcd() { + return hdrCtrlDstcd; + } + + public void setHdrCtrlDstcd(String hdrCtrlDstcd) { + this.hdrCtrlDstcd = hdrCtrlDstcd; + } + + public String getHdrRefClsName() { + return hdrRefClsName; + } + + public void setHdrRefClsName(String hdrRefClsName) { + this.hdrRefClsName = hdrRefClsName; + } + + public String getC2rExtnlInstiCd() { + return this.c2rExtnlInstiCd; + } + + public void setC2rExtnlInstiCd(String c2rExtnlInstiCd) { + this.c2rExtnlInstiCd = c2rExtnlInstiCd; + } + + public String getBsRspCnvEn() { + return bsRspCnvEn; + } + + public boolean isBsRspCnvEn() { + return this.bsRspCnvEn.equals( YES_FLAG ); + } + + public void setBsRspCnvEn(String bsRspCnvEn) { + this.bsRspCnvEn = bsRspCnvEn; + } + + public String getBsRspCnvMsgID() { + return bsRspCnvMsgID; + } + + public void setBsRspCnvMsgID(String bsRspCnvMsgID) { + this.bsRspCnvMsgID = bsRspCnvMsgID; + } + + public String getBsRspMsgCprVl() { + return bsRspMsgCprVl; + } + + public void setBsRspMsgCprVl(String bsRspMsgCprVl) { + this.bsRspMsgCprVl = bsRspMsgCprVl; + } + + public String getCnvEn() { + return cnvEn; + } + + public boolean isCnvEn() { + return this.cnvEn.equals( YES_FLAG ); + } + + public void setCnvEn(String cnvEn) { + this.cnvEn = cnvEn; + } + + public String getCnvMsgID() { + return cnvMsgID; + } + + public void setCnvMsgID(String cnvMsgID) { + this.cnvMsgID = cnvMsgID; + } + + public String getCpnsSvcPssCd() { + return cpnsSvcPssCd; + } + + public void setCpnsSvcPssCd(String cpnsSvcPssCd) { + this.cpnsSvcPssCd = cpnsSvcPssCd; + } + + public String getErrRspCnvEn() { + return errRspCnvEn; + } + + public boolean isErrRspCnvEn() { + return this.errRspCnvEn.equals( YES_FLAG ); + } + + public void setErrRspCnvEn(String errRspCnvEn) { + this.errRspCnvEn = errRspCnvEn; + } + + public String getErrRspCnvMsgID() { + return errRspCnvMsgID; + } + + public void setErrRspCnvMsgID(String errRspCnvMsgID) { + this.errRspCnvMsgID = errRspCnvMsgID; + } + + public String getErrRspMsgCprVl() { + return errRspMsgCprVl; + } + + public void setErrRspMsgCprVl(String errRspMsgCprVl) { + this.errRspMsgCprVl = errRspMsgCprVl; + } + + public String getFlOvrCls() { + return flOvrCls; + } + + public boolean hasFailOver() { + return this.flOvrCls.equals( YES_FLAG ); + } + + public void setFlOvrCls(String flOvrCls) { + this.flOvrCls = flOvrCls; + } + + public int getNxtSvcPssSeq() { + return nxtSvcPssSeq; + } + + public void setNxtSvcPssSeq(int nxtSvcPssSeq) { + this.nxtSvcPssSeq = nxtSvcPssSeq; + } + + public String getOutbRtnNm() { + return outbRtnNm; + } + + public void setOutbRtnNm(String outbRtnNm) { + this.outbRtnNm = outbRtnNm; + } + + public String getPsvBwkSysNm() { + return psvBwkSysNm; + } + + public void setPsvBwkSysNm(String psvBwkSysNm) { + this.psvBwkSysNm = psvBwkSysNm; + } + + public String getPsvItfTp() { + return psvItfTp; + } + + public boolean isSyncItfTp() { + return this.psvItfTp.equals( SYNC_SVC ); + } + + public boolean isAckItfTp() { + return this.psvItfTp.equals( ACKONLY_SVC ); + } + + public void setPsvItfTp(String psvItfTp) { + this.psvItfTp = psvItfTp; + } + + public String getPsvSysID() { + return psvSysID; + } + + public void setPsvSysID(String psvSysID) { + this.psvSysID = psvSysID; + } + + public String getPsvSysItfTp() { + return psvSysItfTp; + } + + + public void setPsvSysItfTp(String psvSysItfTp) { + this.psvSysItfTp = psvSysItfTp; + } + + + public String getPsvSysSvcCd() { + return psvSysSvcCd; + } + + public void setPsvSysSvcCd(String psvSysSvcCd) { + this.psvSysSvcCd = psvSysSvcCd; + } + + public int getTmoVl() { + return tmoVl; + } + + public boolean hasTimeOut() { + return ( this.tmoVl > 0 ); + } + + public void setTmoVl(int tmoVl) { + this.tmoVl = tmoVl; + } + + public int getSvcPssSeq(){ + return svcPssSeq; + } + + public void setSvcPssSeq(int seq){ + svcPssSeq = seq; + } + + public String getUseYn() { + return useYn; + } + + public void setUseYn(String useYn) { + this.useYn = useYn; + } + +} diff --git a/src/main/java/com/eactive/eai/common/c2rservice/mapper/C2RServiceMapper.java b/src/main/java/com/eactive/eai/common/c2rservice/mapper/C2RServiceMapper.java new file mode 100644 index 0000000..4becc54 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/c2rservice/mapper/C2RServiceMapper.java @@ -0,0 +1,45 @@ +package com.eactive.eai.common.c2rservice.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.c2rservice.C2RServiceVO; +import com.eactive.eai.data.entity.onl.c2rservice.C2RService; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface C2RServiceMapper extends GenericMapper { + + @Mapping(source = "id.extnlinstiidnfiname", target = "c2rExtnlInstiCd") + @Mapping(source = "id.svcprcssno", target = "svcPssSeq") + @Mapping(source = "bascrspnschngeonot", target = "bsRspCnvEn") + @Mapping(source = "bascrspnschngmsgidname", target = "bsRspCnvMsgID") + @Mapping(source = "bascrspnsmsgcmprctnt", target = "bsRspMsgCprVl") + @Mapping(source = "chngeonot", target = "cnvEn") + @Mapping(source = "chngmsgidname", target = "cnvMsgID") + @Mapping(source = "cmpensvcprcssdsticname", target = "cpnsSvcPssCd") + @Mapping(source = "errrspnschngeonot", target = "errRspCnvEn") + @Mapping(source = "errrspnschngmsgidname", target = "errRspCnvMsgID") + @Mapping(source = "errrspnsmsgcmprctnt", target = "errRspMsgCprVl") + @Mapping(source = "flovryn", target = "flOvrCls") + @Mapping(source = "hdrctrldstcd", target = "hdrCtrlDstcd") + @Mapping(source = "hdrrefclsname", target = "hdrRefClsName") + @Mapping(source = "nextsvcprcssno", target = "nxtSvcPssSeq") + @Mapping(source = "outbndroutname", target = "outbRtnNm") + @Mapping(source = "psvintfacdsticname", target = "psvItfTp") + @Mapping(source = "psvsysadptrbzwkgroupname", target = "psvSysItfTp") + @Mapping(source = "psvsysbzwkdstcd", target = "psvBwkSysNm") + @Mapping(source = "psvsysidname", target = "psvSysID") + @Mapping(source = "psvsyssvcdsticname", target = "psvSysSvcCd") + @Mapping(source = "suppldelyn", target = "supplDelYn") + @Mapping(source = "toutval", target = "tmoVl") + @Mapping(source = "useyn", target = "useYn") + @Override + C2RServiceVO toVo(C2RService entity); + + @InheritInverseConfiguration + @Override + C2RService toEntity(C2RServiceVO vo); +} diff --git a/src/main/java/com/eactive/eai/common/circuitBreaker/CircuitBreakerManager.java b/src/main/java/com/eactive/eai/common/circuitBreaker/CircuitBreakerManager.java new file mode 100644 index 0000000..1b59209 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/circuitBreaker/CircuitBreakerManager.java @@ -0,0 +1,115 @@ +package com.eactive.eai.common.circuitBreaker; + +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import io.github.resilience4j.circuitbreaker.CircuitBreakerConfig; +import io.github.resilience4j.circuitbreaker.CircuitBreakerRegistry; +import io.github.resilience4j.micrometer.tagged.TaggedCircuitBreakerMetrics; +import io.micrometer.prometheus.PrometheusConfig; +import io.micrometer.prometheus.PrometheusMeterRegistry; +import org.apache.commons.lang3.math.NumberUtils; + +import java.time.Duration; + +public class CircuitBreakerManager implements Lifecycle { + + PrometheusMeterRegistry meterRegistry; + CircuitBreakerRegistry circuitBreakerRegistry; +// CircuitBreakerConfig config; + +// Map circuitBreakerMap = new HashMap<>(); + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static CircuitBreakerManager INSTANCE ; + + private boolean started; + + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + public static synchronized CircuitBreakerManager getInstance() { + if (INSTANCE == null) { + INSTANCE = new CircuitBreakerManager(); + } + return INSTANCE; + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + private void init(){ + meterRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT); + + int failureRateThreshold = NumberUtils.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "failureRateThreshold"), 50); + int slidingWindowSize = NumberUtils.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "slidingWindowSize"), 100); + int minimumNumberOfCalls = NumberUtils.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "minimumNumberOfCalls"), 100); + int waitDurationInOpenState = NumberUtils.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "waitDurationInOpenState"), 60); + int permittedNumberOfCallsInHalfOpenState = NumberUtils.toInt(PropManager.getInstance().getProperty("CircuitBreaker", "permittedNumberOfCallsInHalfOpenState"), 10); + + CircuitBreakerConfig config = CircuitBreakerConfig.custom() + .failureRateThreshold(failureRateThreshold) + .slidingWindowSize(slidingWindowSize) + .minimumNumberOfCalls(minimumNumberOfCalls) + .waitDurationInOpenState(Duration.ofSeconds(waitDurationInOpenState)) + .permittedNumberOfCallsInHalfOpenState(permittedNumberOfCallsInHalfOpenState) + .slidingWindowType(CircuitBreakerConfig.SlidingWindowType.COUNT_BASED) + .build(); + + circuitBreakerRegistry = CircuitBreakerRegistry.of(config); + + TaggedCircuitBreakerMetrics.ofCircuitBreakerRegistry(circuitBreakerRegistry).bindTo(meterRegistry); + + logger.info("init CircuitBreaker - "+config); + } + + public void reload(){ + init(); + } + + public PrometheusMeterRegistry getMeterRegistry(){ + return meterRegistry; + } + + @Override + public void start() throws LifecycleException { + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + init(); + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + @Override + public void stop() throws LifecycleException { + if (!started) { + throw new LifecycleException("RECEAICRT203"); + } + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + started = false; + circuitBreakerRegistry = null; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + @Override + public boolean isStarted() { + return started; + } + + public CircuitBreaker getCircuitBreaker(String apiId){ + return circuitBreakerRegistry.circuitBreaker(apiId); + } +} diff --git a/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusController.java b/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusController.java new file mode 100644 index 0000000..4364a38 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusController.java @@ -0,0 +1,17 @@ +package com.eactive.eai.common.circuitBreaker; + +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PrometheusController { + + + public PrometheusController() { + System.out.println("init"); + } + +// @GetMapping("/prometheus") + public String scrape() { + return CircuitBreakerManager.getInstance().getMeterRegistry().scrape(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusServlet.java b/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusServlet.java new file mode 100644 index 0000000..6a2ecaf --- /dev/null +++ b/src/main/java/com/eactive/eai/common/circuitBreaker/PrometheusServlet.java @@ -0,0 +1,14 @@ +package com.eactive.eai.common.circuitBreaker; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class PrometheusServlet extends HttpServlet { + @Override + protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.getOutputStream().print(CircuitBreakerManager.getInstance().getMeterRegistry().scrape()); + } +} diff --git a/src/main/java/com/eactive/eai/common/duplication/DuplicationGuidDataVo.java b/src/main/java/com/eactive/eai/common/duplication/DuplicationGuidDataVo.java new file mode 100644 index 0000000..9707824 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/duplication/DuplicationGuidDataVo.java @@ -0,0 +1,14 @@ +package com.eactive.eai.common.duplication; + +import lombok.Data; + +@Data +public class DuplicationGuidDataVo { + private String recvDatetime; + private String uuid; + private String channelCode; + private String guid; + private String instanceName; + private String eaisvcname; + private String bizData; +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/duplication/DuplicationGuidLogVo.java b/src/main/java/com/eactive/eai/common/duplication/DuplicationGuidLogVo.java new file mode 100644 index 0000000..473303f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/duplication/DuplicationGuidLogVo.java @@ -0,0 +1,12 @@ +package com.eactive.eai.common.duplication; + +import lombok.Data; + +@Data +public class DuplicationGuidLogVo { + private String channelCode; + private String guid; + private String recvDatetime; + private String instanceName; + private String eaisvcname; +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/duplication/mapper/DuplicationGuidDataMapper.java b/src/main/java/com/eactive/eai/common/duplication/mapper/DuplicationGuidDataMapper.java new file mode 100644 index 0000000..3ae3515 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/duplication/mapper/DuplicationGuidDataMapper.java @@ -0,0 +1,27 @@ +package com.eactive.eai.common.duplication.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import com.eactive.eai.common.duplication.DuplicationGuidDataVo; +import com.eactive.eai.data.entity.onl.duplication.DuplicationGuidData; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class, uses = DuplicationGuidLogMapper.class) +public interface DuplicationGuidDataMapper extends GenericMapper { + + @Override + @Mapping(source = "id.recv_datetime", target = "recvDatetime") + @Mapping(source = "id.uuid", target = "uuid") + @Mapping(source = "channel_code", target = "channelCode") + @Mapping(source = "instance_name", target = "instanceName") + @Mapping(source = "biz_data" , target = "bizData") + DuplicationGuidDataVo toVo(DuplicationGuidData entity); + + @Override + @InheritInverseConfiguration + DuplicationGuidData toEntity(DuplicationGuidDataVo vo); + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/duplication/mapper/DuplicationGuidLogMapper.java b/src/main/java/com/eactive/eai/common/duplication/mapper/DuplicationGuidLogMapper.java new file mode 100644 index 0000000..0fdf7c0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/duplication/mapper/DuplicationGuidLogMapper.java @@ -0,0 +1,38 @@ +package com.eactive.eai.common.duplication.mapper; + +import java.time.DayOfWeek; +import java.time.LocalDate; + +import org.mapstruct.AfterMapping; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.MappingTarget; + +import com.eactive.eai.common.duplication.DuplicationGuidLogVo; +import com.eactive.eai.data.entity.onl.duplication.DuplicationGuidLog; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class) +public interface DuplicationGuidLogMapper extends GenericMapper { + + @Override + @Mapping(source = "id.guid", target = "guid") + @Mapping(source = "id.channel_code", target = "channelCode") + @Mapping(source = "recv_datetime", target = "recvDatetime") + @Mapping(source = "instance_name", target = "instanceName") + DuplicationGuidLogVo toVo(DuplicationGuidLog entity); + + @Override + @InheritInverseConfiguration + DuplicationGuidLog toEntity(DuplicationGuidLogVo vo); + + @AfterMapping + default void setCheckIdAndWeekday(@MappingTarget DuplicationGuidLog entity, DuplicationGuidLogVo vo) { + DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); // 현재 요일 + int dayOfWeekNumber = dayOfWeek.getValue() % 7 + 1; // 1 (일요일)부터 7 (토요일)까지 + entity.getId().setWeekday(dayOfWeekNumber); + } + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/ehcache/CustomRMICacheEventListener.java b/src/main/java/com/eactive/eai/common/ehcache/CustomRMICacheEventListener.java new file mode 100644 index 0000000..4c5f31f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/ehcache/CustomRMICacheEventListener.java @@ -0,0 +1,74 @@ +package com.eactive.eai.common.ehcache; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.session.SessionManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.worker.Future; +import com.eactive.eai.common.worker.ResponseMap; + +import net.sf.ehcache.CacheException; +import net.sf.ehcache.Ehcache; +import net.sf.ehcache.Element; +import net.sf.ehcache.event.CacheEventListener; + +public class CustomRMICacheEventListener implements CacheEventListener { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static final CacheEventListener INSTANCE = new CustomRMICacheEventListener(); + + @Override + public void dispose() { + // empty + } + + @Override + public void notifyElementEvicted(Ehcache cache, Element element) { + // empty + } + + @Override + public void notifyElementExpired(Ehcache cache, Element element) { + // empty + } + + @Override + public void notifyElementPut(Ehcache cache, Element element) throws CacheException { + logger.debug("CustomRMICacheEventListener] notifyElementPut : " + element ); + setEvent(cache, element); + } + + @Override + public void notifyElementRemoved(Ehcache cache, Element element) throws CacheException { + logger.debug("CustomRMICacheEventListener] notifyElementRemoved : " + element ); + } + + @Override + public void notifyElementUpdated(Ehcache cache, Element element) throws CacheException { + logger.debug("CustomRMICacheEventListener] notifyElementUpdated : " + element ); + setEvent(cache, element); + } + + @Override + public void notifyRemoveAll(Ehcache cache) { + // empty + } + + @Override + public Object clone() throws CloneNotSupportedException{ + throw new CloneNotSupportedException("Singleton instance"); + } + + private void setEvent(Ehcache cache, Element element){ + if (SessionManager.TOPIC_CAHCE_NAME.equals(cache.getName())){ + String guidKey = (String)element.getKey(); + EAIMessage data = (EAIMessage)element.getValue(); + logger.debug("CustomRMICacheEventListener] setEvent["+guidKey+"]"); + Future future = ResponseMap.getInstance().get(guidKey); + if (future != null){ + logger.debug("CustomRMICacheEventListener] setEvent["+guidKey+"] put to Future"); + future.getSlot().put(data); + cache.remove(guidKey); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/common/ehcache/CustomRMICacheReplicatorFactory.java b/src/main/java/com/eactive/eai/common/ehcache/CustomRMICacheReplicatorFactory.java new file mode 100644 index 0000000..fbbc898 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/ehcache/CustomRMICacheReplicatorFactory.java @@ -0,0 +1,15 @@ +package com.eactive.eai.common.ehcache; + +import net.sf.ehcache.event.CacheEventListener; +import net.sf.ehcache.event.CacheEventListenerFactory; + +import java.util.Properties; + +public class CustomRMICacheReplicatorFactory extends CacheEventListenerFactory { + + @Override + public CacheEventListener createCacheEventListener(Properties properties) { + return CustomRMICacheEventListener.INSTANCE; + } + +} diff --git a/src/main/java/com/eactive/eai/common/exception/ErrorResponseSender.java b/src/main/java/com/eactive/eai/common/exception/ErrorResponseSender.java new file mode 100644 index 0000000..ee5c949 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/exception/ErrorResponseSender.java @@ -0,0 +1,186 @@ +package com.eactive.eai.common.exception; + +import java.util.HashMap; +import java.util.Properties; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.wca.SNAProperties; +import com.eactive.eai.common.logger.EAILogSender; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.message.ServiceMessage; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.message.StandardMessage; + +public class ErrorResponseSender { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static HashMap errCodeMap = new HashMap(); + + static { + errCodeMap.put("RECEAIOSA001", "RECEAICEU10"); + errCodeMap.put("RECEAIOEP001", "RECEAICEU10"); + errCodeMap.put("RECEAIOHP001", "RECEAICEU10"); + errCodeMap.put("RECEAIOHP003", "RECEAICEU10"); + errCodeMap.put("RECEAIOSP001", "RECEAICEU10"); + errCodeMap.put("RECEAIOSP002", "RECEAICEU10"); + errCodeMap.put("RECEAIOSP003", "RECEAICEU10"); + errCodeMap.put("RECEAIOSP004", "RECEAICEU10"); + errCodeMap.put(EAIMessageKeys.EAI_BLOCKED_CODE, "RECEAICEU30"); // 거래통제 에러 + errCodeMap.put(EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE, "RECEAICEU30"); // 유량제어 에러 + } + + /** + * 1. 기능 : 에러크드 재조합 + * 2. 처리 개요 : + * - RECEAICEU10X - 호출에러 + * - RECEAICEU20X - 변환에러 + * - X (1:취급요청, 2:취급응답, 3:개설요청, 4:개설응답 + * 3. 주의사항 + * + * @param eaiMessage : EAIMessage + * @exception Exception SQLException + **/ + private static String convertErrorCode(String errCode, String guCode) { + String newErrCode = ""; + newErrCode = errCodeMap.get(errCode); + + if(newErrCode == null) { + // 통신에러 코드이거나 TUXEDO 통신에러코드일 경우 + if( errCode!= null && errCode.startsWith("RECEAIOTC9") ) { + newErrCode = "RECEAICEU10"; + } + else { + newErrCode = "RECEAICEU20"; + } + } + return newErrCode + guCode; + } + + private static byte[] makeStandardMessageData(EAIMessage eaiMessage, String msgType + , String charset) throws Exception{ +// InterfaceMapper mapper = eaiMessage.getMapper(); + StandardMessage standardMessage = eaiMessage.getStandardMessage(); +// String operationEnv = mapper.getOperationEnv(standardMessage); +/* +// if(MessageType.JSON.equals(msgType) || MessageType.UJSON.equals(msgType)) { + if(MessageType.JSON.equals(msgType)) { + return standardMessage.toJson().getBytes(charset); + } +// else if(MessageType.XML.equals(msgType) || MessageType.UXML.equals(msgType)) { + else if(MessageType.XML.equals(msgType)) { + return standardMessage.toXML().getBytes(charset); + } + else if(MessageType.ASC.equals(msgType)) { + return standardMessage.toByteArray(charset); + } + else { + throw new Exception("Unsupported msgType - " + msgType); + } +*/ + return standardMessage.getDataBytes(msgType, charset); + } + + public static void sendErrorResponseMessage(EAIMessage eaiMessage, String charset) { + + boolean isError = false; + String errorMsg = ""; + try { + + // 1. EAI메시지 파싱 + ServiceMessage smsg = eaiMessage.getCurrentSvcMsg(); + String adapterGroupName = smsg.getPsvSysItfTp(); + + // 2. 송신어댑터 분석 + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adapterGroup = adapterManager.getAdapterGroupVO(adapterGroupName); + + // ASC/EBC/JOB/FML/F32/XML + String msgType = adapterGroup.getMessageType(); + // SNA/SOC/NET/HTT + String adapterType = adapterGroup.getType(); + + // 3. 송신메시지 생성 + byte[] reqBytes = null; + try { + reqBytes = makeStandardMessageData(eaiMessage, msgType, charset); + } catch (Exception e) { + e.printStackTrace(); + } + //ExtMessageConverter.normalAsyncSend(eaiMessage, msgType); + + AdapterVO adptVO = adapterGroup.nextAdapterVO(); + + // 가용 Adapter가 없는 경우 + if(adptVO == null) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(adapterGroupName); + String resMsg = ExceptionUtil.make("RECEAIOSA900", msgArgs); + throw new Exception(resMsg); + } + Properties prop = null; + + if( Keys.TYPE_HTTP.equals(adapterGroup.getType()) ) { + AdapterPropManager manager = AdapterPropManager.getInstance(); + prop = manager.getProperties(adptVO.getPropGroupName()); + prop.put("adapterName", adptVO.getName()); + } + else { + prop = new Properties(); + } + prop.setProperty("ADAPTER_GROUP_NAME", adapterGroupName); + + //------------------------------------------- + // SNA Property 설정 : 2010.02.07 + prop.setProperty(SNAProperties.TRAN_KEY, eaiMessage.getSvcOgNo()); // UUID + prop.setProperty(SNAProperties.ADAPTER_GRP_NAME, adapterGroupName); + prop.setProperty(SNAProperties.LU_NAME, " "); + prop.setProperty(SNAProperties.DATA_TYPE, SNAProperties.DATA_TYPE_NORMAL); + + + String adapterName = adptVO.getName(); + + prop.setProperty(SNAProperties.ADAPTER_NAME, adapterName); + + prop.setProperty(SNAProperties.TRAN_MODE, SNAProperties.TRAN_MODE_NONRESPONSE); + //------------------------------------------- + + // 4. 비동기 송신 + + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = null; + adapter = factory.getElinkAdapter(adapterType); + adapter.callService(adapterGroupName, prop, reqBytes, new Properties()); + } catch(Exception e) { + logger.error("sendErrorResponseMessage error", e); + errorMsg = e.getMessage(); + isError = true; + } + + // 5. 에러로그(900)저장 + // 2009.10.06 + // 송신에러 와 정상일 경우에 대한 로그 처리 + if(isError) { +// eaiMessage.setRspErrCd("RECEAICEU999"); // 에러응답 송신 에러 + String rspErrMsg = eaiMessage.getRspErrMsg() + errorMsg; +// eaiMessage.setRspErrMsg(rspErrMsg); + eaiMessage.setRspErr("RECEAICEU999", rspErrMsg); + } + + eaiMessage.setLogPssSno(900); + try{ + EAILogSender.send(eaiMessage, null); + }catch(Exception e){ + logger.error("ExceptionHandler] EAILogSender send fail"); +// e.printStackTrace(); + } + } + + +} diff --git a/src/main/java/com/eactive/eai/common/exception/ExceptionHandler.java b/src/main/java/com/eactive/eai/common/exception/ExceptionHandler.java new file mode 100644 index 0000000..6f31671 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/exception/ExceptionHandler.java @@ -0,0 +1,962 @@ +package com.eactive.eai.common.exception; + +import java.nio.charset.Charset; + +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONValue; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.logger.EAILogSender; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.EAIMessageManager; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.message.ServiceMessage; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.SMSLogUtil; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.transformer.engine.TransformEngine; +import com.eactive.eai.transformer.engine.Transformer; +import com.eactive.eai.transformer.layout.Item; +import com.eactive.eai.transformer.layout.Layout; +import com.eactive.eai.transformer.layout.LayoutType; +import com.eactive.eai.transformer.message.Message; +import com.eactive.eai.transformer.message.MessageFactory; +import com.eactive.eai.transformer.transform.Transform; +import com.eactive.eai.transformer.transform.TransformManager; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +/** + * 1. 기능 : Exception의 동기,비동기 방식을 지원하는 클래스 2. 처리 개요 : * - SYNC 방식의 Exception + * Handler 처리 * - ASYNC 방식의 Exception Handler 처리 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : : + */ +public class ExceptionHandler { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public ExceptionHandler() { + // empty + } + + public static String handle(String errMsg) { + if (errMsg == null) { + return "[errCd][/errCd][errMsg]EAI 내부처리 오류 입니다.[/errMsg][GstatSysAdptrBzwkGroupName][/GstatSysAdptrBzwkGroupName][data][/data]"; + } else { + return "[errCd][/errCd][errMsg]" + + errMsg + + "[/errMsg][GstatSysAdptrBzwkGroupName][/GstatSysAdptrBzwkGroupName][data][/data]"; + } + } + + public static EAIMessage handle(EAIMessage eaiMessage) { + String inAdapterGroupName = eaiMessage.getSngSysItfTp(); + AdapterManager manager = AdapterManager.getInstance(); + AdapterGroupVO group = manager.getAdapterGroupVO(inAdapterGroupName); + String charset = StringUtils.defaultIfBlank(group.getMessageEncode(), Charset.defaultCharset().name()); + + String transClassifycation = eaiMessage.getMapper().getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R + boolean transClassify = false; + if (transClassifycation.equals(STDMessageKeys.SEND_RECV_CD_SEND)) { + transClassify = true; + } +// else if (transClassifycation.equals(STDMessageKeys.SEND_RECV_CD_RECV)) { +// transClassify = false; +// } + return handle(eaiMessage, transClassify, charset); + } + + public static EAIMessage handle(EAIMessage eaiMessage, boolean transClassify, String charset) { + smsLogging(eaiMessage); + + EAIMessage resultEAIMessage = null; + + // 3. EAI 서비스 정보 추출 + // 요청오류변환ID명 + String reqErrTransID = eaiMessage.getDmndErrChngIDName(); + // 응답오류변환ID명 + String resErrTransID = eaiMessage.getRspnsErrChngIDName(); + // 오류EAI서비스명 + String resEAISvcCode = eaiMessage.getErrEAISvcName(); + // 요청에러필드명 + String reqErrPosition = eaiMessage.getDmndErrFldName(); + // 응답에러필드명 + String resErrPosition = eaiMessage.getRspnsErrFldName(); + + // 서비스동기사용구분코드 //SYNC/ASYNC/AKON + String serviceType = eaiMessage.getSvcTsmtUsgTp(); + + if (serviceType == null) serviceType = ""; + // 전문요청구분코드 + String tmpTrans = eaiMessage.getMapper().getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R + // 응답에러코드 + String errCode = eaiMessage.getRspErrCd(); + // 응답에러메시지 + String errMsg = eaiMessage.getRspErrMsg(); + // 기동시스템어댑터업무그룹명 + String sngSysItfTp = eaiMessage.getSngSysItfTp(); + + // 어댑터메시지구분코드 //ASC/EBC/JOB/FML/F32/XML + String messageTypeSource = ""; + // 수동시스템어댑터업무그룹명 + String psvSysItfTp = eaiMessage.getCurrentSvcMsg().getPsvSysItfTp(); + // 수동 어댑터메시지구분코드 //ASC/EBC/JOB/FML/F32/XML + String messageTypeTarget = ""; + // 표준메시지사용구분 + String stdMsgUsgCls = eaiMessage.getStdMsgUsgCls(); + // 수동인터페이스구분명 //SYNC/ASYNC/AKON + String psvItfTp = eaiMessage.getCurrentSvcMsg().getPsvItfTp(); + + String inboundCharset = Charset.defaultCharset().name(); + String inAdapterGroupName = eaiMessage.getSngSysItfTp(); + AdapterGroupVO inAdapterGvo = AdapterManager.getInstance().getAdapterGroupVO(inAdapterGroupName); + + if(inAdapterGvo != null) { + inboundCharset = StringUtils.defaultIfBlank(inAdapterGvo.getMessageEncode(), Charset.defaultCharset().name()); + } + if (logger.isInfo()) { + logger.info("ExceptionHandler] inboundCharset : {}", inboundCharset); + } + + if (logger.isInfo()) { + logger.info("ExceptionHandler] 디버그 로그 시작"); + logger.info("EAI 서비스 코드 = " + eaiMessage.getEAISvcCd()); + logger.info("서비스동기사용구분코드 = " + eaiMessage.getSvcTsmtUsgTp()); + logger.info("수동인터페이스구분명 = " + eaiMessage.getCurrentSvcMsg().getPsvItfTp()); + logger.info("전문요청구분코드 = " + eaiMessage.getMapper().getSendRecvDivision(eaiMessage.getStandardMessage())); // S|R); + logger.info("오류EAI서비스명 = " + eaiMessage.getErrEAISvcName()); + logger.info("요청오류변환ID명 = " + eaiMessage.getDmndErrChngIDName()); + logger.info("응답오류변환ID명 = " + eaiMessage.getRspnsErrChngIDName()); + logger.info("요청에러필드명 = " + eaiMessage.getDmndErrFldName()); + logger.info("응답에러필드명 = " + eaiMessage.getRspnsErrFldName()); + + logger.info("응답에러코드 = " + eaiMessage.getRspErrCd()); + logger.info("응답에러메시지 = " + eaiMessage.getRspErrMsg()); + logger.info("기동시스템어댑터업무그룹명 = " + eaiMessage.getSngSysItfTp()); + logger.info("수동시스템어댑터업무그룹명 = " + eaiMessage.getCurrentSvcMsg().getPsvSysItfTp()); + logger.info("표준메시지사용구분 = " + eaiMessage.getStdMsgUsgCls()); + } + + String tgtStdMsgUsgCls = ""; + + // 4. 업무 데이터 추출 + String orgBizDataStr = null; + try { + orgBizDataStr = eaiMessage.getStandardMessage().getBizData(); + } catch (Exception e) { + logger.error("getBizData failed.", e); + } + + String data = null; + try { + AdapterManager adapterManager = null; + AdapterGroupVO adapterGroupVoSource = null; + AdapterGroupVO adapterGroupVoTarget = null; + try { + adapterManager = AdapterManager.getInstance(); + adapterGroupVoSource = adapterManager.getAdapterGroupVO(sngSysItfTp); + // 어댑터메시지구분코드 //ASC/EBC/JOB/FML/F32/XML + messageTypeSource = adapterGroupVoSource.getMessageType(); + } catch (Exception ee) { + if (logger.isError()) + logger.error("ExceptionHandler] 기동어댑터그룹명 = " + adapterGroupVoSource); + throw new Exception("기동어댑터가 정의되지 않았습니다. - " + adapterGroupVoSource); + } + try { + adapterGroupVoTarget = adapterManager.getAdapterGroupVO(psvSysItfTp); + // 수동 어댑터메시지구분코드 //ASC/EBC/JOB/FML/F32/XML + messageTypeTarget = adapterGroupVoTarget.getMessageType(); + tgtStdMsgUsgCls = adapterGroupVoTarget.getAdptrMsgPtrnCd(); + } catch (Exception ee) { + if (logger.isError()) + logger.error("ExceptionHandler] 수동어댑터그룹명 = " + adapterGroupVoTarget); + throw new Exception("수동어댑터가 정의되지 않았습니다. - " + adapterGroupVoTarget); + } + + if (logger.isInfo()) { + logger.info("ExceptionHandler] 요청거래 = " + transClassify); + logger.info("ExceptionHandler] 서비스동기사용구분코드 = " + serviceType); + } + + // ----------------------------------------------------- + // 통변환로직 및 Outbound 호출 로직 추가 필요 + // ----------------------------------------------------- + if (resEAISvcCode == null || resEAISvcCode.trim().length() == 0) { + throw new Exception("ExceptionHandler] 오류EAI서비스명이 등록되지 않았습니다."); + } + + if (!emptyRule(transClassify, serviceType, eaiMessage)) { + // SS, SA 거래는 기존의 로직으로 처리 + if (serviceType.equals(EAIMessageKeys.SYNC_SVC)) { + throw new Exception("Sync Service"); + } + // AS 거래는 요청 업무데이터를 그대로 송신 + // AA 거래는 기동이 표준인 경우 요청업무데이터를 그대로 + // -> 메시지 변경없이 그대로 전달한다.2009.11.05 + else { + data = orgBizDataStr; + } + } + else { + // 5. 오류변환 처리 + // 요청거래 변환 + if (transClassify) { + if (logger.isInfo()) { + logger.info("ExceptionHandler] 요청오류변환ID명 = " + reqErrTransID); + logger.info("ExceptionHandler] 요청에러필드명 = " + reqErrPosition); + logger.info("ExceptionHandler] EAI에러코드 = " + errCode); + logger.info("ExceptionHandler] makeTrans start request transaction"); + } + data = makeTrans(reqErrTransID, orgBizDataStr, reqErrPosition, errCode, inboundCharset); + if (logger.isInfo()) { + logger.info("ExceptionHandler] 요청오류변환완료"); + } + } + // 응답거래 변환 + else { + if (logger.isInfo()) { + logger.info("ExceptionHandler] 응답오류변환ID명 = " + resErrTransID); + logger.info("ExceptionHandler] 응답에러필드명 = " + resErrPosition); + logger.info("ExceptionHandler] EAI에러코드 = " + errCode); + logger.info("ExceptionHandler] makeTrans start response transaction"); + } + data = makeTrans(resErrTransID, orgBizDataStr, resErrPosition, errCode, inboundCharset); + if (logger.isInfo()) { + logger.info("ExceptionHandler] 응답오류변환 완료"); + } + } + } + + boolean isXML = checkXML(serviceType, psvItfTp, messageTypeSource, messageTypeTarget, transClassify); + if (logger.isInfo()) { + logger.info("ExceptionHandler] 표준메시지 사용여부 =" + stdMsgUsgCls); + logger.info("ExceptionHandler] XML 전문 = " + isXML); + } + + // ---------------------------------------------------------------------- + // XML 인터페이스 방식인 경우 : 오류메시지에 대한 XML Tag를 생성한다 + // ---------------------------------------------------------------------- + if (isXML) { +// String xmlString = null; +// if (data instanceof byte[]) { +// xmlString = new String((byte[]) data); // TODO check charset +// +// } else if (data instanceof String) { +// xmlString = (String)data; +// } + String xmlString = data; + if (logger.isInfo()) + logger.info("ExceptionHandler] XML 전문 = " + xmlString); + xmlString = MessageUtil.replaceMsgXmlString(xmlString); + xmlString = MessageUtil.makeErrMsgXmlString(xmlString); + data = xmlString; + } + + if (logger.isInfo()) { + logger.info("ExceptionHandler] serviceType=" + serviceType); + } + // 업무데이타를 EAIMessage에 저장하고 + // 에러응답메시지를 전송한다. + // 기동이 동기(Sync)인 경우 + // 응답에러로그를 생성하여 전달한다. + if (serviceType.equals(EAIMessageKeys.SYNC_SVC)) { + if (psvItfTp.equals(EAIMessageKeys.ASYNC_SVC) && tmpTrans.equals(EAIKeys.TR_RES)) { + if (logger.isInfo()) { + logger.info("ExceptionHandler] SA Type 응답거래처리"); + } + errorAsyncSend(eaiMessage); + if (logger.isInfo()) + logger.info("ExceptionHandler] end"); + return eaiMessage; + } else { + if (logger.isInfo()) + logger.info("ExceptionHandler] SS, SA 요청 Type 거래처리"); + // eaiMessage 에 업무데이타 셋팅 + resultEAIMessage = normalSyncSend(eaiMessage, data, charset); + if (logger.isInfo()) + logger.info("ExceptionHandler] end"); + return resultEAIMessage; + } + } + // 기동이 비동기(Async)인 경우 + // 에러응답을 송신한다. + else if (serviceType.equals(EAIMessageKeys.ASYNC_SVC) || serviceType.equals(EAIMessageKeys.ACKONLY_SVC)) { + if (logger.isInfo()) { + logger.info("ExceptionHandler] AA, AS Type 거래처리"); + } + normalAsyncSend(resEAISvcCode, eaiMessage, data, transClassify, charset); + if (logger.isInfo()) + logger.info("ExceptionHandler] end"); + return eaiMessage; + } + + } catch (Exception e2) { + if (logger.isWarn()) { + logger.warn("ExceptionHandler] 내부 Exception 무응답 처리 거래타입[" + serviceType + "][" + psvItfTp + "] - " + + e2.getMessage()); + } + // 동기일경우 메시지 조립해서 전달 + // 에러 코드 + 에러 메시지 + 기동서버 아답터 그룹명 + 요청전문 + // 비동기 일경우 거래로그(900)를 생성하고 SMS보냄 + if (EAIMessageKeys.SYNC_SVC.equals(serviceType)) { + // SA 응답 거래는 900로그 생성 : 정상일 경우 100로그만 생성되는 거래 + if (psvItfTp.equals(EAIMessageKeys.ASYNC_SVC) && tmpTrans.equals(EAIKeys.TR_RES)) { + if (logger.isInfo()) + logger.info("ExceptionHandler] SA 응답 900 Logging"); + errorAsyncSend(eaiMessage); + return eaiMessage; + } else { + if (logger.isInfo()) + logger.info("ExceptionHandler] SS, SA 요청 Type 거래처리"); + // SS, SA요청 거래일 경우 에러메시지를 생성하여 RETURN + resultEAIMessage = errorSyncSend(eaiMessage, transClassify, errCode, errMsg, sngSysItfTp, orgBizDataStr, + messageTypeSource, messageTypeTarget, stdMsgUsgCls, serviceType, psvItfTp + , charset); + return resultEAIMessage; + } + + } else if (EAIMessageKeys.ASYNC_SVC.equals(serviceType) || EAIMessageKeys.ACKONLY_SVC.equals(serviceType)) { + // AA,AS 거래는 900 에러로그 생성 + if (logger.isInfo()) + logger.info("ExceptionHandler] AA, AS 900 Logging"); + errorAsyncSend(eaiMessage); + return eaiMessage; + } + } + return eaiMessage; + } + + /** + * 1. 기능 : EAI메시지를 생성하는 메소드 2. 처리 개요 : - EAI메시지를 생성한다 3. 주의사항 + * + * @param resEAISvcCode : 응답 EAI서비스명 + * @param eaiMessage : 요청 EAI메시지 + * @return 응답EAI메시지 + * @exception Exception SQLException + **/ + private static EAIMessage makeEAIMessage(String resEAISvcCode, EAIMessage eaiMessage) throws Exception { + + EAIMessageManager eaiMessageManager = EAIMessageManager.getInstance(); + EAIMessage resultEAIMessage = eaiMessageManager.getEAIMessage(resEAISvcCode); + + // -------------------------------------- + // 2009.10.05 + // EAI 서비스메시지의 Outbound 정보를 오류EAI서비스명의 정보로 변경한다. + // -------------------------------------- +// 기동서비스구분 + eaiMessage.setSngSvcCls("EXCEPTION"); + + // AS 거래일 경우 등록된 거래로 송신한다. + if (eaiMessage.getSvcMsgs().size() > 1) { + String keyMgtMsgVl = eaiMessage.getCurrentSvcMsg().getKeyMgtMsgVl(); + eaiMessage.setSvcPssSeq(eaiMessage.getSvcPssSeq() + 1); + eaiMessage.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); + eaiMessage.getCurrentSvcMsg().setCnvEn("0"); + eaiMessage.getCurrentSvcMsg().setSupplDelYn("0"); + return eaiMessage; + } + +// 수동업무구분 : psvBwkSysNm +// 수동시스템ID : psvSysID +// 수동시스템서비스코드 : psvSysSvcCd +// 수동시스템인터페이스유형 : psvSysItfTp +// Outbound라우팅명 : outbRtnNm +// 변환유무 : cnvEn - 없음 (0) +// 추가삭제여부 : supplDelYn - 없음 (0) + + ServiceMessage svcMsg = eaiMessage.getCurrentSvcMsg(); + ServiceMessage errSvcMsg = resultEAIMessage.getCurrentSvcMsg(); + + if (svcMsg != null && errSvcMsg != null) { + svcMsg.setPsvBwkSysNm(errSvcMsg.getPsvBwkSysNm()); + svcMsg.setPsvSysID(errSvcMsg.getPsvSysID()); + svcMsg.setPsvSysSvcCd(errSvcMsg.getPsvSysSvcCd()); + svcMsg.setPsvSysItfTp(errSvcMsg.getPsvSysItfTp()); + svcMsg.setOutbRtnNm(errSvcMsg.getOutbRtnNm()); + svcMsg.setCnvEn("0"); + svcMsg.setSupplDelYn("0"); + } + // add default values + + return eaiMessage; + } + + /** + * 1. 기능 : 에러 응답으로 변환하는 메소드 2. 처리 개요 : - 에러 응답으로 변환한다 3. 주의사항 + * + * @param errTransID : 변환ID + * @param tmpMsg : 업무데이타 + * @param errPosition : 레이아웃위치 + * @param errCode : 에러코드값 + * @return 변환된 업무데이타 + * @exception Exception SQLException + **/ + private static String makeTrans(String errTransID, Object tmpMsg, String errPosition, String errCode, + String charset) + throws Exception { +// TransformResult result =null; + try { + TransformEngine engine = TransformEngine.getInstance(); + Transformer transformer = engine.getTransformer(); + + TransformManager manager = TransformManager.getManager(); + Transform info = manager.getTransform(errTransID); + if (info == null) { + throw new Exception("Transform is NULL - " + errTransID); + } + Layout ls = info.getSourceLayout(0); + com.eactive.eai.transformer.message.Message source = MessageFactory.getFactory().getMessage(ls.getName()); + // xml일 경우 root를 만들어야 한다. + LayoutType type = ls.getLayoutType(); + if (type == null) { + throw new Exception("Transform getLayoutType is NULL - " + errTransID); + } + if (MessageType.XML.equals(type.getName())) { + if (logger.isInfo()) + logger.info("makeTrans] is xml , add root tag "); + String xmlString = ""; + if (tmpMsg instanceof byte[]) { + xmlString = new String((byte[]) tmpMsg); + } else { + xmlString = (String) tmpMsg; + } + Item item = ls.getRootItem(); + if (item != null) { + String rootName = "<" + item.getName() + ">"; + String rootNameTail = ""; + xmlString = rootName + xmlString + rootNameTail; + source.setData(xmlString); + } else { + source.setData(xmlString); + } + } else { + source.setData(tmpMsg); + } + + if (logger.isInfo()) + logger.info("makeTrans] source => " + source); + // 변환 + Message target = transformer.transform(errTransID, new Message[] { source }); + + if (logger.isInfo()) + logger.info("makeTrans] target => " + target); + + // errorcode setting + target.setString(errPosition, errCode); + + if (logger.isInfo()) + logger.info("makeTrans] errorCode setting => " + target); + + // xml일 경우 root를 제거해야 한다. + // if(ls.getLayoutType().getName().equals(MessageType.XML)) { + Layout targetLayout = info.getTargetLayout(); + if (targetLayout == null) { + throw new Exception("TargetLayout is NULL"); + } + + LayoutType targetType = targetLayout.getLayoutType(); + if (targetType == null) { + throw new Exception("TargetLayout Type is NULL"); + } + + String targetData = null; + if (MessageType.XML.equals(targetType.getName())) { + if (logger.isInfo()) + logger.info("makeTrans] is xml , delete root tag "); + Layout tls = info.getTargetLayout(); + String rootNameTarget = "<" + tls.getRootItem().getName() + ">"; + String rootNameTargetTail = ""; + + targetData = target.getData().toString().replaceAll(rootNameTarget, ""); + targetData = targetData.replaceAll(rootNameTargetTail, ""); + } else { + Object targetObject = target.getData(); + if(targetObject instanceof String) { + targetData = (String)targetObject; + } + else if(targetObject instanceof byte[]) { + targetData = new String((byte[])targetObject, charset); + } + } + return targetData; + } catch (Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICEU104")); + } + } + + /** + * 1. 기능 : 에러 메시지를 조합하는 메소드 2. 처리 개요 : - 에러 메시지를 조합한다. 3. 주의사항 + * + * @param errCode : 에러코드 + * @param errMsg : 에러메시지 + * @param sngSysItfTp : 기동시스템어댑터업무그룹명 + * @param Msg : 업무데이타 + * @param SourceType : 소스 어댑터메시지구분코드 + * @param TargetType : 타겟 어댑터메시지구분코드 + * @return 변환된 업무데이타 + * @exception Exception SQLException + **/ +// private static Object errorTrans(String errCode , String errMsg , String sngSysItfTp, Object msgObject,String SourceType,String TargetType ,String TransID )throws Exception{ + private static String errorTrans(String errCode, String errMsg, String sngSysItfTp, String msgObject, + String SourceType, String TargetType, String TransID) throws Exception { + if (logger.isInfo()) { + logger.info("ExceptionHandler] errorTrans SourceType=>" + SourceType); + logger.info("ExceptionHandler] errorTrans TargetType=>" + TargetType); + } +// byte[] msg = null; +// if(msgObject instanceof byte[]) { +// msg = (byte[])msgObject; +// } +// else if(msgObject instanceof byte[]) { +// msg = ((String)msgObject).getBytes(); +// } + String msg = msgObject; + String error = null; + + String tmpErrCode = "[errCd]" + errCode + "[/errCd]"; + String tmpErrMsg = "[errMsg]" + errMsg + "[/errMsg]"; + String tmpSngSysItfTp = "[GstatSysAdptrBzwkGroupName]" + sngSysItfTp + "[/GstatSysAdptrBzwkGroupName]"; + String tmpdatafront = "[data]"; + String tmpdataback = "[/data]"; + + if (TargetType.equals(MessageType.ASC) || TargetType.equals(MessageType.EBC)) { + StringBuilder sb = new StringBuilder(); + sb.append(tmpErrCode); + sb.append(tmpErrMsg); + sb.append(tmpSngSysItfTp); + sb.append(tmpdatafront); + if (msg != null) { + sb.append(msg); + } + sb.append(tmpdataback); + error = sb.toString(); + } else if (TargetType.equals(MessageType.JSON)) { + error = MessageUtil.makeJsonErrorMessage(errCode, errMsg); + } else if (TargetType.equals(MessageType.XML)) { + error = MessageUtil.makeXmlErrorMessage(errCode, errMsg, "UTF-8"); + } else if (TargetType.equals(MessageType.JOB)) { + throw new Exception("not support JOB MessageType "); + } else if (TargetType.equals(MessageType.FML)) { + throw new Exception("not support FML MessageType "); + } else if (TargetType.equals(MessageType.F32)) { +// //-------------------------------------------------------------------------- +// // 에러일 경우 TPURCODE, STATLIN 에 설정한다. +// //-------------------------------------------------------------------------- +// if (logger.isInfo()){ +// logger.info("ExceptionHandler] FML32 Error Setting START"); +// } +// +// TypedFML32 errorFml = new TypedFML32(new CrmFmlTable()); +// +// try { +// errorFml.Fchg(CrmFmlTable.TPURCODE , 0, "-1"); +// errorFml.Fchg(167772165, 0, "[" + errCode + "] " + errMsg); +// } catch(Exception e) { +// if (logger.isError()){ +// logger.error("ExceptionHandler] FML32 Setting Error - " + e.toString()); +// } +// } +// +// error = errorFml; +// +// if (logger.isInfo()){ +// logger.info("ExceptionHandler] FML32 Error Setting END"); +// } +// //-------------------------------------------------------------------------- +// +// //throw new Exception ("not support F32 MessageType "); +// //juns 다시 확인 +// //error = errCode+errMsg+ sngSysItfTp + (String)tmpMsg; + } + return error; + + } + + /** + * 1. 기능 : 에러 메시지를 조합하는 메소드 2. 처리 개요 : - 에러 메시지를 조합한다. 3. 주의사항 + * + * @param errCode : 에러코드 + * @param errMsg : 에러메시지 + * @param sngSysItfTp : 기동시스템어댑터업무그룹명 + * @param Msg : 업무데이타 + * @param SourceType : 소스 어댑터메시지구분코드 + * @param TargetType : 타겟 어댑터메시지구분코드 + * @return 변환된 업무데이타 + * @exception Exception SQLException + **/ + private static boolean emptyRule(boolean transClassify, String serviceType, EAIMessage eaiMessage) { + + String prefix = "ExceptionHandler] RuleCheck "; + if (logger.isInfo()) + logger.info(prefix + " EAI서비스코드 = " + eaiMessage.getEAISvcCd()); + + boolean result = true; + // 비동기의 경우 + if (!serviceType.equals(EAIMessageKeys.SYNC_SVC)) { + if (logger.isInfo()) + logger.info(prefix + "오류EAI서비스코드명(errEAISvcName) =" + eaiMessage.getErrEAISvcName()); + // 오류EAI서비스명 + if (eaiMessage.getErrEAISvcName() == null || eaiMessage.getErrEAISvcName().equals("")) { + if (logger.isInfo()) + logger.info(prefix + "RuleCheck emptyRule 오류EAI서비스코드명 미등록"); + return false; + } + } + + // 요청거래 + if (transClassify) { + if (logger.isInfo()) { + logger.info(prefix + "요청오류변환ID명 (reqErrTransID)=" + eaiMessage.getDmndErrChngIDName()); + logger.info(prefix + "요청에러필드명 (reqErrPosition)=" + eaiMessage.getDmndErrFldName()); + } + // 요청오류변환ID명 + if (eaiMessage.getDmndErrChngIDName() == null || eaiMessage.getDmndErrChngIDName().equals("")) { + if (logger.isInfo()) + logger.info(prefix + "emptyRule 요청오류변환ID명 "); + return false; + } + // 요청에러필드명 + if (eaiMessage.getDmndErrFldName() == null || eaiMessage.getDmndErrFldName().equals("")) { + if (logger.isInfo()) + logger.info(prefix + "emptyRule 요청에러필드명 "); + return false; + } + + } else { + if (logger.isInfo()) { + logger.info(prefix + "응답오류변환ID명 (resErrTransID)=" + eaiMessage.getRspnsErrChngIDName()); + logger.info(prefix + "응답에러필드명 (resErrPosition)=" + eaiMessage.getRspnsErrFldName()); + } + // 응답 거래 + // 응답오류변환ID명 + if (eaiMessage.getRspnsErrChngIDName() == null || eaiMessage.getRspnsErrChngIDName().equals("")) { + if (logger.isInfo()) + logger.info(prefix + "emptyRule 응답오류변환ID명"); + return false; + } + // 응답에러필드명 + if (eaiMessage.getRspnsErrFldName() == null || eaiMessage.getRspnsErrFldName().equals("")) { + if (logger.isInfo()) + logger.info(prefix + " emptyRule 응답에러필드명"); + return false; + } + } + return result; + } + + /** + * 1. 기능 : 동기개별 메시지를 셋팅하는 메소드 2. 처리 개요 : - 동기개별 메시지를 셋팅한다. 3. 주의사항 + * + * @param eaiMessage : EAIMessage + * @param data : 개별메시지 + * @return 개별메시지가 셋팅된 EAIMessage + * @exception Exception SQLException + **/ + private static EAIMessage normalSyncSend(EAIMessage eaiMessage, String data, String charset) { + EAIMessage resultEAIMessage = null; + resultEAIMessage = eaiMessage; + try { + resultEAIMessage.getStandardMessage().setBizData(data, charset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + // Outbound에서 변환을 하지 못하게 하는 셋팅 + resultEAIMessage.getCurrentSvcMsg().setCnvEn("0"); + return resultEAIMessage; + } + + /** + * 1. 기능 : 비동기 메시지를 전송하는 메소드 2. 처리 개요 : - 비동기 메시지를 전송한다. 3. 주의사항 + * + * @param resEAISvcCode : 오류EAI서비스명 + * @param eaiMessage : EAIMessage + * @param data : 개별메시지 + * @exception Exception SQLException + **/ + private static void normalAsyncSend(String resEAISvcCode, EAIMessage eaiMessage, String data + , boolean transClassify, String charset) + throws Exception { + EAIMessage resultEAIMessage = null; + if (logger.isInfo()) { + logger.info("ExceptionHandler] 비동기 에러응답 송신 : 오류EAI서비스명 = " + resEAISvcCode); + } + resultEAIMessage = makeEAIMessage(resEAISvcCode, eaiMessage); + try { + resultEAIMessage.getStandardMessage().setBizData(data, charset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + + // -------------------------------------- + // Outbound 호출시 사용됨 + // 2009.10.06 + // Outbound를 호출하지 않고 별도의 ErrorResponseSender를 + // 호출하여 처리하도록 한다. + // -------------------------------------- +// Properties callProp = new Properties(); +// callProp.setProperty(RouteKeys.ROUTING_TYPE, RouteKeys.ROUT_JPD); +// try{ +// //Outbound에서 변환을 하지 못하게 하는 셋팅 +// resultEAIMessage.getCurrentSvcMsg().setCnvEn("0"); +// +// // Default error code를 설정하여 에러가 발생한 것을 확인 +// // 에러코드를 그대로 유지 - 주석처리함 : 2009.10.05 +// // resultEAIMessage.setRspErrCd(EAIMessageKeys.EAI_DEFAULT_CODE); +// +// EAIMessage retEaiMsg = IFRouter.process(resultEAIMessage, callProp); +// String error = retEaiMsg.getRspErrCd(); +// if( !MessageUtil.checkRspErrCd(error)){ +// throw new Exception (""); +// } +// }catch(Exception e1){ +// //e1.printStackTrace(); +// throw new Exception(ExceptionUtil.getErrorCode(e1,"RECEAICEU101")); +// } + ErrorResponseSender.sendErrorResponseMessage(resultEAIMessage, charset); + } + + /** + * 1. 기능 : ExceptionHandler에서 에러가 발생한 비동기 거래를 전송하는 메소드 2. 처리 개요 : - + * ExceptionHandler에서 에러가 발생한 비동기 거래를 전송한다. 3. 주의사항 + * + * @param eaiMessage : EAIMessage + * @exception Exception SQLException + **/ + private static void errorAsyncSend(EAIMessage eaiMessage) { + eaiMessage.setLogPssSno(900); + try { + EAILogSender.send(eaiMessage, null); + } catch (Exception e) { + logger.error("ExceptionHandler] EAILogSender send fail", e); + } + } + + /** + * 1. 기능 : ExceptionHandler에서 에러가 발생한 비동기 거래를 전송하는 메소드 2. 처리 개요 : - + * ExceptionHandler에서 에러가 발생한 비동기 거래를 전송한다. 3. 주의사항 + * + * @param eaiMessage : EAIMessage + * @exception Exception SQLException + **/ + private static EAIMessage errorSyncSend(EAIMessage eaiMessage, boolean transClassify, String errCode, String errMsg, + String sngSysItfTp, String tmpMsg, String messageTypeSource, String messageTypeTarget, String stdMsgUsgCls, + String serviceType, String psvItfTp, String charset) { + String error = null; + EAIMessage resultEAIMessage = null; + try { + if (transClassify) { + if (logger.isInfo()) { + StringBuilder sb = new StringBuilder(); + sb.append("ExceptionHandler] errorSyncSend errCode=" + errCode); + sb.append(", errMsg=" + errMsg); + sb.append(", sngSysItfTp=" + sngSysItfTp); + sb.append(", messageTypeSource=" + messageTypeSource); + sb.append("\n tmpMsg=" + tmpMsg); + logger.info(sb.toString()); + } + // 요청거래 + // messageType 이 source ,messageTypeTarget이 target + if (logger.isInfo()) + logger.info("ExceptionHandler] 요청 에러변환(errorTrans)"); + error = errorTrans(errCode, errMsg, sngSysItfTp, tmpMsg, messageTypeSource, messageTypeSource, + eaiMessage.getCurrentSvcMsg().getCnvMsgID()); + } else { + if (logger.isInfo()) { + StringBuilder sb = new StringBuilder(); + sb.append("ExceptionHandler] errorSyncSend errCode=" + errCode); + sb.append(", errMsg=" + errMsg); + sb.append(", sngSysItfTp=" + sngSysItfTp); + sb.append(", messageTypeSource=" + messageTypeSource); + sb.append(", stdMsgUsgCls=" + stdMsgUsgCls); + sb.append(", messageTypeTarget=" + messageTypeTarget); +// if (tmpMsg instanceof byte[]) { +// sb.append("\n tmpMsg=>" + new String((byte[]) tmpMsg)); +// } else if (tmpMsg instanceof String) { + sb.append("\n tmpMsg=>" + tmpMsg); +// } + logger.info(sb.toString()); + } + // 응답거래 + // messageTypeTarget이 이 source ,messageType이 target + if (logger.isInfo()) + logger.info("ExceptionHandler] 응답 에러변환(errorTrans)"); + error = errorTrans(errCode, errMsg, sngSysItfTp, tmpMsg, messageTypeTarget, messageTypeSource, + eaiMessage.getCurrentSvcMsg().getBsRspCnvMsgID()); + } + } catch (Exception e) { + if (logger.isError()) + logger.error("ExceptionHandler] handler request return", e); + error = tmpMsg; + } + + if (logger.isInfo()) { + logger.info("ExceptionHandler] stdMsgUsgCls=" + stdMsgUsgCls); + } + + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(stdMsgUsgCls)) { + if (MessageType.JSON.equals(messageTypeSource)) { + if (logger.isInfo()) + logger.info("ExceptionHandler] handler byte[] IF_STANDARD JSON"); + try { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + boolean isBodyErrorSet = standardManager.getMessageCoordinator().coordinateSetStandardMessageError(eaiMessage.getStandardMessage(), eaiMessage.getMapper(), errCode, errMsg); + if(!isBodyErrorSet) { + error = null; + } + //eaiMessage.getMapper().setErrorCode(eaiMessage.getStandardMessage(), errCode); + //eaiMessage.getMapper().setErrorMsg(eaiMessage.getStandardMessage(), errMsg); + + } catch (Exception e) { + logger.error("ExceptionHandler] handler byte[] IF_STANDARD JSON", e); + } + } else { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + standardManager.getMessageCoordinator().coordinateSetStandardMessageError(eaiMessage.getStandardMessage(), eaiMessage.getMapper(), errCode, errMsg); + //eaiMessage.getMapper().setErrorCode(eaiMessage.getStandardMessage(), errCode); + //eaiMessage.getMapper().setErrorMsg(eaiMessage.getStandardMessage(), errMsg); + + if (logger.isInfo()) + logger.info("ExceptionHandler] handler String IF_STANDARD : " + error); + error = null; + } + } else { + if (checkXML(serviceType, psvItfTp, messageTypeSource, messageTypeTarget, transClassify)) { + error = MessageUtil.replaceMsgXmlString(error); + error = MessageUtil.makeErrMsgXmlString(error); + if (logger.isInfo()) + logger.info("ExceptionHandler] handler String xml tag add " + error); + } + } + + resultEAIMessage = eaiMessage; + + try { + if(StringUtils.isNotBlank(error)) + resultEAIMessage.getStandardMessage().setBizData(error, charset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + + resultEAIMessage.getMapper().setResponseType(resultEAIMessage.getStandardMessage(), + STDMessageKeys.RESPONSE_TYPE_CODE_E); + // TODO 표준관련 확인필요 + return resultEAIMessage; + } + + /** + * 1. 기능 : ExceptionHandler에서 에러가 발생한 비동기 거래를 전송하는 메소드 2. 처리 개요 : - + * ExceptionHandler에서 에러가 발생한 비동기 거래를 전송한다. 3. 주의사항 + * + * @param eaiMessage : EAIMessage + * @exception Exception SQLException + **/ + private static boolean checkXML(String serviceType, String psvItfTp, String messageTypeSource, + String messageTypeTarget, boolean transClassify) { + if (logger.isInfo()) { + StringBuilder sb = new StringBuilder(); + sb.append("ExceptionHandler] checkStandard : serviceType=" + serviceType); + sb.append(", psvItfTp=" + psvItfTp); + sb.append(", messageTypeSource=" + messageTypeSource); + sb.append(", messageTypeTarget=" + messageTypeTarget); + sb.append(", transClassify=" + transClassify); + logger.info(sb.toString()); + } + + // 동기-동기 일경우 adptrMsgPtrnCdSource 기준 으로 표준일 경우 tag를 붙인다. + // 동기-비동기 일경우 adptrMsgPtrnCdSource 기준 으로 표준일 경우 tag를 붙인다. + // 비동기-비동기 일경우 요청거래일 경우 adptrMsgPtrnCdSource 기준으로 표준일 경우 tag를 붙인다. + // 비동기-비동기 일경우 응답거래일 경우 adptrMsgPtrnCdTarget 기준으로 표준일 경우 tag를 붙인다. + // 비동기-동기 일경우 adptrMsgPtrnCdSource 표준일 경우 tag를 붙인다. + + if (serviceType.equals(EAIMessageKeys.SYNC_SVC)) { +// if (messageTypeSource.equals(MessageType.XML) || messageTypeSource.equals(MessageType.UXML)) { + if (messageTypeSource.equals(MessageType.XML)) { + return true; + } + } else if (serviceType.equals(EAIMessageKeys.ASYNC_SVC) || serviceType.equals(EAIMessageKeys.ACKONLY_SVC)) { + if (psvItfTp.equals(EAIMessageKeys.SYNC_SVC)) { +// if (messageTypeSource.equals(MessageType.XML) || messageTypeSource.equals(MessageType.UXML)) { + if (messageTypeSource.equals(MessageType.XML)) { + return true; + } + } else { + if (transClassify) { +// if (messageTypeSource.equals(MessageType.XML) || messageTypeSource.equals(MessageType.UXML)) { + if (messageTypeSource.equals(MessageType.XML)) { + return true; + } + } else { +// if (messageTypeTarget.equals(MessageType.XML) || messageTypeSource.equals(MessageType.UXML)) { + if (messageTypeTarget.equals(MessageType.XML)) { + return true; + } + } + } + } + return false; + } + + private static boolean checkJSON(String serviceType, String psvItfTp, String messageTypeSource, + String messageTypeTarget, boolean transClassify) { + if (logger.isInfo()) { + StringBuilder sb = new StringBuilder(); + sb.append("ExceptionHandler] checkStandard : serviceType=" + serviceType); + sb.append(", psvItfTp=" + psvItfTp); + sb.append(", messageTypeSource=" + messageTypeSource); + sb.append(", messageTypeTarget=" + messageTypeTarget); + sb.append(", transClassify=" + transClassify); + logger.info(sb.toString()); + } + + // 동기-동기 일경우 adptrMsgPtrnCdSource 기준 으로 표준일 경우 tag를 붙인다. + // 동기-비동기 일경우 adptrMsgPtrnCdSource 기준 으로 표준일 경우 tag를 붙인다. + // 비동기-비동기 일경우 요청거래일 경우 adptrMsgPtrnCdSource 기준으로 표준일 경우 tag를 붙인다. + // 비동기-비동기 일경우 응답거래일 경우 adptrMsgPtrnCdTarget 기준으로 표준일 경우 tag를 붙인다. + // 비동기-동기 일경우 adptrMsgPtrnCdSource 표준일 경우 tag를 붙인다. + + if (serviceType.equals(EAIMessageKeys.SYNC_SVC)) { + if (messageTypeSource.equals(MessageType.JSON)) { + return true; + } + } else if (serviceType.equals(EAIMessageKeys.ASYNC_SVC) || serviceType.equals(EAIMessageKeys.ACKONLY_SVC)) { + if (psvItfTp.equals(EAIMessageKeys.SYNC_SVC)) { + if (messageTypeSource.equals(MessageType.JSON)) { + return true; + } + } else { + if (transClassify) { + if (messageTypeSource.equals(MessageType.JSON)) { + return true; + } + } else { + if (messageTypeTarget.equals(MessageType.JSON)) { + return true; + } + } + } + } + return false; + } + + /** + * 1. 기능 : SMS를 전송하기 위한 로그를 쓰는 메소드 2. 처리 개요 : + * - SMS 를 전송 하기 위한 로그를 쓴다. + * + * @param eaiMessage : EAIMessage + * @exception Exception SQLException + **/ + private static void smsLogging(EAIMessage eaiMessage) { + // SMS=>[SMS][EAI][E:EAI서비스일련번호][업무구분코드] 에러코드:에러메시지 + // 에러메시지80byte로 자름 + SMSLogUtil.loggingSMSWithCode(eaiMessage.getEAISvcCd(), eaiMessage.getRspErrCd()); + + logger.error("[SMS] [EAI] [E:" + eaiMessage.getSvcOgNo() + "] [" + eaiMessage.getBwkCls() + "] " + + eaiMessage.getRspErrCd() + ":" + eaiMessage.getRspErrMsg()); + } +} diff --git a/src/main/java/com/eactive/eai/common/exception/ExceptionHandlerKeys.java b/src/main/java/com/eactive/eai/common/exception/ExceptionHandlerKeys.java new file mode 100644 index 0000000..e5a7ca3 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/exception/ExceptionHandlerKeys.java @@ -0,0 +1,11 @@ +package com.eactive.eai.common.exception; + +public interface ExceptionHandlerKeys +{ + public static final String GROUP_NAME = "ExceptionHandler"; + + public static final String EXCEPTION_HANDLER_CONNECTION_FACTORY = "exceptionhandler.connection.factory"; + public static final String EXCEPTION_HANDLER_QUEUE = "exceptionhandler.queue"; + public static final String TRANS_CLASSIFY = "transClassify"; + +} diff --git a/src/main/java/com/eactive/eai/common/exception/ExceptionHandlerServiceImpl.java b/src/main/java/com/eactive/eai/common/exception/ExceptionHandlerServiceImpl.java new file mode 100644 index 0000000..496944a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/exception/ExceptionHandlerServiceImpl.java @@ -0,0 +1,255 @@ +package com.eactive.eai.common.exception; + +import com.eactive.eai.common.errorcode.ErrorCodeHandler; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : Exception 발생 시 메시지를 처리하기 위한 Utility 클래스 +* 2. 처리 개요 : Exception 발생 시 메시지를 처리하는 메서드를 정의한다. +* * - +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class ExceptionHandlerServiceImpl implements ExceptionHandleService { + /** + * Default Logger + */ + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * 메시지 코드 자릿수 + */ + public static final int CODE_LENGTH = 12; + /** + * 메시지 코드 Prefix + */ + //public static final String CODE_PREFIX = "RECEAI"; + public static final String CODE_PREFIX_ERROR = "RECEAI"; + public static final String CODE_PREFIX_FATAL = "RFCEAI"; + public static final String MSGCODE_PREFIX_ERROR = "[RECEAI"; + public static final String MSGCODE_PREFIX_FATAL = "[RFCEAI"; +// public static final String MSGCODE_PREFIX_NEW = "[에러코드:S9"; + public static final String MSGCODE_PREFIX_NEW = "[ERRCD:"; + + /** + * 1. 기능 : Exception 발생 시 약속된 메시지 코드를 반환하기 위한 메서드 + * 2. 처리 개요 : Exception 내 메시지가 메시지 코드 체계인지를 판단해서 메시지 체계이면 Excepiton의 메시지를 반환하고, + * 그렇지 않다면 파라미터에 새로 정의한 메시지 코드를 반환한다. + * - + * 3. 주의사항 + * + * @param cause 발생한 오류 + * @param code 새로 정의할 메시지 코드 + * @return 메시지 코드 + **/ + public String getErrorCode(Throwable cause, String code) { + if(cause==null) { + String cd = "RECEAICEU001"; + if (logger.isWarn()) logger.warn("["+cd+"] "+ErrorCodeHandler.getMessage(cd)); + return code; + } + + logger.error(code, cause); + + String msg = makeExceptionCause(cause); + + if( msg!=null && + (msg.startsWith(CODE_PREFIX_ERROR) || msg.startsWith(CODE_PREFIX_FATAL)) ) { + //return msg; + return "["+msg+"] " + ErrorCodeHandler.getMessage(msg); + } + else if( msg!=null + && (msg.startsWith(MSGCODE_PREFIX_NEW) + || msg.startsWith(MSGCODE_PREFIX_ERROR) + || msg.startsWith(MSGCODE_PREFIX_FATAL)) ) { + return msg; + } + else if(msg != null) { + return formatErrorCode(code) + ErrorCodeHandler.getMessage(code) + ", " + msg; + } + else { +// cause.printStackTrace(); + return formatErrorCode(code) + ErrorCodeHandler.getMessage(code); + //return code; + } + + } + + /** + * 1. 기능 : Error 코드 및 텍스트를 정의된 포맷으로 만드는 메서드 + * 2. 처리 개요 : Error 코드 및 텍스트를 정의된 포맷으로 만들어 반환한다. + * - + * 3. 주의사항 + * + * @param errorCode 에러 코드 + * @param errorText 에러 텍스트 + * @return 에러코드와 텍스트 + **/ + public String make(String errorCode, String errorText) { + return formatErrorCode(errorCode) + errorText; + } + + /** + * 1. 기능 : Error 코드 및 텍스트를 정의된 포맷으로 만드는 메서드 + * 2. 처리 개요 : Error 코드 및 텍스트를 정의된 포맷으로 만들어 반환한다. + * - + * 3. 주의사항 + * + * @param errorCode 에러 코드 + * @param causeErrorCode 최초 발생한 오류 코드 + * @param errorText 에러 텍스트 + * @return 에러코드와 텍스트 + **/ + public String make(String errorCode, String causeErrorCode, String errorText) { + return formatErrorCode(errorCode) + errorText + + ", " + causeErrorCode; + } + + /** + * 1. 기능 : Error 코드에 대한 텍스트를 정의된 포맷으로 만드는 메서드 + * 2. 처리 개요 : Error 코드 및 텍스트를 정의된 포맷으로 만들어 반환한다. + * - + * 3. 주의사항 + * + * @param errorCode 에러 코드 + * @param args 에러 텍스트에 셋팅할 인수 리스트 + * @return 에러코드와 텍스트 + **/ + public String make(String errorCode, String[] args) { + String errorText = ErrorCodeHandler.getMessage(errorCode, args); + return make(errorCode, errorText); + } + + /** + * 1. 기능 : Error 코드에 대한 텍스트를 정의된 포맷으로 만드는 메서드 + * 2. 처리 개요 : Error 코드 및 텍스트를 정의된 포맷으로 만들어 반환한다. + * - + * 3. 주의사항 + * + * @param errorCode 에러 코드 + * @param causeErrorCode 최초 발생한 오류 코드 + * @param args 에러 텍스트에 셋팅할 인수 리스트 + * @return 에러코드와 텍스트 + **/ + public String make(String errorCode, String causeErrorCode, String[] args) { + String errorText = ErrorCodeHandler.getMessage(errorCode, args); + return make(errorCode, causeErrorCode, errorText); + } + + /** + * 1. 기능 : Error 코드에 대한 텍스트를 정의된 포맷으로 만드는 메서드 + * 2. 처리 개요 : Error 코드 및 텍스트를 정의된 포맷으로 만들어 반환한다. + * - + * 3. 주의사항 + * + * @param cause 발생한 오류 + * @param errorCode 에러 코드 + * @param args 에러 텍스트에 셋팅할 인수 리스트 + * @return 에러코드와 텍스트 + **/ + public String make(Throwable cause, String errorCode, String[] args) { + String errorText = ErrorCodeHandler.getMessage(errorCode,args); + if(errorText==null) errorText = "메시지 코드 테이블에 등록되지 않은 코드입니다. - "+errorCode; + + String msg = makeExceptionCause(cause); + + if( msg!=null && (msg.startsWith(CODE_PREFIX_ERROR) || msg.startsWith(CODE_PREFIX_FATAL)) ) { + return make(errorCode, msg, errorText); + } + else if( msg!=null + && (msg.startsWith(MSGCODE_PREFIX_NEW) + || msg.startsWith(MSGCODE_PREFIX_ERROR) + || msg.startsWith(MSGCODE_PREFIX_FATAL)) ) { + return make(errorCode, msg, errorText); + } + if(msg != null) { + return make(errorCode, errorText + ", " + msg); + } + else { + return make(errorCode, errorText); + } + } // Controller 용 + + + /** + * 1. 기능 : Error 코드에 대한 텍스트를 정의된 포맷으로 만드는 메서드 + * 2. 처리 개요 : Error 코드 및 텍스트를 정의된 포맷으로 만들어 반환한다. + * - + * 3. 주의사항 + * + * @param cause 발생한 오류 + * @param errorCode 에러 코드 + * @return 에러코드와 텍스트 + **/ + public String make(Throwable cause, String errorCode) { + String errorText = ErrorCodeHandler.getMessage(errorCode); + if(errorText==null) errorText = "메시지 코드 테이블에 등록되지 않은 코드입니다. - "+errorCode; + + String msg = makeExceptionCause(cause); + + if( msg!=null && (msg.startsWith(CODE_PREFIX_ERROR) || msg.startsWith(CODE_PREFIX_FATAL)) ) { + return make(errorCode, msg, errorText); + } + else if( msg!=null + && (msg.startsWith(MSGCODE_PREFIX_NEW) + || msg.startsWith(MSGCODE_PREFIX_ERROR) + || msg.startsWith(MSGCODE_PREFIX_FATAL)) ) { + return make(errorCode, msg, errorText); + } + else { + return make(errorCode, errorText); + } + } // Controller 용 + + public String formatErrorCode( String code ) { + //TODO S9 을 없앨수 있나? + return MSGCODE_PREFIX_NEW +code+ "]"; +// if(code !=null && code.length() > 6) { +// return MSGCODE_PREFIX_NEW + code.substring(6) + "]"; +// } +// else { +// return MSGCODE_PREFIX_NEW + code + "]"; +// } + } + + public String makeExceptionCause(Throwable cause) { + StringBuilder sb = new StringBuilder(); + + if(cause == null) { + return "cause is NULL"; + } + + sb.append(cause.getMessage()); + + Throwable t = cause.getCause(); + String secondCause = null; + String rootCause = null; + + if(t != null) { + secondCause = t.getMessage(); + t = t.getCause(); + while(t != null) { + if(t.getCause() == null) { + rootCause = t.getMessage(); + break; + } + else { + t = t.getCause(); + } + } + } + + if(secondCause != null) { + sb.append(", ").append(secondCause); + } + if( rootCause != null ) { + sb.append(", ").append(rootCause); + } + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/common/header/HeaderAction.java b/src/main/java/com/eactive/eai/common/header/HeaderAction.java new file mode 100644 index 0000000..2e0efe3 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/header/HeaderAction.java @@ -0,0 +1,28 @@ +package com.eactive.eai.common.header; + + + +/** +* 1. 기능 : 공통부 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 interface +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public interface HeaderAction +{ + public byte[] excute( byte[] orgData, byte[] message, String sendRecv, String commandType); + public byte[] deleteHeader(byte[] message, int headerLength) ; + + public byte[] addHeaderDA(byte[] orgData , byte[] message ) ; + public byte[] addHeaderAD(byte[] orgData , byte[] message ) ; + + public int getHeaderLength(); + +} + diff --git a/src/main/java/com/eactive/eai/common/header/HeaderActionException.java b/src/main/java/com/eactive/eai/common/header/HeaderActionException.java new file mode 100644 index 0000000..483df05 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/header/HeaderActionException.java @@ -0,0 +1,12 @@ +package com.eactive.eai.common.header; + +public class HeaderActionException extends Exception +{ + public HeaderActionException() { + super("HeaderActionException is occured."); + } + + public HeaderActionException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/common/header/HeaderActionFactory.java b/src/main/java/com/eactive/eai/common/header/HeaderActionFactory.java new file mode 100644 index 0000000..430bf59 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/header/HeaderActionFactory.java @@ -0,0 +1,32 @@ +package com.eactive.eai.common.header; + +/** +* 1. 기능 : 공통부 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Factory Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class HeaderActionFactory +{ + + private HeaderActionFactory() { + } + + public static HeaderAction createAction(String actionName) throws HeaderActionException { + HeaderAction action = null; + try { + Class cl = Class.forName(actionName); + action = (HeaderAction)cl.newInstance(); + } catch(Exception e) { + throw new HeaderActionException("Cannot create a HeaderAction. - "+actionName); + } + return action; + } + +} diff --git a/src/main/java/com/eactive/eai/common/header/HeaderActionKeys.java b/src/main/java/com/eactive/eai/common/header/HeaderActionKeys.java new file mode 100644 index 0000000..9533dc2 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/header/HeaderActionKeys.java @@ -0,0 +1,27 @@ +package com.eactive.eai.common.header; + +/** +* 1. 기능 : 공통부 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Key +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class HeaderActionKeys +{ + + public static final String ADD_DELETE_HEADER = "02"; + public static final String DELETE_ADD_HEADER = "01"; + + public static final String MESSAGE_SEND = "S"; + public static final String MESSAGE_RECV = "R"; + + public static final String SUPPORT_Y= "1"; + public static final String SUPPORT_N= "0"; + +} diff --git a/src/main/java/com/eactive/eai/common/header/HeaderActionSupport.java b/src/main/java/com/eactive/eai/common/header/HeaderActionSupport.java new file mode 100644 index 0000000..cd03669 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/header/HeaderActionSupport.java @@ -0,0 +1,97 @@ +package com.eactive.eai.common.header; + +import com.eactive.eai.common.util.Logger; + + +/** +* 1. 기능 : 공통부 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Utility Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public abstract class HeaderActionSupport implements HeaderAction +{ + private int HEADER_LENGTH = 0; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + + public void HeaderAction(){ + + } + public int getHeaderLength(){ + return this.HEADER_LENGTH; + } + public void setHeaderLength(int headerLength){ + this.HEADER_LENGTH = headerLength; + } + /** + * input message로 부터 헤더추가 삭제한 메시지를 반환한다. + */ + public byte[] excute( byte[] orgData, byte[] message, String sendRecv, String commandType){ + +// if(logger.isDebug()) { +// logger.debug("HeaderActionSupport] orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// logger.debug("HeaderActionSupport] message=>"+new String(message==null?"".getBytes():message)); +// logger.debug("HeaderActionSupport] sendRecv=>"+sendRecv); +// logger.debug("HeaderActionSupport] commandType=>"+commandType); +// } + + if(HeaderActionKeys.ADD_DELETE_HEADER.equals(commandType)) { + if(HeaderActionKeys.MESSAGE_SEND.equals(sendRecv)) { + return addHeaderAD(orgData , message ); + } + else if(HeaderActionKeys.MESSAGE_RECV.equals(sendRecv)) { + return deleteHeaderAD(message, getHeaderLength()); + + } + else { + return message; + } + } + else if(HeaderActionKeys.DELETE_ADD_HEADER.equals(commandType)) { + if(HeaderActionKeys.MESSAGE_SEND.equals(sendRecv)) { + return deleteHeaderDA(message, getHeaderLength()); + } + else if(HeaderActionKeys.MESSAGE_RECV.equals(sendRecv)) { + return addHeaderDA(orgData , message ); + + } + else { + return message; + } + } + else { + return message; + } + } + public byte[] deleteHeaderAD(byte[] message, int headerLength) { + return deleteHeader(message,headerLength); + } + public byte[] deleteHeaderDA(byte[] message, int headerLength) { + return deleteHeader(message,headerLength); + } + + public byte[] deleteHeader(byte[] message, int headerLength) { + int msgLength = message.length - headerLength; + if(msgLength > 0) { + byte[] retHeader = new byte[msgLength]; + System.arraycopy(message, headerLength, retHeader, 0, retHeader.length); + return retHeader; + } + else { + return message; + } + } + + abstract public byte[] addHeaderDA(byte[] orgData , byte[] message ) ; + abstract public byte[] addHeaderAD(byte[] orgData , byte[] message ) ; + +} + diff --git a/src/main/java/com/eactive/eai/common/inflow/Bucket.java b/src/main/java/com/eactive/eai/common/inflow/Bucket.java new file mode 100644 index 0000000..51db277 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/inflow/Bucket.java @@ -0,0 +1,9 @@ +package com.eactive.eai.common.inflow; + +public interface Bucket { + public boolean isAdapterPass(String adapter); + public boolean isInterfacePass(String inter); + public InflowTargetVO getAdapterInflowThreashold(String adapter); + public InflowTargetVO getInterfaceInflowThreashold(String inter); + public InflowTargetVO getInflowThreashold(String inter); +} diff --git a/src/main/java/com/eactive/eai/common/inflow/CustomBucket.java b/src/main/java/com/eactive/eai/common/inflow/CustomBucket.java new file mode 100644 index 0000000..59070b8 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/inflow/CustomBucket.java @@ -0,0 +1,31 @@ +package com.eactive.eai.common.inflow; + +import io.github.bucket4j.local.LocalBucket; + +public class CustomBucket { + private InflowTargetVO inflowTargetVo; + private LocalBucket localBucket; + + public CustomBucket(LocalBucket localBucket, InflowTargetVO inflowTargetVo) { + super(); + this.inflowTargetVo = inflowTargetVo; + this.localBucket = localBucket; + } + + public InflowTargetVO getInflowTargetVo() { + return inflowTargetVo; + } + + public void setInflowTargetVo(InflowTargetVO inflowTargetVo) { + this.inflowTargetVo = inflowTargetVo; + } + + public LocalBucket getLocalBucket() { + return localBucket; + } + + public void setLocalBucket(LocalBucket localBucket) { + this.localBucket = localBucket; + } + +} diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java b/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java new file mode 100644 index 0000000..b294bc7 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/inflow/InflowControlDAO.java @@ -0,0 +1,135 @@ +package com.eactive.eai.common.inflow; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.inflow.loader.InflowControlLoader; +import com.eactive.eai.common.inflow.loader.InflowControlLogLogger; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.inflow.InflowControl; +import com.eactive.eai.data.entity.onl.inflow.InflowControlLog; +import com.eactive.eai.data.entity.onl.inflow.InflowControlLogId; + +@Service +@Transactional +public class InflowControlDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private InflowControlLoader inflowControlLoader; + + @Autowired + private InflowControlLogLogger inflowControlLogLogger; + + public List getInflowAdapterList() throws DAOException { + return getInflowList("01"); + } + + public List getInflowInterfaceList() throws DAOException { + return getInflowList("02"); + } + + public Map getInflowTargetByAdater(String name) throws DAOException { + return getInflowMap("01", name); + } + + public Map getInflowTargetByInterface(String name) throws DAOException { + return getInflowMap("02", name); + } + + private List getInflowList(String type) throws DAOException { + try { + Iterable inflowControls = inflowControlLoader.findByConditions(type, ""); + List targetList = new ArrayList<>(); + logger.info("[ @@ Load InflowControl Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (InflowControl inflowControl : inflowControls) { + InflowTargetVO vo = new InflowTargetVO(); + vo.setName(inflowControl.getId().getName()); + vo.setThreshold(inflowControl.getThreshold()); + vo.setThresholdPerSecond(inflowControl.getThresholdpersecond()); + vo.setThresholdTimeUnit(inflowControl.getThresholdtimeunit()); + vo.setActivate(!"0".equals(inflowControl.getUseyn())); + targetList.add(vo); + } + logger.info("[>>Load InflowControl Configuration - ended ]"); + return targetList; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + private Map getInflowMap(String type, String name) throws DAOException { + try { + Iterable inflowControls = inflowControlLoader.findByConditions(type, name); + Map targetList = new HashMap<>(); + logger.info("[ @@ Load InflowControl getInflowMap Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + for (InflowControl inflowControl : inflowControls) { + InflowTargetVO vo = new InflowTargetVO(); + vo.setName(inflowControl.getId().getName()); + vo.setThreshold(inflowControl.getThreshold()); + vo.setThresholdPerSecond(inflowControl.getThresholdpersecond()); + vo.setThresholdTimeUnit(inflowControl.getThresholdtimeunit()); + vo.setActivate(!"0".equals(inflowControl.getUseyn())); + targetList.put(vo.getName(), vo); + } + logger.info("[>>Load InflowControl getInflowMap Configuration - ended ]"); + return targetList; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + /** + * 1. 기능 : 유량제어 로그를 INSERT하는 메서드 2. 처리 개요 : 파라미터의 코드, 메시지를 테이블에 INSERT한다. - 3. + * 주의사항 + * + * @param EAIBzwkDstcd EAI업무구분코드 + * @param MsgDpstYMS 메시지수신일시 + * @param EAISvcSerno EAI서비스일련번호 + * @param EAISevrInstncName EAI서버인스턴스명 + * @param EAISvcName EAI서비스명 + * @param EAIOsidInstiCd EAI대외기관코드 + * @exception DAOException JDBC 관련 오류(SQLException) + **/ + // bzwkDstcd + msgDpstYMS + eAISvcSerno + +// String bzwkDstcd, String msgDpstYMS, String eAISvcSerno, +// String eAISevrInstncName, String eAISvcName, String adapterGroupName, +// long limitPerSecond, long limit, String timeUnit + public void addInflowServicetLog(String bzwkDstcd, String msgDpstYMS, String eAISvcSerno, String eAISevrInstncName, + String eAISvcName, String adapterGroupName, long limitPerSecond, long limit, String timeUnit) + throws DAOException { + try { + InflowControlLog inflowControlLog = new InflowControlLog(); + InflowControlLogId id = new InflowControlLogId(); + + id.setEaibzwkdstcd(bzwkDstcd); + id.setMsgdpstyms(msgDpstYMS); + id.setEaisvcserno(eAISvcSerno); + + inflowControlLog.setId(id); + inflowControlLog.setEaisevrinstncname(eAISevrInstncName); + inflowControlLog.setEaisvcname(eAISvcName); + inflowControlLog.setAdptrbzwkgroupname(adapterGroupName); + inflowControlLog.setThresholdpersecond((int) limitPerSecond); + inflowControlLog.setThreshold((int) limit); + inflowControlLog.setThresholdtimeunit(timeUnit); + + inflowControlLogLogger.save(inflowControlLog); + + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java new file mode 100644 index 0000000..1f33788 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/inflow/InflowControlManager.java @@ -0,0 +1,357 @@ +package com.eactive.eai.common.inflow; + +import java.time.Duration; +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.message.service.InterfaceMapper; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +import io.github.bucket4j.Bandwidth; +import io.github.bucket4j.Bucket4j; +import io.github.bucket4j.local.LocalBucketBuilder; + +@Component +public class InflowControlManager implements Lifecycle, Bucket { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + public static final String QUOTA_TIMEUNIT_SECOND = "SEC"; + public static final String QUOTA_TIMEUNIT_MINUTE = "MIN"; + public static final String QUOTA_TIMEUNIT_HOUR = "HOU"; + public static final String QUOTA_TIMEUNIT_DAY = "DAY"; + public static final String QUOTA_TIMEUNIT_MONTH = "MON"; + + private Map adapterBucketList = new HashMap<>(); + private Map interfaceBucketList = new HashMap<>(); + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + @Autowired + private InflowControlDAO inflowControlDAO; + + public static synchronized InflowControlManager getInstance() { + return ApplicationContextProvider.getContext().getBean(InflowControlManager.class); + } + + public static synchronized Bucket getBucket() { + return ApplicationContextProvider.getContext().getBean(InflowControlManager.class); + } + + /** + * 유량제어 대상인 거래인지 체크한다.(사이트에 맞게 구성) + * + * @param eaiServerManager + * @param eaiMessage + * @return + */ + public static Boolean isTargetOfInflowControl(EAIServerManager eaiServerManager, EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + String inExDiv = MessageUtil.getInExDivision(mapper.getInExDivision(eaiMessage.getStandardMessage()), + eaiMessage.getInternalExternalDvcd()); // 1|2 + String returnType = mapper.getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R + + if (STDMessageKeys.DIRECTION_IN.equals(inExDiv) && STDMessageKeys.SEND_RECV_CD_SEND.equals(returnType)) { + return Boolean.valueOf(true); + } + + return Boolean.valueOf(false); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICMM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICMM202")); + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + initAdapter(); + initInterface(); + } + + private void initAdapter() throws Exception { + adapterBucketList = new HashMap<>(); + List inflowAdapterVoList = inflowControlDAO.getInflowAdapterList(); + + for (InflowTargetVO inflowVo : inflowAdapterVoList) { + if (InflowControlManager.isInflowTarget(inflowVo)) { + CustomBucket bucket = makeBucketUsingInflowVO(inflowVo); + if (bucket != null) { + adapterBucketList.put(inflowVo.getName(), bucket); + } + } + } + } + + private void initInterface() throws Exception { + interfaceBucketList = new HashMap<>(); + List inflowInterfaceVoList = inflowControlDAO.getInflowInterfaceList(); + + for (InflowTargetVO inflowVo : inflowInterfaceVoList) { + if (InflowControlManager.isInflowTarget(inflowVo)) { + CustomBucket bucket = makeBucketUsingInflowVO(inflowVo); + if (bucket != null) { + interfaceBucketList.put(inflowVo.getName(), bucket); + } + } + } + } + + public synchronized void reloadAdapter() throws Exception { + if (logger.isWarn()) { + logger.warn("InflowControlManager] reload all Started ..."); + } + initAdapter(); + if (logger.isWarn()) { + logger.warn("InflowControlManager] reload all finished ..."); + } + } + + public synchronized void reloadInterface() throws Exception { + if (logger.isWarn()) { + logger.warn("InflowControlManager] reload all Started ..."); + } + initInterface(); + if (logger.isWarn()) { + logger.warn("InflowControlManager] reload all finished ..."); + } + } + + public synchronized void reloadAdapter(String adapter) throws Exception { + if (logger.isWarn()) { + logger.warn("InflowControlManager] reload Started ..."); + } + Map map = inflowControlDAO.getInflowTargetByAdater(adapter); + if (map != null) { + Iterator it = map.keySet().iterator(); + String key = ""; + while (it.hasNext()) { + key = it.next(); + + InflowTargetVO inflowTarget = map.get(key); + if (InflowControlManager.isInflowTarget(inflowTarget)) { + CustomBucket bucket = makeBucketUsingInflowVO(inflowTarget); + if (bucket != null) { + adapterBucketList.put(inflowTarget.getName(), bucket); + } else { + adapterBucketList.remove(inflowTarget.getName()); + } + } else { + adapterBucketList.remove(inflowTarget.getName()); + } + } + } + if (logger.isWarn()) { + logger.warn("InflowControlManager] reload finished ..."); + } + } + + public synchronized void reloadInterface(String inter) throws Exception { + if (logger.isWarn()) { + logger.warn("InflowControlManager] reload Started ..."); + } + Map map = inflowControlDAO.getInflowTargetByInterface(inter); + if (map != null) { + Iterator it = map.keySet().iterator(); + String key = ""; + while (it.hasNext()) { + key = it.next(); + + InflowTargetVO inflowTarget = map.get(key); + if (InflowControlManager.isInflowTarget(inflowTarget)) { + CustomBucket bucket = makeBucketUsingInflowVO(inflowTarget); + if (bucket != null) { + interfaceBucketList.put(inflowTarget.getName(), bucket); + } else { + interfaceBucketList.remove(inflowTarget.getName()); + } + } else { + interfaceBucketList.remove(inflowTarget.getName()); + } + } + } + + if (logger.isWarn()) { + logger.warn("InflowControlManager] reload finished ..."); + } + } + + public void stop() throws LifecycleException { + // Validate and update our current component state + if (!started) + throw new LifecycleException("RECEAICMM203"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + adapterBucketList.clear(); + interfaceBucketList.clear(); + + started = false; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public String[] getAdapterAllKeys() { + Iterator it = this.adapterBucketList.keySet().iterator(); + String[] svcCd = new String[this.adapterBucketList.size()]; + for (int i = 0; it.hasNext(); i++) { + svcCd[i] = it.next(); + } + Arrays.sort(svcCd); + return svcCd; + } + + public String[] getInterfaceAllKeys() { + Iterator it = this.interfaceBucketList.keySet().iterator(); + String[] svcCd = new String[this.interfaceBucketList.size()]; + for (int i = 0; it.hasNext(); i++) { + svcCd[i] = it.next(); + } + Arrays.sort(svcCd); + return svcCd; + } + + public void removeAdapter(String adapter) { + adapterBucketList.remove(adapter); + } + + public void removeInterface(String inter) { + interfaceBucketList.remove(inter); + } + + private CustomBucket makeBucketUsingInflowVO(InflowTargetVO inflowTarget) { + if (InflowControlManager.isInflowTarget(inflowTarget)) { + LocalBucketBuilder builder = Bucket4j.builder(); + if (inflowTarget.getThresholdPerSecond() > 0) { + builder.addLimit(Bandwidth.simple(inflowTarget.getThresholdPerSecond(), Duration.ofSeconds(1))); + } + + if (inflowTarget.getThreshold() > 0 && StringUtils.isNotBlank(inflowTarget.getThresholdTimeUnit())) { + builder.addLimit(Bandwidth.simple(inflowTarget.getThreshold(), + InflowControlManager.getPeriod(inflowTarget.getThresholdTimeUnit()))); + } + + return new CustomBucket(builder.build(), inflowTarget); + } + + return null; + } + + @Override + public boolean isAdapterPass(String adapter) { + CustomBucket b = adapterBucketList.get(adapter); + + if (b == null) + return true; + + return b.getLocalBucket().tryConsume(1); + } + + @Override + public boolean isInterfacePass(String inter) { + CustomBucket b = interfaceBucketList.get(inter); + + if (b == null) + return true; + + return b.getLocalBucket().tryConsume(1); + } + + @Override + public InflowTargetVO getAdapterInflowThreashold(String adapter) { + CustomBucket b = adapterBucketList.get(adapter); + if (b == null) + return null; + return b.getInflowTargetVo(); + } + + @Override + public InflowTargetVO getInterfaceInflowThreashold(String inter) { + CustomBucket b = interfaceBucketList.get(inter); + if (b == null) + return null; + return b.getInflowTargetVo(); + } + + @Override + public InflowTargetVO getInflowThreashold(String inter) { + return null; + } + + public InflowTargetVO getAdapterInflow(String adapter) { + return getAdapterInflowThreashold(adapter); + } + + public InflowTargetVO getInterfaceInflow(String inter) { + return getInterfaceInflowThreashold(inter); + } + + public static boolean isInflowTarget(InflowTargetVO inflowTarget) { + if (inflowTarget == null || !inflowTarget.isActivate()) { + return false; + } + + return inflowTarget.getThresholdPerSecond() > 0 || (inflowTarget.getThreshold() > 0 && StringUtils + .equalsAnyIgnoreCase(inflowTarget.getThresholdTimeUnit(), QUOTA_TIMEUNIT_DAY, QUOTA_TIMEUNIT_SECOND, + QUOTA_TIMEUNIT_MINUTE, QUOTA_TIMEUNIT_HOUR, QUOTA_TIMEUNIT_DAY, QUOTA_TIMEUNIT_MONTH)); + + } + + public static Duration getPeriod(String timeUnit) { + if (StringUtils.equalsIgnoreCase(timeUnit, QUOTA_TIMEUNIT_SECOND)) { + return Duration.ofSeconds(1); + } else if (StringUtils.equalsIgnoreCase(timeUnit, QUOTA_TIMEUNIT_MINUTE)) { + return Duration.ofMinutes(1); + } else if (StringUtils.equalsIgnoreCase(timeUnit, QUOTA_TIMEUNIT_HOUR)) { + return Duration.ofHours(1); + } else if (StringUtils.equalsIgnoreCase(timeUnit, QUOTA_TIMEUNIT_DAY)) { + return Duration.ofDays(1); + } else if (StringUtils.equalsIgnoreCase(timeUnit, QUOTA_TIMEUNIT_MONTH)) { + Calendar calendar = Calendar.getInstance(); + return Duration.ofDays(calendar.getActualMaximum(Calendar.DAY_OF_MONTH)); + } else { + return null; + } + } +} diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowControlUtil.java b/src/main/java/com/eactive/eai/common/inflow/InflowControlUtil.java new file mode 100644 index 0000000..3fa037f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/inflow/InflowControlUtil.java @@ -0,0 +1,67 @@ +package com.eactive.eai.common.inflow; + +import java.lang.reflect.Method; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +public class InflowControlUtil { + private InflowControlUtil() { + } + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static Bucket getBucket() { + Properties inFlowProp = PropManager.getInstance().getProperties("INFLOW"); + String className = inFlowProp.getProperty("inflow.control.bucket.className"); + if (StringUtils.isBlank(className) + || StringUtils.equals(className, "com.eactive.eai.common.inflow.InflowControlManager")) { + return InflowControlManager.getBucket(); + } else { + try { + Class clazz = Class.forName(className); + Method method = clazz.getMethod("getBucket", (Class[]) null); + return (Bucket) method.invoke(null, (Object[]) null); + } catch (Exception e) { + logger.error("Method call error class= {}, method= getBucket", className); + logger.error(e.getMessage()); + } + } + + return null; + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + public static boolean isTargetOfInflowControl(EAIServerManager eaiServerManager, EAIMessage eaiMessage) { + Properties inFlowProp = PropManager.getInstance().getProperties("INFLOW"); + String controlInflow = inFlowProp.getProperty("inflow.control.yn", "N"); + + if (!"Y".equalsIgnoreCase(controlInflow)) { + return false; + } + + String className = inFlowProp.getProperty("inflow.control.bucket.className"); + if (StringUtils.isBlank(className) + || StringUtils.equals(className, "com.eactive.eai.common.inflow.InflowControlManager")) { + return InflowControlManager.isTargetOfInflowControl(eaiServerManager, eaiMessage).booleanValue(); + } else { + try { + Class clazz = Class.forName(className); + Method method = clazz.getMethod("isTargetOfInflowControl", EAIServerManager.class, EAIMessage.class); + Boolean returnBoolean = (Boolean) method.invoke(null, eaiServerManager, eaiMessage); + return returnBoolean.booleanValue(); + } catch (Exception e) { + logger.error("Method call error class= {}, method= isTargetOfInflowControl", className); + logger.error(e.getMessage()); + } + } + + return false; + } +} diff --git a/src/main/java/com/eactive/eai/common/inflow/InflowTargetVO.java b/src/main/java/com/eactive/eai/common/inflow/InflowTargetVO.java new file mode 100644 index 0000000..9595eb6 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/inflow/InflowTargetVO.java @@ -0,0 +1,68 @@ +package com.eactive.eai.common.inflow; + +import java.io.Serializable; + +@SuppressWarnings("serial") +public class InflowTargetVO implements Serializable { + String name; + long thresholdPerSecond; + long threshold; + String thresholdTimeUnit; + boolean activate; + + @Override + public boolean equals(Object obj) { + return name.equals(obj); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + public boolean isActivate() { + return activate; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getThreshold() { + return threshold; + } + + public void setThreshold(long threshold) { + this.threshold = threshold; + } + + public void setActivate(boolean activate) { + this.activate = activate; + } + + public long getThresholdPerSecond() { + return thresholdPerSecond; + } + + public void setThresholdPerSecond(long thresholdPerSecond) { + this.thresholdPerSecond = thresholdPerSecond; + } + + public String getThresholdTimeUnit() { + return thresholdTimeUnit; + } + + public void setThresholdTimeUnit(String thresholdTimeUnit) { + this.thresholdTimeUnit = thresholdTimeUnit; + } + + @Override + public String toString() { + return "InflowTargetVO [name=" + name + ", thresholdPerSecond=" + thresholdPerSecond + ", threshold=" + + threshold + ", thresholdTimeUnit=" + thresholdTimeUnit + ", activate=" + activate + "]"; + } +} diff --git a/src/main/java/com/eactive/eai/common/jeus/JeusQueueProducer.java b/src/main/java/com/eactive/eai/common/jeus/JeusQueueProducer.java new file mode 100644 index 0000000..8a8f0c8 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/jeus/JeusQueueProducer.java @@ -0,0 +1,87 @@ +package com.eactive.eai.common.jeus; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.Properties; + +import javax.jms.JMSException; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.QueueSender; +import javax.jms.QueueSession; +import javax.jms.Session; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.jms.JmsServiceLocator; +import com.eactive.eai.common.util.Logger; + +public class JeusQueueProducer { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + QueueConnectionFactory qconFactory = null; + + String connectionFactory = null; + String destination = null; + + public JeusQueueProducer(String connectionUrl, String queueName) throws Exception { + this.connectionFactory = connectionUrl; + this.destination = queueName; + } + + public void sendMessage(Serializable object, Properties prop) throws Exception { + QueueConnection qcon = null; + QueueSession qsession = null; + Queue queue = null; + QueueSender qsender = null; + try { + JmsServiceLocator locator = JmsServiceLocator.getInstance(); + + qconFactory = locator.getQueueConnectionFactory(connectionFactory); + qcon = qconFactory.createQueueConnection(); + qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); + + queue = locator.getQueue(destination); + qsender = qsession.createSender(queue); + + ObjectMessage msg = qsession.createObjectMessage(); + msg.setObject(object); + + // Properties setting setStringProperties(); + if (prop != null) { + Iterator it = prop.keySet().iterator(); + while (it.hasNext()) { + String key = (String) it.next(); + String value = prop.getProperty(key); + msg.setStringProperty(key, value); + } + } + + qsender.send(msg); + } catch (Exception e) { + e.printStackTrace(); + // throw new JMSException("RECEAICUL001"); + throw new JMSException(ExceptionUtil.getErrorCode(e, "RECEAICUL001")); + } finally { + try { + if (qsender != null) + qsender.close(); + } catch (Exception e) { + // nothing to do + } + try { + if (qsession != null) + qsession.close(); + } catch (Exception e) { + // nothing to do + } + try { + if (qcon != null) + qcon.close(); + } catch (Exception e) { + // nothing to do + } + } + } +} diff --git a/src/main/java/com/eactive/eai/common/jeus/JeusTopicProducer.java b/src/main/java/com/eactive/eai/common/jeus/JeusTopicProducer.java new file mode 100644 index 0000000..3d4378a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/jeus/JeusTopicProducer.java @@ -0,0 +1,98 @@ +package com.eactive.eai.common.jeus; + +import java.io.Serializable; +import java.util.Iterator; +import java.util.Properties; + +import javax.jms.JMSException; +import javax.jms.ObjectMessage; +import javax.jms.Session; +import javax.jms.Topic; +import javax.jms.TopicConnection; +import javax.jms.TopicConnectionFactory; +import javax.jms.TopicPublisher; +import javax.jms.TopicSession; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.jms.JmsServiceLocator; +import com.eactive.eai.common.util.Logger; + +public class JeusTopicProducer { + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + TopicConnectionFactory topicFactory = null; + + String connectionFactory = null; + String destination = null; + String correlationID = null; + + public JeusTopicProducer(String connectionUrl, String topicName, String correlationID) throws Exception { + this.connectionFactory = connectionUrl; + this.destination = topicName; + this.correlationID = correlationID; + } + + //JMSSender.sendToTopic(eaiMessage, topicConFactory, routeTopicName, null, traceKey, ttl); + + public void sendMessage(Serializable object, Properties prop, long ttl) throws Exception { + TopicConnection tcon = null; + TopicSession tsession = null; + Topic topic = null; + TopicPublisher publisher = null; + try { + if (logger.isDebug()){ + logger.debug("sendToTopic] connectionFactory = "+connectionFactory); + logger.debug("sendToTopic] destination = "+destination); + logger.debug("sendToTopic] correlationID =["+correlationID+"]"); + } + JmsServiceLocator locator = JmsServiceLocator.getInstance(); + topicFactory = locator.getTopicConnectionFactory(connectionFactory); + topic = locator.getTopic(destination); + + tcon = topicFactory.createTopicConnection(); + tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + + publisher = tsession.createPublisher(topic); + + // TTL Setting + if(ttl > 0) { + publisher.setTimeToLive(ttl); + } + + ObjectMessage msg = tsession.createObjectMessage(); + msg.setObject(object); + if (correlationID != null) + msg.setJMSCorrelationID(correlationID); + + // Properties setting setStringProperties(); + if(prop!=null) { + Iterator it = prop.keySet().iterator(); + while(it.hasNext()) { + String key = (String)it.next(); + String value = prop.getProperty(key); + msg.setStringProperty(key,value); + } + } + publisher.publish(msg); + } catch(Exception e) { + throw new JMSException(ExceptionUtil.getErrorCode(e,"RECEAICUL002")); + } finally { + try { + if(publisher!=null) publisher.close(); + } catch(Exception e) { + // nothing to do + } + try { + if(tsession!=null) tsession.close(); + } catch(Exception e) { + // nothing to do + } + try { + if(tcon!=null) tcon.close(); + } catch(Exception e) { + // nothing to do + } + } + } +} diff --git a/src/main/java/com/eactive/eai/common/jms/JmsServiceLocator.java b/src/main/java/com/eactive/eai/common/jms/JmsServiceLocator.java new file mode 100644 index 0000000..0c7aa0c --- /dev/null +++ b/src/main/java/com/eactive/eai/common/jms/JmsServiceLocator.java @@ -0,0 +1,114 @@ +package com.eactive.eai.common.jms; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +import javax.jms.Queue; +import javax.jms.QueueConnectionFactory; +import javax.jms.Topic; +import javax.jms.TopicConnectionFactory; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ServiceLocatorException; + +public class JmsServiceLocator { + static private Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static JmsServiceLocator instance; + private InitialContext initial; + private Map cache; + + protected JmsServiceLocator() throws ServiceLocatorException { + try { + initial = new InitialContext(); + cache = Collections.synchronizedMap(new HashMap()); + } catch (NamingException e) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(e, "RECEAICUL101")); + } catch (Exception e) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(e, "RECEAICUL102")); + } + } + + public static synchronized JmsServiceLocator getInstance() throws ServiceLocatorException { + if (instance == null) { + instance = new JmsServiceLocator(); + return instance; + } else { + return instance; + } + } + + public QueueConnectionFactory getQueueConnectionFactory(String qConnFactoryName) throws ServiceLocatorException { + QueueConnectionFactory factory = null; + + try { + if (cache.containsKey(qConnFactoryName)) { + factory = (QueueConnectionFactory) cache.get(qConnFactoryName); + } else { + factory = (QueueConnectionFactory) initial.lookup(qConnFactoryName); + cache.put(qConnFactoryName, factory); + } + } catch (NamingException ne) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(ne, "RECEAICUL113")); + } catch (Exception e) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(e, "RECEAICUL114")); + } + return factory; + } + + public Queue getQueue(String queueName) throws ServiceLocatorException { + Queue queue = null; + try { + if (cache.containsKey(queueName)) { + queue = (Queue) cache.get(queueName); + } else { + queue = (Queue) initial.lookup(queueName); + cache.put(queueName, queue); + } + } catch (NamingException ne) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(ne, "RECEAICUL115")); + } catch (Exception e) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(e, "RECEAICUL116")); + } + return queue; + } + + public TopicConnectionFactory getTopicConnectionFactory(String topicConnFactoryName) + throws ServiceLocatorException { + TopicConnectionFactory factory = null; + + try { + if (cache.containsKey(topicConnFactoryName)) { + factory = (TopicConnectionFactory) cache.get(topicConnFactoryName); + } else { + factory = (TopicConnectionFactory) initial.lookup(topicConnFactoryName); + cache.put(topicConnFactoryName, factory); + } + } catch (NamingException ne) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(ne, "RECEAICUL117")); + } catch (Exception e) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(e, "RECEAICUL118")); + } + return factory; + } + + public Topic getTopic(String topicName) throws ServiceLocatorException { + Topic topic = null; + try { + if (cache.containsKey(topicName)) { + topic = (Topic) cache.get(topicName); + } else { + topic = (Topic) initial.lookup(topicName); + cache.put(topicName, topic); + } + } catch (NamingException ne) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(ne, "RECEAICUL119")); + } catch (Exception e) { + throw new ServiceLocatorException(ExceptionUtil.getErrorCode(e, "RECEAICUL120")); + } + return topic; + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/CustomStringBuffer.java b/src/main/java/com/eactive/eai/common/logger/CustomStringBuffer.java new file mode 100644 index 0000000..b729d5f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/CustomStringBuffer.java @@ -0,0 +1,42 @@ +package com.eactive.eai.common.logger; + + +public class CustomStringBuffer { + private StringBuffer sb ; + private String DELEMITER ; + public CustomStringBuffer() { + this.sb = new StringBuffer(); + this.DELEMITER = "#|@"; + + } + public CustomStringBuffer(String delemiter) { + this.sb = new StringBuffer(); + this.DELEMITER = delemiter; + } + public CustomStringBuffer appendAndDelimeter(String data){ + sb.append(data).append(DELEMITER); + return this; + } + public CustomStringBuffer appendAndDelimeter(int data){ + sb.append(Integer.toString(data)).append(DELEMITER); + return this; + } + public CustomStringBuffer append(String data){ + sb.append(data); + return this; + } + public CustomStringBuffer append(int data){ + sb.append(Integer.toString(data)); + return this; + } + public String toString(){ + return sb.toString(); + } + +// public static void main(String[] args){ +// CustomStringBuffer sb = new CustomStringBuffer(); +// sb.appendAndDelimeter("ABD").append("KKK"); +// System.out.println(sb.toString()); +// } + +} diff --git a/src/main/java/com/eactive/eai/common/logger/DBLogTransactionLogger.java b/src/main/java/com/eactive/eai/common/logger/DBLogTransactionLogger.java new file mode 100644 index 0000000..7271bfb --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/DBLogTransactionLogger.java @@ -0,0 +1,212 @@ +package com.eactive.eai.common.logger; + + +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; +import com.eactive.eai.common.dao.DAOFactory; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import org.apache.commons.lang.StringUtils; + + +/** + * 1. 기능 : EAI에서 처리되는 모든 On-Line 거래를 데이터베이스에 로깅하기 위한 운영관리 Logger Sender + * 2. 처리 개요 : + * - Processor에서 받은 거래로그 정보를 저장 + * 3. 주의사항 + * + * @author : + * @version : v 3.0.0 + * @see : + * @since :JDK v1.5.0 + */ +public class DBLogTransactionLogger implements TransactionLogger { + // 거래 로그 Count + private int logCount; + + // 에러 로그 Count + private int errCount; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * 1. 기능 : EAI 거래 로그 Count를 반환 + * 2. 처리 개요 : + * - EAI 거래 로그 Count를 반환한다. + * 3. 주의사항 + * + * @return int 거래 로그 Count + **/ + public int logCount() { + return logCount; + } + + /** + * 1. 기능 : EAI 에러 로그 Count를 반환 + * 2. 처리 개요 : + * - EAI 거래 에러 Count를 반환한다. + * 3. 주의사항 + * + * @return int 에러 로그 Count + **/ + public int errCount() { + return errCount; + } + + /** + * 1. 기능 : 거래 로그 및 에러 로그 초기화 + * 2. 처리 개요 : + * - 거래 및 에러 로그를 초기화 한다. + * 3. 주의사항 + * + **/ + public void resetCount() { + logCount = 0; + errCount = 0; + } + + private byte[] callAdapter(String adapterGroupName, Properties prop, Object message) + throws java.lang.Exception { + byte[] resBytes; + try { + + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = null; + adapter = factory.getElinkAdapter(com.eactive.eai.adapter.Keys.TYPE_NET2); + + if(prop==null) { + prop = new Properties(); + } + if(prop.getProperty("ADAPTER_GROUP_NAME") == null) { + prop.setProperty("ADAPTER_GROUP_NAME", adapterGroupName); + } + resBytes = (byte[])adapter.callService(adapterGroupName, prop, message, prop); + } catch(Exception e) { + logger.error("callSocketAdapter error", e); + //throw new Exception(ExceptionUtil.getErrorCode(e, SOCK_CONTROL_ERROR)); + throw e; + } + return resBytes; + } + + private byte[] getItsmSMSMesage(EAIMessage eaimessage) { + byte[] itsmSMSMessage = null; + StringBuilder sb = new StringBuilder(); + try { + // make message from EAIMessage + sb.append(eaimessage.getEAISvcCd()); + itsmSMSMessage = sb.toString().getBytes(); + } + catch(Exception e) { + itsmSMSMessage = sb.toString().getBytes(); + } + return itsmSMSMessage; + } + + /** + * 1. 기능 : 로깅 정보를 로그 Queue로 전달 + * 2. 처리 개요 : + * - 로깅 정보를 로그 Queue로 전달 + * - 실시간 거래 정보 통계를 위해 EAIServiceMonitor로 전달 + * 3. 주의사항 + * + * @param message EAIMessage + * @param prop logging 관련 Properties + * @exception EAILogException + **/ + public void log(EAIMessage message, Properties prop) throws EAILogException { + ++logCount; + int svcLogLvl = message.getSvcLogLvl(); + String svcTsmtUsgTp = message.getSvcTsmtUsgTp(); + int logPssSno = message.getLogPssSno(); + boolean isLogging = false; + + String guidLogPrefix = "DBLogTransactionLogger] GUID[" + + message.getMapper().getGuid(message.getStandardMessage()) + + "] UUID[" + message.getSvcOgNo() + "] "; + + try { + // Direct DB Logging + String logType = "DB"; + String setLogType = PropManager.getInstance().getProperty("LOG_TYPE"); + if(setLogType != null) { + logType = setLogType; + } + + if("DB".equals(logType)) { + insertLog(message, prop); + } + else { + EAIFileLogger.getInstance().setLog(message, prop); + } + //----------------------------------------------------> + // ITSM ERROR Log 전송 + // 템플릿만 남겨두고, 나머지는 사이트에 맞게 수정 필요함. + //----------------------------------------------------> + boolean itsmEnabled = false; + if((itsmEnabled) && !MessageUtil.checkRspErrCd(message.getRspErrCd())) { + if(logger.isDebug()) { + logger.debug(guidLogPrefix + " ITSM Error Message Notify! "); + } + if(( EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && logPssSno == 400 ) || + ( EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && (logPssSno == 200 || logPssSno == 400))) { + String itsmErrorAdapterName = ""; + itsmErrorAdapterName = PropManager.getInstance().getProperty("ITSM_CONFIG","ADAPTER_GROUP_NAME_ERROR"); /* Properties 추가 및 어뎁터 등록 */ + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " ITSM ERROR Send Message Adapter Name[" + itsmErrorAdapterName + "]"); + } + + if(itsmErrorAdapterName != null && itsmErrorAdapterName.length() > 0) { + byte[] itsmSMSMessage = getItsmSMSMesage(message); /* ITSM 전송 메시지 포맷 결정 */ + Properties itsmProp = new Properties(); + callAdapter(itsmErrorAdapterName, itsmProp, itsmSMSMessage); + } + } + } + } catch(Exception e) { + if (logger.isError()) logger.error(guidLogPrefix + " ITSM ERROR Send ERROR " + e.getMessage(),e); + errCount++; + //throw new EAILogException(ExceptionUtil.getErrorCode(e, "RECEAICLG005")); + } + } + + public static void insertLog(EAIMessage eaiMessage, Properties prop) throws EAILogException { + String guidLogPrefix = "DBLogTransactionLogger] GUID["+ eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) + +"] UUID["+eaiMessage.getSvcOgNo()+"] "; + try { + if (EAIDBLogControl.isEnable()){ + try { + EAILogDAO dao = ApplicationContextProvider.getContext().getBean(EAILogDAO.class); + dao.addEAISvcLog(eaiMessage, prop); + } catch(Exception e) { + if (logger.isError()) logger.error(guidLogPrefix +" insertLog DB ERROR. - " + e.getMessage(),e); + // DB Connection Error일 경우에만 설정하도록 수정 + String message = e.getMessage(); + // 오류 메시지 추가 - Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection + // 오류 메시지 추가 - Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection + if( "ConnectionError".equals(message) || StringUtils.contains(message, "JDBCConnectionException") + || StringUtils.contains(message, "Unable to acquire JDBC Connection") ) { + EAIDBLogControl.setEnable(false); + } + //file log + EAIFileLogger.getInstance().setLog(eaiMessage, prop); + throw e; + } + } + else{ + //file log + EAIFileLogger.getInstance().setLog(eaiMessage, prop); + } + + } catch(Exception e) { + if (logger.isError()) logger.error(guidLogPrefix + " insertLog ERROR. - " + e.getMessage(), e); + throw new EAILogException("insertLog ERROR."+ e.getMessage()); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/EAIDBLogControl.java b/src/main/java/com/eactive/eai/common/logger/EAIDBLogControl.java new file mode 100644 index 0000000..a4f8c6a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/EAIDBLogControl.java @@ -0,0 +1,62 @@ +package com.eactive.eai.common.logger; + +import com.eactive.eai.common.dao.DAOFactory; +import com.eactive.eai.common.logger.async.HttpAdapterExtraLogH2Factory; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +/** + * 1. 기능 : DB 장애 상태 관리 + * 2. 처리 개요 : + * 3. 주의사항 + */ +public class EAIDBLogControl { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static boolean isEnable = true; + + private EAIDBLogControl() { + + } + + public static synchronized boolean isEnable() { + return isEnable; + } + + public static synchronized void setEnable(boolean enable) { + if (isEnable == enable) return ; + isEnable = enable; + if (!enable){ + //thread 기동 + Runnable runnable = new Runnable() { + public void run() { + while(true) { + try { + //db check + EAILogDAO dao = ApplicationContextProvider.getContext().getBean(EAILogDAO.class); + + boolean result = dao.getCheck(); + if (result){ + setEnable(result); + // 25.04.29 안해도 정상적으로 Header 정보 저장됨 확인 + // 있으면 오히려 NoClassDefFoundError Exception 발생 +// HttpAdapterExtraLogH2Factory.getInstance().closeSessionFactory(); + break; + } + } catch(Throwable t) { + logger.warn("setEnable", t); + } + try { + Thread.sleep(1000L); + } catch(InterruptedException e) { + logger.warn("sleep", e); + } + } + } + }; + Thread t = new Thread(runnable); + t.setName("DBChecker-Launcher"); + t.start(); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/EAIFileLogger.java b/src/main/java/com/eactive/eai/common/logger/EAIFileLogger.java new file mode 100644 index 0000000..83b593e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/EAIFileLogger.java @@ -0,0 +1,900 @@ +package com.eactive.eai.common.logger; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Properties; + +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.agent.encryption.EncryptionManager; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.message.ServiceMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.LogKeys; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.NullControl; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.transformer.layout.Item; +import com.eactive.eai.transformer.layout.Layout; +import com.eactive.eai.transformer.transform.Transform; +import com.eactive.eai.transformer.transform.TransformManager; +import com.eactive.eai.transformer.util.IConv; +import com.eactive.eai.util.HexaConverter; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +/** +* 1. 기능 : DAO 객체를 생성하기 위한 Factory 클래스 +* 2. 처리 개요 : DAO 객체를 생성하는 Factory 메서드를 정의한다. +* * - +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class EAIFileLogger +{ + private static EAIFileLogger instance ; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static Logger tranLogger = Logger.getLogger(Logger.LOGGER_TRAN); + + private static final String DELIMITER = "#|@"; + private static final String EOL = "EOL$$;"; + + private EAIFileLogger() { + + } + + /** + * 1. 기능 : EAI File Logger 객체를 생성 반환하는 메서드 + * 2. 처리 개요 : EAI File Logger 객체를 생성 반환한다. + * - + * 3. 주의사항 + * + * @return DAOFactory + **/ + public static EAIFileLogger getInstance() { + if (instance == null){ + instance = new EAIFileLogger(); + } + return instance; + } + + /** + * 1. 기능 : 메시지의 Type이 EBCDIC인지 판단 + * 2. 처리 개요 : + * - 로그시퀀스에 맞는 Adapter의 메시지 type을 비교 + * - EBC인지 판별 + * 3. 주의사항 + * + * @param srcIfType String + * @param tgtIfType String + * @param logPssSno int + * @param srcAdapterMsgType String + * @param tgtAdapterMsgType String + * @return boolean + **/ + public boolean isEBC(String srcIfType, String tgtIfType, int logPssSno, + String srcAdapterMsgType, String tgtAdapterMsgType) { + + boolean isEBCDIC = false; + + // SS. SA Type + if(logPssSno == 100) { + if( "EBC".equals(srcAdapterMsgType) ) { + isEBCDIC = true; + } + } + else if(logPssSno == 200) { + if( "EBC".equals(tgtAdapterMsgType) ) { + isEBCDIC = true; + } + } + else if(logPssSno == 300) { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && + EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + if( "EBC".equals(srcAdapterMsgType) ) { + isEBCDIC = true; + } + } + else { + if( "EBC".equals(tgtAdapterMsgType) ) { + isEBCDIC = true; + } + } + } + // 400 + else if(logPssSno == 400) { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && + EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + if( "EBC".equals(tgtAdapterMsgType) ) { + isEBCDIC = true; + } + } + else { + if( "EBC".equals(srcAdapterMsgType) ) { + isEBCDIC = true; + } + } + } + // 900 + else { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && + EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + if( "EBC".equals(tgtAdapterMsgType) ) { + isEBCDIC = true; + } + } + else { + if( "EBC".equals(srcAdapterMsgType) ) { + isEBCDIC = true; + } + } + } + return isEBCDIC; + } + + public boolean isUTF8(String srcIfType, String tgtIfType, int logPssSno, + String srcAdapterMsgEncode, String tgtAdapterMsgEncode) { + boolean isUTF = false; + if (logger.isInfo()) { + logger.info(String.format("EAIFileLogger] isUTF8 %s %s %s %s %s", srcIfType, tgtIfType, logPssSno, srcAdapterMsgEncode, tgtAdapterMsgEncode)); + } + + String adapterMsgEncode = ""; + // SS. SA Type + if(logPssSno == 100) { + adapterMsgEncode = srcAdapterMsgEncode; + } + else if(logPssSno == 200) { + adapterMsgEncode = tgtAdapterMsgEncode; + } + else if(logPssSno == 300) { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && + EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + adapterMsgEncode = srcAdapterMsgEncode; + } + else { + adapterMsgEncode = tgtAdapterMsgEncode; + } + } + // 400 + else if(logPssSno == 400) { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && + EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + adapterMsgEncode = tgtAdapterMsgEncode; + } + else { + adapterMsgEncode = srcAdapterMsgEncode; + } + } + // 900 + else { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && + EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + adapterMsgEncode = tgtAdapterMsgEncode; + } + else { + adapterMsgEncode = srcAdapterMsgEncode; + } + } + isUTF = StringUtils.equalsIgnoreCase(adapterMsgEncode, "UTF-8"); + return isUTF; + } + + protected String removeXMLHeaderAll(String xmlMsg) { + + if(xmlMsg == null) { + return ""; + } + else { + xmlMsg = xmlMsg.trim(); + } + int sPos = xmlMsg.indexOf(""); + int ePos = xmlMsg.indexOf(""); + + // 중간에 있는 경우 - CDATA 의 내용 + if(sPos > -1 && ePos > -1) { + xmlMsg = xmlMsg.substring(sPos+12, ePos); + } + return xmlMsg; + } + +// private String removeXMLRootItem(String xmlString, String rootItemName) { +// String prefix = "<" + rootItemName + ">"; +// String suffix = ""; +// +// int s_idx = xmlString.indexOf(prefix); +// int e_idx = xmlString.indexOf(suffix); +// if (s_idx == -1 || e_idx == -1) { +// return xmlString; +// } else { +// return xmlString.substring(s_idx + prefix.length(), e_idx); +// } +// } + +// private String addJsonRootItem(String jsonString, String rootItemName) { +// JSONObject value = (JSONObject)JSONValue.parse(jsonString); +// JSONObject root = new JSONObject(); +// root.put(rootItemName, value); +// return root.toJSONString(); +// } + +// private String removeJsonRootItem(String jsonString, String rootItemName) { +// JSONObject value = (JSONObject)JSONValue.parse(jsonString); +// JSONObject sub = (JSONObject) value.get(rootItemName); +// return sub.toJSONString(); +// } + + + /** + * 1. 기능 : EAI 서비스 로그 셋팅 + * 2. 처리 개요 : + * - tran.log(EAI서비스로그) 로그값 셋팅 + * 3. 주의사항 + * + * @param message EAIMessage + * @exception DAOException + **/ + public void setLog(EAIMessage message, Properties prop) throws Exception{ + + + // 업무데이터 size 체크하여 업무데이터1,2에 insert하고 + // addBwkDataSub(message) 호출 여부 결정 + + String apndBwkDataYn = "N"; //추가업무데이터 여부 + int dayOfWeek = DatetimeUtil.getDayOfWeekNum(message.getMsgRcvTm()); + + // 개별메시지 +// Object bizMsg = message.getBizMsg()[0]; +// Object bizMsg = message.getExtMsg().getBizData()[0]; + Object bizMsg = message.getStandardMessage().getBizData(); + + ServiceMessage svcMsg = message.getCurrentSvcMsg(); + String bizMsgStr = ""; + + //transformer 적용 + String svcTsmtUsgTp = message.getSvcTsmtUsgTp(); // 기동 Syunc/Async + String psvItfTp = svcMsg.getPsvItfTp(); // 수동 Syunc/Async + int logPssSno = message.getLogPssSno(); + String rspErrCd = message.getRspErrCd(); + + // Duplication Error 방지를 위해 + // 원 로그처리일련번호를 저장 : 2009.07.13 + int orglogPssSno = logPssSno; + +// int svcLogLvl = message.getSvcLogLvl(); + boolean loggingBizData = true; +// if(svcLogLvl > 3) { +// loggingBizData = false; +// } + + if (logger.isWarn()) logger.warn("EAIFileLogger] loggingBizData - " + loggingBizData); + + // 복합거래인 경우 2X1,3X1 -> 200, 2X2,3X2 -> 300 처럼 처리한다. + if( (logPssSno > 200 && logPssSno < 300) + || (logPssSno > 300 && logPssSno < 400) ) { + if( (logPssSno % 2) == 1) { + logPssSno = 200; + } + else { + logPssSno = 300; + } + } + + // 업무테이터 처리 + // 1. Get Source, Target Adapter Group Name + String srcAdapterGroupName = message.getSngSysItfTp(); + String tgtAdapterGroupName = message.getCurrentSvcMsg().getPsvSysItfTp(); + + // 2. Get Source, Target Adapter GroupVO + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO srcAdapterGrpVO = adapterManager.getAdapterGroupVO(srcAdapterGroupName); + AdapterGroupVO tgtAdapterGrpVO = adapterManager.getAdapterGroupVO(tgtAdapterGroupName); + + // 3. Get Source, Target Adapter Message Type + /* + String srcAdapterMsgType = srcAdapterGrpVO.getMessageType(); + String tgtAdapterMsgType = tgtAdapterGrpVO != null ? tgtAdapterGrpVO.getMessageType() : "N/A"; + */ + String srcAdapterMsgType = null; + String tgtAdapterMsgType = null; + //String srcAdptrMsgPtrnCd = null; + String tgtAdptrMsgPtrnCd = null; + + String srcAdapterMsgEncode = null; + String tgtAdapterMsgEncode = null; + +// String s = System.getProperty("os.name"); +// if (s.indexOf("Window") < 0){ + +// srcAdptrMsgPtrnCd = srcAdapterGrpVO.getAdptrMsgPtrnCd(); + if (srcAdapterGrpVO == null){ + srcAdapterMsgType = MessageType.ASC; + srcAdapterMsgEncode = Charset.defaultCharset().name(); + if (logger.isWarn()){ + logger.warn("EAIFileLogger] Source Adapter null. eai service code="+message.getEAISvcCd()); + } + } + else { + srcAdapterMsgType = srcAdapterGrpVO.getMessageType(); + srcAdapterMsgEncode = StringUtils.defaultIfBlank(srcAdapterGrpVO.getMessageEncode(), Charset.defaultCharset().name()); + } + if (tgtAdapterGrpVO == null){ + tgtAdapterMsgType = MessageType.ASC; + tgtAdapterMsgEncode = Charset.defaultCharset().name(); + if (logger.isWarn()){ + logger.warn("EAIFileLogger] Target Adapter null. eai service code="+message.getEAISvcCd()); + } + } + else{ + tgtAdapterMsgType = tgtAdapterGrpVO.getMessageType(); + tgtAdptrMsgPtrnCd = tgtAdapterGrpVO.getAdptrMsgPtrnCd(); + tgtAdapterMsgEncode = StringUtils.defaultIfBlank(tgtAdapterGrpVO.getMessageEncode(), Charset.defaultCharset().name()); + } +// }else{ +// srcAdapterMsgType = MessageType.ASC; +// tgtAdapterMsgType = MessageType.ASC; +// } + + + + String bwkData = ""; + String addBwkData = ""; + String refMsgID = ""; + + if(loggingBizData) { + //--------------------------------------------------- + // LogMasking 을 위해 변환이 등록된 경우에만 + // 변환을 통해 처리하도록 수정 : 20080827 DHLEE + //--------------------------------------------------- + boolean isMasked = false; + boolean isMasking = false; + + // 변환이 등록된 경우 + if ("1".equals(svcMsg.getCnvEn())) { + TransformManager manager = TransformManager.getManager(); + Transform info = null; + Layout l = null; + + // AA - 요청변환에서 + if (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) { + info = manager.getTransform(svcMsg.getCnvMsgID()); //요청변환메시지ID명 + } + // AA이 아닌 경우 + // - 100, 200 요청변환에서 + // - 300, 400 응답변환에서 + else { + if (logPssSno == 100 || logPssSno == 200) { + info = manager.getTransform(svcMsg.getCnvMsgID()); //요청변환메시지ID명 + } else { + if (rspErrCd.equals(EAIMessageKeys.BWK_ERRMSG_CODE)) { //업무에러(RIBEAI999999) + info = manager.getTransform(svcMsg.getErrRspCnvMsgID()); //오류응답변환메시지ID명 + if(info == null) { + info = manager.getTransform(svcMsg.getBsRspCnvMsgID()); //기본응답변환메시지ID명 + } + } else if(MessageUtil.checkRspErrCd(rspErrCd)) { + info = manager.getTransform(svcMsg.getBsRspCnvMsgID()); //기본응답변환메시지ID명 + } + } + } + + // 등록된 변환이 있는 경우 + if (info != null) { + if (logger.isInfo()) logger.info("EAIFileLogger] Masking Log Message - " + message.getEAISvcCd()); + + // 변환은 등록되어 있으나 레이아웃정보가 삭제된 경우 + // 정삭적인 Case 가 아님. + try { + if (logPssSno == 100 || logPssSno == 300 || logPssSno == 900) + l = info.getSourceLayout(0); + else + l = info.getTargetLayout(); + } + catch(Exception e) { + if (logger.isInfo()) logger.info("getTargetLayout error" + e.getMessage()); + } + + // Layout 에 Mask 필드가 없는 경우 SKIP 하도록 한다. + if(l != null) { + try { + Item root = l.getRootItem(); + isMasking = root.existMask(); + } + catch(Exception e) { + if (logger.isWarn()) logger.info("EAIFileLogger] Check Masking field Error - " + e.getMessage()); + isMasking = false; + } + if (logger.isInfo()) logger.info("EAIFileLogger] Message has Masking field [" + l.getName() + "][ " + isMasking+"]"); + } + + if(isMasking) { + try { + bizMsgStr = LogMessageUtil.makeMaskData(message, bizMsg, l, logPssSno,tgtAdptrMsgPtrnCd + , svcTsmtUsgTp, psvItfTp ); + isMasked = true; + } catch(Exception e) { + if (logger.isInfo()) logger.info("EAIFileLogger] LogMasking Error - " + e.getMessage()); + isMasked = false; + } + } + else { + if (logger.isInfo()) { + logger.info("EAIFileLogger] Masking is unnecessary - Skip Masking "); + } + isMasked = false; + } + } + else { + if (logger.isInfo()) { + logger.info("EAIFileLogger] Transform Not Found - Masking Unable"); + } + isMasked = false; + } + // Masking check END + } + +// boolean isUtf8 = isUTF8(svcTsmtUsgTp, psvItfTp, logPssSno, srcAdapterMsgType, tgtAdapterMsgType); + boolean isUtf8 = isUTF8(svcTsmtUsgTp, psvItfTp, logPssSno, srcAdapterMsgEncode, tgtAdapterMsgEncode); + // 요청 변환이 등록되지 않은 경우 또는 Masking 처리를 실패한 경우 + if(!isMasked) { + if (bizMsg == null) { + if (logger.isInfo()) logger.info("EAIFileLogger] Message is NULL"); + bizMsgStr = ""; + } else if (bizMsg instanceof String) { + if (logger.isInfo()) logger.info("EAIFileLogger] Message is String Type"); + bizMsgStr = (String)bizMsg; + } else if (bizMsg instanceof byte[]) { + if(isEBC(svcTsmtUsgTp, psvItfTp, logPssSno, srcAdapterMsgType, tgtAdapterMsgType)) { + if (logger.isInfo()) logger.info("EAIFileLogger] Message is EBCDIC bytes Type"); + try { + bizMsgStr = IConv.ebcdicToASCIIWithSOSIEX( (byte[])bizMsg ); + } catch(Exception ex) { + if (logger.isInfo()) logger.info("EAIFileLogger] 타입변환오류 - " + ex.getMessage()); + bizMsgStr = new String((byte[])bizMsg); + } + } + else if(isUtf8) { + if (logger.isInfo()) logger.info("EAIFileLogger] Message is ASCII-UTF8 bytes Type"); + bizMsgStr = new String((byte[])bizMsg, StandardCharsets.UTF_8); + + } + else { + if (logger.isInfo()) logger.info("EAIFileLogger] Message is ASCII bytes Type"); + bizMsgStr = new String((byte[])bizMsg); +// bizMsgStr = new String((byte[])bizMsg,JSONMessage.encode); + } + } else { + if (logger.isInfo()) logger.info("EAIFileLogger] Message is Object or UNKNOWN Type"); + try { + StringBuilder sbuff = new StringBuilder(); + bizMsgStr = sbuff.append(PropertyUtils.describe(bizMsg)).toString(); + } catch (Exception e) { + if (logger.isWarn()) logger.warn("EAIFileLogger] Object Message Parsing Error - " + e.getMessage()); + } + } + } + //------------------------------------------------------------------------- + + // EAI 업무 개별부(32,000bytes) + /** + * 업무데이터에 대한정의 + * 1. biz 데이터 + * 2. 표준전문 JSON 데이터 + * 3. 전장표 + */ + StringBuilder sb = new StringBuilder(); + String biz =""; +// String header = ExtMessageConverter.getSTDLog(message.getExtMsg()); + String header = message.getStandardMessage().toFixedString(false); + //20220405 +// String header = ""; +// if (logPssSno ==100 || logPssSno ==300){ +// header = ExtMessageConverter.getOriginalSTDLog(message.getExtMsg()); +// }else{ +// header = ExtMessageConverter.getSettingSTDLog(message.getExtMsg()); +// } + String mdclData =""; + if (bizMsgStr == null) { + bizMsgStr = ""; + } + + //전장표 데이터부 JSON Array로 저장 + //암호화 + Charset hexaCharset = Charset.forName("euc-kr"); + if("Y".equalsIgnoreCase(EncryptionManager.getInstance().getEncryptYN()) ){ + try{ + biz = HexaConverter.bytesToHexa(bizMsgStr.getBytes(hexaCharset)); + }catch(Exception e){ + logger.error("EAIFileLogger] bizMsgStr encryption Error - " + e.getMessage()); + } + try{ + header = HexaConverter.bytesToHexa(header.getBytes(hexaCharset)); + }catch(Exception e){ + logger.error("EAIFileLogger] header encryption Error - " + e.getMessage()); + } + try{ + mdclData = HexaConverter.bytesToHexa(mdclData.getBytes(hexaCharset)); + }catch(Exception e){ + logger.error("EAIFileLogger] mdclData encryption Error - " + e.getMessage()); + } + + }else { + biz = bizMsgStr; + } + + //임시코드 시작 + String logType = PropManager.getInstance().getProperty("BIZ_LOG_TYPE"); + if (!StringUtils.isBlank(logType)){ + if ("ALL".equals(logType)){ + sb.append(header).append("|").append(biz).append("|").append(mdclData); + }else if ("HEADER".equals(logType)){ + sb.append(header).append("|").append("|"); + }else if ("BODY".equals(logType)){ + sb.append("|").append(biz).append("|"); + }else if ("NONE".equals(logType)){ + sb.append("|").append("|"); + } + }else{ + sb.append(header).append("|").append(biz).append("|").append(mdclData); + } + + //임시코드 종료 + + // File은 전체전문을 남기도록 한다. + String tmpStr = sb.toString(); + bwkData = tmpStr.length() > 4000 ? StringUtils.substring(tmpStr, 0, 4000) : tmpStr; + addBwkData = tmpStr.length() > 4000 ? StringUtils.substring(tmpStr, 4000) : ""; + + // 업무데이터 사이즈가 4000byte 이상이면 추가업무데이터 테이블에 insert + if (!"".equals(addBwkData)) + apndBwkDataYn = "Y"; + + String[] refMsgIDs = svcMsg.getRefMsgIDs(); + + // 입력메시지IDS 배열은 delimiter로 구분하여 200byte 만 insert + StringBuilder sbMsgIds = new StringBuilder(); + if (refMsgIDs != null && refMsgIDs.length > 0) { + for (int i = 0; i < refMsgIDs.length - 1; i++) { + sbMsgIds.append(refMsgIDs[i]).append(", "); + } + sbMsgIds.append(refMsgIDs[refMsgIDs.length - 1]); + refMsgID = sbMsgIds.toString(); + + if (refMsgID.getBytes().length > 200) { + refMsgID = StringUtil.chunkString(refMsgID, 200); + } + } + } // 업무데이터 로깅을 할 경우에만 END loggingBizData + +// ExtMessage extMessage = message.getExtMsg(); + + // 메시지수신시각으로 테이블명 설정 +// int dayOfWeek = DatetimeUtil.getDayOfWeekNum(message.getMsgRcvTm()); + + + try { + // 1/1000초로 변경 + //String msgPssTm = DatetimeUtil.getTimeCenti(message.getMsgPssTm()); + String msgPssTm = DatetimeUtil.getCurrentTime(message.getMsgPssTm()); + + CustomStringBuffer sb = new CustomStringBuffer(DELIMITER); + + String serverName = EAIServerManager.getInstance().getLocalServerName(); + String serverGroupName = EAIServerManager.getInstance().getServerType(); + + // EAI 업무 공통부(100 bytes) + sb.appendAndDelimeter( NullControl.addSpace(message.getBwkCls())); //EAI업무구분코드 + sb.appendAndDelimeter( DatetimeUtil.getCurrentTime(message.getMsgRcvTm())); //메시지수신시각 + sb.appendAndDelimeter( NullControl.addSpace(message.getSvcOgNo())); //EAI서비스일련번호 + + // 2009.07.13 공동망 통신망관련 수정 - 로그 저장시 원 로그처리일련번호를 저장 +// sb.appendAndDelimeter(4, String.valueOf(logPssSno)); //로그처리일련번호 + sb.appendAndDelimeter( String.valueOf(orglogPssSno)); //로그처리일련번호 + +// sb.appendAndDelimeter(5, NullControl.addSpace(message.getEAISvrInstNm())); //EAI서버인스탄스명 + sb.appendAndDelimeter( NullControl.addSpace(serverName)); //EAI서버인스탄스명 + + sb.appendAndDelimeter( NullControl.addSpace(message.getEAISvcCd())); //EAI서비스명 + sb.appendAndDelimeter( NullControl.addSpace(message.getSvcTmEn())); //서비스시각유무 + sb.appendAndDelimeter( NullControl.addSpace(message.getSvcTsmtUsgTp())); //서비스동기사용구분코드 + sb.appendAndDelimeter( NullControl.addSpace(message.getSvcPssTp())); //서비스처리구분명 + sb.appendAndDelimeter( NullControl.addSpace(message.getFlwCntlRtnNm())); //흐름통제라우팅명 + //index 10 + + sb.appendAndDelimeter( NullControl.addSpace(message.getUnifTp())); //통합구분명 + sb.appendAndDelimeter( NullControl.addSpace(message.getSngSvcCls())); //기동서비스구분명 + sb.appendAndDelimeter( String.valueOf(message.getSvcPssSeq())); //서비스처리번호 + sb.appendAndDelimeter( NullControl.addSpace(message.getSvcWlColLogYn())); //서비스전컬럼로그여부 + sb.appendAndDelimeter( NullControl.addSpace(message.getStdMsgUsgCls())); //표준메시지사용여부 + + sb.appendAndDelimeter( NullControl.addSpace(message.getSngSysItfTp())); //기동시스템어댑터업무그룹명 + sb.appendAndDelimeter( NullControl.addSpace(message.getLydMsgID())); //현재메시지ID명 + sb.appendAndDelimeter( NullControl.addSpace(message.getRspErrCd())); //응답에러코드명 + sb.appendAndDelimeter( msgPssTm); //메시지처리시각 + sb.appendAndDelimeter( String.valueOf(message.getSvrLogLvl())); //서버로그레벨번호 + //index 20 + + sb.appendAndDelimeter( String.valueOf(message.getSvcLogLvl())); //서비스로그레벨번호 + sb.appendAndDelimeter( NullControl.addSpace(message.getErrEAISvcName())); //오류EAI서비스명 + sb.appendAndDelimeter( NullControl.addSpace(message.getDmndErrChngIDName())); //요청오류변환ID명 + sb.appendAndDelimeter( NullControl.addSpace(message.getDmndErrFldName())); //요청에러필드명 + sb.appendAndDelimeter( NullControl.addSpace(message.getRspnsErrChngIDName())); //응답오류변환ID명 + + sb.appendAndDelimeter( NullControl.addSpace(message.getRspnsErrFldName())); //응답에러필드명 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getPsvItfTp())); //수동인터페이스구분명 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getPsvBwkSysNm())); //수동업무시스템명 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getPsvSysID())); //수동시스템ID명 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getPsvSysSvcCd())); //수동시스템서비스구분명 + //index 30 + + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getPsvSysItfTp())); //수동시스템어댑터업무그룹명 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getFlOvrCls())); //장애극복여부 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getCnvEn())); //변환여부 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getCnvMsgID())); //변환메시지ID명 + sb.appendAndDelimeter( NullControl.addSpace(refMsgID)); //입력메시지ID명 + + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getBsRspMsgCprVl())); //기본응답메시지비교내용 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getBsRspCnvEn())); //기본응답변환여부 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getBsRspCnvMsgID())); //기본응답변환메시지ID명 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getErrRspMsgCprVl())); //오류응답메시지비교내용 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getErrRspCnvEn())); //오류응답변환여부 + //index 40 + + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getErrRspCnvMsgID())); //오류응답변환메시지ID명 + sb.appendAndDelimeter( String.valueOf(svcMsg.getNxtSvcPssSeq())); //다음서비스처리번호 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getOutbRtnNm())); //아웃바운드라우팅명 + sb.appendAndDelimeter(svcMsg.getTmoVl()); //타임아웃값 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getCpnsSvcPssCd())); //보상서비스처리명 + + sb.appendAndDelimeter( NullControl.addSpace(apndBwkDataYn)); //추가업무데이터여부 + sb.appendAndDelimeter( NullControl.addSpace(svcMsg.getKeyMgtMsgVl())); //키관리메시지내용 + + + // SS,SA - Send - 100 + // AA - Send - 100 + // AA - Recv - 100, 300 + // AS - 100 +// String telgmDmndDstcd = kbheader.getTelgmDmndDstcd(); +// String telgmDmndDstcd = message.getExtMsg().getSendRecv(); + String telgmDmndDstcd = message.getMapper().getSendRecvDivision(message.getStandardMessage()); // S|R + if (prop != null && + ((EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) + && logPssSno == 100) + || (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) + && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp) + && STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd) + && (logPssSno == 100 || logPssSno == 300)) + || (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) + && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp) + && STDMessageKeys.SEND_RECV_CD_SEND.equals(telgmDmndDstcd) + && logPssSno == 100) + || (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) + && EAIMessageKeys.SYNC_SVC.equals(psvItfTp) + && logPssSno == 100))) { + + sb.appendAndDelimeter( NullControl.addSpace(prop.getProperty(Keys.LOG_ALT_KEY1))); //추적보조키1내용 + sb.appendAndDelimeter( NullControl.addSpace(prop.getProperty(Keys.LOG_ALT_KEY2))); //추적보조키2내용 + + sb.appendAndDelimeter( NullControl.addSpace(prop.getProperty(Keys.LOG_ALT_KEY3))); //추적보조키3내용 + sb.appendAndDelimeter( NullControl.addSpace(prop.getProperty(Keys.LOG_ALT_KEY4))); //추적보조키4내용 + } else { + sb.appendAndDelimeter( " "); //추적보조키1내용 + sb.appendAndDelimeter( " "); //추적보조키2내용 + sb.appendAndDelimeter( " "); //추적보조키3내용 + sb.appendAndDelimeter( " "); //추적보조키4내용 + } + //index 51 + + sb.appendAndDelimeter( NullControl.addSpace(message.getGroupCoCd())); //EAI서비스코드의 그룹회사코드 + +// sb.appendAndDelimeter( kbheader.getGuIdNo().substring(0,33)); // PGUID +// sb.appendAndDelimeter( extMessage.getGuid()); // PGUID + sb.appendAndDelimeter( message.getMapper().getGuid(message.getStandardMessage())); // PGUID + + sb.appendAndDelimeter( message.getTranType()); // 거래처리구분 + sb.appendAndDelimeter( NullControl.addSpace(message.getRspnsChngMsgType())); // 응답변환유형 + + // log level 'E' or 'F' + if ("E".equals(message.getRspErrCd().substring(1, 2)) || "F".equals(message.getRspErrCd().substring(1, 2))) { + sb.appendAndDelimeter( NullControl.addSpace(message.getRspErrCd())); //EAI에러코드 + sb.appendAndDelimeter( StringUtil.chunkString(message.getRspErrMsg(),1000)); //EAI에러내용 + } + else { + sb.appendAndDelimeter( " "); //EAI에러코드 + sb.appendAndDelimeter( " "); //EAI에러내용 + } + + //juns 서버명 변경에 따른 인스턴스 룰 추출변경 + //ex)EAIDSG_i11 => EAIDS01_i01 + //sb.appendAndDelimeter( serverName.substring(3, 6)); //서버그룹명 + sb.appendAndDelimeter( serverGroupName); //서버그룹명 + + sb.appendAndDelimeter( NullControl.addSpace(message.getCompanyCode()) ); //업체코드, add 20190625 + sb.appendAndDelimeter( message.getSplizLength()); //전문크기, add 20190625 + //index 60 + + sb.appendAndDelimeter( NullControl.addSpace(message.getAdptrInstiCode())); // add 20190404 // adapterNickName + sb.appendAndDelimeter( NullControl.addSpace(message.getTxId()));// add 20210331 //TODO 거래ID + sb.appendAndDelimeter( NullControl.addSpace(message.getRefKey()));// add 20210331 //TODO 참조ID + sb.appendAndDelimeter( NullControl.addSpace(message.getExtBizCd()));// add 20210402 //TODO 대외업무구분코드 + // EAI 업무 개별부(32,000bytes) + // 전체업무데이터를 HEXA String 으로 변경해서 저장한다. (newline 등의 문제로) + // Read시에는 HexaConverter.hexaToBytes 를 사용 +// String hexaData = HexaConverter.bytesToHexa(bizMsgStr.getBytes()); +// sb.appendAndDelimeter(hexaData); + // 에러메시지에도 newline이 있을 수 있으므로 다른 방안으로 처리 (2019.06.25) + // - EOL 라인을 추가한다. + if(bwkData == null || bwkData.equals("")) + bwkData = " "; + sb.appendAndDelimeter(bwkData); + + String standardLayoutName = System.getProperty("STANDARD_LAYOUT_NAME"); + sb.appendAndDelimeter( NullControl.addSpace(standardLayoutName)); + sb.appendAndDelimeter( NullControl.addSpace(message.getClientId())); + + // DATA에 NewLine이 있을 경우가 있으므로 + // 데이터 라인 마지막에 추가하여 Loading 시에 EOL로 시작하는 라인이 올때까지 읽도록 처리해야 함. + // 데이터룰 HEXA로 저장하므로 필요없음 + sb.append("\n"+EOL); + +// tranLogger.info(sb.toString()); + // 2025.04.10 tran.log 생성 로그 레벨 변경 info -> error + tranLogger.error(sb.toString()); + +// String sLogDirectory = PropManager.getInstance().getProperty(LogKeys.LOGGER_INFO, LogKeys.LOG_DIRECOTRY_PREFIX); +// String localServer = EAIServerManager.getInstance().getLocalServerName(); +// String type = "TSEAILG1" + dayOfWeek; +// String serialNo = message.getSvcOgNo(); +// String logSeq = String.valueOf(message.getSvcPssSeq()); +// String logPath = sLogDirectory + localServer + File.separator + type + File.separator + serialNo+ File.separator; +// +// FileWrite(logPath, logSeq, sb.toString()); + + if ("Y".equals(apndBwkDataYn)) { + addBwkDataSub(message, addBwkData, dayOfWeek); // 업무데이터서브 + } + } catch(Exception e) { +// logger.error("File Logging[MASTER] Failed - " + message.getEAISvcCd() + "|" + orglogPssSno +// + "|" + message.getSvcOgNo() + "|" + kbheader.getGuIdNo()); + logger.error("File Logging[MASTER] Failed - " + message.getEAISvcCd() + "|" + orglogPssSno + + "|" + message.getSvcOgNo() + "|" + message.getMapper().getGuid(message.getStandardMessage())); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLG001")); + } + } + /** + * 1. 기능 : 업무데이터 서브 로그 셋팅 + * 2. 처리 개요 :info[3] + * - TSEAILG03(EAI로그업무데이터서브정보) 로그값 셋팅 + * - 매 4000byte 마다 row 증가 + * 3. 주의사항 + * + * @param message EAIMessage + * @param subBizMsgStr 추가 업무 데이터 + * @exception DAOException + **/ + public void addBwkDataSub(EAIMessage message, String subBizMsgStr, int dayOfWeek) { + + try { + String sLogDirectory = PropManager.getInstance().getProperty(LogKeys.LOGGER_INFO, LogKeys.LOG_DIRECOTRY_PREFIX); + String localServer = EAIServerManager.getInstance().getLocalServerName(); + String type = "TSEAILG2" + dayOfWeek; + String serialNo = message.getSvcOgNo(); + String logSeq = String.valueOf(message.getLogPssSno()); + String logPath = sLogDirectory + localServer + File.separator + type + File.separator + serialNo + File.separator; + + FileWrite(logPath, logSeq, subBizMsgStr); + }catch(Exception e) { + logger.error("Log Sub Data write error.",e); + } + } + + /** + * 1. 기능 : 모니터링을 위한 별도의 에러로그테이블에 에러정보를 저정 + * 2. 처리 개요 : + * - TSEAILG03(EAI로그업무데이터서브정보) 로그값 셋팅 + * 3. 주의사항 + * + * @param message EAIMessage + * @exception DAOException + **/ + public void addErrorLog(EAIMessage message, int dayOfWeek) { + + try { + CustomStringBuffer sb = new CustomStringBuffer(); + String serverName = EAIServerManager.getInstance().getLocalServerName(); + + sb.appendAndDelimeter(message.getBwkCls()); //EAI업무구분코드 + sb.appendAndDelimeter(DatetimeUtil.getCurrentTime(message.getMsgRcvTm())); //메시지수신시각 + sb.appendAndDelimeter(message.getSvcOgNo()); //EAI거래일련번호 + sb.appendAndDelimeter(String.valueOf(message.getLogPssSno())); //로그처리일련번호 + + sb.appendAndDelimeter(message.getEAISvcCd()); //EAI서비스명 + sb.appendAndDelimeter(message.getRspErrCd()); //응답에러코드명 + + sb.appendAndDelimeter(message.getSngSysItfTp()); //기동시스템어댑터업무그룹명 + sb.appendAndDelimeter(message.getCurrentSvcMsg().getPsvSysItfTp()); //수동시스템어댑터업무그룹명 + + if ("E".equals(message.getRspErrCd().substring(1, 2)) || "F".equals(message.getRspErrCd().substring(1, 2))) { + sb.appendAndDelimeter(NullControl.addSpace(message.getRspErrCd())); //EAI에러코드 + sb.appendAndDelimeter(StringUtil.chunkString(message.getRspErrMsg(),500)); //EAI에러내용 + } + else { + sb.appendAndDelimeter(" "); //EAI에러코드 + sb.appendAndDelimeter(" "); //EAI에러내용 + } + + sb.appendAndDelimeter(NullControl.addSpace(serverName)); //EAI서버인스턴스명 + sb.appendAndDelimeter(NullControl.addSpace(EAIServerManager.getInstance().getEAIServer(serverName).getHostName())); //로깅시스템ID + sb.appendAndDelimeter(DatetimeUtil.getCurrentTime(message.getMsgPssTm())); // 메시지처리일시 + + // TODO DB 필드매핑 2010.12.21 + sb.appendAndDelimeter(message.getGroupCoCd()); // EAI그룹회사코드 + + + String sLogDirectory = PropManager.getInstance().getProperty(LogKeys.LOGGER_INFO, LogKeys.LOG_DIRECOTRY_PREFIX); + String localServer = EAIServerManager.getInstance().getLocalServerName(); + String type = "TSEAILG3" + dayOfWeek; + String serialNo = message.getSvcOgNo(); + String logSeq = String.valueOf(message.getLogPssSno()); + String logPath = sLogDirectory + localServer + File.separator + type + File.separator + serialNo + File.separator; + + FileWrite(logPath, logSeq, sb.toString()); + } catch(Exception e) { + logger.error("Error Log Data write error.",e); + } + } + + public void FileWrite(String path, String fileName, String data)throws Exception{ + File directory = new File(path); + directory.setWritable(true,false); + directory.setReadable(true,false); + directory.setExecutable(true,true); + if (!directory.exists()){ + if (!directory.mkdirs()){ + throw new Exception("디렉토리 생성 오류입니다."+path); + } + } + + File file = new File(path+fileName); + FileOutputStream os = null; + BufferedOutputStream bos = null; + try { + os = new FileOutputStream(file); + bos = new BufferedOutputStream(os); + bos.write(data.getBytes()); + bos.flush(); + file.setWritable(true,false); + file.setReadable(true,false); + file.setExecutable(true,true); + + if (logger.isDebugEnabled()){ + logger.debug(data); + } + } + catch(Exception ex) { + logger.error("file error", ex); + throw ex; + } + finally { + try { if(bos != null) bos.close(); } catch(Exception e) {} + try { if(os != null) os.close(); } catch(Exception e) {} + } + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java new file mode 100644 index 0000000..86612cd --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/EAILogDAO.java @@ -0,0 +1,843 @@ +package com.eactive.eai.common.logger; + +import java.nio.charset.Charset; +import java.util.Properties; + +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.authserver.vo.ClientVO; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.agent.encryption.EncryptionManager; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.logger.EAILogLogger; +import com.eactive.eai.common.logger.StatAdapterLogLogger; +import com.eactive.eai.common.logger.StatLogLogger; +import com.eactive.eai.common.logger.StatTranLogLogger; +import com.eactive.eai.common.logger.SubMessageLogLogger; +import com.eactive.eai.common.logger.mapper.StatAdapterLogMapper; +import com.eactive.eai.common.logger.mapper.StatLogMapper; +import com.eactive.eai.common.logger.mapper.StatTranLogMapper; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.message.ServiceMessage; +import com.eactive.eai.common.monitor.StatMonitorLogVO; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.server.loader.EAIServerLoader; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.data.RollingTable; +import com.eactive.eai.data.entity.onl.logger.EAIErrorLog; +import com.eactive.eai.data.entity.onl.logger.EAIErrorLogId; +import com.eactive.eai.data.entity.onl.logger.EAILog; +import com.eactive.eai.data.entity.onl.logger.EAILogId; +import com.eactive.eai.data.entity.onl.logger.StatAdapterLog; +import com.eactive.eai.data.entity.onl.logger.StatLog; +import com.eactive.eai.data.entity.onl.logger.StatTranLog; +import com.eactive.eai.data.entity.onl.logger.SubMessageLog; +import com.eactive.eai.data.entity.onl.logger.SubMessageLogId; +import com.eactive.eai.message.EncodingVar; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.transformer.layout.Item; +import com.eactive.eai.transformer.layout.Layout; +import com.eactive.eai.transformer.transform.Transform; +import com.eactive.eai.transformer.transform.TransformManager; +import com.eactive.eai.util.HexaConverter; +import com.ext.eai.common.stdmessage.STDMessageKeys; + + +@Service +@Transactional +public class EAILogDAO { +//extends BaseDAO { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private ApplicationContext applicationContext; + + @Autowired + private EAILogLogger eaiLogEntityService; + + @Autowired + private SubMessageLogLogger subMessageLogLogger; + + @Autowired + private StatLogLogger statLogLogger; + + @Autowired + private StatTranLogLogger statTranLogLogger; + + @Autowired + private StatAdapterLogLogger statAdapterLogLogger; + + @Autowired + private StatLogMapper statLogMapper; + + @Autowired + private StatTranLogMapper statTranLogMapper; + + @Autowired + private StatAdapterLogMapper statAdapterLogMapper; + + @Autowired + private EAIServerLoader eaiServerEntityService; + + public EAILogDAO() { + // empty + } + + /** + * 1. 기능 : 메시지의 Type이 EBCDIC인지 판단 2. 처리 개요 : - 로그시퀀스에 맞는 Adapter의 메시지 type을 비교 - + * EBC인지 판별 3. 주의사항 + * + * @param srcIfType String + * @param tgtIfType String + * @param logPssSno int + * @param srcAdapterMsgType String + * @param tgtAdapterMsgType String + * @return boolean + **/ + public boolean isEBC(String srcIfType, String tgtIfType, int logPssSno, String srcAdapterMsgType, + String tgtAdapterMsgType) { + + boolean isEBCDIC = false; + + // SS. SA Type + if (logPssSno == 100) { + if (MessageType.EBC.equals(srcAdapterMsgType)) { + isEBCDIC = true; + } + } else if (logPssSno == 200) { + if (MessageType.EBC.equals(tgtAdapterMsgType)) { + isEBCDIC = true; + } + } else if (logPssSno == 300) { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + if (MessageType.EBC.equals(srcAdapterMsgType)) { + isEBCDIC = true; + } + } else { + if (MessageType.EBC.equals(tgtAdapterMsgType)) { + isEBCDIC = true; + } + } + } + // 400 + else if (logPssSno == 400) { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + if (MessageType.EBC.equals(tgtAdapterMsgType)) { + isEBCDIC = true; + } + } else { + if (MessageType.EBC.equals(srcAdapterMsgType)) { + isEBCDIC = true; + } + } + } + // 900 + else { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + if (MessageType.EBC.equals(tgtAdapterMsgType)) { + isEBCDIC = true; + } + } else { + if (MessageType.EBC.equals(srcAdapterMsgType)) { + isEBCDIC = true; + } + } + } + return isEBCDIC; + } + + public boolean isUTF8(String srcIfType, String tgtIfType, int logPssSno, String srcAdapterMsgEncode, + String tgtAdapterMsgEncode) { + boolean isUTF = false; + if (logger.isInfo()) { + logger.info(String.format("EAILogDAO] isUTF8 %s %s %s %s %s", srcIfType, tgtIfType, logPssSno, + srcAdapterMsgEncode, tgtAdapterMsgEncode)); + } + + String adapterMsgEncode = ""; + // SS. SA Type + if (logPssSno == 100) { + adapterMsgEncode = srcAdapterMsgEncode; + } else if (logPssSno == 200) { + adapterMsgEncode = tgtAdapterMsgEncode; + } else if (logPssSno == 300) { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + adapterMsgEncode = srcAdapterMsgEncode; + } else { + adapterMsgEncode = tgtAdapterMsgEncode; + } + } + // 400 + else if (logPssSno == 400) { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + adapterMsgEncode = tgtAdapterMsgEncode; + } else { + adapterMsgEncode = srcAdapterMsgEncode; + } + } + // 900 + else { + if (EAIMessageKeys.ASYNC_SVC.equals(srcIfType) && EAIMessageKeys.ASYNC_SVC.equals(tgtIfType)) { + adapterMsgEncode = tgtAdapterMsgEncode; + } else { + adapterMsgEncode = srcAdapterMsgEncode; + } + } + isUTF = StringUtils.equalsIgnoreCase(adapterMsgEncode, "UTF-8"); + return isUTF; + } + + /** + * 1. 기능 : EAI 서비스 로그 셋팅 2. 처리 개요 : - TSEAILG01(EAI서비스로그) 로그값 셋팅 - + * TSEAILG03(EAI로그업무데이터서브정보) insert 여부 결정 3. 주의사항 + * + * @param message EAIMessage + * @exception DAOException + **/ + public void addEAISvcLog(EAIMessage message, Properties prop) throws Exception { + String apndBwkDataYn = "N"; // 추가업무데이터 여부 + + // 개별메시지 + String bizMsg = message.getStandardMessage().getBizData(); + + ServiceMessage svcMsg = message.getCurrentSvcMsg(); + String bizMsgStr = ""; + + // transformer 적용 + String svcTsmtUsgTp = message.getSvcTsmtUsgTp(); // 기동 Syunc/Async + String psvItfTp = svcMsg.getPsvItfTp(); // 수동 Syunc/Async + int logPssSno = message.getLogPssSno(); + String rspErrCd = message.getRspErrCd(); + + // Duplication Error 방지를 위해 + // 원 로그처리일련번호를 저장 : 2009.07.13 + int orglogPssSno = logPssSno; + + int svcLogLvl = message.getSvcLogLvl(); + boolean loggingBizData = true; + + // 특정거래에 대해 업무데이터를 저외함. + if (svcLogLvl > 3) { + loggingBizData = false; + } + if (logger.isWarn()) + logger.warn("EAILogDAO] loggingBizData - " + loggingBizData); + + // 복합거래인 경우 2X1,3X1 -> 200, 2X2,3X2 -> 300 처럼 처리한다. + if ((logPssSno > 200 && logPssSno < 300) || (logPssSno > 300 && logPssSno < 400)) { + if ((logPssSno % 2) == 1) { + logPssSno = 200; + } else { + logPssSno = 300; + } + } + + // 업무테이터 처리 + // 1. Get Source, Target Adapter Group Name + String srcAdapterGroupName = message.getSngSysItfTp(); + String tgtAdapterGroupName = message.getCurrentSvcMsg().getPsvSysItfTp(); + + // 2. Get Source, Target Adapter GroupVO + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO srcAdapterGrpVO = adapterManager.getAdapterGroupVO(srcAdapterGroupName); + AdapterGroupVO tgtAdapterGrpVO = adapterManager.getAdapterGroupVO(tgtAdapterGroupName); + + // 3. Get Source, Target Adapter Message Type + String srcAdapterMsgType = null; + String srcAdptrMsgPtrnCd = null; + String tgtAdapterMsgType = null; + String tgtAdptrMsgPtrnCd = null; + + String srcAdapterMsgEncode = null; + String tgtAdapterMsgEncode = null; + + if (srcAdapterGrpVO == null) { + srcAdapterMsgType = MessageType.ASC; + srcAdapterMsgEncode = Charset.defaultCharset().name(); + if (logger.isWarn()) { + logger.warn("EAILogDAO] Source Adapter null. eai service code=" + message.getEAISvcCd()); + } + } else { + srcAdapterMsgType = srcAdapterGrpVO.getMessageType(); + srcAdptrMsgPtrnCd = srcAdapterGrpVO.getAdptrMsgPtrnCd(); + srcAdapterMsgEncode = StringUtils.defaultIfBlank(srcAdapterGrpVO.getMessageEncode(), + Charset.defaultCharset().name()); + } + + if (tgtAdapterGrpVO == null) { + tgtAdapterMsgType = MessageType.ASC; + tgtAdapterMsgEncode = Charset.defaultCharset().name(); + if (logger.isWarn()) { + logger.warn("EAILogDAO] Target Adapter null. eai service code=" + message.getEAISvcCd()); + } + } else { + tgtAdapterMsgType = tgtAdapterGrpVO.getMessageType(); + tgtAdptrMsgPtrnCd = tgtAdapterGrpVO.getAdptrMsgPtrnCd(); + tgtAdapterMsgEncode = StringUtils.defaultIfBlank(tgtAdapterGrpVO.getMessageEncode(), + Charset.defaultCharset().name()); + } + + // SUBSTANDARD Logging + StandardMessage subMessage = message.getSubMessage(); + boolean isSubLogging = false; + if(subMessage != null) { + isSubLogging = checkSubLogging(svcTsmtUsgTp, psvItfTp, srcAdptrMsgPtrnCd, tgtAdptrMsgPtrnCd, logPssSno); + if (logger.isDebug()) { + logger.debug( String.format("EAILogDAO] SUBSTANDARD-LOGGING checkSubLogging %s-%s %s-%s %d => %s", + svcTsmtUsgTp, psvItfTp, srcAdptrMsgPtrnCd, tgtAdptrMsgPtrnCd, logPssSno, isSubLogging) ); + } + } + if(isSubLogging) { + String headerData = subMessage.toFixedString(false, EncodingVar.flatEncoding); + if (logger.isDebug()) { + logger.debug( String.format("EAILogDAO] SUBSTANDARD-LOGGING UUID: %s, LOGSEQ: %s, HEADER: %s", + message.getSvcOgNo(), logPssSno, headerData) ); + } + try { + String layoutName = StandardMessageManager.getInstance().getVersionLayoutName(); + + SubMessageLog subMessageLog = (SubMessageLog) applicationContext.getBean(RollingTable.class, SubMessageLog.class, + message.getMsgRcvTm()); + SubMessageLogId subLogId = new SubMessageLogId(); + subMessageLog.setId(subLogId); + subLogId.setEaisvcserno(message.getSvcOgNo()); + subLogId.setLogprcssserno(String.valueOf(orglogPssSno)); + subMessageLog.setLayoutname(layoutName); + subMessageLog.setHeaderdata(headerData); + subMessageLogLogger.save(subMessageLog); + } + catch(Exception ex) { + logger.error( String.format("EAILogDAO] SUBSTANDARD-LOGGING ERROR UUID: %s, LOGSEQ: %s, HEADER: %s", + message.getSvcOgNo(), logPssSno, headerData), ex); + } + } + + String bwkData = ""; + String addBwkData = ""; + String refMsgID = ""; + + if (loggingBizData) { + // --------------------------------------------------- + // LogMasking 을 위해 변환이 등록된 경우에만 + // 변환을 통해 처리하도록 수정 + // --------------------------------------------------- + boolean isMasked = false; + boolean isMasking = false; + + // 변환이 등록된 경우 + if ("1".equals(svcMsg.getCnvEn())) { + TransformManager manager = TransformManager.getManager(); + Transform info = null; + Layout l = null; + + // AA - 요청변환에서 + if (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) { + info = manager.getTransform(svcMsg.getCnvMsgID()); // 요청변환메시지ID명 + } + // AA이 아닌 경우 + // - 100, 200 요청변환에서 + // - 300, 400 응답변환에서 + else { + if (logPssSno == 100 || logPssSno == 200) { + info = manager.getTransform(svcMsg.getCnvMsgID()); // 요청변환메시지ID명 + } else { + if (rspErrCd.equals(EAIMessageKeys.BWK_ERRMSG_CODE)) { // 업무에러(RIBEAI999999) + info = manager.getTransform(svcMsg.getErrRspCnvMsgID()); // 오류응답변환메시지ID명 + if (info == null) { + info = manager.getTransform(svcMsg.getBsRspCnvMsgID()); // 기본응답변환메시지ID명 + } + } else if (MessageUtil.checkRspErrCd(rspErrCd)) { + info = manager.getTransform(svcMsg.getBsRspCnvMsgID()); // 기본응답변환메시지ID명 + } + } + } + + // 등록된 변환이 있는 경우 + if (info != null) { + if (logger.isInfo()) + logger.info("EAILogDAO] Masking Log Message - " + message.getEAISvcCd()); + + // 변환은 등록되어 있으나 레이아웃정보가 삭제된 경우 + // 정삭적인 Case 가 아님. + try { + if (logPssSno == 100 || logPssSno == 300 || logPssSno == 900) + l = info.getSourceLayout(0); + else + l = info.getTargetLayout(); + } catch (Exception e) { + if (logger.isInfo()) + logger.info("EAILogDAO] Layout not set"); + } + + // Layout 에 Mask 필드가 없는 경우 SKIP 하도록 한다. + if (l != null) { + try { + Item root = l.getRootItem(); + isMasking = root.existMask(); + } catch (Exception e) { + if (logger.isWarn()) + logger.info("EAILogDAO] Check Masking field Error - " + e.getMessage()); + isMasking = false; + } + if (logger.isInfo()) + logger.info( + "EAILogDAO] Message has Masking field [" + l.getName() + "][ " + isMasking + "]"); + } + + if (isMasking) { + try { + bizMsgStr = LogMessageUtil.makeMaskData(message, bizMsg, l, logPssSno, tgtAdptrMsgPtrnCd, + svcTsmtUsgTp, psvItfTp); + isMasked = true; + } catch (Exception e) { + if (logger.isWarn()) + logger.warn("EAILogDAO] LogMasking Error - " + e.getMessage(), e); + isMasked = false; + } + } else { + if (logger.isInfo()) + logger.info("EAILogDAO] Masking is unnecessary - Skip Masking "); + + isMasked = false; + } + } else { + if (logger.isInfo()) + logger.info("EAILogDAO] Transform Not Found - Masking Unable"); + isMasked = false; + } + // Masking check END + } + +// boolean isUtf8 = isUTF8(svcTsmtUsgTp, psvItfTp, logPssSno, srcAdapterMsgEncode, tgtAdapterMsgEncode); + // 요청 변환이 등록되지 않은 경우 또는 Masking 처리를 실패한 경우 + if (!isMasked) { + if (bizMsg == null) { + if (logger.isInfo()) + logger.info("EAILogDAO] Message is NULL"); + bizMsgStr = ""; + } else { + if (logger.isInfo()) + logger.info("EAILogDAO] Message is String Type"); + bizMsgStr = bizMsg; + } + } + + // EAI 업무 개별부(32,000bytes) + /** + * 업무데이터에 대한정의 1. biz 데이터 2. 표준전문 JSON 데이터 3. 전장표 + */ + StringBuilder sb = new StringBuilder(); + String biz = ""; + String header = message.getStandardMessage().toFixedString(false, EncodingVar.flatEncoding); + + String mdclData = ""; + if (bizMsgStr == null) { + bizMsgStr = ""; + } + + // 암호화 + Charset hexaCharset = Charset.forName("euc-kr"); + if ("Y".equalsIgnoreCase(EncryptionManager.getInstance().getEncryptYN())) { + try { + biz = HexaConverter.bytesToHexa(bizMsgStr.getBytes(hexaCharset)); + } catch (Exception e) { + logger.error("EAIFileLogger] bizMsgStr encryption Error - " + e.getMessage()); + } + try { + header = HexaConverter.bytesToHexa(header.getBytes(hexaCharset)); + } catch (Exception e) { + logger.error("EAIFileLogger] header encryption Error - " + e.getMessage()); + } + try { + mdclData = HexaConverter.bytesToHexa(mdclData.getBytes(hexaCharset)); + } catch (Exception e) { + logger.error("EAIFileLogger] mdclData encryption Error - " + e.getMessage()); + } + } else { + biz = bizMsgStr; + } + + // 임시코드 시작 + String logType = PropManager.getInstance().getProperty("BIZ_LOG_TYPE"); + if (!StringUtils.isBlank(logType)) { + if ("ALL".equals(logType)) { + sb.append(header).append("|").append(biz).append("|").append(mdclData); + } else if ("HEADER".equals(logType)) { + sb.append(header).append("|").append("|"); + } else if ("BODY".equals(logType)) { + sb.append("|").append(biz).append("|"); + } else if ("NONE".equals(logType)) { + sb.append("|").append("|"); + } + } else { + sb.append(header).append("|").append(biz).append("|").append(mdclData); + } + // 임시코드 종료 + + bwkData = sb.toString(); + + String[] refMsgIDs = svcMsg.getRefMsgIDs(); + + // 입력메시지IDS 배열은 delimiter로 구분하여 200byte 만 insert + StringBuilder sbMsgIds = new StringBuilder(); + if (refMsgIDs != null && refMsgIDs.length > 0) { + for (int i = 0; i < refMsgIDs.length - 1; i++) { + sbMsgIds.append(refMsgIDs[i]).append(", "); + } + sbMsgIds.append(refMsgIDs[refMsgIDs.length - 1]); + refMsgID = sbMsgIds.toString(); + + if (refMsgID.getBytes().length > 200) { + refMsgID = StringUtil.chunkString(refMsgID, 200); + } + } + } // 업무데이터 로깅을 할 경우에만 END loggingBizData + + EAILog eaiLog = (EAILog) applicationContext.getBean(RollingTable.class, EAILog.class, message.getMsgRcvTm()); + + try { + // 1/1000초로 변경 + String msgPssTm = DatetimeUtil.getCurrentTime(message.getMsgPssTm()); + + String serverName = EAIServerManager.getInstance().getLocalServerName(); + String serverGroupName = EAIServerManager.getInstance().getServerType(); + + // EAI 업무 공통부(100 bytes) + EAILogId eaiLogId = new EAILogId(); + eaiLog.setId(eaiLogId); + + // EAI업무구분코드 + eaiLogId.setEaibzwkdstcd(message.getBwkCls()); + // 메시지수신시각 + eaiLogId.setMsgdpstyms(DatetimeUtil.getCurrentTime(message.getMsgRcvTm())); + // EAI서비스일련번호 + eaiLogId.setEaisvcserno(message.getSvcOgNo()); + // 로그처리일련번호 + eaiLogId.setLogprcssserno(String.valueOf(orglogPssSno)); + // EAI서버인스탄스명 + eaiLog.setEaisevrinstncname(serverName); + + // EAI서비스명 + eaiLog.setEaisvcname(message.getEAISvcCd()); + // 서비스시각유무 + eaiLog.setSvchmseonot(message.getSvcTmEn()); + // 서비스동기사용구분코드 + eaiLog.setSvcmotivusedstcd(message.getSvcTsmtUsgTp()); + // 서비스처리구분명 + eaiLog.setSvcprcssdsticname(message.getSvcPssTp()); + // 흐름통제라우팅명 + eaiLog.setFlowctrlroutname(message.getFlwCntlRtnNm()); + + // 통합구분명 + eaiLog.setIntgradsticname(message.getUnifTp()); + // 기동서비스구분명 + eaiLog.setGstatsvcdsticname(message.getSngSvcCls()); + // 서비스처리번호 + eaiLog.setSvcprcssno(String.valueOf(message.getSvcPssSeq())); + // 서비스전컬럼로그여부 + eaiLog.setSvcbfclmnlogyn(message.getSvcWlColLogYn()); + // 표준메시지사용여부 + eaiLog.setStndmsguseyn(message.getStdMsgUsgCls()); + + // 기동시스템어댑터업무그룹명 + eaiLog.setGstatsysadptrbzwkgroupname(message.getSngSysItfTp()); + // 현재메시지ID명 + eaiLog.setPrsntmsgidname(message.getLydMsgID()); + // 응답에러코드명 + eaiLog.setRspnserrcdname(message.getRspErrCd()); + // 메시지처리시각 + eaiLog.setMsgprcssyms(msgPssTm); + // 서버로그레벨번호 + eaiLog.setSevrloglvelno(String.valueOf(message.getSvrLogLvl())); + + // 서비스로그레벨번호 + eaiLog.setSvcloglvelno(String.valueOf(message.getSvcLogLvl())); + // 오류EAI서비스명 + eaiLog.setErreaisvcname(message.getErrEAISvcName()); + // 요청오류변환ID명 + eaiLog.setDmnderrchngidname(message.getDmndErrChngIDName()); + // 요청에러필드명 + eaiLog.setDmnderrfldname(message.getDmndErrFldName()); + // 응답오류변환ID명 + eaiLog.setRspnserrchngidname(message.getRspnsErrChngIDName()); + + // 응답에러필드명 + eaiLog.setRspnserrfldname(message.getRspnsErrFldName()); + // 수동인터페이스구분명 + eaiLog.setPsvintfacdsticname(svcMsg.getPsvItfTp()); + // 수동업무시스템명 + eaiLog.setPsvbzwksysname(svcMsg.getPsvBwkSysNm()); + // 수동시스템ID명 + eaiLog.setPsvsysidname(svcMsg.getPsvSysID()); + // 수동시스템서비스구분명 + eaiLog.setPsvsyssvcdsticname(svcMsg.getPsvSysSvcCd()); + + // 수동시스템어댑터업무그룹명 + eaiLog.setPsvsysadptrbzwkgroupname(svcMsg.getPsvSysItfTp()); + // 장애극복여부 + eaiLog.setFlovryn(svcMsg.getFlOvrCls()); + // 변환여부 + eaiLog.setChngyn(svcMsg.getCnvEn()); + // 변환메시지ID명 + eaiLog.setChngmsgidname(svcMsg.getCnvMsgID()); + // 입력메시지ID명 + eaiLog.setInptmsgidname(refMsgID); + + // 기본응답메시지비교내용 + eaiLog.setBascrspnsmsgcmprctnt(svcMsg.getBsRspMsgCprVl()); + // 기본응답변환여부 + eaiLog.setBascrspnschngyn(svcMsg.getBsRspCnvEn()); + // 기본응답변환메시지ID명 + eaiLog.setBascrspnschngmsgidname(svcMsg.getBsRspCnvMsgID()); + // 오류응답메시지비교내용 + eaiLog.setErrrspnsmsgcmprctnt(svcMsg.getErrRspMsgCprVl()); + // 오류응답변환여부 + eaiLog.setErrrspnschngyn(svcMsg.getErrRspCnvEn()); + + // 오류응답변환메시지ID명 + eaiLog.setErrrspnschngmsgidname(svcMsg.getErrRspCnvMsgID()); + // 다음서비스처리번호 + eaiLog.setNextsvcprcssno(String.valueOf(svcMsg.getNxtSvcPssSeq())); + // 아웃바운드라우팅명 + eaiLog.setOutbndroutname(svcMsg.getOutbRtnNm()); + // 타임아웃값 + eaiLog.setToutval(svcMsg.getTmoVl()); + // 보상서비스처리명 + eaiLog.setCmpensvcprcssname(svcMsg.getCpnsSvcPssCd()); + // 추가업무데이터여부 + eaiLog.setSupplbzwkdatayn(apndBwkDataYn); + // 키관리메시지내용 + eaiLog.setKeymgtmsgctnt(svcMsg.getKeyMgtMsgVl()); + + // SS,SA - Send - 100 + // AA - Send - 100 + // AA - Recv - 100, 300 + // AS - 100 + String telgmDmndDstcd = message.getMapper().getSendRecvDivision(message.getStandardMessage()); + if (prop != null && ((EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && logPssSno == 100) + || (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp) + && STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd) + && (logPssSno == 100 || logPssSno == 300)) + || (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp) + && STDMessageKeys.SEND_RECV_CD_SEND.equals(telgmDmndDstcd) && logPssSno == 100) + || (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.SYNC_SVC.equals(psvItfTp) + && logPssSno == 100))) { + eaiLog.setTrackasiskey1ctnt(prop.getProperty(com.eactive.eai.common.logger.Keys.LOG_ALT_KEY1)); // 추적보조키1내용 + eaiLog.setTrackasiskey2ctnt(prop.getProperty(com.eactive.eai.common.logger.Keys.LOG_ALT_KEY2)); // 추적보조키2내용 + eaiLog.setTrackasiskey3ctnt(prop.getProperty(com.eactive.eai.common.logger.Keys.LOG_ALT_KEY3)); // 추적보조키3내용 + eaiLog.setTrackasiskey4ctnt(prop.getProperty(com.eactive.eai.common.logger.Keys.LOG_ALT_KEY4)); // 추적보조키4내용 + } + + // EAI서비스코드의 그룹회사코드 + eaiLog.setEaigroupcodstcd(message.getGroupCoCd()); + // PGUID + eaiLog.setPguid(message.getMapper().getOrgGuid(message.getStandardMessage())); + // 송수신구분 + eaiLog.setTrantype(message.getTranType()); + // + eaiLog.setRspnschngmsgtype(message.getRspnsChngMsgType()); + + // log level 'E' or 'F' + if ("E".equals(message.getRspErrCd().substring(1, 2)) + || "F".equals(message.getRspErrCd().substring(1, 2))) { + // EAI에러코드 + eaiLog.setEaierrcd(message.getRspErrCd()); + // EAI에러내용 + eaiLog.setEaierrctnt(StringUtil.chunkString(message.getRspErrMsg(), 1000)); + } + + // 서버그룹명 + eaiLog.setSevrgroupname(serverGroupName); + // 업체코드 + eaiLog.setCompanycode(message.getCompanyCode()); + // 전문크기, add 20190404 + eaiLog.setSplizlength(message.getSplizLength()); + // index 60 + // add 20190404 // adapterNickName + eaiLog.setAdptrinsticode(message.getAdptrInstiCode()); + + // 거래ID + eaiLog.setTxid(message.getTxId()); + // 참조ID + eaiLog.setRefkey(message.getRefKey()); + // 대외업무구분코드 + eaiLog.setExtbizcd(message.getExtBizCd()); + // EAI 업무 개별부(32,000bytes) + if (bwkData == null || bwkData.equals("")) + bwkData = " "; + eaiLog.setBzwkdatactnt(bwkData); + String standardLayoutName = System.getProperty("STANDARD_LAYOUT_NAME"); + // 표준전문레이아웃 명 + eaiLog.setStdlayoutname(standardLayoutName); + + // clientId 로그에 추가 + String clientId = message.getClientId(); + eaiLog.setClientid(clientId); + + // client IP 로그에 추가 + String clientIp = message.getClientIp(); + eaiLog.setClientip(clientIp); + + /** + * CLIENT ID 있을 경우 APP, 기관정보 로그에 추가 + * TODO: ClientVO의 경우 spring security oauth의 ClientDetails를 상속받고 있어 OAUTH가 아닌 인증의 경우에 대한 처리 추가 필요 + */ + if(StringUtils.isNotBlank(clientId)) { + ClientVO clientVO = OAuth2Manager.getInstance().getClientVO(clientId); + if (clientVO != null) { + eaiLog.setClientname(clientVO.getClientName()); + eaiLog.setOrgid(clientVO.getOrgId()); + eaiLog.setOrgname(clientVO.getOrgName()); + } + } + + eaiLogEntityService.save(eaiLog); + + } catch (Exception e) { + logger.error( + "DB Logging[MASTER] Failed - " + message.getEAISvcCd() + "|" + orglogPssSno + "|" + + message.getSvcOgNo() + "|" + message.getMapper().getGuid(message.getStandardMessage()), + e); + + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLG001")); + } + + // 에러로그를 별도의 테이블에 저장하도록 한다. + if (!MessageUtil.checkRspErrCd(message.getRspErrCd())) { + try { + // 거래통제, 유량제어에 의한 에러는 저장하지 않도록 한다. + if (!(EAIMessageKeys.EAI_BLOCKED_CODE.equals(message.getRspErrCd()) + || EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE.equals(message.getRspErrCd()))) { + addErrorLog(message); // 에러로그 + } + } catch (Exception ex) { + logger.warn("에러로그테이블 저장 SKIP 에러발생 - " + ex.getMessage()); + } + } + + } + + public void addErrorLog(EAIMessage message) throws DAOException { + try { + String serverName = EAIServerManager.getInstance().getLocalServerName(); + + EAIErrorLog eaiErrorLog = (EAIErrorLog) applicationContext.getBean(RollingTable.class, EAIErrorLog.class, + message.getMsgRcvTm()); + + // EAI업무구분코드 + EAIErrorLogId eaiErrorLogId = new EAIErrorLogId(); + eaiErrorLog.setId(eaiErrorLogId); + + eaiErrorLogId.setEaibzwkdstcd(message.getBwkCls()); + // 메시지수신시각 + eaiErrorLogId.setMsgdpstyms(DatetimeUtil.getCurrentTime(message.getMsgRcvTm())); + // EAI거래일련번호 + eaiErrorLogId.setEaisvcserno(message.getSvcOgNo()); + // 로그처리일련번호 + eaiErrorLogId.setLogprcssserno(String.valueOf(message.getLogPssSno())); + + // EAI서비스명 + eaiErrorLog.setEaisvcname(message.getEAISvcCd()); + // 응답에러코드명 + eaiErrorLog.setRspnserrcdname(message.getRspErrCd()); + // 기동시스템어댑터업무그룹명 + eaiErrorLog.setGstatsysadptrbzwkgroupname(message.getSngSysItfTp()); + // 수동시스템어댑터업무그룹명 + eaiErrorLog.setPsvsysadptrbzwkgroupname(message.getCurrentSvcMsg().getPsvSysItfTp()); + + if ("E".equals(message.getRspErrCd().substring(1, 2)) + || "F".equals(message.getRspErrCd().substring(1, 2))) { + // EAI에러코드 + eaiErrorLog.setEaierrcd(message.getRspErrCd()); + // EAI에러내용 + eaiErrorLog.setEaierrctnt(StringUtil.chunkString(message.getRspErrMsg(), 500)); + } + + // EAI서버인스턴스명 + eaiErrorLog.setEaisevrinstncname(serverName); + // 로깅시스템ID + EAIServerVO eaiServerVO = EAIServerManager.getInstance().getEAIServer(serverName); + if(eaiServerVO != null) { + eaiErrorLog.setLgingsysid(eaiServerVO.getHostName()); + } + // 메시지처리일시 + eaiErrorLog.setMsgprcssyms(DatetimeUtil.getCurrentTime(message.getMsgPssTm())); + // EAI그룹회사코드 + eaiErrorLog.setEaigroupcodstcd(message.getGroupCoCd()); + + } catch (Exception e) { + logger.error("DB Logging[ERROR_LOG] Failed - " + message.getEAISvcCd() + "|" + message.getLogPssSno() + "|" + + message.getSvcOgNo(), e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLG003")); + } + } + + public void addStaticLog(StatMonitorLogVO vo) throws DAOException { + try { + StatLog statLog = statLogMapper.toEntity(vo); + statLogLogger.save(statLog); + } catch (Exception e) { + logger.error("DB Logging[STATIC_LOG] Failed - " + vo.toString(), e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLG003")); + } + } + + public void addStaticTranCdLog(StatMonitorLogVO vo) throws DAOException { + try { + StatTranLog statTranLog = statTranLogMapper.toEntity(vo); + statTranLogLogger.save(statTranLog); + } catch (Exception e) { + logger.error("DB Logging[STATIC_TRANCD_LOG] Failed - " + vo.toString(), e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLG003")); + } + } + + public void addStaticAdapterLog(StatMonitorLogVO vo) throws DAOException { + try { + StatAdapterLog statAdapterLog = statAdapterLogMapper.toEntity(vo); + statAdapterLogLogger.save(statAdapterLog); + } catch (Exception e) { + logger.error("DB Logging[STATIC_ADAPTER_LOG] Failed - " + vo.toString(), e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICLG003")); + } + } + + public boolean getCheck() throws DAOException { + return eaiServerEntityService.checkConnection(); + } + + private boolean checkSubLogging(String svcTsmtUsgTp, String psvItfTp, String srcAdptrMsgPtrnCd, String tgtAdptrMsgPtrnCd, int logPssSno) { + boolean isAsyncSvc = EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp); + boolean isSrcStandard = com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(srcAdptrMsgPtrnCd); + +// // SOURCE : AA : 100, 300, ELSE: 100, 400 + if(isSrcStandard && ( (isAsyncSvc && (logPssSno == 100 || logPssSno == 300)) || + (!isAsyncSvc && (logPssSno == 100 || logPssSno == 400)) ) ) { + return true; + } + + boolean isTgtStandard = com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(tgtAdptrMsgPtrnCd); +// // TARGET : AA : 200, 400, ELSE : 200, 300 + if (isTgtStandard && ( (isAsyncSvc && (logPssSno == 200 || logPssSno == 400)) || + (!isAsyncSvc && (logPssSno == 200 || logPssSno == 300)) ) ) { + return true; + } + return false; + } + +} diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogException.java b/src/main/java/com/eactive/eai/common/logger/EAILogException.java new file mode 100644 index 0000000..b651315 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/EAILogException.java @@ -0,0 +1,38 @@ +package com.eactive.eai.common.logger; + +/** +* 1. 기능 : EAI 로그 처리 시 예외처리를 위한 Exception +* 2. 처리 개요 : +* - EAILogger 예외처리 +* 3. 주의사항 +* +* @author : 전영석( amjang@evalleyvs.com) +* @version : v 1.0.0 +* @see : TestCall +* @since :JDK v1.4.2 +*/ +public class EAILogException extends Exception +{ + /** + * 1. 기능 : Default 생성자 함수 + * 2. 처리 개요 : + * - Default 생성자 함수 + * 3. 주의사항 + * + **/ + public EAILogException() { + super("EAILogException is occured."); + } + + /** + * 1. 기능 : Exception 발생 원인을 저장하는 생성자 함수 + * 2. 처리 개요 : + * - Exception 발생 원인을 저장하는 생성자 함수 + * 3. 주의사항 + * + *@param msg Exception 발생 원인 + **/ + public EAILogException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogQuery.java b/src/main/java/com/eactive/eai/common/logger/EAILogQuery.java new file mode 100644 index 0000000..3cffca9 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/EAILogQuery.java @@ -0,0 +1,132 @@ +package com.eactive.eai.common.logger; + +import com.eactive.eai.common.dao.Keys; + +/** + * 1. 기능 : EAI에서 처리되는 모든 On-Line 거래를 데이터베이스에 로깅하기 위한 운영관리 Logger Query Object + * 2. 처리 개요 : + * - TSEAILG01(EAI서비스로그), TSEAILG02(로그ALTKEY정보), TSEAILG03(EAI로그업무데이터서브정보), TSEAILG04(EAI서비스오류정보) insert Query + * 3. 주의사항 + * + * @author : 전영석(amjang@evalleyvs.com) + * @version : v 1.0.0 + * @see : IMSAdapterListener, IMSRecord + * @since :JDK v1.4.2 + */ +public interface EAILogQuery +{ + /** + * 1. 기능 : EAI 서비스 로그 셋팅 + * 2. 처리 개요 : + * - TSEAILG01(EAI서비스로그) 로그값 셋팅 + * 3. 주의사항 + **/ + public static final String ADD_EAI_SVC_LOG + = " INSERT INTO " + Keys.TABLE_OWNER + "#{LOG_MASTER_TABLE} ( \n" + //EAI업무공통부 + + " EAIBZWKDSTCD, MSGDPSTYMS, EAISVCSERNO, LOGPRCSSSERNO, EAISEVRINSTNCNAME, \n" + + " EAISVCNAME, SVCHMSEONOT, SVCMOTIVUSEDSTCD, SVCPRCSSDSTICNAME, FLOWCTRLROUTNAME, \n" + + " INTGRADSTICNAME, GSTATSVCDSTICNAME, SVCPRCSSNO, SVCBFCLMNLOGYN, STNDMSGUSEYN, \n" + + " GSTATSYSADPTRBZWKGROUPNAME, PRSNTMSGIDNAME, RSPNSERRCDNAME, MSGPRCSSYMS, SEVRLOGLVELNO, \n" + + " SVCLOGLVELNO, ERREAISVCNAME, DMNDERRCHNGIDNAME, DMNDERRFLDNAME, RSPNSERRCHNGIDNAME, \n" + + " RSPNSERRFLDNAME, PSVINTFACDSTICNAME, PSVBZWKSYSNAME, PSVSYSIDNAME, PSVSYSSVCDSTICNAME, \n" + + " PSVSYSADPTRBZWKGROUPNAME, FLOVRYN, CHNGYN, CHNGMSGIDNAME, INPTMSGIDNAME, \n" + + " BASCRSPNSMSGCMPRCTNT, BASCRSPNSCHNGYN, BASCRSPNSCHNGMSGIDNAME, ERRRSPNSMSGCMPRCTNT, ERRRSPNSCHNGYN, \n" + + " ERRRSPNSCHNGMSGIDNAME, NEXTSVCPRCSSNO, OUTBNDROUTNAME, TOUTVAL, CMPENSVCPRCSSNAME, \n" + + " SUPPLBZWKDATAYN, KEYMGTMSGCTNT, TRACKASISKEY1CTNT, TRACKASISKEY2CTNT, TRACKASISKEY3CTNT, \n" + + " TRACKASISKEY4CTNT, EAIGROUPCODSTCD, PGUID, TRANTYPE, RSPNSCHNGMSGTYPE, \n" + + " EAIERRCD, EAIERRCTNT, SEVRGROUPNAME, COMPANYCODE, SPLIZLENGTH, ADPTRINSTICODE, \n" + + " TXID, REFKEY, EXTBIZCD, \n" + + " BZWKDATACTNT, STDLAYOUTNAME, CLIENTID \n" + + " ) VALUES ( \n" + //EAI업무공통부 + + " ?, ?, ?, ?, ?, \n" //index to 5 + + " ?, ?, ?, ?, ?, \n" //index to 10 + + " ?, ?, ?, ?, ?, \n" //index to 15 + + " ?, ?, ?, ?, ?, \n" //index to 20 + + " ?, ?, ?, ?, ?, \n" //index to 25 + + " ?, ?, ?, ?, ?, \n" //index to 30 + + " ?, ?, ?, ?, ?, \n" //index to 35 + + " ?, ?, ?, ?, ?, \n" //index to 40 + + " ?, ?, ?, ?, ?, \n" //index to 45 + + " ?, ?, ?, ?, ?, \n" //index to 50 + + " ?, ?, ?, ?, ?, \n" //index to 55 + + " ?, ?, ?, ?, ?, \n" //index to 60 + + " ?, ?, ?, ?,\n" //index to 61 + + " ?, ?, ? \n" // 62~66 + + ") "; + + /** + * 1. 기능 : 업무데이터 서브 로그 셋팅 + * 2. 처리 개요 : + * - TSEAILG03(EAI로그업무데이터서브정보) 로그값 셋팅 + * 3. 주의사항 + **/ + public static final String ADD_BWK_DATA_SUB + = " INSERT INTO " + Keys.TABLE_OWNER + "#{LOG_SLAVE_TABLE} ( \n" + + " EAIBZWKDSTCD, MSGDPSTYMS, EAISVCSERNO, BZWKDATASERNO, LOGPRCSSSERNO \n" + + " , BZWKDATACTNT \n" + + " ) VALUES ( \n" + + " ?, ?, ?, ?, ? \n" + + " , ? \n" + + " ) "; + + public static final String ERROR_LOG + = " INSERT INTO " + Keys.TABLE_OWNER + "#{LOG_SLAVE_TABLE} ( \n" + + " EAIBZWKDSTCD, MSGDPSTYMS, EAISVCSERNO, LOGPRCSSSERNO, EAISVCNAME \n" + + " , RSPNSERRCDNAME, GSTATSYSADPTRBZWKGROUPNAME, PSVSYSADPTRBZWKGROUPNAME, EAIERRCD, EAIERRCTNT \n" + + " , EAISEVRINSTNCNAME, LGINGSYSID, MSGPRCSSYMS, EAIGROUPCODSTCD \n" + + " ) VALUES ( \n" + + " ?, ?, ?, ?, ? \n" + + " , ?, ?, ?, ?, ? \n" + + " , ?, ?, ?, ? \n" + + " ) "; + + + public static final String STATIC_LOG + = " INSERT INTO " + Keys.TABLE_OWNER + "TSEAISR01 ( \n" + + " BASEYMD, BASEHH, BASEHHMM, EAIBZWKDSTCD, EAISVCNAME \n" + + " , EAISEVRINSTNCNAME, EAIPRCSSTTMVAL, EAIPSVPRCSSTTMVAL, EAITOTALPRCSSTTMVAL, WHOLPRCSSNOITM \n" + + " , ERRZNOITM, TOUTNOITM, NOMALNOITM \n" + + " ) VALUES ( \n" + + " ?, ?, ?, ?, ? \n" + + " , ?, ?, ?, ?, ? \n" + + " , ?, ?, ? \n" + + " ) "; + + + public static final String STATIC_TRANCD_LOG + = " INSERT INTO " + Keys.TABLE_OWNER + "TSEAISR02 ( \n" + + " BASEYMD, BASEHH, BASEHHMM, EAIBZWKDSTCD, EAISVCNAME \n" + + " , INTFACSENDTRANCD, EAISEVRINSTNCNAME ,EAIPRCSSTTMVAL, EAIPSVPRCSSTTMVAL, EAITOTALPRCSSTTMVAL \n" + + " , WHOLPRCSSNOITM, ERRZNOITM, TOUTNOITM, NOMALNOITM \n" + + " ) VALUES ( \n" + + " ?, ?, ?, ?, ? \n" + + " , ?, ?, ?, ?, ? \n" + + " , ?, ?, ?, ? \n" + + " ) "; + + public static final String STATIC_SCREEN_LOG + = " INSERT INTO " + Keys.TABLE_OWNER + "TSEAISR03 ( \n" + + " BASEYMD, BASEHH, BASEHHMM, EAIBZWKDSTCD, EAISVCNAME \n" + + " , SCRENNO, EAISEVRINSTNCNAME, EAIPRCSSTTMVAL, EAIPSVPRCSSTTMVAL, EAITOTALPRCSSTTMVAL \n" + + " , WHOLPRCSSNOITM, ERRZNOITM, TOUTNOITM, NOMALNOITM \n" + + " ) VALUES ( \n" + + " ?, ?, ?, ?, ? \n" + + " , ?, ?, ?, ?, ? \n" + + " , ?, ?, ?, ? \n" + + " ) "; + + public static final String STATIC_ADAPTER_LOG + = " INSERT INTO " + Keys.TABLE_OWNER + "TSEAISR04 ( \n" + + " BASEYMD, BASEHH, BASEHHMM, EAIBZWKDSTCD, EAISVCNAME \n" + + " , ADPTRBZWKGROUPNAME, EAISEVRINSTNCNAME, EAIPRCSSTTMVAL, EAIPSVPRCSSTTMVAL, EAITOTALPRCSSTTMVAL \n" + + " , WHOLPRCSSNOITM, ERRZNOITM, TOUTNOITM, NOMALNOITM \n" + + " ) VALUES ( \n" + + " ?, ?, ?, ?, ? \n" + + " , ?, ?, ?, ?, ? \n" + + " , ?, ?, ?, ? \n" + + " ) "; + + public static final String CHECK_DB = "select 1"; +} diff --git a/src/main/java/com/eactive/eai/common/logger/EAILogSender.java b/src/main/java/com/eactive/eai/common/logger/EAILogSender.java new file mode 100644 index 0000000..da7eb59 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/EAILogSender.java @@ -0,0 +1,127 @@ +package com.eactive.eai.common.logger; + +import java.util.Properties; + +import org.apache.commons.lang3.SerializationUtils; + +import com.eactive.eai.common.logger.async.AsyncLoggingPoolManager; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.monitor.EAIServiceMonitor; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.env.ElinkConfig; + +/** + * 1. 기능 : EAI에서 처리되는 모든 On-Line 거래를 데이터베이스에 로깅하기 위한 운영관리 Logger Sender + * 2. 처리 개요 : - RequestProcessor에서 받은 로깅 정보를 로그 Queue로 전달 + * 3. 주의사항 + */ +public class EAILogSender { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static TransactionLogger txLogger; + static { + try { + txLogger = (TransactionLogger) Class.forName("com.eactive.eai.common.logger.DBLogTransactionLogger").newInstance(); + } catch(Exception e) { + logger.error(e.getMessage(), e); + } + } + + private EAILogSender() { + + } + public static int logCount() { + return txLogger.logCount(); + } + + public static int errCount() { + return txLogger.errCount(); + } + + public static void resetCount() { + txLogger.resetCount(); + } + + public static void send(EAIMessage message, Properties prop) throws Exception { + if(message == null) { + if(logger.isWarn()) { + logger.warn("EAIMessage is null, skip async logging."); + } + } + else { + String guidLogPrefix = "EAILogSender] GUID[" + message.getMapper().getGuid(message.getStandardMessage()) + + "] UUID[" + message.getSvcOgNo() + "] "; + + boolean isLogging = false; + int svcLogLvl = message.getSvcLogLvl(); + int logPssSno = message.getLogPssSno(); + String svcTsmtUsgTp = message.getSvcTsmtUsgTp(); + if(svcLogLvl >= 3) { + isLogging = true; + } + else if(svcLogLvl == 2) { + if( EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && + (logPssSno == 100 || logPssSno == 400) ) { + isLogging = true; + } + if( EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && + (logPssSno == 200 || logPssSno == 400) ) { + isLogging = true; + } + } + else if(svcLogLvl == 1) { + isLogging = ! MessageUtil.checkRspErrCd(message.getRspErrCd()); + } + else { + isLogging = false; + } + if(logger.isDebug()) { + logger.debug(guidLogPrefix + " svcLogLvl="+ svcLogLvl + ",isLogging="+ isLogging+ ", logPssSno="+ logPssSno); + } + long logTime = System.currentTimeMillis(); + message.setMsgPssTm(logTime); + if(isLogging) { + if(ElinkConfig.isUseAsyncLogging()) { + try { + EAIMessage cloned = null; + // cloned = (EAIMessage) ObjectUtil.deepCopy(message); +// cloned = (EAIMessage) SerializationUtils.clone(message); + // performance issue, use clone -> shallow copy bug -> fix + cloned = (EAIMessage) message.clone(); + Properties clonedProp = null; + if(prop != null) clonedProp = (Properties) prop.clone(); + AsyncLoggingPoolManager.getInstance().publish(cloned, clonedProp); + } catch (Exception e) { + logger.warn("AsyncLogging error", e); + logDirect(message, prop); +// throw e; + } + } + else { + logDirect(message, prop); + } + } + + // 실시간 모니터링 로그 + EAIServiceMonitor servicemonitor = EAIServiceMonitor.getInstance(); + if(EAIMessageKeys.EAI_BLOCKED_CODE.equals(message.getRspErrCd())) { + if(logger.isWarn()) { + logger.warn(guidLogPrefix + " 거래통제 실시간 모니터링 SKIP - " + message.getEAISvcCd() + + ", "+message.getMapper().getGuid(message.getStandardMessage()) ); + } + }else if (EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE.equals(message.getRspErrCd())) { + if(logger.isWarn()) { + logger.warn(guidLogPrefix + " 유량제어 실시간 모니터링 SKIP - " + message.getEAISvcCd() + + ", "+ message.getMapper().getGuid(message.getStandardMessage()) ); + } + }else { + servicemonitor.receiveLogMessage(message); + } + } + } + + public static void logDirect(EAIMessage message, Properties prop) throws EAILogException { + txLogger.log(message, prop); + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java new file mode 100644 index 0000000..975f134 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraHeaderVo.java @@ -0,0 +1,12 @@ +package com.eactive.eai.common.logger; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +@AllArgsConstructor +public class HttpAdapterExtraHeaderVo { + private String name; + + private String value; +} diff --git a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogFileLogger.java b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogFileLogger.java new file mode 100644 index 0000000..e1f19d0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogFileLogger.java @@ -0,0 +1,32 @@ +package com.eactive.eai.common.logger; + +import com.eactive.eai.common.logger.async.HttpAdapterExtraLogH2Factory; +import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; +import org.hibernate.Session; +import org.hibernate.Transaction; +import org.springframework.stereotype.Service; + +@Service +public class HttpAdapterExtraLogFileLogger { + + public void writeFileLog(HttpAdapterExtraLog httpAdapterExtraLog){ + try (Session session = HttpAdapterExtraLogH2Factory.getInstance().openSession()) { + Transaction transaction = null; + + try { + // 트랜잭션 시작 + transaction = session.beginTransaction(); + + session.persist(httpAdapterExtraLog); + + // 트랜잭션 커밋 + transaction.commit(); + } catch (Exception e) { + if (transaction != null) { + transaction.rollback(); + } + throw e; + } + } + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java new file mode 100644 index 0000000..4dcb0ac --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/HttpAdapterExtraLogVo.java @@ -0,0 +1,17 @@ +package com.eactive.eai.common.logger; + +import lombok.Data; + +import java.util.List; + +@Data +public class HttpAdapterExtraLogVo { + private String guid; + private int serviceProcessNumber; + private String adapterGroupName; + private String adapterName; + private String url; + private String httpMethod; + private int httpStatus; + List headerList; +} diff --git a/src/main/java/com/eactive/eai/common/logger/HttpLoggingService.java b/src/main/java/com/eactive/eai/common/logger/HttpLoggingService.java new file mode 100644 index 0000000..4974f7d --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/HttpLoggingService.java @@ -0,0 +1,41 @@ +package com.eactive.eai.common.logger; + +import com.eactive.eai.common.logger.mapper.HttpAdapterExtraLogMapper; +import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + + +@Service +public class HttpLoggingService { + + @Autowired + private HttpAdapterExtraLogMapper mapper; + + @Autowired + private HttpAdapterExtraLogLogger dbLogger; + + @Autowired + private HttpAdapterExtraLogFileLogger fileLogger; + + public void insertHttpAdapterExtraLog(HttpAdapterExtraLogVo httpAdapterExtraLogVo) throws Throwable{ + HttpAdapterExtraLog httpAdapterExtraLog = mapper.toEntity(httpAdapterExtraLogVo); + if (EAIDBLogControl.isEnable()) { + try { + dbLogger.save(httpAdapterExtraLog); + } catch(Exception e){ + String message = e.getMessage(); + // 오류 메시지 추가 - Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection + // 오류 메시지 추가 - Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection + if( "ConnectionError".equals(message) || StringUtils.contains(message, "JDBCConnectionException") + || StringUtils.contains(message, "Unable to acquire JDBC Connection") ) { + EAIDBLogControl.setEnable(false); + } + fileLogger.writeFileLog(httpAdapterExtraLog); + } + } else { + fileLogger.writeFileLog(httpAdapterExtraLog); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/LogListener.java b/src/main/java/com/eactive/eai/common/logger/LogListener.java new file mode 100644 index 0000000..9776c2e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/LogListener.java @@ -0,0 +1,121 @@ +package com.eactive.eai.common.logger; + +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.Queue; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.QueueReceiver; +import javax.jms.QueueSession; +import javax.jms.Session; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.jms.JmsServiceLocator; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; + +/** + * 1. 기능 : LogListener를 관리하는 Manager 클래스 + * 2. 처리 개요 : ServiceLocator로부터 queue를 get하여 Receiver를 생성 관리한한다. + * 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : : + */ +public class LogListener implements MessageListener, Lifecycle { + private String name; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + private boolean started; + + private QueueConnection qcon; + private QueueSession qsession; + private QueueReceiver qreceiver; + private Queue queue; + + public LogListener(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void onMessage(Message msg) { + // write code here! + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICLG101"); + lifecycle.fireLifecycleEvent(STARTING_EVENT, null); + + try { + JmsServiceLocator locator = JmsServiceLocator.getInstance(); + QueueConnectionFactory qconFactory = locator.getQueueConnectionFactory(Keys.LOG_CONNECTION_FACTORY); + if (qconFactory == null) { + throw new Exception("QueueConnectionFactory not found - " + Keys.LOG_CONNECTION_FACTORY); + } + qcon = qconFactory.createQueueConnection(); + qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); + queue = locator.getQueue(Keys.LOG_QUEUE); + qreceiver = qsession.createReceiver(queue); + qreceiver.setMessageListener(this); + qcon.start(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICLG102")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, null); + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICLG103"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, null); + + try { + if (qreceiver != null) + qreceiver.close(); + } catch (Exception e) { + // nothing to do + } + try { + if (qreceiver != null) + qsession.close(); + } catch (Exception e) { + // nothing to do + } + try { + if (qreceiver != null) + qcon.close(); + } catch (Exception e) { + // nothing to do + } + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, null); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + +} diff --git a/src/main/java/com/eactive/eai/common/logger/LogListenerManager.java b/src/main/java/com/eactive/eai/common/logger/LogListenerManager.java new file mode 100644 index 0000000..8a5c14e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/LogListenerManager.java @@ -0,0 +1,178 @@ +package com.eactive.eai.common.logger; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; + +/** +* 1. 기능 : LogListener를 생성 관리하는 Manager 클래스 +* 2. 처리 개요 : LogListener를 생성 관리한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class LogListenerManager implements Lifecycle +{ + + /** + * Default Logger + */ +// private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * LogListener생성 count. LogListener생성시 증가시킴 + */ + private int count; + + +// private ArrayList listeners; + + /** + * LifeccyleSupport object + */ + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + /** + * 기동 여부 + */ + private boolean started; + + /** + * LogListener생성시 동기화를 위한 lock + */ + private Object lock = new Object(); + + /** + * 1. 기능 : Lifecycle의 start 메서드로 LogListenerManager를 초기화하는 메서드 + * 2. 처리 개요 : Lifecycle의 start + * 3. 주의사항 + * + * @exception LifecycleException 이미 시작되었을 경우 발생(RECEAICLG111) + * + **/ + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICLG111"); + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTING_EVENT, null); + +// this.listeners = new ArrayList(); + this.count = 0; + + started = true; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTED_EVENT, null); + } + + /** + * 1. 기능 : Lifecycle의 stop 메서드로 LogListenerManager를 종료하는 메서드 + * 2. 처리 개요 : Lifecycle의 stop 메서드로 LogListenerManager를 종료 + * 3. 주의사항 + * + * @exception LifecycleException 이미 종료된 경우 발생(RECEAICLG112) + **/ + public void stop() throws LifecycleException { + // Validate and update our current component state + if (!started) + throw new LifecycleException("RECEAICLG112"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPING_EVENT, null); + + + + started = false; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPPED_EVENT, null); + } + + /** + * 1. 기능 : LifecycleListener를 등록하는 메서드 + * 2. 처리 개요 : LifecycleListener를 등록한다. + * 3. 주의사항 + * + * @param listener LifecycleEvent를 수신한 LifecycleListener + **/ + public void addLifecycleListener(LifecycleListener listener) + { + lifecycle.addLifecycleListener(listener); + } + + /** + * 1. 기능 : 등록된 LifecycleListener 리스트를 반환하는 메서드 + * 2. 처리 개요 : 등록된 LifecycleListener 리스트를 반환하다. + * 3. 주의사항 + * + * @return 등록된 LifecycleListener 리스트 + **/ + public LifecycleListener[] findLifecycleListeners() + { + return lifecycle.findLifecycleListeners(); + } + + /** + * 1. 기능 : 등록된 LifecycleListener를 삭제하는 메서드 + * 2. 처리 개요 : 파라미터의 LifecycleListener를 삭제한다. + * 3. 주의사항 + * + * @param listener 삭제할 LifecycleListener + **/ + public void removeLifecycleListener(LifecycleListener listener) + { + lifecycle.removeLifecycleListener(listener); + } + + /** + * 1. 기능 : LogListenerManager의 초기화 여부를 반환하는 getter 메서드 + * 2. 처리 개요 : LogListenerManager의 초기화 여부를 반환한다. + * 3. 주의사항 + * + * @return 초기화 여부 + **/ + public boolean isStarted() { + return this.started; + } + + + /** + * 1. 기능 : LogListener를 생성하고 초기화하는 메서드 + * 2. 처리 개요 : LogListener를 생성하고 생성한 LogListener를 start하여 초기화 시킨다. + * 3. 주의사항 + * + **/ + public void addLogListener() { + LogListener listener = createLogListener(); + if(listener instanceof Lifecycle) { + try { + listener.start(); + } catch(Exception e) { + String code = "RECEAICLG113"; + //if (logger.isError()) logger.error(ExceptionUtil.make(code, CodeMessageHandler.getMessage(code))); + throw new RuntimeException(ExceptionUtil.getErrorCode(e, code)); + } + } + } + + /** + * 1. 기능 : LogListener를 생성하는 메서드 + * 2. 처리 개요 : LogListener를 생성시 생성 카운트를 증가시킨다 + * - + * 3. 주의사항 + * @return LogListener 생성된 LogListener + **/ + private LogListener createLogListener() { + String name = null; + synchronized(lock) { + name = "LogListener["+(++count)+"]"; + } + LogListener listener = new LogListener(name); + + return listener; + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/LogMessageUtil.java b/src/main/java/com/eactive/eai/common/logger/LogMessageUtil.java new file mode 100644 index 0000000..bed108a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/LogMessageUtil.java @@ -0,0 +1,96 @@ +package com.eactive.eai.common.logger; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.transformer.layout.Layout; +import com.eactive.eai.transformer.message.BytesMessage; +import com.eactive.eai.transformer.message.JSONMessage; +import com.eactive.eai.transformer.message.Message; +import com.eactive.eai.transformer.message.MessageFactory; +import com.eactive.eai.transformer.message.XMLMessage; + +public class LogMessageUtil { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static String makeMaskData(EAIMessage message, Object bizMsg, Layout l, int logPssSno, String tgtAdptrMsgPtrnCd + , String svcTsmtUsgTp, String psvItfTp) throws Exception { + String bizMsgStr=""; + Message msg = MessageFactory.getFactory().getMessage(l.getName()); + if("XML".equals(l.getLayoutType().getName())) { + if (logger.isInfo()) logger.info("EAILogDAO] XML Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); + + String xmlString = ""; + if(bizMsg instanceof byte[]) { + xmlString = new String((byte[])bizMsg); + } else { + xmlString = (String)bizMsg; + } + + String rootItemName = ((XMLMessage)msg).getLayout().getRootItem().getName(); + xmlString = MessageUtil.removeXMLHeader(xmlString); + xmlString = "<"+rootItemName+">"+xmlString+""; + msg.setData(xmlString); + bizMsgStr = MessageUtil.removeXMLRootItem(msg.toLogString(), rootItemName); + } + else if("JSON".equals(l.getLayoutType().getName())) { + if (logger.isInfo()) logger.info("EAILogDAO] JSON Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); + String jsonString = ""; + + jsonString = (String)bizMsg; + +// String rootItemName = ((JSONMessage)msg).getLayout().getRootItem().getName(); +// jsonString = MessageUtil.addJsonRootItem(jsonString, rootItemName); +// msg.setData(jsonString); +// bizMsgStr = MessageUtil.removeJsonRootItem(msg.toLogString(), rootItemName);; + + // JSON Tuning + msg.setData(jsonString); + bizMsgStr = msg.toLogString(); + } +// else if("UJSON".equals(l.getLayoutType().getName())) { +// if (logger.isInfo()) logger.info("EAILogDAO] UJSON Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); +// +// String jsonString = ""; +// +// if(bizMsg instanceof byte[]) { +// jsonString = new String((byte[])bizMsg, UJSONMessage.encode); +// } else { +// jsonString = (String)bizMsg; +// } +// +// String rootItemName = ((UJSONMessage)msg).getLayout().getRootItem().getName(); +// jsonString = MessageUtil.addJsonRootItem(jsonString, rootItemName); +// msg.setData(jsonString); +// bizMsgStr = MessageUtil.removeJsonRootItem(msg.toLogString(), rootItemName);; +// } + else if("EBCDIC".equals(l.getLayoutType().getName())) { + if (logger.isInfo()) logger.info("EAILogDAO] EBCDIC Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); + + byte[] orgBytes = (byte[])bizMsg; + byte[] msgBytes = null; + byte[] header = null; + + msg.setData(bizMsg); + bizMsgStr = ((BytesMessage)msg).toLogString(true); + } + else if( "BYTES".equals(l.getLayoutType().getName()) ) { + if (logger.isInfo()) logger.info("EAILogDAO] BYTES Message Masking - "+ logPssSno); + byte[] orgBytes = (byte[])bizMsg; + byte[] msgBytes = null; + byte[] header = null; + + if (logger.isInfo()) logger.info("EAILogDAO] BYTES Standard Header Type = " + tgtAdptrMsgPtrnCd); + + if (logger.isInfo()) logger.info("EAILogDAO] "+l.getLayoutType().getName()+" Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); + msg.setData(bizMsg); + bizMsgStr = msg.toLogString(); + } + else { + msg.setData(bizMsg); + bizMsgStr = msg.toLogString(); + } + return bizMsgStr; + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/TransactionLogger.java b/src/main/java/com/eactive/eai/common/logger/TransactionLogger.java new file mode 100644 index 0000000..010f07a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/TransactionLogger.java @@ -0,0 +1,12 @@ +package com.eactive.eai.common.logger; + +import com.eactive.eai.common.message.EAIMessage; + +import java.util.Properties; + +public interface TransactionLogger { + public void log(EAIMessage message,Properties prop) throws EAILogException; + public int logCount(); + public int errCount(); + public void resetCount(); +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/AsyncHttpLoggingPoolManager.java b/src/main/java/com/eactive/eai/common/logger/async/AsyncHttpLoggingPoolManager.java new file mode 100644 index 0000000..ba91d0b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/AsyncHttpLoggingPoolManager.java @@ -0,0 +1,210 @@ +package com.eactive.eai.common.logger.async; + +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.logger.HttpAdapterExtraLogVo; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ElinkConfig; +import org.apache.commons.pool2.ObjectPool; +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; + +import java.time.Duration; +import java.util.Properties; + +/** + * HTTP 로그도 ASYNC 모드를 대응하기 위해 추가 + * 추후 고도화 필요 + */ +public class AsyncHttpLoggingPoolManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static AsyncHttpLoggingPoolManager instance; + + private static boolean stopped = true; + + private int maxPoolSize = 10; + private int initPoolSize = 8; + + private boolean initOnStartup = true; + + private ObjectPool pool = null; + + /** + * 기동 여부 + */ + private boolean started; + + /** + * LifeccyleSupport object + */ + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + public static synchronized AsyncHttpLoggingPoolManager getInstance() { + if (instance == null) { + instance = new AsyncHttpLoggingPoolManager(); + } + return instance; + } + + public int getMaxPoolSize() { + return maxPoolSize; + } + + public void setMaxPoolSize(int maxPoolSize) { + this.maxPoolSize = maxPoolSize; + } + + public int getInitPoolSize() { + return initPoolSize; + } + + public void setInitPoolSize(int initPoolSize) { + this.initPoolSize = initPoolSize; + } + + public boolean isInitOnStartup() { + return initOnStartup; + } + + public void setInitOnStartup(boolean initOnStartup) { + this.initOnStartup = initOnStartup; + } + + public void publish(HttpAdapterExtraLogVo httpAdapterExtraLogVo) throws Exception { + HttpLoggingPoolObject queue = null; + try { + queue = borrowObject(); + queue.putMessage(httpAdapterExtraLogVo); + } catch (Exception ex) { + logger.error("publish failed.", ex); + throw ex; + } finally { + if (queue != null) returnObject(queue); + } + } + + public void init() { + if (pool != null) shutdown(); + maxPoolSize = ElinkConfig.getAsyncPoolMaxSize(); + initPoolSize = ElinkConfig.getAsyncPoolInitSize(); + initOnStartup = ElinkConfig.isAsyncInitOnstartup(); + + if (logger.isWarn()) { + logger.warn("<< init start - maxPoolSize = {}, initPoolSize = {}, initOnStartup = {}", maxPoolSize, initPoolSize, initOnStartup); + } + @SuppressWarnings("rawtypes") + GenericObjectPoolConfig config = new GenericObjectPoolConfig(); + HttpLoggingPoolObjectFactory factory = new HttpLoggingPoolObjectFactory(); + + config.setMaxTotal(maxPoolSize); + //config.setMinIdle(maxPoolSize); // default: 0 + //config.setMaxIdle(maxPoolSize); // default: 8 + config.setMaxWait(Duration.ofSeconds(5)); + // add proper config options +// config.setLifo(true); + pool = new GenericObjectPool(factory, config); + + if (initOnStartup) { + HttpLoggingPoolObject[] pools = new HttpLoggingPoolObject[initPoolSize]; + for (int i = 0; i < initPoolSize; i++) { + try { + logger.warn(">> borrowObject LoggingPoolObject-" + i); + pools[i] = pool.borrowObject(); + } catch (Exception e) { + // nothing to do + } + } + for (int i = 0; i < initPoolSize; i++) { + try { + logger.warn("<< returnObject LoggingPoolObject-" + i); + pool.returnObject(pools[i]); + } catch (Exception e) { + // nothing to do + } + } + } + stopped = false; + logger.warn("<< init end"); + } + + public HttpLoggingPoolObject borrowObject() throws Exception { + if (stopped) throw new PoolShutdownException(); + return pool.borrowObject(); + } + + public void returnObject(HttpLoggingPoolObject object) throws Exception { + if (stopped) throw new PoolShutdownException(); + pool.returnObject(object); + } + + public void shutdown() { + if (logger.isWarn()) { + logger.warn("<< shutdown start"); + } + int retry = 0; + + try { + if (pool != null) { + while (true) { + pool.close(); + logger.warn("close pool.getNumActive() = " + pool.getNumActive()); + if (pool.getNumActive() == 0 || retry > 10) break; + logger.warn("close - sleep 100ms"); + Thread.sleep(100); + retry++; + } + } + } catch (Exception e) { + logger.error("shutdown failed.", e); + } finally { + stopped = true; + pool = null; + } + logger.warn(">> shutdown end"); + } + + @Override + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + @Override + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + @Override + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + @Override + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICRT201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + // init pool & disruptor component + init(); + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + @Override + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICRT203"); + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + shutdown(); + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + @Override + public boolean isStarted() { + return this.started; + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/AsyncLoggingPoolManager.java b/src/main/java/com/eactive/eai/common/logger/async/AsyncLoggingPoolManager.java new file mode 100644 index 0000000..b869058 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/AsyncLoggingPoolManager.java @@ -0,0 +1,209 @@ +package com.eactive.eai.common.logger.async; + +import java.time.Duration; +import java.util.Properties; + +import org.apache.commons.pool2.ObjectPool; +import org.apache.commons.pool2.impl.GenericObjectPool; +import org.apache.commons.pool2.impl.GenericObjectPoolConfig; + +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ElinkConfig; + +public class AsyncLoggingPoolManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static AsyncLoggingPoolManager instance; + + private static boolean stopped = true; + + private int maxPoolSize = 10; + private int initPoolSize = 8; + + private boolean initOnStartup = true; + + private ObjectPool pool = null; + + /** + * 기동 여부 + */ + private boolean started; + + /** + * LifeccyleSupport object + */ + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + public static synchronized AsyncLoggingPoolManager getInstance() { + if(instance == null) { + instance = new AsyncLoggingPoolManager(); + } + return instance; + } + + public int getMaxPoolSize() { + return maxPoolSize; + } + + public void setMaxPoolSize(int maxPoolSize) { + this.maxPoolSize = maxPoolSize; + } + + public int getInitPoolSize() { + return initPoolSize; + } + + public void setInitPoolSize(int initPoolSize) { + this.initPoolSize = initPoolSize; + } + + public boolean isInitOnStartup() { + return initOnStartup; + } + + public void setInitOnStartup(boolean initOnStartup) { + this.initOnStartup = initOnStartup; + } + + public void publish(EAIMessage message, Properties prop) throws Exception { + LoggingPoolObject queue = null; + try { + queue = borrowObject(); + queue.putMessage(message, prop); + } + catch(Exception ex) { + logger.error("publish failed.", ex); + throw ex; + } + finally { + if(queue != null) returnObject(queue); + } + } + + public void init() { + if(pool != null) shutdown(); + maxPoolSize = ElinkConfig.getAsyncPoolMaxSize(); + initPoolSize = ElinkConfig.getAsyncPoolInitSize(); + initOnStartup = ElinkConfig.isAsyncInitOnstartup(); + + if(logger.isWarn()) { + logger.warn("<< init start - maxPoolSize = {}, initPoolSize = {}, initOnStartup = {}", maxPoolSize, initPoolSize, initOnStartup); + } + @SuppressWarnings("rawtypes") + GenericObjectPoolConfig config = new GenericObjectPoolConfig(); + LoggingPoolObjectFactory factory = new LoggingPoolObjectFactory(); + + config.setMaxTotal(maxPoolSize); + //config.setMinIdle(maxPoolSize); // default: 0 + //config.setMaxIdle(maxPoolSize); // default: 8 + config.setMaxWait(Duration.ofSeconds(5)); + // add proper config options +// config.setLifo(true); + pool = new GenericObjectPool(factory, config); + + if(initOnStartup) { + LoggingPoolObject[] pools = new LoggingPoolObject[initPoolSize]; + for(int i=0; i> borrowObject LoggingPoolObject-"+ i); + pools[i] = pool.borrowObject(); + } catch (Exception e) { + // nothing to do + } + } + for(int i=0; i> shutdown end"); + } + @Override + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + @Override + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + @Override + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + @Override + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICRT201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + // init pool & disruptor component + init(); + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + @Override + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICRT203"); + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + shutdown(); + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + @Override + public boolean isStarted() { + return this.started; + } + +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/CustomEventHandler.java b/src/main/java/com/eactive/eai/common/logger/async/CustomEventHandler.java new file mode 100644 index 0000000..d919060 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/CustomEventHandler.java @@ -0,0 +1,61 @@ +package com.eactive.eai.common.logger.async; + +import java.util.ArrayList; +import java.util.List; + +import com.eactive.eai.common.logger.EAILogException; +import com.eactive.eai.common.logger.EAILogSender; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; +import com.lmax.disruptor.EventHandler; + +public class CustomEventHandler implements EventHandler { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + String name; + int sleepMs; + private int batchSize = 1; + + private int count = 0; + private final List eventList = new ArrayList<>(); + + public CustomEventHandler() { + } + + public CustomEventHandler(String name, int sleepMs, int batchSize) { + this.name = name; + this.sleepMs = sleepMs; + this.batchSize = batchSize; + } + + @Override + public void onEvent(LoggingEvent event, long sequence, boolean endOfBatch) throws Exception { + if(sleepMs > 0) Thread.sleep(sleepMs); + if(batchSize > 1) { + eventList.add(event); + if (++count >= batchSize) { + processBatch(); + eventList.clear(); + count = 0; + } + } + else { + EAIMessage message = event.getMessage(); + if(logger.isInfo()) { + logger.info(String.format("CustomWorkHandler: %s LoggingEvent: %s %s\n" + ,name, message.getSvcOgNo() ,message.getLogPssSno()) + ); + } + EAILogSender.logDirect(event.getMessage(), event.getProperty()); + if(event != null) { + event.clear(); + event = null; + } + } + } + + private void processBatch() throws EAILogException { + for(LoggingEvent event:eventList) { + EAILogSender.logDirect(event.getMessage(), event.getProperty()); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/CustomThreadFactory.java b/src/main/java/com/eactive/eai/common/logger/async/CustomThreadFactory.java new file mode 100644 index 0000000..8ed8ca6 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/CustomThreadFactory.java @@ -0,0 +1,21 @@ +package com.eactive.eai.common.logger.async; +import java.util.concurrent.ThreadFactory; +public class CustomThreadFactory implements ThreadFactory { + // stores the thread count + private int count = 0; + + // returns the thread count + public int getCount() { return count; } + + // Factory method + @Override + public Thread newThread(Runnable command) { + count++; +// System.out.println( String.format(">> newThread-%d created", count) ); + return new Thread(command); + } + + public CustomThreadFactory() { + // empty + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/CustomWorkHandler.java b/src/main/java/com/eactive/eai/common/logger/async/CustomWorkHandler.java new file mode 100644 index 0000000..9dc0a1b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/CustomWorkHandler.java @@ -0,0 +1,61 @@ +package com.eactive.eai.common.logger.async; + +import java.util.ArrayList; +import java.util.List; + +import com.eactive.eai.common.logger.EAILogException; +import com.eactive.eai.common.logger.EAILogSender; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; +import com.lmax.disruptor.WorkHandler; + +public class CustomWorkHandler implements WorkHandler { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + String name; + int sleepMs; + private int batchSize = 1; + + private int count = 0; + private final List eventList = new ArrayList<>(); + + public CustomWorkHandler() { + } + + public CustomWorkHandler(String name, int sleepMs, int batchSize) { + this.name = name; + this.sleepMs = sleepMs; + this.batchSize = batchSize; + } + + @Override + public void onEvent(LoggingEvent event) throws Exception { + if(sleepMs > 0) Thread.sleep(sleepMs); + if(batchSize > 1) { + eventList.add(event); + if (++count >= batchSize) { + processBatch(); + eventList.clear(); + count = 0; + } + } + else { + EAIMessage message = event.getMessage(); + if(logger.isInfo()) { + logger.info(String.format("CustomWorkHandler: %s LoggingEvent: %s %s\n" + ,name, message.getSvcOgNo() ,message.getLogPssSno()) + ); + } + EAILogSender.logDirect(event.getMessage(), event.getProperty()); + if(event != null) { + event.clear(); + event = null; + } + } + } + + private void processBatch() throws EAILogException { + for(LoggingEvent event:eventList) { + EAILogSender.logDirect(event.getMessage(), event.getProperty()); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java b/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java new file mode 100644 index 0000000..7eb5292 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/HttpAdapterExtraLogH2Factory.java @@ -0,0 +1,122 @@ +package com.eactive.eai.common.logger.async; + +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.LogKeys; +import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; +import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import org.apache.commons.io.FilenameUtils; +import org.hibernate.Session; +import org.hibernate.SessionFactory; +import org.hibernate.cfg.Configuration; + +import java.io.File; +import java.nio.file.Files; +import java.nio.file.attribute.PosixFilePermission; +import java.nio.file.attribute.PosixFilePermissions; +import java.util.Set; +import java.util.Stack; + +public class HttpAdapterExtraLogH2Factory { + private SessionFactory sessionFactory ; + private HikariDataSource dataSource; + + private static HttpAdapterExtraLogH2Factory httpAdapterExtraLogH2Factory = new HttpAdapterExtraLogH2Factory(); + + private HttpAdapterExtraLogH2Factory(){ + sessionFactory = buildSessionFactory(); + } + + public static HttpAdapterExtraLogH2Factory getInstance(){ + return httpAdapterExtraLogH2Factory; + } + + private SessionFactory buildSessionFactory() { + try { + Configuration configuration = new Configuration(); + configuration.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect"); + configuration.setProperty("hibernate.hbm2ddl.auto", "update"); + configuration.setProperty("hibernate.show_sql", "true"); + configuration.setProperty("hibernate.format_sql", "true"); + configuration.setProperty("hibernate.use_sql_comments", "true"); + configuration.setProperty("hibernate.auto_quote_keyword", "true"); + configuration.setProperty("hibernate.globally_quoted_identifiers", "true"); + + String logBaseDirectory = PropManager.getInstance().getProperty(LogKeys.LOGGER_INFO, LogKeys.LOG_DIRECOTRY_PREFIX); + String localServer = EAIServerManager.getInstance().getLocalServerName(); + String serverLogPath = FilenameUtils.concat(logBaseDirectory, localServer); + makeDirs(serverLogPath); + String httpLogDbFilePath = FilenameUtils.concat(serverLogPath, "http_log"); + httpLogDbFilePath = httpLogDbFilePath.replace("\\", "/"); + // HikariCP 설정 + HikariConfig hikariConfig = new HikariConfig(); + hikariConfig.setDriverClassName("org.h2.Driver"); + hikariConfig.setJdbcUrl("jdbc:h2:file:"+httpLogDbFilePath); + hikariConfig.setUsername("sa"); + hikariConfig.setPassword(""); + hikariConfig.setMaximumPoolSize(20); + hikariConfig.setMinimumIdle(5); + hikariConfig.setIdleTimeout(300000); + hikariConfig.setMaxLifetime(600000); + + dataSource = new HikariDataSource(hikariConfig); + configuration.getProperties().put("hibernate.connection.datasource", dataSource); + + // 엔티티 클래스 추가 + configuration.addAnnotatedClass(HttpAdapterExtraLog.class); + configuration.addAnnotatedClass(HttpAdapterExtraHeader.class); + + return configuration.buildSessionFactory(); + } catch (Throwable ex) { + ex.printStackTrace(); + throw new ExceptionInInitializerError(ex); + } + } + + public synchronized Session openSession(){ + if(sessionFactory == null || sessionFactory.isClosed()){ + sessionFactory = buildSessionFactory(); + } + return sessionFactory.openSession(); + } + + public void closeSessionFactory() { + if (sessionFactory != null && !sessionFactory.isClosed()) { + sessionFactory.close(); + sessionFactory = null; + } + if (dataSource != null && dataSource instanceof HikariDataSource) { + dataSource.close(); + } + } + + private static void makeDirs(String path) throws Exception{ + File directory = new File(path); + + if (directory.exists()){ + return; + } + + Stack stack = new Stack(); + //check + File p = directory; + stack.push(p); + while (true){ + p = p.getParentFile(); + if (p.exists()){ + break; + }else{ + stack.push(p); + } + } + while(!stack.empty()){ + File s = stack.pop(); + s.mkdir(); + //그룹까지 rwx로 권한이 필요한 경우가 많음 필요 시 수정 할 것 + Set perms = PosixFilePermissions.fromString("rwxrwxr-x"); + Files.setPosixFilePermissions(s.toPath(), perms); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingEvent.java b/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingEvent.java new file mode 100644 index 0000000..e403c17 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingEvent.java @@ -0,0 +1,16 @@ +package com.eactive.eai.common.logger.async; + +import com.eactive.eai.common.logger.HttpAdapterExtraLogVo; +import com.lmax.disruptor.EventFactory; +import lombok.Data; + +@Data +public class HttpLoggingEvent { + private HttpAdapterExtraLogVo httpAdapterExtraLogVo; + + public final static EventFactory EVENT_FACTORY = new EventFactory() { + public HttpLoggingEvent newInstance() { + return new HttpLoggingEvent(); + } + }; +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingPoolObject.java b/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingPoolObject.java new file mode 100644 index 0000000..29b5f15 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingPoolObject.java @@ -0,0 +1,117 @@ +package com.eactive.eai.common.logger.async; + +import com.eactive.eai.common.logger.HttpAdapterExtraLogVo; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ConfigKeys; +import com.lmax.disruptor.*; +import com.lmax.disruptor.dsl.Disruptor; +import com.lmax.disruptor.dsl.ProducerType; +import org.jetbrains.annotations.NotNull; + +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +public class HttpLoggingPoolObject { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + Disruptor disruptor = null; + RingBuffer ringBuffer = null; + int id = 0; + int queueMax = (int)Math.pow(2, 10); + int workerSize = 0; + + public HttpLoggingPoolObject() { + + } + + private WaitStrategy getWaitStrategy(String waitStrategy) { + WaitStrategy ws = null; + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_BLOCK.equals(waitStrategy)) { + // throughput and low-latency are not as important as CPU resource + return new BlockingWaitStrategy(); + } + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_SLEEP.equals(waitStrategy)) { + // default : 200, 100ns +// return new SleepingWaitStrategy(); + // default : 200, 10 ms + return new SleepingWaitStrategy(200, 10 * 1000000); + } + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_TIME.equals(waitStrategy)) { + // 100ms + return new TimeoutBlockingWaitStrategy(100 * 1000, TimeUnit.MICROSECONDS); + } + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_BUSYSPIN.equals(waitStrategy)) { + // when threads can be bound to specific CPU cores. + return new BusySpinWaitStrategy(); + } + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_YIELD.equals(waitStrategy)) { + return new YieldingWaitStrategy(); + } + return ws; + } + + public HttpLoggingPoolObject(int id, int queueSize, int workerSize, String waitStrategy) { + this.id = id; + if(logger.isWarn()) { + logger.warn(String.format(">> Disruptor-%d queueSize = %d", id, queueSize)); + logger.warn(String.format(">> Disruptor-%d workerSize = %d", id, workerSize)); + logger.warn(String.format(">> Disruptor-%d waitStrategy = %s", id, waitStrategy)); + } + CustomThreadFactory tFactory = new CustomThreadFactory(); + + disruptor = new Disruptor(HttpLoggingEvent.EVENT_FACTORY, queueSize, tFactory, + ProducerType.SINGLE, + getWaitStrategy(waitStrategy)); +// BlockingWaitStrategy | SleepingWaitStrategy | YieldingWaitStrategy | BusySpinWaitStrategy + WorkHandler[] handlers = new WorkHandler[workerSize]; + for(int i=0; i< handlers.length; i++) { + WorkHandler handler = new HttpLoggingWorkHandler(); + handlers[i] = handler; + } + disruptor.handleEventsWithWorkerPool(handlers); + + try { + + logger.warn(String.format(">> disruptor-%d.start",id)); + disruptor.start(); + ringBuffer = disruptor.getRingBuffer(); + } + catch(Exception ex) { + ex.printStackTrace(); + } + finally { + ; + } + } + + public void putMessage(HttpAdapterExtraLogVo httpAdapterExtraLogVo) { + long seq = ringBuffer.next(); + try { + if(logger.isDebug()) { + logger.debug( String.format("disruptor-%d publish : ringBuffer seq = %d uuid=%s",id, seq, httpAdapterExtraLogVo.getGuid()) ); + } + HttpLoggingEvent httpLoggingEvent = ringBuffer.get(seq); + httpLoggingEvent.setHttpAdapterExtraLogVo(httpAdapterExtraLogVo); + } + finally { + ringBuffer.publish(seq); + } + } + + public void shutdown() { + if(disruptor == null) return; + while(true) { + if(queueMax == disruptor.getRingBuffer().remainingCapacity()) break; + try { + logger.warn(String.format("disruptor-%d Sleep 100 ms.", id)); + Thread.sleep(100); + } catch (InterruptedException e) { + ; + } + } + if(logger.isWarn()) { + logger.warn(String.format("<< disruptor-%d shutdown remainingCapacity : %d",id, disruptor.getRingBuffer().remainingCapacity()) ); + } + if(disruptor !=null) disruptor.shutdown(); + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingPoolObjectFactory.java b/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingPoolObjectFactory.java new file mode 100644 index 0000000..f1362c8 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingPoolObjectFactory.java @@ -0,0 +1,42 @@ +package com.eactive.eai.common.logger.async; + +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ElinkConfig; +import org.apache.commons.pool2.BasePooledObjectFactory; +import org.apache.commons.pool2.PooledObject; +import org.apache.commons.pool2.impl.DefaultPooledObject; + +public class HttpLoggingPoolObjectFactory extends BasePooledObjectFactory { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static int i = 0; + public HttpLoggingPoolObjectFactory() { + // empty + } + + @Override + public HttpLoggingPoolObject create() throws Exception { + int queueSize = ElinkConfig.getAsyncQueueSize(); + int workers = ElinkConfig.getAsyncWorkers(); + String waitStrategy = ElinkConfig.getWaitStrategy(); + return new HttpLoggingPoolObject(i++, queueSize, workers, waitStrategy); + } + + @Override + public PooledObject wrap(HttpLoggingPoolObject object) { + return new DefaultPooledObject<>(object); + } + + @Override + public void passivateObject(PooledObject pooledObject) { + // empty + } + + @Override + public void destroyObject(PooledObject pooledObject) { + HttpLoggingPoolObject loggingPoolObject = pooledObject.getObject(); + if(logger.isWarn()) { + logger.warn("destroyObject - {}", loggingPoolObject.toString()); + } + loggingPoolObject.shutdown(); + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingWorkHandler.java b/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingWorkHandler.java new file mode 100644 index 0000000..7736ba7 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/HttpLoggingWorkHandler.java @@ -0,0 +1,19 @@ +package com.eactive.eai.common.logger.async; + +import com.eactive.eai.common.logger.HttpLoggingService; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.lmax.disruptor.WorkHandler; + +public class HttpLoggingWorkHandler implements WorkHandler { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + @Override + public void onEvent(HttpLoggingEvent httpLoggingEvent) throws Exception { + HttpLoggingService service = ApplicationContextProvider.getContext().getBean(HttpLoggingService.class); + try { + service.insertHttpAdapterExtraLog( httpLoggingEvent.getHttpAdapterExtraLogVo()); + } catch (Throwable th) { + logger.error("failed to insert async http log ", th); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/LoggingEvent.java b/src/main/java/com/eactive/eai/common/logger/async/LoggingEvent.java new file mode 100644 index 0000000..ca0e4a6 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/LoggingEvent.java @@ -0,0 +1,41 @@ +package com.eactive.eai.common.logger.async; + +import java.util.Properties; + +import com.eactive.eai.common.message.EAIMessage; +import com.lmax.disruptor.EventFactory; + +public class LoggingEvent { + EAIMessage message; + Properties prop; + + public EAIMessage getMessage() { + return message; + } + + public void setMessage(EAIMessage message) { + this.message = message; + } + + public Properties getProperty() { + return prop; + } + + public void setProperty(Properties prop) { + this.prop = prop; + } + + public void clear() { + if(this.message != null) { + this.message.clear(); + } + this.message = null; + this.prop = null; + } + + public final static EventFactory EVENT_FACTORY = new EventFactory() { + public LoggingEvent newInstance() { + return new LoggingEvent(); + } + }; +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/LoggingPoolObject.java b/src/main/java/com/eactive/eai/common/logger/async/LoggingPoolObject.java new file mode 100644 index 0000000..ae3a1c7 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/LoggingPoolObject.java @@ -0,0 +1,130 @@ +package com.eactive.eai.common.logger.async; + +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ConfigKeys; +import com.lmax.disruptor.BlockingWaitStrategy; +import com.lmax.disruptor.BusySpinWaitStrategy; +import com.lmax.disruptor.RingBuffer; +import com.lmax.disruptor.SleepingWaitStrategy; +import com.lmax.disruptor.TimeoutBlockingWaitStrategy; +import com.lmax.disruptor.WaitStrategy; +import com.lmax.disruptor.WorkHandler; +import com.lmax.disruptor.YieldingWaitStrategy; +import com.lmax.disruptor.dsl.Disruptor; +import com.lmax.disruptor.dsl.ProducerType; + +public class LoggingPoolObject { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + Disruptor disruptor = null; + RingBuffer ringBuffer = null; + int id = 0; + int queueMax = (int)Math.pow(2, 10); + int workerSize = 0; + + public LoggingPoolObject() { + + } + + private WaitStrategy getWaitStrategy(String waitStrategy) { + WaitStrategy ws = null; + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_BLOCK.equals(waitStrategy)) { + // throughput and low-latency are not as important as CPU resource + return new BlockingWaitStrategy(); + } + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_SLEEP.equals(waitStrategy)) { + // default : 200, 100ns +// return new SleepingWaitStrategy(); + // default : 200, 10 ms + return new SleepingWaitStrategy(200, 10 * 1000000); + } + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_TIME.equals(waitStrategy)) { + // 100ms + return new TimeoutBlockingWaitStrategy(100 * 1000, TimeUnit.MICROSECONDS); + } + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_BUSYSPIN.equals(waitStrategy)) { + // when threads can be bound to specific CPU cores. + return new BusySpinWaitStrategy(); + } + if(ConfigKeys.LOGGER_ASYNC_WAITSTRATEGY_YIELD.equals(waitStrategy)) { + return new YieldingWaitStrategy(); + } + return ws; + } + + public LoggingPoolObject(int id, int queueSize, int workerSize, String waitStrategy) { + this.id = id; + if(logger.isWarn()) { + logger.warn(String.format(">> Disruptor-%d queueSize = %d", id, queueSize)); + logger.warn(String.format(">> Disruptor-%d workerSize = %d", id, workerSize)); + logger.warn(String.format(">> Disruptor-%d waitStrategy = %s", id, waitStrategy)); + } + CustomThreadFactory tFactory = new CustomThreadFactory(); + + disruptor = new Disruptor(LoggingEvent.EVENT_FACTORY, queueSize, tFactory, + ProducerType.SINGLE, + getWaitStrategy(waitStrategy)); +// BlockingWaitStrategy | SleepingWaitStrategy | YieldingWaitStrategy | BusySpinWaitStrategy + if(workerSize > 1) { + WorkHandler[] handlers = new WorkHandler[workerSize]; + for(int i=0; i< handlers.length; i++) { + // TODO : 현재는 delay 없이 처리하도록 하고, 추후 DB부하를 줄이려면 sleep을 정의. + CustomWorkHandler handler = new CustomWorkHandler(String.format("CustomWorkHandler%d-%d",id, i), 0, 1); + handlers[i] = handler; + } + disruptor.handleEventsWithWorkerPool(handlers); + } + else { + CustomEventHandler handler = new CustomEventHandler(String.format("CustomEventHandler%d-%d",id, 0), 0, 1); + disruptor.handleEventsWith(handler); + } + + try { + + logger.warn(String.format(">> disruptor-%d.start",id)); + disruptor.start(); + ringBuffer = disruptor.getRingBuffer(); + } + catch(Exception ex) { + ex.printStackTrace(); + } + finally { + ; + } + } + + public void putMessage(EAIMessage message, Properties prop) { + long seq = ringBuffer.next(); + try { + if(logger.isDebug()) { + logger.debug( String.format("disruptor-%d publish : ringBuffer seq = %d uuid=%s logSeq=%s",id, seq, message.getSvcOgNo() ,message.getLogPssSno()) ); + } + LoggingEvent loggingEvent = ringBuffer.get(seq); + loggingEvent.setMessage(message); + loggingEvent.setProperty(prop); + } + finally { + ringBuffer.publish(seq); + } + } + + public void shutdown() { + if(disruptor == null) return; + while(true) { + if(queueMax == disruptor.getRingBuffer().remainingCapacity()) break; + try { + logger.warn(String.format("disruptor-%d Sleep 100 ms.", id)); + Thread.sleep(100); + } catch (InterruptedException e) { + ; + } + } + if(logger.isWarn()) { + logger.warn(String.format("<< disruptor-%d shutdown remainingCapacity : %d",id, disruptor.getRingBuffer().remainingCapacity()) ); + } + if(disruptor !=null) disruptor.shutdown(); + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/async/LoggingPoolObjectFactory.java b/src/main/java/com/eactive/eai/common/logger/async/LoggingPoolObjectFactory.java new file mode 100644 index 0000000..d036a68 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/LoggingPoolObjectFactory.java @@ -0,0 +1,42 @@ +package com.eactive.eai.common.logger.async; + +import org.apache.commons.pool2.BasePooledObjectFactory; +import org.apache.commons.pool2.PooledObject; +import org.apache.commons.pool2.impl.DefaultPooledObject; + +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ElinkConfig; + +public class LoggingPoolObjectFactory extends BasePooledObjectFactory { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static int i = 0; + public LoggingPoolObjectFactory() { + // empty + } + + @Override + public LoggingPoolObject create() throws Exception { + int queueSize = ElinkConfig.getAsyncQueueSize(); + int workers = ElinkConfig.getAsyncWorkers(); + String waitStrategy = ElinkConfig.getWaitStrategy(); + return new LoggingPoolObject(i++, queueSize, workers, waitStrategy); + } + + @Override + public PooledObject wrap(LoggingPoolObject object) { + return new DefaultPooledObject<>(object); + } + + @Override + public void passivateObject(PooledObject pooledObject) { + // empty + } + @Override + public void destroyObject(PooledObject pooledObject) { + LoggingPoolObject loggingPoolObject = pooledObject.getObject(); + if(logger.isWarn()) { + logger.warn("destroyObject - {}", loggingPoolObject.toString()); + } + loggingPoolObject.shutdown(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/logger/async/PoolShutdownException.java b/src/main/java/com/eactive/eai/common/logger/async/PoolShutdownException.java new file mode 100644 index 0000000..e3ecf5e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/async/PoolShutdownException.java @@ -0,0 +1,26 @@ +package com.eactive.eai.common.logger.async; + +public class PoolShutdownException extends Exception { + + public PoolShutdownException() { + super("pool is shutdown already."); + } + + public PoolShutdownException(String message) { + super(message); + } + + public PoolShutdownException(Throwable cause) { + super(cause); + } + + public PoolShutdownException(String message, Throwable cause) { + super(message, cause); + } + + public PoolShutdownException(String message, Throwable cause, boolean enableSuppression, + boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java new file mode 100644 index 0000000..e6eabe0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraHeaderMapper.java @@ -0,0 +1,22 @@ +package com.eactive.eai.common.logger.mapper; + +import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; +import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeader; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(config = BaseMapperConfig.class) +public interface HttpAdapterExtraHeaderMapper extends GenericMapper { + + @Override + @Mapping(source = "id.name", target = "name") + HttpAdapterExtraHeaderVo toVo(HttpAdapterExtraHeader entity); + + @Override + @InheritInverseConfiguration + HttpAdapterExtraHeader toEntity(HttpAdapterExtraHeaderVo vo); +} diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java new file mode 100644 index 0000000..73ba243 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/mapper/HttpAdapterExtraLogMapper.java @@ -0,0 +1,42 @@ +package com.eactive.eai.common.logger.mapper; + +import com.eactive.eai.common.logger.HttpAdapterExtraLogVo; +import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraHeaderId; +import com.eactive.eai.data.entity.onl.logger.HttpAdapterExtraLog; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +import org.mapstruct.*; + +import java.time.DayOfWeek; +import java.time.LocalDate; +import java.util.Optional; + +@Mapper(config = BaseMapperConfig.class, uses = HttpAdapterExtraHeaderMapper.class) +public interface HttpAdapterExtraLogMapper extends GenericMapper { + + @Override + @Mapping(source = "id.guid", target = "guid") + @Mapping(source = "id.serviceProcessNumber", target = "serviceProcessNumber") + HttpAdapterExtraLogVo toVo(HttpAdapterExtraLog entity); + + @Override + @InheritInverseConfiguration + HttpAdapterExtraLog toEntity(HttpAdapterExtraLogVo vo); + + @AfterMapping + default void setHeaderIdAndWeekday(@MappingTarget HttpAdapterExtraLog entity, HttpAdapterExtraLogVo vo) { + DayOfWeek dayOfWeek = LocalDate.now().getDayOfWeek(); // 현재 요일 + int dayOfWeekNumber = dayOfWeek.getValue() % 7 + 1; // 1 (일요일)부터 7 (토요일)까지 + entity.getId().setWeekday(dayOfWeekNumber); + Optional.ofNullable(entity.getHeaderList()) + .ifPresent(headers -> headers.forEach(header -> { + if (header.getId() == null) { + header.setId(new HttpAdapterExtraHeaderId()); + } + header.getId().setWeekday(dayOfWeekNumber); + header.getId().setGuid(vo.getGuid()); + header.getId().setServiceProcessNumber(vo.getServiceProcessNumber()); + })); + } +} diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/StatAdapterLogMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/StatAdapterLogMapper.java new file mode 100644 index 0000000..4786699 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/mapper/StatAdapterLogMapper.java @@ -0,0 +1,42 @@ +package com.eactive.eai.common.logger.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; + +import com.eactive.eai.common.monitor.StatMonitorLogVO; +import com.eactive.eai.data.entity.onl.logger.StatAdapterLog; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class) +public interface StatAdapterLogMapper extends GenericMapper { + + @Mapping(source = "id.baseymd", target = "ymd") + @Mapping(source = "id.basehh", target = "hour") + @Mapping(source = "id.basehhmm", target = "min") + @Mapping(source = "id.eaibzwkdstcd", target = "bzwkDstcd") + @Mapping(source = "id.eaisvcname", target = "svcName") + @Mapping(source = "id.adptrbzwkgroupname", target = "key") + @Mapping(source = "id.eaisevrinstncname", target = "sevrInstncName") + @Mapping(source = "eaiprcssttmval", target = "prcssTtmVal", qualifiedByName = "devide") + @Mapping(source = "eaipsvprcssttmval", target = "psvPrcssTtmVal", qualifiedByName = "devide") + @Mapping(source = "eaitotalprcssttmval", target = "totalPrcssTtmVal", qualifiedByName = "devide") + @Mapping(source = "wholprcssnoitm", target = "wholPrcssNoitm") + @Mapping(source = "errznoitm", target = "errzNoitm") + @Mapping(source = "toutnoitm", target = "toutNoitm") + @Mapping(source = "nomalnoitm", target = "nomalNoitm") + @Override + StatMonitorLogVO toVo(StatAdapterLog entity); + + @Named("devide") + default Double devide(Double org) { + return org / 1000; + } + + @InheritInverseConfiguration + @Override + StatAdapterLog toEntity(StatMonitorLogVO vo); + +} diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/StatLogMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/StatLogMapper.java new file mode 100644 index 0000000..4442a9e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/mapper/StatLogMapper.java @@ -0,0 +1,41 @@ +package com.eactive.eai.common.logger.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; + +import com.eactive.eai.common.monitor.StatMonitorLogVO; +import com.eactive.eai.data.entity.onl.logger.StatLog; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class) +public interface StatLogMapper extends GenericMapper { + + @Mapping(source = "id.baseymd", target = "ymd") + @Mapping(source = "id.basehh", target = "hour") + @Mapping(source = "id.basehhmm", target = "min") + @Mapping(source = "id.eaibzwkdstcd", target = "bzwkDstcd") + @Mapping(source = "id.eaisvcname", target = "svcName") + @Mapping(source = "id.eaisevrinstncname", target = "sevrInstncName") + @Mapping(source = "eaiprcssttmval", target = "prcssTtmVal", qualifiedByName = "devide") + @Mapping(source = "eaipsvprcssttmval", target = "psvPrcssTtmVal", qualifiedByName = "devide") + @Mapping(source = "eaitotalprcssttmval", target = "totalPrcssTtmVal", qualifiedByName = "devide") + @Mapping(source = "wholprcssnoitm", target = "wholPrcssNoitm") + @Mapping(source = "errznoitm", target = "errzNoitm") + @Mapping(source = "toutnoitm", target = "toutNoitm") + @Mapping(source = "nomalnoitm", target = "nomalNoitm") + @Override + StatMonitorLogVO toVo(StatLog entity); + + @Named("devide") + default Double devide(Double org) { + return org / 1000; + } + + @InheritInverseConfiguration + @Override + StatLog toEntity(StatMonitorLogVO vo); + +} diff --git a/src/main/java/com/eactive/eai/common/logger/mapper/StatTranLogMapper.java b/src/main/java/com/eactive/eai/common/logger/mapper/StatTranLogMapper.java new file mode 100644 index 0000000..1f30efe --- /dev/null +++ b/src/main/java/com/eactive/eai/common/logger/mapper/StatTranLogMapper.java @@ -0,0 +1,42 @@ +package com.eactive.eai.common.logger.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.Named; + +import com.eactive.eai.common.monitor.StatMonitorLogVO; +import com.eactive.eai.data.entity.onl.logger.StatTranLog; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class) +public interface StatTranLogMapper extends GenericMapper { + + @Mapping(source = "id.baseymd", target = "ymd") + @Mapping(source = "id.basehh", target = "hour") + @Mapping(source = "id.basehhmm", target = "min") + @Mapping(source = "id.eaibzwkdstcd", target = "bzwkDstcd") + @Mapping(source = "id.eaisvcname", target = "svcName") + @Mapping(source = "id.intfacsendtrancd", target = "key") + @Mapping(source = "id.eaisevrinstncname", target = "sevrInstncName") + @Mapping(source = "eaiprcssttmval", target = "prcssTtmVal", qualifiedByName = "devide") + @Mapping(source = "eaipsvprcssttmval", target = "psvPrcssTtmVal", qualifiedByName = "devide") + @Mapping(source = "eaitotalprcssttmval", target = "totalPrcssTtmVal", qualifiedByName = "devide") + @Mapping(source = "wholprcssnoitm", target = "wholPrcssNoitm") + @Mapping(source = "errznoitm", target = "errzNoitm") + @Mapping(source = "toutnoitm", target = "toutNoitm") + @Mapping(source = "nomalnoitm", target = "nomalNoitm") + @Override + StatMonitorLogVO toVo(StatTranLog entity); + + @Named("devide") + default Double devide(Double org) { + return org / 1000; + } + + @InheritInverseConfiguration + @Override + StatTranLog toEntity(StatMonitorLogVO vo); + +} diff --git a/src/main/java/com/eactive/eai/common/message/AdapterType.java b/src/main/java/com/eactive/eai/common/message/AdapterType.java new file mode 100644 index 0000000..65c4da2 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/AdapterType.java @@ -0,0 +1,34 @@ +package com.eactive.eai.common.message; + +public interface AdapterType { + // SNA Response + public static final String SNAR = "SNAR"; + + // SNA No Response + public static final String SNAN = "SNAN"; + + // SNA Unsolicited + public static final String SNAU = "SNAU"; + + // IMS + public static final String IMSR = "IMSR"; + + // Socket Sync + public static final String SCKR = "SCKR"; + + // Socket Async + public static final String SCKN = "SCKN"; + + // MQ + public static final String MQIN = "MQIN"; + + // TUXEDO + public static final String TUXR = "TUXR"; + + // EJB + public static final String EJBR = "EJBR"; + + // HTTP + public static final String HTTP = "HTTP"; + +} diff --git a/src/main/java/com/eactive/eai/common/message/CondPerRtgInfo.java b/src/main/java/com/eactive/eai/common/message/CondPerRtgInfo.java new file mode 100644 index 0000000..b46a31a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/CondPerRtgInfo.java @@ -0,0 +1,55 @@ +package com.eactive.eai.common.message; + +import java.io.Serializable; + +@SuppressWarnings("serial") +public class CondPerRtgInfo implements Serializable { + + private String ruleGrpNm; // 규칙필드그룹명[TSEAIFR01.RuleFldGroupName] - RuleGroupName + private String ruleColNm; // 규칙필드명[TSEAIFR01.RuleFldName] - RuleColumnName + private String ruleCprTxt; // 비교내용[TSEAIFR01.CmprCtnt] - ServiceTimeExistenceOrNot - [Y|N] + + private String rsultPrcssNo; // 결과처리번호[TSEAIFR01.RsultPrcssNo] - ResultProcessNumber + + public CondPerRtgInfo() { + } + + public CondPerRtgInfo(String rsultPrcssNo, String ruleGrpNm, String ruleColNm, String ruleCprTxt) { + this.rsultPrcssNo = rsultPrcssNo; + this.ruleGrpNm = ruleGrpNm; + this.ruleColNm = ruleColNm; + this.ruleCprTxt = ruleCprTxt; + } + + public void setRuleGrpNm(String ruleGrpNm) { + this.ruleGrpNm = ruleGrpNm; + } + + public String getRuleGrpNm() { + return this.ruleGrpNm; + } + + public void setRuleColNm(String ruleColNm) { + this.ruleColNm = ruleColNm; + } + + public String getRuleColNm() { + return this.ruleColNm; + } + + public void setRuleCprTxt(String ruleCprTxt) { + this.ruleCprTxt = ruleCprTxt; + } + + public String getRuleCprTxt() { + return this.ruleCprTxt; + } + + public String getRsultPrcssNo() { + return this.rsultPrcssNo; + } + + public void setRsultPrcssNo(String rsultPrcssNo) { + this.rsultPrcssNo = rsultPrcssNo; + } +} diff --git a/src/main/java/com/eactive/eai/common/message/EAIMessage.java b/src/main/java/com/eactive/eai/common/message/EAIMessage.java new file mode 100644 index 0000000..255e974 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/EAIMessage.java @@ -0,0 +1,662 @@ +package com.eactive.eai.common.message; + +import java.io.Serializable; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.List; + +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.service.InterfaceMapper; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class EAIMessage implements EAIMessageKeys, Serializable, Comparable, Cloneable { + + private static final long serialVersionUID = 1L; + + private String eaiSvrInstNm; // EAI서버인스턴스명[Runtime 정보] - EAIServerInstanceName + private String eaiSvcCd; // EAI서비스명[TSEAIHE01.EAISvcName] - EAIServiceCode + private String svcTmEn; // 서비스시각유무[TSEAIHE01.SvcHMSEonot] - ServiceTimeExistenceOrNot - [Y|N] + private String svcOgNo; // 서비스고유번호 - ServiceOriginNumber - [UUID] + private String svcTsmtUsgTp; // 서비스동기사용구분코드[TSEAIHE01.SvcMotivUseDstcd] - ServiceTheSameTimeUsgaeType - [SYNC|ASYN|AKON] + private String svcPssTp; // 서비스프로세스구분명[TSEAIHE01.SvcPrcesDsticName] - ServiceProcessType - [SINGLE|COMPLEX|PCOMPLEX] + private String flwCntlRtnNm; // 흐름통제라우팅명[TSEAIHE01.FlowCtrlRoutName] - FlowControlRoutingName + private String unifTp; // 통합구분명[TSEAIHE01.IntgraDsticName] - UnificationType - [ONLINE|BATCH|FTP] + private String sngSvcCls; // 기동서비스구분 - StartingServiceClassification - [TIMER|EXCEPTION] + private int svcPssSeq = 1; // 서비스처리순서 - ServiceProcessSequence - [1,2,3, etc] + private int logPssSno; // 로그처리일련번호 - LogProcessSequenceNUmber - [100,200,300,400 | 100,211,212,221,222,...,400] + private String svcWlColLogYn; // 서비스전컬럼로그여부[TSEAIHE01.SvcBfClmnLogYn] - ServiceWholeColumnLogYesOrNo - [Y|N] + private String internalExternalDvcd; // 서비스전컬럼로그여부[TSEAIHE01.internalExternalDvcd] - [1|2] + private String bwkCls; // EAI업무구분코드[TSEAIHE01.EAIBzwkDstcd] - BusinessWorkClassification - 3|4자리 KB표준업무구분코드 사용 + private String stdMsgUsgCls; // 표준메시지사용구분[Runtime 정보] - StandardMessageUsageClassification - [Y|N] + private String sngSysItfTp; // 기동시스템어댑터업무그룹명[TSEAIHE01.GstatSysAdptrBzwkGroupName] - StartingSystemInterfaceType - [Adapter_업무명_IN] + private String lydMsgID; // 레이어메시지ID - vlf + private String rspErrCd; // 응답에러코드 - ResponseErrorCode - [12 BYTE EAI에러코드] + private String rspErrMsg; // 응답에러메시지 - ResponseErrorMessage - [ 200 BYTE ] + private long msgRcvTm; // 메시지수신시각 - MessageReceiveTime - RequestProcessor에서 설정한다. + private long msgPssTm; // 메시지처리시각 - MessageProcessTime - LOGGER에서 로깅전 설정한다. Queue로 Push하기전에... + private int svrLogLvl; // 서버로그레벨번호[TSEAIHE01.SevrLogLvelNo] - ServerLogLevel - DEFAULT(WARNING, ERROR, FATAL)-0, INFO-1, DEBUG-2 + private int svcLogLvl; // 서비스로그레벨번호[TSEAIHE01.SvcLogLvelNo] - ServiceLogLevel - [0|1|2|3] + private List svcMsgs; // 서비스처리정보리스트-ArrayList + + private InterfaceMapper mapper; + private StandardMessage standardMessage; + private StandardMessage subMessage; + + private String errEAISvcName; //오류EAI서비스명[TSEAIHE01.ErrEAISvcName] -ErrorEAIServiceName + private String dmndErrChngIDName; //요청오류변환ID명[TSEAIHE01.DmndErrChngIDName] -RequestErrorConversionID + private String dmndErrFldName; //요청에러필드명[TSEAIHE01.DmndErrFldName] -RequestErrorColumnName + private String rspnsErrChngIDName; //응답오류변환ID명[TSEAIHE01.RspnsErrChngIDName] -ResponseErrorConversionID + private String rspnsErrFldName; //응답에러필드명[TSEAIHE01.RspnsErrFldName] -ResponseErrorColumnName + + private String eaiSvcDesc; //EAI서비스 설명 [ TSEAIHE01.EAISvcDesc] + private String extBizCd; //대외업무구분코드[ TSEAIHE01.ExtBizCd] //경우에따라서는 다른컬럼이 아니라 인터페이스 앞3자리일수 있음 //TODO ※JBBEXT※ 인터페이스앞3자리 + + private String clientIp; // 요청 시스템 IP 주소 + + /** + * EAI서버구분코드 (내부-1/대외-2/공동망-3/DMZ-4/OPEN-5) + */ + private String sevrDstcd; + + /** + * 그룹회사코드 (KB0/KC0) + */ + private String groupCoCd; + + /** + * 거래처리구분 (R 실제거래/T TAS/S EAI중단거래/F TAS 기동거래/D 더미단말거래 라우팅됨) + */ + private String tranType; + + /** + * 응답변환유형(0 기본응답변환, 1 에러응답변환) + */ + private String rspnsChngMsgType; + + /** + * 거래로그때문에 추가됨 로그용 휘발성 데이터 companyCode : 업체코드 splizLength : 전문길이 adptrInstiCode + * : 어댑터기관코드명 + * + */ + private String companyCode; + private int splizLength; + private String adptrInstiCode; + private String useYn; + /** + * NexCore 용 으로 인터페이스 조회시 참조 txid : 계정계 거래코드 refKey : 대외 + * 거래코드(대외업무구분코드+전문종별+거래구분코드+기타) + */ + private String txId; // 거래ID[ TSEAIHE01.TxId] + private String refKey;// 참조KEY[ TSEAIHE01.RefKey] + + /** + * Open API 서비스시 client 별 통계용 추가 + */ + private String clientId; + + private String authType; + + private String apiEnabledYn; + + private String apiCacheYn; + + private String apiCacheType; + + private String authkeyfieldname; + + private String authCheckdYn; + + public EAIMessage() { + this.svcMsgs = new ArrayList<>(); + this.svcPssSeq = 1; + } + + public String getBwkCls() { + return bwkCls; + } + + public void setBwkCls(String bwkCls) { + this.bwkCls = bwkCls; + } + + public String getEAISvcCd() { + return eaiSvcCd; + } + + public void setEAISvcCd(String svcCd) { + eaiSvcCd = svcCd; + } + + public String getEAISvrInstNm() { + return eaiSvrInstNm; + } + + public void setEAISvrInstNm(String svrInstNm) { + eaiSvrInstNm = svrInstNm; + } + + public String getFlwCntlRtnNm() { + return flwCntlRtnNm; + } + + public void setFlwCntlRtnNm(String flwCntlRtnNm) { + this.flwCntlRtnNm = flwCntlRtnNm; + } + + public int getLogPssSno() { + return logPssSno; + } + + public void setLogPssSno(int logPssSno) { + this.logPssSno = logPssSno; + } + + public String getLydMsgID() { + return lydMsgID; + } + + public void setLydMsgID(String lydMsgID) { + this.lydMsgID = lydMsgID; + } + + public long getMsgPssTm() { + return msgPssTm; + } + + public void setMsgPssTm(long msgPssTm) { + this.msgPssTm = msgPssTm; + } + + public long getMsgRcvTm() { + return msgRcvTm; + } + + public void setMsgRcvTm(long msgRcvTm) { + this.msgRcvTm = msgRcvTm; + } + + public String getRspErrCd() { + return rspErrCd; + } + + public void setRspErrCd(String rspErrCd) { + this.rspErrCd = rspErrCd; + // -------------------------------------------- + // 에러메시지는 뒤의 9자리를 짤라서 설정한다. + // 에러코드가 아닌경우에는 설정하지 않는다 (RE ,RF ) + // 2008.04.29 + // 2008.07.10 : 8자리로 수정 + // 'S9' + 뒤에 6자리 + // 20080919 - 업무에러일 경우에도 메시지에 설정하도록 수정 + // -------------------------------------------- + + if (this.mapper != null && this.standardMessage != null && rspErrCd != null && rspErrCd.length() == 12) { + if (rspErrCd.startsWith("RE") || rspErrCd.startsWith("RF") || rspErrCd.equals(BWK_FAILMSG_CODE)) { + + // migration ExtMessage to StandardMessage + //getMapper().setErrorCode(standardMessage, rspErrCd); + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + standardManager.getMessageCoordinator().coordinateSetStandardMessageError(standardMessage, getMapper(), rspErrCd, null); + getMapper().setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_E); + + } + } + + } + + public String getRspErrMsg() { + return rspErrMsg; + } + + public void setRspErrMsg(String rspErrMsg) { + this.rspErrMsg = rspErrMsg; + + if (this.mapper != null && this.standardMessage != null && rspErrMsg != null) { + //getMapper().setErrorMsg(standardMessage, rspErrMsg); + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + standardManager.getMessageCoordinator().coordinateSetStandardMessageError(standardMessage, getMapper(), null, rspErrMsg); + } + } + + public void setRspErr(String rspErrCd, String rspErrMsg) { + this.rspErrCd = rspErrCd; + this.rspErrMsg = rspErrMsg; + if (this.mapper != null && this.standardMessage != null) {// 표준전문셋팅 + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + String stdErrCd = null; + String stdErrMsg = null; + if (rspErrCd != null && rspErrCd.length() == 12 && (rspErrCd.startsWith("RE") || rspErrCd.startsWith("RF") || rspErrCd.equals(BWK_FAILMSG_CODE))) { + stdErrCd = rspErrCd; + } + if (rspErrMsg != null) { + stdErrMsg = rspErrMsg; + } + standardManager.getMessageCoordinator().coordinateSetStandardMessageError(standardMessage, getMapper(), stdErrCd, stdErrMsg); + } + } + public String getSngSvcCls() { + return sngSvcCls; + } + + public void setSngSvcCls(String sngSvcCls) { + this.sngSvcCls = sngSvcCls; + } + + public String getSngSysItfTp() { + return sngSysItfTp; + } + + public void setSngSysItfTp(String sngSysItfTp) { + this.sngSysItfTp = sngSysItfTp; + } + + public String getStdMsgUsgCls() { + return stdMsgUsgCls; + } + + public void setStdMsgUsgCls(String stdMsgUsgCls) { + this.stdMsgUsgCls = stdMsgUsgCls; + } + + public int getSvcLogLvl() { + return svcLogLvl; + } + + public void setSvcLogLvl(int svcLogLvl) { + this.svcLogLvl = svcLogLvl; + } + + public List getSvcMsgs() { + return svcMsgs; + } + + public void setSvcMsgs(List svcMsgs) { + this.svcMsgs = svcMsgs; + } + + public void setSvcMsgs(int pos, ServiceMessage svcMsgs) { + this.svcMsgs.set(pos, svcMsgs); + } + + public void addSvcMsg(ServiceMessage svcMsg) { + this.svcMsgs.add(svcMsg); + } + + public void removeSvcMsgs() { + // 제거 후 추가시 에러 방지 - 2008.06.03 + this.svcMsgs.clear(); + } + + public void removeSvcMsg(int pos) { + this.svcMsgs.remove(pos); + } + + public ServiceMessage getCurrentSvcMsg() { + if (getSvcPssSeq() > 0) { + return this.svcMsgs.get(getSvcPssSeq() - 1); + } else { + throw new RuntimeException("EAIMessage] Invalid SvcPssSeq. - " + this.svcPssSeq); + } + } + + public ServiceMessage getNextSvcMsg() { + if (getSvcPssSeq() >= this.svcMsgs.size()) + return null; + return this.svcMsgs.get(getSvcPssSeq()); + } + + public ServiceMessage getSvcMsg(int i) { + if (i >= this.svcMsgs.size()) + return null; + return this.svcMsgs.get(i); + } + + public String getSvcOgNo() { + return svcOgNo; + } + + public void setSvcOgNo(String svcOgNo) { + this.svcOgNo = svcOgNo; + } + + public int getSvcPssSeq() { + return svcPssSeq; + } + + public void setSvcPssSeq(int svcPssSeq) { + this.svcPssSeq = svcPssSeq; + } + + public String getSvcPssTp() { + return svcPssTp; + } + + public void setSvcPssTp(String svcPssTp) { + this.svcPssTp = svcPssTp; + } + + public String getSvcTmEn() { + return svcTmEn; + } + + public void setSvcTmEn(String svcTmEn) { + this.svcTmEn = svcTmEn; + } + + public String getSvcTsmtUsgTp() { + return svcTsmtUsgTp; + } + + public void setSvcTsmtUsgTp(String svcTsmtUsgTp) { + this.svcTsmtUsgTp = svcTsmtUsgTp; + } + + public String getSvcWlColLogYn() { + return svcWlColLogYn; + } + + public void setSvcWlColLogYn(String svcWlColLogYn) { + this.svcWlColLogYn = svcWlColLogYn; + } + + public int getSvrLogLvl() { + return svrLogLvl; + } + + public void setSvrLogLvl(int svrLogLvl) { + this.svrLogLvl = svrLogLvl; + } + + public String getUnifTp() { + return unifTp; + } + + public void setUnifTp(String unifTp) { + this.unifTp = unifTp; + } + + public String getErrEAISvcName() { + return errEAISvcName; + } + + public String getDmndErrChngIDName() { + return dmndErrChngIDName; + } + + public String getDmndErrFldName() { + return dmndErrFldName; + } + + public String getRspnsErrChngIDName() { + return rspnsErrChngIDName; + } + + public String getRspnsErrFldName() { + return rspnsErrFldName; + } + + public void setErrEAISvcName(String errEAISvcName) { + this.errEAISvcName = errEAISvcName; + } + + public void setDmndErrChngIDName(String dmndErrChngIDName) { + this.dmndErrChngIDName = dmndErrChngIDName; + } + + public void setDmndErrFldName(String dmndErrFldName) { + this.dmndErrFldName = dmndErrFldName; + } + + public void setRspnsErrChngIDName(String rspnsErrChngIDName) { + this.rspnsErrChngIDName = rspnsErrChngIDName; + } + + public void setRspnsErrFldName(String rspnsErrFldName) { + this.rspnsErrFldName = rspnsErrFldName; + } + + public void setEAISvcDesc(String eaiSvcDesc) { + this.eaiSvcDesc = eaiSvcDesc; + } + + public String getEAISvcDesc() { + return eaiSvcDesc; + } + + public int compareTo(EAIMessage m) { + if (getMsgRcvTm() > m.getMsgRcvTm()) + return 1; + else if (getMsgRcvTm() == m.getMsgRcvTm()) + return 0; + return -1; + } + + public String getGroupCoCd() { + return groupCoCd; + } + + public void setGroupCoCd(String groupCoCd) { + this.groupCoCd = groupCoCd; + } + + public String getSevrDstcd() { + return sevrDstcd; + } + + public void setSevrDstcd(String sevrDstcd) { + this.sevrDstcd = sevrDstcd; + } + + public String getTranType() { + return tranType; + } + + public void setTranType(String tranType) { + this.tranType = tranType; + } + + public String getRspnsChngMsgType() { + return rspnsChngMsgType; + } + + public void setRspnsChngMsgType(String rspnsChngMsgType) { + this.rspnsChngMsgType = rspnsChngMsgType; + } + + public String getCompanyCode() { + return companyCode; + } + + public void setCompanyCode(String companyCode) { + this.companyCode = companyCode; + } + + public int getSplizLength() { + return splizLength; + } + + public void setSplizLength(int splizLength) { + this.splizLength = splizLength; + } + + public String getAdptrInstiCode() { + return adptrInstiCode; + } + + public void setAdptrInstiCode(String adptrInstiCode) { + this.adptrInstiCode = adptrInstiCode; + } + + public String getUseYn() { + return useYn; + } + + public void setUseYn(String useYn) { + this.useYn = useYn; + } + +// public ExtMessage getExtMsg() { +// return extMsg; +// } +// +// public void setExtMsg(ExtMessage extMsg) { +// this.extMsg = extMsg; +// } + public InterfaceMapper getMapper() { + return mapper; + } + + public void setMapper(InterfaceMapper mapper) { + this.mapper = mapper; + } + + public StandardMessage getStandardMessage() { + return standardMessage; + } + + public void setStandardMessage(StandardMessage standardMessage) { + this.standardMessage = standardMessage; + } + + + public StandardMessage getSubMessage() { + return subMessage; + } + + public void setSubMessage(StandardMessage subMessage) { + this.subMessage = subMessage; + } + + public String getExtBizCd() { + return extBizCd; + } + + public void setExtBizCd(String extBizCd) { + this.extBizCd = extBizCd; + } + + public String getTxId() { + return txId; + } + + public void setTxId(String txId) { + this.txId = txId; + } + + public String getRefKey() { + return refKey; + } + + public void setRefKey(String refKey) { + this.refKey = refKey; + } + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getInternalExternalDvcd() { + return internalExternalDvcd; + } + + public void setInternalExternalDvcd(String internalExternalDvcd) { + this.internalExternalDvcd = internalExternalDvcd; + } + + public String getApiEnabledYn() { + return apiEnabledYn; + } + + public void setApiEnabledYn(String apiEnabledYn) { + this.apiEnabledYn = apiEnabledYn; + } + + public String getAuthType() { + return authType; + } + + public void setAuthType(String authType) { + this.authType = authType; + } + + public String getClientIp() { + return clientIp; + } + + public void setClientIp(String clientIp) { + this.clientIp = clientIp; + } + + public String getApiCacheYn() { + return apiCacheYn; + } + + public void setApiCacheYn(String apiCacheYn) { + this.apiCacheYn = apiCacheYn; + } + + public String getApiCacheType() { + return apiCacheType; + } + + public void setApiCacheType(String apiCacheType) { + this.apiCacheType = apiCacheType; + } + + public String getAuthkeyfieldname() { + return authkeyfieldname; + } + + public void setAuthkeyfieldname(String authkeyfieldname) { + this.authkeyfieldname = authkeyfieldname; + } + + public String getAuthCheckdYn() { + return authCheckdYn; + } + + public void setAuthCheckdYn(String authCheckdYn) { + this.authCheckdYn = authCheckdYn; + } + + @Override + public Object clone() throws CloneNotSupportedException { + EAIMessage cloned = (EAIMessage) super.clone(); + if (svcMsgs != null) { + cloned.setSvcMsgs((List) ((ArrayList) svcMsgs).clone()); + } + if (mapper != null) + cloned.setMapper(mapper); + if (standardMessage != null) + cloned.setStandardMessage((StandardMessage) standardMessage.clone()); + if (subMessage != null) + cloned.setSubMessage((StandardMessage) subMessage.clone()); + return cloned; + } + + public void clear() { + String data = null; + if (standardMessage != null) { + try { + standardMessage.setBizData(data, null); + } catch (Exception e) { + ; + } + } + if (subMessage != null) { + try { + subMessage.setBizData(data, null); + } catch (Exception e) { + ; + } + } + if (svcMsgs != null) { + svcMsgs.clear(); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/message/EAIMessageDAO.java b/src/main/java/com/eactive/eai/common/message/EAIMessageDAO.java new file mode 100644 index 0000000..271ffa6 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/EAIMessageDAO.java @@ -0,0 +1,113 @@ +package com.eactive.eai.common.message; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.loader.CondPerRtgInfoLoader; +import com.eactive.eai.common.message.loader.EAIMessageLoader; +import com.eactive.eai.common.message.loader.EAIReferenceMessageLoader; +import com.eactive.eai.common.message.loader.ServiceMessageLoader; +import com.eactive.eai.common.message.mapper.CondPerRtgInfoMapper; +import com.eactive.eai.common.message.mapper.EAIMessageMapper; +import com.eactive.eai.common.message.mapper.ServiceMessageMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.message.CondPerRtgInfoEntity; +import com.eactive.eai.data.entity.onl.message.EAIMessageEntity; +import com.eactive.eai.data.entity.onl.message.EAIReferenceMessage; + +@Service +@Transactional +public class EAIMessageDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + EAIMessageLoader eaiMessageService; + + @Autowired + EAIMessageMapper eaiMessageMapper; + + @Autowired + ServiceMessageLoader serviceMessageLoader; + + @Autowired + ServiceMessageMapper serviceMessageMapper; + + @Autowired + EAIReferenceMessageLoader eaiReferenceMessageService; + + @Autowired + CondPerRtgInfoLoader condPerRtgInfoLoader; + + @Autowired + CondPerRtgInfoMapper condPerRtgInfoMapper; + + public Map getAllEAIMessages() throws DAOException { + try { + + List eaiMessageEntities = eaiMessageService.findByUseynOrderByEaisvcname("1"); + logger.info("[ @@ Load EAIMessage Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + Map eaiMessages = new HashMap<>(); + for (EAIMessageEntity eaiMessageEntity : eaiMessageEntities) { + EAIMessage eaiMessage = getEAIMessage(eaiMessageEntity); + eaiMessages.put(eaiMessage.getEAISvcCd(), eaiMessage); + } + return eaiMessages; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + private EAIMessage getEAIMessage(EAIMessageEntity eaiMessageEntity) { + EAIMessage eaiMessage = eaiMessageMapper.toVo(eaiMessageEntity); + + mapEaiReference(eaiMessageEntity, eaiMessage); + + mapCondPerRtgInfo(eaiMessageEntity, eaiMessage); + return eaiMessage; + } + + private void mapCondPerRtgInfo(EAIMessageEntity eaiMessageEntity, EAIMessage eaiMessage) { + + eaiMessageEntity.getServiceMessages().stream().forEach(serviceMessageEntity -> { + List condPerRtgInfoEntities = serviceMessageEntity.getCondPerRtgInfos(); + + List condPerRtgInfos = new ArrayList<>(); + condPerRtgInfoEntities.forEach(condPerRtgInfoEntity -> { + CondPerRtgInfo condPerRtgInfo = new CondPerRtgInfo(); + condPerRtgInfos.add(condPerRtgInfo); + }); + + ServiceMessage serviceMessage = eaiMessage.getSvcMsg(serviceMessageEntity.getId().getSvcprcssno() - 1); + serviceMessage.setCondPerRtgInfo(condPerRtgInfos); + }); + } + + private void mapEaiReference(EAIMessageEntity eaiMessageEntity, EAIMessage eaiMessage) { + + eaiMessageEntity.getServiceMessages().stream().forEach(serviceMessageEntity -> { + List eaiReferenceMessages = serviceMessageEntity.getEaiReferenceMessages(); + + String[] refmsgidnames = eaiReferenceMessages.stream().map(EAIReferenceMessage::getRefmsgidname) + .toArray(String[]::new); + + ServiceMessage serviceMessage = eaiMessage.getSvcMsg(serviceMessageEntity.getId().getSvcprcssno() - 1); + serviceMessage.setRefMsgIDs(refmsgidnames); + }); + } + + public EAIMessage getEAIMessagesByCode(String code) { + EAIMessageEntity eaiMessageEntity = eaiMessageService.getById(code); + return getEAIMessage(eaiMessageEntity); + } + +} diff --git a/src/main/java/com/eactive/eai/common/message/EAIMessageKeys.java b/src/main/java/com/eactive/eai/common/message/EAIMessageKeys.java new file mode 100644 index 0000000..64f3060 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/EAIMessageKeys.java @@ -0,0 +1,43 @@ +package com.eactive.eai.common.message; + +public interface EAIMessageKeys { + public static final String YES_FLAG = "1"; // 2005.10.18 CK Y --> 1 + public static final String NO_FLAG = "0"; // 2005.10.18 CK N --> 0 + public static final String SYNC_SVC = "SYNC"; + public static final String ASYNC_SVC = "ASYN"; + public static final String ACKONLY_SVC = "AKON"; + public static final String SINGLE_PROCESS = "SINGLE"; + public static final String PUBLISH_PROCESS = "PUB"; + public static final String COMPLEX_PROCESS = "COMPLEX"; + public static final String PARALLEL_COMPLEX_PROCESS = "PCOMPLEX"; + + // property 에 응답코드를 설정 + public static final String ELINK_RET_CODE = "ELINK_RET_CODE"; + public static final String EAI_DEFAULT_CODE = "ESBEAI111111"; + public static final String EAI_SUCCESS_CODE = "ESBEAI000000"; + public static final String EAI_BLOCKED_CODE = "RECEAIIRP070"; + public static final String EAI_INFLOW_BLOCKED_CODE = "RECEAIIRP072"; + //------------------------------------------------------------- + // 2007.07.12 DHLEE + // 강길수과장 요청 : SNATMProcess의 CAP[51] 에러인 경우에만 BWK_FAILMSG_CODE 사용 + // 업무데이터 값에 의한 오류응답메시지는 BWK_ERRMSG_CODE 를 사용 EAI_SUCCESS_CODE 와 동일한 값 + //------------------------------------------------------------- + public static final String BWK_FAILMSG_CODE = "RIBEAI999999"; + public static final String BWK_ERRMSG_CODE = "ESBEAI000000"; + //------------------------------------------------------------- + + public static final String TRANTYPE_REAL = "R"; // 실제 거래 처리 + public static final String TRANTYPE_TAS = "T"; // TAS 로 거래처리 + public static final String TRANTYPE_STOP = "S"; // EAI에서 수신만하고 STOP + public static final String TRANTYPE_FROMTAS = "F"; // TAS 기동 거래 + public static final String TRANTYPE_DUMMYROUT = "D"; // 더미단말 라우팅 + public static final String TAS_BIZ_CODE = "TAS_BIZ_CODE"; + + public static final String RSPNSCHNGMSGTYPE_RES = "0"; + public static final String RSPNSCHNGMSGTYPE_ERR = "1"; + + public static final String DUMMY_TEST_CASE_ID = "TTTTTTT"; // 'T' 7개 + + public static final String REAL_PRCSS_TIME = "REAL_PRCSS_TIME"; // 실제처리시간 + +} diff --git a/src/main/java/com/eactive/eai/common/message/EAIMessageManager.java b/src/main/java/com/eactive/eai/common/message/EAIMessageManager.java new file mode 100644 index 0000000..e408873 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/EAIMessageManager.java @@ -0,0 +1,135 @@ +package com.eactive.eai.common.message; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ObjectUtil; + +@Component +public class EAIMessageManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private Map eaiMsgs = new HashMap<>(); + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + @Autowired + EAIMessageDAO eaiMessageDAO; + + public static EAIMessageManager getInstance() { + return ApplicationContextProvider.getContext().getBean(EAIMessageManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICMM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICMM202")); + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws DAOException { + eaiMsgs = eaiMessageDAO.getAllEAIMessages(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("EAIMessageManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("EAIMessageManager] reload all finished ..."); + } + } + + public synchronized void reload(String keyName) throws Exception { + EAIMessage msg = eaiMessageDAO.getEAIMessagesByCode(keyName); + if (msg != null) { + if ("1".equals(msg.getUseYn())) { + eaiMsgs.put(keyName, msg); + } else { + eaiMsgs.remove(keyName); + logger.warn("EAIMessageManager] reload key[" + keyName + "] useYn[0] removed"); + } + } else { + throw new Exception("EAIMessage not found in Database : key[" + keyName + "]"); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICMM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + eaiMsgs.clear(); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public EAIMessage getEAIMessage(String eaiSvcCd) throws Exception { + EAIMessage aMsg = eaiMsgs.get(eaiSvcCd); + if (aMsg != null) { + try { + return (EAIMessage) ObjectUtil.deepCopy(aMsg); + } catch (Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICMM204"), e); + } + } else { + return aMsg; + } + } + + public String[] getAllEAISvcCd() { + Iterator it = this.eaiMsgs.keySet().iterator(); + String[] svcCd = new String[this.eaiMsgs.size()]; + for (int i = 0; it.hasNext(); i++) { + svcCd[i] = it.next(); + if (svcCd[i] == null) + svcCd[i] = ""; + } + Arrays.sort(svcCd); + return svcCd; + } + + public void removeEAIMessage(String code) { + eaiMsgs.remove(code); + } +} diff --git a/src/main/java/com/eactive/eai/common/message/ExtMessageKeys.java b/src/main/java/com/eactive/eai/common/message/ExtMessageKeys.java new file mode 100644 index 0000000..9286368 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/ExtMessageKeys.java @@ -0,0 +1,17 @@ +package com.eactive.eai.common.message; + +public interface ExtMessageKeys { + public static final String GROUP_HEADER = "Header"; + public static final String GROUP_STD_HEADER = "stdheader"; + public static final String FIELD_SERVICE_ID = "service_id"; + public static final String FIELD_TRAN_TYPE = "outputMesgTycd"; + public static final String GROUP_STD_COMMON = "stdcommon"; + public static final String FIELD_USERID = "usr_id"; + public static final String FIELD_DLNG_TMNL_NO = "DLNG_TMNL_NO"; + public static final String FIELD_ROFC_CD = "ROFC_CD"; + public static final String FIELD_BRN_CD = "BRN_CD"; + public static final String FIELD_RSPNS_RSLT_DVSN_CD = "RSPNS_RSLT_DVSN_CD"; + + public static final String GROUP_SYSTEM_HEADER = "systemHeader"; + public static final String FIELD_TLGR_TYP_DVSN_CD = "TLGR_TYP_DVSN_CD"; +} diff --git a/src/main/java/com/eactive/eai/common/message/IFType.java b/src/main/java/com/eactive/eai/common/message/IFType.java new file mode 100644 index 0000000..4efd30b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/IFType.java @@ -0,0 +1,19 @@ +package com.eactive.eai.common.message; + +/** +* EAI 인터페이스 타입에 대한 코드를 상수로 정의 +*/ +public interface IFType { + // Sync - Sync + public static final String SS = "SS"; + + // Async - Async + public static final String AA = "AA"; + + // Sync = Async + public static final String SA = "SA"; + + // Async - Sync + public static final String AS = "AS"; + +} diff --git a/src/main/java/com/eactive/eai/common/message/MessageType.java b/src/main/java/com/eactive/eai/common/message/MessageType.java new file mode 100644 index 0000000..cb3cdc0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/MessageType.java @@ -0,0 +1,34 @@ +package com.eactive.eai.common.message; + +/** +* 업무메시지의 타입에 대한 상수를 정의 +*/ +public interface MessageType { + // ASCII + public static final String ASC = "ASC"; + + // EBCDIC + public static final String EBC = "EBC"; + + // Java Value Object + public static final String JOB = "JOB"; + + // Tuxedo FML + public static final String FML = "FML"; + + // Tuxedo FML32 + public static final String F32 = "F32"; + + // XML + public static final String XML = "XML"; + public static final String XML_ENCODE = "euc-kr"; +// public static final String UXML = "UXL"; +// public static final String UXML_ENCODE = "utf-8"; + // EUC-KR JSON + public static final String JSON = "JSN"; + public static final String JSON_ENCODE = "euc-kr"; + // UTF-8 JSON +// public static final String UJSON = "UJN"; +// public static final String UJSON_ENCODE = "utf-8"; +} + diff --git a/src/main/java/com/eactive/eai/common/message/ServiceMessage.java b/src/main/java/com/eactive/eai/common/message/ServiceMessage.java new file mode 100644 index 0000000..731ec80 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/ServiceMessage.java @@ -0,0 +1,315 @@ +package com.eactive.eai.common.message; + +import java.io.Serializable; +import java.util.List; + +public class ServiceMessage implements EAIMessageKeys, Serializable { + private static final long serialVersionUID = 1L; + + private String eAISvcCd; // EAI서비스명[TSEAIHE02.EAISvcName] + private int svcPssSeq; // 서비스처리번호[TSEAIHE02.SvcPrcssNo] + private String psvItfTp; // 수동인터페이스구분명[TSEAIHE02.ManulIntfacDsticName] - PassiveInterfaceType - [SYNC|ASYN|AKON] + private String psvBwkSysNm; // 수동시스템업무구분코드[TSEAIHE02.ManulSysBzwkDstcd] - PassiveBusinessWorkSystemName - [ 3|4 자리 KB표준업무시스템명 사용 ] + private String psvSysID; // 수동시스템ID명[TSEAIHE02.ManulSysIDName] - PassiveSystemIdentifier - KB표준시스템ID Naming Rule을 따른다. + private String psvSysSvcCd; // 수동시스템서비스구분명[TSEAIHE02.ManulSysSvcDsticName] - PassiveSystemServiceCode - + private String psvSysItfTp; // 수동시스템어댑터업무그룹명[TSEAIHE02.ManulSysAdptrBzwkGroupName] - PassiveSystemInterfaceType -[Adapter_업무명_OUT] + private String flOvrCls; // 장애극복여부[TSEAIHE02.FlovrYn] - FailOverClassification -[Y|N] + private String cnvEn; // 변환유무[TSEAIHE02.ChngEonot] - ConversionExistenceOrNot -[Y|N] + private String cnvMsgID; // 변환메시지ID명[TSEAIHE02.ChngMsgIDName] - ConversionMessageIdentifier + private String rspMsgRefID; // 응답메시지ID - ResponseMessageReferenceIdentifier + private String bsRspMsgCprVl; // 기본응답메시지비교내용[TSEAIHE02.BascRspnsMsgCmprCtnt] - BasisResponseMessageCompareValue + private String bsRspCnvEn; // 기본응답변환유무[TSEAIHE02.BascRspnsChngEonot] - BasisResponseConversionExistenceOrNot -[Y|N] + private String bsRspCnvMsgID; // 기본응답변환메시지ID명[TSEAIHE02.BascRspnsChngMsgIDName] - BasisResponseConversionMessageIdentifier + private String errRspMsgCprVl; // 오류응답메시지비교내용[TSEAIHE02.ErrRspnsMsgCmprCtnt] - ErrorResponseMessageCompareValue + private String errRspCnvEn; // 오류응답변환유무[TSEAIHE02.ErrRspnsChngEonot] - ErrorResponseConversionExistenceOrNot -[Y|N] + private String errRspCnvMsgID; // 오류응답변환메시지ID명[TSEAIHE02.ErrRspnsChngMsgIDName] - ErrorResposneConversionIdentifier + private String keyMgtMsgVl; // 키관리메시지값 - KeyManagementMessageValue + private int nxtSvcPssSeq; // 다음서비스처리번호[TSEAIHE02.NextSvcPrcssNo] - NextServiceProcessSequence + private String outbRtnNm; // 아웃바운드라우팅명[TSEAIHE02.OutbndRoutName] - OutboundRoutingName + private int tmoVl; // 타임아웃값[TSEAIHE02.ToutVal] - TimeoutValue(단위: 초) + private String cpnsSvcPssCd; // 보상서비스처리구분명[TSEAIHE02.CmpenSvcPrcssDsticName] - CompensationServiceProcessCode + private String tmRefMsgID; // 타이머참고메시지ID - TimerReferenceMessageIdentifier + + private String supplDelYn; //추가삭제여부[TSEAIHE02.SupplDelYn] -[Y/N] + private String hdrCtrlDstcd; //헤더제어구분코드[TSEAIHE02.HdrCtrlDstcd] -[01/02]삭제추가/추가삭제 + private String hdrRefClsName; //참고틀래스명[TSEAIHE02.HdrRefClsName] -com.eactive.eai.common.header.PPSHeaderUtil + + private String restOption; //REST 옵션[TSEAIHE02.restOption] + private String timeoutCode; //REST 옵션[TSEAIHE02.timeoutCode] + + private String[] refMsgIDs; // 입력메시지IDS[TSEAIMS02.refmsgidno] - ReferenceMessageIdentifiers + private List condPerRtgInfo; // 조건부라우팅정보테이블 - ConditionPerRoutingInformationArragement - key-필드명, value-비교값 + + public String getBsRspCnvEn() { + return bsRspCnvEn; + } + + public boolean isBsRspCnvEn() { + return this.bsRspCnvEn.equals(YES_FLAG); + } + + public void setBsRspCnvEn(String bsRspCnvEn) { + this.bsRspCnvEn = bsRspCnvEn; + } + + public String getBsRspCnvMsgID() { + return bsRspCnvMsgID; + } + + public void setBsRspCnvMsgID(String bsRspCnvMsgID) { + this.bsRspCnvMsgID = bsRspCnvMsgID; + } + + public String getBsRspMsgCprVl() { + return bsRspMsgCprVl; + } + + public void setBsRspMsgCprVl(String bsRspMsgCprVl) { + this.bsRspMsgCprVl = bsRspMsgCprVl; + } + + public String getCnvEn() { + return cnvEn; + } + + public boolean isCnvEn() { + return this.cnvEn.equals(YES_FLAG); + } + + public void setCnvEn(String cnvEn) { + this.cnvEn = cnvEn; + } + + public String getCnvMsgID() { + return cnvMsgID; + } + + public void setCnvMsgID(String cnvMsgID) { + this.cnvMsgID = cnvMsgID; + } + + public List getCondPerRtgInfo() { + return condPerRtgInfo; + } + + public boolean hasCondPerRtgInfo() { + return (this.condPerRtgInfo != null && !this.condPerRtgInfo.isEmpty()); + } + + public void setCondPerRtgInfo(List condPerRtgInfo) { + this.condPerRtgInfo = condPerRtgInfo; + } + + public String getCpnsSvcPssCd() { + return cpnsSvcPssCd; + } + + public void setCpnsSvcPssCd(String cpnsSvcPssCd) { + this.cpnsSvcPssCd = cpnsSvcPssCd; + } + + public String getErrRspCnvEn() { + return errRspCnvEn; + } + + public boolean isErrRspCnvEn() { + return this.errRspCnvEn.equals(YES_FLAG); + } + + public void setErrRspCnvEn(String errRspCnvEn) { + this.errRspCnvEn = errRspCnvEn; + } + + public String getErrRspCnvMsgID() { + return errRspCnvMsgID; + } + + public void setErrRspCnvMsgID(String errRspCnvMsgID) { + this.errRspCnvMsgID = errRspCnvMsgID; + } + + public String getErrRspMsgCprVl() { + return errRspMsgCprVl; + } + + public void setErrRspMsgCprVl(String errRspMsgCprVl) { + this.errRspMsgCprVl = errRspMsgCprVl; + } + + public String getFlOvrCls() { + return flOvrCls; + } + + public boolean hasFailOver() { + return this.flOvrCls.equals(YES_FLAG); + } + + public void setFlOvrCls(String flOvrCls) { + this.flOvrCls = flOvrCls; + } + + public String getKeyMgtMsgVl() { + return keyMgtMsgVl; + } + + public void setKeyMgtMsgVl(String keyMgtMsgVl) { + this.keyMgtMsgVl = keyMgtMsgVl; + } + + public int getNxtSvcPssSeq() { + return nxtSvcPssSeq; + } + + public void setNxtSvcPssSeq(int nxtSvcPssSeq) { + this.nxtSvcPssSeq = nxtSvcPssSeq; + } + + public String getOutbRtnNm() { + return outbRtnNm; + } + + public void setOutbRtnNm(String outbRtnNm) { + this.outbRtnNm = outbRtnNm; + } + + public String getPsvBwkSysNm() { + return psvBwkSysNm; + } + + public void setPsvBwkSysNm(String psvBwkSysNm) { + this.psvBwkSysNm = psvBwkSysNm; + } + + public String getPsvItfTp() { + return psvItfTp; + } + + public boolean isSyncItfTp() { + return this.psvItfTp.equals(SYNC_SVC); + } + + public boolean isAckItfTp() { + return this.psvItfTp.equals(ACKONLY_SVC); + } + + public void setPsvItfTp(String psvItfTp) { + this.psvItfTp = psvItfTp; + } + + public String getPsvSysID() { + return psvSysID; + } + + public void setPsvSysID(String psvSysID) { + this.psvSysID = psvSysID; + } + + public String getPsvSysItfTp() { + return psvSysItfTp; + } + + public void setPsvSysItfTp(String psvSysItfTp) { + this.psvSysItfTp = psvSysItfTp; + } + + public String getPsvSysSvcCd() { + return psvSysSvcCd; + } + + public void setPsvSysSvcCd(String psvSysSvcCd) { + this.psvSysSvcCd = psvSysSvcCd; + } + + public String[] getRefMsgIDs() { + return refMsgIDs; + } + + public void setRefMsgIDs(String[] refMsgIDs) { + this.refMsgIDs = refMsgIDs; + } + + public String getRspMsgRefID() { + return rspMsgRefID; + } + + public void setRspMsgRefID(String rspMsgRefID) { + this.rspMsgRefID = rspMsgRefID; + } + + public int getTmoVl() { + return tmoVl; + } + + public boolean hasTimeOut() { + return (this.tmoVl > 0); + } + + public void setTmoVl(int tmoVl) { + this.tmoVl = tmoVl; + } + + public String getTmRefMsgID() { + return tmRefMsgID; + } + + public void setTmRefMsgID(String tmRefMsgID) { + this.tmRefMsgID = tmRefMsgID; + } + + public String getEAISvcCd() { + return eAISvcCd; + } + + public void setEAISvcCd(String svcCd) { + eAISvcCd = svcCd; + } + + public int getSvcPssSeq() { + return svcPssSeq; + } + + public void setSvcPssSeq(int seq) { + svcPssSeq = seq; + } + + public String getHdrCtrlDstcd() { + return hdrCtrlDstcd; + } + + public void setHdrCtrlDstcd(String hdrCtrlDstcd) { + this.hdrCtrlDstcd = hdrCtrlDstcd; + } + + public String getHdrRefClsName() { + return hdrRefClsName; + } + + public void setHdrRefClsName(String hdrRefClsName) { + this.hdrRefClsName = hdrRefClsName; + } + + public String getSupplDelYn() { + return supplDelYn; + } + + public void setSupplDelYn(String supplDelYn) { + this.supplDelYn = supplDelYn; + } + + public String getRestOption() { + return restOption; + } + + public void setRestOption(String restOption) { + this.restOption = restOption; + } + + public String getTimeoutCode() { + return timeoutCode; + } + + public void setTimeoutCode(String timeoutCode) { + this.timeoutCode = timeoutCode; + } + +} diff --git a/src/main/java/com/eactive/eai/common/message/mapper/CondPerRtgInfoMapper.java b/src/main/java/com/eactive/eai/common/message/mapper/CondPerRtgInfoMapper.java new file mode 100644 index 0000000..6245f22 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/mapper/CondPerRtgInfoMapper.java @@ -0,0 +1,25 @@ +package com.eactive.eai.common.message.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import com.eactive.eai.common.message.CondPerRtgInfo; +import com.eactive.eai.data.entity.onl.message.CondPerRtgInfoEntity; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class) +public interface CondPerRtgInfoMapper extends GenericMapper { + @Mapping(source = "cmprctnt", target = "ruleCprTxt") + @Mapping(source = "rsultprcssno", target = "rsultPrcssNo") + @Mapping(source = "rulefldgroupname", target = "ruleGrpNm") + @Mapping(source = "rulefldname", target = "ruleColNm") + + @Override + CondPerRtgInfo toVo(CondPerRtgInfoEntity entity); + + @InheritInverseConfiguration + CondPerRtgInfoEntity toEntity(CondPerRtgInfo vo); + +} diff --git a/src/main/java/com/eactive/eai/common/message/mapper/EAIMessageMapper.java b/src/main/java/com/eactive/eai/common/message/mapper/EAIMessageMapper.java new file mode 100644 index 0000000..48d3da1 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/mapper/EAIMessageMapper.java @@ -0,0 +1,52 @@ +package com.eactive.eai.common.message.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.data.entity.onl.message.EAIMessageEntity; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class, uses = ServiceMessageMapper.class) +public interface EAIMessageMapper extends GenericMapper { + + @Mapping(source = "eaisvcname", target = "EAISvcCd") + @Mapping(source = "eaibzwkdstcd", target = "bwkCls") + @Mapping(source = "svchmseonot", target = "svcTmEn") + @Mapping(source = "svcmotivusedstcd", target = "svcTsmtUsgTp") + @Mapping(source = "svcprcesdsticname", target = "svcPssTp") + @Mapping(source = "flowctrlroutname", target = "flwCntlRtnNm") + @Mapping(source = "intgradsticname", target = "unifTp") + @Mapping(source = "svcbfclmnlogyn", target = "svcWlColLogYn") + @Mapping(source = "gstatsysadptrbzwkgroupname", target = "sngSysItfTp") + @Mapping(source = "sevrloglvelno", target = "svrLogLvl") + @Mapping(source = "svcloglvelno", target = "svcLogLvl") + @Mapping(source = "erreaisvcname", target = "errEAISvcName") + @Mapping(source = "dmnderrchngidname", target = "dmndErrChngIDName") + @Mapping(source = "dmnderrfldname", target = "dmndErrFldName") + @Mapping(source = "rspnserrchngidname", target = "rspnsErrChngIDName") + @Mapping(source = "rspnserrfldname", target = "rspnsErrFldName") + @Mapping(source = "eaisvcdesc", target = "EAISvcDesc") + @Mapping(source = "eaisevrdstcd", target = "sevrDstcd") + @Mapping(source = "eaigroupcocd", target = "groupCoCd") + @Mapping(source = "trantype", target = "tranType") + @Mapping(source = "useyn", target = "useYn") + @Mapping(source = "txid", target = "txId") + @Mapping(source = "refkey", target = "refKey") + @Mapping(source = "extbizcd", target = "extBizCd") + @Mapping(source = "internalexternaldvcd", target = "internalExternalDvcd") + @Mapping(source = "apienabledyn", target = "apiEnabledYn") + @Mapping(source = "authtype", target = "authType") + @Mapping(source = "serviceMessages", target = "svcMsgs") + @Mapping(source = "apicacheyn", target = "apiCacheYn") + @Mapping(source = "apicachetype", target = "apiCacheType") + @Mapping(source = "authcheckdyn", target = "authCheckdYn") + @Override + EAIMessage toVo(EAIMessageEntity entity); + + @InheritInverseConfiguration + EAIMessageEntity toEntity(EAIMessage vo); + +} diff --git a/src/main/java/com/eactive/eai/common/message/mapper/EAIReferenceMessageMapper.java b/src/main/java/com/eactive/eai/common/message/mapper/EAIReferenceMessageMapper.java new file mode 100644 index 0000000..0791b9a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/mapper/EAIReferenceMessageMapper.java @@ -0,0 +1,22 @@ +package com.eactive.eai.common.message.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import com.eactive.eai.common.message.ServiceMessage; +import com.eactive.eai.data.entity.onl.message.EAIReferenceMessage; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class) +public interface EAIReferenceMessageMapper extends GenericMapper { + @Mapping(source = "id.eaisvcname", target = "EAISvcCd") + @Mapping(source = "id.svcprcssno", target = "svcPssSeq") + @Mapping(target = "id.refmsgidno", expression = "java(mapRefMsgIDsToRefMsgIdNo(vo.getRefMsgIDs())") + @Override + ServiceMessage toVo(EAIReferenceMessage entity); + + @InheritInverseConfiguration + EAIReferenceMessage toEntity(ServiceMessage vo); +} diff --git a/src/main/java/com/eactive/eai/common/message/mapper/ServiceMessageMapper.java b/src/main/java/com/eactive/eai/common/message/mapper/ServiceMessageMapper.java new file mode 100644 index 0000000..a4b235f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/message/mapper/ServiceMessageMapper.java @@ -0,0 +1,46 @@ +package com.eactive.eai.common.message.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import com.eactive.eai.common.message.ServiceMessage; +import com.eactive.eai.data.entity.onl.message.ServiceMessageEntity; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class, uses = EAIReferenceMessageMapper.class) +public interface ServiceMessageMapper extends GenericMapper { + @Mapping(source = "id.eaisvcname", target = "EAISvcCd") + @Mapping(source = "id.svcprcssno", target = "svcPssSeq") + @Mapping(source = "psvintfacdsticname", target = "psvItfTp") + @Mapping(source = "psvsysbzwkdstcd", target = "psvBwkSysNm") + @Mapping(source = "psvsysidname", target = "psvSysID") + @Mapping(source = "psvsyssvcdsticname", target = "psvSysSvcCd") + @Mapping(source = "psvsysadptrbzwkgroupname", target = "psvSysItfTp") + @Mapping(source = "flovryn", target = "flOvrCls") + @Mapping(source = "chngeonot", target = "cnvEn") + @Mapping(source = "chngmsgidname", target = "cnvMsgID") + @Mapping(source = "bascrspnsmsgcmprctnt", target = "bsRspMsgCprVl") + @Mapping(source = "bascrspnschngeonot", target = "bsRspCnvEn") + @Mapping(source = "bascrspnschngmsgidname", target = "bsRspCnvMsgID") + @Mapping(source = "errrspnsmsgcmprctnt", target = "errRspMsgCprVl") + @Mapping(source = "errrspnschngeonot", target = "errRspCnvEn") + @Mapping(source = "errrspnschngmsgidname", target = "errRspCnvMsgID") + @Mapping(source = "nextsvcprcssno", target = "nxtSvcPssSeq") + @Mapping(source = "outbndroutname", target = "outbRtnNm") + @Mapping(source = "toutval", target = "tmoVl") + @Mapping(source = "cmpensvcprcssdsticname", target = "cpnsSvcPssCd") + @Mapping(source = "suppldelyn", target = "supplDelYn") + @Mapping(source = "hdrctrldstcd", target = "hdrCtrlDstcd") + @Mapping(source = "hdrrefclsname", target = "hdrRefClsName") + @Mapping(source = "restoption", target = "restOption") + @Mapping(source = "timeoutcode", target = "timeoutCode") + @Override + ServiceMessage toVo(ServiceMessageEntity entity); + + @InheritInverseConfiguration + @Override + ServiceMessageEntity toEntity(ServiceMessage vo); + +} diff --git a/src/main/java/com/eactive/eai/common/messagekey/MessageKeyDAO.java b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyDAO.java new file mode 100644 index 0000000..0847085 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyDAO.java @@ -0,0 +1,121 @@ +package com.eactive.eai.common.messagekey; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.messagekey.loader.MessageKeyLoader; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.messagekey.MessageKey; + +@Service +@Transactional +public class MessageKeyDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private MessageKeyLoader messageKeyLoader; + + public Map getAllMessageKeys() throws DAOException { + try { + Map messageKeyMap = new HashMap<>(); + List messageKeys = messageKeyLoader.loadAllByOrderByDefault(); + if (logger.isInfo()) + logger.info("[ @@ Load MessageKey Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + String current = null, previous = null; + int currentGroup = 0; + int previousGroup = 0; + MessageKeyVO msgKey = null; + MessageKeyGroupVO msgGroup = null; + for (MessageKey messageKey : messageKeys) { + current = messageKey.getId().getAdptrbzwkgroupname() + messageKey.getId().getIodstcd(); + currentGroup = messageKey.getId().getGroupinorno(); + + if (!current.equals(previous)) { + msgKey = new MessageKeyVO(current, messageKey.getId().getMsgdstcd(), + messageKey.getId().getIodstcd()); + messageKeyMap.put(current, msgKey); + previous = current; + msgGroup = new MessageKeyGroupVO(); + msgKey.addMessageKeyGroup(msgGroup); + previousGroup = currentGroup; + } else { + if (currentGroup != previousGroup) { + msgGroup = new MessageKeyGroupVO(); + msgKey.addMessageKeyGroup(msgGroup); + previousGroup = currentGroup; + } + } + msgGroup.addMessageKeyFld(messageKey.getId().getGroupinorno(), messageKey.getId().getFldprcssno(), + messageKey.getBzwkfldname(), messageKey.getClsname(), + messageKey.getMsgfldstartsituval().intValue(), messageKey.getMsgfldlen(), + messageKey.getNomalprcssctnt()); + } + if (logger.isInfo()) { +// messageKeyMap.entrySet().forEach( entry -> logger.info("@ " + entry.getValue().toString()) ); + logger.info("[>>Load MessageKey Configuration - ended ]"); + } + return messageKeyMap; + } catch (Exception e) { + logger.error("getAllMessageKeys Error", e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMK101")); + } + } + + public MessageKeyVO getMessageKey(String adptrBzwkGroupName, String ioDstcd) throws DAOException { + + try { + List messageKeys = messageKeyLoader + .selectMessageKeyByNameAndIoDstCode(adptrBzwkGroupName, ioDstcd); + + String current = null, previous = null; + + int currentGroup = 0; + int previousGroup = 0; + + MessageKeyVO msgKey = null; + MessageKeyGroupVO msgGroup = null; + + for (MessageKey messageKey : messageKeys) { + current = messageKey.getId().getAdptrbzwkgroupname() + messageKey.getId().getIodstcd(); + currentGroup = messageKey.getId().getGroupinorno(); + + if (!current.equals(previous)) { + msgKey = new MessageKeyVO(current, messageKey.getId().getMsgdstcd(), + messageKey.getId().getIodstcd()); + previous = current; + msgGroup = new MessageKeyGroupVO(); + msgKey.addMessageKeyGroup(msgGroup); + previousGroup = currentGroup; + } else { + if (currentGroup != previousGroup) { + msgGroup = new MessageKeyGroupVO(); + msgKey.addMessageKeyGroup(msgGroup); + previousGroup = currentGroup; + } + } + msgGroup.addMessageKeyFld(messageKey.getId().getGroupinorno(), messageKey.getId().getFldprcssno(), + messageKey.getBzwkfldname(), messageKey.getClsname(), + messageKey.getMsgfldstartsituval().intValue(), messageKey.getMsgfldlen(), + messageKey.getNomalprcssctnt()); + } + return msgKey; + } catch (Exception e) { + + String[] msgArgs = { adptrBzwkGroupName, ioDstcd }; + String errorText = ExceptionUtil.make("RECEAICMK107", msgArgs); + if (logger.isError()) + logger.error(errorText); + throw new DAOException(errorText); + } + } + +} diff --git a/src/main/java/com/eactive/eai/common/messagekey/MessageKeyFldVO.java b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyFldVO.java new file mode 100644 index 0000000..5503890 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyFldVO.java @@ -0,0 +1,100 @@ +package com.eactive.eai.common.messagekey; + +import java.io.Serializable; + +public class MessageKeyFldVO implements Serializable { + private static final long serialVersionUID = 1L; + private String bwkColNm; // 업무필드명[TSEAIFR04.BzwkFldName] + private String bwkClassNm; // 클래스명[TSEAIFR04.ClsName] + private int bwkColStart; // 메시지필드시작위치값[TSEAIFR04.MsgFldStartSituVal] + private int bwkColLength; // 메시지필드길이[TSEAIFR04.MsgFldLen] + private String bwkColDef; // 정상처리내용[TSEAIFR04.NomalPrcssCtnt] + + private int groupSeq; // 업무필드명[TSEAIFR04.GroupInorNo] - UI를 위한 Option Field + private int fieldSeq; // 업무필드명[TSEAIFR04.FldPrcssNo] - UI를 위한 Option Field + + public MessageKeyFldVO(int groupSeq, int fieldSeq, String bwkColNm, String bwkClassNm, int bwkColStart, + int bwkColLength, String bwkColDef) { + this.groupSeq = groupSeq; + this.fieldSeq = fieldSeq; + this.bwkColNm = bwkColNm; + this.bwkClassNm = bwkClassNm; + this.bwkColStart = bwkColStart; + this.bwkColLength = bwkColLength; + this.bwkColDef = bwkColDef; + } + + public MessageKeyFldVO(String bwkColNm, String bwkClassNm, int bwkColStart, int bwkColLength, String bwkColDef) { + this.groupSeq = 0; + this.fieldSeq = 0; + this.bwkColNm = bwkColNm; + this.bwkClassNm = bwkClassNm; + this.bwkColStart = bwkColStart; + this.bwkColLength = bwkColLength; + this.bwkColDef = bwkColDef; + } + + public void setBwkColNm(String bwkColNm) { + this.bwkColNm = bwkColNm; + } + + public String getBwkColNm() { + return this.bwkColNm; + } + + public void setBwkClassNm(String bwkClassNm) { + this.bwkClassNm = bwkClassNm; + } + + public String getBwkClassNm() { + return this.bwkClassNm; + } + + public void setBwkColStart(int bwkColStart) { + this.bwkColStart = bwkColStart; + } + + public int getBwkColStart() { + return this.bwkColStart; + } + + public void setBwkColLength(int bwkColLength) { + this.bwkColLength = bwkColLength; + } + + public int getBwkColLength() { + return this.bwkColLength; + } + + public void setBwkColDef(String bwkColDef) { + this.bwkColDef = bwkColDef; + } + + public String getBwkColDef() { + return this.bwkColDef; + } + + public int getFieldSeq() { + return fieldSeq; + } + + public void setFieldSeq(int fieldSeq) { + this.fieldSeq = fieldSeq; + } + + public int getGroupSeq() { + return groupSeq; + } + + public void setGroupSeq(int groupSeq) { + this.groupSeq = groupSeq; + } + + @Override + public String toString() { + return "MessageKeyFldVO [bwkColNm=" + bwkColNm + ", bwkClassNm=" + bwkClassNm + ", bwkColStart=" + bwkColStart + + ", bwkColLength=" + bwkColLength + ", bwkColDef=" + bwkColDef + ", groupSeq=" + groupSeq + + ", fieldSeq=" + fieldSeq + "]"; + } + +} diff --git a/src/main/java/com/eactive/eai/common/messagekey/MessageKeyGroupVO.java b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyGroupVO.java new file mode 100644 index 0000000..dd81f88 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyGroupVO.java @@ -0,0 +1,55 @@ +package com.eactive.eai.common.messagekey; + +import java.io.Serializable; +import java.util.ArrayList; + +public class MessageKeyGroupVO implements Serializable { + private static final long serialVersionUID = 1L; + private ArrayList alMsgFlds; + + public MessageKeyGroupVO() { + alMsgFlds = new ArrayList<>(); + } + + public MessageKeyFldVO getMessageKeyFld(int key) { + return alMsgFlds.get(key); + } + + public void addMessageKeyFld(String bwkColNm, String bwkClassNm, int bwkColStart, int bwkColLength) { + this.alMsgFlds.add(new MessageKeyFldVO(bwkColNm, bwkClassNm, bwkColStart, bwkColLength, "")); + } + + public void addMessageKeyFld(int groupSeq, int fieldSeq, String bwkColNm, String bwkClassNm, int bwkColStart, int bwkColLength) { + this.alMsgFlds.add(new MessageKeyFldVO(groupSeq, fieldSeq, bwkColNm, bwkClassNm, bwkColStart, bwkColLength, "")); + } + + public void addMessageKeyFld(String bwkColNm, String bwkClassNm, int bwkColStart, int bwkColLength, String bwkColDef) { + MessageKeyFldVO vo = new MessageKeyFldVO(bwkColNm, bwkClassNm, bwkColStart, bwkColLength, bwkColDef); + this.alMsgFlds.add(vo); + } + + public void addMessageKeyFld(int groupSeq, int fieldSeq, String bwkColNm, String bwkClassNm, int bwkColStart, int bwkColLength, String bwkColDef) { + MessageKeyFldVO vo = new MessageKeyFldVO(groupSeq, fieldSeq, bwkColNm, bwkClassNm, bwkColStart, bwkColLength, bwkColDef); + this.alMsgFlds.add(vo); + } + + public void addMessageKeyFld(int fieldSeq, String bwkColNm, String bwkClassNm, int bwkColStart, int bwkColLength, String bwkColDef) { + MessageKeyFldVO vo = new MessageKeyFldVO(bwkColNm, bwkClassNm, bwkColStart, bwkColLength, bwkColDef); + this.alMsgFlds.add(fieldSeq-1, vo); + } + + public int getMessageKeyFldLength() { + return this.alMsgFlds.size(); + } + + @Override + public String toString() { + return "MessageKeyGroupVO [alMsgFlds=" + printMessageFields() + "]"; + } + + private String printMessageFields() { + StringBuilder sb = new StringBuilder(); + alMsgFlds.forEach( field -> sb.append(field.toString()).append("\n | ") ); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/common/messagekey/MessageKeyManager.java b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyManager.java new file mode 100644 index 0000000..5c59334 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyManager.java @@ -0,0 +1,164 @@ +package com.eactive.eai.common.messagekey; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.dao.DAOFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.routing.RoutingDAO; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class MessageKeyManager implements Lifecycle { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private Map messages = new HashMap<>(); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private boolean started; + + @Autowired + private MessageKeyDAO messageKeyDAO; + + public static MessageKeyManager getInstance() { + return ApplicationContextProvider.getContext().getBean(MessageKeyManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICMK201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICMK202")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + messages = null; + messages = messageKeyDAO.getAllMessageKeys(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("MessageKeyManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("MessageKeyManager] reload all finished ..."); + } + } + + public MessageKeyVO getMessageKey(String adptrBzwkGroupName, String ioDstcd) throws DAOException { + return messageKeyDAO.getMessageKey(adptrBzwkGroupName, ioDstcd); + } + + public synchronized void reload(String adptrBzwkGroupName, String ioDstcd) throws Exception { + if (logger.isWarn()) { + logger.warn("MessageKeyManager] reload part : " + adptrBzwkGroupName + "," + ioDstcd + " Started ..."); + } + + if (adptrBzwkGroupName != null && ioDstcd != null) { + MessageKeyVO vo = getMessageKey(adptrBzwkGroupName, ioDstcd); + messages.put(vo.getName(), vo); + } else { + throw new Exception("keyName format error " + adptrBzwkGroupName + "," + ioDstcd); + } + if (logger.isWarn()) { + logger.warn("MessageKeyManager] reload " + adptrBzwkGroupName + "," + ioDstcd + " finished ..."); + } + } + + /** + * 어댑터 CM 반영할때 쓰이는 용도 + */ + public synchronized void reload(String adptrBzwkGroupName) throws Exception { + if (logger.isWarn()) { + logger.warn("MessageKeyManager] reload " + adptrBzwkGroupName + " Started ..."); + } + + if (adptrBzwkGroupName != null) { + MessageKeyVO vo = getMessageKey(adptrBzwkGroupName, "I"); + if (vo != null) { + messages.put(vo.getName(), vo); + } + vo = getMessageKey(adptrBzwkGroupName, "O"); + if (vo != null) { + messages.put(vo.getName(), vo); + } + } else { + throw new Exception("keyName format error " + adptrBzwkGroupName); + } + if (logger.isWarn()) { + logger.warn("MessageKeyManager] reload " + adptrBzwkGroupName + " finished ..."); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICMK203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + messages.clear(); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public MessageKeyVO getMessageKey(String code) { + return messages.get(code); + } + + public void setMessageKey(String code, MessageKeyVO msg) { + messages.put(code, msg); + } + + public void updateMessageKey(String code, MessageKeyVO msg) { + messages.put(code, msg); + } + + public void removeMessageKey(String code) { + messages.remove(code); + } + + public String[] getAllKeyNames() { + String[] names = this.messages.keySet().toArray(new String[0]); + Arrays.sort(names); + return names; + } +} diff --git a/src/main/java/com/eactive/eai/common/messagekey/MessageKeyVO.java b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyVO.java new file mode 100644 index 0000000..4411668 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/messagekey/MessageKeyVO.java @@ -0,0 +1,96 @@ +package com.eactive.eai.common.messagekey; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +// 어댑터에서 사용되는 메시지의 Key 추출 정보 +public class MessageKeyVO implements Serializable { + private static final long serialVersionUID = 1L; + private String name; // 어댑터업무그룹명[TSEAIFR04.AdptrBzwkGroupName] + private String msgTp; // 메시지구분코드[TSEAIFR04.MsgDstcd] + private String exrTp; // 입출력구분코드[TSEAIFR04.IODstcd] + + private int currentGroupKey; // 메모리정보 + + private List alMsgGroups = new ArrayList<>(); + + public List getAlMsgGroups() { + return alMsgGroups; + } + + public void setAlMsgGroups(List alMsgGroups) { + this.alMsgGroups = alMsgGroups; + } + + public void setMessageKeyGroup(int key, MessageKeyGroupVO vo) { + this.alMsgGroups.set(key, vo); + } + + public MessageKeyGroupVO getMessageKeyGroup(int key) { + return alMsgGroups.get(key); + } + + public void addMessageKeyGroup(MessageKeyGroupVO vo) { + this.alMsgGroups.add(vo); + } + + public int getCurrentGroupKey() { + return currentGroupKey; + } + + public void setCurrentGroupKey(int currentGroupKey) { + this.currentGroupKey = currentGroupKey; + } + + public MessageKeyVO() { + this(""); + } + + public MessageKeyVO(String name) { + this(name, "", ""); + } + + public MessageKeyVO(String name, String msgTp, String exrTp) { + this.name = name; + this.msgTp = msgTp; + this.exrTp = exrTp; + this.alMsgGroups = new ArrayList(); + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return this.name; + } + + public void setMsgTp(String msgTp) { + this.msgTp = msgTp; + } + + public String getMsgTp() { + return this.msgTp; + } + + public void setExrTp(String exrTp) { + this.exrTp = exrTp; + } + + public String getExrTp() { + return this.exrTp; + } + + @Override + public String toString() { + return "MessageKeyVO [name=" + name + ", msgTp=" + msgTp + ", exrTp=" + exrTp + ", currentGroupKey=" + + currentGroupKey + ", \n alMsgGroups=" + printMessageGroups() + "\n]"; + } + + private String printMessageGroups() { + StringBuilder sb = new StringBuilder(); + alMsgGroups.forEach(group -> sb.append(group.toString()).append("\n | ")); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/common/monitor/EAIServiceMonitor.java b/src/main/java/com/eactive/eai/common/monitor/EAIServiceMonitor.java new file mode 100644 index 0000000..ce3628b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/monitor/EAIServiceMonitor.java @@ -0,0 +1,709 @@ +package com.eactive.eai.common.monitor; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Timer; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.errorcode.ErrorCodeHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.EAIMessageManager; +import com.eactive.eai.common.message.IFType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; + +/** + * EAIServiceMonitor 컴포넌트는 EAI 모든 거래 마다 각 EAI Service Code 기준으로 처리 통계 데이터를 캐싱 - + * 일 누적 데이터와 최근(10분, 1시간) 누적데이터를 각 EAIServiceCode 별로 MonitorVO 객체로 관리 - 일 누적 + * 데이터와 최근(10분, 1시간) 누적 데이터를 초기화하기 위해 TimerTaskChecker 쓰레드 데몬을 관리 + */ +@Component +public class EAIServiceMonitor implements Lifecycle { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + // 일자전환시 RMS에서 참조할 수 있도록 관리되는 변수 + private String monitorDate = ""; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + public static final String PROP_GROUP = "EAIServiceMonitor"; + + // EAIServiceMonitor에서 사용하는 Property Key : MonitorChecker의 동작 주기 + public static final String PROP_PERIOD = "monitor.checker.period"; + + // EAIServiceMonitor에서 사용하는 Property Key : MonitorChecker의 동작 주기 + public static final String FILE_WRITE_PERIOD = "file.write.period"; + + // 주기적으로 write할 file의 위치 + public static final String FILE_PATH = "file.write.path"; + + // 파일로깅시 데이터를 구분하기 위한 구분자 + public static final String MASTER_DELIMITER = "file.write.master.delimiter"; + + // 파일로깅시 데이터를 구분하기 위한 구분자 + public static final String SUB_DELIMITER = "file.write.sub.delimiter"; + + // EAI FRAMEWORK의 예외처리에서 사용되는 에러 코드 + private static String[] errorCode = { "E", "F" }; + + // EAI Service Code별 모니터링 오브젝트(MonitorVO)를 위한 HashMap + private ConcurrentHashMap monitors = new ConcurrentHashMap<>(); + + // 업무구분별 MonitorVO를 위한 HashMap + private ConcurrentHashMap> bwkClss = new ConcurrentHashMap<>(); + + // 일일, 최근시간별 데이터 저장을 위해 주기적으로 실행 Monitor check를 하는 TimerTask object + private MonitorChecker checker; + + // 주기적으로 파일에 write하기 위한 TimerTask object + private MonitorWriteChecker writer; + + // MonitorChecker를 실제 실행하는 Timer object + private Timer timer; + + // MonitorChecker를 실제 실행하는 Timer object - add 20080618 by kscheon + private Timer write_timer; + + // EAIServiceMonitor starting 여부를 체크하는 flag 변수 + private boolean started; + + @Autowired + private EAIMessageManager eaiMsgManager; + + private String filePath; + + private String fileName; + + private String master_delimiter; + private String sub_delimiter; + + // 에러코드 중 타임아웃으로 분류해야 하는 에러코드 리스트 : 2008.12.11 + public static final String TO_ERRORLIST = "timeout.errorlist"; + + private String timeOutCodes = ""; + private String defTimeOutCodes = "RECEAIOSA777,RECEAIOHP003,RECEAIOSP004,RECEAIOTC913,RECEAIOSA010,RECEAIOEP010,RECEAIOHP010,RECEAIOSP010,RECEAIOTP010"; + + public static final String BIZ_ERRORLIST = "biz.errorlist"; + + private String bizErrorCodes = ""; + + private String defBizErrorCodes = "RECEAICEU104,RECEAICKE301,RECEAIIRP040,RECEAIOEP020,RECEAIOEP030,RECEAIOHP020,RECEAIOHP022,RECEAIOHP030,RECEAIOMP002,RECEAIOMP006,RECEAIOSA020,RECEAIOSP020,RECEAIOSP030,RECEAIOTP002,RECEAIOTP006,RECEAICBE001,RECEAICBE010,RECEAICBX001,RECEAICME001,RECEAICMK001,RECEAIFBR002,RECEAIIRA001,RECEAIIRP050,RECEAIIRP060,RECEAIIRP062"; + + private MonitorCleaner cleaner; + private Timer cleanerTimer; + + public static synchronized EAIServiceMonitor getInstance() { + return ApplicationContextProvider.getContext().getBean(EAIServiceMonitor.class); + } + + public void start() throws LifecycleException { + if (started) { + String errorText = ErrorCodeHandler.getMessage("RECEAICMT201"); + if (logger.isError()) + logger.error(ExceptionUtil.make("RECEAICMT201", errorText)); + } + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + // 데일리 클리너 초기화 + this.cleaner = new MonitorCleaner(); + + // 다음 새벽 2시 계산 + Calendar firstTime = Calendar.getInstance(); + firstTime.set(Calendar.HOUR_OF_DAY, 2); + firstTime.set(Calendar.MINUTE, 0); + firstTime.set(Calendar.SECOND, 0); + + // 이미 오늘 2시가 지났으면 다음날로 설정 + if (firstTime.before(Calendar.getInstance())) { + firstTime.add(Calendar.DATE, 1); + } + + this.cleanerTimer = new Timer("MonitorCleanerTimer"); + // 매일 새벽 2시에 실행 (24시간 = 24 * 60 * 60 * 1000 = 86400000 밀리초) + this.cleanerTimer.scheduleAtFixedRate(this.cleaner, firstTime.getTime(), 86400000); + + PropManager pmanager = PropManager.getInstance(); + + filePath = pmanager.getProperty(PROP_GROUP, FILE_PATH); + if (filePath == null || filePath.equals("")) { + filePath = "."; + } + master_delimiter = pmanager.getProperty(PROP_GROUP, MASTER_DELIMITER); + sub_delimiter = pmanager.getProperty(PROP_GROUP, SUB_DELIMITER); + timeOutCodes = pmanager.getProperty(TO_ERRORLIST); + bizErrorCodes = pmanager.getProperty(BIZ_ERRORLIST); + + // set current timeout error code list + if (timeOutCodes == null || timeOutCodes.length() <= 0) { + timeOutCodes = defTimeOutCodes; + if (logger.isWarn()) { + logger.warn("EAIServiceMonitor] Timeout Error Code List Property NOT SET Group[" + PROP_GROUP + + "] Property[" + TO_ERRORLIST + "]"); + logger.warn("EAIServiceMonitor] Set Default Value ..."); + } + } + + if (logger.isWarn()) { + logger.warn("EAIServiceMonitor] Timeout Error Code List >> " + timeOutCodes); + } + + // 업무에러 코드에 대한 정의가 필요 + if (bizErrorCodes == null || bizErrorCodes.length() <= 0) { + bizErrorCodes = defBizErrorCodes; + if (logger.isWarn()) { + logger.warn("EAIServiceMonitor] Biz Error Code List Property NOT SET Group[" + PROP_GROUP + + "] Property[" + BIZ_ERRORLIST + "]"); + logger.warn("EAIServiceMonitor] Set Default Value ..."); + } + } + + if (logger.isWarn()) { + logger.warn("EAIServiceMonitor] System Error Code List >> " + bizErrorCodes); + } + + if (master_delimiter == null || master_delimiter.length() <= 0) { + master_delimiter = ":"; + } + + if (sub_delimiter == null || sub_delimiter.length() <= 0) { + sub_delimiter = "/"; + } + + // 파일에 저장된 모니터링 정보를 메모리에 로딩 + monitors = createMonitorVO(); + + // 최초 한번 실행하고 10분단위 정각에 실행, 정시에 reset + this.checker = new MonitorChecker(); + this.checker.setEAIServiceMonitor(this); + + Calendar cal = Calendar.getInstance(); + int min = cal.get(Calendar.MINUTE) / 10 * 10; + cal.set(Calendar.MINUTE, min); + cal.set(Calendar.SECOND, 0); + + this.timer = new Timer("EAIServiceMonitorTimer"); + this.timer.scheduleAtFixedRate(this.checker, cal.getTime(), 600000); + + this.writer = new MonitorWriteChecker(); + this.writer.setEAIServiceMonitor(this); + + // reset과 중복되지 않도록 10초 후에 write하도록 처리함 + cal.set(Calendar.SECOND, 10); + this.write_timer = new Timer("EAIServiceMonitorWriteTimer"); + this.write_timer.scheduleAtFixedRate(this.writer, cal.getTime(), 600000); + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) { + String errorText = ErrorCodeHandler.getMessage("RECEAICMT202"); + if (logger.isError()) + logger.error(ExceptionUtil.make("RECEAICMT202", errorText)); + } + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + this.timer.cancel(); + this.write_timer.cancel(); + this.cleanerTimer.cancel(); // 클리너 타이머도 정지 + + this.timer = null; + this.checker = null; + this.cleanerTimer = null; + this.cleaner = null; + if (this.monitors != null) { + this.monitors.clear(); + this.monitors = null; + } + + this.write_timer = null; + this.writer = null; + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public void receiveLogMessage(EAIMessage msg) { + try { + if (msg == null) { + String errorText = ErrorCodeHandler.getMessage("RWCEAICMT203"); + if (logger.isWarn()) + logger.warn(ExceptionUtil.make("RWCEAICMT203", errorText)); + } + + String svcTsmtUsgTP = ""; // 서비스동시사용 - ServiceTheSameTimeUsgaeType - [SYNC|ASYN|AKON] + String psvItfTp = ""; // 수동인터페이스유형 - PassiveInterfaceType - [SYNC|ASYN|AKON] + String rspErrCd = ""; // 응답에러코드 + String eaiSvcCd = ""; + String error = ""; + String svcOgNo = ""; + String bwkCls = ""; // 업무구분 + long msgPssTm; // 메시지처리시각 + long msgRcvTm; // 메시지수신시각 + int logPssSno; // 로그처리일련번호 + boolean isSingle = true; + int iErrorCode = 0; // 0 : 정상, 1 : 에러, 2 : 타임아웃 + + MonitorVO monitor = null; + + svcTsmtUsgTP = msg.getSvcTsmtUsgTp(); + psvItfTp = msg.getCurrentSvcMsg().getPsvItfTp(); + msgPssTm = msg.getMsgPssTm(); + msgRcvTm = msg.getMsgRcvTm(); + logPssSno = msg.getLogPssSno(); + rspErrCd = msg.getRspErrCd(); + eaiSvcCd = msg.getEAISvcCd(); + svcOgNo = msg.getSvcOgNo(); + bwkCls = msg.getBwkCls(); + + String screnNo = " "; + String intfacSendTranCd = msg.getMapper().getServiceId(msg.getStandardMessage()); + + if (StringUtils.isEmpty(intfacSendTranCd)) + intfacSendTranCd = " "; + + String adapterGroupName = ""; + + // S01, R01 => 기동어댑터 + if (eaiSvcCd.endsWith("1")) { + adapterGroupName = msg.getSngSysItfTp(); + } else { + adapterGroupName = msg.getCurrentSvcMsg().getPsvSysItfTp(); + } + + // 메시지의 에러/정상 상태 확인을 위한 데이터 + if (rspErrCd.length() >= 12) { + error = rspErrCd.substring(1, 2); + } + + // 에러와 타임아웃을 분리 : 이동훈 + if (errorCode[0].equals(error.toUpperCase()) || errorCode[1].equals(error.toUpperCase())) { + iErrorCode = 1; + + // Timeout + if (timeOutCodes.indexOf(rspErrCd) > 0) { + iErrorCode = 2; + } + // 업무에러코드에 없을 경우 통신(시스템)에러로 처리함 + else if (bizErrorCodes.indexOf(rspErrCd) == -1) { + iErrorCode = 3; + } + } + + if (monitors == null) + monitors = createMonitorVO(); + + if (EAIMessageKeys.COMPLEX_PROCESS.equalsIgnoreCase(msg.getSvcPssTp())) { + isSingle = false; + } + + monitor = monitors.get(eaiSvcCd); + // MonitorVO에 대한 Null check 후 새로 추가 로직 필요. + if (monitor == null) { + // EAIMessageManager에 있는지 확인 필요 + EAIMessage eaiMsg = eaiMsgManager.getEAIMessage(eaiSvcCd); + + if (eaiMsg != null) { + monitor = new MonitorVO(eaiSvcCd); + monitors.put(eaiSvcCd, monitor); + } else { + String errorText = ErrorCodeHandler.getMessage("RECEAICMT205"); + if (logger.isError()) + logger.error(ExceptionUtil.make("RECEAICMT205", errorText)); + } + } + + if (monitor != null) { + monitor.setIsSingle(isSingle); + monitor.setBwkCls(bwkCls); + + if (msg.getGroupCoCd() == null || "".equals(msg.getGroupCoCd().trim())) + monitor.setGroupCoCd("KB0"); // default : 은행(KB0) + else + monitor.setGroupCoCd(msg.getGroupCoCd()); + + if (EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTP) && EAIMessageKeys.SYNC_SVC.equals(psvItfTp)) { + monitor.onEvent(IFType.SS, isSingle, logPssSno, msgPssTm, msgRcvTm, iErrorCode, svcOgNo, screnNo, + intfacSendTranCd, adapterGroupName); + } else if (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTP) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) { + monitor.onEvent(IFType.AA, isSingle, logPssSno, msgPssTm, msgRcvTm, iErrorCode, svcOgNo, screnNo, + intfacSendTranCd, adapterGroupName); + } else if (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTP) && EAIMessageKeys.SYNC_SVC.equals(psvItfTp)) { + monitor.onEvent(IFType.AS, isSingle, logPssSno, msgPssTm, msgRcvTm, iErrorCode, svcOgNo, screnNo, + intfacSendTranCd, adapterGroupName); + } else { + monitor.onEvent(IFType.SA, isSingle, logPssSno, msgPssTm, msgRcvTm, iErrorCode, svcOgNo, screnNo, + intfacSendTranCd, adapterGroupName); + } + } + + HashMap bwkVO = bwkClss.get(bwkCls); + + if (bwkVO != null) { + bwkVO.put(eaiSvcCd, monitor); + bwkClss.put(bwkCls, bwkVO); + } else { + bwkVO = new HashMap<>(); + bwkVO.put(eaiSvcCd, monitor); + bwkClss.put(bwkCls, bwkVO); + } + } catch (Exception e) { + String errorText = ErrorCodeHandler.getMessage("RECEAICMT204"); + if (logger.isError()) + logger.error(ExceptionUtil.make("RECEAICMT204", errorText)); + } + } + + public void resetAll() { + String[] keys = getAllMonitorVOKey(); + MonitorVO vo = null; + + for (int i = 0; i < keys.length; i++) { + vo = monitors.get(keys[i]); + if (vo != null) { + vo.reset(); + vo.resetPeriod(); + } + } + } + + public void clearAll() { + this.bwkClss.clear(); + this.monitors.clear(); + } + + public Iterator getAllMonitorVO() { + return this.monitors.values().iterator(); + } + + public String[] getAllMonitorVOKey() { + + Iterator it = this.monitors.keySet().iterator(); + + ArrayList keyList = new ArrayList<>(); + while (it.hasNext()) { + String key = it.next(); + if (key != null) { + keyList.add(key); + } + } + + String[] finalVOkey = keyList.toArray(new String[0]); + + if (finalVOkey.length > 0) { + Arrays.sort(finalVOkey); + } + return finalVOkey; + } + + public void removeMonitorVO(String eaiSvcCd) { + monitors.remove(eaiSvcCd); + } + + public MonitorVO getMonitorVO(String eaiSvcCd) { + return monitors.get(eaiSvcCd); + } + + public String[] getAllBwkClsKey() { + Iterator it = this.bwkClss.keySet().iterator(); + ArrayList keyList = new ArrayList<>(); + while (it.hasNext()) { + String key = it.next(); + if (key != null) { + keyList.add(key); + } + } + + String[] finalVOkey = new String[keyList.size()]; + keyList.toArray(finalVOkey); + if (finalVOkey.length > 0) { + Arrays.sort(finalVOkey); + } + return finalVOkey; + } + + public void removeBwkCls(String bwkCls) { + bwkClss.remove(bwkCls); + } + + public HashMap getBwkCls(String bwkCls) { + return bwkClss.get(bwkCls); + } + + private ConcurrentHashMap createMonitorVO() { + ConcurrentHashMap monitorVOs = new ConcurrentHashMap<>(); + + String date = DatetimeUtil.getCurrentDate(); + String wlServer = System.getProperty(Keys.SERVER_KEY); + + fileName = this.filePath + "/" + wlServer + "/MonitorVoData_" + date; + if (logger.isDebug()) { + logger.debug("EAIServiceMonitor ] fileName - [" + fileName + "]"); + } + + File rf = null; + BufferedReader in = null; + String msg = ""; + + // file write + // #eaiServiceCode/bwkCls/isSingle/ifType/groupCoCd: -- key + // 100=2/200=2/300=2/400=2/900=2/9300=2/9400=2: -- 거래 count + // 100=2/200=2/300=2/400=2/900=2/9300=2/9400=2/9900=2: -- error count + // sumOfprocessTime/psvSumOfPssTime -- eai처리시간, 수동처리시간 + try { + rf = new File(fileName); + if (rf != null && rf.exists()) { + in = new BufferedReader(new InputStreamReader(new FileInputStream(rf))); + if (in != null) { + MonitorVO vo = null; + while ((msg = in.readLine()) != null) { + if (logger.isDebug()) { + logger.debug("EAIServiceMonitor ] createMonitorVO - msg[" + msg + "]"); + } + + if (msg.length() > 0) { + String[] token = msg.split(master_delimiter); + + if (token.length != 4) { + if (logger.isDebug()) { + logger.warn("EAIServiceMonitor ] file data parsing error - " + token.length); + } + continue; + } else { + String[] key = token[0].split(sub_delimiter); + String eaiSvcCd = key[0]; + String bwkCls = key[1]; + String groupCoCd = key[4]; // 그룹사코드 추가 + + if (eaiSvcCd == null || eaiSvcCd.trim().length() == 0) { + if (logger.isWarn()) { + logger.warn("EAIServiceMonitor ] createMonitorVO - Skip Invalid eaiSvcCd - " + + eaiSvcCd); + } + continue; + } + vo = new MonitorVO(eaiSvcCd); + + if (vo == null) { + if (logger.isWarn()) { + logger.warn("EAIServiceMonitor ] createMonitorVO - monitorvo is null - " + + eaiSvcCd); + } + continue; + } + vo.setBwkCls(bwkCls); + vo.setIfType(key[3]); + vo.setGroupCoCd(groupCoCd); + + String[] pssTime = token[3].split(sub_delimiter); + + String pssTime0 = pssTime[0]; + String pssTime1 = pssTime[1]; + + vo.setSumOfprocessTime(Double.parseDouble(pssTime0)); + vo.setPsvSumOfPssTime(Double.parseDouble(pssTime1)); + + if ("true".equals(key[2])) { // 단일거래이면 + HashMap pssCount = vo.getPssCnt(); + HashMap errorCount = vo.getErrPssCnt(); + + HashMap pssCountP = vo.getPssCntInPeriod(); // 최근시간 + HashMap errorCountP = vo.getErrPssCntInPeriod(); // 최근 시간 + + String[] count = (token[1]).split(sub_delimiter); + String[] error = (token[2]).split(sub_delimiter); + + for (int i = 0; i < count.length; i++) { + String[] sub_count = count[i].split("="); + pssCount.put(sub_count[0], sub_count[1]); + pssCountP.put(sub_count[0], "0"); + } + for (int i = 0; i < error.length; i++) { + String[] sub_error = error[i].split("="); + errorCount.put(sub_error[0], sub_error[1]); + errorCountP.put(sub_error[0], "0"); + } + vo.setPssCnt(pssCount); + vo.setErrPssCnt(errorCount); + vo.setPssCntInPeriod(pssCountP); + vo.setErrPssCntInPeriod(errorCountP); + + } else { // 복합거래이면... 추가 로직 넣을것 + if (logger.isDebug()) { + logger.debug("EAIServiceMonitor ] is not Single"); + } + } + if (logger.isDebug()) { + logger.debug("EAIServiceMonitor ] Parsed MonitorVO : " + vo.toString()); + } + monitorVOs.put(eaiSvcCd, vo); + + HashMap bwkVO = bwkClss.get(bwkCls); + + if (bwkVO != null) { + MonitorVO mvo = bwkVO.get(eaiSvcCd); + if (mvo == null) { + + bwkVO.put(eaiSvcCd, vo); + bwkClss.put(bwkCls, bwkVO); + } + } else { + bwkVO = new HashMap<>(); + bwkVO.put(eaiSvcCd, vo); + bwkClss.put(bwkCls, bwkVO); + } + } + } + } + } + } else { + if (logger.isWarn()) { + logger.warn("EAIServiceMonitor ] File Not Found Skip Load File : " + fileName); + } + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn("Exception", e); + } + } finally { + try { + if (in != null) { + in.close(); + } + } catch (Exception ex) { + if (logger.isWarn()) { + logger.warn("close error", ex); + } + } + } + + return monitorVOs; + } + + public String getFilPath() { + return this.filePath; + } + + public void setFilePath(String path) { + this.filePath = path; + } + + public String getFilName() { + return this.fileName; + } + + public void setfileName(String name) { + this.fileName = name; + } + + public String getMasterDelimiter() { + return this.master_delimiter; + } + + public void setMasterDelimiter(String delimiter) { + this.master_delimiter = delimiter; + } + + public String getSubDelimiter() { + return this.sub_delimiter; + } + + public void setSubDelimiter(String delimiter) { + this.sub_delimiter = delimiter; + } + + public String resetErrorList() { + PropManager pmanager = PropManager.getInstance(); + + timeOutCodes = pmanager.getProperty(TO_ERRORLIST); + bizErrorCodes = pmanager.getProperty(BIZ_ERRORLIST); + + // set current timeout error code list + if (timeOutCodes == null || timeOutCodes.length() <= 0) { + timeOutCodes = defTimeOutCodes; + } + + if (logger.isWarn()) { + logger.warn("\n\n\nEAIServiceMonitor] =================================================================="); + logger.warn("EAIServiceMonitor] reset Timeout Error Code List >> " + timeOutCodes); + logger.warn("EAIServiceMonitor] ==================================================================\n\n\n"); + } + + if (bizErrorCodes == null || bizErrorCodes.length() <= 0) { + bizErrorCodes = defBizErrorCodes; + if (logger.isWarn()) { + logger.warn("EAIServiceMonitor] Biz Error Code List Property NOT SET Group[" + PROP_GROUP + + "] Property[" + BIZ_ERRORLIST + "]"); + logger.warn("EAIServiceMonitor] Set Default Value ..."); + } + } + + if (logger.isWarn()) { + logger.warn("\n\n\nEAIServiceMonitor] =================================================================="); + logger.warn("EAIServiceMonitor] Biz Error Code List >> " + bizErrorCodes); + logger.warn("EAIServiceMonitor] ==================================================================\n\n\n"); + } + + return "Reset Timeout Error Code List : [" + timeOutCodes + "] Biz Error Code List [" + bizErrorCodes + "]"; + } + + public String getMonitorDate() { + return monitorDate; + } + + public void setMonitorDate(String monitorDate) { + this.monitorDate = monitorDate; + } + + public boolean isTimeOutCodes(String errorCode) { + if (timeOutCodes.indexOf(errorCode) >= 0) { // TIMEOUT일경우 + return true; + } + return false; + } + + public boolean isBizErrorCodes(String errorCode) { + if (bizErrorCodes.indexOf(errorCode) >= 0) { // biz 에러일 경우 + return true; + } + return false; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java b/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java new file mode 100644 index 0000000..486ef4f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/monitor/MonitorChecker.java @@ -0,0 +1,345 @@ +package com.eactive.eai.common.monitor; + +import com.eactive.eai.common.dao.DAOFactory; +import com.eactive.eai.common.errorcode.ErrorCodeHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.logger.EAILogDAO; +import com.eactive.eai.common.message.IFType; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; + +import java.util.Iterator; +import java.util.TimerTask; + +/** +* 1. 기능 : 일, 최근시간(10분 또는 1시간)에 따른 각 MonitorVO 초기화 +* 2. 처리 개요 : +* - Timer에 의해 매일, 매 최근시간 반복적으로 초기화 수행 +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class MonitorChecker extends TimerTask +{ + /** + * EAI FRAMEWORK DEFAULT FILE LOGGER + */ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * EAIServiceMonitor + */ + private EAIServiceMonitor serviceMonitor; + + /** + * 일일 초기화를 위해 현재 날짜와 비교하기 위한 이전날짜 + */ + private String prevDate; + private int resetCount; + + /** + * 1. 기능 : Default 생성자 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public MonitorChecker() { + prevDate = DatetimeUtil.getCurrentDate(); + resetCount = 0; + } + + /** + * 1. 기능 : MonitorChecker가 주기적으로 모니터링할 EAIServiceMonotir 설정 + * 2. 처리 개요 : + * - MonitorChecker가 주기적으로 모니터링할 EAIServiceMonotor 설정 + * 3. 주의사항 + *@param monitor 주기적으로 모니터링할 EAIServiceMonotir + **/ + public void setEAIServiceMonitor(EAIServiceMonitor monitor) { + this.serviceMonitor = monitor; + this.serviceMonitor.setMonitorDate(prevDate); + } + + /** + * 1. 기능 : 정해진시간에 초기화 수행 + * 2. 처리 개요 : + * - DatetimeUtil로부터 현재 일자를 얻어 비교하여 일자가 변경된 경우 reset + * - 최근시간(10분 또는 1시간) 마다 reset + * - 복원정보의 전전일자 데이터를 삭제한다. + * 3. 주의사항 + **/ + public void run() + { + String msg = ErrorCodeHandler.getMessage("RICEAICMT001", new String[]{Thread.currentThread().getName()}); + if (logger.isInfo()) logger.info(ExceptionUtil.make("RICEAICMT001", msg)); + + String date = DatetimeUtil.getCurrentDate(); + + // 2009.12.23 + // 일자전환시 Map의 리스트를 모두 삭제한다. + if(!(date.equals(prevDate))){ + //this.serviceMonitor.resetAll(); + this.serviceMonitor.clearAll(); + resetCount++; + if (logger.isWarn()) { + logger.warn("MonitorChecker] DAILY_RESET_COUNT EXECUTED!"); + } + } + + // 2011.02.27 + // Error 처리로직 추가 + String[] keys = this.serviceMonitor.getAllMonitorVOKey(); + MonitorVO mv = null; + + if(keys == null) { + if (logger.isWarn()) { + logger.warn("MonitorChecker] SKIP : MonitorVO List is NULL!"); + } + return; + } + + for(int i=0; i 3 ) { + rType = eaiServiceCode.charAt(eaiServiceCode.length()-3); + } + + if(IFType.AA.equals(vo.getIfType())) { + if( rType == 'S') { + totCnt = Long.parseLong(vo.getPssCntInPeriod().get("100").toString()) + + Long.parseLong(vo.getErrPssCntInPeriod().get("100").toString()); + } else { + totCnt = Long.parseLong(vo.getPssCntInPeriod().get("300").toString()) + + Long.parseLong(vo.getErrPssCntInPeriod().get("300").toString()); + } + errCnt = Long.parseLong(vo.getErrPssCntInPeriod().get("900").toString()); + toCnt = Long.parseLong(vo.getErrPssCntInPeriod().get("9900").toString()); + succCnt = totCnt - (errCnt + toCnt); + } + // 2011.04.28 이동훈 + // SA 응답일 경우에는 건수를 0으로 한다. + else if(IFType.SA.equals(vo.getIfType()) && rType == 'R') { + errCnt = 0; + toCnt = 0; + succCnt = 0; + } + else { + totCnt = Long.parseLong(vo.getPssCntInPeriod().get("100").toString()) + + Long.parseLong(vo.getErrPssCntInPeriod().get("100").toString()); + + errCnt = Long.parseLong(vo.getErrPssCntInPeriod().get("400").toString()) + + Long.parseLong(vo.getErrPssCntInPeriod().get("900").toString()); + toCnt = Long.parseLong(vo.getErrPssCntInPeriod().get("9400").toString()); + succCnt = totCnt - (errCnt + toCnt); + } + + logVo.setWholPrcssNoitm(totCnt); + logVo.setErrzNoitm(errCnt); + logVo.setToutNoitm(toCnt); + logVo.setNomalNoitm(succCnt); + + EAILogDAO dao = null; + try { + dao = ApplicationContextProvider.getContext().getBean(EAILogDAO.class); + } catch(Exception e) { + if (logger.isError()) logger.error("MonitorVO.insertStaticCount ERROR. - " + e.getMessage(),e); + } + + if(dao == null) { + return; + } + + // 메모리 정보는 건수가 RESET 되므로 건수가 0보다 큰 경우만 DB에 저장 + // SA 응답인 경우는 로깅하도록 함. (SR05와 맞추기 위해) + if(totCnt > 0 || (IFType.SA.equals(vo.getIfType()) && rType == 'R') ) { + try { + dao.addStaticLog(logVo); + } catch(Exception e) { + if (logger.isError()) logger.error("MonitorVO.insertStaticCount ERROR. - " + e.getMessage(),e); + } + } + +// Iterator it_s = mScreenMap.keySet().iterator(); +// for(int i = 0; it_s.hasNext(); i++) { +// String key = (String)it_s.next(); +// StatMonitorVO vo = (StatMonitorVO)mScreenMap.get(key); +// logVo.setKey(key); +// StatMonitorLogVO tmpLogVo = convertLogVO(logVo, vo, ifType, rType); +// +// if(tmpLogVo.getWholPrcssNoitm() < 1 && !(IFType.SA.equals(ifType) && rType == 'R')) { +// StringBuffer sb = new StringBuffer(); +// sb.append(vo.toString()+"\n"); +// sb.append(tmpLogVo.toString()); +// } +// +// try { +// dao.addStaticScreenLog(tmpLogVo); +// } catch(Exception e) { +// if (logger.isError()) logger.error("MonitorVO.insertStaticCount SCREEN ERROR. - " +// + tmpLogVo.toString() + "\n" + e.getMessage(),e); +// } +// } + + Iterator it_t = vo.iteratorTranCdMap(); + for(int i = 0; it_t.hasNext(); i++) { + String key = (String)it_t.next(); + StatMonitorVO smvo = vo.getTranCdMonitorVo(key); + logVo.setKey(key); + StatMonitorLogVO tmpLogVo = convertLogVO(logVo, smvo, vo.getIfType(), rType); + try { + dao.addStaticTranCdLog(tmpLogVo); + } catch(Exception e) { + if (logger.isError()) logger.error("MonitorVO.insertStaticCount TRANCODE ERROR. - " + + tmpLogVo.toString() + "\n" + e.getMessage(),e); + } + } + + Iterator it_a = vo.iteratorAdapterMap(); + for(int i = 0; it_a.hasNext(); i++) { + String key = (String)it_a.next(); + StatMonitorVO smvo = vo.getAdapterMonitorVo(key); + logVo.setKey(key); + StatMonitorLogVO tmpLogVo = convertLogVO(logVo, smvo, vo.getIfType(), rType); + try { + dao.addStaticAdapterLog(tmpLogVo); + } catch(Exception e) { + if (logger.isError()) logger.error("MonitorVO.insertStaticCount ADAPTER ERROR. - " + + tmpLogVo.toString() + "\n" + e.getMessage(),e); + } + } + } + + private StatMonitorLogVO convertLogVO(StatMonitorLogVO logVo, StatMonitorVO statVo, + String ifType, char rType) { + long totCnt = 0; + long errCnt = 0; + long toCnt = 0; + long succCnt = 0; + + logVo.setPrcssTtmVal((statVo.getSumOfprocessTime() - statVo.getPsvSumOfPssTime())); + logVo.setPsvPrcssTtmVal(statVo.getPsvSumOfPssTime()); + logVo.setTotalPrcssTtmVal(statVo.getSumOfprocessTime()); + + if(IFType.AA.equals(ifType)) { + if( rType == 'S') { + totCnt = statVo.getCnt100() + statVo.getErr100(); + } else { + totCnt = statVo.getCnt300() + statVo.getErr300(); + } + errCnt = statVo.getErr900(); + toCnt = statVo.getTimeout900(); + succCnt = totCnt - (errCnt + toCnt); + } + // 2011.04.28 이동훈 + //SA 응답일 경우에는 건수를 0으로 한다. + else if(IFType.SA.equals(ifType) && rType == 'R') { + totCnt = 0; + errCnt = 0; + toCnt = 0; + succCnt = 0; + } + else { + totCnt =statVo.getCnt100() + statVo.getErr100(); + errCnt = statVo.getErr400() + statVo.getErr900(); + toCnt = statVo.getTimeout400(); + succCnt = totCnt - (errCnt + toCnt); + } + logVo.setWholPrcssNoitm(totCnt); + logVo.setErrzNoitm(errCnt); + logVo.setToutNoitm(toCnt); + logVo.setNomalNoitm(succCnt); + + return logVo; + } +} diff --git a/src/main/java/com/eactive/eai/common/monitor/MonitorCleaner.java b/src/main/java/com/eactive/eai/common/monitor/MonitorCleaner.java new file mode 100644 index 0000000..70aff32 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/monitor/MonitorCleaner.java @@ -0,0 +1,118 @@ +package com.eactive.eai.common.monitor; + +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.property.PropManager; +import java.io.File; +import java.util.Calendar; +import java.util.TimerTask; + +public class MonitorCleaner extends TimerTask { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static final String PROP_GROUP = "EAIServiceMonitor"; + public static final String FILE_PATH = "file.write.path"; + + public void run() { + if (logger.isInfo()) { + logger.info("MonitorCleaner started - cleaning files older than 7 days"); + } + + try { + PropManager pmanager = PropManager.getInstance(); + String propPath = pmanager.getProperty(PROP_GROUP, FILE_PATH); + + //filepath를 프로퍼티에 설정 안했으면... + if (propPath == null || propPath.equals("")){ + propPath = "."; + } + + String wlServer = System.getProperty(Keys.SERVER_KEY); + String dirPath = propPath + "/" + wlServer; + + cleanOldFiles(dirPath); + + } catch (Exception e) { + if (logger.isError()) { + logger.error("Error while cleaning old monitor files: " + e.getMessage(), e); + } + } + } + + private void cleanOldFiles(String dirPath) { + if (logger.isDebug()) { + logger.debug("Cleaning old files in directory: " + dirPath); + } + + try { + File dir = new File(dirPath); + + if (dir.exists() && dir.isDirectory()) { + File[] files = dir.listFiles((d, name) -> name.startsWith("MonitorVoData_")); + + if (files != null) { + Calendar weekAgo = Calendar.getInstance(); + weekAgo.add(Calendar.DATE, -7); + + if (logger.isDebug()) { + logger.debug("Files older than: " + + String.format("%04d%02d%02d", + weekAgo.get(Calendar.YEAR), + weekAgo.get(Calendar.MONTH) + 1, + weekAgo.get(Calendar.DATE))); + } + + int deletedCount = 0; + for (File file : files) { + String fileName = file.getName(); + if (fileName.length() >= 22) { + String fileDate = fileName.substring(14, 22); + try { + Calendar fileTime = Calendar.getInstance(); + fileTime.set( + Integer.parseInt(fileDate.substring(0, 4)), + Integer.parseInt(fileDate.substring(4, 6)) - 1, + Integer.parseInt(fileDate.substring(6, 8)) + ); + + if (fileTime.before(weekAgo)) { + if (file.delete()) { + deletedCount++; + if (logger.isInfo()) { + logger.info("Deleted old monitor file: " + fileName); + } + } + } else { + if (logger.isDebug()) { + logger.debug("Keeping file: " + fileName); + } + } + } catch (NumberFormatException e) { + if (logger.isWarn()) { + logger.warn("Invalid date format in filename: " + fileName); + } + } + } + } + + if (logger.isInfo()) { + logger.info("MonitorCleaner finished - deleted " + deletedCount + " old files"); + } + } + } + } catch (Exception e) { + if (logger.isError()) { + logger.error("Error in cleanOldFiles: " + e.getMessage(), e); + } + } + } + + // 테스트용 main 메소드 + public static void main(String[] args) { + String testDir = "C:/temp/test_monitor"; + + MonitorCleaner cleaner = new MonitorCleaner(); + cleaner.cleanOldFiles(testDir); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/monitor/MonitorWriteChecker.java b/src/main/java/com/eactive/eai/common/monitor/MonitorWriteChecker.java new file mode 100644 index 0000000..de0f1a1 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/monitor/MonitorWriteChecker.java @@ -0,0 +1,216 @@ +package com.eactive.eai.common.monitor; + +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.util.HashMap; +import java.util.Iterator; +import java.util.TimerTask; + +/** +* 1. 기능 : 일, 최근시간(10분 또는 1시간)에 따른 각 MonitorVO 초기화 +* 2. 처리 개요 : +* - Timer애 의해 매일, 매 최근시간 반복적으로 초기화 수행 +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +*/ +public class MonitorWriteChecker extends TimerTask +{ + /** + * EAI FRAMEWORK DEFAULT FILE LOGGER + */ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * EAIServiceMonitor + */ + private EAIServiceMonitor serviceMonitor; + + /** + * EAIServiceMonitor에서 사용하는 Poprties Group의 Key + */ + public static final String PROP_GROUP = "EAIServiceMonitor"; + + /** + * 주기적으로 write할 file의 위치 + */ + public static final String FILE_PATH = "file.write.path"; + + /** + * 파일로깅시 데이터를 구분하기 위한 구분자 + */ + public static final String MASTER_DELIMITER = "file.write.master.delimiter"; + + /** + * 파일로깅시 데이터를 구분하기 위한 구분자 + */ + public static final String SUB_DELIMITER = "file.write.sub.delimiter"; + + + + /** + * 1. 기능 : Default 생성자 + * 2. 처리 개요 : + * 3. 주의사항 + **/ + public MonitorWriteChecker() { + + } + + /** + * 1. 기능 : MonitorChecker가 주기적으로 모니터링할 EAIServiceMonotir 설정 + * 2. 처리 개요 : + * - MonitorChecker가 주기적으로 모니터링할 EAIServiceMonotir 설정 + * 3. 주의사항 + *@param monitor 주기적으로 모니터링할 EAIServiceMonotir + **/ + public void setEAIServiceMonitor(EAIServiceMonitor monitor) { + this.serviceMonitor = monitor; + } + + /** + * 1. 기능 : 정해진시간에 초기화 수행 + * 2. 처리 개요 : + * - DatetimeUtil로부터 현재 일자를 얻어 비교하여 일자가 변경된 경우 reset + * - 최근시간(10분 또는 1시간) 마다 reset + * 3. 주의사항 + **/ + public void run() + { + String msg = "MonitorWriteChecker start..... "; + if (logger.isInfo()) logger.info(msg); + + + File dir = null; + File f = null; + FileWriter fw = null; + + Iterator monitorVo = this.serviceMonitor.getAllMonitorVO(); + MonitorVO mv = null; + BufferedWriter bw = null; + + String date = DatetimeUtil.getCurrentDate(); + String wlServer = System.getProperty(Keys.SERVER_KEY); + + PropManager pmanager = PropManager.getInstance(); + String propPath = ""; + String master_delimiter = ""; + String sub_delimiter = ""; + + try{ + + master_delimiter = pmanager.getProperty(PROP_GROUP,MASTER_DELIMITER); + sub_delimiter = pmanager.getProperty(PROP_GROUP,SUB_DELIMITER); + propPath=pmanager.getProperty(PROP_GROUP, FILE_PATH); + + if (master_delimiter == null || master_delimiter.length()<=0 ){ + master_delimiter = ":"; + } + + if (sub_delimiter == null || sub_delimiter.length()<=0 ){ + sub_delimiter = "/"; + } + + //filepath를 프로퍼티에 설정 안했으면... + if (propPath == null || propPath.equals("")){ + propPath = "."; + } + + String dirpath = propPath+"/"+wlServer; + + dir = new File(dirpath); + if(!dir.exists()) { + dir.mkdirs(); + } + + String fileName = "MonitorVoData_"+date; + this.serviceMonitor.setfileName(dirpath+"/"+fileName); + this.serviceMonitor.setFilePath(propPath); + + f = new File(dir, fileName); + fw = new FileWriter(f); + bw = new BufferedWriter(fw); + + while(monitorVo.hasNext()){ + //file write + //#eaiServiceCode/bwkCls/isSingle/ifType/groupCoCd: -- key + //100=2/200=2/300=2/400=2: -- 거래 count + //100=2/200=2/300=2/400=2/900=2: -- error count + //sumOfprocessTime/psvSumOfPssTime -- eai처리시간, 수동처리시간 + + mv = (MonitorVO) monitorVo.next(); + + boolean isSingle = mv.getIsSingle(); + + if(isSingle){//단일거래이면 + + String[] countKey = mv.getAllPssCntKey(); + HashMap countMap = mv.getPssCnt(); + + if (countKey.length >0 ){ + StringBuffer bf = new StringBuffer(); + + bf.append(mv.getEaiServiceCode()).append(sub_delimiter); + bf.append(mv.getBwkCls()).append(sub_delimiter); + bf.append(isSingle).append(sub_delimiter); +// bf.append(mv.getIfType()).append(master_delimiter); + bf.append(mv.getIfType()).append(sub_delimiter); + //그룹사코드 추가, 2010.11.16 + bf.append(mv.getGroupCoCd()).append(master_delimiter); + + + for (int i=0;i pushInfoDetailVoList) throws DAOException { + try { + List list = new ArrayList<>(); + pushInfoDetailVoList.forEach(vo -> list.add(pushInfoDetailMapper.toEntity(vo)) ); + pushInfoDetailLoader.saveAll(list); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE118"), e); + } + } + + public long getPushInfoDetailCount() { + return pushInfoDetailLoader.count(); + } +} diff --git a/src/main/java/com/eactive/eai/common/pushinfo/PushInfoDetailVO.java b/src/main/java/com/eactive/eai/common/pushinfo/PushInfoDetailVO.java new file mode 100644 index 0000000..737d4e8 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/pushinfo/PushInfoDetailVO.java @@ -0,0 +1,112 @@ +package com.eactive.eai.common.pushinfo; + +public class PushInfoDetailVO { + public enum Result { success, fail}; + + private String guid; + private String userId; + private String sessionId; + private String instanceId; + private String wsocRemoteAddr; + private Result pushResult; + private String errorContent; + //YYYYMMDDHHMI24SS + private String pushDatetime; + + public PushInfoDetailVO() { + + } + public PushInfoDetailVO(String guid) { + this.guid = guid; + } + + public PushInfoDetailVO(String guid, String userId, String sessionId, String instanceId, String wsocRemoteAddr, + Result pushResult, String errorContent, String pushDatetime) { + this.guid = guid; + this.userId = userId; + this.sessionId = sessionId; + this.instanceId = instanceId; + this.wsocRemoteAddr = wsocRemoteAddr; + this.pushResult = pushResult; + this.errorContent = errorContent; + this.pushDatetime = pushDatetime; + } + + + public String getGuid() { + return guid; + } + + public void setGuid(String guid) { + this.guid = guid; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getSessionId() { + return sessionId; + } + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + public String getInstanceId() { + return instanceId; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + + public String getWsocRemoteAddr() { + return wsocRemoteAddr; + } + + public void setWsocRemoteAddr(String wsocRemoteAddr) { + this.wsocRemoteAddr = wsocRemoteAddr; + } + + public Result getPushResult() { + return pushResult; + } + public String getPushResultInfo() { + return pushResult==null?"":pushResult.toString(); + } + + public void setPushResult(Result pushResult) { + this.pushResult = pushResult; + } + + public String getErrorContent() { + return errorContent; + } + + public void setErrorContent(String errorContent) { + this.errorContent = errorContent; + } + + public String getPushDatetime() { + return pushDatetime; + } + + public void setPushDatetime(String pushDatetime) { + this.pushDatetime = pushDatetime; + } + + @Override + public String toString() { + return "PushInfoDetailVO [guid=" + guid + ", userId=" + userId + ", sessionId=" + sessionId + ", instanceId=" + + instanceId + ", wsocRemoteAddr=" + wsocRemoteAddr + ", pushResult=" + pushResult + ", errorContent=" + + errorContent + ", pushDatetime=" + pushDatetime + "]"; + } + + +} diff --git a/src/main/java/com/eactive/eai/common/pushinfo/PushInfoVO.java b/src/main/java/com/eactive/eai/common/pushinfo/PushInfoVO.java new file mode 100644 index 0000000..2b1c4f9 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/pushinfo/PushInfoVO.java @@ -0,0 +1,73 @@ +package com.eactive.eai.common.pushinfo; + +public class PushInfoVO { + + private String guid; + private String pushDvsnCode; + private String pushTarget; + private int pushTargetCount; + //YYYYMMDDHHMI24SS + private String pushDateTime; + + public PushInfoVO() { + + } + + public PushInfoVO(String guid) { + this.guid = guid; + } + + public PushInfoVO(String guid, String pushDvsnCode, String pushTarget, int pushTargetCount, String pushDateTime) { + this.guid = guid; + this.pushDvsnCode = pushDvsnCode; + this.pushTarget = pushTarget; + this.pushTargetCount = pushTargetCount; + this.pushDateTime = pushDateTime; + } + + public String getGuid() { + return guid; + } + + public void setGuid(String guid) { + this.guid = guid; + } + + public String getPushDvsnCode() { + return pushDvsnCode; + } + + public void setPushDvsnCode(String pushDvsnCode) { + this.pushDvsnCode = pushDvsnCode; + } + + public String getPushTarget() { + return pushTarget; + } + + public void setPushTarget(String pushTarget) { + this.pushTarget = pushTarget; + } + + public int getPushTargetCount() { + return pushTargetCount; + } + + public void setPushTargetCount(int pushTargetCount) { + this.pushTargetCount = pushTargetCount; + } + + public String getPushDateTime() { + return pushDateTime; + } + + public void setPushDateTime(String pushDateTime) { + this.pushDateTime = pushDateTime; + } + + @Override + public String toString() { + return "PushInfoVO [guid=" + guid + ", pushDvsnCode=" + pushDvsnCode + ", pushTarget=" + pushTarget + + ", pushTargetCount=" + pushTargetCount + ", pushDateTime=" + pushDateTime + "]"; + } +} diff --git a/src/main/java/com/eactive/eai/common/pushinfo/mapper/PushInfoDetailMapper.java b/src/main/java/com/eactive/eai/common/pushinfo/mapper/PushInfoDetailMapper.java new file mode 100644 index 0000000..99beb53 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/pushinfo/mapper/PushInfoDetailMapper.java @@ -0,0 +1,39 @@ +package com.eactive.eai.common.pushinfo.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.pushinfo.PushInfoDetailVO; +import com.eactive.eai.common.pushinfo.PushInfoDetailVO.Result; +import com.eactive.eai.data.entity.onl.pushinfo.PushInfoDetail; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(config = BaseMapperConfig.class, unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface PushInfoDetailMapper extends GenericMapper { + + @Mapping(source = "guid", target = "guid") + @Mapping(source = "userid", target = "userId") + @Mapping(source = "sessionId", target = "sessionId") + @Mapping(source = "instanceId", target = "instanceId") + @Mapping(source = "wsocRemoteAddr", target = "wsocRemoteAddr") + @Mapping(source = "pushResult", target = "pushResult") + @Mapping(source = "errorContent", target = "errorContent") + @Mapping(source = "pushDatetime", target = "pushDatetime") + @Override + PushInfoDetailVO toVo(PushInfoDetail entity); + + @Mapping(source = "pushResult", target = "pushResult") + @InheritInverseConfiguration + PushInfoDetail toEntity(PushInfoDetailVO vo); + + default Result mapStringToResult(String pushResult) { + return Result.valueOf(pushResult); + } + + default String mapResultToString(Result result) { + return result.name(); + } +} diff --git a/src/main/java/com/eactive/eai/common/pushinfo/mapper/PushInfoMapper.java b/src/main/java/com/eactive/eai/common/pushinfo/mapper/PushInfoMapper.java new file mode 100644 index 0000000..719e8de --- /dev/null +++ b/src/main/java/com/eactive/eai/common/pushinfo/mapper/PushInfoMapper.java @@ -0,0 +1,24 @@ +package com.eactive.eai.common.pushinfo.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.pushinfo.PushInfoVO; +import com.eactive.eai.data.entity.onl.pushinfo.PushInfo; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface PushInfoMapper extends GenericMapper { + @Mapping(source = "guid", target = "guid") + @Mapping(source = "pushDatetime", target = "pushDateTime") + @Mapping(source = "pushDvsnCd", target = "pushDvsnCode") + @Mapping(source = "pushTarget", target = "pushTarget") + @Mapping(source = "pushTargetCount", target = "pushTargetCount") + @Override + PushInfoVO toVo(PushInfo entity); + + @InheritInverseConfiguration + PushInfo toEntity(PushInfoVO vo); +} diff --git a/src/main/java/com/eactive/eai/common/restrict/RestrictInfoDAO.java b/src/main/java/com/eactive/eai/common/restrict/RestrictInfoDAO.java new file mode 100644 index 0000000..dc84547 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/restrict/RestrictInfoDAO.java @@ -0,0 +1,74 @@ +package com.eactive.eai.common.restrict; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.restrict.logger.RestrictInfoLoader; +import com.eactive.eai.common.restrict.logger.RestrictInfoLogLogger; +import com.eactive.eai.common.restrict.mapper.RestrictInfoMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.NullControl; +import com.eactive.eai.data.entity.onl.restrict.RestrictInfo; +import com.eactive.eai.data.entity.onl.restrict.RestrictInfoLog; +import com.eactive.eai.data.entity.onl.restrict.RestrictInfoLogId; + +@Service +@Transactional +public class RestrictInfoDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private RestrictInfoLoader restrictInfoLoader; + @Autowired + private RestrictInfoLogLogger restrictInfoLogLogger; + + @Autowired + private RestrictInfoMapper restrictInfoMapper; + + public Map getAllMessages() throws DAOException { + try { + Map routingMap = new HashMap<>(); + List restrictInfos = restrictInfoLoader.findAll(); + if (logger.isInfo()) + logger.info("[ @@ Load RestrictInfo Configuration - starting >>>>>>>>>>>>>>>>> ]"); + for (RestrictInfo restrictInfo : restrictInfos) { + RestrictInfoVO vo = restrictInfoMapper.toVo(restrictInfo); + routingMap.put(vo.getEAICtrlName(), vo); + if (logger.isInfo()) + logger.info("@ " + vo.toString()); + } + if (logger.isInfo()) + logger.info("[>>Load RestrictInfo Configuration - ended ]"); + return routingMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICIM101")); + } + } + + public void addResrtictLog(String bzwkDstcd, String msgDpstYMS, String eAISvcSerno, String eAISevrInstncName, + String eAISvcName, String eAIOsidInstiCd, String eAICtrlNameDstcd) throws DAOException { + try { + RestrictInfoLog restrictInfoLog = new RestrictInfoLog(); + RestrictInfoLogId id = new RestrictInfoLogId(); + id.setEaibzwkdstcd(bzwkDstcd); + id.setMsgdpstyms(msgDpstYMS); + id.setEaisvcserno(NullControl.addSpace(eAISvcSerno)); + restrictInfoLog.setId(id); + restrictInfoLog.setEaisevrinstncname(eAISevrInstncName); + restrictInfoLog.setEaisvcname(eAISvcName); + restrictInfoLog.setEaiosidinsticd(NullControl.addSpace(eAIOsidInstiCd)); + restrictInfoLog.setEaictrlnamedstcd(NullControl.addSpace(eAICtrlNameDstcd)); + restrictInfoLogLogger.save(restrictInfoLog); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICIM102")); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/restrict/RestrictInfoManager.java b/src/main/java/com/eactive/eai/common/restrict/RestrictInfoManager.java new file mode 100644 index 0000000..c2a89c4 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/restrict/RestrictInfoManager.java @@ -0,0 +1,127 @@ +package com.eactive.eai.common.restrict; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.dao.DAOFactory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class RestrictInfoManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static RestrictInfoManager instance = new RestrictInfoManager(); + + private Map messages; + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + private boolean started; + + @Autowired + RestrictInfoDAO restrictInfoDAO; + + public static RestrictInfoManager getInstance() { + return ApplicationContextProvider.getContext().getBean(RestrictInfoManager.class); + } + + public void addResrtictLog(String bzwkDstcd, String msgDpstYMS, String eAISvcSerno, String eAISevrInstncName, + String eAISvcName, String eAIOsidInstiCd, String eAICtrlNameDstcd) throws DAOException { + restrictInfoDAO.addResrtictLog(bzwkDstcd, msgDpstYMS, eAISvcSerno, eAISevrInstncName, eAISvcName, eAIOsidInstiCd, eAICtrlNameDstcd); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICIM201"); + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICIM202")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + messages = restrictInfoDAO.getAllMessages(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("RestrictInfoManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("RestrictInfoManager] reload all finished ..."); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICIM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + messages.clear(); + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public RestrictInfoVO getRestrictInfoVO(String keyCode) { + if (keyCode == null) + return null; + + RestrictInfoVO vo = messages.get(keyCode); + return vo; + } + + public void setRestrictInfoVO(String keyCode, RestrictInfoVO vo) { + messages.put(keyCode, vo); + } + + public void setRestrictInfoVO(RestrictInfoVO vo) { + messages.put(vo.getEAICtrlName(), vo); + } + + public void removeRestrictInfoVO(String keyCode) { + messages.remove(keyCode); + } + + public void clearRestrictInfoVO() { + messages.clear(); + } + + public Map getAllRestrictInfos() { + return this.messages; + } + + public String[] getAllCodes() { + return messages.keySet().toArray(new String[0]); + } +} diff --git a/src/main/java/com/eactive/eai/common/restrict/RestrictInfoVO.java b/src/main/java/com/eactive/eai/common/restrict/RestrictInfoVO.java new file mode 100644 index 0000000..7316b5f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/restrict/RestrictInfoVO.java @@ -0,0 +1,59 @@ +package com.eactive.eai.common.restrict; + +import java.io.Serializable; + +public class RestrictInfoVO implements Serializable { + private String eAICtrlName; // EAI통제명 TSEAITI01.EAICtrlName + private String eAICtrlNameDstcd; // EAI통제명구분코드 TSEAITI01.EAICtrlNameDstcd + private String eAICtrlDsticCtnt; // EAI통제구분내용 TSEAITI01.EAICtrlDsticCtnt + private String ctrlPrcssYMS; // 통제처리일시 TSEAITI01.CtrlPrcssYMS + private String tranCtrlPrcssName; // 거래제어처리명 TSEAITI01.TranCtrlPrcssName + + public String getCtrlPrcssYMS() { + return ctrlPrcssYMS; + } + + public void setCtrlPrcssYMS(String ctrlPrcssYMS) { + this.ctrlPrcssYMS = ctrlPrcssYMS; + } + + public String getEAICtrlDsticCtnt() { + return eAICtrlDsticCtnt; + } + + public void setEAICtrlDsticCtnt(String ctrlDsticCtnt) { + eAICtrlDsticCtnt = ctrlDsticCtnt; + } + + public String getEAICtrlName() { + return eAICtrlName; + } + + public void setEAICtrlName(String ctrlName) { + eAICtrlName = ctrlName; + } + + public String getEAICtrlNameDstcd() { + return eAICtrlNameDstcd; + } + + public void setEAICtrlNameDstcd(String ctrlNameDstcd) { + eAICtrlNameDstcd = ctrlNameDstcd; + } + + public String getTranCtrlPrcssName() { + return tranCtrlPrcssName; + } + + public void setTranCtrlPrcssName(String tranCtrlPrcssName) { + this.tranCtrlPrcssName = tranCtrlPrcssName; + } + + public RestrictInfoVO() { + this(""); + } + + public RestrictInfoVO(String eAICtrlName) { + this.eAICtrlName = eAICtrlName; + } +} diff --git a/src/main/java/com/eactive/eai/common/restrict/mapper/RestrictInfoMapper.java b/src/main/java/com/eactive/eai/common/restrict/mapper/RestrictInfoMapper.java new file mode 100644 index 0000000..1d1a0aa --- /dev/null +++ b/src/main/java/com/eactive/eai/common/restrict/mapper/RestrictInfoMapper.java @@ -0,0 +1,24 @@ +package com.eactive.eai.common.restrict.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.restrict.RestrictInfoVO; +import com.eactive.eai.data.entity.onl.restrict.RestrictInfo; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface RestrictInfoMapper extends GenericMapper { + @Mapping(source = "id", target = "EAICtrlName") + @Mapping(source = "eaictrlnamedstcd", target = "EAICtrlNameDstcd") + @Mapping(source = "eaictrldsticctnt", target = "EAICtrlDsticCtnt") + @Mapping(source = "ctrlprcssyms", target = "ctrlPrcssYMS") + @Mapping(source = "tranctrlprcssname", target = "tranCtrlPrcssName") + @Override + RestrictInfoVO toVo(RestrictInfo entity); + + @InheritInverseConfiguration + RestrictInfo toEntity(RestrictInfoVO vo); +} diff --git a/src/main/java/com/eactive/eai/common/routing/ElinkESBProcess.java b/src/main/java/com/eactive/eai/common/routing/ElinkESBProcess.java new file mode 100644 index 0000000..3d7bcac --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/ElinkESBProcess.java @@ -0,0 +1,36 @@ + +package com.eactive.eai.common.routing; + +import com.eactive.eai.common.message.EAIMessage; + +import java.util.Properties; + +/** + * 1. 기능 : FC 와 Outbound Process를 호출하기 위한 JPD Proxy Interface Class + * 2. 처리 개요 : + * * - + * 3. 주의사항 + * + * @author : DongHoon Lee + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : + * : + */ +public interface ElinkESBProcess +{ + /** + * 1. 기능 : Process의 호출 메소드 + * 2. 처리 개요 : + * - Process의 호출 메소드가 변경된 경우 재정의 해야함. + * 3. 주의사항 + * + * @param message + * @param callProp + * @return EAIMessage + * @exception JpdProxyException + **/ + public abstract EAIMessage callService(EAIMessage message, Properties callProp); + + public static final String SERVICE_URI = "com.eactive.eai.flowcontroller.BaseFCProcess"; +} diff --git a/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java b/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java new file mode 100644 index 0000000..72e8e32 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/ElinkESBProcessProxy.java @@ -0,0 +1,74 @@ +package com.eactive.eai.common.routing; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.util.Logger; + +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + + +/** + * 1. 기능 : ElinkESBProcess를 호출하는 공통 Class + * 2. 처리 개요 : + * * - + * 3. 주의사항 + * + * @author : DongHoon Lee + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : + * : + */ +public class ElinkESBProcessProxy +{ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + public static String PROXY_ERROR_CODE = "RECEAICPR001"; + + private static ConcurrentHashMap classLocalCache = new ConcurrentHashMap(); + + /** + * 1. 기능 : ElinkESBProcess의 호출 메소드(Local|Remote 방식) + * 2. 처리 개요 : + * - + * 3. 주의사항 + * + * @param serviceURI Route하기 위한 Process의 URI + * @param eaiMessage EAIMessage Object + * @param isLocal Local Process 호출인지 Remote Process 호출인지 여부 + * @param prop Remote Process호출인 경우 (RouteKeys.WLI_URL, RouteKeys.WLI_USER,RouteKeys.WLI_PWD)를 설정 + * @return 결과 EAIMessage + * @exception + **/ + public static EAIMessage callElinkESBProcess(String serviceURI, EAIMessage eaiMessage, boolean isLocal, Properties prop) throws Exception + { + EAIMessage retMsg = null; + try { + if (isLocal){ + Class cl = classLocalCache.get(serviceURI); + + if(cl == null) { + cl = Class.forName(serviceURI); + classLocalCache.put(serviceURI, cl); + } + Process proc = (Process)cl.newInstance(); + proc.callService(eaiMessage, prop); + + retMsg = proc.clientReturn(); + }else{ + if(eaiMessage == null) { + throw new Exception("EAIMessage is null"); + } + else { + retMsg = RemoteProxyClient.callProxyBean(eaiMessage, prop); + } + } + } catch( ClassNotFoundException e) { + if (logger.isError()) logger.error("ElinkProcessProxy] callElinkESBProcess["+serviceURI+"] Class Not Found Exception : "); + throw new Exception(PROXY_ERROR_CODE); + } catch( Exception e) { + if (logger.isError()) logger.error("ElinkProcessProxy] callElinkESBProcess["+serviceURI+"] Exception : "+e.getMessage(),e); + throw new Exception(PROXY_ERROR_CODE); + } + return retMsg; + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/ElinkESBTransformProcess.java b/src/main/java/com/eactive/eai/common/routing/ElinkESBTransformProcess.java new file mode 100644 index 0000000..4929fc3 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/ElinkESBTransformProcess.java @@ -0,0 +1,31 @@ + +package com.eactive.eai.common.routing; + +/** + * 1. 기능 : Outbound Process에서 Transform Process 를 호출하기 위한 JPD Proxy Interface Class + * 2. 처리 개요 : + * * - + * 3. 주의사항 + * + * @author : DongHoon Lee + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : + * : + */ +public interface ElinkESBTransformProcess +{ + /** + * 1. 기능 : Transform Process의 호출 메소드 + * 2. 처리 개요 : + * - Transform Process의 호출 메소드가 변경된 경우 재정의 해야함. + * 3. 주의사항 + * + * @param java.io.Serializable + * @return java.io.Serializable + * @exception + **/ + public abstract java.io.Serializable transform(java.io.Serializable object); + + public static final String SERVICE_URI = "com.eactive.eai.transform.HostOpenDeposit200"; +} diff --git a/src/main/java/com/eactive/eai/common/routing/ElinkESBTransformProcessProxy.java b/src/main/java/com/eactive/eai/common/routing/ElinkESBTransformProcessProxy.java new file mode 100644 index 0000000..27f4ecd --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/ElinkESBTransformProcessProxy.java @@ -0,0 +1,51 @@ +package com.eactive.eai.common.routing; + +import com.eactive.eai.common.util.Logger; + + +/** + * 1. 기능 : KBESBProcess를 호출하는 공통 Class + * 2. 처리 개요 : + * * - + * 3. 주의사항 + * + * @author : DongHoon Lee + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : + * : + */ +public class ElinkESBTransformProcessProxy +{ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + public static String TRANPROXY_ERROR_CODE = "RECEAICPR100"; + + /** + * 1. 기능 : KBESBProcess의 호출 메소드(Local|Remote 방식) + * 2. 처리 개요 : + * - + * 3. 주의사항 + * + * @param serviceURI Route하기 위한 Process의 URI + * @param eaiMessage EAIMessage Object + * @param isLocal Local Process 호출인지 Remote Process 호출인지 여부 + * @param prop Remote Process호출인 경우 (RouteKeys.WLI_URL, RouteKeys.WLI_USER,RouteKeys.WLI_PWD)를 설정 + * @return 결과 EAIMessage + * @exception + **/ + public static java.io.Serializable transform(String serviceURI, java.io.Serializable object) throws Exception + { + java.io.Serializable converted = null; + try { +// KBESBTransformProcess proc = null; +// proc = (KBESBTransformProcess)JpdProxy.create(KBESBTransformProcess.class, serviceURI); +// +// converted = proc.transform(object); + + } catch( Exception e) { + if (logger.isError()) logger.error("KBESBTransformProcessProxy] transform["+serviceURI+"] Exception ", e); + throw new Exception(TRANPROXY_ERROR_CODE); + } + return converted; + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/FlowRouter.java b/src/main/java/com/eactive/eai/common/routing/FlowRouter.java new file mode 100644 index 0000000..466c797 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/FlowRouter.java @@ -0,0 +1,186 @@ +package com.eactive.eai.common.routing; + +import java.util.Properties; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.common.session.SessionManager; +import com.eactive.eai.common.util.JMSSender; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ElinkConfig; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +/** + * 1. 기능 : Inbound Layer에서 FlowControl로 라우팅하는 기능을 제공 + * 2. 처리 개요 : + * - Inbound Layer에서 정의한 pProperties를 통해 전달한 값을 기반으로 + * FlowControl로 JMS Queue/JMS Topic/DirectCall 방식으로 EAIMessage를 전달한다. + * 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : + * @since : + * : + */ +public class FlowRouter +{ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static final String FRROUTER_ERROR_INVALID = "RECEAICFR000"; // Routing Info 오류 + public static final String FRROUTER_ERROR_JPD = "RECEAICFR001"; // 호출 오류 + public static final String FRROUTER_ERROR_QUEUE = "RECEAICFR002"; // FC Async Queue 메시지 송신 오류 + public static final String FRROUTER_ERROR_TOPIC = "RECEAICFR003"; // SA 패턴의 응답메시지 전송 오류 + + private static String instPostfix = ""; + + static { + String serverName = System.getProperty(Keys.SERVER_KEY); + if(serverName != null && serverName.length() > 2) { + instPostfix = "_" + EAIServerManager.getInstance().getInstId(); + } + } + + /** + * 1. 기능 : Inbound Layer에서 FlowControl로 라우팅하는 기능을 제공 + * 2. 처리 개요 : + * - Inbound Layer에서 정의한 Properties를 통해 전달한 값을 기반으로 + * FlowControl로 JMS Queue/JMS Topic/JPDProxy 방식으로 EAIMessage를 전달한다. + * 3. 주의사항 + * + * @param eaiMessage Inbound에서 생성한 EAI표준메시지 + * @param prop 라우팅을 위한 환경값 + * @return EAIMessage FlowControl로부터 처리된 결과가 리턴됨 + * @exception + **/ + public static EAIMessage process(EAIMessage eaiMessage, Properties prop) throws Exception { + RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm()); + EAIMessage rtnMsg = null; + + String route_type = prop.getProperty(RouteKeys.ROUTING_TYPE); + +// String guidLogPrefix = "FlowRouter] GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + String guidLogPrefix = "FlowRouter] GUID["+eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage())+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + + if(RouteKeys.ROUT_CALL.equals(route_type)) { + String serviceURI = routingVO.getSyncRoutingPath(); + boolean isLocal = true; + try { + rtnMsg = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, prop); + } catch(Exception e) { + if (logger.isError()) logger.error(guidLogPrefix + " process.JPD Error. JPD Name ["+serviceURI+"]- " + e.getMessage(), e); + //throw new Exception(FRROUTER_ERROR_JPD); + throw new Exception(ExceptionUtil.getErrorCode(e,FRROUTER_ERROR_JPD)); + } + } + else if(RouteKeys.ROUT_QUEUE.equals(route_type)) { + // send Queue + PropManager propManager = PropManager.getInstance(); + String queueConFactory = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY); + + //-------------------------------------------------------------------------- + // 요청거래와 응답거래의 QUEUE를 분리한다 : 2008.10.29 + //-------------------------------------------------------------------------- +// String telgmDmndDstcd = eaiMessage.getKbMsg().getKBHeader().getTelgmDmndDstcd(); +// String telgmDmndDstcd = eaiMessage.getExtMsg().getSendRecv(); + String telgmDmndDstcd = eaiMessage.getMapper().getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R + String routeQueueName = ""; + + routeQueueName = routingVO.getAsynRoutingPath(); + + // 새로 설정한 Queue로 RoutingPath가 정의된 경우 + // 룰 설정이 안된 경우 - 20081111 + if(routeQueueName == null || routeQueueName.trim().length() == 0) { + routeQueueName = "FlowRouterQueue"; + } + else if(routeQueueName.startsWith("com.elink.eai.common")) { + if( STDMessageKeys.SEND_RECV_CD_SEND.equals(telgmDmndDstcd)) { + routeQueueName = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_QUEUE); + } + else { + routeQueueName = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_RESQUEUE); + } + } + else { + // 2009.12.22 + // 다른 인스턴스로 송신하는 부분을 막는다. + // TODO : 적용여부 확인 필요 +// routeQueueName = routeQueueName + instPostfix; + // Local Queue 방식으로 수정함 + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "RoutingPath Async Queue Name - " + routeQueueName); + } + } + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " telgmDmndDstcd[" + telgmDmndDstcd + "] = Async Queue Name - " + routeQueueName); + } + + try { + //-------------------------------------------------------- + // 2009.03.30 - Queue 분리관련 추가 로직 + // EAI 업무그룹코드와 EAI 서비스코드, 표준의 대외기관코드 를 설정 + //-------------------------------------------------------- + prop.setProperty("EAIBWKCLS", eaiMessage.getBwkCls().trim()); + prop.setProperty("EAISVCCD", eaiMessage.getEAISvcCd().trim()); +// prop.setProperty("OSIDINSTCD", eaiMessage.getKbMsg().getKBCommon().getOsidInstiCd().trim()); +// prop.setProperty("OSIDINSTCD", eaiMessage.getExtMsg().getInstitutionCode().trim()); + prop.setProperty("OSIDINSTCD", eaiMessage.getMapper().getInstCode(eaiMessage.getStandardMessage()).trim()); + //-------------------------------------------------------- + } + catch(Exception ex) { + if (logger.isWarn()) logger.debug(guidLogPrefix + "JMS Property set Error - " + ex.getMessage()); + } + + try { + JMSSender.sendToQueue(eaiMessage, queueConFactory, routeQueueName, prop); + } catch(Exception e) { + if (logger.isError()) logger.error(guidLogPrefix +" process.Queue Error. Queue Name[" + routeQueueName + "]- " + e.getMessage(), e); + //throw new Exception(FRROUTER_ERROR_QUEUE); + throw new Exception(ExceptionUtil.getErrorCode(e,FRROUTER_ERROR_QUEUE)); + } + } + else if(RouteKeys.ROUT_TOPIC.equals(route_type)) { + // send Topic + String traceKey = prop.getProperty(RouteKeys.TRACE_KEY); + + PropManager propManager = PropManager.getInstance(); + String topicConFactory = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC_CONNECTION_FACTORY); + String routeTopicName = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC); + String sTTL = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC_TTL); + + long ttl = 60000; // Default Set 60secs + try { + if(sTTL != null && sTTL.length() > 0) { + ttl = Long.parseLong(sTTL); + } + } + catch(Exception e) { + if (logger.isDebug()) logger.debug(guidLogPrefix + " TTL Not Set - " + + RouteKeys.ROUTING_TOPIC_TTL + ":"+ e.getMessage()); + } + + try { + if (ElinkConfig.isUseCacheTopic()) { + SessionManager.getInstance().putTopic(traceKey, eaiMessage); + } + else { + JMSSender.sendToTopic(eaiMessage, topicConFactory, routeTopicName, null, traceKey, ttl); + } + } catch(Exception e) { + if (logger.isError()) logger.error(guidLogPrefix + " process.Topic Error. Topic Name ["+routeTopicName+"]- " + e.getMessage(), e); + //throw new Exception(FRROUTER_ERROR_TOPIC); + throw new Exception(ExceptionUtil.getErrorCode(e,FRROUTER_ERROR_TOPIC)); + } + } + else { + if (logger.isError()) logger.error(guidLogPrefix + " Invalid ROUTING INFO TYPE[" + route_type + "]"); + throw new Exception( FRROUTER_ERROR_INVALID ); + } + + return rtnMsg; + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/GWRemoteProxyClient.java b/src/main/java/com/eactive/eai/common/routing/GWRemoteProxyClient.java new file mode 100644 index 0000000..e15c994 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/GWRemoteProxyClient.java @@ -0,0 +1,137 @@ +package com.eactive.eai.common.routing; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.rmi.server.RMISocketFactory; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang3.time.StopWatch; +import org.springframework.remoting.RemoteConnectFailureException; +import org.springframework.remoting.rmi.RmiProxyFactoryBean; + +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.rmi.GWRemoteProxy; +import com.eactive.eai.common.routing.rmi.TimeoutRmiClientSocketFactory; +import com.eactive.eai.common.util.Logger; + + +public class GWRemoteProxyClient { + + static Logger logger = Logger.getLogger(Logger.LOGGER_SIFT); + private static String SERVICE_URL = "%s/RemoteProxy"; // rmi://%s:1099 + + private static ConcurrentHashMap factoryMap = new ConcurrentHashMap(); + + private static RmiProxyFactoryBean getFactory(String remoteUrl) { + RmiProxyFactoryBean factory = factoryMap.get(remoteUrl); + return factory; + } + + private synchronized static RmiProxyFactoryBean initFactory(String remoteUrl, int connectTimeout, int timeout) { + RmiProxyFactoryBean factory = factoryMap.get(remoteUrl); + if(factory != null) return factory; + + factory = new RmiProxyFactoryBean(); + factory.setServiceInterface(GWRemoteProxy.class); + factory.setServiceUrl(String.format(SERVICE_URL, remoteUrl)); + TimeoutRmiClientSocketFactory registryClientSocketFactory = new TimeoutRmiClientSocketFactory(); + + try { + RMISocketFactory f = RMISocketFactory.getSocketFactory(); + if(f == null) { + RMISocketFactory.setSocketFactory(new RMISocketFactory() { + public Socket createSocket(String host, int port) throws IOException { + int timeout = 120 *1000; // 타임아웃을 기본 120초로 설정 + Socket socket = new Socket(host, port); + socket.setSoTimeout(timeout); + socket.setSoLinger(false, 0); + // System.out.println("RMISocketFactory timeout >> " + timeout); + return socket; + } + public ServerSocket createServerSocket(int port) throws IOException { + return new ServerSocket(port); + } + } + ); + } + else { + logger.warn("initFactory RMISocketFactory already defined : " + f.toString()); + } + registryClientSocketFactory.setConnectTimeout(connectTimeout); + registryClientSocketFactory.setTimeout(timeout); + factory.setRegistryClientSocketFactory(registryClientSocketFactory); + factory.setRefreshStubOnConnectFailure(true); + factory.afterPropertiesSet(); + factoryMap.put(remoteUrl, factory); + return factory; + } catch (Exception e) { + logger.error("initFactory Exception - " + remoteUrl, e); + return null; + } + } + + public static Object callProxyBean(Object message, Properties prop) throws Exception { + Object response = null; + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + String remoteUrl = prop.getProperty(RouteKeys.REMOTE_CALL_URL); + + Properties properties = PropManager.getInstance().getProperties(RouteKeys.REMOTE_CALL); + String connectionTimeout = properties.getProperty(RouteKeys.REMOTE_CALL_CONNECTION_TIMEOUT ,"1000"); +// String readTimeoutAsync = properties.getProperty(RouteKeys.REMOTE_CALL_READ_TIMEOUT_ASYNC ,"4000"); +// String readTimeoutSync = properties.getProperty(RouteKeys.REMOTE_CALL_READ_TIMEOUT_SYNC ,"60000"); + + int connectTimeout = Integer.parseInt(connectionTimeout); + int timeout = 2000; + + if(logger.isDebug()) { + logger.debug("GWRemoteProxyClient] remoteUrl - " + remoteUrl); + logger.debug("GWRemoteProxyClient] connectionTimeout - " + connectionTimeout); + } + +// if( EAIMessageKeys.ASYNC_SVC.equals(psvItfTp) ) { +// timeout = Integer.parseInt(readTimeoutAsync); +// } +// else { +// timeout = Integer.parseInt(readTimeoutSync); +// } + + RmiProxyFactoryBean factory = null; + try { + if(logger.isDebug()) { + logger.debug("GWRemoteProxyClient] Get RemoteProxy/call Service"); + } + if(remoteUrl == null) { + throw new Exception("remoteUrl is NULL"); + } + factory = getFactory(remoteUrl); + if(factory == null) { + factory = initFactory(remoteUrl, connectTimeout, timeout); + if(factory == null) { + logger.error("GWRemoteProxyClient] initFactory Error : " + remoteUrl); + } + } + GWRemoteProxy service = (GWRemoteProxy) factory.getObject(); + response = service.callService(message, prop); + } catch(RemoteConnectFailureException ie) { + logger.warn("GWRemoteProxyClient] Reset RMI Factory : "+ ie.getMessage()); + factory = initFactory(remoteUrl, connectTimeout, timeout); + GWRemoteProxy service = (GWRemoteProxy) factory.getObject(); + response = service.callService(message, prop); + } catch(Exception e) { + logger.error("GWRemoteProxyClient] Get RemoteProxy/call Service Error : "+ e.getMessage(),e); + throw e; + } catch(Throwable t) { + logger.error("GWRemoteProxyClient] Get RemoteProxy/call Service Error : "+ t.getMessage(),t); + throw new Exception("GWRemoteProxyClient] Get RemoteProxy/call Service Error : "+ t.getMessage()); + } finally{ + } + + stopWatch.stop(); + + return response; + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/IFRouter.java b/src/main/java/com/eactive/eai/common/routing/IFRouter.java new file mode 100644 index 0000000..6a8340d --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/IFRouter.java @@ -0,0 +1,262 @@ +package com.eactive.eai.common.routing; + +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.ServiceMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.common.util.Logger; + +/** + * 1. 기능 : Flow Control에서 Outbound 를 호출하기 위한 Router + * 2. 처리 개요 : + * * - FlowControl에서 Outbound 를 호출한다. + * 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : + * : + */ +public class IFRouter +{ + public static final String IFROUTER_ERROR_LOCAL = "RECEAICIR001"; // Local JPD 호출 오류 + public static final String IFROUTER_ERROR_LOCK = "RECEAICIR002"; // Error발생하여 Failover가 불가능함(FailOver Flag=false) + public static final String IFROUTER_ERROR_REMOTE = "RECEAICIR003"; // FailOver증 JPD 호출 오류 + public static final String IFROUTER_INVALID_ROUT = "RECEAICIR099"; // Outbound 이외의 Process를 호출하고록 설정된 경우 + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * 1. 기능 : FlowCOntrol에서 Outbound Process로 라우팅하는 기능을 제공 + * 2. 처리 개요 : + * - FlowControl에서 전달받은 EAIMessage의 Routing명을 통해 JPDProxy 방식으로 EAIMessage를 전달한다. + * 3. 주의사항 + * + * @param eaiMessage Inbound에서 생성한 EAI표준메시지 + * @param callProp 라우팅을 위한 환경값(추가적으로 보낼 인자가 있을 경우 사용) + * @return EAIMessage Outbound Process로부터 처리된 결과가 리턴됨 + * @exception + **/ + public static EAIMessage process(EAIMessage eaiMessage, Properties callProp) throws Exception { + ServiceMessage service = ((ServiceMessage)eaiMessage.getSvcMsgs().get( eaiMessage.getSvcPssSeq() - 1 )); + String routingName = service.getOutbRtnNm(); + boolean isLocal = true; // EAIMessage내의 수동시스템인터페이스유형(AdapterGroupName) + +// String guidLogPrefix = "IFRouter] GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + String guidLogPrefix = "IFRouter] GUID["+eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage())+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + + // TAS 거래는 Local Call 로 처리하도록 한다. (2019.03.04) + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if(eaiServerManager.isTASEnabledEAIServer()) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(service.getPsvSysItfTp()); + if( EAIMessageKeys.TRANTYPE_TAS.equals(eaiMessage.getTranType()) + // RESTAdapter는 교체하지 않는다 + && !StringUtils.equals(adptGrpVO.getType(), "RST")) { +// isLocal = true; +// if (logger.isInfo()) logger.info(guidLogPrefix + " TRANTYPE TAS [" + eaiMessage.getTranType() + "]"); + PropManager manager = PropManager.getInstance(); + Properties prop = manager.getProperties(RouteKeys.SIM); + routingName = prop.getProperty(RouteKeys.SIM_ROUTING,"HTTPOUT"); + String simAdapterGroupName =""; + if (service.isSyncItfTp()){ + simAdapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_SYNC,"_SIM_OU_HTT_SyC"); + }else{ + simAdapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_ASYNC,"_SIM_OU_HTT_AsC"); + } + isLocal = isAlive(simAdapterGroupName); + } + else if( EAIMessageKeys.TRANTYPE_DUMMYROUT.equals(eaiMessage.getTranType()) ) { + isLocal = false; + if (logger.isInfo()) logger.info(guidLogPrefix + " TRANTYPE_DUMMYROUT [" + eaiMessage.getTranType() + "] Route to Other Domain - Local ["+System.getProperty(Keys.EAI_SYSTEMMODE)+"]"); + } + else { + isLocal= isAlive( service.getPsvSysItfTp()); // EAIMessage내의 수동시스템인터페이스유형(AdapterGroupName) + } + } + else { + isLocal = isAlive( service.getPsvSysItfTp()); // EAIMessage내의 수동시스템인터페이스유형(AdapterGroupName) + } + RoutingVO routingUrl = RoutingManager.getInstance().getRoutingVO( routingName ); + + if (logger.isInfo()) { + logger.info(guidLogPrefix + "ROUTING NAME [" + routingName + "]"); + logger.info(guidLogPrefix + "ROUTING URI [" + routingUrl + "]"); + logger.info(guidLogPrefix + "TRANTYPE [" + eaiMessage.getTranType() + "]"); + logger.info(guidLogPrefix + "isLocal [" + isLocal + "]"); + } + + //----------------------------------------------------- + // IFRouter에서는 Outbound Process만 호출할 수 있도록 체크(무한 Loop방지) + // 2006.02.24 - DHLEE + //----------------------------------------------------- + if(! "O".equals(routingUrl.getLayerDstcd()) ) { + throw new Exception(IFROUTER_INVALID_ROUT); + } + + EAIMessage message = null; + if ( eaiMessage.getSvcPssTp().equals( EAIMessage.SINGLE_PROCESS ) + || eaiMessage.getSvcPssTp().equals( EAIMessage.COMPLEX_PROCESS ) ) { + // 단일 수동인터페이스 또는 복합거래 유형인 경우 + + if(!eaiServerManager.isPEAIServer() && EAIMessageKeys.TRANTYPE_DUMMYROUT.equals(eaiMessage.getTranType()) ) { + StringBuffer urlBuf = new StringBuffer(); + + EAIServerManager mgr = EAIServerManager.getInstance(); + EAIServerVO server = mgr.getEAIServer( mgr.getLocalServerName()); + + // get Routing server info + PropManager propManager = PropManager.getInstance(); + String remote_url = propManager.getProperty(RouteKeys.DUMMY_ROUTE_INFO, server.getName()); + if(logger.isWarn()) { + logger.warn(guidLogPrefix + " : DUMMY ROUTE CALL - EAISvcCd="+ eaiMessage.getEAISvcCd() + +", remote_url : " +remote_url); + } + if(remote_url == null) { + String errorMsg = " Dummy Route info not found : Property Group[" + RouteKeys.DUMMY_ROUTE_INFO + "] Property["+server.getName()+"}"; + logger.error(guidLogPrefix + errorMsg); + throw new Exception(errorMsg); + } + urlBuf.append( EAIServerVO.IIOP_PROTOCOL ).append("://"); + urlBuf.append( remote_url ); + + callProp.setProperty( RouteKeys.REMOTE_CALL_URL, urlBuf.toString() ); + + if (logger.isInfo()) { + logger.info(guidLogPrefix + " DummyRoute Remote Call [" + urlBuf.toString() + "] RemoteProxyClient"); + } + + try { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " DummyRoute RemoteProxyClient call"); + } + message = RemoteProxyClient.callProxyBean(eaiMessage, callProp); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " DummyRoute RemoteProxyClient result : "+message); + } + } catch(Exception e) { + logger.error(guidLogPrefix + " DummyRoute Remote Call Error", e); + //throw new Exception(IFROUTER_ERROR_REMOTE); + throw new Exception(ExceptionUtil.getErrorCode(e,IFROUTER_ERROR_REMOTE)); + } + } + else if ( isLocal ) { + try { + message = ElinkESBProcessProxy.callElinkESBProcess( routingUrl.getSyncRoutingPath(), eaiMessage, true, callProp ); + } catch(Exception e) { + //throw new Exception( IFROUTER_ERROR_LOCAL ); + throw new Exception(ExceptionUtil.getErrorCode(e,IFROUTER_ERROR_LOCAL)); + } + } else { + EAIServerManager mgr = EAIServerManager.getInstance(); + EAIServerVO server = mgr.getEAIServer( mgr.getLocalServerName()); + EAIServerVO backupSvr = mgr.getEAIServer( server.getFailoverSvr() ); + + if ( service.getFlOvrCls().equals( EAIMessage.YES_FLAG ) && backupSvr != null) { + //Properties prop = new Properties(); + StringBuffer urlBuf = new StringBuffer(); + urlBuf.append( EAIServerVO.IIOP_PROTOCOL ).append("://"); + urlBuf.append( backupSvr.getAddress() ).append(":"); + urlBuf.append( backupSvr.getRmiPort() ); + + callProp.setProperty( RouteKeys.REMOTE_CALL_URL, urlBuf.toString() ); + + if (logger.isInfo()) { + logger.info(guidLogPrefix + " FailOver Remote Call [" + urlBuf.toString() + "] RemoteProxyClient"); + } + + try { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " FailOver RemoteProxyClient call"); + } + message = RemoteProxyClient.callProxyBean(eaiMessage, callProp); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " FailOver RemoteProxyClient result : "+message); + } + } catch(Exception e) { + logger.error(guidLogPrefix + " FailOver Remote Call Error - " + e.getMessage()); +// e.printStackTrace(); + //throw new Exception(IFROUTER_ERROR_REMOTE); + throw new Exception(ExceptionUtil.getErrorCode(e,IFROUTER_ERROR_REMOTE)); + } + } + else { + throw new Exception( ExceptionUtil.make(IFROUTER_ERROR_LOCK , new String[1]) ); + } + } + } else { + try { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " PCOMPLEX [" + routingUrl.getSyncRoutingPath() + "]"); + } + message = ElinkESBProcessProxy.callElinkESBProcess( routingUrl.getSyncRoutingPath(), eaiMessage, true, callProp ); + } catch(Exception e) { + //throw new Exception( IFROUTER_ERROR_LOCAL ); + throw new Exception(ExceptionUtil.getErrorCode(e,IFROUTER_ERROR_LOCAL)); + } + } + + return message; + } + + /** + * 1. 기능 : Adapter그룹명의 Adapter들의 상태정보를 확인하는 메소드 + * 2. 처리 개요 : + * - AdapterManager를 통해 해당 Adapter그룹의 Adapter의 상태를 확인하여 + * 정상적인 Adapter가 있는지 여부를 리턴한다. + * 3. 주의사항 + * + * @param adapterGroupName Adapter그룹명 + * @return boolean + * @exception Exception + **/ + public static boolean isAlive(String adapterGroupName) throws Exception { + //------------------------------------------------- + // CISCO Router에 대한 처리로직 추가 : 2007.06.15 DHLEE + //------------------------------------------------- + String cadapterGroupName = ""; + String cadapterName = ""; + + if (adapterGroupName.indexOf('.') != -1) { + cadapterName = adapterGroupName.substring(adapterGroupName.indexOf('.')+1); + cadapterGroupName = adapterGroupName.substring(0, adapterGroupName.indexOf('.')); + } + else { + cadapterGroupName = adapterGroupName; + } + + AdapterGroupVO adapterGroup = AdapterManager.getInstance().getAdapterGroupVO( cadapterGroupName ); + if(adapterGroup==null) { + throw new Exception("IFRouter] Cannot find the AdapterGroupVO. - "+ cadapterGroupName); + } + if (adapterGroupName.indexOf('.') != -1) { + AdapterVO vo = adapterGroup.getAdapterVO(cadapterName); + + if (vo == null) { + return false; + }else{ + //라우팅 특정 포트 매핑시 어댑터 업무 이름 선택시 오류 수정 + //isStarted 체크는 node를 변경한경우 대비 + if (vo.isStarted() && vo.isStatus()){ + return true; + }else{ + return false; + } + } + }else{ + return adapterGroup.isAlive(); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/Process.java b/src/main/java/com/eactive/eai/common/routing/Process.java new file mode 100644 index 0000000..9720241 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/Process.java @@ -0,0 +1,171 @@ +package com.eactive.eai.common.routing; + +import java.util.Properties; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.message.service.InterfaceMapper; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public abstract class Process { + + public static final String ADAPTER_TIMEOUT = "ADAPTER_TIMEOUT"; + public static final String ADAPTER_DEFAULT_TIMEOUT = "ADAPTER_DEFAULT_TIMEOUT"; + public static final String HTTP_ADAPTER_TIMEOUT_PROP = "HTTP_ADAPTER_TIMEOUT_PROP"; + public static final String SOCKET_ADAPTER_TIMEOUT_PROP = "SOCKET_ADAPTER_TIMEOUT_PROP"; + + public static final String INTERFACE_TIME_OUT = "INTERFACE_TIME_OUT"; + + + public abstract void callService(EAIMessage message, Properties prop) throws Exception; + public abstract EAIMessage clientReturn() throws Exception; + + protected Object makeStandardMessageData(EAIMessage eaiMessage, String msgType + , Object bizObject, String charset) throws Exception{ + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + + String outboundAdapterGroupName = eaiMessage.getCurrentSvcMsg().getPsvSysItfTp(); + AdapterGroupVO outboundAdapterGvo = AdapterManager.getInstance().getAdapterGroupVO(outboundAdapterGroupName); + standardMessage.setBizData(bizObject, outboundAdapterGvo.getMessageEncode()); + + if(MessageType.JSON.equals(msgType)) { + return standardMessage.toJson(); + } + else if(MessageType.XML.equals(msgType)) { + return standardMessage.toXML(); + } + else if(MessageType.ASC.equals(msgType)) { + return standardMessage.toByteArray(charset); + } + else { + throw new Exception("Unsupported msgType - " + msgType); + } + } + + protected String getGuidSeq(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getGuidSeq(standardMessage); + } + + protected String getGuid(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getGuid(standardMessage); + } + + protected String getOrgGuid(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getOrgGuid(standardMessage); + } + + protected String getReqSysCode(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getReqSysCode(standardMessage); + } + + protected String getTimeout(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getTimeout(standardMessage); + } + + protected void setTimeout(EAIMessage eaiMessage, String timeout) { + InterfaceMapper mapper = eaiMessage.getMapper(); + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + mapper.setTimeout(standardMessage, timeout); + } + + protected String getRecoverYn(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getRecoverYn(standardMessage); + } + + protected String getInstCode(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getInstCode(standardMessage); + } + + protected String getOperationEnv(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getOperationEnv(standardMessage); + } + + protected String getFirstRequestSysIp(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getFirstReqIp(standardMessage); + } + + protected String getServiceId(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getServiceId(standardMessage); + } + + protected String getReturnType(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + if(mapper == null) return null; + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return mapper.getSendRecvDivision(standardMessage); + } + + protected void setReturnType(EAIMessage eaiMessage, String returnType) { + InterfaceMapper mapper = eaiMessage.getMapper(); + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + mapper.setSendRecvDivision(standardMessage, returnType); + } + + protected EAIMessage setResponseForOutbound(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV); + return eaiMessage; + } + + protected EAIMessage setSendTime(EAIMessage eaiMessage) { + InterfaceMapper mapper = eaiMessage.getMapper(); + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + mapper.setSendTime(standardMessage, DatetimeUtil.getCurrentTimeMillis()); + return eaiMessage; + } + + protected EAIMessage setRcvLogInfo(EAIMessage eaiMessage, String msgType, Object message, String charset) + throws Exception { + InterfaceMapper mapper = eaiMessage.getMapper(); + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardMessage standardMessage = standardManager.getStandardMessage(); + StandardReader reader = standardManager.getReader(msgType); + if (reader == null) { + throw new Exception("StandardReader not found, msgType - " + msgType); + } + reader.parse(standardMessage, message); + standardMessage.setBizDataCharset(charset); + standardManager.getMessageCoordinator().coordinateAfterParsing(standardMessage, null, new Properties()); + eaiMessage.setStandardMessage(standardMessage); + + mapper.setRecvTime(standardMessage, DatetimeUtil.getCurrentTimeMillis()); + return eaiMessage; + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/ProcessFactory.java b/src/main/java/com/eactive/eai/common/routing/ProcessFactory.java new file mode 100644 index 0000000..ac2e9d2 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/ProcessFactory.java @@ -0,0 +1,91 @@ +package com.eactive.eai.common.routing; + + + +/** +* 1. 기능 : Process 초기화 하기 위한 Factory Class +* 2. 처리 개요 : +* - 초기화 된 Process 인스턴스를 HashMap 객체에 담는다. +* - 해당 어댑터의 Process 인스턴스를 반환 한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : Process +* @since : +*/ +public class ProcessFactory +{ +// private static final String BaseFCProcess = "com.eactive.eai.flowcontroller.BaseFCProcess"; +// private static final String B2BFCProcess = "com.eactive.eai.flowcontroller.B2BFCProcess"; +// private static final String C2RFCProcess = "com.eactive.eai.flowcontroller.C2RFCProcess"; +// +// +// private static final String SocketProcess = "com.eactive.eai.outbound.SocketProcess"; +// private static final String HTTPProcess = "com.eactive.eai.outbound.HTTPProcess"; +// private static final String SIMHTTPProcess = "com.eactive.eai.outbound.SIMHTTPProcess"; +// private static final String LoopBackProcess = "com.eactive.eai.outbound.LoopBackProcess"; + + /** + * ProcessFactory instance + */ + private static final ProcessFactory factory = new ProcessFactory(); + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * - 타입 별 Process instance를 어댑터 HashMap에 담는다. + * 3. 주의사항 + * + **/ + private ProcessFactory() { + } + + /** + * 1. 기능 : ProcessFactory Object를 반환하는 getter method + * 2. 처리 개요 : ProcessFactory Object를 반환한다. + * 3. 주의사항 + * + * @return ProcessFactory object + **/ + public static ProcessFactory newInstance() { + return factory; + } + + /** + * 1. 기능 : 해당 프로세스의 Process Object를 반환 + * 2. 처리 개요 : + * - Process instance HashMap으로 부터 해당 어댑터의 Process Object를 반환 한다. + * 3. 주의사항 + * + * @param serviceURI URI + * @return Process object + **/ + public Process getProcess(String serviceURI) throws Exception { + if(serviceURI==null) return null; + Process process = null; + +// if(serviceURI.equals(BaseFCProcess)) { +// process = new com.eactive.eai.flowcontroller.BaseFCProcess(); +// } else if(serviceURI.equals(B2BFCProcess)) { +// process = new com.eactive.eai.flowcontroller.B2BFCProcess(); +// } else if(serviceURI.equals(C2RFCProcess)) { +// process = new com.eactive.eai.flowcontroller.C2RFCProcess(); +// } else if(serviceURI.equals(SocketProcess)) { +// process = new com.eactive.eai.outbound.SocketProcess(); +// } else if(serviceURI.equals(HTTPProcess)) { +// process = new com.eactive.eai.outbound.HTTPProcess(); +// } else if(serviceURI.equals(SIMHTTPProcess)) { +// process = new com.eactive.eai.outbound.SIMHTTPProcess(); +// } else if(serviceURI.equals(LoopBackProcess)) { +// process = new com.eactive.eai.outbound.LoopBackProcess(); +// } + if(process==null) { + throw new RuntimeException("Process not found. - "+serviceURI); + } + return process; + } + + +} + diff --git a/src/main/java/com/eactive/eai/common/routing/RemoteProxyClient.java b/src/main/java/com/eactive/eai/common/routing/RemoteProxyClient.java new file mode 100644 index 0000000..d4455db --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/RemoteProxyClient.java @@ -0,0 +1,152 @@ +package com.eactive.eai.common.routing; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.rmi.RemoteProxy; +import com.eactive.eai.common.routing.rmi.TimeoutRmiClientSocketFactory; +import com.eactive.eai.common.util.Logger; +import org.apache.commons.lang3.time.StopWatch; +import org.springframework.remoting.RemoteConnectFailureException; +import org.springframework.remoting.rmi.RmiProxyFactoryBean; + +import java.io.IOException; +import java.net.ServerSocket; +import java.net.Socket; +import java.rmi.server.RMISocketFactory; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + + +public class RemoteProxyClient { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static String SERVICE_URL = "%s/RemoteProxy"; // rmi://%s:1099 + +// private static factory = null; +// private static String currentUrl = null; +// FailOver인스턴스 이외에도 호출할 수 있도록 Map으로 수정함. 2021-04-05 + private static ConcurrentHashMap factoryMap = new ConcurrentHashMap(); + + private static RmiProxyFactoryBean getFactory(String remoteUrl) { + RmiProxyFactoryBean factory = factoryMap.get(remoteUrl); + return factory; + } + + private synchronized static RmiProxyFactoryBean initFactory(String remoteUrl, int connectTimeout, int timeout) { + RmiProxyFactoryBean factory = factoryMap.get(remoteUrl); + if(factory != null) return factory; + + factory = new RmiProxyFactoryBean(); + factory.setServiceInterface(RemoteProxy.class); + factory.setServiceUrl(String.format(SERVICE_URL, remoteUrl)); + TimeoutRmiClientSocketFactory registryClientSocketFactory = new TimeoutRmiClientSocketFactory(); + + try { + RMISocketFactory f = RMISocketFactory.getSocketFactory(); + if(f == null) { + RMISocketFactory.setSocketFactory(new RMISocketFactory() { + public Socket createSocket(String host, int port) throws IOException { + int timeout = 120 *1000; // 타임아웃을 기본 120초로 설정 + Socket socket = new Socket(host, port); + socket.setSoTimeout(timeout); + socket.setSoLinger(false, 0); + // System.out.println("RMISocketFactory timeout >> " + timeout); + return socket; + } + public ServerSocket createServerSocket(int port) throws IOException { + return new ServerSocket(port); + } + } + ); + } + else { + logger.warn("initFactory RMISocketFactory already defined : " + f.toString()); + } + registryClientSocketFactory.setConnectTimeout(connectTimeout); + registryClientSocketFactory.setTimeout(timeout); + factory.setRegistryClientSocketFactory(registryClientSocketFactory); + factory.setRefreshStubOnConnectFailure(true); + factory.afterPropertiesSet(); + factoryMap.put(remoteUrl, factory); + return factory; + } catch (Exception e) { + logger.error("initFactory Exception - " + remoteUrl, e); + return null; + } + } + + public static EAIMessage callProxyBean(EAIMessage eaiMessage, Properties prop) throws Exception { + EAIMessage response = null; +// Object obj = null; + if(logger.isDebug()) { +// logger.debug("RemoteProxyClient] Start - GUID(" + eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"), IFseq("+ eaiMessage.getSvcOgNo()+")" ); + logger.debug("RemoteProxyClient] Start - GUID(" + eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) +"), IFseq("+ eaiMessage.getSvcOgNo()+")" ); + } + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + String psvItfTp = eaiMessage.getCurrentSvcMsg().getPsvItfTp(); + + String remoteUrl = prop.getProperty(RouteKeys.REMOTE_CALL_URL); + + Properties properties = PropManager.getInstance().getProperties(RouteKeys.REMOTE_CALL); +// String user = properties.getProperty(RouteKeys.REMOTE_CALL_USER); +// String pwd = properties.getProperty(RouteKeys.REMOTE_CALL_PWD); + String connectionTimeout = properties.getProperty(RouteKeys.REMOTE_CALL_CONNECTION_TIMEOUT ,"1000"); + String readTimeoutAsync = properties.getProperty(RouteKeys.REMOTE_CALL_READ_TIMEOUT_ASYNC ,"4000"); + String readTimeoutSync = properties.getProperty(RouteKeys.REMOTE_CALL_READ_TIMEOUT_SYNC ,"60000"); + + int connectTimeout = Integer.parseInt(connectionTimeout); + int timeout = 2000; + + if(logger.isDebug()) { + logger.debug("RemoteProxyClient] remoteUrl - " + remoteUrl); + logger.debug("RemoteProxyClient] connectionTimeout - " + connectionTimeout); + } + + if( EAIMessageKeys.ASYNC_SVC.equals(psvItfTp) ) { + timeout = Integer.parseInt(readTimeoutAsync); + } + else { + timeout = Integer.parseInt(readTimeoutSync); + } + + RmiProxyFactoryBean factory = null; + try { + if(logger.isDebug()) { + logger.debug("RemoteProxyClient] Get RemoteProxy/call Service"); + } + if(remoteUrl == null) { + throw new Exception("remoteUrl is NULL"); + } + factory = getFactory(remoteUrl); + if(factory == null) { + factory = initFactory(remoteUrl, connectTimeout, timeout); + if(factory == null) { + logger.error("RemoteProxyClient] initFactory Error : "+remoteUrl); + } + } + RemoteProxy service = (RemoteProxy) factory.getObject(); + response = service.callService(eaiMessage, prop); + } catch(RemoteConnectFailureException ie) { + logger.warn("RemoteProxyClient] Reset RMI Factory : "+ ie.getMessage()); + factory = initFactory(remoteUrl, connectTimeout, timeout); + RemoteProxy service = (RemoteProxy) factory.getObject(); + response = service.callService(eaiMessage, prop); + } catch(Exception e) { + logger.error("RemoteProxyClient] Get RemoteProxy/call Service Error : "+ e.getMessage(),e); + throw e; + } catch(Throwable t) { + logger.error("RemoteProxyClient] Get RemoteProxy/call Service Error : "+ t.getMessage(),t); + throw new Exception("RemoteProxyClient] Get RemoteProxy/call Service Error : "+ t.getMessage()); + } finally{ + } + + stopWatch.stop(); + if(logger.isDebug()) { +// logger.debug("RemoteProxyClient] End - GUID(" + eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"), IFseq("+ eaiMessage.getSvcOgNo() +"), time=("+stopWatch.getTime()+")" ); + logger.debug("RemoteProxyClient] End - GUID(" + eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) +"), IFseq("+ eaiMessage.getSvcOgNo() +"), time=("+stopWatch.getTime()+")" ); + } + return response; + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/RouteKeys.java b/src/main/java/com/eactive/eai/common/routing/RouteKeys.java new file mode 100644 index 0000000..cfd1597 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/RouteKeys.java @@ -0,0 +1,61 @@ +package com.eactive.eai.common.routing; + +/** + * 1. 기능 : routing 패키지에서 사용하는 상수값들을 정의한 Interface Class + * 2. 처리 개요 : + * * - routing 패키지에서 사용하는 상수값들을 정의한 Interface Class + * 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : + * : + */ +public interface RouteKeys +{ + + public static final String REMOTE_CALL = "REMOTE_CALL"; + public static final String REMOTE_CONTAINER_ID = "REMOTE_CONTAINER_ID"; + public static final String REMOTE_CALL_URL = "REMOTE_CALL_URL"; + public static final String REMOTE_CALL_CONNECTION_TIMEOUT = "REMOTE_CALL_CONNECTION_TIMEOUT"; + public static final String REMOTE_CALL_READ_TIMEOUT_ASYNC = "REMOTE_CALL_READ_TIMEOUT_ASYNC"; + public static final String REMOTE_CALL_READ_TIMEOUT_SYNC = "REMOTE_CALL_READ_TIMEOUT_SYNC"; + + public static final String GROUP_NAME = "FlowRouter"; + + public static final String ROUTING_QUEUE_CONNECTION_FACTORY = "routing.queue.connection.factory"; + public static final String ROUTING_TOPIC_CONNECTION_FACTORY = "routing.topic.connection.factory"; + public static final String ROUTING_QUEUE = "routing.queue"; + public static final String ROUTING_RESQUEUE = "routing.resqueue"; // 비동기응답거래를 위한 Queue : 2008.10.29 + public static final String ROUTING_TOPIC = "routing.topic"; + public static final String ROUTING_TOPIC_TTL = "routing.topic.ttl"; + + // ActiveMQ AmqPooledConnectionFactory configuration + public static final String ROUTING_QUEUE_CONNECTION_FACTORY_MAXCONNECTION = "routing.queue.connection.factory.maxconnection"; + public static final String ROUTING_QUEUE_CONNECTION_FACTORY_EXPIRYTIMEOUT = "routing.queue.connection.factory.expirytimeout"; + public static final String ROUTING_QUEUE_CONNECTION_FACTORY_IDLETIMEOUT = "routing.queue.connection.factory.idletimeout"; + + + // RequestProcessor에서 FlowRouter로 전달하는 Routing 방식 정의 + public static final String ROUTING_TYPE = "ROUTING_TYPE"; + + public static final String ROUT_QUEUE = "ROUT_QUEUE"; + public static final String ROUT_TOPIC = "ROUT_TOPIC"; + public static final String ROUT_CALL = "ROUT_CALL"; + + // 동기-비동기의 응답메시지에 대한 TOPIC JMSCorrelationID + public static final String TRACE_KEY = "TRACE_KEY"; + + // 더미단말(연수단말) 거래를 위한 라우팅 정보저장 + public static final String DUMMY_ROUTE_INFO = "DUMMY_ROUTE_INFO"; + public static final String REMOTE_URL = "REMOTE_URL"; // 사용하지 않을 수 있음 + + //시뮬레이터 prop 관련 + public static final String SIM = "SIM"; + public static final String SIM_ROUTING = "sim.routing"; + public static final String SIM_ADAPTER_SYNC = "sim.adapter.sync"; + public static final String SIM_ADAPTER_ASYNC = "sim.adapter.async"; + public static final String SIM_REST_MOCKSERVER = "sim.rest.mockserver"; + +} diff --git a/src/main/java/com/eactive/eai/common/routing/RoutingDAO.java b/src/main/java/com/eactive/eai/common/routing/RoutingDAO.java new file mode 100644 index 0000000..c002581 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/RoutingDAO.java @@ -0,0 +1,56 @@ +package com.eactive.eai.common.routing; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.routing.loader.RoutingLoader; +import com.eactive.eai.common.routing.mapper.RoutingMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.routing.Routing; + +@Service +@Transactional +public class RoutingDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private RoutingLoader routingLoader; + + @Autowired + private RoutingMapper routingMapper; + + public Map getAllRoutings() throws DAOException { + try { + Map routingMap = new HashMap<>(); + List routings = routingLoader.findAllByOrderByDefault(); + if(logger.isInfo()) logger.info("[ @@ Load Routing Configuration - starting >>>>>>>>>>>>>>>>> ]"); + for (Routing routing : routings) { + RoutingVO routingVO = routingMapper.toVo(routing); + routingMap.put(routingVO.getName(), routingVO); + } + if(logger.isInfo()) logger.info("[>>Load Routing Configuration - ended ]"); + return routingMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICRT101")); + } + } + + public RoutingVO getRouting(String routingName) throws DAOException { + try { + Routing routing = routingLoader.getById(routingName); + RoutingVO routingVO = routingMapper.toVo(routing); + if(logger.isInfo()) logger.info("@ " + routingVO.toString()); + return routingVO; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICRT101")); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/RoutingManager.java b/src/main/java/com/eactive/eai/common/routing/RoutingManager.java new file mode 100644 index 0000000..bbaff6b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/RoutingManager.java @@ -0,0 +1,121 @@ +package com.eactive.eai.common.routing; + +import java.util.Arrays; +import java.util.Iterator; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class RoutingManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private Map routings; + + private boolean started; + + @Autowired + private RoutingDAO routingDAO; + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + public static RoutingManager getInstance() { + return ApplicationContextProvider.getContext().getBean(RoutingManager.class); + } + + public void start() throws LifecycleException { + if (started) { + throw new LifecycleException("RECEAICRT201"); + } + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICRT202")); + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + this.routings = routingDAO.getAllRoutings(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("RoutingManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("RoutingManager] reload all finished ..."); + } + } + + public synchronized void reload(String routingName) throws Exception { + RoutingVO vo = routingDAO.getRouting(routingName); + if (vo != null) { + this.routings.put(routingName, vo); + } else { + throw new Exception("Routing not found in Database : key[" + routingName + "]"); + } + } + + public void stop() throws LifecycleException { + if (!started) { + throw new LifecycleException("RECEAICRT203"); + } + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public RoutingVO getRoutingVO(String name) { + return (RoutingVO) routings.get(name); + } + + public String[] getAllRoutingNames() { + Iterator it = this.routings.keySet().iterator(); + String[] routingNames = new String[this.routings.size()]; + for (int i = 0; it.hasNext(); i++) { + routingNames[i] = it.next(); + } + Arrays.sort(routingNames); + return routingNames; + } + + public Iterator getAllRoutingVOs() { + return this.routings.values().iterator(); + } + + public void setRoutingVO(RoutingVO vo) { + routings.put(vo.getName(), vo); + } + + public void removeRoutingVO(String name) { + routings.remove(name); + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/RoutingVO.java b/src/main/java/com/eactive/eai/common/routing/RoutingVO.java new file mode 100644 index 0000000..c7e3600 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/RoutingVO.java @@ -0,0 +1,85 @@ +package com.eactive.eai.common.routing; + +import java.io.Serializable; + +/** +* 1. 기능 : Routing Rule 정보를 표현하는 Java Value Object 클래스. +* 2. 처리 개요 : Layer간 호출을 담당하는 Routing Rule 정보를 정의한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class RoutingVO implements Serializable +{ + + private String name; //라우팅명 [TSEAIFR02.RoutName] - RoutingName + private String syncRoutingPath; //동기라우팅URI명 [TSEAIFR02.NonMotivRoutURIName] - SynchronousRoutingURIName + private String asynRoutingPath; //비동기라우팅URI명 [TSEAIFR02.MotivRoutURIName] - AsynchronousRoutingURI + + //migration by kscheon + private String layerDstcd; //레이어구분코드 [TSEAIFR02.LayerDstcd] - LayerClassificationCode + + public RoutingVO() { + } + + + public RoutingVO(String name, String syncRoutingPath, String asynRoutingPath, String layerDstcd) { + this.name = name; + this.syncRoutingPath = syncRoutingPath; + this.asynRoutingPath = asynRoutingPath; + this.layerDstcd = layerDstcd; + } + + + public void setName(String name) { + this.name = name; + } + + + public String getName() { + return this.name; + } + + + public void setSyncRoutingPath(String syncRoutingPath) { + this.syncRoutingPath = syncRoutingPath; + } + + + public String getSyncRoutingPath() { + return this.syncRoutingPath; + } + + public void setAsynRoutingPath(String asynRoutingPath) { + this.asynRoutingPath = asynRoutingPath; + } + + public String getAsynRoutingPath() { + return this.asynRoutingPath; + } + + //migration by kscheon - start + public String getLayerDstcd() { + return this.layerDstcd; + } + + public void setLayerDstcd(String layerDstcd) { + this.layerDstcd = layerDstcd; + } + //migration by kscheon - end + + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("RoutingVO[ name=").append(name); + sb.append(", syncRoutingPath=").append(syncRoutingPath); + sb.append(", asynRoutingPath=").append(asynRoutingPath); + sb.append(" ]"); + + return sb.toString(); + } + +} diff --git a/src/main/java/com/eactive/eai/common/routing/mapper/RoutingMapper.java b/src/main/java/com/eactive/eai/common/routing/mapper/RoutingMapper.java new file mode 100644 index 0000000..97a9208 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/mapper/RoutingMapper.java @@ -0,0 +1,23 @@ +package com.eactive.eai.common.routing.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.routing.RoutingVO; +import com.eactive.eai.data.entity.onl.routing.Routing; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface RoutingMapper extends GenericMapper { + @Mapping(source = "id", target = "name") + @Mapping(source = "layerdstcd", target = "layerDstcd") + @Mapping(source = "motivrouturiname", target = "syncRoutingPath") + @Mapping(source = "nonmotivrouturiname", target = "asynRoutingPath") + @Override + RoutingVO toVo(Routing entity); + + @InheritInverseConfiguration + Routing toEntity(RoutingVO vo); +} diff --git a/src/main/java/com/eactive/eai/common/routing/pool/PublishThread.java b/src/main/java/com/eactive/eai/common/routing/pool/PublishThread.java new file mode 100644 index 0000000..880435d --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/pool/PublishThread.java @@ -0,0 +1,46 @@ +package com.eactive.eai.common.routing.pool; + +import java.util.Properties; + +import org.apache.commons.lang.time.StopWatch; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.routing.RemoteProxyClient; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.util.Logger; + +public class PublishThread implements Runnable { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private java.util.Properties callProp; + private com.eactive.eai.common.message.EAIMessage eaiMessage; + + public PublishThread(Properties callProp, EAIMessage eaiMessage) { + this.callProp = callProp; + this.eaiMessage = eaiMessage; + } + + public void run(){ + // RemoteProxyClient로 Remote의 EJB 호출 + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + if (logger.isInfo()) { + logger.info("PublishThread] RemoteProxyClient call - " + callProp.getProperty(RouteKeys.REMOTE_CONTAINER_ID) + " " + + callProp.getProperty(RouteKeys.REMOTE_CALL_URL)); + } + + try { + RemoteProxyClient.callProxyBean(eaiMessage, callProp); + } catch (Exception e) { + if (logger.isError()) + logger.error("PublishThread] RemoteProxyClient call ERROR." + e.getMessage(), e); + } finally { + ; + } + stopWatch.stop(); + if (logger.isInfo()) { + logger.info("PublishThread] RemoteProxyClient result time(" + stopWatch.getTime() + + ")"); + } + } + +} diff --git a/src/main/java/com/eactive/eai/common/routing/pool/RoutingThreadPoolExecutor.java b/src/main/java/com/eactive/eai/common/routing/pool/RoutingThreadPoolExecutor.java new file mode 100644 index 0000000..775d27e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/pool/RoutingThreadPoolExecutor.java @@ -0,0 +1,35 @@ +package com.eactive.eai.common.routing.pool; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class RoutingThreadPoolExecutor { + private static RoutingThreadPoolExecutor instance = new RoutingThreadPoolExecutor(); + + /** + * 기동 여부 + */ + private boolean started = false; + private static ExecutorService executor = Executors.newFixedThreadPool(10); + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + private RoutingThreadPoolExecutor() { + + } + + public static RoutingThreadPoolExecutor getInstance() { + return instance; + } + + public ExecutorService getExecutor(){ + return executor; + } + public static void destroy(){ + instance = null; + executor.shutdownNow(); + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/rmi/GWRemoteProxy.java b/src/main/java/com/eactive/eai/common/routing/rmi/GWRemoteProxy.java new file mode 100644 index 0000000..176f1d8 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/rmi/GWRemoteProxy.java @@ -0,0 +1,7 @@ +package com.eactive.eai.common.routing.rmi; + +import java.util.Properties; + +public interface GWRemoteProxy { + public Object callService(Object message, Properties callProp) ; +} diff --git a/src/main/java/com/eactive/eai/common/routing/rmi/GWRemoteProxyImpl.java b/src/main/java/com/eactive/eai/common/routing/rmi/GWRemoteProxyImpl.java new file mode 100644 index 0000000..72d5a83 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/rmi/GWRemoteProxyImpl.java @@ -0,0 +1,30 @@ +package com.eactive.eai.common.routing.rmi; + +import java.util.Properties; + +import com.eactive.eai.adapter.socket2.common.StopWatch; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.inbound.processor.GWRequestProcessor; + +public class GWRemoteProxyImpl implements GWRemoteProxy { + + static Logger logger = Logger.getLogger(Logger.LOGGER_SIFT); + + @Override + public Object callService(Object message, Properties callProp) { + Object response = null; + + try { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + response = GWRequestProcessor.callService(message, callProp); + + stopWatch.stop(); + } catch(Exception e) { + logger.error("GWRemoteProxy called service Error : " + e.getMessage(), e); + } + + return response; + } +} diff --git a/src/main/java/com/eactive/eai/common/routing/rmi/RemoteProxy.java b/src/main/java/com/eactive/eai/common/routing/rmi/RemoteProxy.java new file mode 100644 index 0000000..9b3118e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/rmi/RemoteProxy.java @@ -0,0 +1,9 @@ +package com.eactive.eai.common.routing.rmi; + +import com.eactive.eai.common.message.EAIMessage; + +import java.util.Properties; + +public interface RemoteProxy { + public EAIMessage callService(EAIMessage eaiMessage, Properties callProp) ; +} diff --git a/src/main/java/com/eactive/eai/common/routing/rmi/RemoteProxyImpl.java b/src/main/java/com/eactive/eai/common/routing/rmi/RemoteProxyImpl.java new file mode 100644 index 0000000..88b09f7 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/rmi/RemoteProxyImpl.java @@ -0,0 +1,50 @@ +package com.eactive.eai.common.routing.rmi; + +import com.eactive.eai.adapter.socket2.common.StopWatch; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.ServiceMessage; +import com.eactive.eai.common.routing.ElinkESBProcessProxy; +import com.eactive.eai.common.routing.RoutingManager; +import com.eactive.eai.common.routing.RoutingVO; +import com.eactive.eai.common.util.Logger; + +import java.util.Properties; + +public class RemoteProxyImpl implements RemoteProxy { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// private String name = this.getClass().getName(); + + @Override + public EAIMessage callService(EAIMessage eaiMessage, Properties callProp) { + EAIMessage message = null; + String guidLogPrefix = "RemoteProxyImpl] "; + try { +// guidLogPrefix = "RemoteProxyImpl] GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + guidLogPrefix = "RemoteProxyImpl] GUID["+eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage())+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + + if(logger.isDebug()) { + logger.debug(guidLogPrefix + " called service["+eaiMessage.getEAISvcCd()+ "] UUID["+eaiMessage.getSvcOgNo()+"]"); + } + ServiceMessage service = (eaiMessage.getSvcMsgs().get( eaiMessage.getSvcPssSeq() - 1 )); + String routingName = service.getOutbRtnNm(); + RoutingVO routingUrl = RoutingManager.getInstance().getRoutingVO( routingName ); + + message = ElinkESBProcessProxy.callElinkESBProcess( routingUrl.getSyncRoutingPath(), eaiMessage, true, callProp ); + stopWatch.stop(); + if(logger.isDebug()) { + logger.debug(guidLogPrefix + " called service["+eaiMessage.getEAISvcCd()+ "] time("+stopWatch.getTime()+") "); + } + + } + catch(Exception e) { + if(logger.isError() && eaiMessage != null) { + logger.error(guidLogPrefix+ " called service["+eaiMessage.getEAISvcCd()+ + "] UUID["+eaiMessage.getSvcOgNo()+"] Error : "+e.getMessage(),e); + } + } + return message; + } + +} diff --git a/src/main/java/com/eactive/eai/common/routing/rmi/TimeoutRmiClientSocketFactory.java b/src/main/java/com/eactive/eai/common/routing/rmi/TimeoutRmiClientSocketFactory.java new file mode 100644 index 0000000..9167a7f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/routing/rmi/TimeoutRmiClientSocketFactory.java @@ -0,0 +1,42 @@ +package com.eactive.eai.common.routing.rmi; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.rmi.server.RMIClientSocketFactory; + +public class TimeoutRmiClientSocketFactory implements RMIClientSocketFactory { + private int connectTimeout = 2000; + private int timeout = 2000; + + public TimeoutRmiClientSocketFactory() { + super(); + } + + public TimeoutRmiClientSocketFactory(int timeout) { + super(); + this.timeout = timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + public void setConnectTimeout(int connectTimeout) { + this.connectTimeout = connectTimeout; + } + + @Override + public Socket createSocket(String host, int port) throws IOException { + final Socket socket = new Socket(); + socket.setSoTimeout(timeout); + socket.setSoLinger(false, 0); + + socket.connect(new InetSocketAddress(host, port), connectTimeout); + +// System.out.println("CreateSocket : " + socket +": timeout = " +socket.getSoTimeout()); + + return socket; + } + + } diff --git a/src/main/java/com/eactive/eai/common/security/CryptAction.java b/src/main/java/com/eactive/eai/common/security/CryptAction.java new file mode 100644 index 0000000..af57e1f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/security/CryptAction.java @@ -0,0 +1,7 @@ +package com.eactive.eai.common.security; + +public interface CryptAction +{ + public Object encrypt(Object message) throws CryptException; + public Object decrypt(Object message) throws CryptException; +} diff --git a/src/main/java/com/eactive/eai/common/security/CryptException.java b/src/main/java/com/eactive/eai/common/security/CryptException.java new file mode 100644 index 0000000..0944f74 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/security/CryptException.java @@ -0,0 +1,13 @@ +package com.eactive.eai.common.security; + +public class CryptException extends Exception{ + private static final long serialVersionUID = 1L; + + public CryptException() { + super("CryptException is occured."); + } + + public CryptException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/common/session/CacheInfoVO.java b/src/main/java/com/eactive/eai/common/session/CacheInfoVO.java new file mode 100644 index 0000000..53a244a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/CacheInfoVO.java @@ -0,0 +1,70 @@ +package com.eactive.eai.common.session; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * 1. 기능 : Cache정보를 표현하는 Java Value Object 클래스. 2. 처리 개요 : Cache 정보를 정의한다. 3. + * 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : + */ +public class CacheInfoVO implements Serializable { + private String name; + private List keys; + private long size; + private long timeToLive; + + /** + * 1. 기능 : EAI서비스 코드를 초기화하는 생성자 함수 2. 처리 개요 : EAI 서비스 코드를 초기화한다. 3. 주의사항 + * + * @param eaiInstCd + * EAI 서버인스턴스명 + * @param eaiSvcCd + * EAI 서비스 코드 + **/ + public CacheInfoVO() { + keys = new ArrayList(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getKeys() { + return keys; + } + + public void setKeys(List keys) { + this.keys = keys; + } + + public long getTimeToLive() { + return timeToLive; + } + + public long getTimeToLiveSeconds() { + return timeToLive / 1000; + } + + public void setTimeToLive(long timeToLive) { + this.timeToLive = timeToLive; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + +} diff --git a/src/main/java/com/eactive/eai/common/session/CacheStoreObject.java b/src/main/java/com/eactive/eai/common/session/CacheStoreObject.java new file mode 100644 index 0000000..dd445b7 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/CacheStoreObject.java @@ -0,0 +1,22 @@ +package com.eactive.eai.common.session; + +import java.io.Serializable; + +public class CacheStoreObject implements Serializable { + private static final long serialVersionUID = 1L; + private String message; + private long expirationTime; + + public CacheStoreObject(String message, long expirationTime) { + this.message = message; + this.expirationTime = expirationTime; + } + + public String getMessage() { + return message; + } + + public boolean isExpired() { + return System.currentTimeMillis() > expirationTime; + } +} diff --git a/src/main/java/com/eactive/eai/common/session/ChannelSessionFacade.java b/src/main/java/com/eactive/eai/common/session/ChannelSessionFacade.java new file mode 100644 index 0000000..ddb3668 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/ChannelSessionFacade.java @@ -0,0 +1,514 @@ +package com.eactive.eai.common.session; + +import java.util.List; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang.StringUtils; +import org.java_websocket.WebSocket; +import org.json.simple.JSONObject; +import org.springframework.scheduling.concurrent.CustomizableThreadFactory; + +import com.eactive.eai.adapter.websocket.WebSocketSessionManager; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.property.PropertyLoginKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.sessioninfo.SessionHistoryDTO; +import com.eactive.eai.common.sessioninfo.SessionHistoryVO; +import com.eactive.eai.common.sessioninfo.SessionInfoVO; +import com.eactive.eai.common.sessioninfo.SessionInfoVO.Status; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; + +public class ChannelSessionFacade { + + public enum LogoutType { + Logout, AutoLogout, ForceLogout, WebSocketTimeout, DateChange, ServerDown + } + + private static ChannelSessionFacade instance; + private Logger logger; + + private SessionManager sessionManager; + private WebSocketSessionManager webSocketSessionManager; + + private SessionStatusManager sessionStatusManager; + + private ExecutorService logoutRunnerExecutor; + + private static final Integer DEFAULT_LOGOUT_MIN_THREAD_COUNT = 10; + + public static ChannelSessionFacade getInstance() { + if (instance == null) { + synchronized (ChannelSessionFacade.class) { + if (instance == null) { + instance = new ChannelSessionFacade(); + instance.logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + instance.sessionManager = SessionManager.getInstance(); + instance.webSocketSessionManager = WebSocketSessionManager.getInstance(); + instance.sessionStatusManager = SessionStatusManager.getInstance(); + + PropManager pManager = PropManager.getInstance(); + if (pManager.isContainProperties(PropertyLoginKeys.LOGIN)){ + + Properties loginProp = pManager.getProperties(PropertyLoginKeys.LOGIN); + + int logoutMaxThreadCount = Integer.parseInt(loginProp.getProperty(PropertyLoginKeys.LOGOUT_MAX_THREAD, "30")); + int logoutMinThreadCount = logoutMaxThreadCount < DEFAULT_LOGOUT_MIN_THREAD_COUNT ? logoutMaxThreadCount : DEFAULT_LOGOUT_MIN_THREAD_COUNT; + int logoutMaxQueueSize = Integer.parseInt(loginProp.getProperty(PropertyLoginKeys.LOGOUT_MAX_QUEUE, "500")); + + LinkedBlockingQueue runnerQueue = new LinkedBlockingQueue(logoutMaxQueueSize); + instance.logoutRunnerExecutor = + new ThreadPoolExecutor( + logoutMinThreadCount, logoutMaxThreadCount, 60000L, TimeUnit.MILLISECONDS, runnerQueue, new CustomizableThreadFactory("LogoutRunner-")); + } + + } + } + } + return instance; + } + + public void login(String userId, String uuid, JSONObject resultJson) { + + logger.debug("login] userId : " + userId, " uuid : " + uuid); + + PropManager pManager = PropManager.getInstance(); + Properties loginProp = pManager.getProperties(PropertyLoginKeys.LOGIN); + + /** PostBank + String KEY_USER_NM = loginProp.getProperty(PropertyLoginKeys.LOGIN_USER_NM); + // 소속국 + String KEY_BRN_CD = loginProp.getProperty(PropertyLoginKeys.LOGIN_BRN_CD); + String KEY_BRN_NM = loginProp.getProperty(PropertyLoginKeys.LOGIN_BRN_NM); + + // 소속청 + String KEY_ROFC_CD = loginProp.getProperty(PropertyLoginKeys.LOGIN_ROFC_CD); + + // terminalId + String TERMINAL_ID = loginProp.getProperty(PropertyLoginKeys.LOGIN_TERMINAL_ID); + **/ + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String serverName = eaiServerManager.getLocalServerName(); +// String brncd = (String) resultJson.get(KEY_BRN_CD); + + SessionVO sessionVo = new SessionVO(); + sessionVo.setUuid(uuid); + sessionVo.setLoginUserId(userId); + sessionVo.setLoginInstId(serverName); +// sessionVo.setBrncd(brncd); +// sessionVo.setTerminalId((String) resultJson.get(TERMINAL_ID)); + + sessionManager.putLogin(userId, sessionVo); + sessionManager.putHttpLogin(uuid, sessionVo); + + sessionManager.putWebSocketTimeout(userId, sessionVo); + + SessionInfoVO sessionInfoVO = new SessionInfoVO(userId); + sessionInfoVO.setSessionId(uuid); + sessionInfoVO.setCreateTime(DatetimeUtil.getCurrentDateTime()); + sessionInfoVO.setSessionStatus(SessionInfoVO.Status.active); +// sessionInfoVO.setUserName((String) resultJson.get(KEY_USER_NM)); +// sessionInfoVO.setRofcCode((String) resultJson.get(KEY_ROFC_CD)); +// sessionInfoVO.setBrnName((String) resultJson.get(KEY_BRN_NM)); +// sessionInfoVO.setBrnCode(brncd); +// sessionInfoVO.setTerminalId((String) resultJson.get(TERMINAL_ID)); + + sessionStatusManager.manageStatus(sessionInfoVO); + } + + public void logout(String userId, String uuid, boolean logoutTransaction, LogoutType logoutType) { + + sessionManager.removeLogin(userId); + sessionManager.removeHTTPLogin(uuid); + + sessionManager.removeWebSocketTimeout(userId); // logout시 timeout 해제 + + logger.info(userId + " 사용자 연결 끊어짐으로 로그아웃 거래 수행."); + + if(logoutTransaction) { + logoutRunnerExecutor.submit(() -> { + try { + sendLogoutTransaction(userId, uuid, logoutType); + } catch (Exception e) { + logger.error("sendLogoutTransaction Runner error. USERID{"+userId+"}", e); + } + }); + } + + sessionStatusManager.manageLoginStatus(userId); + } + + public void logout(String userId, String uuid, boolean logoutTransaction, LogoutType logoutType, CountDownLatch latch) { + + sessionManager.removeLogin(userId); + sessionManager.removeHTTPLogin(uuid); + + sessionManager.removeWebSocketTimeout(userId); // logout시 timeout 해제 + + logger.info(userId + " 사용자 연결 끊어짐으로 로그아웃 거래 수행."); + + if(logoutTransaction) { + logoutRunnerExecutor.submit(() -> { + try { + sendLogoutTransaction(userId, uuid, logoutType); + latch.countDown(); + logger.info("Remove Cache And Logout. key= " + userId + "remain=" + latch.getCount()); + } catch (Exception e) { + logger.error("sendLogoutTransaction Runner error. USERID{"+userId+"}", e); + } + }); + } else { + latch.countDown(); + logger.info("cache has been removed but not a logoutTransaction. key= " + userId + "remain=" + latch.getCount()); + SessionHistoryLogger.getInstance().log( + new SessionHistoryDTO("LOGOUT( "+userId+" )NOT-TRANSACTION", SessionHistoryVO.convertLogoutType_EnumToString(logoutType), "N", uuid, null, false)); + } + + sessionStatusManager.manageLoginStatus(userId); + } + + public void removeFromLoginCache(String userId) { + logger.debug("removeFromLoginCache] userId : " + userId); + sessionManager.removeLogin(userId); + } + + public void removeFromHttpCache(String uuid) { + logger.debug("removeFromHttpCache] uuid : " + uuid); + sessionManager.removeHTTPLogin(uuid); + } + + public void removeFromHttpCacheByUserId(String userId) { + logger.debug("removeFromHttpCacheByUserId] userId : " + userId); + for(String uuid : sessionManager.getHttpLoginCache().getKeys()) { + SessionVO httpLogin = sessionManager.getHttpLogin(uuid); + if(StringUtils.equals(userId, httpLogin.getLoginUserId())) { + sessionManager.removeHTTPLogin(uuid); + } + } + } + + public void onAttachWebSocketSession(String adapterGroupName, WebSocket conn, String userId) { + + logger.debug("onAttachWebSocketSession] adapterGroupName : " + adapterGroupName + " userId : " + userId); + SessionVO sessionVo = SessionManager.getInstance().getLogin(userId); + + webSocketSessionManager.sessionLogin(adapterGroupName, conn, userId); + + // WebSocket connection instance + String serverName = EAIServerManager.getInstance().getLocalServerName(); + sessionVo.setWsInstId(serverName); + sessionVo.setWsAdapterGroupName(adapterGroupName); + + sessionManager.putLogin(userId, sessionVo); // refresh + sessionManager.putHttpLogin(sessionVo.getUuid(), sessionVo); // refresh + + sessionManager.removeWebSocketTimeout(userId); // webSocket 연결 시 timeout 해제 + + SessionInfoVO sessionInfoVO = new SessionInfoVO(userId); + sessionInfoVO.setWsocInstance(serverName); + sessionInfoVO.setWsocRemoteAddr(conn.getRemoteSocketAddress().toString()); + sessionInfoVO.setWsocSessionStatus(Status.active); + + sessionStatusManager.manageStatus(sessionInfoVO); + } + + public void onDetachWebSocketSession(String adapterGroupName, WebSocket conn) { + + logger.debug("onDetachWebSocketSession] adapterGroupName : " + adapterGroupName + " connection : " + conn.getRemoteSocketAddress()); + webSocketSessionManager.onCloseEvent(adapterGroupName, conn); + + } + + public void closeWebSocketByUserId(String userId, boolean logoutTransaction, LogoutType logoutType) { + + logger.debug("closeWebSocketByUserId] userId : " + userId + " logoutTransaction : " + logoutTransaction + " logoutType : " + logoutType.name()); + + for (String adapterGroupName : webSocketSessionManager.getAdapterGroupNames()) { + try { + if (webSocketSessionManager.isContainKeys(adapterGroupName, userId)) { + WebSocket conn = webSocketSessionManager.getSession(adapterGroupName, userId); + if (conn != null) { + if (logger.isDebug()) { + logger.debug("Close WebSocket Connection : " + conn.getRemoteSocketAddress()); + } + webSocketSessionManager.closeSession(adapterGroupName, userId); + } else { + logger.debug("closeWebSocketByUserId] userId ["+userId+"]connection is NULL. closeWebSocket skipped"); + } + } + } catch (Exception e) { + // Logging And Skip + logger.error("closeSession Error : " + e.getMessage(), e); + continue; + } + } + + if(logoutTransaction) { + logoutRunnerExecutor.submit(() -> { + try { + sendLogoutTransaction(userId, null, logoutType); + } catch (Exception e) { + logger.error("sendLogoutTransaction Runner error. USERID{"+userId+"}", e); + } + }); + } + + SessionStatusManager.getInstance().manageWebSocketStatus(userId, Status.inactive); + } + + public void closeWebSocketByAdapterGroupAndUserId(String adapterGroupName, String userId, boolean logoutTransaction, LogoutType logoutType) { + + if(webSocketSessionManager.getAdapterGroupNames().contains(adapterGroupName)) { + try { + WebSocket conn = webSocketSessionManager.getSession(adapterGroupName, userId); + if (conn != null) { + if (logger.isDebug()) { + logger.debug("Close WebSocket Connection : " + conn.getRemoteSocketAddress()); + } + webSocketSessionManager.closeSession(adapterGroupName, userId); + } else { + logger.debug("closeWebSocketByUserId] userId ["+userId+"]connection is NULL. closeWebSocket skipped"); + } + } catch (Exception e) { + // Logging And Skip + logger.error("closeSession Error : " + e.getMessage(), e); + } + } + + if(logoutTransaction) { + logoutRunnerExecutor.submit(() -> { + try { + sendLogoutTransaction(userId, null, logoutType); + } catch (Exception e) { + logger.error("sendLogoutTransaction Runner error. USERID{"+userId+"}", e); + } + }); + } + + SessionStatusManager.getInstance().manageWebSocketStatus(userId, Status.inactive); + } + + public void refreshLoginCache(String userId, SessionVO sessionVO) { + sessionManager.putLogin(userId, sessionVO); + } + + public void refreshHttpLoginCache(String uuid, SessionVO sessionVO) { + sessionManager.putHttpLogin(uuid, sessionVO); + } + + public void onDateChange() { + + logger.debug("DateChange] Start"); + + webSocketSessionManager.closeSessionAll(); + + try { + + removeAllLocalCache(false, LogoutType.DateChange); + + } catch (Exception e) { + logger.error("removeAllLocalCache error.", e); + } + + logger.debug("DateChange] End"); + } + + public void onServerDown() { + + logger.debug("ServerDown] Start"); + + webSocketSessionManager.closeSessionAll(); + + try { + removeAllLocalCache(true, LogoutType.ServerDown); + } catch (Exception e) { + logger.error("removeAllLocalCache error.", e); + } finally { // onServerDown시 Executor와 sessionManager를 close한다. + if (logoutRunnerExecutor != null) + try { + logoutRunnerExecutor.shutdown(); + } catch (Exception e) { + } + if (sessionManager != null) + try { + sessionManager.closeManager(); + } catch (Exception e) { + } + + } + if (logoutRunnerExecutor != null) { + logoutRunnerExecutor.shutdown(); + } + logger.debug("ServerDown] End"); + } + + private void removeAllLocalCache(boolean logoutTransaction, LogoutType logoutType) throws InterruptedException { + + List loginCacheKeys = sessionManager.getLoginCache().getKeys(); + CountDownLatch latch = new CountDownLatch(loginCacheKeys.size()); + + for(String loginKey : loginCacheKeys) { + SessionVO login = sessionManager.getLogin(loginKey); + if(login != null) { + String localServerName = EAIServerManager.getInstance().getLocalServerName(); + String wsInstId = login.getWsInstId(); + String loginInstId = login.getLoginInstId(); + if((wsInstId == null && localServerName.equals(loginInstId))// http login 을 했는데 websocket 로그인이 안된경우 + || localServerName.equals(wsInstId)) { // stop 하는 인스턴스의 websocket을 구별해서 + logout(login.getLoginUserId(), login.getUuid(), logoutTransaction, logoutType, latch); + } else { + latch.countDown(); + logger.info("pass other instance. key= " + loginKey + "remain=" + latch.getCount()); + } + } else { + latch.countDown(); + logger.info("pass sessionVo is null. key= " + loginKey + "remain=" + latch.getCount()); + } + } + + boolean await = latch.await(180, TimeUnit.SECONDS); + + if(await) { + logger.debug("removeAllLocalCache success. remain latch count : " + latch.getCount()); + } else { + logger.warn("latch timeout occurred. remain count : " + latch.getCount()); + } + + } + + private void sendLogoutTransaction(String userId, String uuid, LogoutType logoutType) throws Exception { +// +// String historyDstcd = SessionHistoryVO.convertLogoutType_EnumToString(logoutType); +// +// PropManager pManager = PropManager.getInstance(); +// Properties loginProp = pManager.getProperties("LOGIN"); +// Properties stdMessageProp = pManager.getProperties("STDMESSAGE"); +// EAIServerManager serverManager = EAIServerManager.getInstance(); +//// String envMode = System.getProperty(Keys.EAI_SYSTEMMODE); +// String envMode = serverManager.getSystemEnvTypeConvert(); +// +// String logoutServiceId = loginProp.getProperty("LOGOUT_SERVICE_ID"); +// String logoutInterfaceId = loginProp.getProperty("LOGOUT_INTERFACE_ID"); +// String messageVersion = stdMessageProp.getProperty("VERSION"); +// +// String currentTimeMills = DatetimeUtil.getCurrentTimeMillis(); +// +// String systemCode = "MCC"; +// String guid = UUIDGenerator.getGUID(systemCode); +// STDMessage stdmsg = new STDMessage(); +// stdmsg.setData("systemHeader.VRSN", messageVersion); //버전 +// stdmsg.setData("systemHeader.IPOP_DVSN_CD", "I"); //입력출력구분코드 +// stdmsg.setData("systemHeader.FRST_GUID", guid); //최초GUID +// stdmsg.setData("systemHeader.GUID", guid); //GUID +// //stdmsg.setData("systemHeader.PRGR_SN", "1"); //진행일련번호 +// //stdmsg.setData("systemHeader.TLGR_ENCRT_YN", "N"); //전문암호화여부 +// stdmsg.setData("systemHeader.CHNL_DVSN_CD", "00"); //채널구분 +// stdmsg.setData("systemHeader.IP_VRSN_DVSN_CD", "V4"); //IP버전구분코드 +// stdmsg.setData("systemHeader.ENVR_INFO_DVSN_CD", envMode); //환경정보구분코드 +// stdmsg.setData("systemHeader.FRST_DMND_APLC_SYS_CD", systemCode); //최초요청어플리케이션시스템코드 +// stdmsg.setData("systemHeader.FRST_DMND_INTF_SYS_CD", systemCode); //최초요청인터페이스시스템코드 +// stdmsg.setData("systemHeader.TRSM_SYS_CD", systemCode); //전송시스템코드 +// stdmsg.setData("systemHeader.MCI_INTF_ID", logoutInterfaceId); //MCI_인터페이스ID +// stdmsg.setData("systemHeader.FRST_TLGR_DMND_DT", currentTimeMills); //최초전문요청일시 +// stdmsg.setData("systemHeader.DMND_SYS_CD", systemCode); //요청시스템코드 +// stdmsg.setData("systemHeader.TLGR_DMND_DT", currentTimeMills); //전문요청일시 +// stdmsg.setData("systemHeader.DLNG_PRCS_DVSN_CD", "S"); //거래처리구분코드 +// +// stdmsg.setData("systemHeader.RSPNS_RSLT_DVSN_CD", "N"); //응답결과구분코드 +// +// //stdmsg.setData("systemHeader.MULTILNG_DVSN_CD", "ko"); //다국어구분코드 +// stdmsg.setData("systemHeader.DLNG_ID", logoutServiceId); //거래ID +// //stdmsg.setData("systemHeader.RTRCN_DLNG_YN", "N"); //취소거래여부 +// //stdmsg.setData("systemHeader.TLGR_TYP_DVSN_CD", "G"); //전문 유형코드 +// //stdmsg.setData("systemHeader.LVOL_DAT_PRCS_DVSN_CD", "N"); //대량데이터처리구분코드 +// //stdmsg.setData("systemHeader.LVOL_DAT_PRCS_SN", "0"); //대량데이터처리일련번호 +// //stdmsg.setData("systemHeader.SMLT_DLNG_DVSN_CD", "G"); //시뮬레이션 거래 구분코드 +// //stdmsg.setData("systemHeader.ACNT_MODE_DVSN_CD", "0"); //계정모드 구분코드 +// +// //기존 대비 validation 추가 항목 - start - 20220310 +// stdmsg.setData("systemHeader.FRST_DMND_SYS_IP_VAL", serverManager.getServerIp()); //최초요청시스템IP값 +// stdmsg.setData("systemHeader.FRST_DMND_SYS_MAC_VAL", serverManager.getServerMac()); //최초요청시스템MAC값 +// stdmsg.setData("systemHeader.TMOT_CD", "S"); //타임아웃코드 +// //기존 대비 validation 추가 항목 - end - 20220310 +// +// stdmsg.setData("commonHeader.USERID", userId); //사용자 ID +// +// //공통 헤더 셋팅 못함 +// //청코드 +// //국코드 +// //취급청코드 +// //취급국코드 +// +// String body = "{\"USERID\":\""+userId+"\"}"; +// String sendData = stdmsg.toJSONString(body); +// +// try { +// String eaiSvcCd = logoutInterfaceId + STDMessage.SEND_RECV_CD_SEND + STDMessage.DIRECTION_IN; +// EAIMessage eaiMsg = EAIMessageManager.getInstance().getEAIMessage(eaiSvcCd); +// if(eaiMsg == null){ +// logger.error(eaiSvcCd+" 서비스가 존재하지 않음"); +// return; +// } +// String adapterGroupName = eaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); +// +// AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName); +// +// // 어댑터가 사용중이 아니면 Skip한다. +// if (gvo == null || gvo.isUsedFlag() == false) { +// logger.error(adapterGroupName+" 어댑터가 등록되어있지 않거나 미사용 상태라 로그아웃 미수행"); +// return; +// } +// +// AdapterVO avo = gvo.nextAdapterVO(); +// if (avo == null){ +// logger.error(adapterGroupName+"에 가용한 어댑터가 없어 로그아웃 미수행"); +// return; +// } +// +// AdapterPropManager manager = AdapterPropManager.getInstance(); +// Properties outboundProp = (Properties)manager.getProperties(avo.getPropGroupName()).clone(); +// String charset = outboundProp.getProperty(HttpClientAdapterServiceKey.ENCODE, "utf-8"); +// +// if(logger.isDebug()) +// logger.debug("logout send >> "+sendData); +// +// byte[] reqBytes = sendData.getBytes(charset); +// Properties tempProp = new Properties(); +// tempProp.put(HttpClientAdapterServiceKey.TRAN_CODE, logoutServiceId); +// tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME, adapterGroupName); +// tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_NAME, avo.getName()); +// +// byte[] resBytes = null; +// if ("SOCKETOUT".equals(eaiMsg.getCurrentSvcMsg().getOutbRtnNm()) ){ +// resBytes = SocketSender.callService(adapterGroupName, outboundProp, reqBytes, tempProp); +// }else{ +// resBytes = HttpSender.callService(adapterGroupName, outboundProp, reqBytes, tempProp); +// } +// +// if(logger.isDebug()){ +// String recvData = new String(resBytes, charset); +// logger.debug("logout recv << "+recvData); +// } +// +// ExtMessage resExtMessage = ExtMessageConverter.getExtMessageForStandard(resBytes, gvo.getMessageType()); +// +// SessionHistoryLogger.getInstance().log( +// new SessionHistoryDTO(sendData, historyDstcd, resExtMessage.getResponseType(), uuid, null, true)); +// +// } catch (Exception e) { +// +// SessionHistoryLogger.getInstance().log( +// new SessionHistoryDTO(sendData, historyDstcd, "C", uuid, null, true)); +// +// throw e; +// } + + } + +} diff --git a/src/main/java/com/eactive/eai/common/session/IgniteEvent.java b/src/main/java/com/eactive/eai/common/session/IgniteEvent.java new file mode 100644 index 0000000..8f6b1a5 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/IgniteEvent.java @@ -0,0 +1,334 @@ +package com.eactive.eai.common.session; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.apache.ignite.events.CacheEvent; +import org.apache.ignite.events.EventType; +import org.apache.ignite.internal.binary.BinaryObjectImpl; +import org.apache.ignite.lang.IgnitePredicate; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.session.ChannelSessionFacade.LogoutType; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.worker.Future; +import com.eactive.eai.common.worker.ResponseMap; + +public class IgniteEvent implements IgnitePredicate { + private static final long serialVersionUID = 1L; + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static final ExecutorService executor = new ThreadPoolExecutor(20, 20, 0, TimeUnit.SECONDS, + new LinkedBlockingQueue()); + + @Override + public boolean apply(CacheEvent event) { + IgniteEventDataBundle bundle = new IgniteEventDataBundle(event); + + if (logger.isDebug()) { + logger.debug("localListener] local event<"+ event.name() +"> [name= " + bundle.getCacheName() + ", " + "key=" + bundle.getKey() + ", " + + "oldVal=" + bundle.getOldValue() + ", " + "newVal=" + bundle.getNewValue()); + } + +// if (SessionManager.TOPIC_CAHCE_NAME.equals(bundle.getCacheName()) && EventType.EVT_CACHE_OBJECT_PUT == bundle.getEventType()) { +// removeTopic(bundle); +// } + if (SessionManager.TOPIC_CAHCE_NAME.equals(bundle.getCacheName()) && EventType.EVT_CACHE_OBJECT_PUT == bundle.getEventType()) { + Future future = ResponseMap.getInstance().get(event.key()); + if ( future == null) { + if (logger.isDebug()) { + logger.debug("localListener] event.key["+event.key() + "] skip to Future"); + } + } else { + if (logger.isDebug()) { + logger.debug("localListener] event.key["+event.key() + "] put to Future"); + } + EAIMessage data = (EAIMessage)event.newValue(); + future.getSlot().put(data); + } + } else + if (SessionManager.LOGIN_CAHCE_NAME.equals(bundle.getCacheName()) + && EventType.EVT_CACHE_OBJECT_REMOVED == bundle.getEventType()) { +// if (logger.isWarn()) { +// logger.warn("localListener] loginSession removed event[" + bundle.getKey() + "] start"); +// } +// if (isWebSocketContainer(bundle)) { +// closeWebSocket(bundle); +// } + } else if (SessionManager.LOGIN_CAHCE_NAME.equals(bundle.getCacheName()) + && EventType.EVT_CACHE_OBJECT_EXPIRED == bundle.getEventType()) { +// if (logger.isWarn()) { +// logger.warn("localListener] loginSession expired event[" + bundle.getKey() + "] start"); +// } +// if (isWebSocketContainer_or_httpLoginContainer(bundle)) { +// SessionStatusManager.getInstance().manageLoginStatus(bundle.getKey()); +// closeWebSocketWithLogoutTransaction(bundle); +// } + } else if (SessionManager.HTTP_CAHCE_NAME.equals(bundle.getCacheName()) + && EventType.EVT_CACHE_OBJECT_EXPIRED == bundle.getEventType()) { + if (logger.isWarn()) { + logger.warn("localListener] httpLogin expired event[" + bundle.getKey() + "] start"); + } +// if (isWebSocketContainer_or_httpLoginContainer(bundle)) { +// removeLoginCacheWithLogoutTransaction(bundle, LogoutType.AutoLogout); +// } + manageLoginStatusWithUUID(bundle); + } else if (SessionManager.WEBSOCKER_CAHCE_NAME.equals(bundle.getCacheName()) + && EventType.EVT_CACHE_OBJECT_EXPIRED == bundle.getEventType()) { +// if (logger.isWarn()) { +// logger.warn("localListener] webSocketTimeout expired event[" + bundle.getKey() + "] start"); +// } +// if (isHTTPLoginContainer(bundle)) { +// removeLoginCacheWithLogoutTransaction(bundle, LogoutType.WebSocketTimeout); +// } + } + return true; // Continue listening. + } + + private void removeTopic(IgniteEventDataBundle bundle) { + EAIMessage data = (EAIMessage) bundle.getNewValue(); + if (logger.isDebug()) { + logger.debug("localListener] setEvent[" + bundle.getKey() + "]"); + } + Future future = ResponseMap.getInstance().get(bundle.getKey()); + if (future != null) { + if (logger.isDebug()) { + logger.debug("localListener] setEvent[" + bundle.getKey() + "] put to Future"); + } + future.getSlot().put(data); + SessionManager.getInstance().removeTopic(bundle.getKey()); + } + } + + private boolean isWebSocketContainer(IgniteEventDataBundle bundle) { + if (logger.isWarn()) { + logger.warn("localListener] loginSession setExpireEvent[" + bundle.getKey() + "] start"); + } + + SessionVO sessionVo = bundle.getSessionVO(); + + if (sessionVo == null) { + if (logger.isWarn()) { + logger.warn("localListener] loginSession setExpireEvent SessionVO not found! - " + bundle.getKey()); + } + return false; + } + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String serverName = eaiServerManager.getLocalServerName(); + String webSocketInstanceName = sessionVo.getWsInstId(); + + if (webSocketInstanceName == null) { + return false; + } else if (serverName.equals(webSocketInstanceName)) { + return true; + } + if (logger.isWarn()) { + logger.warn("localListener] loginSession setExpireEvent[" + bundle.getKey() + "] skip.. "); + } + return false; + } + + private boolean isWebSocketContainer_or_httpLoginContainer(IgniteEventDataBundle bundle) { + if (logger.isWarn()) { + logger.warn("localListener] loginSession event[" + bundle.getKey() + "] start"); + } + + SessionVO sessionVo = bundle.getSessionVO(); + + if (sessionVo == null) { + if (logger.isWarn()) { + logger.warn("localListener] loginSession event SessionVO not found! - " + bundle.getKey()); + } + return false; + } + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String serverName = eaiServerManager.getLocalServerName(); + String webSocketInstanceName = sessionVo.getWsInstId(); + + if (webSocketInstanceName == null) { + if (serverName.equals(sessionVo.getLoginInstId())) { + return true; + } + } else if (serverName.equals(webSocketInstanceName)) { + return true; + } + + if (logger.isWarn()) { + logger.warn("localListener] loginSession event[" + bundle.getKey() + "] skip.. "); + } + return false; + } + + private boolean isHTTPLoginContainer(IgniteEventDataBundle bundle) { + SessionVO sessionVo = bundle.getSessionVO(); + if (sessionVo == null) { + if (logger.isWarn()) { + logger.warn("localListener] loginSession setExpireEvent SessionVO not found! - " + bundle.getKey()); + } + return false; + } + + String localServerName = EAIServerManager.getInstance().getLocalServerName(); + String httpLoginInstanceName = sessionVo.getLoginInstId(); + + if (localServerName.equals(httpLoginInstanceName)) { + return true; + } else { + if (logger.isWarn()) { + logger.warn("localListener] loginSession setExpireEvent[" + bundle.getKey() + "] skip.. "); + } + return false; + } + } + + private void closeWebSocket(IgniteEventDataBundle bundle) { + if (logger.isWarn()) { + logger.warn("localListener] loginSession closeWebSocket[" + bundle.getKey() + "] start"); + } + + SessionVO sessionVo = bundle.getSessionVO(); + + String adapterGroupName = sessionVo.getWsAdapterGroupName(); + + try { + executor.execute(() -> { + ChannelSessionFacade.getInstance().closeWebSocketByAdapterGroupAndUserId(adapterGroupName, + bundle.getKey(), false, LogoutType.AutoLogout); + }); + if (logger.isDebug()) { + logger.debug("localListener] loginSession ChannelSessionFacade.closeWebSocketByAdapterGroupAndUserId [" + + bundle.getKey() + "] -" + adapterGroupName); + } + } catch (Exception ex) { + logger.error( + "localListener] loginSession login removed ChannelSessionFacade.closeWebSocketByAdapterGroupAndUserId failed, adapterGroupName [" + + adapterGroupName + "] loginUserId [" + bundle.getKey() + "]", + ex); + } + if (logger.isWarn()) { + logger.warn("localListener] loginSession login removed[" + bundle.getKey() + "] end"); + } + + } + + private void closeWebSocketWithLogoutTransaction(IgniteEventDataBundle bundle) { + if (logger.isWarn()) { + logger.warn( + "localListener] loginSession closeWebSocketWithLogoutTransaction[" + bundle.getKey() + "] start"); + } + SessionVO sessionVo = bundle.getSessionVO(); + + String adapterGroupName = sessionVo.getWsAdapterGroupName(); + + try { + executor.execute(() -> { + ChannelSessionFacade.getInstance().closeWebSocketByAdapterGroupAndUserId(adapterGroupName, + bundle.getKey(), true, LogoutType.AutoLogout); + ChannelSessionFacade.getInstance().removeFromHttpCacheByUserId(bundle.getKey()); + }); + if (logger.isDebug()) { + logger.debug("localListener] loginSession ChannelSessionFacade.closeWebSocketByAdapterGroupAndUserId [" + + bundle.getKey() + "] - adapterGroupName : " + adapterGroupName); + } + } catch (Exception ex) { + logger.error( + "localListener] loginSession login expired ChannelSessionFacade.closeWebSocketByAdapterGroupAndUserId failed, adapterGroupName [" + + adapterGroupName + "] loginUserId [" + bundle.getKey() + "]", + ex); + } + if (logger.isWarn()) { + logger.warn("localListener] loginSession login expired[" + bundle.getKey() + "] end. "); + } + } + + private void removeLoginCacheWithLogoutTransaction(IgniteEventDataBundle bundle, LogoutType logoutType) { + if (logger.isWarn()) { + logger.warn("localListener] loginSession removeLoginCacheWithLogoutTransaction [" + bundle.getKey() + + "] start"); + } + + SessionVO sessionVo = bundle.getSessionVO(); + try { + executor.execute(() -> { + ChannelSessionFacade.getInstance().logout(sessionVo.getLoginUserId(), sessionVo.getUuid(), true, + logoutType); + }); + if (logger.isDebug()) { + logger.debug("localListener] loginSession ChannelSessionFacade.logout [" + bundle.getKey() + "]"); + } + } catch (Exception e) { + logger.error("localListener] loginSession HTTP expired ChannelSessionFacade.logout failed", e); + } + if (logger.isWarn()) { + logger.warn("localListener] loginSession HTTP expired [" + bundle.getKey() + "] end. "); + } + } + + private void manageLoginStatusWithUUID(IgniteEventDataBundle bundle) { + if (logger.isWarn()) { + logger.warn("localListener] loginSession manageLoginStatusWithUUID [" + bundle.getKey() + "] start"); + } + + SessionVO sessionVo = bundle.getSessionVO(); + + SessionStatusManager.getInstance().manageLoginStatusWithUUID(sessionVo); + } + public void shutdown() { + if(executor != null) { + executor.shutdown(); + } + } +} + +class IgniteEventDataBundle { + private String cacheName; + private int eventType; + private String key; + private Object oldValue; + private Object newValue; + private SessionVO sessionVO; + + public IgniteEventDataBundle(CacheEvent event) { + cacheName = event.cacheName(); + eventType = event.type(); + key = event.key(); + oldValue = event.oldValue(); + newValue = event.newValue(); + if (oldValue instanceof SessionVO) { + sessionVO = (SessionVO) oldValue; + } + else if (oldValue instanceof BinaryObjectImpl) { + BinaryObjectImpl b = (BinaryObjectImpl) oldValue; + sessionVO = (SessionVO) b.deserialize(); + } + } + + public String getCacheName() { + return cacheName; + } + + public int getEventType() { + return eventType; + } + + public String getKey() { + return key; + } + + public Object getOldValue() { + return oldValue; + } + + public Object getNewValue() { + return newValue; + } + + public SessionVO getSessionVO() { + return sessionVO; + } +} diff --git a/src/main/java/com/eactive/eai/common/session/LoggingCacheListenerFactory.java b/src/main/java/com/eactive/eai/common/session/LoggingCacheListenerFactory.java new file mode 100644 index 0000000..a25fdb2 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/LoggingCacheListenerFactory.java @@ -0,0 +1,63 @@ +package com.eactive.eai.common.session; + +import com.eactive.eai.common.util.Logger; +import net.sf.ehcache.CacheException; +import net.sf.ehcache.Ehcache; +import net.sf.ehcache.Element; +import net.sf.ehcache.event.CacheEventListener; +import net.sf.ehcache.event.CacheEventListenerFactory; + +import java.util.Properties; + +public class LoggingCacheListenerFactory extends CacheEventListenerFactory { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + @Override + public CacheEventListener createCacheEventListener(Properties properties) { + return new CacheEventListener(){ + public Object clone() throws CloneNotSupportedException{ + logger.debug("LoggingCacheListenerFactory] Clone obtained"); + return super.clone(); + } + + @Override + public void dispose() { + logger.debug("LoggingCacheListenerFactory] disponse the listener"); + } + + @Override + public void notifyElementEvicted(Ehcache ehcache, + Element element) { + logger.debug("LoggingCacheListenerFactory] Element evicted from the cache: "+element.getObjectKey()); + } + + @Override + public void notifyElementExpired(Ehcache ehcache, + Element element) { + logger.debug("LoggingCacheListenerFactory] Element expired in the cache: "+element.getObjectKey()); + } + + @Override + public void notifyElementPut(Ehcache ehcache, Element element) + throws CacheException { + logger.debug("LoggingCacheListenerFactory] Element put into the cache: "+element.getObjectKey()); + } + + @Override + public void notifyElementRemoved(Ehcache ehcache, + Element element) throws CacheException { + logger.debug("LoggingCacheListenerFactory] Element remove from the cache: "+element.getObjectKey()); + } + + @Override + public void notifyElementUpdated(Ehcache ehcache, + Element element) throws CacheException { + logger.debug("LoggingCacheListenerFactory] Element updated in the cache: "+element.getObjectKey()); + } + + @Override + public void notifyRemoveAll(Ehcache ehcache) { + logger.debug("LoggingCacheListenerFactory] Element remove all element from the cache"); + } + }; + } +} diff --git a/src/main/java/com/eactive/eai/common/session/SessionHistoryLogger.java b/src/main/java/com/eactive/eai/common/session/SessionHistoryLogger.java new file mode 100644 index 0000000..5c370e8 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/SessionHistoryLogger.java @@ -0,0 +1,44 @@ +package com.eactive.eai.common.session; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.property.PropertyLoginKeys; +import com.eactive.eai.common.sessioninfo.SessionHistoryDAO; +import com.eactive.eai.common.sessioninfo.SessionHistoryDTO; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component("onlSessionHistoryLogger") +public class SessionHistoryLogger { + + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + + @Autowired + private SessionHistoryDAO sessionHistoryDAO; + +// private static SessionHistoryLogger instance = null; + + private SessionHistoryLogger() { + } + + public static SessionHistoryLogger getInstance() { + return ApplicationContextProvider.getContext().getBean(SessionHistoryLogger.class); + } + + public void log(SessionHistoryDTO sessionHistoryDTO) { + try { + if (!"Y".equals(PropManager.getInstance().getProperty(PropertyLoginKeys.LOGIN, + PropertyLoginKeys.LOGIN_LOGGING_YN, "Y"))) { + logger.debug("LOGIN_LOGGING_YN option is \"N\". SessionHistory not logged."); + return; + } + sessionHistoryDAO.insertSessionHistory(sessionHistoryDTO.toVo()); + } catch (DAOException de) { + logger.error("SessionHistoryLogger] Fail logging session history. sessionHistoryDTO : " + + sessionHistoryDTO.toString(), de); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/session/SessionManager.java b/src/main/java/com/eactive/eai/common/session/SessionManager.java new file mode 100644 index 0000000..fcf007a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/SessionManager.java @@ -0,0 +1,237 @@ +package com.eactive.eai.common.session; + +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.sessioninfo.TerminalInfoVO; +import com.eactive.eai.common.util.Logger; + +/** + * 1. 기능 : + * 1) websocket login session 정보 + * 2) SA 응답거래 매핑 정보 + * 3) Single Socket 접속정보 + * 4) 복원거래에 대한 헤더정보 저장 + * 정보 공유 관리하는 Manager 클래스 + * 2. 처리 개요 : Cache 를 통한 기능처리 + * 3. 주의사항 + * 4. 오류처리 + * deadlock 회피 - 2022.01.05 jun's + * 1. WebSocketSessionManager.sessionClose() : synchronized 범위변경 + * 2. CustomRMICacheEventListener + * - cache 가 다른 cache에 접근할때 Thread 방식으로 변경 + * - websocket 인스턴스에서만 작동하도록변경 + * 인스턴스 stop시 오류 + * 1. WebSocket 인증시에 HttpLogin 의 websocket instance및 어댑터 그룹 갱신 + * 2. sessionManager stop 시 expireThread interrupt 후 logout 처리 및 cacheManager.shutdown + * + * + * @author : + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : + * : + */ +public abstract class SessionManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static final String ADAPTER_MASTER_CAHCE_NAME = "evictMasterCache"; + public static final String ADAPTER_CAHCE_NAME = "adapterSession"; + + public static final String TOPIC_CAHCE_NAME = "topic"; + public static final String TOPIC_MAXSZIE = "topicMaxSize"; + public static final String CACHE_TOPIC_DURATION = "topicDurationSecs"; + + public static final String CACHE_WORKING_DIR= "workingDir"; + public static final String STORE_CAHCE_NAME = "cacheStore"; + public static final String CAHCE_STORE_MAXSIZE = "cacheStoreMaxSize"; + public static final String CACHE_STORE_DURATION = "cacheStoreDurationSecs"; +// public static final String CACHE_MAX_MEM_MB = "cacheMaxMemMb"; + + public static final String LOGIN_CAHCE_NAME = "loginSession"; + public static final String HTTP_CAHCE_NAME = "httpLogin"; + public static final String USERID_CAHCE_NAME = "convertUserIdSession"; + public static final String WEBSOCKER_CAHCE_NAME = "webSocketTimeout"; + public static final String TERMINAL_CAHCE_NAME = "terminalSession"; + + public static final String SESSION_MANAGER_GROUPNAME = "RMIInfo"; + public static final String SESSION_MANAGER_CACHETYPE = "cacheType"; + public static final String SESSION_MANAGER_CACHETYPE_IGNITE = "IGNITE"; + public static final String SESSION_MANAGER_CACHETYPE_EHCACHE = "EHCACHE"; + + public static final String SESSION_MANAGER_EXPIRE_INTERVAL = "expireInterval"; + public static final String SESSION_MANAGER_MULTI_GROUP_IP = "multi_group_ip"; + public static final String SESSION_MANAGER_MULTI_GROUP_PORT = "multi_group_port"; + public static final String SESSION_MANAGER_SESSION_TIMEOUT = "sessionTimeout"; + public static final String SESSION_MANAGER_WEBSOCKET_TIMEOUT = "webSocketTimeout"; + + public static final String SESSION_MANAGER_KUBERNETES_NAMESPACE = "kubernetes_namespace"; + public static final String SESSION_MANAGER_KUBERNETES_SERVICENAME = "kubernetes_servicename"; + public static final String SESSION_MANAGER_KUBERNETES_MASTERURL = "kubernetes_masterurl"; + public static final String SESSION_MANAGER_KUBERNETES_ACCOUNTTOKEN = "kubernetes_accounttoken"; + public static final String SESSION_MANAGER_KUBERNETES_DISCOVERYPORT = "kubernetes_discoveryport"; + + public static final String ENABLE_MULTILOGIN_YN = "enable_multilogin_yn"; + public static final String SESSION_VO_VALIDATION_FROM = "session_vo_validation_from"; + + private static ChannelSessionFacade channelSessionFacade; + private static SessionManager instance; + + private boolean started; + + public static final String MASTER_KEY = "master"; + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + protected SessionManager() { + // nothing to do + } + + public static synchronized SessionManager getInstance() { + if (instance == null) { + PropManager manager = PropManager.getInstance(); + String type = manager.getProperty(SessionManager.SESSION_MANAGER_GROUPNAME, + SessionManager.SESSION_MANAGER_CACHETYPE, SESSION_MANAGER_CACHETYPE_IGNITE); + + if (SESSION_MANAGER_CACHETYPE_IGNITE.equalsIgnoreCase(type)) { + instance = new SessionManagerForIgnite(); + } else if (SESSION_MANAGER_CACHETYPE_EHCACHE.equalsIgnoreCase(type)) { + instance = new SessionManagerForEhcache(); + } else { + instance = new SessionManagerForIgnite(); + } + } + return instance; + } + + public void start() throws LifecycleException { + if (started) { + throw new LifecycleException("RECEAICRT201"); + } + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + int port = 0; + int remoteObjectPort = 0; + + channelSessionFacade = ChannelSessionFacade.getInstance(); + + EAIServerManager mgr = EAIServerManager.getInstance(); + EAIServerVO vo = mgr.getEAIServer(mgr.getLocalServerName()); + // site의 포트 정책에 따라 변경될 수 있음. + // EAIServerVO 에 정의됨. + port = vo.getCacheLocalPort(); + remoteObjectPort = vo.getCacheRemotePort(); + init(port, remoteObjectPort); + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) { + throw new LifecycleException("RECEAICRT203"); + } + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + channelSessionFacade.onServerDown(); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + protected abstract void init(int localPort, int remoteObjectPort); + + // Single Socket 관련 + public abstract SessionVO getConnectionInfo(String key); + + public abstract SessionVO getConnectionStatus(String key); + + public abstract void putConnectionInfo(String key, SessionVO value); + + public abstract void removeConnectionInfo(String key); + + // Topic 관련 + public abstract EAIMessage getTopic(String key); + + public abstract void putTopic(String key, EAIMessage value); + + public abstract void removeTopic(String key); + + // 비동기 거래 복원용 + public abstract String getCacheStore(String key); + + public abstract void putCacheStore(String key, String value, int ttlSecs); + + public abstract void putCacheStore(String key, String value); + + public abstract void removeCacheStore(String key); + + // Login Cache + public abstract SessionVO getLogin(String key); + + public abstract void putLogin(String key, SessionVO value); + + public abstract void removeLogin(String key); + + // HTTP Cache + public abstract SessionVO getHttpLogin(String key); + + public abstract void putHttpLogin(String key, SessionVO value); + + public abstract void removeHTTPLogin(String key); + + // Terminal + public abstract TerminalVO getTerminal(String key); + + public abstract void putTerminal(String key, TerminalVO value, TerminalInfoVO terminalInfoVO); + + public abstract void removeTerminal(String key); + + // CacheInfoVO + public abstract CacheInfoVO getLoginCache(); + + public abstract CacheInfoVO getHttpLoginCache(); + + public abstract CacheInfoVO getEvictMasterCache(); + + public abstract CacheInfoVO getTerminalCache(); + + public abstract CacheInfoVO getConvertUserIdCache(); + + public abstract CacheInfoVO getSocketCache(); + + public abstract String getMasterInstId(); + + // Convert terminalId to userId + public abstract String getConvertUserId(String key); + + // WebSocketTimeout Cache + public abstract void putWebSocketTimeout(String key, SessionVO value); + + public abstract void removeWebSocketTimeout(String key); + + public abstract void closeManager(); + + public abstract String getCacheStatus(); +} diff --git a/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java b/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java new file mode 100644 index 0000000..571afa3 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/SessionManagerForEhcache.java @@ -0,0 +1,924 @@ +package com.eactive.eai.common.session; + +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import com.eactive.eai.common.ehcache.CustomRMICacheReplicatorFactory; +import com.eactive.eai.common.logger.EAIDBLogControl; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.sessioninfo.SessionInfoVO; +import com.eactive.eai.common.sessioninfo.TerminalInfoDAO; +import com.eactive.eai.common.sessioninfo.TerminalInfoVO; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.util.HealthCheckManager; + +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheException; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Element; +import net.sf.ehcache.bootstrap.BootstrapCacheLoader; +import net.sf.ehcache.bootstrap.BootstrapCacheLoaderFactory; +import net.sf.ehcache.config.CacheConfiguration; +import net.sf.ehcache.config.Configuration; +import net.sf.ehcache.config.FactoryConfiguration; +import net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory; +import net.sf.ehcache.distribution.RMICacheReplicatorFactory; +import net.sf.ehcache.event.CacheEventListener; +import net.sf.ehcache.event.CacheEventListenerFactory; + +//use Ehcache +public class SessionManagerForEhcache extends SessionManager { + // evictMaster Instance - single socket 관련 + private static Cache evictMasterCache = null; + // Socket Session cache 정보 + private static Cache cacheSocket = null; + // Topic 용 cache 정보 + private static Cache cacheTopic = null; + // 비동기 거래 복원용 + private static Cache cacheStore = null; + + // WebSocket Login cache 정보 + private static Cache cacheLogin = null; // key = loginId + private static Cache cacheConvertUserId = null; // 단말ID 를 userID로 변경 + // HTTP Polling 에 대한 timeout 관리용 + private static Cache httpLogin = null; // key == uuid + // Terminal용 cache 정보 : ATM, 무인공과금 + private static Cache cacheTerminal = null; + + // HTTP Login 후 WebSocket Connection 일정 시간동안 없을시 Expired되며 자동 로그아웃 발생 + private static Cache cacheWebSocketTimeout = null; + + private static CacheManager manager = null; + + // expireThread run interval secs, default 10 secs + int expireInterval = 10; + Thread expireThread = null; + String localServerName = null; + + private int cacheStoreDurationSecs = 60; + + private final String logPrefix = this.getClass().getName(); + + public void init(int localPort, int remoteObjectPort) { + PropManager pManager = PropManager.getInstance(); + Properties prpty = pManager.getProperties(SessionManager.SESSION_MANAGER_GROUPNAME); + String mltIp = "230.0.0.1"; // 224.0.1.0 ~ 239.255.255.255 + String gPort = "4443"; + int sessionTimeout = 60; + int webSocketTimeout = 60; + + int topicTimeout = 60; + int topicMaxSize = 10000; + + int cacheStoreMaxSize = 10000; + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + localServerName = eaiServerManager.getLocalServerName(); + + if (prpty != null) { + mltIp = prpty.getProperty(SessionManager.SESSION_MANAGER_MULTI_GROUP_IP); + gPort = prpty.getProperty(SessionManager.SESSION_MANAGER_MULTI_GROUP_PORT); + String sTimeout = prpty.getProperty(SessionManager.SESSION_MANAGER_SESSION_TIMEOUT); + if (sTimeout != null) { + try { + sessionTimeout = Integer.parseInt(sTimeout); + if (sessionTimeout < 30) + sessionTimeout = 30; + } catch (NumberFormatException ex) { + sessionTimeout = 60; + } + } + + String sExpireInterval = prpty.getProperty(SessionManager.SESSION_MANAGER_EXPIRE_INTERVAL); + if (sExpireInterval != null) { + try { + expireInterval = Integer.parseInt(sExpireInterval); + if (expireInterval < 10) + expireInterval = 10; + } catch (NumberFormatException ex) { + expireInterval = 10; + } + } + + String wTimeout = prpty.getProperty(SessionManager.SESSION_MANAGER_WEBSOCKET_TIMEOUT); + if (wTimeout != null) { + try { + webSocketTimeout = Integer.parseInt(wTimeout); + } catch (NumberFormatException ex) { + webSocketTimeout = 60; + } + } + + String topicTimeoutSec = prpty.getProperty(SessionManager.CACHE_TOPIC_DURATION); + if (topicTimeoutSec != null) { + try { + topicTimeout = Integer.parseInt(topicTimeoutSec); + if (topicTimeout < 0) + topicTimeout = 60; + } catch (NumberFormatException ex) { + topicTimeout = 60; + } + } + String topicMax = prpty.getProperty(SessionManager.TOPIC_MAXSZIE); + if (topicMax != null) { + try { + topicMaxSize = Integer.parseInt(topicMax); + if (topicMaxSize < 0) + topicMaxSize = 10000; + } catch (NumberFormatException ex) { + topicMaxSize = 10000; + } + } + + String durationSecs = prpty.getProperty(SessionManager.CACHE_STORE_DURATION); + if (durationSecs != null) { + try { + cacheStoreDurationSecs = Integer.parseInt(durationSecs); + if (cacheStoreDurationSecs < 60) + cacheStoreDurationSecs = 60; + } catch (NumberFormatException ex) { + cacheStoreDurationSecs = 60; + } + } + String cacheStoreMax = prpty.getProperty(SessionManager.CAHCE_STORE_MAXSIZE); + if (cacheStoreMax != null) { + try { + cacheStoreMaxSize = Integer.parseInt(cacheStoreMax); + if (cacheStoreMaxSize < 0) + cacheStoreMaxSize = 10000; + } catch (NumberFormatException ex) { + cacheStoreMaxSize = 10000; + } + } + } + + System.setProperty("net.sf.ehcache.skipUpdateCheck", "true"); + String bootstrapAsynchronously = "false"; + + Configuration cf = new Configuration(); + FactoryConfiguration ppFactory = new FactoryConfiguration(); + /** + * manual로 설정할경우 shutdown시 멈춤현상이 발생 auto로 변경됨 + * ppFactory.setClass("com.eactive.eai.common.session.TimeoutRMICacheManagerPeerProviderFactory"); + * ppFactory.setProperties("peerDiscovery=manual,rmiUrls="+rmiUrls); + */ + ppFactory.setClass("net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"); + ppFactory.setProperties( + "peerDiscovery=automatic,multicastGroupAddress=" + mltIp + ", multicastGroupPort=" + gPort); + ppFactory.setPropertySeparator(","); + + cf.addCacheManagerPeerProviderFactory(ppFactory); + + logger.debug(logPrefix + " >>>>INIT<<< Multicast ip = " + mltIp + ", port = " + gPort); + + FactoryConfiguration plFactory = new FactoryConfiguration(); + plFactory.setClass("net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"); + plFactory.setProperties("port=" + localPort + ", remoteObjectPort=" + remoteObjectPort); + + plFactory.setPropertySeparator(","); + cf.addCacheManagerPeerListenerFactory(plFactory); + + CacheConfiguration defaultCacheConfiguration = new CacheConfiguration(); + defaultCacheConfiguration.setName("ChannelSessionCache"); + defaultCacheConfiguration.setMaxElementsInMemory(200000); + cf.addDefaultCache(defaultCacheConfiguration); + + manager = new CacheManager(cf); + + initSocket(manager, sessionTimeout, 10000, bootstrapAsynchronously); + initTopic(manager, topicTimeout, topicMaxSize, bootstrapAsynchronously); + initCacheStore(manager, cacheStoreDurationSecs, cacheStoreMaxSize, bootstrapAsynchronously); + + initLogin(manager, sessionTimeout, 20000, bootstrapAsynchronously); + initHttpLogin(manager, sessionTimeout, 20000, bootstrapAsynchronously); + initEvict(manager, sessionTimeout, 10, bootstrapAsynchronously); + initTerminal(manager, sessionTimeout, 20000, bootstrapAsynchronously); + initConvertUserId(manager, sessionTimeout, 20000, bootstrapAsynchronously); + initWebSocketTimeout(manager, webSocketTimeout, 20000, bootstrapAsynchronously); + + /** + * expire event가 전파가 안되는 문제 발견(2022-01-13) + * 조치는 master에서만 하는게 아니라 전체 인스턴스에서 + * expireThread 실행되도록변경 + */ + expireThread = new Thread() { + @Override + public void run() { + String logPrefix = "SessionManager.expireThread] "; + while (true) { + String master = null; + try { + Thread.sleep(expireInterval * 1000); + if (evictMasterCache.getSize() > 0) { + evictMasterCache.evictExpiredElements(); + Element element = evictMasterCache.get(MASTER_KEY); + if (element == null) { + evictMasterCache.put(new Element(MASTER_KEY, localServerName)); + if (logger.isInfo()) + logger.info(logPrefix + "EVICT-PUT master = " + localServerName); + } else { + master = (String) element.getObjectValue(); + if (localServerName.equals(master)) { + evictMasterCache.put(new Element(MASTER_KEY, localServerName)); + } + } + } else { + evictMasterCache.put(new Element(MASTER_KEY, localServerName)); + if (logger.isInfo()) + logger.info(logPrefix + "INIT-PUT master = " + localServerName); + } + + int cacheSize = cacheLogin.getSize(); + if (cacheSize > 0) { + if (logger.isInfo()) { + logger.info(logPrefix + "cacheLogin.evictExpiredElements = " + cacheSize); + } + cacheLogin.evictExpiredElements(); + } + cacheSize = httpLogin.getSize(); + if (cacheSize > 0) { + if (logger.isInfo()) { + logger.info(logPrefix + "httpLogin.evictExpiredElements = " + cacheSize); + } + httpLogin.evictExpiredElements(); + } + } catch (InterruptedException ie) { + logger.error(logPrefix + "expireThread error - stop", ie); + break; + } catch (Exception e) { + logger.error(logPrefix + "expireThread error - skip", e); + } + } + } + }; + expireThread.setName("SessionManagerForEhcache-expireThread"); + expireThread.start(); + } + + private synchronized void initEvict(CacheManager manager, int sessionTimeout, int maxSize, String bootstrapAsynchronously) { + int masterTimeout = (expireInterval + expireInterval / 2); + if (logger.isDebug()) { + logger.debug(logPrefix + " create evictMasterCache cache - expire=" + masterTimeout + ", maxSize=" + maxSize); + } + evictMasterCache = new Cache(ADAPTER_MASTER_CAHCE_NAME, 10, false, false, masterTimeout, masterTimeout); + + CacheEventListenerFactory celf = new RMICacheReplicatorFactory(); + Properties celfProp = new Properties(); + celfProp.put("replicateAsynchronously", "false"); + celfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener cel = celf.createCacheEventListener(celfProp); + evictMasterCache.getCacheEventNotificationService().registerListener(cel); + + @SuppressWarnings("rawtypes") + BootstrapCacheLoaderFactory bclf = new RMIBootstrapCacheLoaderFactory(); + Properties bclfProp = new Properties(); + bclfProp.put("bootstrapAsynchronously", bootstrapAsynchronously); + bclfProp.put("maximumChunkSizeBytes", "5000000"); + BootstrapCacheLoader bcl = bclf.createBootstrapCacheLoader(bclfProp); + evictMasterCache.setBootstrapCacheLoader(bcl); + + manager.addCache(evictMasterCache); + } + + private synchronized void initSocket(CacheManager manager, int sessionTimeout, int maxSize, String bootstrapAsynchronously) { + if (logger.isDebug()) { + logger.debug(logPrefix + " create AdapterSession cache sessionTimeout="+sessionTimeout +", maxSize=" + maxSize); + } + cacheSocket = new Cache(ADAPTER_CAHCE_NAME, maxSize, false, false, 0, 0); + + CacheEventListenerFactory celf = new RMICacheReplicatorFactory(); + Properties celfProp = new Properties(); + celfProp.put("replicateAsynchronously", "false"); + // celfProp.put("asynchronousReplicationIntervalMillis", "100"); + CacheEventListener cel = celf.createCacheEventListener(celfProp); + cacheSocket.getCacheEventNotificationService().registerListener(cel); + + @SuppressWarnings("rawtypes") + BootstrapCacheLoaderFactory bclf = new RMIBootstrapCacheLoaderFactory(); + Properties bclfProp = new Properties(); + bclfProp.put("bootstrapAsynchronously", bootstrapAsynchronously); + bclfProp.put("maximumChunkSizeBytes", "5000000"); + BootstrapCacheLoader bcl = bclf.createBootstrapCacheLoader(bclfProp); + cacheSocket.setBootstrapCacheLoader(bcl); + + manager.addCache(cacheSocket); + } + + private synchronized void initTopic(CacheManager manager, int sessionTimeout, int maxSize, String bootstrapAsynchronously) { + if (logger.isDebug()) { + logger.debug(logPrefix + " create topic cache sessionTimeout="+sessionTimeout +", maxSize=" + maxSize); + } + cacheTopic = new Cache(TOPIC_CAHCE_NAME, maxSize, false, false, sessionTimeout, sessionTimeout); + + CacheEventListenerFactory celf = new RMICacheReplicatorFactory(); + Properties celfProp = new Properties(); + celfProp.put("replicateAsynchronously", "false"); + celfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener cel = celf.createCacheEventListener(celfProp); + cacheTopic.getCacheEventNotificationService().registerListener(cel); + + // add Custom EventListener + CacheEventListenerFactory ccelf = new CustomRMICacheReplicatorFactory(); + Properties ccelfProp = new Properties(); + ccelfProp.put("replicateAsynchronously", "false"); + ccelfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener ccel = ccelf.createCacheEventListener(ccelfProp); + cacheTopic.getCacheEventNotificationService().registerListener(ccel); + + @SuppressWarnings("rawtypes") + BootstrapCacheLoaderFactory bclf = new RMIBootstrapCacheLoaderFactory(); + Properties bclfProp = new Properties(); + bclfProp.put("bootstrapAsynchronously", bootstrapAsynchronously); + bclfProp.put("maximumChunkSizeBytes", "5000000"); + BootstrapCacheLoader bcl = bclf.createBootstrapCacheLoader(bclfProp); + cacheTopic.setBootstrapCacheLoader(bcl); + + manager.addCache(cacheTopic); + } + + private synchronized void initCacheStore(CacheManager manager, int sessionTimeout, int maxSize, String bootstrapAsynchronously) { + if (logger.isDebug()) { + logger.debug(logPrefix + " create cacheStore cache sessionTimeout="+sessionTimeout +", maxSize=" + maxSize); + } + cacheStore = new Cache(STORE_CAHCE_NAME, maxSize, false, false, sessionTimeout, sessionTimeout); + + CacheEventListenerFactory celf = new RMICacheReplicatorFactory(); + Properties celfProp = new Properties(); + celfProp.put("replicateAsynchronously", "false"); + celfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener cel = celf.createCacheEventListener(celfProp); + cacheStore.getCacheEventNotificationService().registerListener(cel); + + // add Custom EventListener + CacheEventListenerFactory ccelf = new CustomRMICacheReplicatorFactory(); + Properties ccelfProp = new Properties(); + ccelfProp.put("replicateAsynchronously", "false"); + ccelfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener ccel = ccelf.createCacheEventListener(ccelfProp); + cacheStore.getCacheEventNotificationService().registerListener(ccel); + + @SuppressWarnings("rawtypes") + BootstrapCacheLoaderFactory bclf = new RMIBootstrapCacheLoaderFactory(); + Properties bclfProp = new Properties(); + bclfProp.put("bootstrapAsynchronously", bootstrapAsynchronously); + bclfProp.put("maximumChunkSizeBytes", "5000000"); + BootstrapCacheLoader bcl = bclf.createBootstrapCacheLoader(bclfProp); + cacheStore.setBootstrapCacheLoader(bcl); + + manager.addCache(cacheStore); + } + + private synchronized void initLogin(CacheManager manager, int sessionTimeout, int maxSize, String bootstrapAsynchronously) { + if (logger.isDebug()) { + logger.debug(logPrefix + " create loginSession cache sessionTimeout="+sessionTimeout +", maxSize=" + maxSize); + } + + cacheLogin = new Cache(LOGIN_CAHCE_NAME, 20000, false, false, sessionTimeout, sessionTimeout); + + String isAsync = PropManager.getInstance().getProperty("LOGIN", "IS_ASYNC", "false"); + + CacheEventListenerFactory celf = new RMICacheReplicatorFactory(); + Properties celfProp = new Properties(); + celfProp.put("replicateAsynchronously", isAsync); + // 비동기 방식을 사용할때 변경 내역을 다른 노드에 통지하는 주기 default 1000 + celfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener cel = celf.createCacheEventListener(celfProp); + cacheLogin.getCacheEventNotificationService().registerListener(cel); + + // add Custom EventListener + CacheEventListenerFactory ccelf = new CustomRMICacheReplicatorFactory(); + Properties ccelfProp = new Properties(); + ccelfProp.put("replicateAsynchronously", isAsync); + ccelfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener ccel = ccelf.createCacheEventListener(ccelfProp); + cacheLogin.getCacheEventNotificationService().registerListener(ccel); + + @SuppressWarnings("rawtypes") + BootstrapCacheLoaderFactory bclf = new RMIBootstrapCacheLoaderFactory(); + Properties bclfProp = new Properties(); + bclfProp.put("bootstrapAsynchronously", bootstrapAsynchronously); + bclfProp.put("maximumChunkSizeBytes", "5000000"); + BootstrapCacheLoader bcl = bclf.createBootstrapCacheLoader(bclfProp); + + cacheLogin.setBootstrapCacheLoader(bcl); +// cacheLogin.getCacheConfiguration().setDiskExpiryThreadIntervalSeconds(10); + manager.addCache(cacheLogin); + logger.warn(logPrefix + " cacheLogin DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS = " + + Cache.DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS); + } + + private synchronized void initHttpLogin(CacheManager manager, int sessionTimeout, int maxSize, String bootstrapAsynchronously) { + if (logger.isDebug()) { + logger.debug(logPrefix + " create httpLogin cache timeToIdleSeconds=" + sessionTimeout); + } + httpLogin = new Cache(HTTP_CAHCE_NAME, 20000, false, false, sessionTimeout, sessionTimeout); + + String isAsync = PropManager.getInstance().getProperty("LOGIN", "IS_ASYNC", "false"); + + CacheEventListenerFactory celf = new RMICacheReplicatorFactory(); + Properties celfProp = new Properties(); + celfProp.put("replicateAsynchronously", isAsync); + celfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener cel = celf.createCacheEventListener(celfProp); + httpLogin.getCacheEventNotificationService().registerListener(cel); + + // add Custom EventListener + CacheEventListenerFactory ccelf = new CustomRMICacheReplicatorFactory(); + Properties ccelfProp = new Properties(); + ccelfProp.put("replicateAsynchronously", isAsync); + ccelfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener ccel = ccelf.createCacheEventListener(ccelfProp); + httpLogin.getCacheEventNotificationService().registerListener(ccel); + + @SuppressWarnings("rawtypes") + BootstrapCacheLoaderFactory bclf = new RMIBootstrapCacheLoaderFactory(); + Properties bclfProp = new Properties(); + bclfProp.put("bootstrapAsynchronously", bootstrapAsynchronously); + bclfProp.put("maximumChunkSizeBytes", "5000000"); + BootstrapCacheLoader bcl = bclf.createBootstrapCacheLoader(bclfProp); + httpLogin.setBootstrapCacheLoader(bcl); + + manager.addCache(httpLogin); + if (logger.isWarn()) { + logger.warn(logPrefix + " httpLogin DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS = " + + Cache.DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS); + } + } + + + + private synchronized void initConvertUserId(CacheManager manager, int sessionTimeout, int maxSize, String bootstrapAsynchronously) { + if (logger.isDebug()) { + logger.debug(logPrefix + " create convertUserIdSession cache sessionTimeout="+sessionTimeout +", maxSize=" + maxSize); + } + cacheConvertUserId = new Cache(USERID_CAHCE_NAME, maxSize, false, false, sessionTimeout, sessionTimeout); + + String isAsync = PropManager.getInstance().getProperty("LOGIN", "IS_ASYNC", "false"); + + CacheEventListenerFactory celf = new RMICacheReplicatorFactory(); + Properties celfProp = new Properties(); + celfProp.put("replicateAsynchronously", isAsync); + celfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener cel = celf.createCacheEventListener(celfProp); + cacheConvertUserId.getCacheEventNotificationService().registerListener(cel); + + // add Custom EventListener + CacheEventListenerFactory ccelf = new CustomRMICacheReplicatorFactory(); + Properties ccelfProp = new Properties(); + ccelfProp.put("replicateAsynchronously", isAsync); + ccelfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener ccel = ccelf.createCacheEventListener(ccelfProp); + cacheConvertUserId.getCacheEventNotificationService().registerListener(ccel); + + @SuppressWarnings("rawtypes") + BootstrapCacheLoaderFactory bclf = new RMIBootstrapCacheLoaderFactory(); + Properties bclfProp = new Properties(); + bclfProp.put("bootstrapAsynchronously", bootstrapAsynchronously); + bclfProp.put("maximumChunkSizeBytes", "5000000"); + BootstrapCacheLoader bcl = bclf.createBootstrapCacheLoader(bclfProp); + cacheConvertUserId.setBootstrapCacheLoader(bcl); + + manager.addCache(cacheConvertUserId); + if (logger.isWarn()) { + logger.warn(logPrefix + " cacheConvertUserId DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS = " + + Cache.DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS); + } + } + + private synchronized void initWebSocketTimeout(CacheManager manager, int sessionTimeout, int maxSize, String bootstrapAsynchronously) { + if (logger.isDebug()) { + logger.debug(logPrefix + " create webSocketTimeout cache sessionTimeout="+sessionTimeout +", maxSize=" + maxSize); + } + + cacheWebSocketTimeout = new Cache(WEBSOCKER_CAHCE_NAME, maxSize, false, false, sessionTimeout, sessionTimeout); + + String isAsync = PropManager.getInstance().getProperty("LOGIN", "IS_ASYNC", "false"); + + CacheEventListenerFactory celf = new RMICacheReplicatorFactory(); + Properties celfProp = new Properties(); + celfProp.put("replicateAsynchronously", isAsync); + celfProp.put("asynchronousReplicationIntervalMillis", "1000");// 비동기 방식을 사용할때 변경 내역을 다른 노드에 통지하는 주기 default 1000 + CacheEventListener cel = celf.createCacheEventListener(celfProp); + cacheWebSocketTimeout.getCacheEventNotificationService().registerListener(cel); + + // add Custom EventListener + CacheEventListenerFactory ccelf = new CustomRMICacheReplicatorFactory(); + Properties ccelfProp = new Properties(); + ccelfProp.put("replicateAsynchronously", isAsync); + ccelfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener ccel = ccelf.createCacheEventListener(ccelfProp); + cacheWebSocketTimeout.getCacheEventNotificationService().registerListener(ccel); + + @SuppressWarnings("rawtypes") + BootstrapCacheLoaderFactory bclf = new RMIBootstrapCacheLoaderFactory(); + Properties bclfProp = new Properties(); + bclfProp.put("bootstrapAsynchronously", bootstrapAsynchronously); + bclfProp.put("maximumChunkSizeBytes", "5000000"); + BootstrapCacheLoader bcl = bclf.createBootstrapCacheLoader(bclfProp); + cacheWebSocketTimeout.setBootstrapCacheLoader(bcl); + + manager.addCache(cacheWebSocketTimeout); + if (logger.isWarn()) { + logger.warn(logPrefix + " cacheWebSocketTimeout DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS = " + + Cache.DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS); + } + } + + private synchronized void initTerminal(CacheManager manager, int sessionTimeout, int maxSize, String bootstrapAsynchronously) { + if (logger.isDebug()) { + logger.debug(logPrefix + " create TerminalSession cache sessionTimeout="+sessionTimeout +", maxSize=" + maxSize); + } + cacheTerminal = new Cache(TERMINAL_CAHCE_NAME, maxSize, false, false, sessionTimeout, sessionTimeout); + + CacheEventListenerFactory celf = new RMICacheReplicatorFactory(); + Properties celfProp = new Properties(); + celfProp.put("replicateAsynchronously", "false"); + celfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener cel = celf.createCacheEventListener(celfProp); + cacheTerminal.getCacheEventNotificationService().registerListener(cel); + + // add Custom EventListener + CacheEventListenerFactory ccelf = new CustomRMICacheReplicatorFactory(); + Properties ccelfProp = new Properties(); + ccelfProp.put("replicateAsynchronously", "false"); + ccelfProp.put("asynchronousReplicationIntervalMillis", "1000"); + CacheEventListener ccel = ccelf.createCacheEventListener(ccelfProp); + cacheTerminal.getCacheEventNotificationService().registerListener(ccel); + + @SuppressWarnings("rawtypes") + BootstrapCacheLoaderFactory bclf = new RMIBootstrapCacheLoaderFactory(); + Properties bclfProp = new Properties(); + bclfProp.put("bootstrapAsynchronously", bootstrapAsynchronously); + bclfProp.put("maximumChunkSizeBytes", "5000000"); + BootstrapCacheLoader bcl = bclf.createBootstrapCacheLoader(bclfProp); + cacheTerminal.setBootstrapCacheLoader(bcl); + + manager.addCache(cacheTerminal); + if (logger.isWarn()) { + logger.warn(logPrefix + " cacheTerminal DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS = " + + Cache.DEFAULT_EXPIRY_THREAD_INTERVAL_SECONDS); + } + } + + // WebSocket Login 관련 + public SessionVO getLogin(String key) { + try { + Element element = cacheLogin.get(key); + if (element != null) { + return (SessionVO) element.getObjectValue(); + } + return null; + } catch (CacheException e) { + logger.error(e.getMessage(), e); + return null; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } + } + + public void putLogin(String key, SessionVO value) { + putLogin(key, value, null); + } + + public void putLogin(String key, SessionVO value, SessionInfoVO sessionInfoVO) { + if (logger.isWarn()) { + logger.warn("Put session key - " + key + ", Session - " + value.toString()); + } + cacheLogin.put(new Element(key, value)); + // terminal to userID 매핑 생성 + if (value != null && value.getTerminalId() != null) { + cacheConvertUserId.put(new Element(value.getTerminalId(), key)); + } + + if (sessionInfoVO != null) { + SessionStatusManager.getInstance().manageStatus(sessionInfoVO); + } else { + SessionStatusManager.getInstance().manageLoginStatus(key); + } + } + + public void removeLogin(String key) { + SessionVO vo = getLogin(key); + if (logger.isWarn()) { + logger.warn("Remove websocket login session key - " + key); + } + // terminal to userID 매핑 제거 + if (vo != null && vo.getTerminalId() != null) { + cacheConvertUserId.remove(vo.getTerminalId()); + } + cacheLogin.remove(key); + SessionStatusManager.getInstance().manageLoginStatus(key); + } + + // terminalId 2 userId convert + public String getConvertUserId(String key) { + try { + Element element = cacheConvertUserId.get(key); + if (element != null) { + return (String) element.getObjectValue(); + } + return null; + } catch (CacheException e) { + logger.error(e.getMessage(), e); + return null; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } + } + + public SessionVO getHttpLogin(String key) { + try { + Element element = httpLogin.get(key); + if (element != null) { + return (SessionVO) element.getObjectValue(); + } + return null; + } catch (CacheException e) { + logger.error(e.getMessage(), e); + return null; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } + } + + public void putHttpLogin(String key, SessionVO value) { + logger.warn("Put session key - " + key + ", Session - " + value.toString()); + httpLogin.put(new Element(key, value)); + } + + public void removeHTTPLogin(String key) { + logger.warn("Remove http login session key - " + key); + httpLogin.remove(key); + } + + // Single Socket 관련 + public SessionVO getConnectionInfo(String key) { + try { + Element element = cacheSocket.get(key); + if (element != null) { + SessionVO sessionVo = (SessionVO) element.getObjectValue(); + return sessionVo; + } + return null; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } + } + + public SessionVO getConnectionStatus(String adapterGroupName) { + SessionVO sessionVo = null; + try { + sessionVo = getConnectionInfo(adapterGroupName); + if (sessionVo != null) { + String connectedInst = sessionVo.getLoginInstId(); + // 싱글어댑터 Start ---------------------------> +// EAIServerManager eaiServerManager = EAIServerManager.getInstance(); +// String localServerName = eaiServerManager.getLocalServerName(); + + // 로컬서버가 연결시도 중인데 캐시에 자신의 인스턴스가 있을경우 삭제 + if (localServerName.equals(connectedInst)) { + cacheSocket.remove(adapterGroupName); + return null; + } + // 싱글어댑터 End <--------------------------- + + // 케시에서 조회된 인스던스가 살았는지 확인 - 좀비캐시 삭제 + if (logger.isWarn()) { + logger.warn("getConnectionInfo check primary server status - " + connectedInst); + } + boolean isAlive = HealthCheckManager.getInstance().getServerStatus(connectedInst); + + if (!isAlive) { + if (logger.isWarn()) { + logger.warn("getConnectionInfo check primary server is Not Alive, clear cache."); + } + cacheSocket.remove(adapterGroupName); + return null; + } + } + return sessionVo; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } + } + + public void putConnectionInfo(String key, SessionVO value) { + if (logger.isWarn()) { + logger.warn("Put socket session key - " + key + ", Session - " + value.toString()); + } + cacheSocket.put(new Element(key, value)); + } + + public void removeConnectionInfo(String key) { + if (logger.isWarn()) { + logger.warn("Remove socket session key - " + key); + } + cacheSocket.remove(key); + } + + // Topic 관련 + public EAIMessage getTopic(String key) { + try { + Element element = cacheTopic.get(key); + if (element != null) { + return (EAIMessage) element.getObjectValue(); + } + return null; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } + } + + public void putTopic(String key, EAIMessage value) { + if (logger.isWarn()) { + logger.warn("Put Topic response - " + key + ", value - " + value.toString()); + } + cacheTopic.put(new Element(key, value)); + } + + public void removeTopic(String key) { + if (logger.isWarn()) { + logger.warn("Remove Topic response key - " + key); + } + cacheTopic.remove(key); + } + + @Override + public String getCacheStore(String key) { + try { + Element element = cacheStore.get(key); + if (element == null) { + return null; + } else { +// String message = (String)element.getObjectValue(); + CacheStoreObject object = (CacheStoreObject) element.getObjectValue(); + if (object.isExpired()) { + if (logger.isWarn()) + logger.warn("getCacheStore expired key [" + key + "]"); + cacheStore.remove(key); + return null; + } else { + return object.getMessage(); + } + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } + } + + @Override + public void putCacheStore(String key, String value) { + putCacheStore(key, value, cacheStoreDurationSecs); + } + + @Override + public void putCacheStore(String key, String value, int ttlSecs) { + if (logger.isWarn()) { + logger.warn("Put cacheStore key[" + key + "], value - " + value); + } +// cacheStore.put(new Element(key, value)); + CacheStoreObject object = new CacheStoreObject(value, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(ttlSecs)); + cacheStore.put(new Element(key, object)); + } + + @Override + public void removeCacheStore(String key) { + if (logger.isWarn()) { + logger.warn("Remove cacheStore key - " + key); + } + cacheStore.remove(key); + } + + public TerminalVO getTerminal(String key) { + try { + Element element = cacheTerminal.get(key); + if (element != null) { + return (TerminalVO) element.getObjectValue(); + } + return null; + } catch (CacheException e) { + logger.error(e.getMessage(), e); + return null; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } + } + + public void putTerminal(String key, TerminalVO value, TerminalInfoVO terminalInfoVO) { + if (logger.isWarn()) { + logger.warn("Put terminal key - " + key + ", Terminal - " + value.toString()); + } + cacheTerminal.put(new Element(key, value)); + if (terminalInfoVO != null && EAIDBLogControl.isEnable()) { + try { + TerminalInfoDAO dao = ApplicationContextProvider.getContext().getBean(TerminalInfoDAO.class); + dao.upsertTerminalInfo(terminalInfoVO); + } catch (Exception e) { + logger.error(" insert Terminal DB ERROR. - " + e.getMessage(), e); + } + } else if (terminalInfoVO != null) { + logger.error("DB 장애로 업데이트 미수행 - " + value.toString()); + } + } + + public void removeTerminal(String key) { + if (logger.isWarn()) { + logger.warn("Remove socket teminal session key - " + key); + } + cacheTerminal.remove(key); + + if (EAIDBLogControl.isEnable()) { + try { + TerminalInfoDAO dao = ApplicationContextProvider.getContext().getBean(TerminalInfoDAO.class); + TerminalInfoVO terminalInfoVO = new TerminalInfoVO(key); + terminalInfoVO.setSocSessionStatus(TerminalInfoVO.Status.inactive); + dao.upsertTerminalInfo(terminalInfoVO); + } catch (Exception e) { + logger.error(" insert Terminal DB ERROR. - " + key, e); + } + } else { + logger.error(" DB 장애로 인해 업데이트 미수행 - " + key); + } + } + + private CacheInfoVO convert(Cache cache) { + CacheInfoVO v = new CacheInfoVO(); + v.setName(cache.getName()); + v.setSize(cache.getSize()); + v.setTimeToLive(cache.getCacheConfiguration().getTimeToLiveSeconds() * 1000L); + v.setKeys(cache.getKeys()); + return v; + } + + public CacheInfoVO getLoginCache() { + return convert(cacheLogin); + } + + public CacheInfoVO getHttpLoginCache() { + return convert(httpLogin); + } + + public CacheInfoVO getEvictMasterCache() { + return convert(evictMasterCache); + } + + public CacheInfoVO getTerminalCache() { + return convert(cacheTerminal); + } + + public CacheInfoVO getConvertUserIdCache() { + return convert(cacheConvertUserId); + } + + public CacheInfoVO getSocketCache() { + return convert(cacheSocket); + } + + @Override + public void putWebSocketTimeout(String key, SessionVO value) { + cacheWebSocketTimeout.put(new Element(key, value)); + } + + @Override + public void removeWebSocketTimeout(String key) { + cacheWebSocketTimeout.remove(key); + } + + public String getMasterInstId() { + Element element = evictMasterCache.get(MASTER_KEY); + if (element == null) { + return null; + } else { + return (String) element.getObjectValue(); + } + } + + public void closeManager() { + manager.shutdown(); + } + + @Override + public String getCacheStatus() { + StringBuilder sb = new StringBuilder(); + String[] cacheNames = manager.getCacheNames(); + sb.append("").append("\n"); + for(String cacheName : cacheNames) { + Cache cache = manager.getCache(cacheName); + // Get the cache size + long cacheSize = cache.getSize(); + sb.append("\n"); + } + sb.append(""); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java new file mode 100644 index 0000000..fa397a5 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/SessionManagerForIgnite.java @@ -0,0 +1,813 @@ +package com.eactive.eai.common.session; + +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import javax.cache.Cache; +import javax.cache.configuration.Factory; +import javax.cache.expiry.Duration; +import javax.cache.expiry.ModifiedExpiryPolicy; +import javax.cache.expiry.TouchedExpiryPolicy; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.ignite.Ignite; +import org.apache.ignite.IgniteCache; +import org.apache.ignite.IgniteEvents; +import org.apache.ignite.IgniteLogger; +import org.apache.ignite.Ignition; +import org.apache.ignite.cache.CacheAtomicityMode; +import org.apache.ignite.cache.CacheMetrics; +import org.apache.ignite.cache.CacheMode; +import org.apache.ignite.cache.CacheWriteSynchronizationMode; +import org.apache.ignite.cache.eviction.lru.LruEvictionPolicy; +import org.apache.ignite.cache.query.QueryCursor; +import org.apache.ignite.cache.query.ScanQuery; +import org.apache.ignite.configuration.CacheConfiguration; +import org.apache.ignite.configuration.ClientConnectorConfiguration; +import org.apache.ignite.configuration.ConnectorConfiguration; +import org.apache.ignite.configuration.IgniteConfiguration; +import org.apache.ignite.configuration.NearCacheConfiguration; +import org.apache.ignite.events.CacheEvent; +import org.apache.ignite.events.EventType; +import org.apache.ignite.kubernetes.configuration.KubernetesConnectionConfiguration; +import org.apache.ignite.lang.IgnitePredicate; +import org.apache.ignite.logger.slf4j.Slf4jLogger; +import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; +import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; +import org.apache.ignite.spi.discovery.tcp.ipfinder.kubernetes.TcpDiscoveryKubernetesIpFinder; +import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder; +import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; + +import com.eactive.eai.adapter.socket2.common.Env; +import com.eactive.eai.common.logger.EAIDBLogControl; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.sessioninfo.TerminalInfoDAO; +import com.eactive.eai.common.sessioninfo.TerminalInfoVO; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.worker.Future; +import com.eactive.eai.common.worker.ResponseMap; +import com.eactive.eai.util.HealthCheckManager; + +import ch.qos.logback.classic.Level; + +// use Ignite +//------------------------------------------------------------------------------------ +// Important : +// Persistence 를 사용할 경우, 일부서버 다운시 에러가 발생하므로 사용하지 않도록 한다. +// 에러내용 : Failed to execute the cache operation +// (all partition owners have left the grid, partition data has been lost) + //------------------------------------------------------------------------------------ +public class SessionManagerForIgnite extends SessionManager { + // evictMaster Instance - single socket 관련 + private static IgniteCache evictMasterCache = null; + // Socket Session cache 정보 + private static IgniteCache cacheSocket = null; + // SyncAsync Type 거래 매핑을 위한 Topic 용 cache 정보 + private static IgniteCache cacheTopic = null; + // 비동기 거래 복원용 + private static IgniteCache cacheStore = null; + + // webSocket Login cache 정보 + private static IgniteCache cacheLogin = null; // key = loginId + private static IgniteCache cacheConvertUserId = null; // 단말ID 를 userID로 변경 + // HTTP Polling 에 대한 timeout 관리용 + private static IgniteCache httpLogin = null; // key == uuid + // Terminal용 cache 정보 ATM, 무인공과금 + private static IgniteCache cacheTerminal = null; + // HTTP Login 후 WebSocket Connection 일정 시간동안 없을시 Expired되며 자동 로그아웃 발생 + private static IgniteCache cacheWebSocketTimeout = null; + + private static Ignite manager = null; + + String localServerName = null; + + private final String logPrefix = this.getClass().getName(); + + private boolean useMulticast = false; + + private IgnitePredicate localListener = null; + + private int cacheStoreDurationSecs = 60; + + public void init(int communicationPort, int discoveryPort) { + int topicTimeout = 60; + int topicMaxSize = 10000; + int cacheStoreMaxSize = 10000; + + PropManager pManager = PropManager.getInstance(); + Properties prpty = pManager.getProperties(SessionManager.SESSION_MANAGER_GROUPNAME); + // 224.0.1.0 ~ 239.255.255.255 + String mltIp = "230.0.0.1"; + + String workingDirectory = null; + + int iPort = 4443; + int sessionTimeout = 60; + + int webSocketTimeout = 60; + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + localServerName = eaiServerManager.getLocalServerName(); + + EAIServerVO eaiServerVo = eaiServerManager.getEAIServer(localServerName); + + if (prpty != null) { + workingDirectory = prpty.getProperty(SessionManager.CACHE_WORKING_DIR); + + if (logger.isWarn()) { + logger.warn(">> CACHE_WORKING_DIR = " + workingDirectory); + } + + mltIp = prpty.getProperty(SessionManager.SESSION_MANAGER_MULTI_GROUP_IP); + + String sPort = prpty.getProperty(SessionManager.SESSION_MANAGER_MULTI_GROUP_PORT); + if (sPort != null) { + try { + iPort = Integer.parseInt(sPort); + } catch (NumberFormatException ex) { + iPort = 4443; + } + } + + String sTimeout = prpty.getProperty(SessionManager.SESSION_MANAGER_SESSION_TIMEOUT); + if (sTimeout != null) { + try { + sessionTimeout = Integer.parseInt(sTimeout); + if (sessionTimeout < 30) + sessionTimeout = 30; + } catch (NumberFormatException ex) { + sessionTimeout = 60; + } + } + + String wTimeout = prpty.getProperty(SessionManager.SESSION_MANAGER_WEBSOCKET_TIMEOUT); + if (wTimeout != null) { + try { + webSocketTimeout = Integer.parseInt(wTimeout); + } catch (NumberFormatException ex) { + webSocketTimeout = 60; + } + } + + String topicTimeoutSec = prpty.getProperty(SessionManager.CACHE_TOPIC_DURATION); + if (topicTimeoutSec != null) { + try { + topicTimeout = Integer.parseInt(topicTimeoutSec); + if (topicTimeout < 0) + topicTimeout = 60; + } catch (NumberFormatException ex) { + topicTimeout = 60; + } + } + String topicMax = prpty.getProperty(SessionManager.TOPIC_MAXSZIE); + if (topicMax != null) { + try { + topicMaxSize = Integer.parseInt(topicMax); + if (topicMaxSize < 0) + topicMaxSize = 10000; + } catch (NumberFormatException ex) { + topicMaxSize = 10000; + } + } + + String durationSecs = prpty.getProperty(SessionManager.CACHE_STORE_DURATION); + if (durationSecs != null) { + try { + cacheStoreDurationSecs = Integer.parseInt(durationSecs); + if (cacheStoreDurationSecs < 60) + cacheStoreDurationSecs = 60; + } catch (NumberFormatException ex) { + cacheStoreDurationSecs = 60; + } + } + } + String cacheStoreMax = prpty.getProperty(SessionManager.CAHCE_STORE_MAXSIZE); + if (cacheStoreMax != null) { + try { + cacheStoreMaxSize = Integer.parseInt(cacheStoreMax); + if (cacheStoreMaxSize < 0) + cacheStoreMaxSize = 10000; + } catch (NumberFormatException ex) { + cacheStoreMaxSize = 10000; + } + } + + IgniteConfiguration config = new IgniteConfiguration(); + + if(StringUtils.isNotEmpty(workingDirectory)) { + config.setWorkDirectory(workingDirectory); + } + // System.setProperty("net.sf.ehcache.skipUpdateCheck", "true"); + // CommunicationSpi + TcpCommunicationSpi communicationSpi = new TcpCommunicationSpi(); + communicationSpi.setLocalPort(communicationPort); + communicationSpi.setIdleConnectionTimeout(15000); + communicationSpi.setConnectTimeout(1000); + communicationSpi.setReconnectCount(3); + communicationSpi.setMaxConnectTimeout(30000); + communicationSpi.setConnectionsPerNode(2); + communicationSpi.setSlowClientQueueLimit(1000); + + String instanceLocalGroup = pManager.getProperty(SessionManager.SESSION_MANAGER_GROUPNAME, localServerName, + "DEFAULT"); + + // discoverySpi + TcpDiscoverySpi discoverySpi = new TcpDiscoverySpi(); + discoverySpi.setLocalPort(discoveryPort); + discoverySpi.setClientReconnectDisabled(false); + discoverySpi.setSocketTimeout(5000); + discoverySpi.setNetworkTimeout(5000); + discoverySpi.setAckTimeout(5000); + discoverySpi.setMaxAckTimeout(15000); + discoverySpi.setReconnectCount(3); + + if (!Env.isWindows() && BooleanUtils.toBoolean(System.getProperty("scalable", "false"))) { + // https://kubernetes.default.svc.cluster.local:443/api/v1/namespaces/card/endpoints/card-channel-runtime + String nameSpace = pManager.getProperty(SessionManager.SESSION_MANAGER_GROUPNAME, SESSION_MANAGER_KUBERNETES_NAMESPACE, ""); + String serviceName = pManager.getProperty(SessionManager.SESSION_MANAGER_GROUPNAME, SESSION_MANAGER_KUBERNETES_SERVICENAME, ""); + String masterUrl = pManager.getProperty(SessionManager.SESSION_MANAGER_GROUPNAME, SESSION_MANAGER_KUBERNETES_MASTERURL, ""); + String accountToken = pManager.getProperty(SessionManager.SESSION_MANAGER_GROUPNAME, SESSION_MANAGER_KUBERNETES_ACCOUNTTOKEN, ""); + if (logger.isDebug()) { + logger.debug(logPrefix + " >>>>Ignite INIT<<< Multicast nameSpace = " + nameSpace); + } + KubernetesConnectionConfiguration kubernetesCfg = new KubernetesConnectionConfiguration(); + if (StringUtils.isNotBlank(nameSpace)) { + kubernetesCfg.setNamespace(nameSpace.trim()); + } + if (StringUtils.isNotBlank(serviceName)) { + kubernetesCfg.setServiceName(serviceName.trim()); + } + if (StringUtils.isNotBlank(masterUrl)) { + kubernetesCfg.setMasterUrl(masterUrl.trim()); + } + if (StringUtils.isNotBlank(accountToken)) { + kubernetesCfg.setAccountToken(accountToken.trim()); + } + TcpDiscoveryKubernetesIpFinder ipFinder = new TcpDiscoveryKubernetesIpFinder(kubernetesCfg); + if (logger.isWarn()) { + logger.warn(">> Use TcpDiscoveryKubernetesIpFinder setting nameSpace = " + nameSpace + ", serviceName = " + + serviceName + ", masterUrl = " + masterUrl + ", accountToken = " + accountToken); + logger.warn(">> Use TcpDiscoveryKubernetesIpFinder config nameSpace = " + kubernetesCfg.getNamespace() + + ", servcieName = " + kubernetesCfg.getServiceName() + ", masterUrl = " + + kubernetesCfg.getMaster() + ", accountToken = " + kubernetesCfg.getAccountToken()); + } + discoverySpi.setIpFinder(ipFinder); + }else { + // ipFinder + List lists = new ArrayList<>(); + for (String key : EAIServerManager.getInstance().getAllServer().keySet()) { + EAIServerVO vo = EAIServerManager.getInstance().getEAIServer(key); + if ("ALL".equals(key)) + continue; + int discoverPort = vo.getCacheRemotePort(); + String instanceGroup = pManager.getProperty(SessionManager.SESSION_MANAGER_GROUPNAME, key, "DEFAULT"); + + // 서버그룹별 Cluster 분리 + if (instanceLocalGroup.equals(instanceGroup)) { + String server = null; + // 서버정보의 IP가 시스템과 다른 ip로 설정되면 기동이 안되는 문제 + if (localServerName.equals(key) && !"GW".equals(System.getProperty("spring.profiles.active", ""))) { + server = "127.0.0.1:" + discoverPort; + } else { + server = vo.getAddress() + ":" + discoverPort; + } + lists.add(server); + if (logger.isWarn()) { + logger.warn("ipFind key= " + key + ", lists = " + server + ", instanceLocalGroup =" + + instanceLocalGroup); + } + } + } + + if (useMulticast) { + if (logger.isDebug()) { + logger.debug(logPrefix + " >>>>Ignite INIT<<< Multicast ip = " + mltIp); + } + TcpDiscoveryMulticastIpFinder ipFinder = new TcpDiscoveryMulticastIpFinder(); + ipFinder.setMulticastGroup(mltIp); + ipFinder.setMulticastPort(iPort); + if (logger.isWarn()) { + logger.warn(">> Use TcpDiscoveryMulticastIpFinder mltIp = " + mltIp + ", port = " + iPort); + } + discoverySpi.setIpFinder(ipFinder); + } else { + if (lists.isEmpty()) { + if (logger.isWarn()) { + logger.warn(">> Single Server mode skip regist TcpDiscoveryVmIpFinder addresses"); + } + } else { + TcpDiscoveryVmIpFinder ipFinder = new TcpDiscoveryVmIpFinder(); + ipFinder.setAddresses(lists); + discoverySpi.setIpFinder(ipFinder); + if (logger.isWarn()) { + logger.warn(">> Use TcpDiscoveryVmIpFinder addresses = " + lists); + } + } + } + } + String bootstrapAsynchronously = "false"; + + ClientConnectorConfiguration cliConnCfg = new ClientConnectorConfiguration(); + cliConnCfg.setPort(Integer.parseInt(eaiServerVo.getPort()) + 6); + config.setClientConnectorConfiguration(cliConnCfg); + + ConnectorConfiguration connectorCfg = new ConnectorConfiguration(); + connectorCfg.setPort(Integer.parseInt(eaiServerVo.getPort()) + 7); + config.setConnectorConfiguration(connectorCfg); + + String serverGroupName = EAIServerManager.getInstance().getServerMappingType(); + String instName = EAIServerManager.getInstance().getLocalServerName(); + + config.setGridName("elink_" + serverGroupName);// elink_mcc + config.setIgniteInstanceName(instName);// elink_mcc + config.setConsistentId(instName); + + ch.qos.logback.classic.Logger blogger = (ch.qos.logback.classic.Logger) org.slf4j.LoggerFactory + .getLogger("org.apache.ignite"); + blogger.setLevel(Level.INFO); + + IgniteLogger log = new Slf4jLogger((org.slf4j.Logger) blogger); + config.setGridLogger(log); + config.setMetricsLogFrequency(10 * 60 * 1000); // 10분 + + config.setCommunicationSpi(communicationSpi); + config.setDiscoverySpi(discoverySpi); + config.setClientMode(false); + config.setIncludeEventTypes(EventType.EVT_CACHE_OBJECT_PUT, EventType.EVT_CACHE_OBJECT_REMOVED, + EventType.EVT_CACHE_OBJECT_EXPIRED + // , EventType.EVT_NODE_JOINED + // , EventType.EVT_NODE_LEFT + ); + + List caches = new ArrayList<>(); + // Default + caches.add(initCache(config, 0, bootstrapAsynchronously, ADAPTER_MASTER_CAHCE_NAME, 10, false)); + caches.add(initCache(config, 0, bootstrapAsynchronously, ADAPTER_CAHCE_NAME, 10000, false)); + + caches.add(initCache(config, topicTimeout, bootstrapAsynchronously, TOPIC_CAHCE_NAME, topicMaxSize, false)); + + if(logger.isWarn()) { + logger.warn(STORE_CAHCE_NAME +" - cacheStoreDurationSecs = " + cacheStoreDurationSecs); + } + + caches.add(initCache(config, cacheStoreDurationSecs, bootstrapAsynchronously, STORE_CAHCE_NAME, cacheStoreMaxSize, false)); + + // for MCI + caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, LOGIN_CAHCE_NAME, 20000, false)); + caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, HTTP_CAHCE_NAME, 20000, false)); + caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, USERID_CAHCE_NAME, 20000, false)); + caches.add(initCache(config, webSocketTimeout, bootstrapAsynchronously, WEBSOCKER_CAHCE_NAME, 20000, false)); + caches.add(initCache(config, sessionTimeout, bootstrapAsynchronously, TERMINAL_CAHCE_NAME, 20000, false)); + + config.setCacheConfiguration(caches.stream().toArray(CacheConfiguration[]::new)); + + // Start a node. + if (logger.isWarn()) { + logger.warn(">> Ignition.starting..."); + } + manager = Ignition.start(config); + manager.cluster().active(true); + if (logger.isWarn()) { + logger.warn(">> Ignition.started."); + } + + IgniteEvents events = manager.events(); + // Local listener that listens to local events. + localListener = new IgniteEvent(); + + // Subscribe to the cache events that are triggered on the local node. + events.localListen(localListener, + EventType.EVT_CACHE_OBJECT_PUT, + EventType.EVT_CACHE_OBJECT_REMOVED, + EventType.EVT_CACHE_OBJECT_EXPIRED); + + evictMasterCache = manager.cache(ADAPTER_MASTER_CAHCE_NAME); + cacheSocket = manager.cache(ADAPTER_CAHCE_NAME); + cacheTopic = manager.cache(TOPIC_CAHCE_NAME); + cacheStore = manager.cache(STORE_CAHCE_NAME); + + cacheLogin = manager.cache(LOGIN_CAHCE_NAME); + httpLogin = manager.cache(HTTP_CAHCE_NAME); + cacheConvertUserId = manager.cache(USERID_CAHCE_NAME); + cacheWebSocketTimeout = manager.cache(WEBSOCKER_CAHCE_NAME); + cacheTerminal = manager.cache(TERMINAL_CAHCE_NAME); + } + + private CacheConfiguration initCache(IgniteConfiguration config, int expiryDurationSecs, String bootstrapAsynchronously, + String name, int maxsize, boolean useCacheWriteModeAsync) { + if (logger.isDebug()) { + logger.debug(logPrefix + " create " + name + " cache expiryDurationSecs=" + expiryDurationSecs); + } + // near-cache + NearCacheConfiguration nearConfiguration = new NearCacheConfiguration(); + LruEvictionPolicy nearEvictionPolicy = new LruEvictionPolicy(); + nearEvictionPolicy.setMaxSize(maxsize); + nearConfiguration.setNearEvictionPolicy(nearEvictionPolicy); + + CacheConfiguration cacheConfig = new CacheConfiguration(name); + // REPLICATED,PARTITIONED(default) +// cacheConfig.setCacheMode(CacheMode.REPLICATED); + cacheConfig.setCacheMode(CacheMode.PARTITIONED); + + // ATOMIC,TRANSACTIONAL + cacheConfig.setAtomicityMode(CacheAtomicityMode.ATOMIC); + + // Set the number of backups (replicas) for each partition : default(0) + cacheConfig.setBackups(1); + // Enable reading from backups to improve read consistency : default(true) + cacheConfig.setReadFromBackup(true); + + // FULL_SYNC/FULL_ASYNC/PRIMARY_SYNC(default) + if (useCacheWriteModeAsync) { + cacheConfig.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_ASYNC); + } else { +// cacheConfig.setWriteSynchronizationMode(CacheWriteSynchronizationMode.FULL_SYNC); + cacheConfig.setWriteSynchronizationMode(CacheWriteSynchronizationMode.PRIMARY_SYNC); + } + + if(expiryDurationSecs > 0) { + cacheConfig + .setExpiryPolicyFactory(ModifiedExpiryPolicy.factoryOf(new Duration(TimeUnit.SECONDS, expiryDurationSecs))); + } + else { + cacheConfig + .setExpiryPolicyFactory( ModifiedExpiryPolicy.factoryOf(Duration.ETERNAL) ); + } + cacheConfig.setNearConfiguration(nearConfiguration); + return cacheConfig; + } + + // WebSocket Login 관련 + public SessionVO getLogin(String key) { + try { + return cacheLogin.get(key); + } catch (Exception e) { + logger.error("getLogin null key=" + key, e); + return null; + } + } + + public void putLogin(String key, SessionVO value) { + if (logger.isWarn()) { + logger.warn("Put session key - " + key + ", Session - " + value.toString()); + } + cacheLogin.put(key, value); + // terminal to userID 매핑 생성 + if (value != null && value.getTerminalId() != null) { + cacheConvertUserId.put(value.getTerminalId(), key); + } + } + + public void removeLogin(String key) { + SessionVO vo = getLogin(key); + // terminal to userID 매핑 제거 + if (vo != null && vo.getTerminalId() != null) { + cacheConvertUserId.remove(vo.getTerminalId()); + } + cacheLogin.remove(key); + } + + // terminalId 2 userId convert + public String getConvertUserId(String key) { + try { + return cacheConvertUserId.get(key); + } catch (Exception e) { + logger.error("getConvertUserId null key=" + key, e); + return null; + } + } + + public SessionVO getHttpLogin(String key) { + try { + return httpLogin.get(key); + } catch (Exception e) { + logger.error("getHttpLogin null key=" + key, e); + return null; + } + } + + public void putHttpLogin(String key, SessionVO value) { + if (logger.isWarn()) { + logger.warn("Put session key - " + key + ", Session - " + value.toString()); + } + httpLogin.put(key, value); + } + + public void removeHTTPLogin(String key) { + if (logger.isWarn()) { + logger.warn("Remove http login session key - " + key); + } + httpLogin.remove(key); + } + + // Single Socket 관련 + public SessionVO getConnectionInfo(String key) { + try { + return cacheSocket.get(key); + } catch (Exception e) { + logger.error("getConnectionInfo null key=" + key, e); + return null; + } + } + + public SessionVO getConnectionStatus(String adapterGroupName) { + SessionVO sessionVo = null; + try { + sessionVo = getConnectionInfo(adapterGroupName); + + if (sessionVo != null) { + String connectedInst = sessionVo.getLoginInstId(); + // 싱글어댑터 Start ---------------------------> +// EAIServerManager eaiServerManager = EAIServerManager.getInstance(); +// String localServerName = eaiServerManager.getLocalServerName(); + + // 로컬서버가 연결시도 중인데 캐시에 자신의 인스던스가 있을경우 삭제 + if (localServerName.equals(connectedInst)) { + cacheSocket.remove(adapterGroupName); + return null; + } + // 싱글어댑터 End <--------------------------- + + // 케시에서 조회된 인스던스가 살았는지 확인 - 좀비캐시 삭제 + if (logger.isWarn()) { + logger.warn("getConnectionInfo check primary server status - " + connectedInst); + } + boolean isAlive = HealthCheckManager.getInstance().getServerStatus(connectedInst); + + if (!isAlive) { + if (logger.isWarn()) { + logger.warn("getConnectionInfo check primary server is Not Alive, clear cache."); + } + cacheSocket.remove(adapterGroupName); + return null; + } + } + return sessionVo; + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } + } + + public void putConnectionInfo(String key, SessionVO value) { + if (logger.isWarn()) { + logger.warn("Put socket session key - " + key + ", Session - " + value.toString()); + } + try { + cacheSocket.put(key, value); + } catch (Exception e) { + logger.error("Put socket session error key=" + key + " Session - " + value.toString(), e); + } + } + + public void removeConnectionInfo(String key) { + if (logger.isWarn()) { + logger.warn("Remove socket session key - " + key); + } + try { + cacheSocket.remove(key); + } catch (Exception e) { + logger.error("Remove socket session error key=" + key, e); + } + } + + // Topic 관련 + public EAIMessage getTopic(String key) { + try { + return cacheTopic.get(key); + } catch (Exception e) { + logger.error("getTopic null key=" + key, e); + return null; + } + } + + public void putTopic(String key, EAIMessage value) { + if (logger.isWarn()) { + logger.warn("Put Topic response - " + key + ", value - " + value.toString()); + } + + // local event인 경우 ignite skip + Future future = ResponseMap.getInstance().get(key); + if(future != null) { + if (logger.isDebug()) { + logger.debug("PutTopic] local [" + key + "] put to Future"); + } + future.getSlot().put(value); + return; + } + // remote Event + if (logger.isDebug()) { + logger.debug("PutTopic] remote [" + key + "] put to Future"); + } + int retry = 3; + while(!cacheTopic.putIfAbsent(key, value) && retry > 0) { + retry--; + try { + Thread.sleep(300); + } catch (InterruptedException e) { + if(logger.isDebug()) { + logger.debug("PutTopic] sleep Fail"); + } + } + if (logger.isDebug()) { + logger.debug("PutTopic] remote retry [" + key + "] put to Future"); + } + }; + removeTopic(key); + } + + public void removeTopic(String key) { + if (logger.isWarn()) { + logger.warn("Remove Topic response key - " + key); + } + cacheTopic.remove(key); + } + + // cacheStore 관련 + public String getCacheStore(String key) { + try { + // Important : get 힌 후 바로 remove 하므로, 객체를 생성해서 return 해야 함. +// String message = cacheStore.get(key); + CacheStoreObject object = cacheStore.get(key); + if (object.isExpired()) { + if (logger.isWarn()) + logger.warn("getCacheStore expired key [" + key + "]"); + cacheStore.remove(key); + return null; + } else { + return object.getMessage(); + } + } catch (Exception e) { + logger.error("getTopic null key [" + key + "]", e); + return null; + } + } + @Override + public void putCacheStore(String key, String value, int ttlSecs) { + if (logger.isWarn()) { + logger.warn("Put CacheStore key [" + key + "], value - " + value); + } +// cacheStore.put(key, value); + CacheStoreObject object = new CacheStoreObject(value, System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(ttlSecs)); + cacheStore.put(key, object); + } + + @Override + public void putCacheStore(String key, String value) { + putCacheStore(key, value, cacheStoreDurationSecs); + } + + public void removeCacheStore(String key) { + if (logger.isWarn()) { + logger.warn("Remove CacheStore key [" + key + "]"); + } + cacheStore.remove(key); + } + + // Terminal + public TerminalVO getTerminal(String key) { + try { + return cacheTerminal.get(key); + } catch (Exception e) { + logger.error("getTerminal null key=" + key, e); + return null; + } + } + + public void putTerminal(String key, TerminalVO value, TerminalInfoVO terminalInfoVO) { + if (logger.isWarn()) { + logger.warn("Put terminal key - " + key + ", Terminal - " + value.toString()); + } + cacheTerminal.put(key, value); + if (terminalInfoVO != null && EAIDBLogControl.isEnable()) { + try { + TerminalInfoDAO dao = ApplicationContextProvider.getContext().getBean(TerminalInfoDAO.class); + dao.upsertTerminalInfo(terminalInfoVO); + } catch (Exception e) { + logger.error(" insert Terminal DB ERROR. - " + e.getMessage(), e); + } + } else if (terminalInfoVO != null) { + logger.error("DB 장애로 업데이트 미수행 - " + value.toString()); + } + } + + public void removeTerminal(String key) { + if (logger.isWarn()) { + logger.warn("Remove socket teminal session key - " + key); + } + try { + // 서버다운시 org.apache.ignite.internal.processors.cache.CacheStoppedException 때문에 + // try catch 추가 : jun's 20220826 + cacheTerminal.remove(key); + + } catch (Exception e) { + logger.error(" cacheTerminal remove error. - " + key, e); + } + if (EAIDBLogControl.isEnable()) { + try { + TerminalInfoDAO dao = ApplicationContextProvider.getContext().getBean(TerminalInfoDAO.class); + TerminalInfoVO terminalInfoVO = new TerminalInfoVO(key); + terminalInfoVO.setSocSessionStatus(TerminalInfoVO.Status.inactive); + dao.upsertTerminalInfo(terminalInfoVO); + } catch (Exception e) { + logger.error(" insert Terminal DB ERROR. - " + key, e); + } + } else { + logger.error(" DB 장애로 인해 업데이트 미수행 - " + key); + } + } + + @SuppressWarnings("rawtypes") + private CacheInfoVO convert(IgniteCache cache) { + CacheInfoVO v = new CacheInfoVO(); + long timeToLive = 0; + CacheConfiguration cf = (CacheConfiguration) cache.getConfiguration(CacheConfiguration.class); + Factory factory = cf.getExpiryPolicyFactory(); + Object obj = factory.create(); + if (obj instanceof TouchedExpiryPolicy) { + TouchedExpiryPolicy cep = (TouchedExpiryPolicy) obj; + Duration dur = cep.getExpiryForCreation(); + timeToLive = dur.getTimeUnit().toMillis(dur.getDurationAmount()); + } + v.setTimeToLive(timeToLive); + v.setName(cache.getName()); + + List keys = new ArrayList<>(); + QueryCursor> cursor = cache.query(new ScanQuery<>()); + cursor.forEach(entry -> keys.add(entry.getKey())); + v.setKeys(keys); + v.setSize(keys.size()); + return v; + } + + public CacheInfoVO getLoginCache() { + return convert(cacheLogin); + } + + public CacheInfoVO getHttpLoginCache() { + return convert(httpLogin); + } + + public CacheInfoVO getEvictMasterCache() { + return convert(evictMasterCache); + } + + public CacheInfoVO getTerminalCache() { + return convert(cacheTerminal); + } + + public CacheInfoVO getConvertUserIdCache() { + return convert(cacheConvertUserId); + } + + public CacheInfoVO getSocketCache() { + return convert(cacheSocket); + } + + @Override + public void putWebSocketTimeout(String key, SessionVO value) { + cacheWebSocketTimeout.put(key, value); + } + + @Override + public void removeWebSocketTimeout(String key) { + cacheWebSocketTimeout.remove(key); + } + + public String getMasterInstId() { + try { + return evictMasterCache.get(MASTER_KEY); + } catch (Exception e) { + logger.error("getMasterInstId null key=" + MASTER_KEY, e); + return null; + } + } + + public void closeManager() { + if(localListener != null) { + ((IgniteEvent) localListener).shutdown(); + } + manager.close(); + } + + @Override + public String getCacheStatus() { + StringBuilder sb = new StringBuilder(); + Iterable cacheNames = manager.cacheNames(); + sb.append("").append("\n"); + for (String cacheName : cacheNames) { + IgniteCache cache = manager.cache(cacheName); + CacheMetrics metrics = cache.metrics(); + long cacheSize = metrics.getSize(); + sb.append("\n"); + } + sb.append(""); + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/common/session/SessionStatusManager.java b/src/main/java/com/eactive/eai/common/session/SessionStatusManager.java new file mode 100644 index 0000000..c018700 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/SessionStatusManager.java @@ -0,0 +1,79 @@ +package com.eactive.eai.common.session; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.logger.EAIDBLogControl; +import com.eactive.eai.common.sessioninfo.SessionInfoDAO; +import com.eactive.eai.common.sessioninfo.SessionInfoVO; +import com.eactive.eai.common.sessioninfo.SessionInfoVO.Status; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class SessionStatusManager { + + private static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + +// private static SessionStatusManager instance; + + @Autowired + SessionInfoDAO sessionInfoDAO; + + private SessionStatusManager() { + } + + public static SessionStatusManager getInstance() { + return ApplicationContextProvider.getContext().getBean(SessionStatusManager.class); + } + + public void manageStatus(SessionInfoVO sessionInfoVO) { + + if (EAIDBLogControl.isEnable()) { + try { + sessionInfoDAO.upsertSessionInfo(sessionInfoVO); + } catch (Exception e) { + if (logger.isError()) { + logger.error("Insert Session DB ERROR. - " + sessionInfoVO.getUserId(), e); + } + } + } else { + if (logger.isError()) { + logger.error("EAIDBLogControl is not enable - " + sessionInfoVO.getUserId()); + } + } + + } + + public void manageLoginStatus(String userId) { + SessionVO login = SessionManager.getInstance().getLogin(userId); + Status status = login == null ? SessionInfoVO.Status.inactive : SessionInfoVO.Status.active; + SessionInfoVO sessionInfoVO = new SessionInfoVO(userId); + sessionInfoVO.setSessionStatus(status); + + /** upsert **/ + manageStatus(sessionInfoVO); + } + + public void manageLoginStatusWithUUID(SessionVO session) { + + SessionVO login = SessionManager.getInstance().getHttpLogin(session.getUuid()); + Status status = login == null ? SessionInfoVO.Status.inactive : SessionInfoVO.Status.active; + String userId = login == null ? session.getLoginUserId() : login.getLoginUserId(); + SessionInfoVO sessionInfoVO = new SessionInfoVO(session.getLoginUserId()); + sessionInfoVO.setSessionId(session.getUuid()); + sessionInfoVO.setUserId(userId); + sessionInfoVO.setSessionStatus(status); + + /** upsert **/ + manageStatus(sessionInfoVO); + } + public void manageWebSocketStatus(String userId, Status status) { + SessionInfoVO sessionInfoVO = new SessionInfoVO(userId); + sessionInfoVO.setWsocSessionStatus(status); + + /** upsert **/ + manageStatus(sessionInfoVO); + } + +} diff --git a/src/main/java/com/eactive/eai/common/session/SessionVO.java b/src/main/java/com/eactive/eai/common/session/SessionVO.java new file mode 100644 index 0000000..8646b97 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/SessionVO.java @@ -0,0 +1,133 @@ +package com.eactive.eai.common.session; + +import java.io.Serializable; + +/** +* 1. 기능 : SessionVO 객체 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class SessionVO implements Serializable +{ + + /** + * + */ + private static final long serialVersionUID = 8397247737238565420L; + + private String loginUserId; + private String loginInstId; + private String wsInstId; + private String wsAdapterGroupName; + private String uuid; + private String primaryInst; // 싱글어댑터 + + //국코드 추가 + private String brncd; +// private String sessionAES; +// private String httpSessionId; + private String terminalId; + + public SessionVO() { + super(); + + } + + public SessionVO(String loginUserId, String loginInstId, String uuid) { + super(); + this.loginUserId = loginUserId; + this.loginInstId = loginInstId; + this.uuid = uuid; + } + + public String getLoginUserId() { + return loginUserId; + } + public void setLoginUserId(String loginUserId) { + this.loginUserId = loginUserId; + } + public String getLoginInstId() { + return loginInstId; + } + public void setLoginInstId(String loginInstId) { + this.loginInstId = loginInstId; + } + public String getUuid() { + return uuid; + } + public void setUuid(String uuid) { + this.uuid = uuid; + } + +// public String getSessionAES() { +// return sessionAES; +// } +// +// public void setSessionAES(String sessionAES) { +// this.sessionAES = sessionAES; +// } +// +// +// public String getHttpSessionId() { +// return httpSessionId; +// } +// +// public void setHttpSessionId(String httpSessionId) { +// this.httpSessionId = httpSessionId; +// } + + public String getWsInstId() { + return wsInstId; + } + + public void setWsInstId(String wsInstId) { + this.wsInstId = wsInstId; + } + + public String getWsAdapterGroupName() { + return wsAdapterGroupName; + } + + public void setWsAdapterGroupName(String wsAdapterGroupName) { + this.wsAdapterGroupName = wsAdapterGroupName; + } + + public String getBrncd() { + return brncd; + } + + public void setBrncd(String brncd) { + this.brncd = brncd; + } + + public String getTerminalId() { + return terminalId; + } + + public void setTerminalId(String terminalId) { + this.terminalId = terminalId; + } + + public String getPrimaryInst() { + return primaryInst; + } + + public void setPrimaryInst(String primaryInst) { + this.primaryInst = primaryInst; + } + + @Override + public String toString() { + return "SessionVO [loginUserId=" + loginUserId + ", loginInstId=" + loginInstId + ", wsInstId=" + wsInstId + + ", wsAdapterGroupName=" + wsAdapterGroupName + ", uuid=" + uuid + ", brncd=" + brncd + ", terminalId=" + + terminalId + ", primaryInst="+ primaryInst +"]"; + } + + +} diff --git a/src/main/java/com/eactive/eai/common/session/TcpSessionManager.java b/src/main/java/com/eactive/eai/common/session/TcpSessionManager.java new file mode 100644 index 0000000..140588d --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/TcpSessionManager.java @@ -0,0 +1,250 @@ +package com.eactive.eai.common.session; + +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.mina.common.IoSession; + +import com.eactive.eai.adapter.socket2.common.ExpiringMap; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.sessioninfo.SessionInfoVO; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; + +/** +* 1. 기능 : websocket session 정보를 관리하는 Manager 클래스 +* 2. 처리 개요 : ehcache 로 session 을 공유함. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class TcpSessionManager implements Lifecycle +{ + /** + * Default Logger + */ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * SessionManager Single Instance + */ + private static TcpSessionManager instance; + /** + * cache 정보 + */ + private static ExpiringMap uidCache ; // + + private static ExpiringMap chnCache ; // + + + /** + * 기동 여부 + */ + private boolean started; + + /** + * LifeccyleSupport object + */ + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : 라우팅 Rule 정보를 저장하기 위한 HashMap을 초기화한다. + * 3. 주의사항 + * + **/ + private TcpSessionManager() { + //init(); + } + + /** + * 1. 기능 : SessionManager Singleton Object를 반환하는 getter method + * 2. 처리 개요 : SessionManager Singleton Object를 반환한다. + * 3. 주의사항 + * + * @return SessionManager Singleton object + **/ + public static TcpSessionManager getInstance() { + if(instance == null) { + synchronized(TcpSessionManager.class) { + if(instance==null) { + instance = new TcpSessionManager(); + } + } + } + return instance; + } + + /** + * 1. 기능 : Lifecycle의 start 메서드로 RoutingMangaer를 초기화하는 메서드 + * 2. 처리 개요 : RoutingDAO를 이용해 추출 Rule 정보 모두를 가져와 초기화한다. + * 3. 주의사항 + * + * @exception LifecycleException 이미 시작되었거나(RECEAICBM201), RoutingDAO를 통해 Rule 정보를 가져오다 DAOExcepiton이 발생될 경우(RECEAICRT201) + * + **/ + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICRT201"); + + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + + this.uidCache = new ExpiringMap(86400,600); + this.chnCache = new ExpiringMap(86400,600); +// this.uuidCache = new ExpiringMap(60,1); +// this.chnCache = new ExpiringMap(60,1); + + started = true; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + /** + * 1. 기능 : Lifecycle의 stop 메서드로 SessionManager를 종료하는 메서드 + * 2. 처리 개요 : 멤버에 캐싱한 라우팅 Rule 정보를 clear한다. + * 3. 주의사항 + * + * @exception LifecycleException 이미 종료된 경우 발생(RECEAICRT203) + **/ + public void stop() throws LifecycleException { + // Validate and update our current component state + if (!started) + throw new LifecycleException("RECEAICRT203"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + + + + started = false; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + /** + * 1. 기능 : LifecycleListener를 등록하는 메서드 + * 2. 처리 개요 : LifecycleListener를 등록한다. + * 3. 주의사항 + * + * @param listener LifecycleEvent를 수신한 LifecycleListener + **/ + public void addLifecycleListener(LifecycleListener listener) + { + lifecycle.addLifecycleListener(listener); + } + + /** + * 1. 기능 : 등록된 LifecycleListener 리스트를 반환하는 메서드 + * 2. 처리 개요 : 등록된 LifecycleListener 리스트를 반환하다. + * 3. 주의사항 + * + * @return 등록된 LifecycleListener 리스트 + **/ + public LifecycleListener[] findLifecycleListeners() + { + return lifecycle.findLifecycleListeners(); + } + + /** + * 1. 기능 : 등록된 LifecycleListener를 삭제하는 메서드 + * 2. 처리 개요 : 파라미터의 LifecycleListener를 삭제한다. + * 3. 주의사항 + * + * @param listener 삭제할 LifecycleListener + **/ + public void removeLifecycleListener(LifecycleListener listener) + { + lifecycle.removeLifecycleListener(listener); + } + + /** + * 1. 기능 : SessionManager의 초기화 여부를 반환하는 getter 메서드 + * 2. 처리 개요 : SessionManager의 초기화 여부를 반환한다. + * 3. 주의사항 + * + * @return 초기화 여부 + **/ + public boolean isStarted() { + return this.started; + } + + public ExpiringMap getSessionList(){ + return chnCache; + } + public synchronized void sessionOpen(IoSession session){ + logger.warn("TcpSessionManager ] session Opened - [ " + session + "]"); + } + +// public synchronized void sessionLogin(String uuid, String usrid, IoSession session){ +// if(usrid == null && session == null){ +// return; +// } +// this.uidCache.put(session.toString(), usrid); +// this.chnCache.put(usrid, session); +// +// logger.warn("TcpSessionManager ] session saved " + uuid + "["+usrid+"] : " + session); +// +// +// EAIServerManager eaiServerManager = EAIServerManager.getInstance(); +// String serverName = eaiServerManager.getLocalServerName(); +// +// SessionVO sessionVo = new SessionVO(); +// sessionVo.setUuid(uuid); +// sessionVo.setLoginUserId(usrid); +// sessionVo.setLoginInstId(serverName); +// +// SessionInfoVO sessionInfoVO = new SessionInfoVO(usrid); +// sessionInfoVO.setSessionId(uuid); +// sessionInfoVO.setCreateTime(DatetimeUtil.getCurrentDateTime()); +// +// SessionManager.getInstance().putLogin(session.toString(), sessionVo, sessionInfoVO); +// +// } + + + public synchronized void sessionClose(IoSession session){ + try{ + String sessionId = session.toString(); + String userId = null; + try{ + userId = this.uidCache.get(sessionId); + this.uidCache.remove(sessionId); + }catch(NullPointerException e){ + logger.error("TcpSessionManager ] tried to remove Cache , but UIDCache value of ["+sessionId+"] is null "); + } + try{ + if(userId != null) this.chnCache.remove(userId); + }catch(NullPointerException e){ + logger.error("TcpSessionManager ] tried to remove Cache , but ChnCache value of ["+sessionId+"] is null "); + } + try{ + if(userId != null) { + ChannelSessionFacade.getInstance().removeFromLoginCache(userId); + } + }catch(NullPointerException e){ + logger.error("TcpSessionManager ] tried to remove Cache , but ehCache value of ["+sessionId+"] is null "); + } + }catch(Exception e){ + logger.error("TcpSessionManager ] Error occured in removing Session Info - " + session); + } + } + public synchronized String getUid(String sessionId){ + String uid = uidCache.get(sessionId); + return uid; + } + public synchronized IoSession getSession(String sessionId){ + IoSession session = chnCache.get(sessionId); + return session; + } +} diff --git a/src/main/java/com/eactive/eai/common/session/TerminalVO.java b/src/main/java/com/eactive/eai/common/session/TerminalVO.java new file mode 100644 index 0000000..7dc66d5 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/TerminalVO.java @@ -0,0 +1,87 @@ +package com.eactive.eai.common.session; + +import java.io.Serializable; + +/** + * 1. 기능 : SessionVO 객체 2. 처리 개요 : 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : : + */ +public class TerminalVO implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 1; + + private String terminalNo; + private String rofcCd;// 청코드 + private String brncd;// 국코드 + private String brnName;// 국명 + private boolean isOpenTran;// 개국거래여부 + private boolean isOpen; //개국여부 + + public TerminalVO() { + super(); + } + + public String getTerminalNo() { + return terminalNo; + } + + public void setTerminalNo(String terminalNo) { + this.terminalNo = terminalNo; + } + + public String getRofcCd() { + return rofcCd; + } + + public void setRofcCd(String rofcCd) { + this.rofcCd = rofcCd; + } + + public String getBrncd() { + return brncd; + } + + public void setBrncd(String brncd) { + this.brncd = brncd; + } + + public String getBrnName() { + return brnName; + } + + public void setBrnName(String brnName) { + this.brnName = brnName; + } + + public boolean isOpenTran() { + return isOpenTran; + } + + public void setOpenTran(boolean isOpenTran) { + this.isOpenTran = isOpenTran; + } + + public boolean isOpen() { + return isOpen; + } + + public void setOpen(boolean isOpen) { + this.isOpen = isOpen; + } + + @Override + public String toString() { + return "TerminalVO [terminalNo=" + terminalNo + ", rofcCd=" + rofcCd + ", brncd=" + brncd + ", brnName=" + + brnName + ", isOpenTran=" + isOpenTran + ", isOpen=" + isOpen + "]"; + } + + + +} diff --git a/src/main/java/com/eactive/eai/common/session/TimeoutManualRMICacheManagerPeerProvider.java b/src/main/java/com/eactive/eai/common/session/TimeoutManualRMICacheManagerPeerProvider.java new file mode 100644 index 0000000..e193536 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/TimeoutManualRMICacheManagerPeerProvider.java @@ -0,0 +1,144 @@ +/** + * Copyright Terracotta, Inc. + * + * 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 + * + * http://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. + */ + + +package com.eactive.eai.common.session; + +import net.sf.ehcache.CacheException; +import net.sf.ehcache.Ehcache; +import net.sf.ehcache.distribution.CachePeer; +import net.sf.ehcache.distribution.RMICacheManagerPeerProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.MalformedURLException; +import java.rmi.NotBoundException; +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; + +/** + * A provider of Peer RMI addresses based off manual configuration. + *

+ * Because there is no monitoring of whether a peer is actually there, the list of peers is dynamically + * looked up and verified each time a lookup request is made. + *

+ * + * @author Greg Luck + * @version $Id: ManualRMICacheManagerPeerProvider.java 5594 2012-05-07 16:04:31Z cdennis $ + */ +public final class TimeoutManualRMICacheManagerPeerProvider extends RMICacheManagerPeerProvider { + + private static final Logger LOG = LoggerFactory.getLogger(TimeoutManualRMICacheManagerPeerProvider.class.getName()); + + /** + * Empty constructor. + */ + public TimeoutManualRMICacheManagerPeerProvider() { + super(); + } + + /** + * {@inheritDoc} + */ + public final void init() { + //nothing to do here + } + + /** + * Time for a cluster to form. This varies considerably, depending on the implementation. + * + * @return the time in ms, for a cluster to form + */ + public long getTimeForClusterToForm() { + return 0; + } + + /** + * Register a new peer. + * + * @param rmiUrl + */ + public final synchronized void registerPeer(String rmiUrl) { + peerUrls.put(rmiUrl, new Date()); + } + + + /** + * @return a list of {@link CachePeer} peers, excluding the local peer. + */ + public final synchronized List listRemoteCachePeers(Ehcache cache) throws CacheException { + List remoteCachePeers = new ArrayList(); + List staleList = new ArrayList(); + for (Iterator iterator = peerUrls.keySet().iterator(); iterator.hasNext();) { + String rmiUrl = (String) iterator.next(); + String rmiUrlCacheName = extractCacheName(rmiUrl); + + if (!rmiUrlCacheName.equals(cache.getName())) { + continue; + } + Date date = (Date) peerUrls.get(rmiUrl); + if (!stale(date)) { + CachePeer cachePeer = null; + try { + cachePeer = lookupRemoteCachePeer(rmiUrl); + remoteCachePeers.add(cachePeer); + } catch (Exception e) { + if (LOG.isDebugEnabled()) { + LOG.debug("Looking up rmiUrl " + rmiUrl + " through exception " + e.getMessage() + + ". This may be normal if a node has gone offline. Or it may indicate network connectivity" + + " difficulties", e); + } + } + } else { + LOG.debug("rmiUrl {} should never be stale for a manually configured cluster.", rmiUrl); + staleList.add(rmiUrl); + } + + } + + //Remove any stale remote peers. Must be done here to avoid concurrent modification exception. + for (int i = 0; i < staleList.size(); i++) { + String rmiUrl = (String) staleList.get(i); + peerUrls.remove(rmiUrl); + } + return remoteCachePeers; + } + + + /** + * Whether the entry should be considered stale. + *

+ * Manual RMICacheManagerProviders use a static list of urls and are therefore never stale. + * + * @param date the date the entry was created + * @return true if stale + */ + protected final boolean stale(Date date) { + return false; + } + static String extractCacheName(String rmiUrl) { + return rmiUrl.substring(rmiUrl.lastIndexOf('/') + 1); + } + public CachePeer lookupRemoteCachePeer(String url) throws MalformedURLException, NotBoundException, RemoteException { + LOG.debug("Lookup URL {}", url); + CachePeer cachePeer = (CachePeer) TimeoutNaming.lookup(url); + return cachePeer; + } + +} diff --git a/src/main/java/com/eactive/eai/common/session/TimeoutNaming.java b/src/main/java/com/eactive/eai/common/session/TimeoutNaming.java new file mode 100644 index 0000000..13fccde --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/TimeoutNaming.java @@ -0,0 +1,366 @@ +/* + * Copyright 1996-2005 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ +package com.eactive.eai.common.session; + +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.rmi.AccessException; +import java.rmi.AlreadyBoundException; +import java.rmi.NotBoundException; +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; + + +/** + * The Naming class provides methods for storing and obtaining + * references to remote objects in a remote object registry. Each method of + * the Naming class takes as one of its arguments a name that + * is a java.lang.String in URL format (without the + * scheme component) of the form: + * + *

+ *    //host:port/name
+ * 
+ * + *

where host is the host (remote or local) where the registry + * is located, port is the port number on which the registry + * accepts calls, and where name is a simple string uninterpreted + * by the registry. Both host and port are optional. + * If host is omitted, the host defaults to the local host. If + * port is omitted, then the port defaults to 1099, the + * "well-known" port that RMI's registry, rmiregistry, uses. + * + *

Binding a name for a remote object is associating or + * registering a name for a remote object that can be used at a later time to + * look up that remote object. A remote object can be associated with a name + * using the Naming class's bind or + * rebind methods. + * + *

Once a remote object is registered (bound) with the RMI registry on the + * local host, callers on a remote (or local) host can lookup the remote + * object by name, obtain its reference, and then invoke remote methods on the + * object. A registry may be shared by all servers running on a host or an + * individual server process may create and use its own registry if desired + * (see java.rmi.registry.LocateRegistry.createRegistry method + * for details). + * + * @author Ann Wollrath + * @author Roger Riggs + * @since JDK1.1 + * @see java.rmi.registry.Registry + * @see java.rmi.registry.LocateRegistry + * @see java.rmi.registry.LocateRegistry#createRegistry(int) + */ +public final class TimeoutNaming { + /** + * Disallow anyone from creating one of these + */ + private TimeoutNaming() {} + + /** + * Returns a reference, a stub, for the remote object associated + * with the specified name. + * + * @param name a name in URL format (without the scheme component) + * @return a reference for a remote object + * @exception NotBoundException if name is not currently bound + * @exception RemoteException if registry could not be contacted + * @exception AccessException if this operation is not permitted + * @exception MalformedURLException if the name is not an appropriately + * formatted URL + * @since JDK1.1 + */ + public static Remote lookup(String name) + throws NotBoundException, + java.net.MalformedURLException, + RemoteException + { + ParsedNamingURL parsed = parseURL(name); + Registry registry = getRegistry(parsed); + + if (parsed.name == null) + return registry; + return registry.lookup(parsed.name); + } + + /** + * Binds the specified name to a remote object. + * + * @param name a name in URL format (without the scheme component) + * @param obj a reference for the remote object (usually a stub) + * @exception AlreadyBoundException if name is already bound + * @exception MalformedURLException if the name is not an appropriately + * formatted URL + * @exception RemoteException if registry could not be contacted + * @exception AccessException if this operation is not permitted (if + * originating from a non-local host, for example) + * @since JDK1.1 + */ + public static void bind(String name, Remote obj) + throws AlreadyBoundException, + java.net.MalformedURLException, + RemoteException + { + ParsedNamingURL parsed = parseURL(name); + Registry registry = getRegistry(parsed); + + if (obj == null) + throw new NullPointerException("cannot bind to null"); + + registry.bind(parsed.name, obj); + } + + /** + * Destroys the binding for the specified name that is associated + * with a remote object. + * + * @param name a name in URL format (without the scheme component) + * @exception NotBoundException if name is not currently bound + * @exception MalformedURLException if the name is not an appropriately + * formatted URL + * @exception RemoteException if registry could not be contacted + * @exception AccessException if this operation is not permitted (if + * originating from a non-local host, for example) + * @since JDK1.1 + */ + public static void unbind(String name) + throws RemoteException, + NotBoundException, + java.net.MalformedURLException + { + ParsedNamingURL parsed = parseURL(name); + Registry registry = getRegistry(parsed); + + registry.unbind(parsed.name); + } + + /** + * Rebinds the specified name to a new remote object. Any existing + * binding for the name is replaced. + * + * @param name a name in URL format (without the scheme component) + * @param obj new remote object to associate with the name + * @exception MalformedURLException if the name is not an appropriately + * formatted URL + * @exception RemoteException if registry could not be contacted + * @exception AccessException if this operation is not permitted (if + * originating from a non-local host, for example) + * @since JDK1.1 + */ + public static void rebind(String name, Remote obj) + throws RemoteException, java.net.MalformedURLException + { + ParsedNamingURL parsed = parseURL(name); + Registry registry = getRegistry(parsed); + + if (obj == null) + throw new NullPointerException("cannot bind to null"); + + registry.rebind(parsed.name, obj); + } + + /** + * Returns an array of the names bound in the registry. The names are + * URL-formatted (without the scheme component) strings. The array contains + * a snapshot of the names present in the registry at the time of the + * call. + * + * @param name a registry name in URL format (without the scheme + * component) + * @return an array of names (in the appropriate format) bound + * in the registry + * @exception MalformedURLException if the name is not an appropriately + * formatted URL + * @exception RemoteException if registry could not be contacted. + * @since JDK1.1 + */ + public static String[] list(String name) + throws RemoteException, java.net.MalformedURLException + { + ParsedNamingURL parsed = parseURL(name); + Registry registry = getRegistry(parsed); + + String prefix = ""; + if (parsed.port > 0 || !parsed.host.equals("")) + prefix += "//" + parsed.host; + if (parsed.port > 0) + prefix += ":" + parsed.port; + prefix += "/"; + + String[] names = registry.list(); + for (int i = 0; i < names.length; i++) { + names[i] = prefix + names[i]; + } + return names; + } + + /** + * Returns a registry reference obtained from information in the URL. + * + * jun's + * Timeout RMI Socket Factory 를 추가함 + */ + private static Registry getRegistry(ParsedNamingURL parsed) + throws RemoteException + { + return LocateRegistry.getRegistry(parsed.host, parsed.port, new TimeoutRMISocketFactory(3*1000,10*1000)); + } + + /** + * Dissect Naming URL strings to obtain referenced host, port and + * object name. + * + * @return an object which contains each of the above + * components. + * + * @exception MalformedURLException if given url string is malformed + */ + private static ParsedNamingURL parseURL(String str) + throws MalformedURLException + { + try { + return intParseURL(str); + } catch (URISyntaxException ex) { + /* With RFC 3986 URI handling, 'rmi://:' and + * '//:' forms will result in a URI syntax exception + * Convert the authority to a localhost: form + */ + MalformedURLException mue = new MalformedURLException( + "invalid URL String: " + str); + mue.initCause(ex); + int indexSchemeEnd = str.indexOf(':'); + int indexAuthorityBegin = str.indexOf("//:"); + if (indexAuthorityBegin < 0) { + throw mue; + } + if ((indexAuthorityBegin == 0) || + ((indexSchemeEnd > 0) && + (indexAuthorityBegin == indexSchemeEnd + 1))) { + int indexHostBegin = indexAuthorityBegin + 2; + String newStr = str.substring(0, indexHostBegin) + + "localhost" + + str.substring(indexHostBegin); + try { + return intParseURL(newStr); + } catch (URISyntaxException inte) { + throw mue; + } catch (MalformedURLException inte) { + throw inte; + } + } + throw mue; + } + } + + private static ParsedNamingURL intParseURL(String str) + throws MalformedURLException, URISyntaxException + { + URI uri = new URI(str); + if (uri.isOpaque()) { + throw new MalformedURLException( + "not a hierarchical URL: " + str); + } + if (uri.getFragment() != null) { + throw new MalformedURLException( + "invalid character, '#', in URL name: " + str); + } else if (uri.getQuery() != null) { + throw new MalformedURLException( + "invalid character, '?', in URL name: " + str); + } else if (uri.getUserInfo() != null) { + throw new MalformedURLException( + "invalid character, '@', in URL host: " + str); + } + String scheme = uri.getScheme(); + if (scheme != null && !scheme.equals("rmi")) { + throw new MalformedURLException("invalid URL scheme: " + str); + } + + String name = uri.getPath(); + if (name != null) { + if (name.startsWith("/")) { + name = name.substring(1); + } + if (name.length() == 0) { + name = null; + } + } + + String host = uri.getHost(); + if (host == null) { + host = ""; + try { + /* + * With 2396 URI handling, forms such as 'rmi://host:bar' + * or 'rmi://:' are parsed into a registry based + * authority. We only want to allow server based naming + * authorities. + */ + uri.parseServerAuthority(); + } catch (URISyntaxException use) { + // Check if the authority is of form ':' + String authority = uri.getAuthority(); + if (authority != null && authority.startsWith(":")) { + // Convert the authority to 'localhost:' form + authority = "localhost" + authority; + try { + uri = new URI(null, authority, null, null, null); + // Make sure it now parses to a valid server based + // naming authority + uri.parseServerAuthority(); + } catch (URISyntaxException use2) { + throw new + MalformedURLException("invalid authority: " + str); + } + } else { + throw new + MalformedURLException("invalid authority: " + str); + } + } + } + int port = uri.getPort(); + if (port == -1) { + port = Registry.REGISTRY_PORT; + } + return new ParsedNamingURL(host, port, name); + } + + /** + * Simple class to enable multiple URL return values. + */ + private static class ParsedNamingURL { + String host; + int port; + String name; + + ParsedNamingURL(String host, int port, String name) { + this.host = host; + this.port = port; + this.name = name; + } + } +} diff --git a/src/main/java/com/eactive/eai/common/session/TimeoutRMICacheManagerPeerProviderFactory.java b/src/main/java/com/eactive/eai/common/session/TimeoutRMICacheManagerPeerProviderFactory.java new file mode 100644 index 0000000..f035ad2 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/TimeoutRMICacheManagerPeerProviderFactory.java @@ -0,0 +1,66 @@ +/** + * Copyright Terracotta, Inc. + * + * 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 + * + * http://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. + */ + +package com.eactive.eai.common.session; + +import net.sf.ehcache.distribution.CacheManagerPeerProvider; +import net.sf.ehcache.distribution.RMICacheManagerPeerProvider; +import net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory; +import net.sf.ehcache.util.PropertyUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Properties; +import java.util.StringTokenizer; + +/** + * RMICacheManagerPeerProviderFactory 상속받아서 + * CustomManualRMICacheManagerPeerProvider 로 벼경 + * + * + * @author jun's + * @version + */ +public class TimeoutRMICacheManagerPeerProviderFactory extends RMICacheManagerPeerProviderFactory { + + private static final Logger LOG = LoggerFactory.getLogger(TimeoutRMICacheManagerPeerProviderFactory.class.getName()); + + private static final String RMI_URLS = "rmiUrls"; + private static final String URL_DELIMITER = "|"; + + /** + * peerDiscovery=manual, rmiUrls=//hostname:port/cacheName //hostname:port/cacheName //hostname:port/cacheName + */ + protected CacheManagerPeerProvider createManuallyConfiguredCachePeerProvider(Properties properties) { + String rmiUrls = PropertyUtil.extractAndLogProperty(RMI_URLS, properties); + if (rmiUrls == null || rmiUrls.length() == 0) { + LOG.info("Starting manual peer provider with empty list of peers. " + + "No replication will occur unless peers are added."); + rmiUrls = ""; + } + rmiUrls = rmiUrls.trim(); + StringTokenizer stringTokenizer = new StringTokenizer(rmiUrls, URL_DELIMITER); + RMICacheManagerPeerProvider rmiPeerProvider = new TimeoutManualRMICacheManagerPeerProvider(); + while (stringTokenizer.hasMoreTokens()) { + String rmiUrl = stringTokenizer.nextToken(); + rmiUrl = rmiUrl.trim(); + rmiPeerProvider.registerPeer(rmiUrl); + + LOG.debug("Registering peer {}", rmiUrl); + } + return rmiPeerProvider; + } +} diff --git a/src/main/java/com/eactive/eai/common/session/TimeoutRMISocketFactory.java b/src/main/java/com/eactive/eai/common/session/TimeoutRMISocketFactory.java new file mode 100644 index 0000000..5140be3 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/session/TimeoutRMISocketFactory.java @@ -0,0 +1,40 @@ +package com.eactive.eai.common.session; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.rmi.server.RMISocketFactory; + +/** +* 1. 기능 : RMISocketFactory를 상속받아서 +* connection Timeout 과 read Timeout 을 설정할수 있도록 구현 +* 2. 처리 개요 : +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class TimeoutRMISocketFactory extends RMISocketFactory +{ + private int connectionTimeout; + private int readTimeout; + public TimeoutRMISocketFactory(int connectionTimeout,int readTimeout){ + super(); + this.connectionTimeout = connectionTimeout; + this.readTimeout =readTimeout; + } + public Socket createSocket(String host,int port) throws IOException{ + Socket socket = new Socket(); + socket.setSoTimeout(this.readTimeout); + socket.setSoLinger(false, 0); + socket.connect(new InetSocketAddress(host,port), this.connectionTimeout); + return socket; + } + public ServerSocket createServerSocket(int port) throws IOException{ + return new ServerSocket(port); + } +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryDAO.java b/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryDAO.java new file mode 100644 index 0000000..271c369 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryDAO.java @@ -0,0 +1,35 @@ +package com.eactive.eai.common.sessioninfo; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.sessioninfo.loader.SessionHistoryLogger; +import com.eactive.eai.common.sessioninfo.mapper.SessionHistoryMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.sessioninfo.SessionHistory; + +@Service +@Transactional +public class SessionHistoryDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private SessionHistoryLogger sessionHistoryLogger; + + @Autowired + private SessionHistoryMapper sessionHistoryMapper; + + public void insertSessionHistory(SessionHistoryVO sessionHistoryVo) throws DAOException { + try { + SessionHistory entity = sessionHistoryMapper.toEntity(sessionHistoryVo); + sessionHistoryLogger.save(entity); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE118")); + } + } + +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryDTO.java b/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryDTO.java new file mode 100644 index 0000000..0bdbcd4 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryDTO.java @@ -0,0 +1,107 @@ +package com.eactive.eai.common.sessioninfo; + +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.UUIDGenerator; +import com.eactive.eai.message.EncodingVar; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.ReaderType; +import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.message.service.InterfaceMapper; + +public class SessionHistoryDTO { + private String historyId; + private String requestData; + private String historyDstcd; + private String responseResultDvsn; + private String uuid; + private String remoteIp; + private boolean isJson; + + public SessionHistoryDTO(String requestData, String historyDstcd, String responseResultDvsn, String uuid, String remoteIp, boolean isJson) { + + this.requestData = requestData; + this.historyDstcd = historyDstcd; + this.responseResultDvsn = responseResultDvsn; + this.uuid = uuid; + this.remoteIp = remoteIp; + this.isJson = isJson; + + } + + public SessionHistoryVO toVo() { + + if (isJson) { + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + InterfaceMapper mapper = standardManager.getMapper(); + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(ReaderType.JSON); + String historyId = null; + String guid = null; + String userId = null; + String body = null; + try { + reader.parse(standardMessage, requestData); + // 표준전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(EncodingVar.jsonEncoding); + + historyId = "HISL" + UUIDGenerator.getUUID(); + guid = mapper.getGuid(standardMessage); + userId = mapper.getUserId(standardMessage); + + String bizData = standardMessage.getBizData(); + JSONObject bodyObject = (JSONObject) JSONValue.parse(bizData); + // TODO 추후 제거해야될 값 확인 + // bodyObject.remove(ExtMessageKeys.FIELD_USER_PASSWORD); + body = bodyObject.toJSONString(); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } +// +// JSONObject reqJsonObject = (JSONObject) JSONValue.parse(requestData); +// JSONObject headerObject = (JSONObject) reqJsonObject.get(ExtMessageKeys.GROUP_HEADER); +// JSONObject systemHeader = (JSONObject) headerObject.get(ExtMessageKeys.GROUP_SYSTEM_HEADER); +// JSONObject commonHeader = (JSONObject) headerObject.get(ExtMessageKeys.GROUP_COMMON_HEADER); +// +// String historyId = "HISL" + UUIDGenerator.getUUID(); +// String guid = (String) systemHeader.get(ExtMessageKeys.FIELD_GUID); +// String userId = (String) commonHeader.get(ExtMessageKeys.FIELD_USERID); +// +// JSONObject bodyObject = (JSONObject)reqJsonObject.get(ExtMessageKeys.GROUP_BODY); +// bodyObject.remove(ExtMessageKeys.FIELD_USER_PASSWORD); +// +// String body = bodyObject.toJSONString(); +// String tranTime = (String) systemHeader.get(ExtMessageKeys.FIELD_TLGR_DMND_DT); + String tranTime = DatetimeUtil.getCurrentTimeMillis(); + + return new SessionHistoryVO(historyId, guid, userId, uuid, remoteIp, historyDstcd, responseResultDvsn, body, + tranTime); + } else { + + // requestData : 57 bytes + // ICON(4) + REQ/RES(3) + 정상여부(1) + 사용자 ID(9) + UUID(40) + String historyId = "HISL" + UUIDGenerator.getUUID(); + String guid = ""; + String userId = StringUtils.trim(requestData.substring(8, 8 + 9)); + String tranTime = DatetimeUtil.getCurrentTimeMillis(); + + return new SessionHistoryVO(historyId, guid, userId, uuid, remoteIp, historyDstcd, responseResultDvsn, requestData, tranTime); + } + + } + + @Override + public String toString() { + return "SessionHistoryDTO [requestData=" + requestData + ", historyDstcd=" + historyDstcd + + ", responseResultDvsn=" + responseResultDvsn + ", uuid=" + uuid + ", remoteIp=" + remoteIp + + ", isJson=" + isJson + "]"; + } + +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryQuery.java b/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryQuery.java new file mode 100644 index 0000000..b8dbd07 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryQuery.java @@ -0,0 +1,23 @@ +package com.eactive.eai.common.sessioninfo; + +import com.eactive.eai.common.dao.Keys; + +public class SessionHistoryQuery { + + public static final String INSERT_SESSION_HISTORY = String.join(System.getProperty("line.separator"), + " INSERT INTO", + " " + Keys.TABLE_OWNER + "TSEAISM05 SM05", + " (HISTORYID, GUID, USERID, UUID, HISTORYDSTCD, RSPNSRSLTDVSN, BODY, TRANTIME, REMOTEIP)", + " VALUES", + " (", + " ?, ", //HISTORYID + " ?, ", //GUID + " ?, ", //USERID + " ?, ", //UUID + " ?, ", //HISTORYDSTCD + " ?, ", //RSPNSRSLTDVSN + " ?, ", //BODY + " ?, ", //TRANTIME + " ?) " //REMOTEIP + ); +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryVO.java b/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryVO.java new file mode 100644 index 0000000..3bd3af6 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/SessionHistoryVO.java @@ -0,0 +1,140 @@ +package com.eactive.eai.common.sessioninfo; + +import com.eactive.eai.common.session.ChannelSessionFacade.LogoutType; + +public class SessionHistoryVO { + + public static final String HISTORYDSTCD_LOGIN = "LOGIN"; + public static final String HISTORYDSTCD_LOGOUT = "LOGOUT"; + public static final String HISTORYDSTCD_DUPLOGIN = "DUPLOGIN"; + public static final String HISTORYDSTCD_AUTOLOGOUT = "AUTOLOGOUT"; + public static final String HISTORYDSTCD_WEBSOCKET = "WEBSOCKET"; + public static final String HISTORYDSTCD_FORCELOGOUT = "FORCELOUT"; + public static final String HISTORYDSTCD_WEBSOCKET_TIMEOUT = "WSTIMEOUT"; + public static final String HISTORYDSTCD_DATECHANGE = "DATECHANGE"; + public static final String HISTORYDSTCD_SERVERDOWN = "SERVERDOWN"; + + public static String convertLogoutType_EnumToString(LogoutType logoutType) { + + switch(logoutType) { + case AutoLogout: + return SessionHistoryVO.HISTORYDSTCD_AUTOLOGOUT; + case ForceLogout: + return SessionHistoryVO.HISTORYDSTCD_FORCELOGOUT; + case Logout: + return SessionHistoryVO.HISTORYDSTCD_LOGOUT; + case WebSocketTimeout: + return SessionHistoryVO.HISTORYDSTCD_WEBSOCKET_TIMEOUT; + case DateChange: + return SessionHistoryVO.HISTORYDSTCD_DATECHANGE; + case ServerDown: + return SessionHistoryVO.HISTORYDSTCD_SERVERDOWN; + default: + throw new RuntimeException("Fail to convert LogoutTypeEnum : " + logoutType.toString()); + } + + } + + private String historyId; + private String guid; + private String userId; + private String uuid; + private String historyDstcd; + private String rspnsRsltDvsn; + private String body; + private String tranTime; + private String remoteIp; + + public SessionHistoryVO(String historyId, String guid, String userId, String uuid, String remoteIp, String historyDstcd, String rspnsRsltDvsn, String body, String tranTime) { + this.historyId = historyId; + this.guid = guid; + this.userId = userId; + this.uuid = uuid; + this.historyDstcd = historyDstcd; + this.rspnsRsltDvsn = rspnsRsltDvsn; + this.body = body; + this.tranTime = tranTime; + this.remoteIp = remoteIp; + } + + public String getHistoryId() { + return historyId; + } + + public void setHistoryId(String historyId) { + this.historyId = historyId; + } + + public String getGuid() { + return guid; + } + + public void setGuid(String guid) { + this.guid = guid; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getHistoryDstcd() { + return historyDstcd; + } + + public void setHistoryDstcd(String historyDstcd) { + this.historyDstcd = historyDstcd; + } + + public String getRspnsRsltDvsn() { + return rspnsRsltDvsn; + } + + public void setRspnsRsltDvsn(String rspnsRsltDvsn) { + this.rspnsRsltDvsn = rspnsRsltDvsn; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public String getTranTime() { + return tranTime; + } + + public void setTranTime(String tranTime) { + this.tranTime = tranTime; + } + + public String getRemoteIp() { + return remoteIp; + } + + public void setRemoteIp(String remoteIp) { + this.remoteIp = remoteIp; + } + + @Override + public String toString() { + return "SessionHistoryVO [historyId=" + historyId + ", guid=" + guid + ", userId=" + userId + ", uuid=" + uuid + + ", historyDstcd=" + historyDstcd + ", rspnsRsltDvsn=" + rspnsRsltDvsn + ", body=" + body + + ", tranTime=" + tranTime + ", remote=" + remoteIp + "]"; + } + + +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/SessionInfoDAO.java b/src/main/java/com/eactive/eai/common/sessioninfo/SessionInfoDAO.java new file mode 100644 index 0000000..fbfeecd --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/SessionInfoDAO.java @@ -0,0 +1,78 @@ +package com.eactive.eai.common.sessioninfo; + +import java.io.IOException; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.sessioninfo.loader.SessionInfoLoader; +import com.eactive.eai.common.sessioninfo.mapper.SessionInfoMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ObjectUtil; +import com.eactive.eai.data.entity.onl.sessioninfo.SessionInfo; + +@Service +@Transactional +public class SessionInfoDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private SessionInfoLoader sessionInfoLoader; + + @Autowired + private SessionInfoMapper sessionInfoMapper; + + + public void upsertSessionInfo(SessionInfoVO vo) throws DAOException { + SessionInfoVO cloned = null; + try { + cloned = (SessionInfoVO) ObjectUtil.deepCopy(vo); + } catch (IOException e) { + // TODO Auto-generated catch block + throw new DAOException(e); + } + cloned.setUserId(cloned.getUserId() + "_" + cloned.getSessionId()); + + try { + SessionInfo sessionInfo = null; + Optional optional = sessionInfoLoader.findById(cloned.getUserId()); + if(optional.isPresent()) { + sessionInfo = optional.get(); + sessionInfo.setSessionStatus( vo.getSessionStatusInfo() ); + sessionInfo.setWsocSessionStatus( vo.getWsocSessionStatusInfo() ); +// sessionInfo.setUserid( vo.getUserId() ); + sessionInfo.setBrnCd( vo.getBrnCode() ); + sessionInfo.setBrnName( vo.getBrnName() ); +// sessionInfo.setCreateTime( vo.getCreateTime() ); + sessionInfo.setRofcCd( vo.getRofcCode() ); +// sessionInfo.setSessionId( vo.getSessionId() ); + sessionInfo.setTerminalId( vo.getTerminalId() ); +// sessionInfo.setUserName( vo.getUserName() ); + sessionInfo.setWsocInstance( vo.getWsocInstance() ); + sessionInfo.setWsocRemoteAddr( vo.getWsocRemoteAddr() ); + } + else { + sessionInfo = sessionInfoMapper.toEntity(cloned); + sessionInfoLoader.save(sessionInfo); + } + } catch (Exception e) { + logger.error(e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE118")); + } + } + + public SessionInfoVO getSessionInfo(String userId) throws DAOException { + try { + SessionInfo sessionInfo = sessionInfoLoader.getById(userId); + return sessionInfoMapper.toVo(sessionInfo); + } catch (Exception e) { + logger.error(e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE118")); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/SessionInfoVO.java b/src/main/java/com/eactive/eai/common/sessioninfo/SessionInfoVO.java new file mode 100644 index 0000000..7a232da --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/SessionInfoVO.java @@ -0,0 +1,151 @@ +package com.eactive.eai.common.sessioninfo; + +import java.io.Serializable; + +public class SessionInfoVO implements Serializable { + public enum Status { + active, inactive + }; + + private String userId; + private String sessionId; + private String userName; + private String rofcCode; + private String brnName; + private String brnCode; + private Status sessionStatus; + private String wsocInstance; + private String wsocRemoteAddr; + private Status wsocSessionStatus; + private String terminalId; + // YYYYMMDDHHMI24SS + private String createTime; + + public SessionInfoVO() { + + } + + public SessionInfoVO(String userId) { + this.userId = userId; +// this.createTime = DatetimeUtil.getCurrentDateTime(); + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getSessionId() { + return sessionId; + } + + public void setSessionId(String sessionId) { + this.sessionId = sessionId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getRofcCode() { + return rofcCode; + } + + public void setRofcCode(String rofcCode) { + this.rofcCode = rofcCode; + } + + public String getBrnName() { + return brnName; + } + + public void setBrnName(String brnName) { + this.brnName = brnName; + } + + public String getBrnCode() { + return brnCode; + } + + public void setBrnCode(String brnCode) { + this.brnCode = brnCode; + } + + public Status getSessionStatus() { + return sessionStatus; + } + + public String getSessionStatusInfo() { + return sessionStatus == null ? "" : sessionStatus.toString(); + } + public void setSessionStatusInfo(String status) { + sessionStatus = Status.inactive.toString().equals(status) ? Status.inactive : Status.active; + } + + public void setSessionStatus(Status sessionStatus) { + this.sessionStatus = sessionStatus; + } + + public String getWsocInstance() { + return wsocInstance; + } + + public void setWsocInstance(String wsocInstance) { + this.wsocInstance = wsocInstance; + } + + public String getWsocRemoteAddr() { + return wsocRemoteAddr; + } + + public void setWsocRemoteAddr(String wsocRemoteAddr) { + this.wsocRemoteAddr = wsocRemoteAddr; + } + + public Status getWsocSessionStatus() { + return wsocSessionStatus; + } + + public String getWsocSessionStatusInfo() { + return wsocSessionStatus == null ? "" : wsocSessionStatus.toString(); + } + + public void setWsocSessionStatusInfo(String status) { + wsocSessionStatus = Status.inactive.toString().equals(status) ? Status.inactive : Status.active; + } + + public void setWsocSessionStatus(Status wsocSessionStatus) { + this.wsocSessionStatus = wsocSessionStatus; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + public String getTerminalId() { + return terminalId; + } + + public void setTerminalId(String terminalId) { + this.terminalId = terminalId; + } + + @Override + public String toString() { + return "SessionInfoVO [userId=" + userId + ", sessionId=" + sessionId + ", rofcCode=" + rofcCode + ", brnCode=" + + brnCode + ", sessionStatus=" + sessionStatus + ", wsocInstance=" + wsocInstance + ", wsocRemoteAddr=" + + wsocRemoteAddr + ", wsocSessionStatus=" + wsocSessionStatus + ", terminalId=" + terminalId + + ", createTime=" + createTime + "]"; + } +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/TerminalInfoDAO.java b/src/main/java/com/eactive/eai/common/sessioninfo/TerminalInfoDAO.java new file mode 100644 index 0000000..e69af08 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/TerminalInfoDAO.java @@ -0,0 +1,51 @@ +package com.eactive.eai.common.sessioninfo; + +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.sessioninfo.loader.TerminalInfoLoader; +import com.eactive.eai.common.sessioninfo.mapper.TerminalInfoMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.sessioninfo.TerminalInfo; + +@Service +@Transactional +public class TerminalInfoDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private TerminalInfoLoader terminalInfoLoader; + + @Autowired + private TerminalInfoMapper terminalInfoMapper; + + public void upsertTerminalInfo(TerminalInfoVO vo) throws DAOException { + try { + TerminalInfo terminalInfo = null; + Optional optional = terminalInfoLoader.findById(vo.getTerminalNo()); + if(optional.isPresent()) { + terminalInfo = optional.get(); + terminalInfo.setSocSessionStatus( vo.getSocSessionStatusInfo() ); + terminalInfo.setTerminalNo( vo.getTerminalNo() ); + terminalInfo.setBrnCd( vo.getBrnCode() ); + terminalInfo.setBrnName( vo.getBrnName() ); + terminalInfo.setCreateTime( vo.getCreateTime() ); + terminalInfo.setRofcCd( vo.getRofcCode() ); + terminalInfo.setSocInstance( vo.getSocInstance() ); + terminalInfo.setSocRemoteAddr( vo.getSocRemoteAddr() ); + } + else { + terminalInfo = terminalInfoMapper.toEntity(vo); + terminalInfoLoader.save(terminalInfo); + } + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE118")); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/TerminalInfoVO.java b/src/main/java/com/eactive/eai/common/sessioninfo/TerminalInfoVO.java new file mode 100644 index 0000000..48a14f5 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/TerminalInfoVO.java @@ -0,0 +1,98 @@ +package com.eactive.eai.common.sessioninfo; + +public class TerminalInfoVO { + public enum Status { + active, inactive + }; + + private String terminalNo; + private String rofcCode; + private String brnName; + private String brnCode; + private String socInstance; + private String socRemoteAddr; + private Status socSessionStatus; + // YYYYMMDDHHMI24SS + private String createTime; + + public TerminalInfoVO(String terminalNo) { + this.terminalNo = terminalNo; + // this.createTime = DatetimeUtil.getCurrentDateTime(); + } + + public String getTerminalNo() { + return terminalNo; + } + + public void setTerminalNo(String terminalNo) { + this.terminalNo = terminalNo; + } + + public String getRofcCode() { + return rofcCode; + } + + public void setRofcCode(String rofcCode) { + this.rofcCode = rofcCode; + } + + public String getBrnName() { + return brnName; + } + + public void setBrnName(String brnName) { + this.brnName = brnName; + } + + public String getBrnCode() { + return brnCode; + } + + public void setBrnCode(String brnCode) { + this.brnCode = brnCode; + } + + public String getSocInstance() { + return socInstance; + } + + public void setSocInstance(String socInstance) { + this.socInstance = socInstance; + } + + public String getSocRemoteAddr() { + return socRemoteAddr; + } + + public void setSocRemoteAddr(String socRemoteAddr) { + this.socRemoteAddr = socRemoteAddr; + } + + public Status getSocSessionStatus() { + return socSessionStatus; + } + + public String getSocSessionStatusInfo() { + return socSessionStatus == null ? "" : socSessionStatus.toString(); + } + + public void setSocSessionStatus(Status socSessionStatus) { + this.socSessionStatus = socSessionStatus; + } + + public String getCreateTime() { + return createTime; + } + + public void setCreateTime(String createTime) { + this.createTime = createTime; + } + + @Override + public String toString() { + return "TerminalInfoVO [terminalNo=" + terminalNo + ", rofcCode=" + rofcCode + ", brnName=" + brnName + + ", brnCode=" + brnCode + ", socInstance=" + socInstance + ", socRemoteAddr=" + socRemoteAddr + + ", socSessionStatus=" + socSessionStatus + ", createTime=" + createTime + "]"; + } + +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/mapper/SessionHistoryMapper.java b/src/main/java/com/eactive/eai/common/sessioninfo/mapper/SessionHistoryMapper.java new file mode 100644 index 0000000..1749b43 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/mapper/SessionHistoryMapper.java @@ -0,0 +1,28 @@ +package com.eactive.eai.common.sessioninfo.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.sessioninfo.SessionHistoryVO; +import com.eactive.eai.data.entity.onl.sessioninfo.SessionHistory; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface SessionHistoryMapper extends GenericMapper { + @Mapping(source = "historyid", target = "historyId") + @Mapping(source = "body", target = "body") + @Mapping(source = "guid", target = "guid") + @Mapping(source = "historydstcd", target = "historyDstcd") + @Mapping(source = "rspnsrsltdvsn", target = "rspnsRsltDvsn") + @Mapping(source = "trantime", target = "tranTime") + @Mapping(source = "userid", target = "userId") + @Mapping(source = "uuid", target = "uuid") + @Override + SessionHistoryVO toVo(SessionHistory entity); + + @InheritInverseConfiguration + SessionHistory toEntity(SessionHistoryVO vo); + +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/mapper/SessionInfoMapper.java b/src/main/java/com/eactive/eai/common/sessioninfo/mapper/SessionInfoMapper.java new file mode 100644 index 0000000..7088c30 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/mapper/SessionInfoMapper.java @@ -0,0 +1,39 @@ +package com.eactive.eai.common.sessioninfo.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.sessioninfo.SessionInfoVO; +import com.eactive.eai.common.sessioninfo.SessionInfoVO.Status; +import com.eactive.eai.data.entity.onl.sessioninfo.SessionInfo; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface SessionInfoMapper extends GenericMapper { + @Mapping(source = "userid", target = "userId") + @Mapping(source = "brnCd", target = "brnCode") + @Mapping(source = "brnName", target = "brnName") + @Mapping(source = "createTime", target = "createTime") + @Mapping(source = "rofcCd", target = "rofcCode") + @Mapping(source = "sessionId", target = "sessionId") + @Mapping(source = "sessionStatus", target = "sessionStatus") + @Mapping(source = "terminalId", target = "terminalId") + @Mapping(source = "userName", target = "userName") + @Mapping(source = "wsocInstance", target = "wsocInstance") + @Mapping(source = "wsocRemoteAddr", target = "wsocRemoteAddr") + @Mapping(source = "wsocSessionStatus", target = "wsocSessionStatus") + @Override + SessionInfoVO toVo(SessionInfo entity); + + @InheritInverseConfiguration + @Mapping(source = "sessionStatusInfo", target = "sessionStatus") + @Mapping(source = "wsocSessionStatusInfo", target = "wsocSessionStatus") + SessionInfo toEntity(SessionInfoVO vo); + + default Status mapStatus(String status) { + return Status.inactive.toString().equals(status) ? Status.inactive : Status.active; + } + +} diff --git a/src/main/java/com/eactive/eai/common/sessioninfo/mapper/TerminalInfoMapper.java b/src/main/java/com/eactive/eai/common/sessioninfo/mapper/TerminalInfoMapper.java new file mode 100644 index 0000000..acc932d --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sessioninfo/mapper/TerminalInfoMapper.java @@ -0,0 +1,34 @@ +package com.eactive.eai.common.sessioninfo.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.sessioninfo.TerminalInfoVO; +import com.eactive.eai.common.sessioninfo.TerminalInfoVO.Status; +import com.eactive.eai.data.entity.onl.sessioninfo.TerminalInfo; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface TerminalInfoMapper extends GenericMapper { + @Mapping(source = "terminalNo", target = "terminalNo") + @Mapping(source = "brnCd", target = "brnCode") + @Mapping(source = "brnName", target = "brnName") + @Mapping(source = "createTime", target = "createTime") + @Mapping(source = "rofcCd", target = "rofcCode") + @Mapping(source = "socInstance", target = "socInstance") + @Mapping(source = "socRemoteAddr", target = "socRemoteAddr") + @Mapping(source = "socSessionStatus", target = "socSessionStatus") + @Override + TerminalInfoVO toVo(TerminalInfo entity); + + @InheritInverseConfiguration + @Mapping(source = "socSessionStatusInfo", target = "socSessionStatus") + TerminalInfo toEntity(TerminalInfoVO vo); + + default Status mapStatus(String statusString) { + return Status.inactive.toString().equals(statusString) ? Status.inactive : Status.active; + } + +} diff --git a/src/main/java/com/eactive/eai/common/state/ElinkState.java b/src/main/java/com/eactive/eai/common/state/ElinkState.java new file mode 100644 index 0000000..0b7845a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/state/ElinkState.java @@ -0,0 +1,8 @@ +package com.eactive.eai.common.state; + +public enum ElinkState { + STARTING, + STARTED, + STOPPING, + STOPPED +} diff --git a/src/main/java/com/eactive/eai/common/state/ElinkStateException.java b/src/main/java/com/eactive/eai/common/state/ElinkStateException.java new file mode 100644 index 0000000..3775162 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/state/ElinkStateException.java @@ -0,0 +1,17 @@ +package com.eactive.eai.common.state; + +public class ElinkStateException extends Exception { + private static final long serialVersionUID = 1L; + + public ElinkStateException(String msg) { + super(msg); + } + + public ElinkStateException(Throwable cause) { + super(cause); + } + + public ElinkStateException(String msg, Throwable cause) { + super(msg, cause); + } +} diff --git a/src/main/java/com/eactive/eai/common/state/ElinkStateManager.java b/src/main/java/com/eactive/eai/common/state/ElinkStateManager.java new file mode 100644 index 0000000..7f69873 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/state/ElinkStateManager.java @@ -0,0 +1,122 @@ +package com.eactive.eai.common.state; + +import java.util.concurrent.atomic.AtomicInteger; + +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; + +public class ElinkStateManager { + private static ElinkStateManager instance; + private volatile ElinkState currentState = ElinkState.STOPPED; + private AtomicInteger transactionsInProgress = new AtomicInteger(0); + private long waitMaxMs = 60000; + private long sleepIntervalMs = 500; + + private static final String LOG_PREFIX = "ElinkStateManager] "; + + private void log(String message) { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger != null) { + logger.warn(message); + } + System.out.println(DatetimeUtil.getCurrentTime() + " " + LOG_PREFIX + message); + } + + public static synchronized ElinkStateManager getInstance() { + if (instance == null) { + instance = new ElinkStateManager(); + } + return instance; + } + + public int getTransactionsInProgress() { + return transactionsInProgress.get(); + } + + public long getWaitMaxMs() { + return waitMaxMs; + } + + public void setWaitMaxMs(long waitMaxMs) { + this.waitMaxMs = waitMaxMs; + } + + public long getSleepIntervalMs() { + return sleepIntervalMs; + } + + public void setSleepIntervalMs(long sleepIntervalMs) { + this.sleepIntervalMs = sleepIntervalMs; + } + + public void starting() { + synchronized (this) { + if (currentState == ElinkState.STOPPED) { + currentState = ElinkState.STARTING; + log("Elink starting successfully."); + } else { + log("Elink is already started or in the process of starting."); + } + } + } + + public void started() { + synchronized (this) { + if (currentState == ElinkState.STARTING) { + currentState = ElinkState.STARTED; + log("Elink started successfully."); + } else { + log("Elink is already started or in the process of started."); + } + } + } + + public void stop() { + if (this.waitMaxMs <= 0) { + log("Elink stopping - transactionsInProgress : " + transactionsInProgress.get() + " waitMaxMs : " + + this.waitMaxMs + " sleepIntervalMs : " + this.sleepIntervalMs); + currentState = ElinkState.STOPPED; + log("Elink stopped forcely."); + return; + } + + log("Elink stopping - transactionsInProgress : " + transactionsInProgress.get() + " waitMaxMs : " + + this.waitMaxMs); + + if (currentState == ElinkState.STARTED || currentState == ElinkState.STARTING) { + currentState = ElinkState.STOPPING; + long startTime = System.currentTimeMillis(); + while (transactionsInProgress.get() > 0) { + long elapsedTime = System.currentTimeMillis() - startTime; + if (elapsedTime >= waitMaxMs) { + log("Timeout! Unable to stop. Transactions are still in progress. transactionsInProgress: " + + transactionsInProgress.get()); + break; + } + try { + log("Elink wait in procress transaction, sleep " + sleepIntervalMs + + " msecs. transactionsInProgress : " + transactionsInProgress.get()); + Thread.sleep(sleepIntervalMs); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + currentState = ElinkState.STOPPED; + log("Elink stopped successfully."); + } else { + log("Elink is already stopped or in the process of stopping."); + } + } + + public void startRequest() { + transactionsInProgress.incrementAndGet(); + } + + public void completeRequest() { + transactionsInProgress.decrementAndGet(); + } + + public ElinkState getState() { + return currentState; + } +} diff --git a/src/main/java/com/eactive/eai/common/stdmessage/ExtMessageConverter.java b/src/main/java/com/eactive/eai/common/stdmessage/ExtMessageConverter.java new file mode 100644 index 0000000..4ba3d8e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/stdmessage/ExtMessageConverter.java @@ -0,0 +1,1727 @@ +//package com.ext.eai.common.stdmessage; +// +//import com.eactive.eai.common.dao.Keys; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.message.*; +//import com.eactive.eai.common.message.MessageType; +//import com.eactive.eai.common.server.EAIServerManager; +//import com.eactive.eai.common.util.*; +//import com.eactive.eai.inbound.error.InboundErrorKeys; +//import com.eactive.eai.inbound.processor.ProcessVO; +//import com.eactive.eai.inbound.processor.RequestProcessorException; +//import com.eactive.eai.transformer.layout.Layout; +//import com.eactive.eai.transformer.message.*; +//import com.eactive.eai.util.SimHeaderUtil; +//import com.ext.eai.common.stdmessage.parser.STDMessageParser; +//import com.ext.eai.common.stdmessage.parser.STDMessageParserFactory; +//import com.ext.eai.common.stdmessage.parser.STDMessageParserType; +//import org.apache.commons.lang3.StringUtils; +//import org.json.simple.JSONArray; +//import org.json.simple.JSONObject; +//import org.json.simple.JSONValue; +// +//import java.io.UnsupportedEncodingException; +//import java.net.UnknownHostException; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.List; +// +///** +//* 1. 기능 :EAI Message 와 표준전문 변환 class +//* 2. 처리 개요 : EAI 메시지 와 표준전문 상호 변환 +//* 3. 주의사항 : +//* @author : +//* @version : v 1.0.0 +//* @see : +//* @since : +//* : +//*/ +//public class ExtMessageConverter { +// //출력 매체부 관련 +// private static final String FIELD_OTPT_MDCL_LIST = "otptMdclList"; +// private static final String FIELD_OTPT_MDCL_DAT = "OTPT_MDCL_DAT"; +// private static final String FIELD_OTPT_MDCL_INTF_ID = "OTPT_MDCL_INTF_ID"; +// private static final String DEFAULT_ENCODE = "euc-kr"; +// /** +// * Default Logger +// */ +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// public ExtMessageConverter() { +// super(); +// } +// //데이터 받으면 필요 (100,300 전에 필요) +// private static ExtMessage toExtMessage(ExtMessage extmessage,Object stdmessage) { +// boolean isFEP = EAIServerManager.getInstance().isFEP(); +// String systemType = EAIServerManager.getInstance().getSystemType(); +// +// if (stdmessage instanceof STDMessage) { +// STDMessage stdmsg = (STDMessage)stdmessage; +// +// +// //stdheader 와 stdcommon 의 field 값을 셋팅 +// HashMap map = new HashMap(); +// HashMap hdr = stdmsg.getKeyValues(STDMessage.STDHEADER); +//// HashMap com = stdmsg.getKeyValues(STDMessage.STDCOMMON); +// +// if (hdr != null) map.putAll(hdr); +//// if (com != null) map.putAll(com); +// extmessage.setFullheaders(map); +// +// //이후 부터는 stdmsg 에서 가져오던걸 extmessage 에서 가져오는 걸로 변경 +//// extmessage.setGuidKey(extmessage.getFullHeaderString("stdcommon.groupCmpCd")); +// extmessage.setGuid(extmessage.getFullHeaderString("stdheader.global_id").substring(0,UUIDGenerator.GUID_LENGTH)); +//// extmessage.setOrgGuid(extmessage.getFullHeaderString("stdcommon.ortrGuid")); +// extmessage.setGuidSeq(new Integer(extmessage.getFullHeaderString("stdheader.global_id").substring(UUIDGenerator.GUID_LENGTH,UUIDGenerator.GUID_LENGTH + UUIDGenerator.GUID_SEQ_LENGTH))); +// +// //계정계 서비스ID +// extmessage.setServiceId(extmessage.getFullHeaderString(ExtMessageKeys.GROUP_STD_HEADER+"."+ExtMessageKeys.FIELD_SERVICE_ID)); +//// //응답받을 정상 서비스ID +//// extmessage.setReturnServiceId(extmessage.getFullHeaderString("stdcommon.procsRsltRcmsSrvcId")); +//// //응답받을 오류 서비스ID +//// extmessage.setErrorServiceId(""); +// +// +// /** +// * 인터페이스관련 시작 +// */ +// //인터페이스 +// extmessage.setSystemType(systemType); +// String ifId = extmessage.getFullHeaderString(ExtMessageKeys.GROUP_STD_HEADER+"."+ExtMessageKeys.FIELD_SERVICE_ID) ; +// if(StringUtils.isNotBlank(ifId))extmessage.setInterfaceId(ifId); +// +// +// //인스턴스ID +// extmessage.setInstanceId(EAIServerManager.getInstance().getInstId()); +// //세션ID +// String sessionId = extmessage.getFullHeaderString("stdheader.Session_id"); +// extmessage.setSessionId(sessionId); +// +// //요청응답관련 : S/R +// if (StringUtils.isBlank(extmessage.getSendRecv())) { +// String mesgDmanDvcd = extmessage.getFullHeaderString("stdheader.return_gubun"); +// if (StringUtils.isNotBlank(mesgDmanDvcd)) +// extmessage.setSendRecv(mesgDmanDvcd); +// } +// +// //내외부 구분 코드 : 1(내부로)/2(외부로) +//// String hmabDvcd = extmessage.getFullHeaderString("stdcommon.hmabDvcd"); +// String hmabDvcd = "1"; +// if (isFEP) { +// // TODO 하나캐피탈 POC 준비로 임시로 2로 처리 +// hmabDvcd = "2"; +// } +// if(StringUtils.isNotBlank(hmabDvcd)) extmessage.setDirection(hmabDvcd); +// +// /** +// * 인터페이스관련 종료 +// */ +// +// /** +// * 운영환경구분코드 +// * +// * engine +// * 운영 (O), 스테이징(S), 개발(D), DR(R), LOCAL(L), SIM(E) +// * +// * 사이트(전북) +// * 운영(O) , 스테이징(S), 개발(D), DR(R), 로컬(L), SIM(E) +//*/ +//// extmessage.setOperationEnv(extmessage.getFullHeaderString("stdcommon.sysOprtEnvDvcd")); +// +// //최초요청IP주소 +// extmessage.setFirstRequestSysIp(extmessage.getFullHeaderString("stdheader.ip_addr")); +// +// //복원여부 +//// extmessage.setRecoverYn(extmessage.getFullHeaderString("stdcommon.ortrRestrYn")); +// +// //기관코드 +// extmessage.setInstitutionCode(extmessage.getFullHeaderString("stdheader.com_code")); //그룹사코드 +// +// //타임아웃 +//// extmessage.setTotalTimeout(extmessage.getFullHeaderString("stdheader.gnrzTmotTktm")); +// +// //extmessage.setDate(stdmsg.getData("stdcommon.txDt")); //날짜 +// //extmessage.setTime(stdmsg.getData("stdcommon.txTime"));//시간 +// +//// /** +//// * extMessage 에서 에러코드는 표준전문 에러 응답때문에 필요 +//// */ +//// extmessage.setErrorCode(extmessage.getFullHeaderString("stdheader.msg_id")); +//// extmessage.setErrorMessage(extmessage.getFullHeaderString("stdheader.msg_nm")); +// +//// /** +//// * 우체국 +//// * 거래 형태 - MCI만 구분필요할꺼라고 보여짐 +//// * G : 일반거래 +//// * P : PUSH거래 +//// * D : Dummy 응답 +//// * M : 대량거래(Mass) +//// * K : Ack응답 +//// */ +//// String TLGR_TYP_DVSN_CD = stdmsg.getData(ExtMessageKeys.GROUP_STD_HEADER+"."+ExtMessageKeys.FIELD_TLGR_TYP_DVSN_CD); +//// if ("D".equals(TLGR_TYP_DVSN_CD)) { +//// extmessage.setDummy(true); +//// }else if ("P".equals(TLGR_TYP_DVSN_CD)) { +//// extmessage.setPush(true); +//// }else if ("M".equals(TLGR_TYP_DVSN_CD)) { +//// extmessage.setMass(true); +//// }else if ("G".equals(TLGR_TYP_DVSN_CD)) { +//// extmessage.setNormal(true); +//// } +// /** +// * 전북 +// */ +// //String TRAN_TYPE = stdmsg.getData(ExtMessageKeys.GROUP_STD_COMMON+"."+ExtMessageKeys.FIELD_TRAN_TYPE); +// extmessage.setNormal(true); +// +//// extmessage.setTargetGroup("1"); +// +// extmessage.setStdMessage(stdmessage); +// +// extmessage.setUserId( extmessage.getFullHeaderString(ExtMessageKeys.GROUP_STD_HEADER+"."+ExtMessageKeys.FIELD_USERID) ); +// +// /** +// * MCI 전옹 시작 ?? +// */ +// //extmessage.setRofcCode( ); +// //extmessage.setBrnCode( ); +// //extmessage.setRspsAprvProcCode( ); +// //extmessage.setPushDvsnCode( ); +// //extmessage.setPushRcvrList(); +//// try { +//// String aprvUserId = stdmsg.getData("commonHeader.approveList[0].RPNB_USERID"); +//// extmessage.setAprvUserId( aprvUserId ); +//// } +//// catch(Exception e) { +//// extmessage.setAprvUserId( null ); +//// } +// +// /** +// * MCI 전용 종료 ?? +// */ +// +// //처리결과 구분코드 : NR/ER +// //extmessage.setResponseType( extmessage.getFullHeaderString("stdcommon.procsRsltDvcd") ); +// +// //대외업무구분코드 +//// String extBizCode = ifId == null || ifId.length() < 3 ? "" : ifId.substring(0,3); +//// if (extBizCode == null) extBizCode =""; +//// extmessage.setExtBizCode(extBizCode); +// +// //거래처리구분코드 : S/A/D +// //extmessage.setSyncAsyncType( extmessage.getFullHeaderString("stdcommon.txSynzDvcd") ); +// +// } +// return extmessage; +// +// } +// //전송하기전에 필요(200,400 전에 셋팅 필요) +// private static Object fromExtMessage(ExtMessage extmessage,Object stdmessage) { +// +// boolean isFEP = EAIServerManager.getInstance().isFEP(); +// //eai.systemType = MCI/EAI/FEP +//// String systemType = EAIServerManager.getInstance().getSystemType(); +// +// //inst.Name에서 추출 +//// String serverType = EAIServerManager.getInstance().getServerType(); +// +// STDMessage stdmsg = null; +// if (stdmessage instanceof STDMessage) { +// stdmsg = (STDMessage)stdmessage; +// +// //extmessage에 셋팅했던 값을 stdmsg에 일괄적으로 셋팅 +// HashMap map = extmessage.getFullheaders(); +// for(String key : map.keySet()) { +// stdmsg.setObjectData(key, map.get(key)); +// } +// //위쪽 일괄 매핑시 엔진에서 사용하지는 않지만 변경한값이 매핑(엔진에서 직접 extmessage.setFullheader 에 셋팅 +// //아래쪽은 일괄적으로 셋팅한 값위에 엔진에서 변경한 값 매핑 +// +//// stdmsg.setData("stdcommon.groupCmpCd",extmessage.getGuidKey()); +// //전북은 GUID(33) + 일련번호(3) +// stdmsg.setData("stdheader.global_id",extmessage.getGuid()+ StringUtils.leftPad(Integer.toString(extmessage.getGuidSeq()), UUIDGenerator.GUID_SEQ_LENGTH,'0')); +//// stdmsg.setData("stdcommon.ortrGuid",extmessage.getOrgGuid()) ; +// +// //계정계 서비스ID +// stdmsg.setData(ExtMessageKeys.GROUP_STD_HEADER+"."+ExtMessageKeys.FIELD_SERVICE_ID,extmessage.getServiceId()); +// //응답받을 정상 서비스ID +//// stdmsg.setData("stdcommon.procsRsltRcmsSrvcId",extmessage.getReturnServiceId()) ; +// //응답받을 오류 서비스ID +// //stdmsg.setData("stdcommon.procsRsltRcmsSrvcId",extmessage.getErrorServiceId()) ; +// +//// String eaiTranName = stdmsg.getEaiTranName(); +//// if (eaiTranName == null) { +//// eaiTranName = stdmsg.getData("systemHeader.MCI_INTF_ID"); +//// } +// +//// stdmsg.setData("stdcommon.ifId",extmessage.getInterfaceId()); +// //인스턴스ID +// //stdmsg.setData("",extmessage.getInstanceId()); +// //세션ID +// //stdmsg.setData("",extmessage.getSessionId()); +// +// //요청응답관련 : S/R +// if (StringUtils.isBlank(stdmsg.getData("stdheader.return_gubun"))) { +// stdmsg.setData("stdheader.return_gubun", extmessage.getSendRecv()); +// } +// //내외부 구분 코드 : 1(내부로)/2(외부로) 바뀔일이 없음 +//// stdmsg.setData("stdcommon.hmabDvcd",extmessage.getDirection()); +// +// //운영환경구분코드 +//// stdmsg.setData("stdcommon.sysOprtEnvDvcd",extmessage.getOperationEnv()); +// +// //최초요청IP주소 : 바뀔일이 없음 +// stdmsg.setData("stdheader.ip_addr",extmessage.getFirstRequestSysIp()); +// +// //복원여부 : 바뀔일 없음 +//// stdmsg.setData("stdcommon.ortrRestrYn",extmessage.getRecoverYn()); +// +// //기관코드 +// stdmsg.setData("stdheader.com_code",extmessage.getInstitutionCode()); +// +// //타임아웃 +//// stdmsg.setData("stdheader.gnrzTmotTktm",extmessage.getTotalTimeout()); +// +// //extmessage.setDate((stdmsg.getData("systemHeader.TLGR_DMND_DT")).substring(0,8)); //날짜 +// //extmessage.setTime((stdmsg.getData("systemHeader.TLGR_DMND_DT")).substring(8,17)); //시간 +// +//// stdmsg.setData("systemHeader.TLGR_DMND_DT",extmessage.getDate() + extmessage.getTime()); +// //stdmsg.setData("stdcommon.txDt",extmessage.getDate()); +// //stdmsg.setData("stdcommon.txTime",extmessage.getTime()); +// +////// stdmsg.setData("systemHeader.msg_id",extmessage.getErrorCode()); +////// stdmsg.setData("systemHeader.msg_nm",extmessage.getErrorMessage()); +// +// //extmessage.setTargetGroup("1"); +// +// stdmsg.setData(ExtMessageKeys.GROUP_STD_HEADER+"."+ExtMessageKeys.FIELD_USERID,extmessage.getUserId()); +// +//// stdmsg.setData("stdcommon.procsRsltDvcd",extmessage.getResponseType()); +// +// //대외업무구분코드 +// //stdmsg.setData("",extmessage.getExtBizCode()); +// +// //거래처리구분코드 +//// stdmsg.setData("stdcommon.txSynzDvcd",extmessage.getSyncAsyncType()); +// +// //최초전송시스템코드 +//// String ifSysCode =stdmsg.getData("stdheader.frstTrnmSysCd"); +//// if (StringUtils.isBlank(ifSysCode) && StringUtils.isNotBlank(serverType) ){ +//// stdmsg.setData("stdheader.frstTrnmSysCd",serverType.toUpperCase()); +//// } +// +// //전송시스템코드 +// stdmsg.setData("stdheader.Inter_chn", EAIServerManager.getInstance().getSystemGubun()); +// +// //전송시각 +// stdmsg.setData("stdheader.send_tm", DatetimeUtil.getCurrentTimeMillis()); +// } +// return (Object)stdmsg; +// } +// /** +// * STDMessage 를 ExtMessage로 변환 하는 메소드 +// * stdMessage는 사이트별 표준메시지임 +// * +// * 사용처 +// * 1. requestProcess에서 요청/응답 전문 컨버젼 +// * (getExtMessageForNonStandard,getExtMessageForStandard) +// * 2. requestProcess에서 복원할때 컨버젼 +// * 3. outboundProcess에서 응답받은 전문 컨버젼 +// * @param extmessage +// * @param stdmessage +// * @param isStandard +// * @return +// * @throws Exception +// */ +//// private static ExtMessage toExtMessage(ExtMessage extmessage,Object stdmessage, boolean isStandard) throws Exception { +//// +//// boolean isFEP = EAIServerManager.getInstance().isFEP(); +//// String systemType = EAIServerManager.getInstance().getSystemType(); +//// +//// if (stdmessage instanceof STDMessage) { +//// STDMessage stdmsg = (STDMessage)stdmessage; +//// extmessage.setGuidKey(stdmsg.getData("stdcommon.groupCmpCd")); +//// extmessage.setGuid(stdmsg.getData("stdheader.guid").substring(0,33)); +//// extmessage.setOrgGuid(stdmsg.getData("stdcommon.ortrGuid")); +//// extmessage.setGuidSeq(new Integer(stdmsg.getData("stdheader.guid").substring(33,3))); +//// +//// //계정계 서비스ID +//// extmessage.setServiceId(stdmsg.getData(ExtMessageKeys.GROUP_STD_COMMON+"."+ExtMessageKeys.FIELD_SERVICE_ID)); +//// //응답받을 정상 서비스ID +//// extmessage.setReturnServiceId(stdmsg.getData("stdcommon.procsRsltRcmsSrvcId")); +//// //응답받을 오류 서비스ID +//// extmessage.setErrorServiceId(""); +//// +//// +//// /** +//// * 인터페이스관련 시작 +//// */ +//// //인터페이스 +//// extmessage.setSystemType(systemType); +//// extmessage.setInterfaceId( stdmsg.getData("stdcommon.ifId") ); +//// //인스턴스ID +//// extmessage.setInstanceId(""); +//// //세션ID +//// extmessage.setSessionId(""); +//// +//// //요청응답관련 : S/R +//// extmessage.setSendRecv(stdmsg.getData("stdheader.mesgDmanDvcd")); +//// //내외부 구분 코드 : 1(내부로)/2(외부로) +//// extmessage.setDirection(stdmsg.getData("stdcommon.hmabDvcd")); +//// /** +//// * 인터페이스관련 종료 +//// */ +//// +//// /** +//// * 운영환경구분코드 +//// * +//// * engine +//// * 운영 (O), 스테이징(S), 개발(D), DR(R), LOCAL(L), SIM(E) +//// * +//// * 사이트(전북) +//// * 운영(O) , 스테이징(S), 개발(D), DR(R), 로컬(L), SIM(E) +//// */ +//// extmessage.setOperationEnv(stdmsg.getData("stdcommon.sysOprtEnvDvcd")); +//// +//// //최초요청IP주소 +//// extmessage.setFirstRequestSysIp(stdmsg.getData("stdheader.frstTrnmIpad")); +//// +//// //복원여부 +//// extmessage.setRecoverYn(stdmsg.getData("stdcommon.ortrRestrYn")); +//// +//// //기관코드 +//// extmessage.setInstitutionCode(stdmsg.getData("stdcommon.otsdChnlInstCd")); +//// +//// //타임아웃 +//// extmessage.setTotalTimeout(stdmsg.getData("stdheader.gnrzTmotTktm")); +//// +//// //extmessage.setDate(stdmsg.getData("stdcommon.txDt")); //날짜 +//// //extmessage.setTime(stdmsg.getData("stdcommon.txTime"));//시간 +//// +//// /** +//// * extMessage 에서 에러코드는 표준전문 에러 응답때문에 필요 +//// */ +//// extmessage.setErrorCode(stdmsg.getData("stdcommon.errCd")); +//// //extmessage.setErrorMessage(stdmsg.getData("stdcommon.errSysCd")); +//// +////// /** +////// * 우체국 +////// * 거래 형태 - MCI만 구분필요할꺼라고 보여짐 +////// * G : 일반거래 +////// * P : PUSH거래 +////// * D : Dummy 응답 +////// * M : 대량거래(Mass) +////// * K : Ack응답 +////// */ +////// String TLGR_TYP_DVSN_CD = stdmsg.getData(ExtMessageKeys.GROUP_STD_HEADER+"."+ExtMessageKeys.FIELD_TLGR_TYP_DVSN_CD); +////// if ("D".equals(TLGR_TYP_DVSN_CD)) { +////// extmessage.setDummy(true); +////// }else if ("P".equals(TLGR_TYP_DVSN_CD)) { +////// extmessage.setPush(true); +////// }else if ("M".equals(TLGR_TYP_DVSN_CD)) { +////// extmessage.setMass(true); +////// }else if ("G".equals(TLGR_TYP_DVSN_CD)) { +////// extmessage.setNormal(true); +////// } +//// /** +//// * 전북 +//// */ +//// //String TRAN_TYPE = stdmsg.getData(ExtMessageKeys.GROUP_STD_COMMON+"."+ExtMessageKeys.FIELD_TRAN_TYPE); +//// extmessage.setNormal(true); +//// +//// +//// extmessage.setTargetGroup("1"); +//// +//// extmessage.setStdMessage(stdmessage); +//// +//// extmessage.setUserId( stdmsg.getData(ExtMessageKeys.GROUP_STD_COMMON+"."+ExtMessageKeys.FIELD_USERID) ); +//// +//// /** +//// * MCI 전옹 시작 ?? +//// */ +//// //extmessage.setRofcCode( ); +//// //extmessage.setBrnCode( ); +//// +//// //extmessage.setRspsAprvProcCode( ); +//// +//// //extmessage.setPushDvsnCode( ); +//// +//// //extmessage.setPushRcvrList(); +//// +//// +////// try { +////// String aprvUserId = stdmsg.getData("commonHeader.approveList[0].RPNB_USERID"); +////// extmessage.setAprvUserId( aprvUserId ); +////// } +////// catch(Exception e) { +////// extmessage.setAprvUserId( null ); +////// } +//// +//// /** +//// * MCI 전용 종료 ?? +//// */ +//// +//// //처리결과 구분코드 : NR/ER +//// extmessage.setResponseType( stdmsg.getData("stdcommon.procsRsltDvcd") ); +//// +//// //대외업무구분코드 +//// String extBizCode = stdmsg.getData("stdcommon.ifId").substring(0,3); +//// if (extBizCode == null) extBizCode =""; +//// extmessage.setExtBizCode(extBizCode); +//// +//// +//// //거래처리구분코드 : S/A/D +//// extmessage.setSyncAsyncType( stdmsg.getData("stdcommon.txSynzDvcd") ); +//// +//// } +//// return extmessage; +//// } +// +// /** +// * ExtMessage를 STDMessage로 변환하는 메소드 +// * stdMessage는 사이트별 표준메시지임 +// * 사용처(예상) +// * 1.Logging +// * 2.전송전 +// * 3. +// * @param extmessage +// * @param stdmessage +// * @return +// * @throws Exception +// */ +//// private static Object fromExtMessage(ExtMessage extmessage,Object stdmessage) { +//// +//// boolean isFEP = EAIServerManager.getInstance().isFEP(); +//// //eai.systemType = MCI/EAI/FEP +//// String systemType = EAIServerManager.getInstance().getSystemType(); +//// +//// //inst.Name에서 추출 +//// String serverType = EAIServerManager.getInstance().getServerType(); +//// +//// STDMessage stdmsg = null; +//// if (stdmessage instanceof STDMessage) { +//// stdmsg = (STDMessage)stdmessage; +//// stdmsg.setData("stdcommon.groupCmpCd",extmessage.getGuidKey()); +//// //전북은 GUID(33) + 일련번호(3) +//// stdmsg.setData("stdheader.guid",extmessage.getGuid()+ StringUtils.leftPad(Integer.toString(extmessage.getGuidSeq()), 3,'0')); +//// stdmsg.setData("stdcommon.ortrGuid",extmessage.getOrgGuid()) ; +//// +//// //계정계 서비스ID +//// stdmsg.setData(ExtMessageKeys.GROUP_STD_COMMON+"."+ExtMessageKeys.FIELD_SERVICE_ID,extmessage.getServiceId()); +//// //응답받을 정상 서비스ID +//// stdmsg.setData("stdcommon.procsRsltRcmsSrvcId",extmessage.getReturnServiceId()) ; +//// //응답받을 오류 서비스ID +//// //stdmsg.setData("stdcommon.procsRsltRcmsSrvcId",extmessage.getErrorServiceId()) ; +//// +////// String eaiTranName = stdmsg.getEaiTranName(); +////// if (eaiTranName == null) { +////// eaiTranName = stdmsg.getData("systemHeader.MCI_INTF_ID"); +////// } +//// +//// stdmsg.setData("stdcommon.ifId",extmessage.getInterfaceId()); +//// //인스턴스ID +//// //stdmsg.setData("",extmessage.getInstanceId()); +//// //세션ID +//// //stdmsg.setData("",extmessage.getSessionId()); +//// +//// //요청응답관련 : S/R +//// stdmsg.setData("stdheader.mesgDmanDvcd",extmessage.getSendRecv()); +//// //내외부 구분 코드 : 1(내부로)/2(외부로) 바뀔일이 없음 +//// stdmsg.setData("stdcommon.hmabDvcd",extmessage.getDirection()); +//// +//// //운영환경구분코드 +//// stdmsg.setData("stdcommon.sysOprtEnvDvcd",extmessage.getOperationEnv()); +//// +//// //최초요청IP주소 : 바뀔일이 없음 +//// stdmsg.setData("stdheader.frstTrnmIpad",extmessage.getFirstRequestSysIp()); +//// +//// //복원여부 : 바뀔일 없음 +//// stdmsg.setData("stdcommon.ortrRestrYn",extmessage.getRecoverYn()); +//// +//// //기관코드 +//// stdmsg.setData("stdcommon.otsdChnlInstCd",extmessage.getInstitutionCode()); +//// +//// //타임아웃 +//// stdmsg.setData("stdheader.gnrzTmotTktm",extmessage.getTotalTimeout()); +//// +//// //extmessage.setDate((stdmsg.getData("systemHeader.TLGR_DMND_DT")).substring(0,8)); //날짜 +//// //extmessage.setTime((stdmsg.getData("systemHeader.TLGR_DMND_DT")).substring(8,17)); //시간 +//// +////// stdmsg.setData("systemHeader.TLGR_DMND_DT",extmessage.getDate() + extmessage.getTime()); +//// //stdmsg.setData("stdcommon.txDt",extmessage.getDate()); +//// //stdmsg.setData("stdcommon.txTime",extmessage.getTime()); +//// +//// stdmsg.setData("stdcommon.errCd",extmessage.getErrorCode()); +//// +//// //extmessage.setTargetGroup("1"); +//// +//// stdmsg.setData(ExtMessageKeys.GROUP_STD_COMMON+"."+ExtMessageKeys.FIELD_USERID,extmessage.getUserId()); +//// +//// stdmsg.setData("stdcommon.procsRsltDvcd",extmessage.getResponseType()); +//// +//// //대외업무구분코드 +//// //stdmsg.setData("",extmessage.getExtBizCode()); +//// +//// //거래처리구분코드 +//// stdmsg.setData("stdcommon.txSynzDvcd",extmessage.getSyncAsyncType()); +//// +//// //최초전송시스템코드 +//// String ifSysCode =stdmsg.getData("stdheader.frstTrnmSysCd"); +//// if (StringUtils.isBlank(ifSysCode) && StringUtils.isNotBlank(serverType) ){ +//// stdmsg.setData("stdheader.frstTrnmSysCd",serverType.toUpperCase()); +//// } +//// +//// //전송시스템코드 +//// if (StringUtils.isNotBlank(serverType) ){ +//// stdmsg.setData("stdheader.trnmSysCd",serverType.toUpperCase()); +//// } +//// } +//// return (Object)stdmsg; +//// } +// /** +// * 비표준 전문을 사이트별 표준메시지에 맞게 기본값 셋팅 +// * @param stdmessage +// * @param message +// * @param selectedkey +// * @param msgRcvTm +// * @return +// */ +// private static STDMessage setDefaultValues(STDMessage stdmessage, ProcessVO vo, Object bizMsg) { +// //비표준 셋팅과 표준셋팅을 구별해야됨 +// +// stdmessage.setBwkSvcKey(vo.getSelectedKey()); +// +// String systemType = EAIServerManager.getInstance().getSystemType(); +// String serverType = EAIServerManager.getInstance().getServerType(); +// +// String instanceId = EAIServerManager.getInstance().getInstId(); +// +// +// // 통합전문고유번호 - GUID +//// String groupCmpCd = stdmessage.getData("stdcommon.groupCmpCd"); +//// if(StringUtils.isBlank(groupCmpCd)) groupCmpCd = "NON" ; +// String userId = vo.getInAdapterUserEmpid(); +// if (StringUtils.isBlank(userId)) { +// userId = EAIServerManager.getInstance().getSystemType() + "0000000"; +// } +// String guid = UUIDGenerator.getGUID(userId); +// //stdmessage.setData("stdcommon.ortrGuid",guid); //최초GUID +// stdmessage.setData("stdheader.global_id",guid+"01");//GUID +// +// stdmessage.setData(ExtMessageKeys.GROUP_STD_HEADER + "." + ExtMessageKeys.FIELD_SERVICE_ID, +// stdmessage.getEaiTranName()); // 거래코드 +// +// stdmessage.setData("stdheader.service_tn", "0"); // 거래구분 +// stdmessage.setData("stdheader.encrypt_yn", "01"); // 전문암호화여부 +// +//// //전문요청일자 +//// stdmessage.setData("stdcommon.mesgDmanDt",DatetimeUtil.getCurrentDate()); +//// //전문요청시간 +//// stdmessage.setData("stdcommon.mesgDmanTktm",DatetimeUtil.getTime8()); +// stdmessage.setData("stdheader.recv_tm",DatetimeUtil.getCurrentTimeMillis()); +// +//// stdmessage.setData("stdcommon.langDvcd","KOR");//다국어 구분코드 +// +// stdmessage.setData("stdheader.Inter_chn", EAIServerManager.getInstance().getSystemGubun()); +// stdmessage.setData("stdheader.return_value", STDMessageKeys.RESPONSE_TYPE_CODE_N); +// +//// stdmessage.setSTDData(new STDData()); +//// //데이터헤더 종류코드 +//// stdmessage.getSTDData().setDataHedrKncd("IO"); +// +//// //2012-07-24 임의 로 영업일자에 system시간 설정 +//// stdmessage.setData("stdcommon.bzopDt",DatetimeUtil.getCurrentDate()); +//// +//// //2013-02-01 나영채 차장 +//// stdmessage.setData("stdcommon.atmcClsnDvcd","0"); +//// //2013-05-29 나영채 차장 -타발거래에 셋팅요청 - 파출수납부점구분코드 +//// stdmessage.setData("stdcommon.dspcRcvBrnDvcd","00"); +//// +//// +//// //비표준일경우 시스템 운영환경 구분코드를 셋팅한다. +//// stdmessage.setData("stdcommon.sysOprtEnvDvcd",EAIServerManager.getInstance().getSystemEnvTypeConvert()); +//// +//// //2013-06-04 +//// //String mesgVerNo = std.getProperty(PropManagerKeys.MESG_VER_NO, DEFAULT_VERSION); +//// Properties prop = PropManager.getInstance().getProperties("STDMESSAGE"); +//// String gnrzTmotTktm = prop.getProperty("GNRZ_TMOT_TKTM", "070"); +//// String txTmotTktm = prop.getProperty("TX_TMOT_TKTM", "060"); +// +// +// //헤더부 전문버전번호 MESG_VER_NO +// //stdmessage.getSTDHeader().setMesgVerNo(mesgVerNo); +// //헤더부 최초전송IP주소 FRST_TRNM_IPAD +// String ip=""; +// try { +// ip = java.net.InetAddress.getLocalHost().getHostAddress(); +// } catch (UnknownHostException e1) { +// +// e1.printStackTrace(); +// } +// stdmessage.setData("stdheader.ip_addr",ip); +//// //헤더부 총괄타임아웃시간 GNRZ_TMOT_TKTM +//// stdmessage.setData("stdheader.gnrzTmotTktm",gnrzTmotTktm); +//// //헤더부 거래타임아웃시간 TX_TMOT_TKTM +//// stdmessage.setData("stdheader.txTmotTktm",txTmotTktm); +// +// if (EAIServerManager.getInstance().isFEP()){ +// //--------------------------------------------------- +// // 기동 어댑터의 대외기관코드 값이 존재하면 그값으로 설정한다. +// //--------------------------------------------------- +// if(StringUtils.isNotBlank(vo.getInAdapterOsidInstiNo())) { +//// stdmessage.setData("stdcommon.otsdChnlInstCd",vo.getInAdapterOsidInstiNo());//대외연계기관코드 +// stdmessage.setData("stdheader.com_code",vo.getInAdapterOsidInstiNo());//대외연계기관코드 +//// if (logger.isDebug()) { +//// logger.debug("RequestProcessor] SET STDMessage OsidInstiCd ["+stdmessage.getData("stdcommon.otsdChnlInstCd")+"]" ); +//// } +// } +// if(StringUtils.isNotBlank(vo.getInAdapterUserEmpid())) { +// stdmessage.setData("stdheader.usr_id",vo.getInAdapterUserEmpid()); //사용자ID +// if (logger.isDebug()) { +// logger.debug("RequestProcessor] SET STDMessage Tlrno ["+stdmessage.getData("stdheader.usr_id")+"]" ); +// } +// } +// } +// +// int bizMsgLength = 0; +// if (bizMsg instanceof byte[]) { +// bizMsgLength = ((byte[])bizMsg).length; +// } else if (bizMsg instanceof String) { +// try { +// bizMsgLength = ((String) bizMsg).getBytes(DEFAULT_ENCODE).length; +// } catch (UnsupportedEncodingException e) { +// logger.error(e.getMessage()); +// } +// } +// stdmessage.setData("stdheader.msg_len", String.format("%06d", STDMessage.STD_HEADER_LENGTH + bizMsgLength - 6)); +// +// return stdmessage; +// } +// /** +// * 사이트별 표준메시지가 들어왔을경우 ExtMessage로 변환하는 메소드 +// * requestProcess에서만 쓰임 +// * @param message +// * @param orgMessage +// * @param adptrMsgType +// * @return +// * @throws Exception +// */ +// public static ExtMessage getExtMessageForStandard(Object message, String adptrMsgType) throws Exception { +// STDMessage stdmessage = null; +// String[] msgArgs = null; +// String rspErrorCode = EAIMessageKeys.EAI_DEFAULT_CODE; +// String rspErrorMsg = ""; +// +// STDMessageParser parser = STDMessageParserFactory.createPaserFactory(adptrMsgType); +// if (parser == null){ +// msgArgs = new String[1]; +// msgArgs[0] = message.getClass().getName(); +// rspErrorCode = "RECEAIIRP009"; +// rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(rspErrorMsg); +// throw new RequestProcessorException(rspErrorMsg); +// } +// stdmessage = parser.convert(message); +// +// message = parser.getDataValue(message, false, stdmessage); +// +// // 표준일 경우 수신거래코드를 EAI거래코드에 설정한다. +// //stdmessage.setEAITranName(stdmessage.getData()KBCommon().getTelgmRecvTranCd()); +// //????? +// +// // 메세지 수신시각 설정 +// stdmessage.setData("stdheader.recv_tm", DatetimeUtil.getCurrentTimeMillis()); +// +// ExtMessage extMessage = new ExtMessage(); +// extMessage.setBizData(new Object[] {message}); +//// extMessage = toExtMessage(extMessage, (Object)stdmessage, true); +// extMessage = toExtMessage(extMessage, (Object)stdmessage); +// +// +// //SA 매핑문제 +// String guid = extMessage.getGuid(); +///* if(guid == null || guid.trim().length() != UUIDGenerator.GUID_LENGTH) { +// if (logger.isError()) { +// logger.error("RequestProcessor] Received STDMessage's GUID ["+guid+"] is INVALID GUID. -" + extMessage.getInterfaceId()); +// logger.error("RequestProcessor] Check Request Server Message"); +// } +// throw new RequestProcessorException("Invalid GUID Length"); +// } +//*/ +// +// return extMessage; +// } +// +// /** +// * 비표준메시지가 들어왔을경우 ExtMessage로 변환하는 메소드 +// * @param message +// * @param orgMessage1 +// * @param key +// * @param inAdapterOsidInstiNo +// * @param msgRcvTm +// * @param adapterGroupName +// * @param adapterName +// * @return +// * @throws Exception +// */ +// public static ExtMessage getExtMessageForNonStandard(Object message, Object orgMessage1,ProcessVO vo +// /*,String key, String inAdapterOsidInstiNo,String inAdapterUserEmpid , long msgRcvTm +// ,String adapterGroupName, String adapterName*/) throws Exception { +// /** +// * key = vo.getSelectedKey() +// * inAdapterOsidInstiNo = vo.getInAdapterOsidInstiNo() +// * inAdapterUserEmpid = +// * msgRcvTm = vo.getErrTm() +// * adapterGroupName = vo.getAdapterGroupName() +// * adapterName = vo.getAdapterName() +// */ +// STDMessage stdmessage = null; +// STDMessageManager stdMessageManager = STDMessageManager.getInstance(); +// stdmessage = stdMessageManager.getSTDMessage(vo.getSelectedKey()); +// if(stdmessage == null) { +// return null; +// } +// else +// { +// //표준전문에 셋팅 하는게 맞을까 ext메시지로 변경해서 하는게 맞을까? +// stdmessage = setDefaultValues(stdmessage, vo, message); +// if (logger.isDebug()) logger.debug("RequestProcessor] Set STDMessage Runtime Info\n" + stdmessage.toFixedString() ); +// } +// ExtMessage extMessage = new ExtMessage(); +// extMessage.setBizData(new Object[] {message}); +// +// extMessage = toExtMessage(extMessage, (Object)stdmessage); +// +// /** +// * 20220408 비표준 인터페이스ID 설정 this.interfaceId.trim() + this.sendRecv + this.direction; +// */ +// extMessage.setInterfaceId(stdmessage.getEaiTranName()); +// extMessage.setSendRecv(stdmessage.getEaiSendRecv()); //요청응답관련 : S/R +// extMessage.setDirection(stdmessage.getEaiDirection()); //내외부 구분 코드 : 1(내부로)/2(외부로) +// //extMessage.setea .setEAIServiceCode(extMessage.getEAIServiceCode()); +//// stdmessage. +// return extMessage; +// } +// /** +// * async sync 응답일 경우 표준전문셋팅 +// * @param guidLogPrefix +// * @param reqEaiMsg +// * @param resEaiMsg +// * @return +// */ +// public static EAIMessage setAsyncSyncResponseForStandard(String guidLogPrefix,EAIMessage reqEaiMsg, EAIMessage resEaiMsg) { +// ExtMessage extMessage = resEaiMsg.getExtMsg(); +// +// STDMessage stdmessage = (STDMessage)extMessage.getStdMessage(); +//// stdmessage.getKBHeader().setTelgmDmndDstcd(STDMessageKeys.TELGMDMNDDSTCD_RECV); +// //확인필요 +// extMessage.setSendRecv(STDMessageKeys.SEND_RECV_CD_RECV); +// extMessage.setStdMessage(stdmessage); +// resEaiMsg.setExtMsg(extMessage); +// //--------------------------------------------------- +// return resEaiMsg; +// } +// /** +// * 위의 메소드와 확인필요 +// * baseFC에서 setGUID() +// * CICS +// * kbmessage.getKBHeader().setCicsTrncd(cicsTrncd); +// * 중계채널구분코드 +// * kbmessage.getKBCommon().setRelayChnlDstcd("02"); +// * 원거래 복원시 수신LU명 (STND-RECV-LU-NAME) 8바이트 Blank로 초기화 요망(A-S 포함) +// * kbmessage.getKBCommon().setRecvLuName(" "); +// */ +// +// /** +// * +// * @param guidLogPrefix +// * @param reqEaiMsg +// * @param resEaiMsg +// * @return +// */ +// //outboundCtrlCallService, setTopicResult 에서 같이씀 +// public static EAIMessage setResponseForOutbound(EAIMessage resEaiMsg) { +// ExtMessage extMessage = resEaiMsg.getExtMsg(); +// +// STDMessage stdmessage = (STDMessage)extMessage.getStdMessage(); +// //stdmessage.getKBHeader().setTelgmDmndDstcd(STDMessageKeys.TELGMDMNDDSTCD_RECV); +// extMessage.setSendRecv(STDMessageKeys.SEND_RECV_CD_RECV); +// +// // ??????? +// //fromExtMessage(extMessage, stdmessage); +// +// extMessage.setStdMessage(stdmessage); +// resEaiMsg.setExtMsg(extMessage); +// +// return resEaiMsg; +// } +// /** +// * 표준전문일경우 응답로그값 설정 +// * @param reqEaiMsg +// * @param resEaiMsg +// * @param adptrMsgType +// * @param resBytes +// * @return +// * @throws Exception +// */ +// public static EAIMessage setRcvLogInfo(EAIMessage reqEaiMsg,EAIMessage resEaiMsg, String adptrMsgType, byte[] resBytes) throws Exception{ +// //String kesaSeq = reqEaiMsg.getKbMsg().getKesaSeq(); +// STDMessageParser parser = STDMessageParserFactory.createPaserFactory(adptrMsgType); +// if(parser == null) { +// throw new Exception("Parser not found - " + adptrMsgType); +// } +// byte[] message = null; +// STDMessage stdmessage = null; +// if (MessageType.UJSON.equals(adptrMsgType) ) { //출력매체부 관련 +// /* +// * 현재 resBytes의 JSON 객체를 파싱해서 출력 매체부 extMsg에 셋팅 후 resBytes에서 제거 +// */ +// String jsonString = new String(resBytes, MessageType.UJSON_ENCODE); +// JSONObject messageObj = (JSONObject) JSONValue.parse(jsonString); +// JSONObject headerObj = (JSONObject) messageObj.get("Header"); +// JSONObject dataHeaderObj = (JSONObject) headerObj.get("dataHeader"); +// JSONObject terminalInfoObj = (JSONObject) dataHeaderObj.get("terminalInfo"); +// List otptMdclDatList = new ArrayList(); +// +// /* +// * 전문에서 출력 매체 부의 인터페이스 별 데이터부 추출 및 제거 +// */ +// if(terminalInfoObj.containsKey(FIELD_OTPT_MDCL_LIST)) { +// JSONArray otptMdclList = (JSONArray) terminalInfoObj.get(FIELD_OTPT_MDCL_LIST); +// if(otptMdclList != null && otptMdclList.size() > 0){ +// for (int i = 0; i < otptMdclList.size(); i++) { +// JSONObject childJson = (JSONObject) otptMdclList.get(i); +// String interfaceId = (String) childJson.get(FIELD_OTPT_MDCL_INTF_ID); +// JSONObject otptMdclDat = (JSONObject) childJson.remove(FIELD_OTPT_MDCL_DAT); +// otptMdclDatList.add(new OtptMdclVO(interfaceId, otptMdclDat)); +// //빈 JSON OBJECT로 치환 +// childJson.put(FIELD_OTPT_MDCL_DAT, new JSONObject()); +// } +// } +// } +// +// stdmessage = parser.convert(messageObj); +// // if( STDMessageKeys.TELGMDMNDDSTCD_RECV.equals(stdmessage.getKBHeader().getTelgmDmndDstcd()) ) { +// // message = parser.getDataValue(resBytes, false); +// // } +// // else { +// // message = parser.getDataValue(resBytes, true); +// // } +// message = parser.getDataValue(messageObj, false); +// }else { //출력매체부가 없을경우 +// stdmessage = parser.convert(resBytes); +// message = parser.getDataValue(resBytes, false); +// } +// +// // 수신시각 설정 +// stdmessage.setData("stdheader.recv_tm",DatetimeUtil.getCurrentTimeMillis()); +// +// ExtMessage extMessage = new ExtMessage(); +// extMessage.setBizData(new Object[] {message}); +// +//// extMessage = toExtMessage(extMessage, (Object)stdmessage, true); +// extMessage = toExtMessage(extMessage, (Object)stdmessage); +// /* 출력 매체 부 extMessage에 셋팅 +// */ +//// extMessage.setOtptMdclDatList(otptMdclDatList); +// resEaiMsg.setExtMsg(extMessage); +// return resEaiMsg; +// } +// +// /** +// * 타입에 맞는 사이트별 표준메시지 형태의 데이터 로 변경 +// * @param inAdapterMsgType +// * @param adptrMsgType +// * @param reqBytes +// * @param reqEaiMsg +// * @return +// * @throws Exception +// */ +// public static byte[] makeStandardMessage(String inAdapterMsgType,String adptrMsgType, byte[] reqBytes,EAIMessage reqEaiMsg) throws Exception{ +// STDMessage stdmessage = (STDMessage) reqEaiMsg.getExtMsg().getStdMessage(); +//// reqBytes = stdmessage.toFixedBytes(inAdapterMsgType, adptrMsgType, reqBytes, MessageType.UJSON_ENCODE); +// reqBytes = stdmessage.toFixedBytes( reqBytes); +// return reqBytes; +// } +// public static byte[] addSimHeader(String inAdapterMsgType,String adptrMsgType, byte[] reqBytes,EAIMessage reqEaiMsg) throws Exception{ +// return SimHeaderUtil.addSimHeader(reqEaiMsg.getEAISvcCd(),reqEaiMsg.getExtMsg().getInstitutionCode(), reqBytes); +// } +// +// /** +// * 사이트별 표준메시지에서 업무데이터 추출(응답) +// * @param adptrMsgType +// * @param resBytes +// * @return +// * @throws Exception +// */ +// public static byte[] getBizMessage(String adptrMsgType, byte[] resBytes) throws Exception{ +// STDMessageParser parser = STDMessageParserFactory.createPaserFactory(adptrMsgType); +// if(parser == null) { +// throw new Exception("Parser not found - " + adptrMsgType); +// } +// return parser.getDataValue(resBytes, false); +// } +// +// @SuppressWarnings("unchecked") +// public static Object getReturnObject(EAIMessage retEaiMsg, Object message, Object retMsgObject, +// String adptrMsgPtrnCd, String adptrMsgType, String uuid) { +// +// if(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(adptrMsgPtrnCd)) { +// +// String targetAdptrMsgType = MessageType.ASC; +// STDMessage stdmessage = (STDMessage)fromExtMessage(retEaiMsg.getExtMsg(), retEaiMsg.getExtMsg().getStdMessage()); +//// if(retMsgObject == null) { +//// if (logger.isWarn()) logger.warn("ExceptionHandler 결과 데이터가 NULL 입니다. - "+uuid); +//// retMsgObject = ""; +//// } +//// String resDataString = null ; +//// if(retMsgObject instanceof byte[]) { +//// try { +//// resDataString = new String((byte[])retMsgObject, MessageType.UJSON_ENCODE); +//// } catch (UnsupportedEncodingException e) { +//// if (logger.isWarn()) logger.error("String 변환 오류 "+uuid, e); +//// } +//// } else if(retMsgObject instanceof String) { +//// resDataString = (String) retMsgObject; +//// } else { +//// resDataString = ""; +//// } +//// +//// /* +//// * 출력 매체 부 작업 +//// * JSON 변환 후 ExtMsg에 보관 한 출력 매체부를 추가 +//// */ +//// JSONObject messageObj = stdmessage.toJSONObject(resDataString); +//// //JSONObject messageObj = (JSONObject) JSONValue.parse(resJsonString); +//// JSONObject headerObj = (JSONObject) messageObj.get("Header"); +//// JSONObject dataHeaderObj = (JSONObject) headerObj.get("dataHeader"); +//// JSONObject terminalInfoObj = (JSONObject) dataHeaderObj.get("terminalInfo"); +//// /* +//// * 전문에 출력 매체 부의 인터페이스 별 데이터부 적재 +//// */ +//// List otptMdclDatList = retEaiMsg.getExtMsg().getOtptMdclDatList(); +//// if(otptMdclDatList != null && otptMdclDatList.size() > 0){ +//// JSONArray otptMdclList = (JSONArray) terminalInfoObj.get(FIELD_OTPT_MDCL_LIST); +//// if(otptMdclList != null && otptMdclList.size() > 0){ +//// for (int i = 0; i < otptMdclList.size(); i++) { +//// JSONObject childJson = (JSONObject) otptMdclList.get(i); +//// OtptMdclVO otptMdclDatVo = (OtptMdclVO) otptMdclDatList.get(i); +//// JSONObject otptMdclDat = (JSONObject) otptMdclDatVo.getOtptMdclDat(); +//// if(otptMdclDat != null){ +//// childJson.put(FIELD_OTPT_MDCL_DAT, otptMdclDat); +//// } +//// } +//// } +//// } +//// +//// String rtnJsonString = messageObj.toJSONString(); +//// Object rtnObj = null; +//// if(message instanceof String) { +//// rtnObj = rtnJsonString; +//// }else { +//// try { +//// rtnObj = rtnJsonString.getBytes(MessageType.UJSON_ENCODE); +//// } catch (UnsupportedEncodingException e) { +//// if (logger.isWarn()) logger.error("String 변환 오류 "+uuid, e); +//// if(retMsgObject instanceof byte[]) { +//// rtnObj = retMsgObject; +//// } +//// } +//// } +//// return rtnObj; +// +// +// if(message instanceof byte[]) { +// if(retMsgObject == null) { +// if (logger.isWarn()) logger.warn("ExceptionHandler 결과 데이터가 NULL 입니다. - "+uuid); +// retMsgObject = new byte[0]; +// } +// +// byte[] byteResponse = null; +// if(retMsgObject instanceof byte[]) { +// byteResponse = (byte[])retMsgObject; +// } +// else if(retMsgObject instanceof String) { +// byteResponse = ((String)retMsgObject).getBytes(); +// } +// +// if(retMsgObject instanceof byte[]) { +//// return stdmessage.toFixedBytes(adptrMsgType,targetAdptrMsgType, byteResponse, "euc-kr"); +// return stdmessage.toFixedBytes(byteResponse); +// } else { +//// return stdmessage.toFixedBytes(adptrMsgType,targetAdptrMsgType, null, "euc-kr"); +// return stdmessage.toFixedBytes( null); +// } +// } else if(message instanceof String) { +// if(retMsgObject == null) { +// if (logger.isWarn()) logger.warn("ExceptionHandler 결과 데이터가 NULL 입니다. - "+uuid); +// retMsgObject = ""; +// } +// +// String strResponse = null; +// +// if(retMsgObject instanceof String) { +// strResponse = (String)retMsgObject; +// } +// else if(retMsgObject instanceof byte[]) { +// strResponse = new String((byte[])retMsgObject); +// } +// +// if(retMsgObject instanceof String) { +//// return stdmessage.toFixedString(adptrMsgType,targetAdptrMsgType, strResponse, "euc-kr"); +// return stdmessage.toFixedString(strResponse, DEFAULT_ENCODE); +// } +// else { +//// return stdmessage.toFixedString(adptrMsgType,targetAdptrMsgType, "", "euc-kr"); +// return stdmessage.toFixedString( "", DEFAULT_ENCODE); +// } +// } +// else { +//// return stdmessage.toFixedString(adptrMsgType,targetAdptrMsgType, "", "euc-kr"); +// return stdmessage.toFixedString( "", DEFAULT_ENCODE); +// } +// } +// else { +// //------------------------------------------------- +// // 비표준 XML의 경우를 고려하여 +// // XML Header의 유무를 확인해야 한다. (한진호 대리 요청) +// // 2007.10.29 - 이동훈 +// //------------------------------------------------- +// // 비표준 XML일 경우 XML Header Tag의 존재여부를 확인하여 없는 경우 추가해야 한다. +// if(MessageType.XML.equals(adptrMsgType) || MessageType.UXML.equals(adptrMsgType)) { +// String encode = MessageType.XML_ENCODE; +// if(MessageType.UXML.equals(adptrMsgType)) { +// encode = MessageType.UXML_ENCODE; +// } +// +// if(message instanceof byte[]) { +// if(retMsgObject == null) { +// return new byte[0]; +// } +// else { +// String xmlString = null; +// try { +// xmlString = new String( (byte[])retMsgObject, encode ); +// } catch (UnsupportedEncodingException e) { +// xmlString = new String( (byte[])retMsgObject); +// } +// if(xmlString.indexOf("") == -1) { +// xmlString = "" +// + xmlString; +// } +// byte[] responseBytes = null; +// try { +// responseBytes = xmlString.getBytes(encode); +// } catch (UnsupportedEncodingException e) { +// responseBytes = xmlString.getBytes(); +// } +// return responseBytes; +// } +// } +// else if(message instanceof String) { +// if(retMsgObject == null) { +// return ""; +// } +// else { +// String xmlString = (String)retMsgObject; +// if(xmlString.indexOf("") == -1) { +// xmlString = "" +// + xmlString; +// } +// return xmlString; +// } +// } +// else { +// return retMsgObject; +// } +// } +// else { +// return retMsgObject; +// } +// } +// } +// /** +// * 저장된 표준전문헤더를 복원해서 사이트에 맞게 셋팅해야됨 +// * 현재는 float으로 동작함 +// * JSON 이나 XML은 고려해야됨 +// * @param traceKey +// * @param orgMessage +// * @param isNKESA +// * @param dbString +// * @return +// * @throws Exception +// */ +// public static ExtMessage getStoredMessageHeader(String traceKey, ExtMessage orgMessage, String dbString , String extBizCd ) throws Exception{ +// ExtMessage orgExtMessage = (ExtMessage) ObjectUtil.deepCopy(orgMessage); +// STDMessage orgSTDMessage = (STDMessage)orgExtMessage.getStdMessage(); +// +// STDMessageParser parser = STDMessageParserFactory.createPaserFactory(STDMessageParserType.ASC.toString()); +// if (parser == null) { +// throw new Exception("STDMessageParser not found - " + STDMessageParserType.ASC.toString()); +// } +// STDMessage dbStdMessage = parser.convert(dbString, false); +// +//// String eaiTranName = extMessage.getInterfaceId(); +//// String applCd = eaiTranName.substring(0,3); +// String applCd = extBizCd; +// +// if(dbStdMessage != null) { +// +// /** +// * 요청표준전문의 정상응답/오류응답은 +// * 표준전문의 당방응답정상여부로 판단 +// */ +//// boolean isSuccess = true; +//// +//// String normYn = orgSTDMessage.getData("dataHeader.externalInfo.OTWD_RSPNS_NORM_YN"); +//// +//// if (normYn != null && "N".equals(normYn)){ +//// isSuccess = false; +//// } +// +// //TODO 이걸 여기에 넣은게 낳은지 변경하고 넣는제 낳은지 판단필요 +// dbStdMessage.setData("stdheader.return_gubun", STDMessageKeys.SEND_RECV_CD_RECV); +//// dbStdMessage.setData("stdcommon.hmabDvcd", "1"); +// //2012-07-17협의 +// //당발응답에 서비스ID가 있으면 당발응답 서비스ID로 셋팅 +// //당발응답에 서비스ID가 없으면 당발요청의 처리결과수신 서비스ID를 서비스ID로 셋팅 +//// if (StringUtils.isBlank(orgMessage.getServiceId())){ +//// dbStdMessage.setData("stdcommon.ifId", dbStdMessage.getData("stdcommon.procsRsltRcmsSrvcId") ); +//// }else{ +//// dbStdMessage.setData("stdcommon.ifId", orgMessage.getServiceId()); +//// } +// +//// if (isSuccess) {//정상일경우에 +//// //dbStdMessage.setData("dataHeader.externalInfo.OTWD_RSPNS_NORM_YN", "Y" ); +//// }else { +//// //dbStdMessage.setData("systemHeader.DLNG_ID", dbStdMessage.getData("systemHeader.ERR_RSPNS_RCPTN_DLNG_ID") ); +//// dbStdMessage.setData("dataHeader.externalInfo.OTWD_RSPNS_NORM_YN", "N" ); +//// } +// //채널구분코드 대외이관에서 싯팅하던거 원복 +// //dbStdMessage.setData("systemHeader.CHNL_DVSN_CD", orgSTDMessage.getData("systemHeader.CHNL_DVSN_CD")); +// +//// message.getKBHeader().setTelgmDmndDstcd(STDMessageKeys.TELGMDMNDDSTCD_RECV); +// +// // 2020.03.03 NKESA가 아닌 경우에만 값을 변경한다. +//// if(!isNKESA) { +//// message.getKBCommon().setInoPartlDstcd(STDMessageKeys.WTINEXTNLDSTCD_IN); +//// } +// +// if(logger.isDebug()) { +// logger.debug("================================================================"); +// logger.debug("STDMessageMapper] - Restored STDMessage["+traceKey+"]"); +// logger.debug(dbStdMessage.toString()); +// logger.debug("================================================================"); +// logger.debug("================================================================"); +// logger.debug("STDMessageMapper] - Current STDMessage"); +// logger.debug(orgMessage.toString()); +// logger.debug("================================================================"); +// } +// +// if(logger.isDebug()) { +// +// logger.debug("================================================================"); +// logger.debug("STDMessageMapper] - Converted STDMessage"); +// logger.debug(dbStdMessage.toString()); +// logger.debug("================================================================"); +// } +// //복원이기 때문에 비표준 +//// ExtMessage result = toExtMessage(orgExtMessage, dbStdMessage,false); +// ExtMessage result = toExtMessage(orgExtMessage, dbStdMessage); +// result.nextGuidSeq(); +// return result; +// } +// else { +// if(logger.isWarn()) { +// logger.warn("STDMessage is NULL - " + dbStdMessage); +// } +// throw new Exception("복원 실패"); +// } +// } +// /** +// * 복원을 저장하기 위해서 Flat 전문을 만드는 메소드 +// * 현재는 float으로 동작함 +// * JSON 이나 XML은 고려해야됨 +// * @param extMessage +// * @return +// * @throws Exception +// */ +// public static String setStoredMessageHeader(ExtMessage extMessage ) throws Exception{ +// STDMessage stdmessage = (STDMessage)fromExtMessage(extMessage, extMessage.getStdMessage()); +// return stdmessage.toFixedHeaderString(); +// } +// /** +// * DB 로그 저장시 masking하기 위해서 +// * @param message +// * @param bizMsg +// * @param l +// * @param logPssSno +// * @param tgtAdptrMsgPtrnCd +// * @param svcTsmtUsgTp +// * @param psvItfTp +// * @return +// * @throws Exception +// */ +// public static String makeMaskData(EAIMessage message, Object bizMsg, Layout l, int logPssSno, String tgtAdptrMsgPtrnCd +// , String svcTsmtUsgTp, String psvItfTp) throws Exception { +// String bizMsgStr=""; +// Message msg = MessageFactory.getFactory().getMessage(l.getName()); +// if("XML".equals(l.getLayoutType().getName())) { +// if (logger.isInfo()) logger.info("EAILogDAO] XML Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); +// +// String xmlString = ""; +// if(bizMsg instanceof byte[]) { +// xmlString = new String((byte[])bizMsg); +// } else { +// xmlString = (String)bizMsg; +// } +// +// String rootItemName = ((XMLMessage)msg).getLayout().getRootItem().getName(); +// xmlString = MessageUtil.removeXMLHeader(xmlString); +// xmlString = "<"+rootItemName+">"+xmlString+""; +// msg.setData(xmlString); +// bizMsgStr = MessageUtil.removeXMLRootItem(msg.toLogString(), rootItemName); +// } +// else if("JSON".equals(l.getLayoutType().getName())) { +// if (logger.isInfo()) logger.info("EAILogDAO] JSON Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); +// String jsonString = ""; +// +// if(bizMsg instanceof byte[]) { +// jsonString = new String((byte[])bizMsg, JSONMessage.encode); +// } else { +// jsonString = (String)bizMsg; +// } +// +// String rootItemName = ((JSONMessage)msg).getLayout().getRootItem().getName(); +// jsonString = MessageUtil.addJsonRootItem(jsonString, rootItemName); +// msg.setData(jsonString); +// bizMsgStr = MessageUtil.removeJsonRootItem(msg.toLogString(), rootItemName);; +// } +// else if("UJSON".equals(l.getLayoutType().getName())) { +// if (logger.isInfo()) logger.info("EAILogDAO] UJSON Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); +// +// String jsonString = ""; +// +// if(bizMsg instanceof byte[]) { +// jsonString = new String((byte[])bizMsg, UJSONMessage.encode); +// } else { +// jsonString = (String)bizMsg; +// } +// +// String rootItemName = ((UJSONMessage)msg).getLayout().getRootItem().getName(); +// jsonString = MessageUtil.addJsonRootItem(jsonString, rootItemName); +// msg.setData(jsonString); +// bizMsgStr = MessageUtil.removeJsonRootItem(msg.toLogString(), rootItemName);; +// } +// else if("EBCDIC".equals(l.getLayoutType().getName())) { +// if (logger.isInfo()) logger.info("EAILogDAO] EBCDIC Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); +// +// byte[] orgBytes = (byte[])bizMsg; +// byte[] msgBytes = null; +// byte[] header = null; +// +// msg.setData(bizMsg); +// bizMsgStr = ((BytesMessage)msg).toLogString(true); +// } +// else if( "BYTES".equals(l.getLayoutType().getName()) ) { +// if (logger.isInfo()) logger.info("EAILogDAO] BYTES Message Masking - "+ logPssSno); +// byte[] orgBytes = (byte[])bizMsg; +// byte[] msgBytes = null; +// byte[] header = null; +// +// if (logger.isInfo()) logger.info("EAILogDAO] BYTES Standard Header Type = " + tgtAdptrMsgPtrnCd); +// +// if (logger.isInfo()) logger.info("EAILogDAO] "+l.getLayoutType().getName()+" Message Masking - "+ message.getEAISvcCd()+" - "+ logPssSno); +// msg.setData(bizMsg); +// bizMsgStr = msg.toLogString(); +// } +// else { +// msg.setData(bizMsg); +// bizMsgStr = msg.toLogString(); +// } +// return bizMsgStr; +// } +// +// public static String getSTDLog(ExtMessage extmessage) throws Exception { +// STDMessage stdmessage = (STDMessage) extmessage.getStdMessage(); +// return stdmessage.toFixedHeaderString(); +// } +// /** +// * 송신메시지 설정 +// * @param eaiMessage +// * @return +// */ +// public static byte[] normalAsyncSend(EAIMessage eaiMessage,String msgType) throws Exception{ +// ExtMessage extMessage = eaiMessage.getExtMsg(); +//// //-------------------------------------------------------------------- +//// // 취급요청거래일 경우 +//// // 에러코드를 다르게 설정 +//// //-------------------------------------------------------------------- +//// // 취급요청 (S_2) (S_3) -> 내외부구분코드가 2(대외),3(공동망)일 수 있다 +////// if(STDMessageKeys.TELGMDMNDDSTCD_SEND.equals( kbmessage.getKBHeader().getTelgmDmndDstcd() ) +////// && !STDMessageKeys.WTINEXTNLDSTCD_IN.equals( kbmessage.getKBCommon().getInoPartlDstcd() )){ +//// if(STDMessageKeys.SEND_RECV_CD_SEND.equals( extMessage.getSendRecv() ) +//// && !STDMessageKeys.DIRECTION_IN.equals( extMessage.getDirection() )){ +//// +////// String prcssRtdTranCd = kbmessage.getKBCommon().getPrcssRtdTranCd(); +//// String prcssRtdTranCd = extMessage.getReturnServiceId(); +//// +//// if(prcssRtdTranCd != null && prcssRtdTranCd.length() >= 14) { +//// String cicsTrncd = prcssRtdTranCd.substring(0,4); +//// String telgmRecvTranCd = prcssRtdTranCd.substring(4,14); +//// +////// kbmessage.getKBHeader().setCicsTrncd(cicsTrncd); +////// kbmessage.getKBCommon().setTelgmRecvTranCd(telgmRecvTranCd); +//// //TOBE 표준전문 확인 필요 +////// kbmessage.getKBHeader().setCicsTrncd(cicsTrncd); +//// extMessage.setServiceId(telgmRecvTranCd); +//// if(logger.isDebug()) { +////// logger.debug("ErrorResponseSender] - CicsTrncd ["+kbmessage.getKBHeader().getCicsTrncd()+"]"); +////// logger.debug("ErrorResponseSender] - TelgmRecvTranCd ["+kbmessage.getKBCommon().getTelgmRecvTranCd()+"]"); +////// logger.debug("ErrorResponseSender] - CicsTrncd ["+kbmessage.getKBHeader().getCicsTrncd()+"]"); +//// logger.debug("ErrorResponseSender] - TelgmRecvTranCd ["+extMessage.getServiceId()+"]"); +//// } +//// } +//// //TODO 표준전문 확인필요 +////// kbmessage.getKBCommon().setRecvLuName(" "); +//// } +// +// // eLink 내부에서는 GUID 진행번호를 분리 +// // ExtMessage 에서는 분리 +// // STDMessage 에서는 사이트에 맞게 변경처리 +// String guid = extMessage.getGuid(); +// int seq = extMessage.getGuidSeq(); +// +// if (logger.isDebug()) logger.debug("ErrorResponseSender] Current GUID ["+guid+ "]["+seq+"]"); +// extMessage.nextGuidSeq(); +// seq = extMessage.getGuidSeq(); +// if (logger.isDebug()) logger.debug("ErrorResponseSender] ADD PATHSEQ GUID ["+guid+ "]["+seq+"]"); +// extMessage.setGuidSeq(seq); +// +// //-------------------------------------------------------------------- +// +//// Object message = eaiMessage.getBizMsg()[0]; +// Object message = eaiMessage.getExtMsg().getBizData()[0]; +// +// byte[] reqBytes = null; +// +// STDMessage stdmessage = (STDMessage)extMessage.getStdMessage(); +// +// if(message instanceof byte[]) { +//// if( MessageType.EBC.equals(msgType) ) { +//// reqBytes = stdmessage.toFixedEbcdicBytes( (byte[])message ); +//// } +//// else if( MessageType.ASC.equals(msgType) ) { +//// reqBytes = stdmessage.toFixedBytes( (byte[])message ); +//// } +//// if( MessageType.XML.equals(msgType) ) { +//// reqBytes = stdmessage.toXMLBytes( (byte[])message ); +//// } +//// reqBytes = stdmessage.toFixedBytes( (byte[])message, "euc-kr"); +// reqBytes = stdmessage.toFixedBytes( (byte[])message); +// } +// else { +// throw new Exception("업무데이터타입이 전문이 아닙니다."); +// } +// return reqBytes; +// } +// /** +// * 거래통제에의한 표준전문응답 +// * @param retEaiMsg +// * @param message +// * @param adptrMsgPtrnCd +// * @param adptrMsgType +// * @param uuid +// * @return +// * @throws Exception +// */ +// public static Object getRestrictedResponse(EAIMessage retEaiMsg, Object message, +// String adptrMsgType, String uuid) { +// ExtMessage extmessage = retEaiMsg.getExtMsg(); +// STDMessage stdmessage = (STDMessage) fromExtMessage(extmessage, extmessage.getStdMessage()); +// String errorMessage = ExceptionUtil.make(EAIMessageKeys.EAI_BLOCKED_CODE, new String[]{retEaiMsg.getEAISvcCd()}); +// stdmessage = setInternalError(stdmessage,STDMessageKeys.ERROR_CODE_VALUE, errorMessage) ; +// if(message instanceof byte[]) { +// if(message == null) { +// if (logger.isWarn()) logger.warn("ExceptionHandler 결과 데이터가 NULL 입니다. - "+uuid); +// message = new byte[0]; +// } +// if(message instanceof byte[]) { +//// if(MessageType.XML.equals(adptrMsgType)) { +//// return stdmessage.toXMLBytes( (byte[])message, MessageType.XML_ENCODE ); +//// } +//// else if(MessageType.UXML.equals(adptrMsgType)) { +//// return stdmessage.toXMLBytes( (byte[])message, MessageType.UXML_ENCODE ); +//// } +//// else if(MessageType.ASC.equals(adptrMsgType)) { +//// try { +//// return stdmessage.toFixedBytes(( (byte[]) message) ); +//// } catch(Exception e) { +//// return (byte[]) message; +//// } +//// } +//// else if(MessageType.EBC.equals(adptrMsgType)) { +//// try { +//// return stdmessage.toFixedEbcdicBytes(( (byte[]) message) ); +//// } catch(Exception e) { +//// return (byte[]) message; +//// } +//// } +//// else if(MessageType.JSON.equals(adptrMsgType)) { +//// return stdmessage.toJSONBytes( (byte[])message ); +//// } +//// else if(MessageUtil.isUTF8(adptrMsgType)) { +//// return stdmessage.toJSONBytes( (byte[])message, MessageType.UJSON_ENCODE); +//// } +//// else { +//// return message; +//// } +//// return stdmessage.toFixedBytes( (byte[])message, "euc-kr"); +// return stdmessage.toFixedBytes( (byte[])message); +// } +// else { +//// return stdmessage.toFixedString( "" ).getBytes("euc-kr"); +// return stdmessage.toFixedString( "" ).getBytes(); +// } +// } else if(message instanceof String) { +// if(message == null) { +// if (logger.isWarn()) logger.warn("ExceptionHandler 결과 데이터가 NULL 입니다. - "+uuid); +// message = ""; +// } +// if(message instanceof String) { +//// if(MessageType.XML.equals(adptrMsgType)) { +//// return stdmessage.toXMLString( (String)message, MessageType.XML_ENCODE ); +//// } +//// else if(MessageType.UXML.equals(adptrMsgType)) { +//// return stdmessage.toXMLString( (String)message, MessageType.UXML_ENCODE ); +//// } +//// else if(MessageType.ASC.equals(adptrMsgType)) { +//// try { +//// return stdmessage.toFixedString(( (String) message) ); +//// } catch(Exception e) { +//// return (byte[]) message; +//// } +//// } +//// else if(MessageType.JSON.equals(adptrMsgType)) { +//// return stdmessage.toJSONString( (String)message ); +//// } +//// else if(MessageType.UJSON.equals(adptrMsgType)) { +//// return stdmessage.toJSONString( (String)message ); +//// } +//// else { +//// return message; +//// } +// return stdmessage.toFixedString( (String)message ); +// } +// else { +//// return stdmessage.toFixedString( "" ).getBytes("euc-kr"); +// return stdmessage.toFixedString( "" ).getBytes(); +// } +// } +// else { +// return stdmessage.toFixedString(""); +// } +// } +// public static String getTellerId(Object message, String messageType) throws Exception { +// STDMessageParser parser = STDMessageParserFactory.createPaserFactory(messageType); +// STDMessage std = parser.convert(message); +//// return std.getKBCommon().getUserEmpid(); +// return std.getData("stdheader.usr_id"); +// } +// public static byte[] getInboundErrorResponseForStandard(ExtMessage extMessage, String errCode, String errMsg) { +// extMessage.nextGuidSeq();; +// extMessage.setSendRecv(STDMessageKeys.SEND_RECV_CD_RECV); +// extMessage.setErrorCode(errCode); +// +// STDMessage stdmessage = (STDMessage)fromExtMessage(extMessage,extMessage.getStdMessage()); +// stdmessage = setInternalError(stdmessage, errCode, errMsg); +// try { +// return stdmessage.toFixedString().getBytes("euc-kr"); +// } catch (UnsupportedEncodingException e) { +// logger.warn("use default encoding - ", e); +// return stdmessage.toFixedString().getBytes(); +// } +// } +// +// public static byte[] getDuplicateLoginResponseForStandard(ExtMessage extMessage, String errCode, String errMsg, String siteErrCode, String siteErrMessage) { +// extMessage.nextGuidSeq(); +// extMessage.setSendRecv(STDMessageKeys.SEND_RECV_CD_RECV); +// extMessage.setErrorCode(errCode); +// +// STDMessage stdmessage = (STDMessage)fromExtMessage(extMessage,extMessage.getStdMessage()); +// stdmessage.setMessage(siteErrCode, siteErrMessage, errMsg); +// //stdmessage.setData("systemHeader.RSPNS_SYS_CD", EAIServerManager.getInstance().getServerType().toUpperCase()); +// //stdmessage.setData("systemHeader.TLGR_RSPNS_DT", DatetimeUtil.getCurrentTimeMillis()); +// +// stdmessage.setData("stdheader.return_value",STDMessageKeys.RESPONSE_TYPE_CODE_E);//시스템오류 +//// if (STDMessageKeys.ERROR_CODE_VALUE.equals(errCode)) { +//// }else { +//// stdmessage.setData("systemHeader.RSPNS_RSLT_DVSN_CD","T");//타임아웃오류 +//// } +// try { +//// return stdmessage.toFixedString().getBytes(MessageType.UJSON_ENCODE); +// return stdmessage.toFixedString().getBytes(DEFAULT_ENCODE); +// } catch (UnsupportedEncodingException e) { +// logger.warn("use default encoding - ", e); +//// return stdmessage.toFixedString().getBytes("euc-kr"); +// return stdmessage.toFixedString().getBytes(); +// } +// } +// +// /** +// * 에러 발생시 표준전문에 셋팅해야 되는 것들 +// * 1. 메시지 헤더 생성 (messageHeader) +// * 2. 시스템 헤더 설정(systemHeader) +// * 2.1 응답시스템코드 +// * 2.2 전문응답일시 +// * 2.3 응답결과구분코드 +// * 2.4 메시지발생시스템코드 +// * 2.5 메시지코드 +// * 2.6 guid 일련번호 증가 +// */ +// private static STDMessage setInternalError(STDMessage std,String errCode, String errMsg) { +// String siteErrCode = getSiteCode(errCode); +// String siteErrMessage = getSiteMessage(errCode); +// std.setMessage(siteErrCode,siteErrMessage, errMsg); +// //std.setData("systemHeader.RSPNS_SYS_CD", EAIServerManager.getInstance().getServerType().toUpperCase()); +// //std.setData("systemHeader.TLGR_RSPNS_DT", DatetimeUtil.getCurrentTimeMillis()); +// +// std.setData("stdheader.return_value",STDMessageKeys.RESPONSE_TYPE_CODE_E);//시스템오류 +//// if (STDMessageKeys.ERROR_CODE_VALUE.equals(errCode)) { +//// }else { +//// std.setData("systemHeader.RSPNS_RSLT_DVSN_CD","T");//타임아웃오류 +//// } +// //std.setData("systemHeader.MSG_GENT_SYS_CODE", EAIServerManager.getInstance().getServerType().toUpperCase()); +// //std.setData("systemHeader.MSG_CD", siteErrCode); +// std.setData("stdheader.msg_id", siteErrCode); +// std.setData("stdheader.msg_nm", siteErrMessage); +// +// return std; +// } +// +// public static ExtMessage setErrorMsg(ExtMessage ext,String errCode, String errMsg) { +// STDMessage std = (STDMessage)ext.getStdMessage(); +// std.setData("stdheader.Inter_chn", EAIServerManager.getInstance().getSystemGubun()); +// std.setData("stdheader.return_gubun", STDMessageKeys.SEND_RECV_CD_RECV); +// std.setData("stdheader.global_id",ext.getGuid()+ StringUtils.leftPad(Integer.toString(ext.getGuidSeq()), UUIDGenerator.GUID_SEQ_LENGTH,'0')); +// +// std = setInternalError(std, errCode, errMsg); +//// try { +//// std.setSTDData(null); +//// } catch (Exception e) { +//// +//// e.printStackTrace(); +//// } +// ext.setStdMessage(std); +// return toExtMessage(ext, std); +// } +// public static String getSiteCode(String oldErrCode){ +// if ("".equals(oldErrCode)){ +// return STDMessageKeys.ERROR_CODE_VALUE; +// } +// if ("RECEAIOSA777,RECEAIOHP003,RECEAIOSP004,RECEAIOTC913,RECEAIOSA010,RECEAIOEP010,RECEAIOHP010,RECEAIOSP010,RECEAIOTP010".indexOf(oldErrCode) >= 0 ){ //TIMEOUT일경우 +// return STDMessageKeys.TIMEOUT_CODE_VALUE; +// }else{ +// return STDMessageKeys.ERROR_CODE_VALUE; +// } +// } +// public static String getSiteMessage(String oldErrCode){ +// if ("".equals(oldErrCode)){ +// return "시스템오류가 발생하였습니다."; +// } +// if ("RECEAIOSA777,RECEAIOHP003,RECEAIOSP004,RECEAIOTC913,RECEAIOSA010,RECEAIOEP010,RECEAIOHP010,RECEAIOSP010,RECEAIOTP010".indexOf(oldErrCode) >= 0 ){ //TIMEOUT일경우 +// return "타임아웃오류가 발생하였습니다."; +// }else{ +// return "시스템오류가 발생하였습니다."; +// } +// } +// public static ExtMessage getParsing(Object message, String messageType) throws Exception { +// STDMessageParser parser = STDMessageParserFactory.createPaserFactory(messageType); +// STDMessage std = parser.convert(message); +// ExtMessage ext = new ExtMessage(); +// return toExtMessage(ext, std); +// } +// +// public static byte[] toJsonBytes(ExtMessage extMessage, String encode) { +// STDMessage stdMsg = (STDMessage)extMessage.getStdMessage(); +// byte[] bizData = (byte[])extMessage.getBizData()[0]; +// STDMessage resultStdMsg = (STDMessage)ExtMessageConverter.fromExtMessage(extMessage, stdMsg); +//// return resultStdMsg.toFixedBytes(bizData, encode); +// return resultStdMsg.toFixedBytes(bizData); +// } +// public static STDMessage setSTDMessageDefault(STDMessage vo, String version, String systemEnvType, String serverType, boolean isFEP,String chnlCode){ +// vo.setData("stdheader.Inter_chn", EAIServerManager.getInstance().getSystemGubun()); +//// vo.setData("stdheder.mesgVerNo", version);//버전 +////// if(isFEP){ +////// vo.setData("systemHeader.CHNL_DVSN_CD", chnlCode);//채널구분 +////// } +//// vo.setData("stdcommon.sysOprtEnvDvcd", systemEnvType);//환경정보구분 +//// //vo.setData("systemHeader.FRST_DMND_APLC_SYS_CD", serverType.toUpperCase());//최초요청어플리케이션시스템코드 +//// vo.setData("stdheader.trnmSysCd", serverType.toUpperCase());//요청시스템코드 +// return vo; +// } +//// public static String getRealHeader(ExtMessage extmessage) throws Exception { +//// STDMessage std = (STDMessage)extmessage.getStdMessage(); +//// if (std == null) return ""; +//// return std.toJSONHeaderString(); +//// } +// public static ExtMessage setTimeoutCode(ExtMessage ext,String timeoutCode) { +// STDMessage std = (STDMessage)ext.getStdMessage(); +// //std.setData("systemHeader.TMOT_CD",timeoutCode); +// ext.setStdMessage(std); +// return ext; +// } +// public static boolean validation(ExtMessage extMessage,ProcessVO vo) { +// STDMessage std = (STDMessage)extMessage.getStdMessage(); +// /** +// * eai에만 userID셋팅 에서 USERID가 없을경우 오류처리로 변경 20211013 +// */ +// String userId = std.getData("stdheader.usr_id"); +// if (StringUtils.isBlank(userId)){ +// String systemType = EAIServerManager.getInstance().getSystemType(); +// String interfaceId = std.getData("stdheader.service_id"); +// vo.setRspErrorCode("RECEAIIRP110"); +// vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), new String[]{interfaceId,"USERID"})); +// vo.setErrTypeCode(InboundErrorKeys.IN_ERROR); +// return false; +// } +// +// return true; +// } +//// public static ExtMessage setTimeForNonStandard(ExtMessage ext) { +//// STDMessage std = (STDMessage)ext.getStdMessage(); +//// //정상셋팅 +//// //표준전문이 아닐경우 +//// //전문응답일자 MESG_RSPN_DT +//// //전문응답시간 MESG_RSPN_TKTM +//// std.setData("stdcommon.mesgRspnDt",DatetimeUtil.getCurrentDate()); +//// std.setData("stdcommon.mesgRspnTktm",DatetimeUtil.getTime8()); +//// +//// ext.setStdMessage(std); +//// return ext; +//// } +// public static void convertExtMsg2STDMsg(ExtMessage extMsg ) { +// STDMessage stdmessage = (STDMessage)extMsg.getStdMessage(); +// STDMessage rstdmessage = (STDMessage) fromExtMessage(extMsg,stdmessage); +// extMsg.setStdMessage(rstdmessage); +// +// } +// public static ExtMessage convertSTDMsg2ExtMsg(ExtMessage extMsg ) { +// STDMessage stdmessage = (STDMessage)extMsg.getStdMessage(); +// ExtMessage extMessage = toExtMessage(extMsg,stdmessage); +// return extMessage; +// } +// +// /** +// * 하나캐피탈 POC 표준전문 전용 +// * @param extMsg +// */ +// public static void setStdGuid(ExtMessage extMsg) { +// try { +// ((STDMessage) extMsg.getStdMessage()).setData("stdheader.global_id", extMsg.getGuid() +// + StringUtils.leftPad(Integer.toString(extMsg.getGuidSeq()), UUIDGenerator.GUID_SEQ_LENGTH, '0')); +// } catch (Exception e) { +// logger.error(e.getMessage()); +// } +// } +//} diff --git a/src/main/java/com/eactive/eai/common/stdmessage/OtptMdclVO.java b/src/main/java/com/eactive/eai/common/stdmessage/OtptMdclVO.java new file mode 100644 index 0000000..8320dab --- /dev/null +++ b/src/main/java/com/eactive/eai/common/stdmessage/OtptMdclVO.java @@ -0,0 +1,24 @@ +package com.eactive.eai.common.stdmessage; + +import org.json.simple.JSONObject; + +public class OtptMdclVO{ + private String interfaceId; + private JSONObject otptMdclDat; + public OtptMdclVO(String interfaceId, JSONObject otptMdclDat) { + this.interfaceId = interfaceId; + this.otptMdclDat = otptMdclDat; + } + public String getInterfaceId() { + return interfaceId; + } + public void setInterfaceId(String interfaceId) { + this.interfaceId = interfaceId; + } + public JSONObject getOtptMdclDat() { + return otptMdclDat; + } + public void setOtptMdclDat(JSONObject otptMdclDat) { + this.otptMdclDat = otptMdclDat; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java new file mode 100644 index 0000000..8b8c320 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageDAO.java @@ -0,0 +1,227 @@ +package com.eactive.eai.common.stdmessage; + +import java.sql.ResultSet; +import java.util.HashMap; +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.stdmessage.loader.StandardMessageInfoLoader; +import com.eactive.eai.common.stdmessage.loader.StandardMessageRestoreService; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageInfo; +import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageItem; +import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageRestore; +import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageRestoreId; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.ReaderType; +import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.message.service.InterfaceMapper; + +@Service +@Transactional +public class STDMessageDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private StandardMessageInfoLoader standardMessageInfoLoader; + + @Autowired + private StandardMessageRestoreService standardMessageRestoreService; + + public HashMap getAllSTDMessages() throws DAOException { + HashMap all = new HashMap<>(); + + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardMessage vo = null; + InterfaceMapper mapper = standardManager.getMapper(); + + try { + List list = standardMessageInfoLoader.findAll(); + for (StandardMessageInfo info : list) { + vo = standardManager.getStandardMessage(); + vo.setServiceKey(info.getBzwksvckeyname()); + // TODO + // to be defined... + mapper.setInterfaceId(vo, info.getEaitranname()); + mapper.setSendRecvDivision(vo, info.getEaisendrecv()); // S | R + mapper.setInExDivision(vo, info.getEaidirection()); // 1 | 2 + List items = info.getStandardMessageItems(); + for (StandardMessageItem item : items) { + vo.setData(item.getId().getColumnname(), item.getColumnvalue()); + } + all.put(vo.getServiceKey(), vo); + } + return all; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE102"), e); + } + } + + public StandardMessage getSTDMessage(String serviceKey) throws DAOException { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + try { + Optional optional = standardMessageInfoLoader.findById(serviceKey); + if (optional.isPresent()) { + StandardMessageInfo info = optional.get(); + StandardMessage vo = standardManager.getStandardMessage(); + vo.setServiceKey(info.getBzwksvckeyname()); + + InterfaceMapper mapper = standardManager.getMapper(); + mapper.setInterfaceId(vo, info.getEaitranname()); + mapper.setSendRecvDivision(vo, info.getEaisendrecv()); // S | R + mapper.setInExDivision(vo, info.getEaidirection()); // 1 | 2 + + List items = info.getStandardMessageItems(); + for (StandardMessageItem item : items) { + vo.setData(item.getId().getColumnname(), item.getColumnvalue()); + } + return vo; + } else { + throw new DAOException("RECEAICKE110"); + } + } catch (DAOException e) { + throw e; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE111")); + } + } + + // -------------------------------------------------------------------- + // STD 표준메시지헤더 복원 관련 Methods + // -------------------------------------------------------------------- + + // 내부표준헤더 복원정보를 저장 + public void addRestoreMessage(String applCd, String traceKey, String flatMessage) throws DAOException { + + try { + StandardMessageRestore entity = new StandardMessageRestore(); + StandardMessageRestoreId id = new StandardMessageRestoreId(); + id.setNwuapplcd(applCd); + id.setKeymgtmsgctnt(traceKey); + entity.setId(id); + entity.setMsghdrctnt(flatMessage); + standardMessageRestoreService.save(entity); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE118")); + } + } + + public void addRestoreSTDMessage(String applCd, String keyMgtMsgCtnt, StandardMessage stdmessage) + throws DAOException { + try { + addRestoreMessage(applCd, keyMgtMsgCtnt, stdmessage.toFixedString(false)); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE118")); + } + } + + public void updateRestoreMessage(String applCd, String traceKey, String flatMessage) throws DAOException { + try { + StandardMessageRestoreId id = new StandardMessageRestoreId(); + id.setNwuapplcd(applCd); + id.setKeymgtmsgctnt(traceKey); + + Optional optional = standardMessageRestoreService.findById(id); + if (optional.isPresent()) { + StandardMessageRestore entity = optional.get(); + entity.setMsghdrctnt(flatMessage); + } else { + StandardMessageRestore entity = new StandardMessageRestore(); + entity.setId(id); + entity.setMsghdrctnt(flatMessage); + standardMessageRestoreService.save(entity); + } + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE118")); + } finally { + this.disconnect(); + } + } + + // 내부표준헤더 복원정보를 저장 + public void updateRestoreSTDMessage(String applCd, String keyMgtMsgCtnt, StandardMessage stdmessage) + throws DAOException { + try { + updateRestoreMessage(applCd, keyMgtMsgCtnt, stdmessage.toFixedString(false)); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE118")); + } + } + + public StandardMessage getRestoreSTDMessage(String applCd, String keyMgtMsgCtnt) throws DAOException { + ResultSet rs = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + try { + StandardMessage standardMessage = new StandardMessage(); + + StandardMessageRestoreId id = new StandardMessageRestoreId(); + id.setNwuapplcd(applCd); + id.setKeymgtmsgctnt(keyMgtMsgCtnt); + + Optional optional = standardMessageRestoreService.findById(id); + if (optional.isPresent()) { + StandardMessageRestore entity = optional.get(); + String headerString = entity.getMsghdrctnt(); + StandardReader parser = standardManager.getReader(ReaderType.FLAT); + if (parser == null) { + throw new Exception("STDMessageParser not found - " + ReaderType.FLAT); + } + parser.parse(standardMessage, headerString); + return standardMessage; + } else { + throw new Exception("Can not find stored StandardMessage [applCd=" + applCd + ", keyMgtMsgCtnt=" + + keyMgtMsgCtnt + "]"); + } + } catch (DAOException e) { + throw e; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE111")); + } + } + + public void deleteRestoreSTDMessage(String applCd, String keyMgtMsgCtnt) throws DAOException { + try { + StandardMessageRestoreId id = new StandardMessageRestoreId(); + id.setNwuapplcd(applCd); + id.setKeymgtmsgctnt(keyMgtMsgCtnt); + standardMessageRestoreService.deleteById(id); + } catch (Exception e) { + try { + this.conn.rollback(); + } catch (Exception ex) { + logger.error("rollback error", ex); + } + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE114")); + } + } + + public String getRestoreMessage(String applCd, String keyMgtMsgCtnt) throws DAOException { + try { + StandardMessageRestoreId id = new StandardMessageRestoreId(); + id.setNwuapplcd(applCd); + id.setKeymgtmsgctnt(keyMgtMsgCtnt); + + Optional optional = standardMessageRestoreService.findById(id); + if (optional.isPresent()) { + StandardMessageRestore entity = optional.get(); + String headerString = entity.getMsghdrctnt(); + return headerString; + } else { + throw new Exception("Can not find stored StandardMessage [applCd=" + applCd + ", keyMgtMsgCtnt=" + + keyMgtMsgCtnt + "]"); + } + } catch (DAOException e) { + throw e; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE111")); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageManager.java b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageManager.java new file mode 100644 index 0000000..08d440d --- /dev/null +++ b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageManager.java @@ -0,0 +1,179 @@ +package com.eactive.eai.common.stdmessage; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.AntPathMatcher; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ObjectUtil; +import com.eactive.eai.message.StandardMessage; + +@Component +public class STDMessageManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + STDMessageDAO sTDMessageDAO; + + private HashMap headers = new HashMap<>(); + private HashMap headersForPathVariables = new HashMap<>(); + + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + public static STDMessageManager getInstance() { + return ApplicationContextProvider.getContext().getBean(STDMessageManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICKE201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICKE202")); + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + headers = sTDMessageDAO.getAllSTDMessages(); + headersForPathVariables.clear(); + for (Map.Entry entry : headers.entrySet()) { + if (isPathVariable(entry.getKey())) { + headersForPathVariables.put(entry.getKey(), entry.getValue()); + } + } + } + + public static boolean isPathVariable(String key) { + return StringUtils.containsAny(key, '*', '{', '?'); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("STDMessageManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("STDMessageManager] reload all finished ..."); + } + } + + public synchronized void reload(String keyName) throws Exception { + StandardMessage msg = sTDMessageDAO.getSTDMessage(keyName); + if (msg != null) { + headers.put(keyName, msg); + if (isPathVariable(keyName)) { + headersForPathVariables.put(keyName, msg); + } + } else { + throw new Exception("STDMessage not found in Database : key[" + keyName + "]"); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICKE203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public boolean isStarted() { + return this.started; + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public StandardMessage getSTDMessage(String bwkSvcKey) { + StandardMessage stdmessage = (StandardMessage) headers.get(bwkSvcKey); + try { + if (stdmessage != null) { + stdmessage = (StandardMessage) stdmessage.clone(); + } + return stdmessage; + } catch (Exception e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAIEMM204")); + } + } + + public StandardMessage getSTDMessageForPathVariable(String bwkSvcKey) { + String matchedKey = getMatchedPathVariable(bwkSvcKey); + if (matchedKey != null) { + return getSTDMessage(matchedKey); + } else { + return null; + } + } + + public String getMatchedPathVariable(String bwkSvcKey) { + AntPathMatcher matcher = new AntPathMatcher(); + for (String key : headersForPathVariables.keySet()) { + if (matcher.match(key, bwkSvcKey)) { + return key; + } + } + return null; + } + + public String[] getAllSTDMessageKeys() { + String[] ks = new String[this.headers.size()]; + Iterator it = this.headers.keySet().iterator(); + for (int i = 0; it.hasNext(); i++) { + ks[i] = (String) it.next(); + } + Arrays.sort(ks); + return ks; + } + + public ArrayList getAllSTDMessages() { + ArrayList al = new ArrayList<>(); + Iterator it = this.headers.values().iterator(); + while (it.hasNext()) { + al.add(it.next()); + } + return al; + } + + public void addSTDMessage(StandardMessage msg) { + this.headers.put(msg.getServiceKey(), msg); + + if (isPathVariable(msg.getServiceKey())) { + headersForPathVariables.put(msg.getServiceKey(), msg); + } + } + + public synchronized void removeSTDMessage(String bwkSvcKey) { + this.headers.remove(bwkSvcKey); + this.headersForPathVariables.remove(bwkSvcKey); + } +} diff --git a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageMapper.java b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageMapper.java new file mode 100644 index 0000000..562d174 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageMapper.java @@ -0,0 +1,91 @@ +package com.eactive.eai.common.stdmessage; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.session.SessionManager; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.parser.ReaderType; + +public class STDMessageMapper { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public STDMessageMapper() { + super(); + } + + public static void storeMessageHeader(String traceKey, StandardMessage standardMessage, String extBizCd, String type) + throws Exception { + try { + if(ElinkConfig.isUseCacheStore()) { + String key = extBizCd + traceKey; + String flatMessage = null; + if (ReaderType.ASC.equals(type)) { + flatMessage = standardMessage.toFixedString(false); + }else if (ReaderType.JSON.equals(type)) { + flatMessage = standardMessage.toJson(false,false); + }else if (ReaderType.XML.equals(type)) { + flatMessage = standardMessage.toXML(); + } + SessionManager.getInstance().putCacheStore(key, flatMessage); + if (logger.isWarn()) { + logger.warn("STDMessageMapper] putCacheStore Key[" + key + "] value[" + flatMessage + "]"); + } + } + else { + STDMessageDAO dao = ApplicationContextProvider.getContext().getBean(STDMessageDAO.class); + String applCd = extBizCd; + String flatMessage = null; + if (ReaderType.ASC.equals(type)) { + flatMessage = standardMessage.toFixedString(false); + }else if (ReaderType.JSON.equals(type)) { + flatMessage = standardMessage.toJson(false,false); + }else if (ReaderType.XML.equals(type)) { + flatMessage = standardMessage.toXML(); + } + + boolean duplicate = false; + try { + dao.addRestoreMessage(applCd, traceKey, flatMessage); + } catch (Exception ex) { + duplicate = true; + if (logger.isWarn()) { + logger.warn("STDMessageMapper] Duplicate Key[" + traceKey + "] update STDMessage"); + } + } + if (duplicate) { + dao.updateRestoreMessage(applCd, traceKey, flatMessage); + } + } + } catch (DAOException e) { + throw new Exception("STDMessageMapper.storeMessageHeader Error - " + e.getMessage()); + } + } + + public static String getStoredMessageFixedHeader(String traceKey, String applCd) throws Exception { + try { + String message = null; + if(ElinkConfig.isUseCacheStore()) { + String key = applCd + traceKey; + message = SessionManager.getInstance().getCacheStore(key); + // String 객체를 생성해서 전달되므로 삭제해도 가능함. + SessionManager.getInstance().removeCacheStore(key); + if (logger.isWarn()) { + logger.warn("STDMessageMapper] get & remove CacheStore Key[" + key + "]"); + } + } + else { + STDMessageDAO dao = ApplicationContextProvider.getContext().getBean(STDMessageDAO.class); + message = dao.getRestoreMessage(applCd, traceKey); + } + + if (message == null) { + throw new Exception("복원헤더 조회 중 에러(NotFound), Keys (applCd=" + applCd + ",traceKey=" + traceKey + ")"); + } + return message; + } catch (DAOException e) { + throw new Exception("STDMessageMapper.getStoredMessageFixedHeader Error - " + e.getMessage()); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/stdmessage/STDMessageUtil.java b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageUtil.java new file mode 100644 index 0000000..820277e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/stdmessage/STDMessageUtil.java @@ -0,0 +1,113 @@ +//package com.ext.eai.common.stdmessage; +// +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.util.Logger; +//import com.eactive.eai.transformer.TransformService; +// +///** +//* 1. 기능 : KB 표준전문을 파싱하고 KESA 전문과 매핑하는 기능을 제공 +//* 2. 처리 개요 : KB 표준 XML/전문 파싱, KESA 전문과 변환 +//* 3. 주의사항 : KB 표준전문 변경에 따라 수정되어야 함 +//* +//* @author : dhlee +//* @version : v 1.0.0 +//* @see : KBMessageKeys +//* @since : +//* : +//*/ +//public class STDMessageUtil implements STDMessageKeys { +// /** +// * Default Logger +// */ +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// /** +// * +// */ +// public STDMessageUtil() { +// super(); +// } +// +// public static boolean checkCard(String code) { +// boolean isCard = false; +// +// if(code == null || code.length() < 2) { +// return false; +// } +// +// char c = code.charAt(1); +// if(c >= '0' && c<='9') { +// isCard = true; +// } +// return isCard; +// } +// +// // 2009.09.09 강길수 차장 +// // 입력매체부 변환을 위한 함수로 변환기능을 통해 한글변환처리를 위해 사용됨 +// public static byte[] transformMediaData(String telgmDmndDstcd, String chnlDstcd, byte[] mediaData, +// String sendEaiSvcCd, String relayChnlCd, String inoPartlDstcd, String chnlDBzwkDstcd, +// String iscSendSysid) throws Exception { +// byte[] resMediaData = null; +// Object[] sources = new Object[1]; +// boolean isReq = true; +// sources[0] = mediaData; +// String transformName = null; +// String propName = ""; +// +// // 일반거래 : S01, S02, S03, S03A6, S04, S06 (ASCII -> EBCDIC) +// // ISC거래 : S0107, S0207, S0307, S03A607, S0407 (EBCDIC -> ASCII) +// if("S".equals(telgmDmndDstcd)) { +// isReq = true; +// propName = telgmDmndDstcd + chnlDstcd; +// +// // 인뱅 오픈API +// if("03".equals(chnlDstcd) && "A6".equals(chnlDBzwkDstcd)) { +// propName = propName + chnlDBzwkDstcd; +// } +// +// if(relayChnlCd.equals("07") && inoPartlDstcd.equals("2")){ // 은행카드 간 ISC 대응거래 처리 (ISC & 카드로 송신) 2018.07.31 +// propName = propName + relayChnlCd; +// } +// else if(relayChnlCd.equals("07") && checkCard(iscSendSysid) ){ // 카드기동 ISC거래일 경우 +// propName = propName + relayChnlCd + "C"; +// } +// } +// // 일반거래 : R (EBCDIC -> ASCII) +// // ISC거래 : R07 (ASCII -> EBCDIC) +// else { +// isReq = false; +// propName = telgmDmndDstcd; +// if(relayChnlCd.equals("07") & inoPartlDstcd.equals("1")){ // 은행카드 간 ISC 대응거래 처리 (ISC & 은행으로 송신) 2018.07.31 +// propName = propName + relayChnlCd; +// } +// } +// +// if(logger.isInfo()) { +// logger.info("KBMessageUtil] telgmDmndDstcd ["+telgmDmndDstcd+"] chnlDstcd ["+chnlDstcd+ +// "] relayChnlCd ["+relayChnlCd+"] iscSendSysid ["+iscSendSysid+"] propName ["+propName+"]"); +// } +// +// PropManager propManager = PropManager.getInstance(); +// +// transformName = propManager.getProperty("KBMESSAGE_MEDIA_TRANSFORM", propName); +// if(transformName != null) { +// Object resObject = TransformService.transform("KBMessage", isReq, transformName, sources); +// if(resObject instanceof byte[]) { +// resMediaData = (byte[])resObject; +// } +// else if(resObject instanceof String) { +// resMediaData = ((String)resObject).getBytes(); +// } +// else { +// logger.warn("KBMessageUtil] 변환결과가 전문이 아닙니다. 변환등록정보확인 필요 ["+transformName+"]"); +// throw new Exception("변환결과가 전문이 아닙니다. 변환등록정보확인 필요 ["+transformName+"]"); +// } +// } +// else { +// logger.warn("KBMessageUtil] 프라퍼티에 매체부 변환이 등록되지 않았습니다. : 프라퍼티 그룹[KBMESSAGE_MEDIA_TRANSFORM] 프라퍼티 키 ["+propName+"]"); +// throw new Exception("프라퍼티에 매체부 변환이 등록되지 않았습니다. : 프라퍼티 그룹[KBMESSAGE_MEDIA_TRANSFORM] 프라퍼티 키 ["+propName+"]"); +// } +// +// return resMediaData; +// } +//} diff --git a/src/main/java/com/eactive/eai/common/submessage/SubMessageDAO.java b/src/main/java/com/eactive/eai/common/submessage/SubMessageDAO.java new file mode 100644 index 0000000..bfb73e0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/submessage/SubMessageDAO.java @@ -0,0 +1,68 @@ +package com.eactive.eai.common.submessage; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.submessage.loader.SubMessageInfoLoader; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.submessage.SubMessageInfo; +import com.eactive.eai.data.entity.onl.submessage.SubMessageItem; + +@Service +@Transactional +public class SubMessageDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private SubMessageInfoLoader subMessageInfoLoader; + + public Map> getAllSubMessages() throws DAOException { + HashMap> all = new HashMap<>(); + try { + List list = subMessageInfoLoader.selectAll(); + for (SubMessageInfo info : list) { + String key =info.getBzwksvckeyname(); + List items = info.getSubMessageItems(); + HashMap map = new HashMap<>(); + for (SubMessageItem item : items) { + map.put(item.getId().getColumnname(), item.getColumnvalue()); + } + all.put(key, map); + } + return all; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE102"), e); + } + } + + public Map getSubMessage(String serviceKey) throws DAOException { + try { + Optional optional = subMessageInfoLoader.findById(serviceKey); + if (optional.isPresent()) { + SubMessageInfo info = optional.get(); + + List items = info.getSubMessageItems(); + HashMap map = new HashMap<>(); + for (SubMessageItem item : items) { + map.put(item.getId().getColumnname(), item.getColumnvalue()); + } + return map; + } else { + throw new DAOException("RECEAICKE110"); + } + } catch (DAOException e) { + throw e; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICKE111")); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/submessage/SubMessageManager.java b/src/main/java/com/eactive/eai/common/submessage/SubMessageManager.java new file mode 100644 index 0000000..e050249 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/submessage/SubMessageManager.java @@ -0,0 +1,121 @@ +package com.eactive.eai.common.submessage; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class SubMessageManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + SubMessageDAO subMessageDAO; + + private ConcurrentHashMap> headers = new ConcurrentHashMap<>(); + + + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + public static SubMessageManager getInstance() { + return ApplicationContextProvider.getContext().getBean(SubMessageManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICKE201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + try { + if (logger.isDebug()) { + logger.warn("SubMessageManager] reload all Started ..."); + } + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICKE202")); + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + HashMap> map = (HashMap>) subMessageDAO.getAllSubMessages(); + headers = new ConcurrentHashMap<> (map); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("SubMessageManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("SubMessageManager] reload all finished ..."); + } + } + + public synchronized void remove(String bwkSvcKey) { + this.headers.remove(bwkSvcKey); + } + + public synchronized void reload(String keyName) throws Exception { + HashMap map = (HashMap) subMessageDAO.getSubMessage(keyName); + if (map != null) { + headers.put(keyName, map); + } else { + throw new Exception("SubMessage not found in Database : key[" + keyName + "]"); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICKE203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public boolean isStarted() { + return this.started; + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public Map getSubMessageMap(String bwkSvcKey) { + return headers.get(bwkSvcKey); + } + + public String[] getAllSubMessageKeys() { + String[] ks = new String[this.headers.size()]; + Iterator it = this.headers.keySet().iterator(); + for (int i = 0; it.hasNext(); i++) { + ks[i] = (String) it.next(); + } + Arrays.sort(ks); + return ks; + } +} diff --git a/src/main/java/com/eactive/eai/common/sysdomain/SysDomainDAO.java b/src/main/java/com/eactive/eai/common/sysdomain/SysDomainDAO.java new file mode 100644 index 0000000..9ad7e43 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sysdomain/SysDomainDAO.java @@ -0,0 +1,54 @@ +package com.eactive.eai.common.sysdomain; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.sysdomain.loader.SysDomainLoader; +import com.eactive.eai.common.sysdomain.mapper.SysDomainMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.sysdomain.SysDomain; + +@Service +@Transactional +public class SysDomainDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private SysDomainLoader sysDomainLoader; + + @Autowired + private SysDomainMapper sysDomainMapper; + + public List getAllSysDomains() throws DAOException { + try { + List list = sysDomainLoader.findAll(); + List volist = new ArrayList<>(); + list.forEach(e -> volist.add(sysDomainMapper.toVo(e))); + return volist; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICSD101")); + } + } + + public SysDomainVO getSysDomain(String sysDomainNm) throws DAOException { + try { + Optional entity = sysDomainLoader.findById(sysDomainNm); + SysDomainVO vo = null; + if (entity.isPresent()) { + vo = sysDomainMapper.toVo(entity.get()); + } + return vo; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICSD103")); + } + } + +} diff --git a/src/main/java/com/eactive/eai/common/sysdomain/SysDomainVO.java b/src/main/java/com/eactive/eai/common/sysdomain/SysDomainVO.java new file mode 100644 index 0000000..e2710b8 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sysdomain/SysDomainVO.java @@ -0,0 +1,26 @@ +package com.eactive.eai.common.sysdomain; + +import com.eactive.eai.common.util.NullControl; + +import java.io.Serializable; + +public class SysDomainVO implements Serializable { + private String sysDomainNm; // 시스템도메인명[TSEAISY01.SysDomnName] + private String sysDomainDesc; // 시스템도메인설명[TSEAISY01.SysDomnDesc] + + public void setSysDomainNm(String sysDomainNm) { + this.sysDomainNm = sysDomainNm; + } + + public String getSysDomainNm() { + return this.sysDomainNm; + } + + public void setSysDomainDesc(String sysDomainDesc) { + this.sysDomainDesc = sysDomainDesc; + } + + public String getSysDomainDesc() { + return NullControl.trimSpace(this.sysDomainDesc); + } +} diff --git a/src/main/java/com/eactive/eai/common/sysdomain/mapper/SysDomainMapper.java b/src/main/java/com/eactive/eai/common/sysdomain/mapper/SysDomainMapper.java new file mode 100644 index 0000000..281ac0b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/sysdomain/mapper/SysDomainMapper.java @@ -0,0 +1,17 @@ +package com.eactive.eai.common.sysdomain.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.sysdomain.SysDomainVO; +import com.eactive.eai.data.entity.onl.sysdomain.SysDomain; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface SysDomainMapper extends GenericMapper { + @Mapping(source = "sysdomnname", target = "sysDomainNm") + @Mapping(source = "sysdomndesc", target = "sysDomainDesc") + @Override + SysDomainVO toVo(SysDomain entity); +} diff --git a/src/main/java/com/eactive/eai/common/tas/TASUtil.java b/src/main/java/com/eactive/eai/common/tas/TASUtil.java new file mode 100644 index 0000000..01ce84b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/tas/TASUtil.java @@ -0,0 +1,44 @@ +package com.eactive.eai.common.tas; + +public class TASUtil { + private static int TAS_HEADER_LENGTH = 3; + + public static byte[] removeTasHeader(byte[] srcBytes) { + if (srcBytes == null) { + return null; + } + byte[] result = new byte[srcBytes.length - TAS_HEADER_LENGTH]; + System.arraycopy(srcBytes, 3, result, 0, result.length); + return result; + } + + public static byte[] addTasHeader(byte[] srcBytes, String bizCode) { + if (srcBytes == null) { + return null; + } + byte[] result = new byte[srcBytes.length + TAS_HEADER_LENGTH]; + System.arraycopy(bizCode.getBytes(), 0, result, 0, TAS_HEADER_LENGTH); + System.arraycopy(srcBytes, 0, result, TAS_HEADER_LENGTH, srcBytes.length); + return result; + } + + public static String getTasHeader(byte[] srcBytes) { + if (srcBytes == null) { + return null; + } + return new String((byte[])srcBytes,0,TAS_HEADER_LENGTH); + + } + +// public static void main(String[] argv) { +// String bizCode = ""; +// byte[] message = "ABC1234567890".getBytes(); +// +// bizCode = getTasHeader(message); +// message = removeTasHeader(message); +// +// System.out.println(bizCode + ":" +new String(message)); +// +// System.out.println(new String(addTasHeader(message, bizCode)) ); +// } +} diff --git a/src/main/java/com/eactive/eai/common/testcall/TestCall.java b/src/main/java/com/eactive/eai/common/testcall/TestCall.java new file mode 100644 index 0000000..7b2fcd2 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/testcall/TestCall.java @@ -0,0 +1,15 @@ +package com.eactive.eai.common.testcall; + +import com.eactive.eai.adapter.AdapterVO; + +/* +* TestCallRunner가 일정 주기로 TestCall의 isAlive() 메서드를 실행하여 결과가 true일 경우 해당 어댑터의 상태를 true로 변경한다. +* Recovery 통신 테스트 로직을 isAlive() 메서드에 구현한다. +*/ +public interface TestCall { + public AdapterVO getAdapterInfo(); + + public void setAdapterInfo(AdapterVO adapterInfo); + + public boolean isAlive() throws TestCallException; +} diff --git a/src/main/java/com/eactive/eai/common/testcall/TestCallException.java b/src/main/java/com/eactive/eai/common/testcall/TestCallException.java new file mode 100644 index 0000000..0bb5149 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/testcall/TestCallException.java @@ -0,0 +1,17 @@ +package com.eactive.eai.common.testcall; + +public class TestCallException extends Exception { + private static final long serialVersionUID = 1L; + + public TestCallException() { + super("TestCallException is occured."); + } + + public TestCallException(String msg) { + super(msg); + } + + public TestCallException(String msg, Throwable t) { + super(msg, t); + } +} diff --git a/src/main/java/com/eactive/eai/common/testcall/TestCallManager.java b/src/main/java/com/eactive/eai/common/testcall/TestCallManager.java new file mode 100644 index 0000000..2fbd2cb --- /dev/null +++ b/src/main/java/com/eactive/eai/common/testcall/TestCallManager.java @@ -0,0 +1,167 @@ +package com.eactive.eai.common.testcall; + +import java.util.Iterator; +import java.util.Timer; +import java.util.concurrent.ConcurrentHashMap; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; + +public class TestCallManager implements Lifecycle { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static final String PROP_GROUP = "TestCallManager"; + + // TestCallManager에서 사용하는 Property Key : TestCallRunner의 동작 주기 + public static final String PROP_PERIOD = "testcall.runner.period"; + + // TestCallManager에서 사용하는 Property Key : TestCallRunner의 응답 타입 + public static final String RESPONSE_TYPE = "RESPONSE_TYPE"; + + // TestCallManager에서 사용하는 Property Key : TestCallRunner의 HTTP 응답 타임 아웃 + public static final String HTTP_TIME_OUT = "HTTP_TIME_OUT"; + + // TestCallManager에서 사용하는 Property Key : TestCallRunner의 HTTP 접속 타임 아웃 + public static final String CONNECTION_TIMEOUT = "CONNECTION_TIMEOUT"; + + /** + * TestCallManager에서 사용하는 Property Key : TestCallRunner의 TESTCALL 여부 "Y" 이면 테스트콜 + * 거래 로그 안찍힘 "N" 면 테스트콜 거래 로그 찍힘 + */ + public static final String TESTCALL_YN = "TESTCALL_YN"; + + // TestCallManager에서 사용하는 Property Key : TestCallRunner의 요청 메시지 + public static final String REQUEST_MESSAGE = "REQUEST_MESSAGE"; + + // TestCallManager에서 사용하는 Property Key : TestCallRunner의 응답 메시지 + public static final String RESPONSE_MESSAGE = "RESPONSE_MESSAGE"; + + private static TestCallManager manager = new TestCallManager(); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private boolean started; + + private ConcurrentHashMap testers = new ConcurrentHashMap<>(); + + private TestCallRunner runner; + + private Timer timer; + + public static TestCallManager getInstance() { + return manager; + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICTM001"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + PropManager pmanager = PropManager.getInstance(); + // default 10 mins + long period = 1000 * 600; + try { + period = Long.parseLong(pmanager.getProperty(PROP_GROUP, PROP_PERIOD)); + } catch (Exception e) { + logger.info("PROP_PERIOD not number"); + } + + this.runner = new TestCallRunner(); + this.runner.setTestCallManager(this); + + this.timer = new Timer("TestCallTimer"); + this.timer.schedule(this.runner, period, period); + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICTM002"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + this.timer.cancel(); + this.timer = null; + this.runner = null; + + if (this.testers != null) { + this.testers.clear(); + this.testers = null; + } + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, null); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public void addTester(AdapterVO vo) throws TestCallException { + if (vo.getTestCallClass() == null) + throw new TestCallException("RECEAICTM005"); + Class tclass = null; + + if (!started) { + logger.error("TesterManager] TesterManager is stopped"); + } + + try { + tclass = Class.forName(vo.getTestCallClass()); + } catch (Exception e) { + logger.error("TesterManager] addTester Error. [" + vo.getAdapterGroupName() + "][" + vo.getName() + "][" + + vo.getTestCallClass() + "]", e); + throw new TestCallException(ExceptionUtil.getErrorCode(e, "RECEAICTM003"), e); + } + + try { + TestCall tester = (TestCall) tclass.newInstance(); + tester.setAdapterInfo(vo); + if (this.testers != null && vo != null) { + this.testers.put(vo.getAdapterGroupName() + "-" + vo.getName(), tester); + } + } catch (Exception e) { + logger.error("TesterManager] addTester Error. [" + vo.getAdapterGroupName() + "][" + vo.getName() + "][" + + vo.getTestCallClass() + "]", e); + throw new TestCallException(ExceptionUtil.getErrorCode(e, "RECEAICTM004")); + } + } + + public Iterator getAllAdapterNames() { + ConcurrentHashMap map = new ConcurrentHashMap<>(testers); + return map.keySet().iterator(); + } + + public TestCall getTestCall(String adapterName) { + return this.testers.get(adapterName); + } + + public void removeTestCall(String adapterName) { + this.testers.remove(adapterName); + } + + public int getTestCallCount() { + return this.testers.size(); + } +} diff --git a/src/main/java/com/eactive/eai/common/testcall/TestCallRunner.java b/src/main/java/com/eactive/eai/common/testcall/TestCallRunner.java new file mode 100644 index 0000000..002692e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/testcall/TestCallRunner.java @@ -0,0 +1,68 @@ +package com.eactive.eai.common.testcall; + +import java.util.Iterator; +import java.util.TimerTask; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.errorcode.ErrorCodeHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; + +public class TestCallRunner extends TimerTask { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private TestCallManager manager; + + // TestCallRunner 동작 시 INFO 메시지에 대한 코드 + private static final String START_MSGCODE = "RICEAICTR001"; + // TestCallRunner 동작 시 발생되는 오류에 대한 코드 + private static final String ERROR_MSGCODE = "RECEAICTR002"; + + public void setTestCallManager(TestCallManager manager) { + this.manager = manager; + } + + public void run() { + String msg = ErrorCodeHandler.getMessage(START_MSGCODE, new String[] { Thread.currentThread().getName() }); + logger.warn("TestCallRunner] " + msg); + + if (this.manager == null || !this.manager.isStarted()) { + logger.warn("TestCallManager is stopped. stop TestCallRunner."); + return; + } + + Iterator adapterNames = manager.getAllAdapterNames(); + + ExecutorService executor = Executors.newFixedThreadPool(10); + try { + while (adapterNames.hasNext()) { + String name = adapterNames.next(); + TestCall testObj = manager.getTestCall(name); + AdapterVO vo = testObj.getAdapterInfo(); + if (testObj == null || vo.isStatus()) { + manager.removeTestCall(name); + continue; + } + + executor.submit(() -> { + try { + if (testObj.isAlive()) { + manager.removeTestCall(name); + vo.setStatus(true); + } + } catch (Exception e) { + String[] args = { testObj.getAdapterInfo().toString(), e.getMessage() }; + if (logger.isError()) { + logger.error(ExceptionUtil.make(ERROR_MSGCODE, args), e); + } + } + }); + } + } + finally { + executor.shutdown(); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/testcall/TestCallSupport.java b/src/main/java/com/eactive/eai/common/testcall/TestCallSupport.java new file mode 100644 index 0000000..e0bc46a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/testcall/TestCallSupport.java @@ -0,0 +1,19 @@ +package com.eactive.eai.common.testcall; + +import com.eactive.eai.adapter.AdapterVO; + +public class TestCallSupport implements TestCall { + protected AdapterVO adapterInfo; + + public boolean isAlive() throws TestCallException { + return false; + } + + public void setAdapterInfo(AdapterVO adapterInfo) { + this.adapterInfo = adapterInfo; + } + + public AdapterVO getAdapterInfo() { + return this.adapterInfo; + } +} diff --git a/src/main/java/com/eactive/eai/common/unifbwk/UnifBwkTpDAO.java b/src/main/java/com/eactive/eai/common/unifbwk/UnifBwkTpDAO.java new file mode 100644 index 0000000..83ae298 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/unifbwk/UnifBwkTpDAO.java @@ -0,0 +1,53 @@ +package com.eactive.eai.common.unifbwk; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.unifbwk.loader.UnifBwkTpLoader; +import com.eactive.eai.common.unifbwk.mapper.UnifBwkTpMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.unifbwk.UnifBwkTp; + +@Service +@Transactional +public class UnifBwkTpDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private UnifBwkTpLoader unifBwkTpLoader; + + @Autowired + private UnifBwkTpMapper unifBwkTpMapper; + + public List getAllUnifBwkTp() throws DAOException { + try { + List list = unifBwkTpLoader.findAll(); + List volist = new ArrayList<>(); + list.forEach(e -> volist.add(unifBwkTpMapper.toVo(e))); + return volist; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICUB101")); + } + } + + public UnifBwkTpVO getUnifBwkTp(String bwkClsCd) throws DAOException { + try { + Optional entity = unifBwkTpLoader.findById(bwkClsCd); + UnifBwkTpVO vo = null; + if (entity.isPresent()) { + vo = unifBwkTpMapper.toVo(entity.get()); + } + return vo; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICUB103")); + } + } +} diff --git a/src/main/java/com/eactive/eai/common/unifbwk/UnifBwkTpVO.java b/src/main/java/com/eactive/eai/common/unifbwk/UnifBwkTpVO.java new file mode 100644 index 0000000..bb31aef --- /dev/null +++ b/src/main/java/com/eactive/eai/common/unifbwk/UnifBwkTpVO.java @@ -0,0 +1,51 @@ +package com.eactive.eai.common.unifbwk; + +import java.io.Serializable; + +public class UnifBwkTpVO implements Serializable { + private String bwkClsCd; // EAI업무그룹코드[TSEAICM01.EAIBzwkDstcd] + private String bwkGrpNm; // 업무구분명[TSEAICM01.BzwkDstinName] + private String bwkGrpDesc; // 업무구분설명[TSEAICM01.BzwkDstinDesc] + private String trackAsisKey1Name; // 추적보조키1명[TSEAICM01.TrackAsisKey1Name] + private String trackAsisKey2Name; // 추적보조키2명[TSEAICM01.TrackAsisKey2Name] + + public void setBwkClsCd(String bwkClsCd) { + this.bwkClsCd = bwkClsCd; + } + + public String getBwkClsCd() { + return this.bwkClsCd; + } + + public void setBwkGrpNm(String bwkGrpNm) { + this.bwkGrpNm = bwkGrpNm; + } + + public String getBwkGrpNm() { + return this.bwkGrpNm; + } + + public void setBwkGrpDesc(String bwkGrpDesc) { + this.bwkGrpDesc = bwkGrpDesc; + } + + public String getBwkGrpDesc() { + return this.bwkGrpDesc; + } + + public void setTrackAsisKey1Name(String trackAsisKey1Name) { + this.trackAsisKey1Name = trackAsisKey1Name; + } + + public String getTrackAsisKey1Name() { + return this.trackAsisKey1Name; + } + + public void setTrackAsisKey2Name(String trackAsisKey2Name) { + this.trackAsisKey2Name = trackAsisKey2Name; + } + + public String getTrackAsisKey2Name() { + return this.trackAsisKey2Name; + } +} diff --git a/src/main/java/com/eactive/eai/common/unifbwk/mapper/UnifBwkTpMapper.java b/src/main/java/com/eactive/eai/common/unifbwk/mapper/UnifBwkTpMapper.java new file mode 100644 index 0000000..2364d7a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/unifbwk/mapper/UnifBwkTpMapper.java @@ -0,0 +1,22 @@ +package com.eactive.eai.common.unifbwk.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.unifbwk.UnifBwkTpVO; +import com.eactive.eai.data.entity.onl.unifbwk.UnifBwkTp; +import com.eactive.eai.data.mapper.GenericMapper; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface UnifBwkTpMapper extends GenericMapper { + + @Mapping(source = "eaibzwkdstcd", target = "bwkClsCd") + @Mapping(source = "bzwkdsticname", target = "bwkGrpNm") + @Mapping(source = "bzwkdsticdesc", target = "bwkGrpDesc") + @Mapping(source = "trackasiskey1name", target = "trackAsisKey1Name") + @Mapping(source = "trackasiskey2name", target = "trackAsisKey2Name") + @Override + UnifBwkTpVO toVo(UnifBwkTp entity); + +} diff --git a/src/main/java/com/eactive/eai/common/usedate/Pass.java b/src/main/java/com/eactive/eai/common/usedate/Pass.java new file mode 100644 index 0000000..1049c06 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/usedate/Pass.java @@ -0,0 +1,5 @@ +package com.eactive.eai.common.usedate; + +public interface Pass { + public boolean isPass(String inter, long date); +} diff --git a/src/main/java/com/eactive/eai/common/usedate/UseDateControlDAO.java b/src/main/java/com/eactive/eai/common/usedate/UseDateControlDAO.java new file mode 100644 index 0000000..3fdca12 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/usedate/UseDateControlDAO.java @@ -0,0 +1,91 @@ +package com.eactive.eai.common.usedate; + +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.usedate.loader.UseDateControlLoader; +import com.eactive.eai.common.usedate.mapper.UseDateControlMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.useDate.UseDateControl; + +@Service +@Transactional +public class UseDateControlDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private UseDateControlLoader useDateControlLoader; + + @Autowired + private UseDateControlMapper useDateControlMapper; + + public List getUseDateContorlList() throws DAOException { + try { + List useDateControls = useDateControlLoader.findUseDateByTypeDSL("01"); + List vos = new ArrayList<>(); + useDateControls.forEach( e -> vos.add(useDateControlMapper.toVo(e)) ); + return vos; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + public UseDateControlVO getUseDateContorlListByInterface(String inter) throws DAOException { + ResultSet rs = null; + UseDateControlVO useDateControlVO = null; + try { +// TODO : 아래의 로직이 정상이 아니므로 확인이 핗요함 + +// // 사용일자제어 전체 인터페이스 조회 +// public static final String SELECT_USE_DATE_CONTROL_BY_ALL_INTERFACE = +// "SELECT NAME, STARTDATE, ENDDATE, USEYN\r\n" + +// "FROM " + Keys.TABLE_OWNER + "TSEAIFR10\r\n" + +// "WHERE TYPE='01'\r\n" + +// "ORDER BY NAME, USEYN"; + +// // 사용일자제어 인터페이스 조회 +// public static final String SELECT_USE_DATE_CONTROL_BY_INTERFACE = +// "SELECT NAME, STARTDATE, ENDDATE, USEYN\r\n" + +// "FROM " + Keys.TABLE_OWNER + "TSEAIFR10\r\n" + +// "WHERE TYPE='01'\r\n" + +// "ORDER BY NAME, USEYN"; + +// this.connect(SELECT_USE_DATE_CONTROL_BY_INTERFACE); +// +// rs = this.executeQuery(); +// if (rs.next()) { +// +// useDateControlVO = new UseDateControlVO(); +// SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); +// useDateControlVO.setName(rs.getString(1)); // NAME 인터페이스 +// Date start = null; +// Date end = null; +// try { +// start = format.parse(rs.getString(2) + "000000"); +// end = format.parse(rs.getString(3) + "235959"); +// } catch (Exception e) { +// useDateControlVO.setActivate(false); +// +// } +// useDateControlVO.setStartDate(start); // 시작일자 +// useDateControlVO.setEndDate(end); // 종료일자 +// useDateControlVO.setActivate("0".equals(rs.getString(4)) ? false : true); +// +// } + return useDateControlVO; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } finally { + this.disconnect(); + } + } + +} diff --git a/src/main/java/com/eactive/eai/common/usedate/UseDateControlManager.java b/src/main/java/com/eactive/eai/common/usedate/UseDateControlManager.java new file mode 100644 index 0000000..277ccb8 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/usedate/UseDateControlManager.java @@ -0,0 +1,151 @@ +package com.eactive.eai.common.usedate; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class UseDateControlManager implements Lifecycle, Pass { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private UseDateControlDAO useDateControlDAO; + + private Map interfaceList; + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private UseDateControlManager() { + interfaceList = new HashMap(); + } + + public static UseDateControlManager getInstance() { + return ApplicationContextProvider.getContext().getBean(UseDateControlManager.class); + } + +// public static com.eactive.eai.common.usedate.Pass getPass() { +// if(manager == null) { +// synchronized(UseDateControlManager.class) { +// if(manager == null) { +// manager = new UseDateControlManager(); +// } +// } +// } +// +// return manager; +// } + + @Override + public boolean isPass(String inter, long date) { + UseDateControlVO vo = interfaceList.get(inter); + if (vo == null) { + return true; + } + return vo.isPass(date); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICMM201"); + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICMM202")); + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + interfaceList = new HashMap<>(); + List list = useDateControlDAO.getUseDateContorlList(); + list.forEach(vo -> interfaceList.put(vo.getName(), vo)); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("UseDateControlManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("UseDateControlManager] reload all finished ..."); + } + } + + public synchronized void reload(String inter) throws Exception { + if (logger.isWarn()) { + logger.warn("UseDateControlManager] reload Started ..."); + } + UseDateControlVO vo = useDateControlDAO.getUseDateContorlListByInterface(inter); + + if (vo.isActivate()) { + interfaceList.put(vo.getName(), vo); + } else { + interfaceList.remove(vo.getName()); + } + + if (logger.isWarn()) { + logger.warn("UseDateControlManager] reload finished ..."); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICMM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + interfaceList.clear(); + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public String[] getAllKeys() { + Iterator it = this.interfaceList.keySet().iterator(); + String[] svcCd = new String[this.interfaceList.size()]; + for (int i = 0; it.hasNext(); i++) { + svcCd[i] = (String) it.next(); + } + Arrays.sort(svcCd); + return svcCd; + } + + public UseDateControlVO get(String inter) { + return interfaceList.get(inter); + } + + public void remove(String inter) { + interfaceList.remove(inter); + } + +} diff --git a/src/main/java/com/eactive/eai/common/usedate/UseDateControlVO.java b/src/main/java/com/eactive/eai/common/usedate/UseDateControlVO.java new file mode 100644 index 0000000..d0250c0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/usedate/UseDateControlVO.java @@ -0,0 +1,97 @@ +package com.eactive.eai.common.usedate; + +import java.io.Serializable; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.format.DateTimeFormatter; +import java.util.Date; + +/** + * 1. 기능 : 업무 사용일자를 표현하는 Java Value Object 클래스. + * 2. 처리 개요 : 사용일자 정보를 정의한다. + * 3. + * 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : 관련 기능을 참조 + * @since : + */ + +public class UseDateControlVO implements Serializable { + /** + * + */ + private static final long serialVersionUID = 1L; + private String name; + private Date startDate; + private Date endDate; + private boolean activate; + + DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + + @Override + public boolean equals(Object obj) { + return name.equals(obj); + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Date getStartDate() { + return startDate; + } + + public void setStartDate(Date startDate) { + this.startDate = startDate; + } + + public Date getEndDate() { + return endDate; + } + + public void setEndDate(Date endDate) { + this.endDate = endDate; + } + + public boolean isActivate() { + return activate; + } + + public void setActivate(boolean activate) { + this.activate = activate; + } + + public boolean isPass(long date) { + if(startDate.getTime() <= date && date <= endDate.getTime()){ + return true; + }else{ + return false; + } + } + public String getStartDateString(){ + Instant instant = startDate.toInstant(); + LocalDateTime ldt = instant.atZone(ZoneId.systemDefault()).toLocalDateTime(); + return ldt.format(format); + } + + public String getEndDateString(){ + Instant instant = endDate.toInstant(); + LocalDateTime ldt = instant.atZone(ZoneId.systemDefault()).toLocalDateTime(); + return ldt.format(format); + } + + + +} diff --git a/src/main/java/com/eactive/eai/common/usedate/mapper/UseDateControlMapper.java b/src/main/java/com/eactive/eai/common/usedate/mapper/UseDateControlMapper.java new file mode 100644 index 0000000..8728c1f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/usedate/mapper/UseDateControlMapper.java @@ -0,0 +1,29 @@ +package com.eactive.eai.common.usedate.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.usedate.UseDateControlVO; +import com.eactive.eai.data.entity.onl.useDate.UseDateControl; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.BooleanToStringMapper; +import com.eactive.eai.data.mapper.GenericMapper; +import com.eactive.eai.data.mapper.StringToBooleanMapper; + +@Mapper(config = BaseMapperConfig.class) +public interface UseDateControlMapper extends GenericMapper { + @Mapping(source = "id.name", target = "name") + @Mapping(source = "startdate", target = "startDate") + @Mapping(source = "enddate", target = "endDate") + @Mapping(source = "useyn", target = "activate", qualifiedBy = StringToBooleanMapper.class) + @Override + UseDateControlVO toVo(UseDateControl entity); + + @Mapping(target = "id.type", constant = "01") + @Mapping(target = "id.name", source = "name") + @Mapping(target = "startdate", source = "startDate") + @Mapping(target = "enddate", source = "endDate") + @Mapping(target = "useyn", source = "activate", qualifiedBy = BooleanToStringMapper.class) + UseDateControl toEntity(UseDateControlVO vo); +} diff --git a/src/main/java/com/eactive/eai/common/util/B2BExtractor.java b/src/main/java/com/eactive/eai/common/util/B2BExtractor.java new file mode 100644 index 0000000..63c57d0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/B2BExtractor.java @@ -0,0 +1,88 @@ +package com.eactive.eai.common.util; + +import com.eactive.eai.common.b2bextractor.B2BExtractManager; +import com.eactive.eai.common.b2bextractor.B2BExtractVO; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.flowcontrol.action.RouteAction; +import com.eactive.eai.flowcontrol.action.RouteActionFactory; + +// B2BRouterFCProcess 에서 기관코드/업무데이터을 추출 +public final class B2BExtractor { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private B2BExtractor() { + + } + + public static String[] getB2BRouteKeyValues(String eaiSvcCd, int svcPssSeq, Object message, String charset) throws Exception { + String[] keys = null; + try { + String actionName = ""; + // example "com.eactive.eai.flowcontrol.action.SGWRouteAction"; + B2BExtractManager manager = B2BExtractManager.getInstance(); + B2BExtractVO vo = manager.getB2BExtract(eaiSvcCd + svcPssSeq); + + if (vo == null) { + return null; + } + + actionName = vo.getRouteActionName(); + + if (actionName != null && actionName.trim().length() > 0) { + RouteActionFactory factory = new RouteActionFactory(); + RouteAction action = factory.createAction(actionName); + if (message instanceof byte[]) { + keys = action.getRouteKeys((byte[]) message); + } + else if (message instanceof String) { + keys = action.getRouteKeys(((String) message).getBytes(charset)); + } + else { + throw new Exception("Invalid message EAISVCCD [" + eaiSvcCd + "] message[" + message + "]"); + } + } + } catch (Exception e) { + logger.error("getB2BRouteKeyValues error", e); + // throw new Exception("RECEAICBX001"); + // B2B Service Routing 키정보 추출 중 오류가 발생 + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICBX001")); + } + return keys; + } + + public static String[] getB2BAdapterRouteKeyValues(String eaiSvcCd, int svcPssSeq, Object message, String charset) + throws Exception { + String[] keys = null; + try { + String actionName = ""; + // example "com.eactive.eai.flowcontrol.action.SGWAdapterRouteAction"; + B2BExtractManager manager = B2BExtractManager.getInstance(); + B2BExtractVO vo = manager.getB2BExtract(eaiSvcCd + svcPssSeq); + + if (vo == null) { + return null; + } + actionName = vo.getAdapterActionName(); + + if (actionName != null && actionName.trim().length() > 0) { + RouteActionFactory factory = new RouteActionFactory(); + RouteAction action = factory.createAction(actionName); + if (message instanceof byte[]) { + keys = action.getRouteKeys((byte[]) message); + } + else if (message instanceof String) { + keys = action.getRouteKeys(((String) message).getBytes(charset)); + } + else { + throw new Exception("Invalid message EAISVCCD [" + eaiSvcCd + "] message[" + message + "]"); + } + } + } catch (Exception e) { + logger.error("getB2BAdapterRouteKeyValues error", e); + // throw new Exception("RECEAICBX001"); + // B2B Adapter Routing 키정보 추출 중 오류가 발생 + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICBX002")); + } + return keys; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/B2BServiceMapper.java b/src/main/java/com/eactive/eai/common/util/B2BServiceMapper.java new file mode 100644 index 0000000..d85f29b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/B2BServiceMapper.java @@ -0,0 +1,198 @@ +package com.eactive.eai.common.util; + +import java.util.List; +import java.util.Properties; + +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.common.b2badaptermapping.B2BAdapterMapFldVO; +import com.eactive.eai.common.b2badaptermapping.B2BAdapterMapManager; +import com.eactive.eai.common.b2badaptermapping.B2BAdapterMapVO; +import com.eactive.eai.common.b2bservice.B2BServiceManager; +import com.eactive.eai.common.b2bservice.B2BServiceVO; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.ServiceMessage; + +// B2BRouterFCProcess 에서 기관코드/업무데이터에 맞는 Service 정보 설정 +public final class B2BServiceMapper { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private B2BServiceMapper() + { + + } + + // 기관코드에 해당하는 서비스메시지를 EAI메시지에 설정 + public static EAIMessage setB2BService(String b2bExtnlInstiCd, EAIMessage eaiMsg) + throws Exception { + + try { + List svcs = eaiMsg.getSvcMsgs(); + + boolean found = false; + + B2BServiceManager manager = B2BServiceManager.getInstance(); + + // STD표준에서 12자리 고정값이므로 trim 하고 비교해야 한다. + if(b2bExtnlInstiCd != null) b2bExtnlInstiCd = b2bExtnlInstiCd.trim(); + + for(int p=0; p KBMessage 로 변경 : 20080324 DHLEE + //---------------------------------------------------- + /* + try { + Object b2bEachMsg = eaiMsg.getKesaMsg().getKesaEachMsg(); + if(b2bEachMsg instanceof KESAB2BIMessage) { + ((KESAB2BIMessage)b2bEachMsg).setBBizCode(b2bExtnlInstiCd); + } + } catch(Exception e) { ; } + */ + // + // KBCommon kbcommon = eaiMsg.getKbMsg().getKBCommon(); + // try { + // if(KBMessageKeys.WTINEXTNLDSTCD_EX.equals( kbcommon.getInoPartlDstcd() )) { + // kbcommon.setOsidInstiCd(b2bExtnlInstiCd); + // } + // } catch(Exception e) { ; } + // + //---------------------------------------------------- + found = true; + } + } + + if(found) { + return eaiMsg; + } + else { + return null; + } + } + catch (Exception e) { + // B2B 기관코드에 해당하는 서비스메시지 설정 중 오류가 발생. + logger.error("setB2BService error", e); + throw new Exception(ExceptionUtil.getErrorCode(e,"RECEAICBS001")); + } + } + + private static String makeTramsformName(EAIMessage eaiMsg, int reqIndex) { + String transformName = ""; + + String transformNameFormat = "TRANSFORM_%s_%s_%s"; + + String eaiSvcPrefix = eaiMsg.getEAISvcCd().trim(); + if(eaiSvcPrefix.length() > 3) { + eaiSvcPrefix = eaiSvcPrefix.substring(0, eaiSvcPrefix.length() -3); + } + + if(reqIndex == 1) { + transformName = String.format(transformNameFormat, eaiMsg.getBwkCls().trim(), eaiSvcPrefix, "REQ"); + } + else if(reqIndex == 2) { + transformName = String.format(transformNameFormat, eaiMsg.getBwkCls().trim(), eaiSvcPrefix, "RES"); + } + else { + transformName = String.format(transformNameFormat, eaiMsg.getBwkCls().trim(), eaiSvcPrefix, "ERR"); + } + return transformName; + } + + // 업무데이터에 해당하는 Addpater를 EAI메시지에 설정 + public static EAIMessage setB2BAdapter(String b2bExtnlInstiCd, String bzwkVal, EAIMessage eaiMsg, Properties callProp) + throws Exception { + + try { + String eaiSvcCd = eaiMsg.getEAISvcCd(); + int svcSeq = eaiMsg.getSvcPssSeq(); + B2BAdapterMapManager manager = B2BAdapterMapManager.getInstance(); + B2BAdapterMapVO map = manager.getB2BAdapterMap(eaiSvcCd); + + if(map == null) { + return null; + // throw new Exception("B2B 업무데이터["+bzwkVal+"]의 라우팅룰이 정의되지 않았습니다."); + } + + B2BAdapterMapFldVO fvo = map.getB2BAdapterMapFld(b2bExtnlInstiCd, bzwkVal); + + if(fvo == null) { + // 등록된 정보가 없는 경우 NULL을 return + return null; + } + + // Socket Adapter일 경우에 + ServiceMessage svcMsg = eaiMsg.getCurrentSvcMsg(); + String adapterGroupName = fvo.getAdapterGroupName(); + String adapterName = fvo.getAdapterName(); + if(adapterName != null && adapterName.length() > 0 && !"DEFAULT".equals(adapterName) ) { + svcMsg.setPsvSysItfTp(adapterGroupName); + callProp.setProperty(Keys.OUT_ADAPTER_NAME, adapterName); + } + else { + svcMsg.setPsvSysItfTp(adapterGroupName); + } + + eaiMsg.setSvcMsgs(svcSeq - 1, svcMsg); + } + catch (Exception e) { + // B2B 업무데이터에 대한 B2B Adapter 매핑 중 오류가 발생. + throw new Exception(ExceptionUtil.getErrorCode(e,"RECEAICBS002")); + } + return eaiMsg; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/BidMsgExtractor.java b/src/main/java/com/eactive/eai/common/util/BidMsgExtractor.java new file mode 100644 index 0000000..baf013e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/BidMsgExtractor.java @@ -0,0 +1,88 @@ +package com.eactive.eai.common.util; + +public final class BidMsgExtractor { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private BidMsgExtractor() { + + } + +// 업무메시지에서 비드 메시지를 추출 +// public static BidMessage getBizKeyValue(String eaiSvcCd, String messageID, Object message, BidMessage bidMsg) +// throws Exception { +// try { +// PropManager pManager = PropManager.getInstance(); +// Properties prop = pManager.getProperties("BIDMessage"); +// +// if(prop==null) { +// throw new RuntimeException("비드메시지 프로퍼티 정보 없음"); +// } +// if(prop != null) { +// Message msg = MessageFactory.getFactory().getMessage(messageID); +// String msgType = ((Message) msg).getLayout().getLayoutType().getName(); +// if("XML".equals(msgType)) { +// String rootItemName = msg.getName(); +// String xmlString = ""; +// +// if(message instanceof byte[]) { +// xmlString = "<"+rootItemName+">" + new String((byte[])message) + ""; +// } +// else if(message instanceof String) { +// xmlString = "<"+rootItemName+">" + (String)message + ""; +// } +// +// try { +// msg.setData(xmlString); +// } catch(MessageSetDataException e) { +// MemoryLogger.error("BidMsgExtractor | setData error", e); +// throw e; +// } +// }else if("JSON".equals(msgType)) { +// String rootItemName = msg.getName(); +// String jsonString = ""; +// +// if(message instanceof byte[]) { +// jsonString = new String((byte[])message); +// } +// else if(message instanceof String) { +// jsonString = (String)message; +// } +// +// try { +// JSONObject value = (JSONObject)JSONValue.parse(jsonString); +// JSONObject root = new JSONObject(); +// root.put(rootItemName, value); +// jsonString = root.toJSONString(); +// msg.setData(jsonString); +// } catch(MessageSetDataException e) { +// MemoryLogger.error("BidMsgExtractor | setData error", e); +// throw e; +// } +// } +// else { +// try { +// msg.setData(message); +// } catch(MessageSetDataException e) { +// MemoryLogger.error("BidMsgExtractor | setData error", e); +// throw e; +// } +// } +// +// String contentName = prop.getProperty("contents.name"); +// String userNames = prop.getProperty("user.name"); +// String userSep = prop.getProperty("user.seperator"); +// String[] users = msg.getString(userNames).split(userSep); +// +// +// bidMsg.setMsg(msg.getString(contentName)); +// bidMsg.setTgtList(users); +// +// } +// } +// catch (Exception e) { +// logger.error("BidMsgExtractor]"+e.getMessage(),e); +// throw e; +// } +// return bidMsg; +// } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/BizKeyExtractor.java b/src/main/java/com/eactive/eai/common/util/BizKeyExtractor.java new file mode 100644 index 0000000..9c3ba79 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/BizKeyExtractor.java @@ -0,0 +1,245 @@ +package com.eactive.eai.common.util; + +import com.eactive.eai.common.bizkey.BizKeyFldVO; +import com.eactive.eai.common.bizkey.BizKeyManager; +import com.eactive.eai.common.bizkey.BizKeyVO; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.transformer.function.util.CodeConversion; +import com.eactive.eai.transformer.layout.LayoutTypeKey; +import com.eactive.eai.transformer.message.*; +import com.eactive.eai.transformer.util.MemoryLogger; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +// Inbound 에서 업무추적필드값, ALT-KEY값을 추출하는 기능을 제공 +public final class BizKeyExtractor { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private BizKeyExtractor() { + + } + + public static boolean isHex(String eaiSvcCd) { + BizKeyManager manager = BizKeyManager.getInstance(); + BizKeyVO bizKey = manager.getBizKey(eaiSvcCd + "TR"); + if (bizKey == null) + return false; + if ("HEX".equals(bizKey.getBizKeyFld(0).getMsgTp())) { + return true; + } + return false; + } + + private static Message setMessageValue(Message msg, Object message) throws Exception { + String msgType = ((Message) msg).getLayout().getLayoutType().getName(); + if (LayoutTypeKey.XML.equals(msgType)) { + String rootItemName = msg.getName(); + String xmlString = ""; + + xmlString = "<" + rootItemName + ">" + (String) message + ""; + + try { + msg.setData(xmlString); + } catch (MessageSetDataException e) { + MemoryLogger.error("BizKeyExtractor | setData error", e); + throw e; + } + } else if (LayoutTypeKey.JSON.equals(msgType)) { + String rootItemName = msg.getName(); + String jsonString = (String) message; + try { + JSONObject value = (JSONObject) JSONValue.parse(jsonString); + JSONObject root = new JSONObject(); + root.put(rootItemName, value); + jsonString = root.toJSONString(); + msg.setData(jsonString); + } catch (MessageSetDataException e) { + MemoryLogger.error("BizKeyExtractor | setData error", e); + throw e; + } + } else { + try { + msg.setData(message); + } catch (MessageSetDataException e) { + MemoryLogger.error("BizKeyExtractor | setData error", e); + throw e; + } + } + return msg; + } + + public static String getBizKeyValue(String eaiSvcCd, String messageID, Object message) throws Exception { + String key = ""; + try { + BizKeyManager manager = BizKeyManager.getInstance(); + BizKeyVO bizKey = manager.getBizKey(eaiSvcCd + "TR"); + String tmp = ""; // Transformer 호출 + + if (bizKey != null) { + // tobe 추가 로직 + // 1. 참조메시지가 없어도 추적키의 레이아웃으로 추출 + // 2. 참조메시지가 있다면 추적키의 레이아웃을 바꿔치기함 + Message msg = null; + if (StringUtils.isEmpty(messageID)) { + BizKeyFldVO keyFld = bizKey.getBizKeyFld(0); + if (keyFld == null) { + throw new Exception("not found bizKey"); + } + String bizMessageID = keyFld.getBwkColNm(); + bizMessageID = bizMessageID.substring(0, bizMessageID.indexOf(".")); + msg = MessageFactory.getFactory().getMessage(bizMessageID); + } else { + msg = MessageFactory.getFactory().getMessage(messageID); + } + + msg = setMessageValue(msg, message); + + int fldSize = bizKey.getBizKeyFldLength(); + for (int i = 0; i < fldSize; i++) { + BizKeyFldVO keyFld = bizKey.getBizKeyFld(i); + if (keyFld == null) { + throw new Exception("BizKeyFldVO is null - " + i); + } + String colName = keyFld.getBwkColNm(); + if (colName != null) { + colName = colName.trim(); + if (colName.length() > 0) { + if ((msg instanceof EbcdicMessage || msg instanceof CommonEbcdicMessage) + || "EBC".equals(keyFld.getMsgTp())) { + tmp = new String(CodeConversion.seToAsc(msg.getByteArray(colName))); + } else { + tmp = msg.getString(colName); + } + key = key + tmp; + } + } + } + } + } catch (Exception e) { + logger.error("getBizKeyValue error", e); + // throw new Exception("RECEAICBE001"); +// throw new Exception(ExceptionUtil.getErrorCode(e,"RECEAICBE001"), e); + throw e; + } + return key; + } + + public static String[] getAltKeyValues(String eaiSvcCd, String messageID, Object message) throws Exception { + String[] key = new String[4]; + try { + BizKeyManager manager = BizKeyManager.getInstance(); + BizKeyVO bizKey = manager.getBizKey(eaiSvcCd + "AK"); + + if (bizKey != null) { + + // tobe 추가 로직 + // 1. 참조메시지가 없어도 추적키의 레이아웃으로 추출 + // 2. 참조메시지가 있다면 추적키의 레이아웃을 바꿔치기함 + Message msg = null; + if (StringUtils.isEmpty(messageID)) { + BizKeyFldVO keyFld = bizKey.getBizKeyFld(0); + if (keyFld == null) { + throw new Exception("not found bizKey"); + } + String bizMessageID = keyFld.getBwkColNm(); + bizMessageID = bizMessageID.substring(0, bizMessageID.indexOf(".")); + msg = MessageFactory.getFactory().getMessage(bizMessageID); + } else { + msg = MessageFactory.getFactory().getMessage(messageID); + } + + int fldSize = bizKey.getBizKeyFldLength(); + + msg = setMessageValue(msg, message); + + String tmp = ""; // Transformer 호출 + for (int i = 0; i < fldSize; i++) { + if (i >= 4) + break; // ALT-KEY는 4개가 최대값이다. + BizKeyFldVO keyFld = bizKey.getBizKeyFld(i); + + if (keyFld == null) { + throw new Exception("BizKeyFldVO is null - " + i); + } + + String colName = keyFld.getBwkColNm(); + if (colName != null) { + colName = colName.trim(); + if (colName.length() > 0) { + if (msg instanceof EbcdicMessage) { + key[i] = new String(CodeConversion.seToAsc(msg.getByteArray(colName))); + } else { + key[i] = tmp = msg.getString(colName); + } + } else { + key[i] = ""; + } + } else { + key[i] = ""; + } + } + } else { + return new String[] { "", "", "", "" }; + } + } catch (Exception e) { + // e.printStackTrace(); + // throw new Exception("RECEAICBE010"); +// throw new Exception(ExceptionUtil.getErrorCode(e,"RECEAICBE010"), e); + throw e; + } + return key; + } + + public static String getBizKeyCode(String bizCodeData, Object message, boolean isEbcdic) throws Exception { + if (message == null) + return ""; + + String keys = ""; + byte[] key = null; + byte[] msg = null; + if (message instanceof byte[]) { + msg = (byte[]) message; + } else if (message instanceof String) { + msg = ((String) message).getBytes(); + } else { + return ""; + } + + if (bizCodeData != null && !"".equals(bizCodeData.trim())) { + Matcher matcher = Pattern.compile("\\[([ ]*[0-9]+)[ ]*,([ ]*[0-9]+)[ ]*\\]").matcher(bizCodeData.trim()); + while (matcher.find()) { + int offset = Integer.parseInt(matcher.group(1).trim()); + int length = Integer.parseInt(matcher.group(2).trim()); + if (msg.length < offset + length) { + continue; + } + key = new byte[length]; + System.arraycopy(msg, offset, key, 0, length); + if (isEbcdic) { + keys = keys + (new String(CodeConversion.seToAsc(key)).trim()); + } else { + keys = keys + (new String(key)).trim(); + } + } + } + return keys; + + } +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String bizCodeData = "[0,4][4,2]"; +// byte[] message = "1234567890ABCD".getBytes(); +// boolean isEbcdic = false; +// +// String s = BizKeyExtractor.getBizKeyCode(bizCodeData, message, isEbcdic); +// System.out.println(s); +// } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/C2RServiceMapper.java b/src/main/java/com/eactive/eai/common/util/C2RServiceMapper.java new file mode 100644 index 0000000..b1e147e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/C2RServiceMapper.java @@ -0,0 +1,74 @@ +package com.eactive.eai.common.util; + +import java.util.List; + +import com.eactive.eai.common.c2rservice.C2RServiceManager; +import com.eactive.eai.common.c2rservice.C2RServiceVO; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.ServiceMessage; + +// B2BRouterFCProcess 에서 기관코드/업무데이터에 맞는 Service 정보 설정 +public final class C2RServiceMapper { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private C2RServiceMapper() { + + } + + // 기관코드에 해당하는 서비스메시지를 EAI메시지에 설정 + public static EAIMessage setC2RService(String c2rRequestSystemCd, EAIMessage eaiMsg) throws Exception { + try { + + List svcs = eaiMsg.getSvcMsgs(); + C2RServiceManager manager = C2RServiceManager.getInstance(); + + if (c2rRequestSystemCd != null) + c2rRequestSystemCd = c2rRequestSystemCd.trim(); + + for (int p = 0; p < svcs.size(); p++) { + + C2RServiceVO c2rService = manager.getC2RServiceVO(c2rRequestSystemCd, p + 1); + if (c2rService != null) { + ServiceMessage svcMsg = eaiMsg.getSvcMsg(p); + // Service Data Mapping + setServiceData(svcMsg, c2rService); + eaiMsg.setSvcMsgs(p, svcMsg); + return eaiMsg; + } + } + + return null; + } catch (Exception e) { + // B2B 기관코드에 해당하는 서비스메시지 설정 중 오류가 발생. + logger.error("C2RServiceMapper]" + e.getMessage(), e); + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICBS001")); + } + } + + private static void setServiceData(ServiceMessage svcMsg, C2RServiceVO c2rService) { + if (c2rService.getPsvItfTp() != null) + svcMsg.setPsvItfTp(c2rService.getPsvItfTp()); // 수동인터페이스유형[TSEAIHE04.PsvIntfacDsticName] + if (c2rService.getPsvBwkSysNm() != null) + svcMsg.setPsvBwkSysNm(c2rService.getPsvBwkSysNm()); // 수동업무시스템명[TSEAIHE04.PsvSysbzwkdstcd] + if (c2rService.getPsvSysID() != null) + svcMsg.setPsvSysID(c2rService.getPsvSysID()); // 수동시스템ID명[TSEAIHE04.PsvSysIDName] + if (c2rService.getPsvSysSvcCd() != null) + svcMsg.setPsvSysSvcCd(c2rService.getPsvSysSvcCd()); // 수동시스템서비스구분명[TSEAIHE04.PsvSysSvcDsticName] + if (c2rService.getPsvSysItfTp() != null) + svcMsg.setPsvSysItfTp(c2rService.getPsvSysItfTp()); // 수동시스템어댑터업무그룹명[TSEAIHE04.PsvSysAdptrBzwkGroupName] + if (c2rService.getFlOvrCls() != null) + svcMsg.setFlOvrCls(c2rService.getFlOvrCls()); // 장애극복여부[TSEAIHE04.FlovrYn] + if (c2rService.getOutbRtnNm() != null) + svcMsg.setOutbRtnNm(c2rService.getOutbRtnNm()); // 아웃바운드라우팅명[TSEAIHE04.OutbndRoutName] + svcMsg.setTmoVl(c2rService.getTmoVl()); // 타임아웃값[TSEAIHE04.ToutVal] + if (c2rService.getCpnsSvcPssCd() != null) + svcMsg.setCpnsSvcPssCd(c2rService.getCpnsSvcPssCd()); // 보상서비스처리코드[TSEAIHE04.CmpenSvcPrcssDsticName] + if (c2rService.getSupplDelYn() != null) + svcMsg.setSupplDelYn(c2rService.getSupplDelYn()); // 추가삭제여부[TSEAIHE02.SupplDelYn] -[Y/N] + if (c2rService.getHdrCtrlDstcd() != null) + svcMsg.setHdrCtrlDstcd(c2rService.getHdrCtrlDstcd()); // 헤더제어구분코드[TSEAIHE02.HdrCtrlDstcd]-[01/02]삭제제추가/추가삭제 + if (c2rService.getHdrRefClsName() != null) + svcMsg.setHdrRefClsName(c2rService.getHdrRefClsName()); // 참고클래스명[TSEAIHE02.HdrRefClsName] + } +} diff --git a/src/main/java/com/eactive/eai/common/util/CodeUtil.java b/src/main/java/com/eactive/eai/common/util/CodeUtil.java new file mode 100644 index 0000000..496970e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/CodeUtil.java @@ -0,0 +1,198 @@ +package com.eactive.eai.common.util; + +import java.nio.ByteBuffer; + +public class CodeUtil { + + // invalid bytes + private static final byte[] invalidBytes = { (byte) 0x0E, (byte) 0x0F, (byte) 0xFF }; + +// private static final byte SO = (byte) 0x0E; +// private static final byte SI = (byte) 0x0F; +// private static final byte FF = (byte) 0xFF; + + // 0x00 - 0x7F + private static final byte ASC_S = (byte) 0x00; + private static final byte ASC_E = (byte) 0x7F; + + // space + private static final byte DEF_B = (byte) 0x20; + +// private static boolean debug = false; + + public static byte[] getHexIn0x(String line) { + ByteBuffer bb = ByteBuffer.allocate(line.getBytes().length / 2); + while (line.indexOf("0x") != -1) { + bb.put(line.substring(0, line.indexOf("0x")).getBytes()); + String hex = line.substring(line.indexOf("0x"), line.indexOf("0x") + 4); + bb.put((byte) Integer.parseInt(hex.substring(2), 16)); + line = line.substring(line.indexOf("0x") + 4); + } + bb.put(line.getBytes()); + byte[] dst = new byte[bb.limit()]; + bb.position(0); + bb.get(dst); + return dst; + + } + + public static byte[] getHex(String line) { + ByteBuffer bb = ByteBuffer.allocate(line.getBytes().length / 2); + while (line.length() > 0) { + bb.put((byte) Integer.parseInt(line.substring(0, 2), 16)); + line = line.substring(2); + } + byte[] dst = new byte[bb.limit()]; + bb.position(0); + bb.get(dst); + return dst; + } + + public static boolean checkInvalid(byte cbyte) { + for (int i = 0; i < invalidBytes.length; i++) { + if (invalidBytes[i] == cbyte) + return true; + } + return false; + } + + public static String scanBytes(byte[] source) { + int index = 0; + +// if(debug) System.out.println("Source : [" + new String(source) +"]"); + + byte[] convertedBytes = new byte[source.length]; + + while (index < source.length) { + if (checkInvalid(source[index])) { +// if(debug) System.out.println("invalid : " + byte2Hex(source[index]) ); + convertedBytes[index] = DEF_B; + index++; + } else if (source[index] >= ASC_S && source[index] <= ASC_E) { +// if(debug) System.out.println("Single : " + byte2Hex(source[index]) ); + convertedBytes[index] = source[index]; + index++; + } else { + if (index + 1 <= source.length - 1) { + if (checkInvalid(source[index + 1])) { +// if(debug) System.out.println("Multi, but broken"); + convertedBytes[index] = DEF_B; + convertedBytes[index + 1] = DEF_B; + } else if (source[index + 1] >= ASC_S && source[index + 1] <= ASC_E) { + convertedBytes[index] = DEF_B; + index++; + continue; + } else { + +// byte[] multiBytes = {source[index], source[index+1]}; +// if(debug) System.out.println("Multi : " + bytes2Hex(multiBytes) ); + convertedBytes[index] = source[index]; + convertedBytes[index + 1] = source[index + 1]; + } + } else { + convertedBytes[index] = DEF_B; + break; + } + index++; + index++; + } + } + +// if(debug) System.out.println("Converted bytes2Hex : "+convertedBytes.length+"[" + bytes2Hex(convertedBytes) +"]"); +// if(debug) System.out.println("Converted new String : "+new String(convertedBytes).getBytes().length+"[" + new String(convertedBytes) +"]"); + return new String(convertedBytes); + } + + public static String byte2Hex(byte inByte) { + String s = ""; + s = s + Integer.toHexString((inByte & 0xf0) >> 4) + Integer.toHexString(inByte & 0xf); + + return s.toUpperCase(); + } + + public static String bytes2Hex(byte inBytes[]) { + String s = ""; + for (int i = 0; i < inBytes.length; i++) + s = s + Integer.toHexString((inBytes[i] & 0xf0) >> 4) + Integer.toHexString(inBytes[i] & 0xf); + + return s.toUpperCase(); + } + + public static String str2Hex(String inStr) { + if (inStr == null || inStr.equals("")) { + return ""; + } + String retStr = bytes2Hex(inStr.getBytes()); + return retStr; + } + + public static String fullToHalf(String full) { + String answer = null; + int fullLength = full.length(); + char[] ch1 = new char[fullLength]; + full.getChars(0, fullLength, ch1, 0); + for (int i = 0; i < fullLength; i++) { + if (ch1[i] > 0xff00 && ch1[i] <= 0xff5e) { + ch1[i] -= 0xfee0; + } else if (ch1[i] == 0x3000) + ch1[i] = 0x20; + } + answer = new String(ch1); + + // 뒷쪽 공백문자 trim + char[] ch2 = new char[fullLength]; + full.getChars(0, fullLength, ch2, 0); + for (int i = fullLength - 1; i >= 0; i--) { + if (ch2[i] != 0x3000 && ch2[i] != 0x20) { + answer = answer.substring(0, i + 1); + break; + } + if (i == 0) + answer = ""; + } + return answer; + } + + public static String halfToFull(String half) { + + String answer = null; + + int halfLength = half.length(); + + char[] ch = new char[halfLength]; + half.getChars(0, halfLength, ch, 0); + for (int i = 0; i < halfLength; i++) { + if (ch[i] > 0x20 && ch[i] <= 0x7e) { + ch[i] += 0xfee0; + } else if (ch[i] == 0x20) + ch[i] = 0x3000; + } + answer = new String(ch); + + return answer; + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +//private static void test() throws Exception { +// +// String line2 =""; +// ArrayList al = new ArrayList(); +// //al.add("0E20C8A83E2053204320C1FDB1DDB40F"); +// //al.add("BFA9A1A1A3B1C0CEB4E7FFFFC3D6"); +// //al.add("B8B6C1F6B8B720C0DFB8AEB4C2B0"); +// al.add("C4BFC7C72FC3B5BEC8BDD6BFEBC12020"); +// while (!al.isEmpty()){ +// line2 = al.remove(0); +// byte [] src = getHex(line2); +// +// System.out.println("byte length="+ CommonLib.getDumpMessage(src)+""); +// System.out.println("String length="+ CommonLib.getDumpMessage(new String(src).getBytes())+""); +// System.out.println("scan length="+ CommonLib.getDumpMessage( scanBytes(src).getBytes())+""); +// System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"); +// } +// +// } +} diff --git a/src/main/java/com/eactive/eai/common/util/DiagLogger.java b/src/main/java/com/eactive/eai/common/util/DiagLogger.java new file mode 100644 index 0000000..bc08a09 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/DiagLogger.java @@ -0,0 +1,77 @@ +/* + * Created on 2005. 2. 26. + * + */ +package com.eactive.eai.common.util; + + +/** + * @author janet + * + */ +public class DiagLogger { + + /* + * Constants for Trace Level + */ + public static final int DEFAULT = 0; // WARNING, ERROR, FATAL인 경우 에러로깅 + + public static final int INFO = 1; // INFO 수준의 LOGGING을 수행한다. + + public static final int DEBUG = 2; // DEBUG 수준의 송수신전문 및 에러 메인처리내용의 모든수준의 로깅을 수행한다. + + +// public static void logMethodEntry(String s) { +// logGenericTrace( new StringBuffer().append(">").append(s).toString() ); +// } +// +// public static void logMethodExit(String s) { +// logGenericTrace( new StringBuffer().append("<").append(s).toString() ); +// } +// +// public static void log(String s) { +// logGenericTrace( new StringBuffer().append("[INFO] ").append(s).toString() ); +// } +// +// public static void logError(String s) { +// logGenericTrace( new StringBuffer().append("[ERROR] ").append(s).toString() ); +// } +// +// +// public static void logException(Exception e) { +// StackTraceElement aStackTraceElement[] = e.getStackTrace(); +// for(int i = 0; i < aStackTraceElement.length; i++) +// log(aStackTraceElement[i].toString()); +// } +// +// public static void logDump(byte[] data) { +// String[] hexDump = CommonLib.makeDumpFormat( data ); +// for (int i=0; i < hexDump.length; i++) +// log( hexDump[i] ); +// } +// +// public static void logDump(String s) { +// logDump(s.getBytes()); +// } + +// public static void logNameValue(String name, String value) { +// logGenericTrace(name + " = " + value); +// } + +// public static void logNameValue(int traceLevel, int logLevel, String name, String value) { +// if ( traceLevel >= logLevel ) +// logNameValue( name, value ); +// } + +// public static void logNameValue(String name, byte[] value) { +// logGenericTrace(name + " = x'" + CommonLib.byte2Hex(value) + "'"); +// } + +// public static void logNameValue(int traceLevel, int logLevel, String name, byte[] value) { +// if ( traceLevel >= logLevel ) +// logNameValue( name, value ); +// } +// public static void logGenericTrace( String value ) { +// System.out.println( "[" + DatetimeUtil.getFormattedDate("yyyy-MM-dd HH:mm:ss.SSS") + "] " + Thread.currentThread().getName() + " - " + value ); +// } +} diff --git a/src/main/java/com/eactive/eai/common/util/DuplicationGuidLogUtil.java b/src/main/java/com/eactive/eai/common/util/DuplicationGuidLogUtil.java new file mode 100644 index 0000000..1c9e245 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/DuplicationGuidLogUtil.java @@ -0,0 +1,95 @@ +package com.eactive.eai.common.util; + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.jdbc.UncategorizedSQLException; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.common.duplication.DuplicationGuidDataVo; +import com.eactive.eai.common.duplication.DuplicationGuidLogVo; +import com.eactive.eai.common.duplication.loader.DuplicationGuidDataLogger; +import com.eactive.eai.common.duplication.loader.DuplicationGuidLogLogger; +import com.eactive.eai.common.duplication.mapper.DuplicationGuidDataMapper; +import com.eactive.eai.common.duplication.mapper.DuplicationGuidLogMapper; +import com.eactive.eai.common.logger.EAIDBLogControl; +import com.eactive.eai.data.entity.onl.duplication.DuplicationGuidData; +import com.eactive.eai.data.entity.onl.duplication.DuplicationGuidLog; +import com.eactive.eai.inbound.processor.ProcessVO; + +public class DuplicationGuidLogUtil { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static void insert(String guid, String channelTypeCd, ProcessVO processVo, Object message) throws Exception { + if (EAIDBLogControl.isEnable()) { + try { + DuplicationGuidLogLogger service = ApplicationContextProvider.getContext() + .getBean(DuplicationGuidLogLogger.class); + DuplicationGuidLogMapper mapper = ApplicationContextProvider.getContext() + .getBean(DuplicationGuidLogMapper.class); + DuplicationGuidLogVo vo = new DuplicationGuidLogVo(); + vo.setGuid(guid); + vo.setChannelCode(channelTypeCd); + vo.setInstanceName(processVo.getServerName()); + vo.setEaisvcname(processVo.getEaiSvcCd()); + vo.setRecvDatetime(DatetimeUtil.getCurrentTime(processVo.getErrTm())); + + DuplicationGuidLog entity = mapper.toEntity(vo); + service.save(entity); + } catch (DataIntegrityViolationException | UncategorizedSQLException e) { + DuplicationGuidDataLogger service = ApplicationContextProvider.getContext() + .getBean(DuplicationGuidDataLogger.class); + DuplicationGuidDataMapper mapper = ApplicationContextProvider.getContext() + .getBean(DuplicationGuidDataMapper.class); + DuplicationGuidDataVo vo = new DuplicationGuidDataVo(); + vo.setUuid(processVo.getUuid()); + vo.setChannelCode(channelTypeCd); + vo.setGuid(guid); + vo.setInstanceName(processVo.getServerName()); + vo.setEaisvcname(processVo.getEaiSvcCd()); + vo.setRecvDatetime(DatetimeUtil.getCurrentTime(processVo.getErrTm())); + vo.setBizData(toStringBizData(message, processVo.getAdapterGroupName())); + + DuplicationGuidData entity = mapper.toEntity(vo); + service.save(entity); + throw new Exception("GUID duplication error guid=" + guid); + } catch (Throwable th) { + logger.error("[" + guid + "] Insert Guid Log Error. - " + th.getMessage(), th); + } + } + } + + private static String toStringBizData(Object message, String adapterGroupName) { + String msg = null; + if (message == null) { + msg = "null"; + } else { + if (message instanceof byte[]) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO srcAdapterGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + if (srcAdapterGrpVO == null) { + msg = new String((byte[]) message); + } else { + String charset = StringUtils.defaultIfBlank(srcAdapterGrpVO.getMessageEncode(), + Charset.defaultCharset().name()); + try { + msg = new String((byte[]) message, charset); + } catch (UnsupportedEncodingException e) { + logger.warn("msg encode error", e); + msg = new String((byte[]) message); + } + } + + } else if (message instanceof String) { + msg = (String) message; + } else { + msg = "invaild message [" + message.getClass().getName() + "] " + message.toString(); + } + } + return msg; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/FMLLogUtil.java b/src/main/java/com/eactive/eai/common/util/FMLLogUtil.java new file mode 100644 index 0000000..bf2c2b4 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/FMLLogUtil.java @@ -0,0 +1,76 @@ +package com.eactive.eai.common.util; +//package com.eactive.eai.common.util; +// +//import com.eactive.eai.adapter.wtc.CrmFmlTable; +//import java.util.Iterator; +//import java.util.Map; +//import weblogic.wtc.jatmi.FML; +//import weblogic.wtc.jatmi.FldTbl; +//import weblogic.wtc.jatmi.FmlKey; +//import weblogic.wtc.jatmi.TypedFML32; +// +///** +// * 1. 기능 : FML의 필드, 값을 로그스트링으로 변환하는 Method Class +// * 2. 처리 개요 : FML의 필드, 값을 로그스트링으로 변환 +// * * - +// * 3. 주의사항 +// * +// * @author : dhlee +// * @version : v 1.0.0 +// * @see : +// * @since : +// * : +// */ +// +//public class FMLLogUtil +//{ +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// public static String getFMLLogString(Object fmlObj) throws Exception { +// +// if(!(fmlObj instanceof FML)) { +// throw new Exception("Invalid Object : Not FML Object!"); +// } +// +// FML fml = (FML)fmlObj; +// FldTbl[] ft = fml.getFieldTables(); +// +// //------------------------------------------------------------- +// // JMS Queue 또는 Remote로 전달할 경우 FieldTable은 전송되지 않는다. +// // 이에 대한 처리방안 +// //------------------------------------------------------------- +// if(ft == null) { +// FldTbl[] pft = {new CrmFmlTable()}; +// fml.setFieldTables(pft); +// } +// +// StringBuffer sb = new StringBuffer(); +// try { +// Iterator fmliter = fml.Fiterator(); +// String fname = null; +// int fid = 0; +// while (fmliter.hasNext()) { +// Map.Entry entry = (Map.Entry) fmliter.next(); +// FmlKey fmlkey = (FmlKey) entry.getKey(); +// +// try { +// fid = fmlkey.get_fldid(); +// fname = fml.Fname(fid); +// } +// catch(Exception ferr) { +// if (logger.isInfo()) logger.info("FMLLogUtil Undefined Fldid - Skip fldid["+fid+"]"); +// continue; +// } +// sb.append(fname); +// sb.append("["+fmlkey.get_occurance()+"]"); +// sb.append("="); +// sb.append(entry.getValue()); +// sb.append(","); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// return sb.toString(); +// } +// +//} diff --git a/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java new file mode 100644 index 0000000..8251e53 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/HttpAdapterExtraLogUtil.java @@ -0,0 +1,114 @@ +package com.eactive.eai.common.util; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import com.eactive.eai.common.logger.HttpAdapterExtraHeaderVo; +import com.eactive.eai.common.logger.HttpAdapterExtraLogVo; +import com.eactive.eai.common.logger.HttpLoggingService; +import com.eactive.eai.common.logger.async.AsyncHttpLoggingPoolManager; +import com.eactive.eai.env.ElinkConfig; +import org.apache.hc.core5.http.Header; +import org.apache.commons.lang3.StringUtils; + + +public class HttpAdapterExtraLogUtil { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static void insertHttpAdapterExtraLog(String guid, int serviceProcessNumber, String adapterGroupName, String adapterName, Map headers, String url, String httpMethod){ + insertHttpAdapterExtraLog(guid, serviceProcessNumber, adapterGroupName, adapterName, headers, url, httpMethod, 0); + } + + public static void insertHttpAdapterExtraLog(String guid, int serviceProcessNumber, String adapterGroupName, String adapterName, Map headers, String url, String httpMethod, int httpStatus){ + List headerVoList = convertMapToListOfHttpAdapterExtraHeaderVo(headers); + insertHttpAdapterExtraLog(guid, serviceProcessNumber, adapterGroupName, adapterName, headerVoList, url, httpMethod, httpStatus); + } + + public static void insertHttpAdapterExtraLog(String guid, int serviceProcessNumber, String adapterGroupName, String adapterName, Header[] headers, String url, String httpMethod){ + insertHttpAdapterExtraLog(guid, serviceProcessNumber, adapterGroupName, adapterName, headers, url, httpMethod, 0); + } + + public static void insertHttpAdapterExtraLog(String guid, int serviceProcessNumber, String adapterGroupName, String adapterName, Header[] headers, String url, String httpMethod, int httpStatus){ + List headerVoList = convertHeaderToListOfHttpAdapterExtraHeaderVo(headers); + insertHttpAdapterExtraLog(guid, serviceProcessNumber, adapterGroupName, adapterName, headerVoList, url, httpMethod, httpStatus); + } + + public static void insertHttpAdapterExtraLog(String guid, int serviceProcessNumber, String adapterGroupName, String adapterName, List headerVoList, String url, String httpMethod, int httpStatus){ + try { +// HttpAdapterExtraLogMapper mapper = ApplicationContextProvider.getContext().getBean(HttpAdapterExtraLogMapper.class); + HttpAdapterExtraLogVo httpAdapterExtraLogVo = new HttpAdapterExtraLogVo(); + httpAdapterExtraLogVo.setGuid(guid); + httpAdapterExtraLogVo.setServiceProcessNumber(serviceProcessNumber); + httpAdapterExtraLogVo.setAdapterGroupName(adapterGroupName); + httpAdapterExtraLogVo.setAdapterName(adapterName); + httpAdapterExtraLogVo.setUrl(url); + httpAdapterExtraLogVo.setHttpMethod(httpMethod); + + for (HttpAdapterExtraHeaderVo httpAdapterExtraHeaderVo : headerVoList) { + String name = httpAdapterExtraHeaderVo.getName(); + if(StringUtils.isNotBlank(name) && "authorization".equals(name.toLowerCase())) { + httpAdapterExtraHeaderVo.setValue("{hidden}"); + } + String value = httpAdapterExtraHeaderVo.getValue(); + if(StringUtils.isNotBlank(value) && value.length() > 400) { + value = value.substring(0, 400) + "..."; + httpAdapterExtraHeaderVo.setValue(value); + }else if(value == null){ + httpAdapterExtraHeaderVo.setValue(" "); + } + } + httpAdapterExtraLogVo.setHeaderList(headerVoList); + httpAdapterExtraLogVo.setHttpStatus(httpStatus); + if(ElinkConfig.isUseAsyncLogging()) { + AsyncHttpLoggingPoolManager.getInstance().publish(httpAdapterExtraLogVo); + } else { + HttpLoggingService service = ApplicationContextProvider.getContext().getBean(HttpLoggingService.class); + service.insertHttpAdapterExtraLog(httpAdapterExtraLogVo); + } + + // 2025.04.30 DB Log 작업 Async 처리 적용으로 수정 +// if (EAIDBLogControl.isEnable()) { +// // 2025.04.11 DB 장애시 DB 장애 Flag 설정하도록 수정 +// try { +// HttpAdapterExtraLog httpAdapterExtraLog = mapper.toEntity(httpAdapterExtraLogVo); +// HttpAdapterExtraLogLogger service = ApplicationContextProvider.getContext().getBean(HttpAdapterExtraLogLogger.class); +// service.save(httpAdapterExtraLog); +// } catch (Exception e) { +// logger.error("["+guid+"] Insert HTTP Log Error. - " + e.getMessage(), e); +// // DB Connection Error일 경우에만 설정하도록 수정 +// String message = e.getMessage(); +// // 오류 메시지 추가 - Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to acquire JDBC Connection +// // 오류 메시지 추가 - Could not open JPA EntityManager for transaction; nested exception is org.hibernate.exception.GenericJDBCException: Unable to acquire JDBC Connection +// if( "ConnectionError".equals(message) || org.apache.commons.lang.StringUtils.contains(message, "JDBCConnectionException") +// || org.apache.commons.lang.StringUtils.contains(message, "Unable to acquire JDBC Connection") ) { +// EAIDBLogControl.setEnable(false); +// } +//// throw e; +// } +// } else { +// // TODO: 파일 로그 및 복구 처리 추가 필요 +// } + } catch(Throwable th){ + logger.error("["+guid+"] Insert HTTP Log Error. - " + th.getMessage(), th); + } + } + + public static List convertHeaderToListOfHttpAdapterExtraHeaderVo(Header[] headers) { + Set seenNames = new HashSet<>(); + return Arrays.stream(headers) + .filter(header -> seenNames.add(header.getName())) // 중복된 이름을 스킵 + .map(header -> new HttpAdapterExtraHeaderVo(header.getName(), header.getValue())) + .collect(Collectors.toList()); + } + + public static List convertMapToListOfHttpAdapterExtraHeaderVo(Map map) { + return map.entrySet().stream() + .map(entry -> new HttpAdapterExtraHeaderVo(entry.getKey().toString(), entry.getValue().toString())) + .collect(Collectors.toList()); + } +} diff --git a/src/main/java/com/eactive/eai/common/util/InboundErrorLogger.java b/src/main/java/com/eactive/eai/common/util/InboundErrorLogger.java new file mode 100644 index 0000000..b8bea6f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/InboundErrorLogger.java @@ -0,0 +1,54 @@ +package com.eactive.eai.common.util; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.dao.DAOFactory; +import com.eactive.eai.common.errorcode.ErrorCodeManager; +import com.eactive.eai.inbound.error.InboundErrorInfoDAO; +import com.eactive.eai.inbound.error.InboundErrorInfoVO; + +public class InboundErrorLogger { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static void error(String uuid, String adapterGroupName, String adapterName, String errCode, String errMsg, + long errTm, String svcInstNm, String errDstCd, Object message) { + String msg = null; + + if (errDstCd == null || errDstCd.length() == 0) { + errDstCd = "ND"; + } + + InboundErrorInfoVO errorInfoVO = new InboundErrorInfoVO(); + errorInfoVO.setEaiSvcSno(uuid); // EAI서비스일련번호 + errorInfoVO.setAdptBwkGrpNm(adapterGroupName); // 어댑터업무그룹명 + errorInfoVO.setErrCd(errCode); // 에러코드 + errorInfoVO.setErrTxt(errMsg); // 에러내용 + errorInfoVO.setErrTm(DatetimeUtil.getCurrentTime(errTm)); // 에러발생시각 + errorInfoVO.setErrDstcd(errDstCd); + + if (message == null) { + msg = "null"; + } else if (message instanceof byte[]) { + msg = new String((byte[]) message); + } else if (message instanceof String) { + msg = (String) message; + } else { + msg = "invaild message [" + message.getClass().getName() + "] " + message.toString(); + } + + errorInfoVO.setBwkDataTxt(msg); // 업무데이터내용 + errorInfoVO.setEaiSvrInstNm(svcInstNm); // EAI서버인스턴스명 + + error(errorInfoVO); + } + + public static void error(InboundErrorInfoVO errorInfoVO) { + InboundErrorInfoDAO dao = null; + try { + dao = ApplicationContextProvider.getContext().getBean(InboundErrorInfoDAO.class); + dao.addInboundErrorInfo(errorInfoVO); + } catch (DAOException e) { + logger.error("InboundErrorLogger] Inbound Unknown Message Logging Error", e); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/JMSReceiver.java b/src/main/java/com/eactive/eai/common/util/JMSReceiver.java new file mode 100644 index 0000000..fcc2b96 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/JMSReceiver.java @@ -0,0 +1,176 @@ +package com.eactive.eai.common.util; + +import java.io.ByteArrayOutputStream; + +import javax.jms.BytesMessage; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.ObjectMessage; +import javax.jms.TextMessage; +import javax.jms.Topic; +import javax.jms.TopicConnection; +import javax.jms.TopicConnectionFactory; +import javax.jms.TopicSession; +import javax.jms.TopicSubscriber; +import javax.naming.Context; + +import com.eactive.eai.common.jms.JmsServiceLocator; +import com.eactive.eai.common.server.EAIServerManager; + +public class JMSReceiver { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + static final String JMSRES_CONTROL_ERROR = "RECEAIORC001"; + static final String JMSRES_CONNNECTION_FAIL = "RECEAIORC100"; + static final String JMSRES_TIME_OUT = "RECEAIORC200"; + + private TopicConnectionFactory factory; + private TopicConnection con = null; + private TopicSession ses = null; + private Topic topic = null; + private String jms_connectionfactory; + private String topic_name; + + private static String topic_surfix; + static { + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String serverName = eaiServerManager.getLocalServerName(); + + if (serverName != null && serverName.length() >= 11) { + topic_surfix = "_" + serverName.substring(serverName.length() - 5, serverName.length() - 4) + + serverName.substring(serverName.length() - 1, serverName.length()); + } else { + topic_surfix = "_11"; + } + } + + public Object receive(String topicConnectionFactory, String topicName, String traceNumber, int timeout) + throws Exception { + jms_connectionfactory = topicConnectionFactory; + topic_name = topicName + topic_surfix; + startTopicConnection(); + + TopicSubscriber subscriber = null; + + try { + if (con != null && ses != null) { + subscriber = ses.createSubscriber(topic, "JMSCorrelationID = '" + traceNumber + "'", true); + + Message message = (Message) subscriber.receive(timeout); + + if (message == null) { + if (logger.isError()) + logger.error( + "JmsResponseControl] received message is NULL. JMSCorrelationID[" + traceNumber + "]"); + throw new Exception(JMSRES_TIME_OUT); + } + + if (message instanceof ObjectMessage) { + return ((ObjectMessage) message).getObject(); + } else if (message instanceof TextMessage) { + return ((TextMessage) message).getText(); + } else if (message instanceof BytesMessage) { + return getBytesMessage((BytesMessage) message); + } else { + return null; + } + } else { + if (logger.isError()) + logger.error("Topic Connection Failed [" + topicConnectionFactory + "]"); + throw new JMSException(JMSRES_CONNNECTION_FAIL); + } + } catch (Exception e) { + throw new Exception(JMSRES_CONTROL_ERROR); + } finally { + if (subscriber != null) { + try { + subscriber.close(); + subscriber = null; + } catch (Throwable e) { + logger.warn("skip error"); + } + } + close(); + } + } + + private byte[] getBytesMessage(BytesMessage message) throws Exception { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int getSize = -1; + try { + while (true) { + getSize = message.readBytes(buff); + if (getSize > 0) { + bos.write(buff, 0, getSize); + } else { + break; + } + } + return bos.toByteArray(); + } catch (Exception e) { + throw new Exception("Read ByteMessage Error : " + e.getMessage()); + } finally { + try { + if (bos != null) + bos.close(); + } catch (Exception ex) { + logger.warn("skip error"); + } + } + + } + + public void close() { + closeTopicConnection(); + } + + private void startTopicConnection() { + Context ctx = null; + try { + JmsServiceLocator locator = JmsServiceLocator.getInstance(); + + factory = locator.getTopicConnectionFactory(jms_connectionfactory); + con = factory.createTopicConnection(); + ses = con.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE); + topic = locator.getTopic(topic_name); + con.start(); + } catch (Throwable e) { + logger.error("startTopicConnection error", e); + closeTopicConnection(); + if (ctx != null) + try { + ctx.close(); + ctx = null; + } catch (Throwable ex) { + logger.warn("skip error"); + } + } + } + + private void closeTopicConnection() { + if (ses != null) + try { + ses.close(); + ses = null; + } catch (Throwable e) { + logger.warn("skip error"); + } + ; + if (con != null) + try { + con.stop(); + } catch (Throwable e) { + logger.warn("skip error"); + } + ; + if (con != null) + try { + con.close(); + con = null; + } catch (Throwable e) { + logger.warn("skip error"); + } + ; + } +} diff --git a/src/main/java/com/eactive/eai/common/util/JMSSender.java b/src/main/java/com/eactive/eai/common/util/JMSSender.java new file mode 100644 index 0000000..5f55115 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/JMSSender.java @@ -0,0 +1,201 @@ +package com.eactive.eai.common.util; + +import java.util.Iterator; +import java.util.Properties; + +import javax.jms.DeliveryMode; +import javax.jms.JMSException; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.QueueSender; +import javax.jms.QueueSession; +import javax.jms.Session; +import javax.jms.Topic; +import javax.jms.TopicConnection; +import javax.jms.TopicConnectionFactory; +import javax.jms.TopicPublisher; +import javax.jms.TopicSession; + +import com.eactive.eai.common.activemq.AmqQueueProducer; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.jms.JmsServiceLocator; +import com.eactive.eai.env.ElinkConfig; + +public class JMSSender { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static void sendToQueue(Object data, String connectionFactory, String destination, Properties prop) + throws Exception { + try { + //내부에서 AmqPooledConnectionFactory 에서 uri 가져옴 + if (ElinkConfig.isUseInternalQueue()) { + AmqQueueProducer aproducer = new AmqQueueProducer(null, destination); + aproducer.sendMessage((java.io.Serializable) data, prop); + } else { + sendToJmsQueue(data, connectionFactory, destination, prop); + } + + } catch (Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICUL001")); + } finally { + + } + } + + public static void sendToJmsQueue(Object data, String connectionFactory, String destination, Properties prop) + throws JMSException { + + QueueConnectionFactory qconFactory = null; + QueueConnection qcon = null; + QueueSession qsession = null; + Queue queue = null; + QueueSender qsender = null; + + try { + JmsServiceLocator locator = JmsServiceLocator.getInstance(); + + qconFactory = locator.getQueueConnectionFactory(connectionFactory); + if (qconFactory == null) + throw new Exception("qconFactory not found -" + connectionFactory); + qcon = qconFactory.createQueueConnection(); + if (qcon == null) + throw new Exception("createQueueConnection return null"); + qsession = qcon.createQueueSession(false, Session.AUTO_ACKNOWLEDGE); + if (qsession == null) + throw new Exception("createQueueSession return null"); + if (qconFactory == null) + throw new Exception("qconFactory not found -" + connectionFactory); + + queue = locator.getQueue(destination); + qsender = qsession.createSender(queue); + + ObjectMessage msg = qsession.createObjectMessage(); + msg.setObject((java.io.Serializable) data); + + // Properties setting setStringProperties(); + if (prop != null) { + Iterator it = prop.keySet().iterator(); + while (it.hasNext()) { + String key = (String) it.next(); + String value = prop.getProperty(key); + msg.setStringProperty(key, value); + } + } + qsender.setDeliveryMode(DeliveryMode.NON_PERSISTENT); + qsender.send(msg); + } catch (Exception e) { + logger.error("sendToJmsQueue error", e); + // throw new JMSException("RECEAICUL001"); + throw new JMSException(ExceptionUtil.getErrorCode(e, "RECEAICUL001")); + } finally { + try { + if (qsender != null) + qsender.close(); + } catch (Exception e) { + } + try { + if (qsession != null) + qsession.close(); + } catch (Exception e) { + } + try { + if (qcon != null) + qcon.close(); + } catch (Exception e) { + } + } + } + + public static void sendToTopic(Object data, String connectionFactory, String destination, Properties prop, + String correlationID, long ttl) throws Exception { + try { + sendToJmsTopic(data, connectionFactory, destination, prop, correlationID, ttl); + } catch (Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICUL002")); + } finally { + ; + } + } + + public static void sendToJmsTopic(Object data, String connectionFactory, String destination, Properties prop, + String correlationID, long ttl) throws JMSException { + logger.warn("sendToJmsTopic-ST correlationID[" + correlationID + "]"); + TopicConnectionFactory topicFactory = null; + TopicConnection tcon = null; + TopicSession tsession = null; + Topic topic = null; + TopicPublisher publisher = null; + int retryCount = 0; + try { + JmsServiceLocator locator = JmsServiceLocator.getInstance(); + topicFactory = locator.getTopicConnectionFactory(connectionFactory); + if (topicFactory == null) + throw new Exception("topicFactory not found - " + connectionFactory); + // retry 3times + while (retryCount < 3) { + try { + tcon = topicFactory.createTopicConnection(); + } catch (Exception ex) { + retryCount++; + if (retryCount < 3) { +// if(logger.isWarn()) + logger.error("sendToJmsTopic correlationID[" + correlationID + "] retry count=" + retryCount); + continue; + } + throw ex; + } + if (tcon != null) + break; + } + + tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + topic = locator.getTopic(destination); + publisher = tsession.createPublisher(topic); + // TTL Setting + if (ttl > 0) { + publisher.setTimeToLive(ttl); + } + + ObjectMessage msg = tsession.createObjectMessage(); + msg.setObject((java.io.Serializable) data); + if (correlationID != null) { + msg.setJMSCorrelationID(correlationID); + } + if (prop != null) { + Iterator it = prop.keySet().iterator(); + while (it.hasNext()) { + String key = (String) it.next(); + String value = prop.getProperty(key); + msg.setStringProperty(key, value); + } + } + logger.info("publish factory =" + connectionFactory + ", destination=" + destination + ", correlationID=" + + correlationID + ", ttl=" + ttl + ", message=" + msg); + publisher.publish(msg, javax.jms.DeliveryMode.NON_PERSISTENT, javax.jms.Message.DEFAULT_DELIVERY_MODE, ttl); + logger.warn("sendToJmsTopic-ED correlationID[" + correlationID + "]"); + } catch (Exception e) { + logger.error("sendToJmsTopic] send error publish factory =" + connectionFactory + ", destination=" + + destination + ", correlationID=" + correlationID + ", ttl=" + ttl + " " + e.getMessage(), e); + throw new JMSException(ExceptionUtil.getErrorCode(e, "RECEAICUL002")); + } finally { + try { + if (publisher != null) + publisher.close(); + } catch (Exception e) { + } + try { + if (tsession != null) + tsession.close(); + } catch (Exception e) { + } + try { + if (tcon != null) + tcon.close(); + } catch (Exception e) { + } + } + logger.warn("sendToJmsTopic-CL correlationID[" + correlationID + "]"); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/JndiObjectFactoryBeanForElink.java b/src/main/java/com/eactive/eai/common/util/JndiObjectFactoryBeanForElink.java new file mode 100644 index 0000000..04a8c25 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/JndiObjectFactoryBeanForElink.java @@ -0,0 +1,26 @@ +package com.eactive.eai.common.util; + +import org.springframework.jndi.JndiObjectFactoryBean; + +public class JndiObjectFactoryBeanForElink extends JndiObjectFactoryBean { + public void setJndiName(String jndiName) { + super.setJndiName(jndiName); + + if (ContainerUtil.get() == ContainerUtil.TOMCAT) { + super.setResourceRef(true); + } else if (ContainerUtil.get() == ContainerUtil.WEBLOGIC) { + super.setResourceRef(false); + } else if (ContainerUtil.get() == ContainerUtil.JBOSS) { + super.setResourceRef(false); + } else if (ContainerUtil.get() == ContainerUtil.WEBSPHERE) { + super.setResourceRef(false); + } else { + super.setResourceRef(false); + } + } + + public String getJndiName() { + return super.getJndiName(); + } + +} diff --git a/src/main/java/com/eactive/eai/common/util/MessageKeyExtractor.java b/src/main/java/com/eactive/eai/common/util/MessageKeyExtractor.java new file mode 100644 index 0000000..07e8e96 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/MessageKeyExtractor.java @@ -0,0 +1,679 @@ +package com.eactive.eai.common.util; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.common.EAITable; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.messagekey.MessageKeyFldVO; +import com.eactive.eai.common.messagekey.MessageKeyGroupVO; +import com.eactive.eai.common.messagekey.MessageKeyManager; +import com.eactive.eai.common.messagekey.MessageKeyVO; +import com.eactive.eai.transformer.message.ISO8583MessageFactory; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.solab.iso8583.IsoMessage; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONValue; + +import java.nio.charset.Charset; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public final class MessageKeyExtractor { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + /** + * Private 생성자 + * Instance를 생성하지 못함 + */ + private MessageKeyExtractor() + { + + } + + + /** + * 1. 기능 : 메시지에서 특정필드의 값을 추출하는 메소드 + * 2. 처리 개요 : + * - MessageKeyManager에서 Rule정보를 조회 + * - 조회된 Rule을 기반으로 MessageUtil을 통해 기능 처리 + * 3. 주의사항 + * + * @param adapterName 업무 Adapter 이름 + * @param message 변환대상 Object + * @return 결과 String 값(키값) + */ + public static String[] getMessageKeyValue(String fadapterGroupName, Object message) + throws Exception { + return getMessageKeyValue( fadapterGroupName, message, true , false); + } + + + private static String getAdapterCahrset(String adapterGroupName) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO group = adapterManager.getAdapterGroupVO(adapterGroupName); + return StringUtils.defaultIfBlank(group.getMessageEncode(), Charset.defaultCharset().name()); + } + + /** + * 1. 기능 : 메시지에서 특정필드의 값을 추출하는 메소드 + * 2. 처리 개요 : + * - MessageKeyManager에서 Rule정보를 조회 + * - 조회된 Rule을 기반으로 MessageUtil을 통해 기능 처리 + * 3. 주의사항 + * + * @param adapterName 업무 Adapter 이름 + * @param message 변환대상 Object + * @param isTrim trim 여부 + * @param isDynamic true 이면 컬럼 Default값으로 비교 해서 값이 있으면 룰적용 값이 없으면 룰 제거 + * @return 결과 String 값(키값) + */ + public static String[] getMessageKeyValue(String fadapterGroupName, Object message, boolean isTrim, boolean isDynamic) + throws Exception { + + String[] keys = null; + String key = null; + MessageKeyVO msgKey = null; + + String keyCode = fadapterGroupName + "I"; + try { + MessageKeyManager manager = MessageKeyManager.getInstance(); + msgKey = manager.getMessageKey(keyCode); +// String msgType = msgKey.getMsgTp(); + + int groupSize = msgKey.getAlMsgGroups().size(); + + keys = new String[groupSize]; + + if(logger.isInfo()) { + logger.info("MessageKeyExtractor] CURRENT RULE =" + keyCode + +", GROUP SIZE [" + groupSize +"]"); + } + + String colType = msgKey.getMsgTp(); + byte[] bytesMessage = null; + String stringMessage = null; + Object json = null; + + IsoMessage parsedIsoMessage = null; + + // 처음에만 message conversion을 하고 재사용한다.(tuning) + if(groupSize > 0) { + if (EAITable.ASCII_TYPE.equals(colType) || EAITable.EBCDIC_TYPE.equals(colType) +// || EAITable.ISO85-83_TYPE.equals(colType) || EAITable.ISO85-83_H2H_TYPE.equals(colType)) { + || ISO8583MessageFactory.isISO8583Message(colType)) { + if(message instanceof String) { + String inboundCahrset = getAdapterCahrset(fadapterGroupName); + bytesMessage = ((String) message).getBytes(inboundCahrset); + } + else { + bytesMessage = (byte[]) message; + } + } + else if(EAITable.XML_TYPE.equals(colType)) { + stringMessage = (String)message; + } + else if(EAITable.JSON_TYPE.equals(colType)) { + json = JSONValue.parse((String)message); + } + } + + for(int g=0; g0){ + //정상값 위치에 값이 들어올경우 추출한 값과 다를 경우 룰을 제거 한다. + if(tmp != null && ( !keyFld.getBwkColDef().equals(tmp.trim()) ) ){ + key =""; + break; + } + } + } + + // Key 값이 여러 필드로 구성될 경우 고려함 + key = key + tmp; + + if(key!= null && key.length() > 0) { + if (isTrim){ + key = key.trim(); + } + } + } // Field Loop + } + catch(Exception ex) { + if(logger.isWarn()) { + logger.info("MessageKeyExtractor] CURRENT RULE [" + keyCode +"] group idx=" + g + + ", 추출 중 에러 -" + ex.getMessage()); + } + key = ""; + } + keys[g] = key; + } // Group Loop + } catch(Exception e) { + String[] args = new String[1]; + args[0] = fadapterGroupName; + throw new Exception(ExceptionUtil.make(e, "RECEAICME001", args)); + } + return keys; + } + + + public static String subString(String key, int start, int length) { + String returnKey = ""; + + if(start ==0 && length == 0) return key; + + if(key == null || key.length() <(start+length)) { + return key; + } + else { + returnKey = key.substring(start, (start+length)); + } + return returnKey; + } + + /** + * EAI 메시지가 정상인지 오류인지 판별하는 기능 + * + *

+	 * 1. 처리 개요
+	 *   - MessageKeyManager를 통해 메시지 분기 룰 조회
+	 *   - 룰이 있는 경우:
+	 *     1) 메시지 타입(XML/JSON 등)에 따라 지정된 필드값 추출
+	 *     2) XPath/JSONPath 등 특수 패턴 처리
+	 *     3) 추출된 값을 정의된 정상값과 비교 (@예약어 처리)
+	 *   - 룰이 없는 경우 정상 메시지로 처리
+	 *
+	 * 2. 입력 파라미터 예시
+	 *   - XML 메시지, XPath 사용:
+	 *     adapterGroupName: "REST_OUT"
+	 *     message: "0000"
+	 *     분기조건: //response/code = @eq:0000
+	 *
+	 *   - JSON 메시지, JSONPath 사용:
+	 *     adapterGroupName: "REST_OUT"
+	 *     message: {"response":{"code":"0000"}}
+	 *     분기조건: $.response.code = @contains:0000,2000
+	 *
+	 * 3. 주의사항
+	 *   - message 파라미터는 XML의 경우 String 또는 byte[], JSON의 경우 String 타입 지원
+	 *   - 필드값 비교시 대소문자 구분
+	 *   - XPath/JSONPath 사용시 해당 표현식 문법 준수 필요
+	 * 
+ * + * @param fadapterGroupName Adapter 그룹명 (메시지 분기 룰 조회용 키) + * @param message 업무메시지 Object (XML, JSON 등) + * @return boolean 정상 메시지 여부 (정상:true / 오류:false) + * @throws Exception 메시지 처리 중 오류 발생시 + */ + public static boolean isSuccessMessage(String fadapterGroupName, Object message) + throws Exception { + String key = ""; + + String keyCode = fadapterGroupName + "O"; + + try { + MessageKeyManager manager = MessageKeyManager.getInstance(); + MessageKeyVO msgKey = manager.getMessageKey(keyCode); + + if(msgKey == null || "I".equals(msgKey.getExrTp())) { + if (logger.isDebug()) logger.debug("MessageKeyExtractor] isSuccessMessage AdapterGroupName[" + + keyCode + + "] : 메시지 정상여부 확인 룰이 없는 경우 정상메시지변환룰을 사용함."); + return true; + } + + byte[] bytesMessage = null; + String stringMessage = null; + Object json = null; + + String colType = msgKey.getMsgTp(); + int groupSize = msgKey.getAlMsgGroups().size(); + + // 처음에만 message conversion을 하고 재사용한다. (tuning) + if(groupSize > 0) { + if(EAITable.ASCII_TYPE.equals(colType) || EAITable.EBCDIC_TYPE.equals(colType) ) { + bytesMessage = (byte[])message; + } + else if(EAITable.XML_TYPE.equals(colType) ) { + if(message instanceof byte[]) { + stringMessage = new String((byte[])message); + } + else if(message instanceof String) { + stringMessage = (String)message; + } + } + else if(EAITable.JSON_TYPE.equals(colType)) { + json = JSONValue.parse((String)message); + } + } + + for(int g=0; g 0) { + MessageKeyFldVO keyFld = groupVo.getMessageKeyFld(0); + if(keyFld == null) { + throw new Exception("MessageKeyFldVO is null"); + } + + // 메시지 타입별 필드값 추출 + if(EAITable.ASCII_TYPE.equals(colType)) { + key = MessageUtil.getAscBytes(bytesMessage, keyFld.getBwkColStart(), keyFld.getBwkColLength()); + } + else if(EAITable.EBCDIC_TYPE.equals(colType)) { + key = MessageUtil.getEbcdicBytes(bytesMessage, keyFld.getBwkColStart(), keyFld.getBwkColLength()); + } + else if(EAITable.XML_TYPE.equals(colType)) { + if(stringMessage != null) { + key = extractXmlValue(stringMessage, keyFld.getBwkColNm()); + } + } + else if(EAITable.JSON_TYPE.equals(colType)) { + key = extractJsonValue(json, keyFld.getBwkColNm()); + } + else if(EAITable.JAVAOBJECT_TYPE.equals(colType)) { + key = (String)ObjectUtil.getProperty(message, keyFld.getBwkColNm()); + } + + if(key == null) key = ""; + if (logger.isDebug()) logger.debug("MessageKeyExtractor] isSuccessMessage KEY VALUE["+key+"], DEF["+keyFld.getBwkColDef()+"]"); + + if(compareMessageValue(key, keyFld.getBwkColDef())) { + return true; + } + } + } + return false; + } catch(Exception e) { + throw new Exception(ExceptionUtil.make(e,"RECEAICME002")); + } + } + + /** + * 메시지 값 비교를 수행하는 메소드 + */ + private static boolean compareMessageValue(String actualValue, String expectedValue) { + if(actualValue == null) actualValue = ""; + if(expectedValue == null) return false; + + // 예약어로 시작하는 경우 + if(expectedValue.startsWith("@")) { + return compareWithReservedWord(actualValue, expectedValue); + } + + // 일반 equals 비교 + return actualValue.equals(expectedValue); + } + + /** + * 예약어를 포함한 값 비교 처리 + * @param actualValue 실제 값 + * @param definition 정의된 값 (예약어 포함 가능) + * @return 비교 결과 + */ + public static boolean compareWithReservedWord(String actualValue, String definition) { + if (actualValue == null) actualValue = ""; + if (definition == null) return false; + + // 예약어가 없는 경우 단순 equals 비교 + if (!definition.startsWith("@")) { + return actualValue.equals(definition); + } + + try { + // 1. 기본 비교 + if (definition.startsWith("@eq:")) { + return actualValue.equals(definition.substring(4)); + } + if (definition.startsWith("@ne:")) { + return !actualValue.equals(definition.substring(4)); + } + if ("@null".equals(definition)) { + return actualValue == null || actualValue.isEmpty(); + } + if ("@!null".equals(definition)) { + return actualValue != null && !actualValue.isEmpty(); + } + + // 2. 문자열 패턴 + if (definition.startsWith("@contains:")) { + String[] values = definition.substring(10).split(","); + for (String value : values) { + if (actualValue.equals(value.trim())) { + return true; + } + } + return false; + } + if (definition.startsWith("@!contains:")) { + String[] values = definition.substring(11).split(","); + for (String value : values) { + if (actualValue.equals(value.trim())) { + return false; + } + } + return true; + } + if (definition.startsWith("@starts:")) { + return actualValue.startsWith(definition.substring(8)); + } + if (definition.startsWith("@ends:")) { + return actualValue.endsWith(definition.substring(6)); + } + + // 3. 숫자 비교 + if (definition.startsWith("@gt:") || + definition.startsWith("@lt:") || + definition.startsWith("@ge:") || + definition.startsWith("@le:")) { + + double actualNum; + double defNum; + + try { + actualNum = Double.parseDouble(actualValue); + if (definition.startsWith("@gt:")) { + defNum = Double.parseDouble(definition.substring(4)); + return actualNum > defNum; + } + if (definition.startsWith("@lt:")) { + defNum = Double.parseDouble(definition.substring(4)); + return actualNum < defNum; + } + if (definition.startsWith("@ge:")) { + defNum = Double.parseDouble(definition.substring(4)); + return actualNum >= defNum; + } + if (definition.startsWith("@le:")) { + defNum = Double.parseDouble(definition.substring(4)); + return actualNum <= defNum; + } + } catch (NumberFormatException e) { + logger.error("숫자 변환 실패: " + e.getMessage()); + return false; + } + } + + // 인식할 수 없는 예약어 + logger.warn("인식할 수 없는 예약어 패턴: " + definition); + return false; + + } catch (Exception e) { + logger.error("비교 처리 중 오류 발생: " + e.getMessage()); + return false; + } + } + + /** + * XML 메시지에서 필드값을 추출하는 메소드 + */ + private static String extractXmlValue(String message, String fieldName) { + if(fieldName == null) return ""; + + // XPath 처리 + if(fieldName.startsWith("//")) { + return MessageUtil.getXmlFldByXPath(message, fieldName); + } + + // 일반 태그 처리 + return MessageUtil.getXmlFld(message, fieldName); + } + + /** + * JSON 메시지에서 필드값을 추출하는 메소드 + */ + private static String extractJsonValue(Object json, String fieldName) { + if(fieldName == null) return ""; + + // JSONPath 처리 + if(fieldName.startsWith("$.")) { + return MessageUtil.getJSONValueByPath(json, fieldName); + } + + // 일반 필드 처리 + return MessageUtil.getJSONValue(json, fieldName); + } + + public static String[] getMessageKeyValueForRest(String fadapterGroupName, Object message, Properties prop, String type, boolean isTrim) throws Exception { + + String[] keys = null; + String key = null; + MessageKeyVO msgKey = null; + String extUri = null; + Properties header = null; + String method = null; + + // 2009.12.30 + // 어댑터명과 기능구분코드 조합으로 변경 + String keyCode = fadapterGroupName + "I"; + try { + MessageKeyManager manager = MessageKeyManager.getInstance(); + msgKey = manager.getMessageKey(keyCode); + String msgType = msgKey.getMsgTp(); + + if ("url".equals(type)){ + extUri = prop.getProperty("INBOUND_EXTURI"); + if (extUri == null ){ + throw new Exception("Can't find ext url"); + } + } else if ("header".equals(type)){ + Object obj = prop.get("INBOUND_HEADER"); + if (obj == null){ + throw new Exception("Can't find header"); + } + if (obj instanceof Properties){ + header = (Properties)obj; + } else{ + throw new Exception("Can't find header"); + } + } else if ("data".equals(type)){ + method = prop.getProperty("INBOUND_METHOD"); + if (method == null || "".equals(method.trim())){ + throw new Exception("Can't find method"); + } + } else { + throw new Exception ("not support type["+type+"]"); + } + + int groupSize = msgKey.getAlMsgGroups().size(); + + keys = new String[groupSize]; + + if (logger.isInfo()) { + logger.info("MessageKeyExtractor] CURRENT RULE =" + keyCode + ", GROUP SIZE [" + groupSize + "]"); + } + + for (int g = 0; g < groupSize; g++) { + key = ""; + try { + MessageKeyGroupVO groupVo = msgKey.getMessageKeyGroup(g); + int fldSize = groupVo.getMessageKeyFldLength(); + + if (logger.isInfo()) { + logger.info("MessageKeyExtractor] CURRENT RULE [" + keyCode + "] group idx=" + g + + ", CURRENT RULE FIELDS SIZE [" + fldSize + "]"); + } + String colType = msgKey.getMsgTp(); + for (int i = 0; i < fldSize; i++) { + MessageKeyFldVO keyFld = groupVo.getMessageKeyFld(i); + String tmp = ""; + if ("url".equals(type)){ + tmp = getUrlValue(extUri, keyFld.getBwkClassNm(),keyFld.getBwkColNm()); + } else if ("header".equals(type)){ + tmp = header.getProperty(keyFld.getBwkColNm().toLowerCase(),""); + } else if ("data".equals(type)){ + if ("GET".equals(method) || "DELETE".equals(method)){ + if(message instanceof byte[]) { + tmp = getParameterValue(new String((byte[])message), keyFld.getBwkColNm()); + }else if(message instanceof String) { + tmp = getParameterValue((String)message, keyFld.getBwkColNm()); + + } + }else{ + if(EAITable.JSON_TYPE.equals(colType)) { + if(message instanceof byte[]) { + Object json = JSONValue.parse(new String((byte[])message)); + tmp = MessageUtil.getJSONValue(json, keyFld.getBwkColNm()); + + } + else if(message instanceof String) { + Object json = JSONValue.parse((String)message); + tmp = MessageUtil.getJSONValue(json, keyFld.getBwkColNm()); + } + } // end JSON + else if(EAITable.XML_TYPE.equals(colType)) { + if(message instanceof byte[]) { + tmp = MessageUtil.getXmlFld(new String((byte[])message), keyFld.getBwkColNm()); + } + else if(message instanceof String) { + tmp = MessageUtil.getXmlFld((String)message, keyFld.getBwkColNm()); + } + tmp = subString(tmp, keyFld.getBwkColStart(), keyFld.getBwkColLength()); + } + } + } else { + throw new Exception ("not support type["+type+"]"); + } + + + //if (keyFld.getBwkColDef().trim().length() > 0) { + if (StringUtils.isNotBlank(keyFld.getBwkColDef())) { + // 정상값 위치에 값이 들어올경우 + // 추출한 값과 다를 경우 룰을 제거 한다. + if (!keyFld.getBwkColDef().equals(tmp.trim())) { + key = ""; + break; + } + } + + // Key 값이 여러 필드로 구성될 경우 고려함 + if (tmp != null) { + key = key + tmp; + } + + if (key != null && key.length() > 0) { + if (isTrim) { + key = key.trim(); + } + } + + } // Field Loop + } catch (Exception ex) { + if (logger.isWarn()) { + logger.info("MessageKeyExtractor] CURRENT RULE [" + keyCode + "] group idx=" + g + + ", extract error -" + ex.getMessage()); + } + key = ""; + } + keys[g] = key; + } // Group Loop + } catch (Exception e) { + String[] args = new String[1]; + args[0] = fadapterGroupName; + throw new Exception(ExceptionUtil.make(e, "RECEAICME001", args)); + } + return keys; + } + + private static String getUrlValue(String uri, String pattern, String key) throws Exception{ + String[] uris = uri.split("/"); + String[] patterns = pattern.split("/"); + if (patterns.length != uris.length){ + return ""; + } + for(int i=0; i"; + String eTag = ""; + int s_idx = xmlMessage.indexOf(sTag); + int e_idx = xmlMessage.indexOf(eTag); + if (s_idx == -1 || e_idx == -1) { + return ""; + } else { + return xmlMessage.substring(s_idx + sTag.length(), e_idx); + } + } catch (Exception e) { + return ""; + } + } + + public static String getJSONValue(Object message, String key) { + try { + if (message instanceof JSONObject) { + JSONObject json = (JSONObject) message; + Iterator i = json.keySet().iterator(); + while (i.hasNext()) { + String keys = (String) i.next(); + Object obj = json.get(keys); + if (obj instanceof String) { + if (keys.equals(key)) { + return (String) json.get(key); + } + } else { + String value = getJSONValue(obj, key); + if (!"".equals(value)) + return value; + } + } + } else if (message instanceof JSONArray) { + JSONArray arr = (JSONArray) message; + for (int i = 0; i < arr.size(); i++) { + JSONObject json = (JSONObject) arr.get(i); + if (json.containsKey(key)) { + return (String) ((JSONObject) message).get(key); + } else { + String value = getJSONValue(json, key); + if (!"".equals(value)) + return value; + } + } + } + return ""; + } catch (Exception e) { + return ""; + } + } + + public static String getISO8583Fld(IsoMessage isoMessage, int index) { + // Field는 Max 128까지만 정의 + if (index <= 128) { + return isoMessage.getObjectValue(index); + } else { + return ""; + } + } + + public static IsoMessage parseIsoMessage(byte[] message, String messageType) throws Exception { +// ISO8583Message iso8583Message = null; +// if (StringUtils.equals(messageType, EAITable.ISO8583_TYPE)) { +// iso8583Message = new ISO8583Message(); +// } else if (StringUtils.equals(messageType, EAITable.ISO8583_H2H_TYPE)) { +// iso8583Message = new ISO8583H2HMessage(); +// } + ISO8583Message iso8583Message = ISO8583MessageFactory.create(messageType); + + if (iso8583Message == null) { + throw new Exception("Cannot create ISO8583Message, messageType=" + messageType); + } + +// MessageFactory mf = iso8583Message.createMessageFactory(); +// +// // Message Type으로 parseMap을 등록해야 MessageFactory에서 사용가능 +// byte[] _type = new byte[4]; +// System.arraycopy(message, 0, _type, 0, 4); +// +// HashMap parseMap = iso8583Message.getFullSpecMap(mf.getCharacterEncoding()); +// +// mf.setParseMap(Integer.parseInt(new String(_type), 16), parseMap); +// +// IsoMessage m = mf.parseMessage(message, 0); + + IsoMessage m = iso8583Message.parseIsoMessage(message, 0); + + if (logger.isDebugEnabled()) + logger.debug("Parsed Key ISO Message: \n" + dumpIsoMessage(m)); + return m; + } + + public static String dumpIsoMessage(IsoMessage isoMessage) { + return dumpIsoMessage(isoMessage, null); + } + + public static String dumpIsoMessage(IsoMessage isoMessage, ISO8583Message iso8583Message) { + return ISO8583DumpUtil.dumpIsoMessage(isoMessage, iso8583Message); + } + + // EAI헤더의 응답코드가 오류인지 판별하는 기능 + public static boolean checkRspErrCd(String rspErrCd) { + if (rspErrCd == null) { + return false; + } else if (rspErrCd.startsWith("RE") || rspErrCd.startsWith("RF")) { + return false; + } else { + return true; + } + } + +// Message내의 특정 byte를 다른 byte로 치환 + public static byte[] removeBytes(byte[] source, byte removeByte, byte replace) { + + byte[] seBytes = new byte[source.length]; + int sPos = 0; + for (int i = 0; i < source.length; i++) { + if (source[i] == removeByte) { + seBytes[sPos] = replace; + sPos++; + } else { + seBytes[sPos] = source[i]; + sPos++; + } + } + + byte[] newBytes = new byte[sPos]; + + System.arraycopy(seBytes, 0, newBytes, 0, newBytes.length); + return newBytes; + + } + + // 업무오류메시지응답에 대한 XML을 생성 + public static byte[] makeErrMsgXml(String errMsg) { + if (errMsg == null) { + errMsg = ""; + } + StringBuffer sb = new StringBuffer(); + sb.append(""); + sb.append(errMsg); + sb.append(""); + return sb.toString().getBytes(); + } + + public static String makeErrMsgXmlString(String errMsg) { + if (errMsg == null) { + errMsg = ""; + } + StringBuffer sb = new StringBuffer(); + sb.append(""); + sb.append(errMsg); + sb.append(""); + return sb.toString(); + } + + public static byte[] makeErrMsgXml(byte[] errMsg) { + if (errMsg == null) + errMsg = new byte[0]; + return makeErrMsgXml(new String(errMsg)); + } + +// public static byte[] makeStandardErrMsgJson(String errCode, String errMsg, String encode) { +// if (errCode == null) { +// errCode = ""; +// } else { +// errCode = getTobeCode(errCode); +// } +// STDErrorCodeVO vo = STDErrorCodeManager.getInstance().getSTDErrorCode(errCode); +// +// String errCodeCtnt = ""; // 에러내용 +// String actCtnt = ""; // 조치내용 +// +// if (vo != null) { +// errCodeCtnt = vo.getIsdErrCasCt(); +// if (vo.getActnCode() != null) { +// actCtnt = vo.getActnCode().getActnMsgCtnt(); +// } +// } +// +// StringBuffer sb = new StringBuffer(); +// sb.append("{\"messageHeader\":{"); +// sb.append(" \"messageList\" : "); +// sb.append(" ["); +// sb.append(" {\"MSG_CODE\":\"" + errCode + "\",\"MSG_CNTT\":\"" + errCodeCtnt + "\",\"addMessageList\": "); +// sb.append(" ["); +// sb.append(" {\"ADTN_MSG_CODE\":\"\",\"ADTN_MSG_CNTT\":\"\"} "); +// sb.append(" ] "); +// sb.append(" }"); +// sb.append(" ]"); +// sb.append(" }"); +// sb.append("}"); +// +// try { +// return sb.toString().getBytes(encode); +// } catch (UnsupportedEncodingException e) { +// return sb.toString().getBytes(); +// } +// } + + public static byte[] makeStandardErrMsgXml(byte[] errCode) { + if (errCode == null) + errCode = new byte[0]; + return makeErrMsgXml(new String(errCode)); + } + + public static String makeStandardErrMsgXmlString(String errCode) { + return makeErrMsgXmlString(errCode); + } + + public static String replaceMsgXmlString(String Msg) { + if (Msg == null) { + Msg = ""; + } + Msg = Msg.replaceAll("<", "["); + Msg = Msg.replaceAll(">", "]"); + return Msg; + } + + public static byte[] replaceMsgXml(String Msg) { + if (Msg == null) { + Msg = ""; + } + Msg = Msg.replaceAll("<", "["); + Msg = Msg.replaceAll(">", "]"); + return Msg.getBytes(); + } + + public static byte[] replaceMsgXml(byte[] Msg) { + if (Msg == null) + Msg = new byte[0]; + return replaceMsgXml(new String(Msg)); + } + + // 요청,응답 유무를 판단하는 메소드 + public static String transClassify(String tmpTrans) { + String result = "0"; + if (tmpTrans.equals(EAIKeys.TR_REQ) || tmpTrans.equals(EAIKeys.TR_RE_REQ) + || tmpTrans.equals(EAIKeys.TR_CANCEL_REQ)) { + // 요청 거래 + result = "0"; + } else if (tmpTrans.equals(EAIKeys.TR_RES) || tmpTrans.equals(EAIKeys.TR_CANCEL_RES)) { + // 응답거래 + result = "1"; + } + return result; + } + + public static String removeXMLHeader(String xmlMsg) { + + if (xmlMsg == null) { + return ""; + } else { + xmlMsg = xmlMsg.trim(); + } + int sPos = xmlMsg.indexOf(""); + + // 중간에 있는 경우 - CDATA 의 내용 + if (sPos == 0 && ePos > -1) { + xmlMsg = xmlMsg.substring(ePos + 2); + } + return xmlMsg; + } + + public static byte[] removeXMLHeader(byte[] xmlMsg) { + return removeXMLHeader(new String(xmlMsg)).getBytes(); + } + + public static String addXMLHeader(String encode, String xmlMsg) { + if (xmlMsg != null) { + xmlMsg = "" + xmlMsg; + } + return xmlMsg; + } + + public static byte[] addXMLHeader(String encode, byte[] xmlMsg) throws UnsupportedEncodingException { + return addXMLHeader(encode, new String(xmlMsg, encode)).getBytes(encode); + } + + public static String removeXMLRootItem(String xmlString, String rootItemName) { + String prefix = "<" + rootItemName + ">"; + String suffix = ""; + + int s_idx = xmlString.indexOf(prefix); + int e_idx = xmlString.indexOf(suffix); + if (s_idx == -1 || e_idx == -1) { + return xmlString; + } else { + return xmlString.substring(s_idx + prefix.length(), e_idx); + } + } + + public static boolean isBizDataEmpty(Object bizData) { + boolean isEmpty = false; + if (bizData == null) { + isEmpty = true; + } else { + if (bizData instanceof byte[]) { + if (((byte[]) bizData).length == 0) { + isEmpty = true; + } + } else if (bizData instanceof String) { + if (((String) bizData).length() == 0) { + isEmpty = true; + } + } + + } + return isEmpty; + } + + public static String getTobeCode(String oldErrCode){ + if ("".equals(oldErrCode)){ + return STDMessageErrorKeys.SYSTEM_ERROR_CODE_VALUE; + } + if ("RECEAIOWP010".equals(oldErrCode)){ //책임자 승인 타임아웃 + return STDMessageErrorKeys.APPROVE_ERROR_CODE_VALUE; + } + if ("RECEAIFBF010".equals(oldErrCode)){ //책임자 승인자가 존재하지 않는 오류 + return STDMessageErrorKeys.APPROVE_NOT_FOUND_ERROR_CODE_VALUE; + } + if ("RECEAIIRP020,RECEAIIRP120,RECEAIIRP110".indexOf(oldErrCode) >= 0 ){ //유효값 오류 + return STDMessageErrorKeys.VALID_VALUE_ERROR_CODE_VALUE; + } + if ("RECEAIAHA020".equals(oldErrCode)) { // 미로그인 에러 + return STDMessageErrorKeys.NOT_LOGIN_ERROR_CODE_VALUE; + } + if ("RECEAIAHA021".equals(oldErrCode)) { // 중복로그인 에러 + return STDMessageErrorKeys.DUP_LOGIN_ERROR_CODE_VALUE; + } + if ("RECEAIAHA022".equals(oldErrCode)) { // UUID가 같지 않은 에러 + return STDMessageErrorKeys.UUID_MISMATCH_ERROR_CODE_VALUE; + } + if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러 + return STDMessageErrorKeys.RATELIMIT_ERROR_CODE_VALUE; + } + if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode)){ //TIMEOUT일경우 + return STDMessageErrorKeys.TIMEOUT_ERROR_CODE_VALUE; + }else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우 + return STDMessageErrorKeys.BIZ_ERROR_CODE_VALUE; + }else{ + return STDMessageErrorKeys.SYSTEM_ERROR_CODE_VALUE; + } + } + public static String getTobeMessage(String oldErrCode){ + if ("".equals(oldErrCode)){ + return STDMessageErrorKeys.SYSTEM_ERROR_MSG_VALUE; + } + if ("RECEAIOWP010".equals(oldErrCode)){//책임자승인 타임아웃 + return STDMessageErrorKeys.APPROVE_ERROR_MSG_VALUE; + } + if ("RECEAIFBF010".equals(oldErrCode)){ //책임자 승인자가 존재하지 않는 오류 + return STDMessageErrorKeys.APPROVE_NOT_FOUND_ERROR_MSG_VALUE; + } + if ("RECEAIIRP020,RECEAIIRP120,RECEAIIRP110".indexOf(oldErrCode) >= 0 ){//유효값 오류 + return STDMessageErrorKeys.VALID_VALUE_ERROR_MSG_VALUE; + } + if ("RECEAIAHA020".equals(oldErrCode)) { // 미로그인 에러 + return STDMessageErrorKeys.NOT_LOGIN_ERROR_MSG_VALUE; + } + if ("RECEAIAHA021".equals(oldErrCode)) { // 중복로그인 에러 + return STDMessageErrorKeys.DUP_LOGIN_ERROR_MSG_VALUE; + } + if ("RECEAIAHA022".equals(oldErrCode)) { // UUID가 같지 않은 에러 + return STDMessageErrorKeys.UUID_MISMATCH_ERROR_MSG_VALUE; + } + if ("RECEAIIRP072".equals(oldErrCode)) { // 유량제어 초과 에러 + return STDMessageErrorKeys.RATELIMIT_ERROR_MSG_VALUE; + } + if (EAIServiceMonitor.getInstance().isTimeOutCodes(oldErrCode) ){ //TIMEOUT일경우 + return STDMessageErrorKeys.TIMEOUT_ERROR_MSG_VALUE; + }else if (EAIServiceMonitor.getInstance().isBizErrorCodes(oldErrCode)){ //업무오류일경우 + return STDMessageErrorKeys.BIZ_ERROR_MSG_VALUE; + }else{ + return STDMessageErrorKeys.SYSTEM_ERROR_MSG_VALUE; + } + } + + // TODO json tunning 요소 다시 확인해봐야됨(불필요한 파싱) + public static String addJsonRootItem(String jsonString, String rootItemName) { + JSONObject value = (JSONObject) JSONValue.parse(jsonString); + JSONObject root = new JSONObject(); + root.put(rootItemName, value); + return root.toJSONString(); + } + + // TODO json tunning 요소 다시 확인해봐야됨(불필요한 파싱) + public static String removeJsonRootItem(String jsonString, String rootItemName) { + JSONObject value = (JSONObject) JSONValue.parse(jsonString); + JSONObject sub = (JSONObject) value.get(rootItemName); + return sub.toJSONString(); + } + + public static String toAdapterTypeString(Object data, String charset) throws Exception { + if (data instanceof String) { + return (String) data; + } else if (data instanceof byte[]) { + String encode = StringUtils.defaultIfBlank(charset, Charset.defaultCharset().name()); + return new String((byte[]) data, encode); + } else { + throw new Exception("unsupported object - " + data.getClass()); + } + } + + public static boolean isBytesMessage(String messageType) { + return StringUtils.equalsAny(messageType, MessageType.ASC, MessageType.EBC); + } + + /** + * 표준전문에 내외부구분이 없는 사이트를 고려하여 서비스정보(he01)에 internalExternalDvcd 추가
+ * 표준전문의 값을 우선으로 한다(없으면 서비스정보(he01)의 값으로 설정) + */ + public static String getInExDivision(String mapperValue, String eaiSvcValue) { + if (StringUtils.isNotBlank(mapperValue)) { + return mapperValue; + } else { + return eaiSvcValue; + } + } + + public static String makeErrorMessageByMessageType(String msgType, String msgCharset, String code, String msg, + String errorFormat) { + if (StringUtils.equals(msgType, MessageType.JSON)) { + return makeJsonErrorMessage(code, msg, errorFormat); + } else if (StringUtils.equals(msgType, MessageType.XML)) { + return makeXmlErrorMessage(code, msg, msgCharset, errorFormat); + } else { + return "[errCd]" + code + "[/errCd]" + "[errMsg]" + msg + "[/errMsg]"; + } + } + + public static String makeJsonErrorMessage(String code, String msg) { + return makeJsonErrorMessage(code, msg, null); + } + + public static String makeXmlErrorMessage(String code, String msg, String charset) { + return makeXmlErrorMessage(code, msg, charset, null); + } + + public static String makeJsonErrorMessage(String code, String msg, String errorFormat) { + if (StringUtils.isNotBlank(errorFormat)) { + try { + return String.format(errorFormat, code, JSONValue.escape(msg)); + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + return String.format("{\"error\":\"%s\",\"error_description\":\"%s\"}", code, JSONValue.escape(msg)); + } + + public static String makeXmlErrorMessage(String code, String msg, String charset, String errorFormat) { + if (StringUtils.isNotBlank(errorFormat)) { + try { + return String.format(errorFormat, StringUtils.defaultIfBlank(charset, "UTF-8"), code, msg); + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + return String.format( + "%s%s", + StringUtils.defaultIfBlank(charset, "UTF-8"), code, msg); + } + + /** + * XPath를 이용하여 XML 메시지에서 값을 추출 + * @param xmlMessage XML 메시지 + * @param xpath XPath 표현식 + * @return 추출된 값 (실패 시 빈 문자열) + */ + public static String getXmlFldByXPath(String xmlMessage, String xpath) { + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.parse(new BufferedInputStream(new StringInputStream(xmlMessage))); + + XPath xPath = XPathFactory.newInstance().newXPath(); + String value = (String) xPath.evaluate(xpath, document, XPathConstants.STRING); + + return value != null ? value.trim() : ""; + } catch (Exception e) { + logger.error("XPath 처리 중 오류 발생: " + e.getMessage()); + return ""; + } + } + + /** + * JSONPath를 이용하여 JSON 메시지에서 값을 추출 + * @param json JSON 객체 + * @param jsonPath JSONPath 표현식 + * @return 추출된 값 (실패 시 빈 문자열) + */ + public static String getJSONValueByPath(Object json, String jsonPath) { + try { + if(json == null || jsonPath == null) return ""; + + JsonPath path = JsonPath.compile(jsonPath); + Object result = path.read(json); + + if(result == null) return ""; + + // 결과가 기본 타입인 경우 + if(result instanceof String || result instanceof Number || result instanceof Boolean) { + return String.valueOf(result); + } + // JSON 객체나 배열인 경우 + else if(result instanceof JSONObject || result instanceof JSONArray) { + return result.toString(); + } + + return ""; + } catch (Exception e) { + logger.error("JSONPath 처리 중 오류 발생: " + e.getMessage()); + return ""; + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/RunCommandUtil.java b/src/main/java/com/eactive/eai/common/util/RunCommandUtil.java new file mode 100644 index 0000000..e3c2e56 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/RunCommandUtil.java @@ -0,0 +1,105 @@ +package com.eactive.eai.common.util; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.concurrent.TimeUnit; + +public class RunCommandUtil { + public String execCommand(String command) { + String result = ""; + Runtime rt = Runtime.getRuntime(); + Process ps = null; + InputStream is = null; + byte[] buff = null; + + int len; + ByteArrayOutputStream baos = null; + + try { +// System.out.println("Command Exec : " + command); + ps = rt.exec(command); + ps.waitFor(20, TimeUnit.SECONDS); + if (!isError(ps)) { + is = ps.getInputStream(); + len = 0; + buff = new byte[4096]; + baos = new ByteArrayOutputStream(); + + while ((len = is.read(buff)) > 0) { + baos.write(buff, 0, len); + } + + result = new String(baos.toByteArray()); + } + } catch (Exception e) { +// System.out.println(e.toString()); + result = null; + } finally { + if (baos != null) { + try { + baos.close(); + } catch (IOException e) { + baos = null; + } + } + + if (is != null) { + try { + is.close(); + } catch (IOException e) { + is = null; + } + } + + if (ps != null) { + ps.destroy(); + } + } + return result; + } + + private boolean isError(Process ps) { + + boolean result = true; + InputStream es = ps.getErrorStream(); + byte[] buff = new byte[1024]; + + try { + + // check + if (es.available() <= 0) { +// System.out.println("isError = false"); + return false; + } + + if (es.read(buff) != -1) { +// String s = new String(buff); +// System.out.println(s); + result = true; + } else { + result = false; + } + } catch (IOException e) { + result = true; + } finally { + if (es != null) { + try { + es.close(); + } catch (IOException e) { + es = null; + } + } + } + return result; + } + +// public static void main(String[] args) { +// RunCommandUtil r = new RunCommandUtil(); +// String cmd = "/fswas/wasadm/script/eai/was_sna_status.sh"; +//// String cmd = "c:\\ls.bat"; +// String result = r.execCommand(cmd); +// System.out.println("Cmd : " +cmd); +// System.out.println(result); +// } +} diff --git a/src/main/java/com/eactive/eai/common/util/SMSLogUtil.java b/src/main/java/com/eactive/eai/common/util/SMSLogUtil.java new file mode 100644 index 0000000..df42ee0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/SMSLogUtil.java @@ -0,0 +1,86 @@ +package com.eactive.eai.common.util; + +import com.eactive.eai.common.errorcode.ErrorCodeManager; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.EAIServerManager; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.springframework.scheduling.quartz.QuartzJobBean; + +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; + +/** + * 1. 기능 : SMS Message Filtering, Logging Util + * 2. 처리 개요 : SMS 대상 메시지를 Filtering하여 File Write(kbsms.log) 한다. + * - 동일 Message 일정시간 skip + * - 동일 Message count + * - SMS Message layout 정의 + * - reset SMS Message Collections + */ +public class SMSLogUtil extends QuartzJobBean { + + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static Logger loggerSMS = Logger.getLogger(Logger.LOGGER_SMS); + + public static Map m = Collections.synchronizedMap(new HashMap()); + +// SMS 발송 주기 + private static long smsInteval = Long + .parseLong(PropManager.getInstance().getProperty(LogKeys.LOGGER_SMS_PREFIX, LogKeys.SMS_INTERVAL)); + + /** + * management SMS log message - make message layout - check, update log message + * Map + * + * @param svcName + * @param logMsg sms log data format 월일 시간[건수]인스턴스 메시지 1103 + * 13:56:58.715[1]mcc11 HTTP호출에러|MUTMIAS00000170S1 + */ + public static void loggingSMS(String svcName, String logMsg) { + String nodeName = EAIServerManager.getInstance().getGroupInstId(); + String logMessage = nodeName + " " + logMsg + "|" + svcName; + SMSLogVO vo = m.get(logMessage); + if (vo == null) { + m.put(logMessage, new SMSLogVO(System.currentTimeMillis(), 1, logMessage)); + logMessage = "[1]" + logMessage; + writeSMSMessage(logMessage); + } else { + vo.increaseOccurCount(); + if ((System.currentTimeMillis() - vo.getInitTimeMillis()) > (smsInteval * 1000 * 60)) { + vo.setInitTimeMillis(System.currentTimeMillis()); // reflesh init Time + logMessage = "[" + vo.getOccurCount() + "]" + logMessage; + writeSMSMessage(logMessage); + } + } + } + + public static void loggingSMSWithCode(String svcName, String code) { + String error = ErrorCodeManager.getInstance().getMessageEtc(code); + if (code == null) + code = "UNDEFINE"; + loggingSMS(svcName, StringUtil.chunkString(error, 16)); + } + +// management SMS log message for SocketAdapter + public static void loggingSMS4Soc(String adptName, String adptDesc, String code) { + String svcName = StringUtil.chunkString(adptDesc, 10) + "|" + adptName; + loggingSMSWithCode(svcName, code); + } + +// write SMS log use SMS Logger + private static void writeSMSMessage(String logMessage) { + try { + loggerSMS.error(logMessage); + } catch (Exception e) { + logger.error("SMS logging error", e); + } + } + +// Scheduled SMS Log Info Map clear, call by spring config + protected void executeInternal(JobExecutionContext ctx) throws JobExecutionException { + m.clear(); + logger.info("purge SMSLogVO Map!"); + } +} diff --git a/src/main/java/com/eactive/eai/common/util/SMSLogVO.java b/src/main/java/com/eactive/eai/common/util/SMSLogVO.java new file mode 100644 index 0000000..c467b3f --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/SMSLogVO.java @@ -0,0 +1,46 @@ +package com.eactive.eai.common.util; + +import java.io.Serializable; + +public class SMSLogVO implements Serializable { + + private static final long serialVersionUID = 1L; + + private long initTimeMillis; // 최초 logging 시간(millisecond) + private int occurCount; // error 발생 건수 + private String logMessage; // sms log message + + public SMSLogVO(long initTimeMillis, int occurCount, String logMessage) { + this.initTimeMillis = initTimeMillis; + this.occurCount = occurCount; + this.logMessage = logMessage; + } + + public long getInitTimeMillis() { + return initTimeMillis; + } + + public void setInitTimeMillis(long initTimeMillis) { + this.initTimeMillis = initTimeMillis; + } + + public String getLogMessage() { + return logMessage; + } + + public void setLogMessage(String logMessage) { + this.logMessage = logMessage; + } + + public int getOccurCount() { + return occurCount; + } + + public void setOccurCount(int occurCount) { + this.occurCount = occurCount; + } + + public void increaseOccurCount() { + this.occurCount++; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/SecureUtil.java b/src/main/java/com/eactive/eai/common/util/SecureUtil.java new file mode 100644 index 0000000..6275c16 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/SecureUtil.java @@ -0,0 +1,119 @@ +package com.eactive.eai.common.util; + +public final class SecureUtil { + private SecureUtil() { + + } + +// Path Manipulation 보안취약점 필터 + public static String getPMFilter(String sInvalid) { + String sValid = sInvalid; + + if (sValid == null || sValid.equals("")) + return ""; + + sValid = sValid.replaceAll("\\.\\./", ""); + return sValid; + } + +// XSS 보안취약점 필터 + public static String getXSSFilter(String sInvalid) { + String sValid = sInvalid; + if (sInvalid == null || sInvalid.equals("")) { + return ""; + } + sValid = sValid.replaceAll("<", "& lt;").replaceAll(">", "& gt;"); + sValid = sValid.replaceAll("\\(", "& #40;").replaceAll("\\)", "& #41;"); + sValid = sValid.replaceAll("'", "& #39;"); + sValid = sValid.replaceAll("eval\\((.*)\\)", ""); + sValid = sValid.replaceAll("[\\\"\\\'][\\s]*javascript:(.*)[\\\"\\\']", "\"\""); + sValid = sValid.replaceAll("script", ""); + return sValid; + } + +// SQL Injection 보안취약점 필터 + public static String getSQLInjectionFilter(String sInvalid) { + String sValid = sInvalid; + if (sValid == null || sValid.equals("")) + return ""; + + sValid = sValid.replaceAll(" (?i)or ", ""); + sValid = sValid.replaceAll(" (?i)and ", ""); + sValid = sValid.replaceAll(" (?i)select ", ""); + sValid = sValid.replaceAll(" (?i)delete ", ""); + sValid = sValid.replaceAll(" (?i)insert ", ""); + sValid = sValid.replaceAll(";", ""); + sValid = sValid.replaceAll(":", ""); + sValid = sValid.replaceAll("--", ""); + sValid = sValid.replaceAll("\\\\", ""); + sValid = sValid.replaceAll("\'", ""); + sValid = sValid.replaceAll("'", ""); + sValid = sValid.replaceAll("-", ""); + sValid = sValid.replaceAll("[.]", ""); + sValid = sValid.replaceAll("[(]", ""); + sValid = sValid.replaceAll("[)]", ""); + sValid = sValid.replaceAll("\"", ""); + + return sValid; + } + +// Header Manipulation 보안취약점 필터 + public static String getHMFilter(String sInvalid) { + String sValid = sInvalid; + + if (sValid == null || sValid.equals("")) + return ""; + + sValid = sValid.replaceAll("\\n", ""); + sValid = sValid.replaceAll("\\r", ""); + return sValid; + } + +// Dangerous File Inclusion 보안취약점 필터 + public static String getDFIFilter(String sInvalid) { + String sValid = sInvalid; + + if (sValid == null || sValid.length() < 1) + return ""; + + sValid = sValid.replaceAll("\\.\\./|\\./|\\|:|\\*|\"|<|>", ""); + + return sValid; + } + +// Command Injection 보안취약점 필터 + public static String getCIFilter(String sInvalid) { + String sValid = sInvalid; + + if (sValid == null || sValid.equals("")) + return ""; + + sValid = sValid.replaceAll("&", ""); + sValid = sValid.replaceAll("&", ""); + sValid = sValid.replaceAll("&&", ""); + sValid = sValid.replaceAll("|", ""); + sValid = sValid.replaceAll("||", ""); + sValid = sValid.replaceAll(";", ""); + sValid = sValid.replaceAll("\\.\\.", ""); + + return sValid; + } + +// Log Forging 보안취약점 필터 + public static String getLFFilter(String sInvalid) { + String sValid = sInvalid; + + if (sValid == null || sValid.equals("")) + return ""; + + sValid = sValid.replaceAll("\\r", ""); + sValid = sValid.replaceAll("\\n", ""); + sValid = sValid.replaceAll("DEBUG", ""); + sValid = sValid.replaceAll("WARN", ""); + sValid = sValid.replaceAll("INFO", ""); + sValid = sValid.replaceAll("FATAL", ""); + sValid = sValid.replaceAll("ERROR", ""); + + return sValid; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/ServiceUtil.java b/src/main/java/com/eactive/eai/common/util/ServiceUtil.java new file mode 100644 index 0000000..e776245 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/ServiceUtil.java @@ -0,0 +1,49 @@ +package com.eactive.eai.common.util; + +import java.util.Iterator; +import java.util.Properties; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; + +public final class ServiceUtil { + private ServiceUtil() { + + } + +// Adapter의 타임아웃값을 추출 + public static int getTimeoutValue(String adapterGroupName) { + int timeout = -1; // seconds + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + AdapterVO adptVO = null; + Iterator it = adptGrpVO.getAdapters(); + if(it.hasNext()) adptVO = it.next(); + if (adptVO == null) { + timeout = -1; + return timeout; + } + + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties adapterProp = manager.getProperties(adptVO.getPropGroupName()); + + // Socket Adapter Timeout is Seconds + if (Keys.TYPE_NET2.equals(adptGrpVO.getType())) { + timeout = Integer.parseInt(adapterProp.getProperty("timeout")); + } + // HTTP Adapter Timeout is Mili-Seconds + else if (Keys.TYPE_HTTP.equals(adptGrpVO.getType())) { + timeout = Integer.parseInt((String) adapterProp.getProperty("HTTP_TIME_OUT")); + timeout = timeout / 1000; // ms -> src + } + // Other Adapter set Default Timeout + } catch (Exception e) { + timeout = -1; + } + return timeout; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/TranLogUtil.java b/src/main/java/com/eactive/eai/common/util/TranLogUtil.java new file mode 100644 index 0000000..a5171c0 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/TranLogUtil.java @@ -0,0 +1,34 @@ +package com.eactive.eai.common.util; + +import com.eactive.eai.common.message.EAIMessageKeys; + +// 요청/응답 거래의 로그시퀀스를 추출 +public final class TranLogUtil { + private TranLogUtil() { + + } + + public static int getReqLogSeq(String svcPssTp, int svcPssSeq, boolean isComp) { + if (EAIMessageKeys.SINGLE_PROCESS.equals(svcPssTp)) { + return 200; + } else { + if (isComp) { + return (300 + (svcPssSeq * 10) + 1); + } else { + return (200 + (svcPssSeq * 10) + 1); + } + } + } + + public static int getResLogSeq(String svcPssTp, int svcPssSeq, boolean isComp) { + if (EAIMessageKeys.SINGLE_PROCESS.equals(svcPssTp)) { + return 300; + } else { + if (isComp) { + return (300 + (svcPssSeq * 10) + 2); + } else { + return (200 + (svcPssSeq * 10) + 2); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/util/XSSUtil.java b/src/main/java/com/eactive/eai/common/util/XSSUtil.java new file mode 100644 index 0000000..2eccc4e --- /dev/null +++ b/src/main/java/com/eactive/eai/common/util/XSSUtil.java @@ -0,0 +1,45 @@ +package com.eactive.eai.common.util; + +import java.util.HashMap; + +public class XSSUtil { + public static final HashMap m = new HashMap<>(); + static { + m.put(34, """); + m.put(60, "<"); + m.put(62, ">"); + m.put(38, "&"); + m.put(162, "¢"); + m.put(163, "£"); + m.put(165, "¥"); + m.put(8364, "€"); + m.put(167, "§"); + m.put(169, "©"); + m.put(174, "®"); + m.put(8482, "™"); + } + + public static String escape(String str) { + StringBuilder sb = new StringBuilder(); + int charSize = str.length(); + + for (int i = 0; i < charSize; i++) { + char c = str.charAt(i); + int ascCode = (int) c; + + String replaceCode = (String) m.get(ascCode); + if (replaceCode == null) { + if (c > 0x7F) { + sb.append("&#"); + sb.append(Integer.toString(c, 10)); + sb.append(";"); + } else { + sb.append(c); + } + } else { + sb.append(replaceCode); + } + } + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/common/web/AppInitializer.java b/src/main/java/com/eactive/eai/common/web/AppInitializer.java new file mode 100644 index 0000000..7b1e723 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/AppInitializer.java @@ -0,0 +1,546 @@ +package com.eactive.eai.common.web; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.InetAddress; +import java.nio.charset.Charset; +import java.rmi.RemoteException; + +import javax.sql.DataSource; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.remoting.rmi.RmiServiceExporter; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.common.dao.Keys; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleManager; +import com.eactive.eai.common.logger.async.AsyncLoggingPoolManager; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.rmi.RemoteProxy; +import com.eactive.eai.common.routing.rmi.RemoteProxyImpl; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.state.ElinkStateManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ServiceLocator; +import com.eactive.eai.common.util.ServiceLocatorException; +import com.eactive.eai.env.ConfigKeys; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.common.logger.async.AsyncHttpLoggingPoolManager; + +/** + * eLink FrameWork이 초기화(Deploy)될 때 실행되어야 할 작업을 정의 + */ +@SuppressWarnings("deprecation") +public class AppInitializer implements InitializingBean, DisposableBean { + + RemoteProxy remoteProxy = new RemoteProxyImpl(); + Class serviceInterface = RemoteProxy.class; + RmiServiceExporter rmiServiceExporter = new org.springframework.remoting.rmi.RmiServiceExporter(); + + @Autowired + private LifecycleManager lifecycleManager; + + @Autowired + private EAIServerManager eaiServerManager; + + private DataSource dataSource; + + private String instName; + + private String instPort; + + private String tableOwner; + + private String scalable; + + private boolean isScalable; + + private String routerUrl; + + private String systemType; // eLink System Type + private String systemMode = "D"; // eLink System Mode : [P/T/D/S + + private String eaiServerExtractor = ""; + + private String jndiName = ""; + + private int shutdownWaitSecs = 60; + private int shutdownWaitIntervalMs = 500; + + private static final String SHUTDOWN_WAIT_SECS = "shutdown.wait.secs"; + private static final String SHUTDOWN_WAIT_INTERVALMS = "shutdown.wait.intervalms"; + + public String getJndiName() { + return jndiName; + } + + public void setJndiName(String jndiName) { + this.jndiName = jndiName; + } + + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } + + public void setInstName(String instName) { + this.instName = instName; + } + + public void setTableOwner(String tableOwner) { + this.tableOwner = tableOwner; + } + + public void setScalable(String scalable) { + this.scalable = scalable; + } + + public String getScalable() { + return scalable; + } + + public String getSystemType() { + return systemType; + } + + public void setSystemType(String systemType) { + this.systemType = systemType; + } + + public void setSystemMode(String systemMode) { + this.systemMode = systemMode; + } + + private String rmiPort; + private String rmiServicePort; + + public String getRmiPort() { + return rmiPort; + } + + public void setRmiPort(String rmiPort) { + this.rmiPort = rmiPort; + } + + public String getRmiServicePort() { + return rmiServicePort; + } + + public void setRmiServicePort(String rmiServicePort) { + this.rmiServicePort = rmiServicePort; + } + + public String getRouterUrl() { + return routerUrl; + } + + public void setRouterUrl(String routerUrl) { + this.routerUrl = routerUrl; + } + + public String getInstPort() { + return instPort; + } + + public void setInstPort(String instPort) { + this.instPort = instPort; + } + + public String getEaiServerExtractor() { + return eaiServerExtractor; + } + + public void setEaiServerExtractor(String eaiServerExtractor) { + this.eaiServerExtractor = eaiServerExtractor; + } + + public int getShutdownWaitSecs() { + return shutdownWaitSecs; + } + + public void setShutdownWaitSecs(int shutdownWaitSecs) { + this.shutdownWaitSecs = shutdownWaitSecs; + } + + public int getShutdownWaitIntervalMs() { + return shutdownWaitIntervalMs; + } + + public void setShutdownWaitIntervalMs(int shutdownWaitIntervalMs) { + this.shutdownWaitIntervalMs = shutdownWaitIntervalMs; + } + + @SuppressWarnings("deprecation") + private void initRmiServer(int registryPort, int servicePort) throws RemoteException { + rmiServiceExporter.setServiceName("RemoteProxy"); + rmiServiceExporter.setService(remoteProxy); + rmiServiceExporter.setServiceInterface(serviceInterface); + rmiServiceExporter.setRegistryPort(registryPort); + rmiServiceExporter.setServicePort(servicePort); + rmiServiceExporter.setAlwaysCreateRegistry(true); + rmiServiceExporter.afterPropertiesSet(); + } + + private void stopRmiServer() { + if(rmiServiceExporter != null) { + try { + rmiServiceExporter.destroy(); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + } + + /** + * eLink FrameWork의 웹어플리케이션이 될 때 초기화 작업을 수행 + **/ + private void init() { + ElinkStateManager.getInstance().setWaitMaxMs(shutdownWaitSecs * 1000); + ElinkStateManager.getInstance().setSleepIntervalMs(shutdownWaitIntervalMs); + ElinkStateManager.getInstance().starting(); + + if (StringUtils.isBlank(System.getProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEM_TYPE))) { + if (StringUtils.isNotBlank(systemType)) { + System.setProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEM_TYPE, systemType); + } + } + + if (StringUtils.isBlank(System.getProperty("scalable"))) { + if (StringUtils.isNotBlank(scalable)) { + System.setProperty("scalable", scalable); + } + } + + if (StringUtils.isBlank(System.getProperty("router.url"))) { + if (StringUtils.isNotBlank(routerUrl)) { + System.setProperty("router.url", routerUrl); + } + } + + if (StringUtils.isBlank(System.getProperty("eai.server.extractor"))) { + if (StringUtils.isNotBlank(eaiServerExtractor)) { + System.setProperty("eai.server.extractor", eaiServerExtractor); + } + } + + this.isScalable = BooleanUtils.toBoolean(System.getProperty("scalable")); + + if (this.isScalable) { + String uniqueInstName = instName; + if (StringUtils.isBlank(uniqueInstName)) { + uniqueInstName = RandomStringUtils.randomAlphabetic(20); +// }else if(uniqueInstName.length() > 20){ +// int l = uniqueInstName.length(); +// uniqueInstName = uniqueInstName.substring(l-14, l) + "-" + RandomStringUtils.randomAlphabetic(5); + } + System.setProperty(com.eactive.eai.common.server.Keys.SERVER_KEY, uniqueInstName); + } else { + String serverName = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY); + if (serverName == null) { + System.setProperty(com.eactive.eai.common.server.Keys.SERVER_KEY, instName); + } + } + + String instPort = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_PORT); + if (instPort == null) { + System.setProperty(com.eactive.eai.common.server.Keys.SERVER_PORT, this.instPort); + } + /** + * OpenJDK 11 이상 사용 시 -Dfile.encoding 프로퍼티로 ms949, euc-kr + * Charset.defaultCharset()의 값이 지정되지 않는 지정할 수 없는 버그가 존재한다 + * 해당 버그를 Charset을 초기화 하여 우회하는 방법으로 처리한다. + */ + Field charset = null; + try { + charset = Charset.class.getDeclaredField("defaultCharset"); + charset.setAccessible(true); + charset.set(null, null); + } catch (Exception e) { + e.printStackTrace(); + } + + String serverName = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY); + if (serverName == null) { + System.setProperty(com.eactive.eai.common.server.Keys.SERVER_KEY, instName); + } + + String tOwner = System.getProperty(Keys.TABLE_OWNER_KEY); + if (tOwner == null) { + System.setProperty(Keys.TABLE_OWNER_KEY, tableOwner); + } + + String sMode = System.getProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE); + if (sMode == null) { + System.setProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE, systemMode); + } + + // set Spring dataSource to ServiceLoactor + try { + String datasourceName = System.getProperty(Keys.JDBC_NAME_KEY); + if(StringUtils.isEmpty(datasourceName)) { + System.setProperty(Keys.JDBC_NAME_KEY, this.jndiName); + } + + ServiceLocator sl = ServiceLocator.getInstance(); + sl.putDataSource(Keys.EAI_DATASOURCE, dataSource); + System.out.println("\n@@ " + Keys.EAI_DATASOURCE + " = " + dataSource); + } catch (ServiceLocatorException e1) { + System.out.println("ServiceLocator error"); + } + + System.out.println("\n@@ eLink Framework(JSON_TUNE) ====================================================="); + System.out.println("@ eLink System Config Initializing -----------------------"); + + try { + if (StringUtils.isBlank(this.tableOwner)) { + System.out.println("=========================================================================="); + System.out.println("# E R R O R : eLink System Configuration"); + System.out.println("# Check Start Script Rule table Owner : -D" + + com.eactive.eai.common.dao.Keys.TABLE_OWNER_KEY + "="); + System.out.println("# Check Start Script eLink System Mode : -D" + + com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE + "="); + System.out.println("# eLink System Mode : [P/T/D/S]"); + System.out.println("=========================================================================="); + throw new Exception(" Rule Table Owner Not Configured "); + } + if (StringUtils.isBlank(this.systemMode)) { + System.out.println("=========================================================================="); + System.out.println("# E R R O R : eLink System Configuration"); + System.out.println("# Check Start Script Rule table Owner : -D" + + com.eactive.eai.common.dao.Keys.TABLE_OWNER_KEY + "="); + System.out.println("# Check Start Script eLink System Mode : -D" + + com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE + "="); + System.out.println("# eLink System Mode : [P/T/D/S]"); + System.out.println("=========================================================================="); + throw new Exception(" eLink System Mode Not Configured "); + } + System.out.println("=========================================================================="); + System.out.println("# S U C C E S S : eLink System Configuration"); + System.out.println("# Rule table Owner : " + this.tableOwner); + System.out.println("# Rule JDBC Name : " + com.eactive.eai.common.dao.Keys.EAI_DATASOURCE); + System.out.println("# eLink System Mode : " + this.systemMode); + System.out.println("# eLink System Mode : [P(Product)/T(Test)/D(Develop)/S(Staging)]"); + System.out.println( + String.format("# %s : %s", ConfigKeys.USE_INTERNAL_TOPIC, ElinkConfig.isUseCacheTopic())); + System.out.println("=========================================================================="); + System.out.println( + String.format("# %s : %s", SHUTDOWN_WAIT_SECS, shutdownWaitSecs) ); + System.out.println( + String.format("# %s : %s", SHUTDOWN_WAIT_INTERVALMS, shutdownWaitIntervalMs) ); + } catch (Exception e) { + throw new RuntimeException("eLink System Configuration Error - " + e.toString()); + } + + try { + PropManager.getInstance().start(); + } catch (LifecycleException e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RFCEAICWB001")); + } + + try { + Logger.doConfigure(); + } catch (Exception e) { + System.out.println("Logger.doConfigure error"); + } + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * 서버정보 입력 + */ + if (this.isScalable) { + try { + EAIServerVO vo = new EAIServerVO(); + vo.setAddress(InetAddress.getLocalHost().getHostAddress()); + vo.setHostName(InetAddress.getLocalHost().getHostName()); + vo.setName(System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY)); + // scalable merge +// vo.setPort(System.getProperty("tomcat.port.http")); + vo.setPort(System.getProperty("inst.Port")); + vo.setRouterUrl(System.getProperty("router.url")); + + System.out.println("----------------------------"); + System.out.println(vo.toString()); + System.out.println("----------------------------"); + + //addServer 에서 존재여부 체크해서 updateg함 + eaiServerManager.addServer(vo); + logger.info("Success Insert Server Info!!!!"); + System.out.println("Success Insert Server Info!!!!"); + } catch (Exception e) { + logger.error("Refresh Server Info Error~~", e); + System.out.println("Refresh Server Info Error~~" + e.getMessage()); + } + } + + // print system config to logger + logger.warn("=========================================================================="); + logger.warn("# S U C C E S S : eLink System Configuration"); + logger.warn("# Rule table Owner : " + this.tableOwner); + logger.warn("# System Mode : " + this.systemMode); + logger.warn("# System Mode : [P(Product)/T(Test)/D(Develop)/S(Staging)]"); + logger.warn("=========================================================================="); + + // init RMI Server + String pRmiPort = System.getProperty("eai.rmiport"); + if (pRmiPort != null) { + this.rmiPort = pRmiPort; + } + + String pRmiServicePort = System.getProperty("eai.rmiserviceport"); + if (pRmiServicePort != null) { + this.rmiServicePort = pRmiServicePort; + } + + try { + logger.warn("\n@@ eLink RMI Register Port : " + rmiPort + ", Service Port : " + rmiServicePort); + initRmiServer(Integer.parseInt(rmiPort), Integer.parseInt(rmiServicePort)); + } catch (NumberFormatException e2) { + logger.error("eLink System RMI Server Configuration Error check port", e2); + throw new RuntimeException("eLink System RMI Server Configuration Error check port - " + e2.toString()); + } catch (RemoteException e2) { + logger.error("eLink System RMI Server Start Error ", e2); + throw new RuntimeException("eLink System RMI Server Start Error - " + e2.toString()); + } + + // MonitoringContextFactory 기동 + try { + Class clazz = Class.forName("com.eactive.eai.rms.client.context.MonitoringContextFactory"); + Object factory = clazz.newInstance(); + Method method = clazz.getMethod("create"); + method.invoke(factory); + logger.warn("EMSCLIENT AGENT STARTED"); + } catch (InvocationTargetException e) { + logger.error("EMSCLIENT AGENT CANNOT START - " + e.getTargetException().toString(), e.getTargetException()); + e.getTargetException().printStackTrace(); + } catch (Throwable e) { + logger.error("EMSCLIENT AGENT CANNOT START - " + e.toString(), e); + } + + logger.warn("@ eLink Application Initializing -------------------------"); + logger.warn(ElinkConfig.getConfigLog()); + + if (ElinkConfig.isUseAsyncLogging()) { + try { + logger.warn("START AsyncLoggingPoolManager"); + AsyncLoggingPoolManager.getInstance().start(); + logger.warn("SUCCESS AsyncLoggingPoolManager"); + } catch (LifecycleException e) { + logger.error("START AsyncLoggingPoolManager failed.", e); + } + try { + logger.warn("START AsyncHttpLoggingPoolManager"); + AsyncHttpLoggingPoolManager.getInstance().start(); + logger.warn("SUCCESS AsyncHttpLoggingPoolManager"); + } catch (LifecycleException e) { + logger.error("START AsyncHttpLoggingPoolManager failed.", e); + } + } + + try { + lifecycleManager.start(); + } catch (LifecycleException e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB002")); + } + + ElinkStateManager.getInstance().started(); + } + + /** + * eLink FrameWork의 웹어플리케이션이 Undeploy될 때 초기화된 Manager들을 중지시킴 + **/ + public void destroy() { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isWarn()) + logger.warn("@ eLink Application Check current transactions."); + + // Check current transaction & wait specific seconds until finish + ElinkStateManager.getInstance().stop(); + + if (logger.isWarn()) + logger.warn("@ eLink Application destroying."); + + logger.warn("stopRmiServer"); + stopRmiServer(); + + // MonitoringContextFactory 중지 + try { + Class clazz = Class.forName("com.eactive.eai.rms.client.context.MonitoringContextFactory"); + Object factory = clazz.newInstance(); + Method method = clazz.getMethod("stop"); + method.invoke(factory); + logger.warn("EMSCLIENT AGENT STOPPED"); + } catch (InvocationTargetException e) { + logger.error("EMSCLIENT AGENT CANNOT STOP - " + e.getTargetException().toString(), e.getTargetException()); + e.getTargetException().printStackTrace(); + } catch (Throwable e) { + logger.error("EMSCLIENT AGENT CANNOT STOP - " + e.toString(), e); + } + + /** + * 서버정보 삭제 + */ + if (this.isScalable) { + String instanceName = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY); + logger.info("Starting, Delete Server Info: " + instanceName); + System.out.println("Starting, Delete Server Info: " + instanceName); + + if (StringUtils.isNotBlank(instanceName)) { + try { + eaiServerManager.removeServer(instanceName); + + logger.info("Success Delete Server Info: " + instanceName); + System.out.println("Success Delete Server Info: " + instanceName); + } catch (Exception e) { + logger.error("Delete Server Info Error~~", e); + System.out.println("Delete Server Info Error~~" + instanceName + e.getMessage()); + } + } + } + + try { + lifecycleManager.stop(); + } catch (LifecycleException e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB002")); + } + + try { + PropManager.getInstance().stop(); + } catch (LifecycleException e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB004")); + } + + try { + SocketAdapterManager.getInstance().stop(); + } catch (Exception e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB005")); + } + + if (ElinkConfig.isUseAsyncLogging()) { + try { + logger.warn("STOP AsyncLoggingPoolManager"); + AsyncLoggingPoolManager.getInstance().stop(); + logger.warn("STOPPED AsyncLoggingPoolManager"); + } catch (LifecycleException e) { + logger.error("STOP AsyncLoggingPoolManager failed.", e); + } + } + + logger.warn("STOP Logger"); + Logger.stop(); + System.out.println("\n\n"); + } + + @Override + public void afterPropertiesSet() throws Exception { + init(); + } +} diff --git a/src/main/java/com/eactive/eai/common/web/ErrorCodeLoader.java b/src/main/java/com/eactive/eai/common/web/ErrorCodeLoader.java new file mode 100644 index 0000000..9d6e62c --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/ErrorCodeLoader.java @@ -0,0 +1,229 @@ +package com.eactive.eai.common.web; +//package com.eactive.eai.common.web; +// +//import com.eactive.eai.transformer.function.Function; +//import com.eactive.eai.transformer.function.FunctionDefinition; +//import com.eactive.eai.transformer.function.ParameterDefinition; +//import com.eactive.eai.transformer.layout.Types; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import java.io.DataInputStream; +//import java.io.DataOutputStream; +//import java.io.File; +//import java.io.FileInputStream; +//import java.io.FileOutputStream; +//import java.io.InputStream; +//import java.io.OutputStream; +//import java.sql.Connection; +//import java.sql.PreparedStatement; +//import java.sql.Statement; +//import java.util.ArrayList; +//import java.util.Iterator; +//import java.util.List; +//import com.eactive.eai.transformer.tools.loader.AbstractExcelLoader; +//import com.eactive.eai.transformer.tools.loader.ExcelLoader; +//import com.eactive.eai.transformer.tools.util.ConstantUtil; +//import com.eactive.eai.transformer.tools.util.ExcelSheet; +// +//import com.eactive.eai.common.dao.Keys; +// +///** +//* 1. 기능 : 정형화된 EXCEL 문서를 통해 DB의 메시지 테이블에 insert하는 sql문을 생성한다. +//* 2. 처리 개요 : XLS메시지 테이블에 insert하는 sql문을 생성한다. +//* +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : AbstractExcelLoader.java +//* @since : +//* : +//*/ +// +//public class ErrorCodeLoader extends AbstractExcelLoader +//{ +// private static final int DATA_ROW_OFFSET = 4; +// +// private static final int COL_MSGKEY = 6; +// private static final int COL_MSGTXT = 7; +// +// private static final String QUERY_PREFIX = "INSERT INTO " + Keys.TABLE_OWNER + "TSMSGM001 (MSGKEY, MSGTXT) VALUES "; +// +// private static final String FILE_NAME = "insertQuery.sql"; +// +// +// public ErrorCodeLoader() { +// super(ErrorCodeLoader.class.getName().substring(ErrorCodeLoader.class.getName().lastIndexOf('.') + 1)); +// } +// +// /** +// * 1. 기능 : AbstractExcelLoader에 선언된 메소드 정의 +// * 2. 처리 개요 : AbstractExcelLoader에 선언된 메소드 정의 +// * 3. 주의사항 +// * +// * @return Obejct +// * @exception +// **/ +// public Object parseExcelSheet(ExcelSheet[] sheets) +// { +// return ""; +// } +// +// /** +// * 1. 기능 : ExcelSheet를 파싱하여 sql화일 을 생성 +// * 2. 처리 개요 : parseExcelSheet를 통해 ExcelSheet를 파싱하여 sql화일을 생성한다. +// * 3. 주의사항 +// * +// * @return void +// * @exception +// **/ +// public void loadExcelSheet(ExcelSheet[] sheets) +// { +// +// ExcelSheet sheet = sheets[0]; +// String directory = null; +// try { +// directory = sheet.getCellString(2,3); +// } catch(Exception e) { +// e.printStackTrace(); +// throw new RuntimeException("ErrorCodeLoader] loadExcelSheet>>"+e.getMessage()); +// } +// System.out.println("directory : "+ directory); +// +// DataOutputStream out = getOutputFile(FILE_NAME, directory); +// StringBuffer sb = new StringBuffer(); +// +// for (int currentRow = DATA_ROW_OFFSET; sheet.existRow(currentRow); ++currentRow) { +// try { +// +// String msgKey = sheet.getCellString(currentRow, COL_MSGKEY); +// String msgTxt = sheet.getCellString(currentRow, COL_MSGTXT); +// +// if (msgKey.trim().length() > 0 && msgTxt.trim().length() > 0) { +// sb.append(QUERY_PREFIX); +// sb.append("( " + quote(msgKey) + " , " + quote(msgTxt) + "); \n"); +// +// System.out.println("Query : " + sb.toString()); +// +// +// } +// else { +// break; +// } +// +// } catch (Exception e) { +// println("[ERROR] !!!!! " + e.getMessage() + " - ROW: " + currentRow); +// e.printStackTrace(); +// +// } +// } +// +// if(out != null){ +// try{ +// out.write(sb.toString().getBytes()); +// }catch (Exception e){ +// e.printStackTrace(); +// } +// +// } +// else { +// System.out.println("out is null"); +// } +// +// } +// +// /** +// * 1. 기능 : 생성할 화일의 DataOutputStream을 생성 +// * 2. 처리 개요 : ExcelSheet에 정의된 화일명과 위치를 통해 생성할 화일의 DataOutputStream을 생성하여 리턴한다. +// * 3. 주의사항 +// * +// * @return DataOutputStream +// * @exception +// **/ +// +// public DataOutputStream getOutputFile(String name, String dir) { +// +// String outFile = ""; +// File out = new File(dir); +// +// if(!out.exists()){ +// if(!out.mkdir()) +// System.out.println(outFile+" Faild make directory"); +// } +// outFile = dir+"/"+name; +// +// DataOutputStream outs = null; +// +// try { +// outs = new DataOutputStream( new FileOutputStream(outFile, false)); +// +// if(outs != null) +// System.out.println("ErrorCodeLoader ] File Name - " + outFile +" created."); +// else +// System.out.println("ErrorCodeLoader ] File Name - " + outFile +" can't create."); +// +// } catch(Exception _ex) { +// _ex.printStackTrace(); +// } +// return outs; +// +// } +// +// /** +// * 1. 기능 : 문자열을 받아서 단일 따옴표로 감싸 반환한다. +// * 2. 처리 개요 : 문자열을 받아서 단일 따옴표로 감싸 반환한다. +// * 이때 문자열 중 단일 따움표(')가 있으면 이중 단일 따옴표('')로 변환한다. +// * 3. 주의사항 +// * +// * @param String str +// * @return String 단일 따옴표로 감싼 문자열 +// **/ +// private String quote(String str){ +// +// StringBuffer sqlStr = new StringBuffer(); +// +// if(str == null) { +// return ""; +// } +// else { +// sqlStr.append("'"); +// for(int i = 0; i < str.length(); i++) { +// if(str.charAt(i) == '\'') { +// sqlStr.append("''"); +// } +// else { +// sqlStr.append(str.charAt(i)); +// } +// +// } +// sqlStr.append("'"); +// return sqlStr.toString(); +// } +// } +// +// public void clearData(ExcelSheet[] sheets) { +// } +// +// public static void main(String[] argv) { +// +// InputStream in = null; +// ErrorCodeLoader loader = new ErrorCodeLoader(); +// +// try { +// +//// in = ErrorCodeLoader.class.getClassLoader().getResourceAsStream(argv[0]); +// in = new DataInputStream(new FileInputStream(argv[0])); +// ExcelSheet[] sheets = ExcelSheet.getExcelSheets(in); +// +//// ExcelLoader loader = (ExcelLoader)Class.forName("ErrorCodeLoader.class").newInstance(); +// +// loader.loadExcelSheet(sheets); +// +// } catch (Exception e) { +// e.printStackTrace(); +// } finally { +// if (in != null) try { in.close(); } catch (Exception e) {}; +// } +// +// } +// +//} diff --git a/src/main/java/com/eactive/eai/common/web/FrontFilter.java b/src/main/java/com/eactive/eai/common/web/FrontFilter.java new file mode 100644 index 0000000..e045156 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/FrontFilter.java @@ -0,0 +1,45 @@ +package com.eactive.eai.common.web; + +import javax.servlet.*; +import java.io.IOException; + +public class FrontFilter implements Filter { + private static int count; + + private FilterConfig config; + + public void destroy() { + + } + + public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) + throws IOException, ServletException { + try { + increase(); + chain.doFilter(req, res); + } catch (Exception e) { + throw new ServletException(e.getMessage()); + } finally { + descrease(); + } + } + + public void init(FilterConfig config) throws ServletException { + this.config = config; + if (this.config != null) { + this.config.getFilterName(); + } + } + + private synchronized void increase() { + count++; + } + + private synchronized void descrease() { + count--; + } + + public static int count() { + return count; + } +} diff --git a/src/main/java/com/eactive/eai/common/web/GWAppInitializer.java b/src/main/java/com/eactive/eai/common/web/GWAppInitializer.java new file mode 100644 index 0000000..4e5af07 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/GWAppInitializer.java @@ -0,0 +1,526 @@ +package com.eactive.eai.common.web; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.InetAddress; +import java.nio.charset.Charset; +import java.rmi.RemoteException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.sql.DataSource; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.remoting.rmi.RmiServiceExporter; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.common.dao.Keys; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleManager; +import com.eactive.eai.common.logger.async.AsyncLoggingPoolManager; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.rmi.GWRemoteProxy; +import com.eactive.eai.common.routing.rmi.GWRemoteProxyImpl; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.state.ElinkStateManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ServiceLocator; +import com.eactive.eai.common.util.ServiceLocatorException; +import com.eactive.eai.env.ConfigKeys; +import com.eactive.eai.env.ElinkConfig; + +/** + * eLink-GW FrameWork이 초기화(Deploy)될 때 실행되어야 할 작업을 정의 + */ +@SuppressWarnings("deprecation") +public class GWAppInitializer implements InitializingBean, DisposableBean { + + GWRemoteProxy remoteProxy = new GWRemoteProxyImpl(); + Class serviceInterface = GWRemoteProxy.class; + RmiServiceExporter rmiServiceExporter = new org.springframework.remoting.rmi.RmiServiceExporter(); + + @Autowired + private LifecycleManager lifecycleManager; + + @Autowired + private EAIServerManager eaiServerManager; + + private DataSource dataSource; + + private String instName; + + private String instPort; + + private String tableOwner; + + private String scalable; + + private boolean isScalable; + + private String routerUrl; + + private String systemType; // eLink System Type + private String systemMode = "D"; // eLink-GW System Mode : [P/T/D/S] + + private String eaiServerExtractor = ""; + + private String jndiName = ""; + + private int shutdownWaitSecs = 60; + private int shutdownWaitIntervalMs = 500; + + private static final String SHUTDOWN_WAIT_SECS = "shutdown.wait.secs"; + private static final String SHUTDOWN_WAIT_INTERVALMS = "shutdown.wait.intervalms"; + + public String getJndiName() { + return jndiName; + } + + public void setJndiName(String jndiName) { + this.jndiName = jndiName; + } + + public void setDataSource(DataSource dataSource) { + this.dataSource = dataSource; + } + + public void setInstName(String instName) { + this.instName = instName; + } + + public void setTableOwner(String tableOwner) { + this.tableOwner = tableOwner; + } + + public void setScalable(String scalable) { + this.scalable = scalable; + } + + public String getScalable() { + return scalable; + } + + public String getSystemType() { + return systemType; + } + + public void setSystemType(String systemType) { + this.systemType = systemType; + } + + public void setSystemMode(String systemMode) { + this.systemMode = systemMode; + } + + private String rmiPort; + private String rmiServicePort; + + public String getRmiPort() { + return rmiPort; + } + + public void setRmiPort(String rmiPort) { + this.rmiPort = rmiPort; + } + + public String getRmiServicePort() { + return rmiServicePort; + } + + public void setRmiServicePort(String rmiServicePort) { + this.rmiServicePort = rmiServicePort; + } + + public String getRouterUrl() { + return routerUrl; + } + + public void setRouterUrl(String routerUrl) { + this.routerUrl = routerUrl; + } + + public String getInstPort() { + return instPort; + } + + public void setInstPort(String instPort) { + this.instPort = instPort; + } + + public String getEaiServerExtractor() { + return eaiServerExtractor; + } + + public void setEaiServerExtractor(String eaiServerExtractor) { + this.eaiServerExtractor = eaiServerExtractor; + } + + public int getShutdownWaitSecs() { + return shutdownWaitSecs; + } + + public void setShutdownWaitSecs(int shutdownWaitSecs) { + this.shutdownWaitSecs = shutdownWaitSecs; + } + + public int getShutdownWaitIntervalMs() { + return shutdownWaitIntervalMs; + } + + public void setShutdownWaitIntervalMs(int shutdownWaitIntervalMs) { + this.shutdownWaitIntervalMs = shutdownWaitIntervalMs; + } + + @SuppressWarnings("deprecation") + private void initRmiServer(int registryPort, int servicePort) throws RemoteException { + rmiServiceExporter.setServiceName("RemoteProxy"); + rmiServiceExporter.setService(remoteProxy); + rmiServiceExporter.setServiceInterface(serviceInterface); + rmiServiceExporter.setRegistryPort(registryPort); + rmiServiceExporter.setServicePort(servicePort); + rmiServiceExporter.setAlwaysCreateRegistry(true); + rmiServiceExporter.afterPropertiesSet(); + } + + private void stopRmiServer() { + if(rmiServiceExporter != null) { + try { + rmiServiceExporter.destroy(); + } catch (RemoteException e) { + e.printStackTrace(); + } + } + } + /** + * 기능 : eLink-GW FrameWork의 웹어플리케이션이 될 때 초기화 작업을 수행 + **/ + private void init() { + ElinkStateManager.getInstance().setWaitMaxMs(shutdownWaitSecs * 1000); + ElinkStateManager.getInstance().setSleepIntervalMs(shutdownWaitIntervalMs); + ElinkStateManager.getInstance().starting(); + + if (StringUtils.isBlank(System.getProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEM_TYPE))) { + if (StringUtils.isNotBlank(systemType)) { + System.setProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEM_TYPE, systemType); + } + } + + if (StringUtils.isBlank(System.getProperty("scalable"))) { + if (StringUtils.isNotBlank(scalable)) { + System.setProperty("scalable", scalable); + } + } + + if (StringUtils.isBlank(System.getProperty("router.url"))) { + if (StringUtils.isNotBlank(routerUrl)) { + System.setProperty("router.url", routerUrl); + } + } + + this.isScalable = BooleanUtils.toBoolean(System.getProperty("scalable")); + + if (this.isScalable) { + String uniqueInstName = instName; + if (StringUtils.isBlank(uniqueInstName)) { + uniqueInstName = RandomStringUtils.randomAlphabetic(20); +// }else if(uniqueInstName.length() > 20){ +// int l = uniqueInstName.length(); +// uniqueInstName = uniqueInstName.substring(l-14, l) + "-" + RandomStringUtils.randomAlphabetic(5); + } + System.setProperty(com.eactive.eai.common.server.Keys.SERVER_KEY, uniqueInstName); + } else { + String serverName = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY); + if (serverName == null) { + System.setProperty(com.eactive.eai.common.server.Keys.SERVER_KEY, instName); + } + } + + String instPort = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_PORT); + if (instPort == null) { + System.setProperty(com.eactive.eai.common.server.Keys.SERVER_PORT, this.instPort); + } + /** + * OpenJDK 11 이상 사용 시 -Dfile.encoding 프로퍼티로 ms949, euc-kr + * Charset.defaultCharset()의 값이 지정되지 않는 지정할 수 없는 버그가 존재한다 + * 해당 버그를 Charset을 초기화 하여 우회하는 방법으로 처리한다. + */ + Field charset = null; + try { + charset = Charset.class.getDeclaredField("defaultCharset"); + charset.setAccessible(true); + charset.set(null, null); + } catch (Exception e) { + e.printStackTrace(); + } + + String serverName = System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY); + if (serverName == null) { + System.setProperty(com.eactive.eai.common.server.Keys.SERVER_KEY, instName); + } + + String tOwner = System.getProperty(Keys.TABLE_OWNER_KEY); + if (tOwner == null) { + System.setProperty(Keys.TABLE_OWNER_KEY, tableOwner); + } + + String sMode = System.getProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE); + if (sMode == null) { + System.setProperty(com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE, systemMode); + } + + // set Spring dataSource to ServiceLoactor + try { + String datasourceName = System.getProperty(Keys.JDBC_NAME_KEY); + if(StringUtils.isEmpty(datasourceName)) { + System.setProperty(Keys.JDBC_NAME_KEY, this.jndiName); + } + ServiceLocator sl = ServiceLocator.getInstance(); + sl.putDataSource(Keys.EAI_DATASOURCE, dataSource); + System.out.println("\n@@ " + Keys.EAI_DATASOURCE + " = " + dataSource); + } catch (ServiceLocatorException e1) { + System.out.println("ServiceLocator error"); + } + + System.out.println("@ eLink-GW System Config Initializing -----------------------"); + + try { + if (StringUtils.isBlank(this.tableOwner)) { + System.out.println("=========================================================================="); + System.out.println("# E R R O R : eLink System Configuration"); + System.out.println("# Check Start Script Rule table Owner : -D" + + com.eactive.eai.common.dao.Keys.TABLE_OWNER_KEY + "="); + System.out.println("# Check Start Script eLink System Mode : -D" + + com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE + "="); + System.out.println("# eLink System Mode : [P/T/D/S]"); + System.out.println("=========================================================================="); + throw new Exception(" Rule Table Owner Not Configured "); + } + if (StringUtils.isBlank(this.systemMode)) { + System.out.println("=========================================================================="); + System.out.println("# E R R O R : eLink System Configuration"); + System.out.println("# Check Start Script Rule table Owner : -D" + + com.eactive.eai.common.dao.Keys.TABLE_OWNER_KEY + "="); + System.out.println("# Check Start Script eLink System Mode : -D" + + com.eactive.eai.common.server.Keys.EAI_SYSTEMMODE + "="); + System.out.println("# eLink System Mode : [P/T/D/S]"); + System.out.println("=========================================================================="); + throw new Exception(" eLink System Mode Not Configured "); + } + System.out.println("=========================================================================="); + System.out.println("# S U C C E S S : eLink System Configuration"); + System.out.println("# Rule table Owner : " + this.tableOwner); + System.out.println("# Rule JDBC Name : " + com.eactive.eai.common.dao.Keys.EAI_DATASOURCE); + System.out.println("# eLink System Mode : " + this.systemMode); + System.out.println("# eLink System Mode : [P(Product)/T(Test)/D(Develop)/S(Staging)]"); + System.out.println( + String.format("# %s : %s", ConfigKeys.USE_INTERNAL_TOPIC, ElinkConfig.isUseCacheTopic())); + System.out.println("=========================================================================="); + System.out.println( + String.format("# %s : %s", SHUTDOWN_WAIT_SECS, shutdownWaitSecs) ); + System.out.println( + String.format("# %s : %s", SHUTDOWN_WAIT_INTERVALMS, shutdownWaitIntervalMs) ); + + } catch (Exception e) { + throw new RuntimeException("eLink-GW System Configuration Error - " + e.toString()); + } + + try { + PropManager.getInstance().start(); + } catch (LifecycleException e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RFCEAICWB001")); + } + + try { + Logger.doConfigure(); + } catch (Exception e) { + System.out.println("Logger.doConfigure error"); + } + + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * 서버정보 입력 + */ + if (this.isScalable) { + try { + EAIServerVO vo = new EAIServerVO(); + vo.setAddress(InetAddress.getLocalHost().getHostAddress()); + vo.setHostName(InetAddress.getLocalHost().getHostName()); + vo.setName(System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY)); + // scalable merge +// vo.setPort(System.getProperty("tomcat.port.http")); + vo.setPort(System.getProperty("inst.Port")); + vo.setRouterUrl(System.getProperty("router.url")); + String failoverSvr = getFailoverSvr(System.getProperty(com.eactive.eai.common.server.Keys.SERVER_KEY)); + if (failoverSvr != null) { + vo.setFailoverSvr(failoverSvr); + } + System.out.println("----------------------------"); + System.out.println(vo.toString()); + System.out.println("----------------------------"); + + //addServer 에서 존재여부 체크해서 updateg함 + eaiServerManager.addServer(vo); + logger.info("Success Insert Server Info!!!!"); + System.out.println("Success Insert Server Info!!!!"); + } catch (Exception e) { + logger.error("Refresh Server Info Error~~", e); + System.out.println("Refresh Server Info Error~~"+ e.getMessage()); + } + } + + // print system config to logger + logger.warn("=========================================================================="); + logger.warn("# S U C C E S S : eLink-GW System Configuration"); + logger.warn("# Rule table Owner : " + this.tableOwner); + logger.warn("# System Mode : " + this.systemMode); + logger.warn("# eLink-GW System Mode : [P(Product)/T(Test)/D(Develop)/S(Staging)]"); + logger.warn("=========================================================================="); + + // init RMI Server + String pRmiPort = System.getProperty("eai.rmiport"); + if (pRmiPort != null) { + this.rmiPort = pRmiPort; + } + + String pRmiServicePort = System.getProperty("eai.rmiserviceport"); + if (pRmiServicePort != null) { + this.rmiServicePort = pRmiServicePort; + } + + try { + logger.warn("\n@@ eLink-GW RMI Register Port : " + rmiPort + ", Service Port : " + rmiServicePort); + initRmiServer(Integer.parseInt(rmiPort), Integer.parseInt(rmiServicePort)); + } catch (NumberFormatException e2) { + logger.error("eLink-GW System RMI Server Configuration Error check port", e2); + throw new RuntimeException("eLink-GW System RMI Server Configuration Error check port - " + e2.toString()); + } catch (RemoteException e2) { + logger.error("eLink-GW System RMI Server Start Error ", e2); + throw new RuntimeException("eLink-GW System RMI Server Start Error - " + e2.toString()); + } + + // MonitoringContextFactory 기동 + try { + Class clazz = Class.forName("com.eactive.eai.rms.client.context.MonitoringContextFactory"); + Object factory = clazz.newInstance(); + Method method = clazz.getMethod("create"); + method.invoke(factory); + logger.warn("EMSCLIENT AGENT STARTED"); + } catch (InvocationTargetException e) { + logger.error("EMSCLIENT AGENT CANNOT START - " + e.getTargetException().toString(), e.getTargetException()); + e.getTargetException().printStackTrace(); + } catch (Throwable e) { + logger.error("EMSCLIENT AGENT CANNOT START - " + e.toString(), e); + } + + logger.warn("@ eLink-GW Application Initializing -------------------------"); + logger.warn(ElinkConfig.getConfigLog()); + + try { + lifecycleManager.start(); + } catch (LifecycleException e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB002")); + } + ElinkStateManager.getInstance().started(); + + } + + /** + * eLink-GW FrameWork의 웹어플리케이션이 Undeploy될 때 초기화된 Manager들을 중지시킴 + **/ + public void destroy() { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isWarn()) + logger.warn("@ eLink Application destroying."); + + // Check current transaction & wait specific seconds until finish + ElinkStateManager.getInstance().stop(); + + logger.warn("stopRmiServer"); + stopRmiServer(); + + // MonitoringContextFactory 중지 + try { + Class clazz = Class.forName("com.eactive.eai.rms.client.context.MonitoringContextFactory"); + Object factory = clazz.newInstance(); + Method method = clazz.getMethod("stop"); + method.invoke(factory); + logger.warn("EMSCLIENT AGENT STOPPED"); + } catch (InvocationTargetException e) { + logger.error("EMSCLIENT AGENT CANNOT STOP - " + e.getTargetException().toString(), e.getTargetException()); + e.getTargetException().printStackTrace(); + } catch (Throwable e) { + logger.error("EMSCLIENT AGENT CANNOT STOP - " + e.toString(), e); + } + +// /** +// * 서버정보 삭제 GW 일경우 서버정보 삭제 안함- statefulset 형태로 fgw-0, fgw-1 의 host 명 으로 됨 +// */ +// if (this.isScalable) { +// String instanceName = System.getProperty(Keys.SERVER_KEY); +// logger.info("Starting, Delete Server Info: " + instanceName); +// System.out.println("Starting, Delete Server Info: " + instanceName); +// +// if (StringUtils.isNotBlank(instanceName)) { +// try { +// eaiServerManager.removeServer(instanceName); +// +// logger.info("Success Delete Server Info: " + instanceName); +// System.out.println("Success Delete Server Info: " + instanceName); +// } catch (Exception e) { +// logger.error("Delete Server Info Error~~", e); +// System.out.println("Delete Server Info Error~~" + instanceName + e.getMessage()); +// } +// } +// } + + try { + lifecycleManager.stop(); + } catch (LifecycleException e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB002")); + } + + try { + PropManager.getInstance().stop(); + } catch (LifecycleException e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB004")); + } + + try { + SocketAdapterManager.getInstance().stop(); + } catch (Exception e) { + throw new RuntimeException(ExceptionUtil.getErrorCode(e, "RECEAICWB005")); + } + System.out.println("\n\n"); + } + + @Override + public void afterPropertiesSet() throws Exception { + init(); + } + private String getFailoverSvr(String instName) { + Matcher matcher = Pattern.compile("([\\S]*)-([0-9]{1,2})$").matcher(instName); + String failover = ""; + while (matcher.find()) { + String name = matcher.group(1).trim(); + String index = matcher.group(2).trim(); + int size = index.length(); + int num = Integer.parseInt(index); + if (num %2 == 1) { + num = num - 1; + }else { + num = num + 1; + } + failover = name + "-" + StringUtils.leftPad(Integer.toString(num), size, '0'); + } + return failover; + } +} diff --git a/src/main/java/com/eactive/eai/common/web/HelpLoader.java b/src/main/java/com/eactive/eai/common/web/HelpLoader.java new file mode 100644 index 0000000..c9a7021 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/HelpLoader.java @@ -0,0 +1,232 @@ +package com.eactive.eai.common.web; +//package com.eactive.eai.common.web; +// +//import com.eactive.eai.transformer.function.Function; +//import com.eactive.eai.transformer.function.FunctionDefinition; +//import com.eactive.eai.transformer.function.ParameterDefinition; +//import com.eactive.eai.transformer.layout.Types; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import java.io.DataInputStream; +//import java.io.DataOutputStream; +//import java.io.File; +//import java.io.FileInputStream; +//import java.io.FileOutputStream; +//import java.io.InputStream; +//import java.io.OutputStream; +//import java.sql.Connection; +//import java.sql.PreparedStatement; +//import java.sql.Statement; +//import java.util.ArrayList; +//import java.util.Iterator; +//import java.util.List; +//import com.eactive.eai.transformer.tools.loader.AbstractExcelLoader; +//import com.eactive.eai.transformer.tools.loader.ExcelLoader; +//import com.eactive.eai.transformer.tools.util.ConstantUtil; +//import com.eactive.eai.transformer.tools.util.ExcelSheet; +// +///** +//* 1. 기능 : 정형화된 EXCEL 문서를 통해 관리자화면의 help 풍선도움말을 만들기 위한 XML화일을 생성 +//* 2. 처리 개요 : 입력받은 xml화일을 파싱하여 정형화된 XML화일을 생성한다. +//* +//* 3. 주의사항 +//* +//* @author : +//* @version : v 1.0.0 +//* @see : AbstractExcelLoader.java +//* @since : +//* : +//*/ +// +//public class HelpLoader extends AbstractExcelLoader +//{ +// private static final int DATA_ROW_OFFSET = 7; +// +// private static final int COL_ID = 1; +// private static final int COL_TYPE = 2; +// private static final int COL_DESC = 3; +// +// private static final String PAGE_TITLE_TYPE = "pageTitle"; +// private static final String LABEL_TYPE = "Label"; +// +// +// public HelpLoader() { +// super(HelpLoader.class.getName().substring(HelpLoader.class.getName().lastIndexOf('.') + 1)); +// } +// +// /** +// * 1. 기능 : ExcelSheet를 파싱하여 ArrayList를 생성 +// * 2. 처리 개요 : ExcelSheet를 파싱하여 ArrayList에 HelpVO를 생성해서 리턴한다. +// * 3. 주의사항 +// * +// * @return ArrayList HelpVO를 가진 ArrayList +// * @exception +// **/ +// public Object parseExcelSheet(ExcelSheet[] sheets) +// { +// ExcelSheet sheet = sheets[0]; +// +// ArrayList helpList = new ArrayList(); +// +// for (int currentRow = DATA_ROW_OFFSET; sheet.existRow(currentRow); currentRow++) { +// try { +// HelpVO vo = new HelpVO(); +// +// String type = sheet.getCellString(currentRow, COL_TYPE); +// String id = sheet.getCellString(currentRow, COL_ID); +// String desc = sheet.getCellString(currentRow, COL_DESC); +// +// if (id.trim().length() > 0) { +// vo.setId(id); +// vo.setDescription(desc); +// vo.setType(type); +// +// helpList.add(vo); +// +// } +// else { +// break; +// } +// +// } catch (Exception e) { +// println("[ERROR] !!!!! " + e.getMessage() + " - ROW: " + currentRow); +// e.printStackTrace(); +// +// } +// } +// +// return helpList; +// } +// +// /** +// * 1. 기능 : ExcelSheet를 파싱하여 XML을 생성 +// * 2. 처리 개요 : parseExcelSheet를 통해 ExcelSheet를 파싱하여 XML 화일을 생성한다. +// * 3. 주의사항 +// * +// * @return void +// * @exception +// **/ +// public void loadExcelSheet(ExcelSheet[] sheets) +// { +// List helpList = (List)parseExcelSheet(sheets); +// int helpSize = helpList.size(); +// +// println("Load할 Help 수: " + helpSize); +// +// String name = null; +// try { +// name = sheets[0].getCellString(2, 1); +// } catch(Exception e) { +// e.printStackTrace(); +// throw new RuntimeException("HelpLoader] loadExcelSheet>> "+e.getMessage()); +// } +// String directory = null; +// try { +// directory = sheets[0].getCellString(3,1); +// } catch(Exception e) { +// e.printStackTrace(); +// throw new RuntimeException("HelpLoader] loadExcelSheet>> "+e.getMessage()); +// } +// +// DataOutputStream out = getOutputFile(name, directory); +// StringBuffer sb = new StringBuffer(); +// +// try{ +// sb.append("\n"); +// sb.append("\n"); +// +// // "); +// HelpVO vo = new HelpVO(); +// for(int i=0; i < helpSize; i++){ +// vo = (HelpVO)helpList.get(i); +// +// if(this.PAGE_TITLE_TYPE.equalsIgnoreCase(vo.getType())){ +// sb.append( "\n\t"); +// sb.append(vo.getDescription()+""); +// } +// else{ +// sb.append("\n\t"); +// } +// +// } +// sb.append("\n"); +// System.out.println(sb.toString()); +// if(out != null) +// out.write(sb.toString().getBytes()); +// else +// System.out.println("out is null"); +// +// } catch (Exception e) { +// +// e.printStackTrace(); +// } finally { +// +// } +// } +// +// /** +// * 1. 기능 : 생성할 XML화일의 DataOutputStream을 생성 +// * 2. 처리 개요 : ExcelSheet에 정의된 화일명과 위치를 통해 생성할 XML화일의 DataOutputStream을 생성하여 리턴한다. +// * 3. 주의사항 +// * +// * @return DataOutputStream +// * @exception +// **/ +// +// public DataOutputStream getOutputFile(String name, String dir) { +// +// String outFile = ""; +// File out = new File(dir); +// +// if(!out.exists()){ +// if(!out.mkdir()) +// System.out.println(outFile+" Faild make directory"); +// } +// outFile = dir+"/"+name; +// +// DataOutputStream outs = null; +// +// try { +// outs = new DataOutputStream( new FileOutputStream(outFile, false)); +// +// if(outs != null) +// System.out.println("HelpLoader ] File Name - " + outFile +" created."); +// else +// System.out.println("HelpLoader ] File Name - " + outFile +" can't create."); +// +// } catch(Exception _ex) { +// _ex.printStackTrace(); +// } +// return outs; +// +// } +// +// public void clearData(ExcelSheet[] sheets) { +// } +// +// public static void main(String[] argv) { +// +// InputStream in = null; +// HelpLoader loader = new HelpLoader(); +// +// try { +// +//// in = HelpLoader.class.getClassLoader().getResourceAsStream(argv[0]); +// in = new DataInputStream(new FileInputStream(argv[0])); +// ExcelSheet[] sheets = ExcelSheet.getExcelSheets(in); +// +//// ExcelLoader loader = (ExcelLoader)Class.forName("HelpLoader.class").newInstance(); +// +// loader.loadExcelSheet(sheets); +// +// } catch (Exception e) { +// e.printStackTrace(); +// } finally { +// if (in != null) try { in.close(); } catch (Exception e) {}; +// } +// +// } +// +//} diff --git a/src/main/java/com/eactive/eai/common/web/HelpVO.java b/src/main/java/com/eactive/eai/common/web/HelpVO.java new file mode 100644 index 0000000..210708a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/HelpVO.java @@ -0,0 +1,43 @@ +package com.eactive.eai.common.web; + +/** + * 1. 기능 : 관리자 화면의 Help 풍선도움말을 표현한 Java Value Object + * + * @author : + * @version : v 1.0.0 + * @see : + * @since : : + */ + +public class HelpVO { + private String id; + private String description; + private String type; + + public HelpVO() { + } + + public void setId(String id) { + this.id = id; + } + + public void setDescription(String des) { + this.description = des; + } + + public String getId() { + return this.id; + } + + public String getDescription() { + return this.description; + } + + public void setType(String type) { + this.type = type; + } + + public String getType() { + return this.type; + } +} diff --git a/src/main/java/com/eactive/eai/common/web/MakeSelectDataTEI.java b/src/main/java/com/eactive/eai/common/web/MakeSelectDataTEI.java new file mode 100644 index 0000000..001cdfa --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/MakeSelectDataTEI.java @@ -0,0 +1,12 @@ +package com.eactive.eai.common.web; + +import javax.servlet.jsp.tagext.TagData; +import javax.servlet.jsp.tagext.TagExtraInfo; +import javax.servlet.jsp.tagext.VariableInfo; + +public class MakeSelectDataTEI extends TagExtraInfo { + public VariableInfo[] getVariableInfo(TagData data) { + return new VariableInfo[] { new VariableInfo(data.getAttributeString("id"), data.getAttributeString("type"), + true, VariableInfo.NESTED), }; + } +} diff --git a/src/main/java/com/eactive/eai/common/web/MakeSelectDataTag.java b/src/main/java/com/eactive/eai/common/web/MakeSelectDataTag.java new file mode 100644 index 0000000..c86694a --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/MakeSelectDataTag.java @@ -0,0 +1,145 @@ +package com.eactive.eai.common.web; + +import com.eactive.eai.common.dao.Keys; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.servlet.jsp.JspTagException; +import javax.servlet.jsp.PageContext; +import javax.servlet.jsp.tagext.BodyTagSupport; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * 1. 기능 : 관리자화면에서 select Tag를 생성해주는 Custom Tag Class + * 2. 처리 개요 : 필드 추출 Rule 정보테이블에 대한 Create, Read, Update, Delete 를 처리한다. + * + * + * @author : + * @version : v 1.0.0 + * @see : + * @since : : + */ + +public class MakeSelectDataTag extends BodyTagSupport { + private String dataSource; + private String table; + private String where; + private String value; + private String label; +// private String type; + + public void setDataSource(String dataSource) { + this.dataSource = dataSource; + } + + public void setTable(String table) { + this.table = Keys.TABLE_OWNER + table; + } + + public void setWhere(String where) { + this.where = where; + } + + public void setValue(String value) { + this.value = value; + } + + public void setLabel(String label) { + this.label = label; + } + +// public void setType(String type) { +// this.type = type; +// } + + public int doStartTag() throws JspTagException { + if (dataSource == null) { + return SKIP_BODY; + } + try { + pageContext.setAttribute(id, selectFromTable(), PageContext.PAGE_SCOPE); + } catch (Exception e) { + throw new JspTagException(e.toString()); + } + return EVAL_BODY_TAG; + } + + public int doEndTag() throws JspTagException { + + try { + if (bodyContent != null) + bodyContent.writeOut(bodyContent.getEnclosingWriter()); + } catch (java.io.IOException e) { + throw new JspTagException("IO Error: " + e.toString()); + } + return EVAL_PAGE; + } + + /** + * 1. 기능 : 입력받은 Tag Value를 통해 html select Tag를 생성하기 위한 KEY, VALUE를 조회한다. 2. 처리 + * 개요 : Query를 생성하여 설정된 DataSource를 통해 key, value를 조회한다. 3. 주의사항 + * + * @return HashMap label, value 쌍을 가진 HashMap + * @exception Excepiton SQLException + **/ + + public Map selectFromTable() throws Exception { + Connection con = null; + PreparedStatement stmt = null; + ResultSet rs = null; + try { + con = getConnection(); + StringBuffer query = new StringBuffer(); + query.append("select ").append(label).append(", ").append(value).append(" ").append(" from ").append(table) + .append(" "); + if (where != null) { + query.append("where ").append(where).append(" "); + } + query.append("order by ").append(label); + +// System.out.println("query>> "+query.toString()); + stmt = con.prepareStatement(query.toString()); + rs = stmt.executeQuery(); + + Map map = new LinkedHashMap(); + while (rs.next()) { + map.put(rs.getString(1), rs.getString(2)); + } + return map; + } catch (SQLException e) { + throw e; + } finally { + try { + if (rs != null) + rs.close(); + } catch (Exception e) { + } + try { + if (stmt != null) + stmt.close(); + } catch (Exception e) { + } + try { + if (con != null) + con.close(); + } catch (Exception e) { + } + } + } + + public Connection getConnection() throws Exception { + try { + Context ctx = new InitialContext(); + DataSource ds = (DataSource) ctx.lookup(dataSource); + return ds.getConnection(); + } catch (Exception e) { + throw e; + } + } +} diff --git a/src/main/java/com/eactive/eai/common/web/PageInfo.java b/src/main/java/com/eactive/eai/common/web/PageInfo.java new file mode 100644 index 0000000..0f712c7 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/PageInfo.java @@ -0,0 +1,79 @@ +package com.eactive.eai.common.web; + +import java.io.Serializable; +import java.util.Vector; + +/** + * 1. 기능 : 관리자 화면에서 Page List를 구성하기위한 정보를 저장 + * 2. 처리 개요 : 관리자 화면에서 Page List를 구성하기위한 정보를 저장 + * + * @author : + * @version : v 1.0.0 + * @see : + * @since : : + */ +public class PageInfo implements Serializable { + private int page; + private int rowsPerPage; + private Vector whereItem; + private Vector orderItem; + + /** 한페이지에 보여줄 라인 카운트 */ + public static int ROWS_PER_PAGE = 10; + + public void setPage(int page) { + this.page = page; + } + + public int getPage() { + return this.page; + } + + public void setRowPerPage(int rowsPerPage) { + this.rowsPerPage = rowsPerPage; + } + + public int getRowPerPage() { + return this.rowsPerPage; + } + + public void setWhereItem(Vector whereItem) { + this.whereItem = whereItem; + } + + public Vector getWhereItem() { + return this.whereItem; + } + + public void setOrderItem(Vector orderItem) { + this.orderItem = orderItem; + } + + public Vector getOrderItem() { + return this.orderItem; + } + + /** + * view page의 start row를 반환하는 method + * + * @return view page의 start row + */ + public int startrow() { + page = page < 1 ? 1 : page; + if (this.rowsPerPage == 0) + rowsPerPage = ROWS_PER_PAGE; + return (page - 1) * rowsPerPage + 1; + } + + /** + * view page의 end row를 반환하는 method + * + * @return view page의 end row + */ + public int endrow() { + page = page < 1 ? 1 : page; + if (this.rowsPerPage == 0) + rowsPerPage = ROWS_PER_PAGE; + return (page - 1) * rowsPerPage + rowsPerPage; + } +} diff --git a/src/main/java/com/eactive/eai/common/web/PageListTag.java b/src/main/java/com/eactive/eai/common/web/PageListTag.java new file mode 100644 index 0000000..ac11963 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/web/PageListTag.java @@ -0,0 +1,317 @@ +package com.eactive.eai.common.web; + +/* +* @@(#)PageListTag.java +* @@author Jeon HongSeong +* @@version 1.0 +* Copyright (c) 1998-2001 InfoTops Co., Ltd. All Rights Reserved. +*/ + +import javax.servlet.jsp.JspTagException; +import javax.servlet.jsp.JspWriter; +import javax.servlet.jsp.tagext.TagSupport; +import java.io.IOException; + + +/** + * 1. 기능 : 관리자 화면에서 페이지 리스트를 만들어 준다. + * 2. 처리 개요 : 관리자 화면에서 Page List를 구성하기위한 정보를 저장 + * totalCount 전체 레코드 갯수 + * viewPage 현재 페이지 번호 + * rowPerPage 한 페이지당 레코드 건수 + * pageListCount 한 페이지 리스트당 페이지 갯수 + * viewPageColor 현재 페이지 색깔 + * javaScript 페이지 이동 자바스크립트 함수 / 페이지 이동 href + * first, prev, next, last 버튼 (처음, 이전 블럭, 다음 블럭, 마지막) + * |◀ ◀ [11] [12] [13] [14] [15] [16] [17] [18] [19] [20] ▶ ▶| + * 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : + * @since : + * : + */ + +public class PageListTag extends TagSupport +{ + private int totalCount; + private int viewPage; + + private int rowPerPage; + private int pageListCount; + + private String javaScript; + private String viewPageColor; + + private String first; + private String prev; + private String next; + private String last; + +// private final static int DEFAULT_ROW_PER_PAGE = 10; +// private final static int DEFAULT_PAGE_LIST_COUNT = 10; +// private final static String DEFAULT_JAVA_SCRIPT = "gotoPage"; +// private final static String DEFAULT_VIEW_PAGE_COLOR = "#FF6300"; + + private final static String DEFAULT_FIRST_BUTTON = "|◀"; + private final static String DEFAULT_PREV_BUTTON = "◀"; + private final static String DEFAULT_NEXT_BUTTON = "▶"; + private final static String DEFAULT_LAST_BUTTON = "▶|"; + + //mendatory : total row count + public void setTotalCount(int totalCount) + { + this.totalCount = totalCount; + } + + //view page number + public void setViewPage(int viewPage) + { + this.viewPage = (viewPage < 1) ? 1 : viewPage; + } + + //row per page + public void setRowPerPage(int rowPerPage) + { + this.rowPerPage = rowPerPage; + } + + //page list count + public void setPageListCount(int pageListCount) + { + this.pageListCount = pageListCount; + } + + //java script function name + public void setJavaScript(String javaScript) + { + this.javaScript = javaScript; + } + + //view page color + public void setViewPageColor(String viewPageColor) + { + this.viewPageColor = viewPageColor; + } + + //first button + public void setFirst(String first) + { + this.first = first; + } + + //previous button + public void setPrev(String prev) + { + this.prev = prev; + } + + //next button + public void setNext(String next) + { + this.next = next; + } + + //last button + public void setLast(String last) + { + this.last = last; + } + + private String getPageList( + int rowCount, //전체 레코드 갯수 + int viewPage, //현재 페이지 번호 + int rowPerPage, //한 페이지당 레코드 갯수 + int pageListCount, //한 페이지당 하단 페이지 갯수 + String javascript_name, //자바스크립트 + String current_page_color, //현재 페이지 색깔 + String first_button, + String prev_button, + String next_button, + String last_button + ) + { + int intTotPage = 0; //전체 페이지 갯수 + int intStartPage = 0; //페이지 리스트를 시작할 페이지 번호 + int intEndPage = 0; //페이지 리스트가 끝나는 페이지 번호 + + //페이지 리스트를 시작할 페이지를 계산한다. + intStartPage = (int) Math.ceil((viewPage - 1) / pageListCount); + intStartPage = (intStartPage * pageListCount) + 1; + if (intStartPage % pageListCount == 0) intStartPage = intStartPage - pageListCount + 1 ; + + //전체 페이지 갯수를 계산한다. +// intTotPage = ( (rowCount % rowPerPage) > 0 ) ? 1 : 0; +// intTotPage = (int) Math.ceil(rowCount / rowPerPage) + intTotPage; + intTotPage = getTotalPage(rowCount, rowPerPage); + + //페이지 리스트가 끝나는 페이지를 계산한다. + intEndPage = (intTotPage >= (pageListCount + intStartPage)) + ? intStartPage + pageListCount - 1 + : intStartPage + (intTotPage - intStartPage); + + + StringBuffer sb = new StringBuffer(); + //첫번째 페이지(리스트)로 이동 : |◀ + //|◀ + + //if ( viewPage > 1 ) + //if ( intStartPage > (pageListCount * 2) ) + //System.out.println( intStartPage+"====="+pageListCount+"****************"); + if ( intStartPage > pageListCount ) + { + sb.append(""); + sb.append( first_button ); + sb.append(""); + sb.append("\n"); + } + else + { + sb.append( first_button ); + sb.append("\n"); + } + + //이전 페이지 리스트로 이동 : ◀ + // --16 - 5 = 11 + if (intStartPage > pageListCount) + { + sb.append(""); + sb.append( prev_button ); + sb.append(""); + sb.append(""); + sb.append("\n"); + sb.append(" "); + sb.append("\n"); + } + + else + { + sb.append( prev_button ); + sb.append("\n"); + sb.append(" "); + sb.append("\n"); + } + + //해당 페이지로 이동 : [16][17][18][19][20] -- 현재페이지 = 17 + for (int i=intStartPage; i<=intEndPage; i++) + { + if (viewPage == i) + { + sb.append("["); + sb.append(i); + sb.append("]"); + sb.append("\n"); + } + + else + { + sb.append("["); + sb.append(i); + sb.append("]"); + sb.append("\n"); + } + } + + //다음 페이지 리스트로 이동 : ▶ + // --16 + 5 = 21 + if (intTotPage > intEndPage ) + { + sb.append(" "); + sb.append("\n"); + sb.append(""); + sb.append( next_button ); + sb.append(""); + //sb.append(" "); + sb.append("\n"); + } + else + { + sb.append(" "); + sb.append("\n"); + sb.append( next_button ); + //sb.append(" "); + sb.append("\n"); + } + + //마지막 페이지 리스트로 이동 : ▶| + //▶| --intTotPage + //if (intTotPage >= ( intStartPage + (pageListCount * 2) )) + if (intTotPage > intEndPage ) + { + sb.append(""); + sb.append(last_button); + sb.append(""); + //sb.append("\n"); + } + + else + { + sb.append(last_button); + } + + return sb.toString(); + } + + public int doStartTag() + throws JspTagException + { + try { + + if (totalCount <=0 ) + return SKIP_BODY; + + + + JspWriter out = pageContext.getOut(); + + out.println( + getPageList( + totalCount, + (viewPage <= 0)? 1 : viewPage, + (rowPerPage > 0) ? rowPerPage : 10, + (pageListCount > 0) ? pageListCount : 5, + javaScript, + (viewPageColor != null && viewPageColor.length() > 0)? viewPageColor : "#FF9933", + (first != null && first.length() > 0) ? first : DEFAULT_FIRST_BUTTON, + (prev != null && prev.length() > 0) ? prev : DEFAULT_PREV_BUTTON, + (next != null && next.length() > 0) ? next : DEFAULT_NEXT_BUTTON, + (last != null && last.length() > 0) ? last : DEFAULT_LAST_BUTTON + ) + ); + return SKIP_BODY; + } + catch (IOException e) + { + throw new JspTagException( "IOException:" +e.toString() ); + } + catch (Exception e) + { + throw new JspTagException( "Exception:" +e.toString() ); + } + } + + private int getTotalPage(int rowCount, int rowPerPage) + { + return ( (int)(Math.ceil(rowCount/rowPerPage)) + ( (rowCount%rowPerPage)>0?1:0) ); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/common/worker/Action.java b/src/main/java/com/eactive/eai/common/worker/Action.java new file mode 100644 index 0000000..47fa0d3 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/worker/Action.java @@ -0,0 +1,19 @@ +package com.eactive.eai.common.worker; + +// SA 인터페이스 유형에서 요청에 대한 응답을 맞추기 위해 Outbound 인터페이스에서 사용하는 Worker Action +public interface Action { + // Action의 고유 ID를 반환 + public String getId(); + + // Action의 고유 ID를 Setting하고, Action의 초기화 + public void doInit(String id) throws ActionException; + + // 요청에 대한 응답 메시지를 수신하기위한 전처리 + public void doStart(Slot slot) throws ActionException; + + // 초기화 로직에 대한 Undo 로직을 처리 + public void doEnd() throws ActionException; + + // 요청에 대한 응답 메시지를 받기 위한 초기화가 되었는지 Flag를 반환 + public boolean isReady(); +} diff --git a/src/main/java/com/eactive/eai/common/worker/ActionException.java b/src/main/java/com/eactive/eai/common/worker/ActionException.java new file mode 100644 index 0000000..540c5ce --- /dev/null +++ b/src/main/java/com/eactive/eai/common/worker/ActionException.java @@ -0,0 +1,11 @@ +package com.eactive.eai.common.worker; + +public class ActionException extends Exception { + public ActionException() { + super("ActionException is occured."); + } + + public ActionException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/common/worker/ActionSupport.java b/src/main/java/com/eactive/eai/common/worker/ActionSupport.java new file mode 100644 index 0000000..ef84edb --- /dev/null +++ b/src/main/java/com/eactive/eai/common/worker/ActionSupport.java @@ -0,0 +1,27 @@ +package com.eactive.eai.common.worker; + +import com.eactive.eai.common.util.Logger; + +public abstract class ActionSupport implements Action { + protected boolean ready; + protected String id; + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public String getId() { + return this.id; + } + + public boolean isReady() { + return this.ready; + } + + public void doInit(String id) throws ActionException { + this.id = id; + logger.info("execute doInit... "); + } + + public void doEnd() throws ActionException { + logger.info("execute doEnd... "); + } + +} diff --git a/src/main/java/com/eactive/eai/common/worker/Future.java b/src/main/java/com/eactive/eai/common/worker/Future.java new file mode 100644 index 0000000..4cce65b --- /dev/null +++ b/src/main/java/com/eactive/eai/common/worker/Future.java @@ -0,0 +1,30 @@ +package com.eactive.eai.common.worker; + +public class Future { + private Object value; + private Slot slot; // shared with some worker + + public Future() { + this.slot = new Slot(); + } + + public Slot getSlot() { + return this.slot; + } + + public Object value() { + synchronized (slot) { // avoid race conditions! + if (value == null) + value = slot.get(); + } + return value; + } + + public Object value(long timeout) { + synchronized (slot) { // avoid race conditions! + if (value == null) + value = slot.get(timeout); + } + return value; + } +} diff --git a/src/main/java/com/eactive/eai/common/worker/JMSListenerAction.java b/src/main/java/com/eactive/eai/common/worker/JMSListenerAction.java new file mode 100644 index 0000000..7db9464 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/worker/JMSListenerAction.java @@ -0,0 +1,192 @@ +package com.eactive.eai.common.worker; + +import java.lang.Thread.State; + +import javax.jms.Message; +import javax.jms.MessageListener; +import javax.jms.ObjectMessage; +import javax.jms.Session; +import javax.jms.Topic; +import javax.jms.TopicConnection; +import javax.jms.TopicConnectionFactory; +import javax.jms.TopicSession; +import javax.jms.TopicSubscriber; + +import com.eactive.eai.common.jms.JmsServiceLocator; +import com.eactive.eai.common.util.ContainerUtil; + +public class JMSListenerAction extends ActionSupport implements MessageListener { + private String topicConFactory; + private String topicName; + private int timeout; + + private TopicConnectionFactory tconFactory; + private TopicConnection tcon; + private TopicSession tsession; + private TopicSubscriber tsubscriber; + private Topic topic; + private Slot slot; + + public JMSListenerAction(String topicConFactory, String topicName, int timeout) { + this.topicConFactory = topicConFactory; + this.topicName = topicName; + this.timeout = timeout; + } + + public void doStart(Slot slot) throws ActionException { + if (ContainerUtil.get() == ContainerUtil.WEBSPHERE) { + doStartForWebSphere(slot); + } else if (ContainerUtil.get() == ContainerUtil.WEBLOGIC) { + doStartForWeblogic(slot); + } else { + doStartForWeblogic(slot); + } + } + + public void doStartForWeblogic(Slot slot) throws ActionException { + this.slot = slot; + try { + JmsServiceLocator slocator = JmsServiceLocator.getInstance(); + tconFactory = (TopicConnectionFactory) slocator.getTopicConnectionFactory(this.topicConFactory); + tcon = tconFactory.createTopicConnection(); + tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + topic = (Topic) slocator.getTopic(this.topicName); + tsubscriber = tsession.createSubscriber(topic, "JMSCorrelationID = '" + id + "'", true); + tsubscriber.setMessageListener(this); + tcon.start(); + this.ready = true; + } catch (Exception e) { + this.ready = false; + this.doEnd(); + throw new ActionException("ResponseTopic에 응답메시지를 수신하기 위한 JMSListener를 초기화 하지 못했습니다."); + } + } + + public void doStartForWebSphere(Slot slot) throws ActionException { + this.slot = slot; + int retryCount = 0; + try { + if (logger.isWarn()) + logger.warn("start correlationID[" + id + "]"); + JmsServiceLocator slocator = JmsServiceLocator.getInstance(); + tconFactory = (TopicConnectionFactory) slocator.getTopicConnectionFactory(this.topicConFactory); + if (tconFactory == null) + throw new Exception("tconFactory not found - " + this.topicConFactory); + while (retryCount < 3) { + try { + tcon = tconFactory.createTopicConnection(); + } catch (Exception ex) { + retryCount++; + if (retryCount < 3) { +// if(logger.isWarn()) + logger.error("correlationID[" + id + "] retry count=" + retryCount); + continue; + } + throw ex; + } + if (tcon != null) + break; + } + + tsession = tcon.createTopicSession(false, Session.AUTO_ACKNOWLEDGE); + topic = (Topic) slocator.getTopic(this.topicName); + tsubscriber = tsession.createSubscriber(topic, "JMSCorrelationID = '" + id + "'", true); + tcon.start(); + Thread receiverThread = new Thread(new Runnable() { + @Override + public void run() { + if (logger.isWarn()) + logger.warn("run correlationID[" + id + "]"); + long startTime = System.currentTimeMillis(); + Message msg = null; + if (logger.isInfo()) + logger.info("executing. - " + id); + try { + msg = tsubscriber.receive(timeout + (10 * 1000L)); + if (logger.isInfoEnabled()) + logger.info("receive JMSCorrelationID=" + id + ", message=" + msg); + + if (logger.isWarn()) + logger.warn("receive correlationID[" + id + "]"); + + if (msg instanceof ObjectMessage) { + ObjectMessage omsg = (ObjectMessage) msg; + Object value = omsg.getObject(); + slot.put(value); + } + if (logger.isWarn()) + logger.warn("slot.put correlationID[" + id + "]"); + } catch (Exception e) { + logger.error("JMSListenerAction Error", e); + } + long endTime = System.currentTimeMillis(); + if (logger.isInfo()) + logger.info(id + " >> ELAPSE TIME : " + (endTime - startTime) / 1000.); + } + }); + receiverThread.setName("JMSTopicReceiver"); + receiverThread.setPriority(Thread.MAX_PRIORITY); + receiverThread.start(); + + int i = 0; + while (true) { + State s = receiverThread.getState(); + if (s == Thread.State.TIMED_WAITING || i > 100) { + if (i > 100) { + logger.error("JMSListenerAction] receiverThread state = " + s.toString() + ",count=" + i); + } else if (100 >= i && i > 0) { + logger.info("JMSListenerAction] receiverThread state = " + s.toString() + ",count=" + i); + } + break; + } + Thread.sleep(10L); + i++; + } + + this.ready = true; + } catch (Exception e) { + this.ready = false; + this.doEnd(); + logger.error("ResponseTopic에 응답메시지를 수신하기 위한 JMSListener를 초기화 하지 못했습니다.topicConFactory=" + + this.topicConFactory + ", topic=" + topicName + ", " + e.getMessage(), e); + throw new ActionException("ResponseTopic에 응답메시지를 수신하기 위한 JMSListener를 초기화 하지 못했습니다."); + } + } + + public void doEnd() { + try { + if (tsubscriber != null) + tsubscriber.close(); + } catch (Exception e) { + } + try { + if (tsession != null) + tsession.close(); + } catch (Exception e) { + } + try { + if (tcon != null) + tcon.close(); + } catch (Exception e) { + } + } + + public void onMessage(Message msg) { + long startTime = System.currentTimeMillis(); + if (logger.isInfo()) + logger.info("executing. - " + id); + + try { + if (msg instanceof ObjectMessage) { + ObjectMessage omsg = (ObjectMessage) msg; + Object value = omsg.getObject(); + this.slot.put(value); + } + } catch (Exception e) { + logger.error("JMSListenerAction Error - " + e.getMessage()); + } + long endTime = System.currentTimeMillis(); + if (logger.isInfo()) + logger.info(id + " >> ELAPSE TIME : " + (endTime - startTime) / 1000.); + } +} diff --git a/src/main/java/com/eactive/eai/common/worker/ResponseMap.java b/src/main/java/com/eactive/eai/common/worker/ResponseMap.java new file mode 100644 index 0000000..726ed69 --- /dev/null +++ b/src/main/java/com/eactive/eai/common/worker/ResponseMap.java @@ -0,0 +1,38 @@ +package com.eactive.eai.common.worker; + +import java.util.concurrent.ConcurrentHashMap; + +public class ResponseMap { + + private volatile static ResponseMap singleton; + + private static ConcurrentHashMap responseMap = new ConcurrentHashMap(); + + private ResponseMap() { +// System.out.println("Create ResponseMap..."); + } + + public static ResponseMap getInstance() { + if (singleton == null) { + synchronized (ResponseMap.class) { + if (singleton == null) { + singleton = new ResponseMap(); + } + } + } + return singleton; + } + + public void put(String key, Future future) { + responseMap.put(key, future); + } + + public Future get(String key) { + return responseMap.remove(key); + } + + public boolean containsKey(String key) { + return responseMap.containsKey(key); + } + +} diff --git a/src/main/java/com/eactive/eai/common/worker/Slot.java b/src/main/java/com/eactive/eai/common/worker/Slot.java new file mode 100644 index 0000000..862fb8d --- /dev/null +++ b/src/main/java/com/eactive/eai/common/worker/Slot.java @@ -0,0 +1,49 @@ +package com.eactive.eai.common.worker; + +public class Slot { + private Object slotVal; + + public synchronized void put(Object val) { + while (slotVal != null) { + try { + wait(); + } catch (InterruptedException e) { + ; + } + } + slotVal = val; + notifyAll(); + } + + public synchronized Object get() { + Object rval; + while (slotVal == null) { + try { + if (slotVal == null) + wait(); + } catch (InterruptedException e) { + break; + } + } + + rval = slotVal; + slotVal = null; + notifyAll(); + return rval; + } + + public synchronized Object get(long timeout) { + Object rval; + try { + if (slotVal == null) + wait(timeout); + } catch (InterruptedException e) { + rval = slotVal; + } + + rval = slotVal; + slotVal = null; + notifyAll(); + return rval; + } +} diff --git a/src/main/java/com/eactive/eai/control/AMQSender.java b/src/main/java/com/eactive/eai/control/AMQSender.java new file mode 100644 index 0000000..b149892 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/AMQSender.java @@ -0,0 +1,27 @@ +package com.eactive.eai.control; + +import java.util.Properties; + +import javax.jms.JMSException; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.common.exception.ExceptionUtil; + +public class AMQSender { + + public static Object callService(String adapterGroupName, Properties prop, Object inputData, Properties tempProp) + throws Exception { + ElinkAdapter adapter = ElinkAdapterFactory.newInstance().getElinkAdapter(Keys.TYPE_AMQ); + + try { + return adapter.callService(adapterGroupName, prop, inputData, tempProp); + } catch (JMSException jmse) { + throw jmse; + } catch (Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAICUL001")); + } + } + +} diff --git a/src/main/java/com/eactive/eai/control/BusinessApplicationSender.java b/src/main/java/com/eactive/eai/control/BusinessApplicationSender.java new file mode 100644 index 0000000..aacaa71 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/BusinessApplicationSender.java @@ -0,0 +1,35 @@ +package com.eactive.eai.control; + +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; +import com.eactive.eai.common.util.Logger; + +public class BusinessApplicationSender { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static final String IA_CONTROL_ERROR = "RECEAIAHA003"; + + public static byte[] callService(String adapterGroupName, Properties prop, Object message, Properties tempProp) + throws Exception { + byte[] resBytes; + try { + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = factory.getElinkAdapter(com.eactive.eai.adapter.Keys.TYPE_APP); + if (prop == null) { + prop = new Properties(); + } + if (tempProp == null) { + tempProp = new Properties(); + } + if (tempProp.getProperty("ADAPTER_GROUP_NAME") == null) { + tempProp.setProperty("ADAPTER_GROUP_NAME", adapterGroupName); + } + resBytes = (byte[]) adapter.callService(adapterGroupName, prop, message, tempProp); + } catch (Exception e) { + logger.error("callService error", e); + throw e; + } + return resBytes; + } +} diff --git a/src/main/java/com/eactive/eai/control/HttpSender.java b/src/main/java/com/eactive/eai/control/HttpSender.java new file mode 100644 index 0000000..2384828 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/HttpSender.java @@ -0,0 +1,40 @@ +package com.eactive.eai.control; + +import java.net.SocketTimeoutException; +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; + +public class HttpSender { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static final long serialVersionUID = 1L; + static final String HTTP_CONTROL_ERROR1 = "RECEAIOHC001"; + static final String HTTP_CONTROL_ERROR2 = "RECEAIOHC002"; + static final String HTTP_QUICS = "HTTP_QUICS"; //럭키넘버스 업무를 위한 http adpater + + public static Object callService(String adapterGroupName, Properties prop, Object inputData, Properties tempProp) + throws Exception { + + ElinkAdapter adapter = null; + + adapter = ElinkAdapterFactory.newInstance().getElinkAdapter(Keys.TYPE_HTTP); + + String adapterName = tempProp.getProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_NAME); + + try { + return adapter.callService(adapterGroupName, prop, inputData, tempProp); + } catch (SocketTimeoutException ste) { + throw ste; + } catch (HttpStatusException hse) { + throw hse; + } catch (Exception e) { + logger.error("HttpSender] callService " + adapterName + " : "+ e.getMessage(), e); + throw new Exception(ExceptionUtil.getErrorCode(e, HTTP_CONTROL_ERROR1) + ", Adapter : " + adapterName); + } + } +} diff --git a/src/main/java/com/eactive/eai/control/IBMMQUtil.java b/src/main/java/com/eactive/eai/control/IBMMQUtil.java new file mode 100644 index 0000000..31af2ce --- /dev/null +++ b/src/main/java/com/eactive/eai/control/IBMMQUtil.java @@ -0,0 +1,40 @@ +package com.eactive.eai.control; +//package com.eactive.eai.control; +// +//import java.util.Properties; +// +//import com.eactive.eai.adapter.mq.Keys; +//import com.eactive.eai.adapter.mq.MQChannelChecker; +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.util.StringUtil; +// +//public class IBMMQUtil { +// +// public static boolean checkChannel(String adapterName) +// { +// PropManager manager = PropManager.getInstance(); +// Properties prop = manager.getProperties(adapterName); +// +// String senderChannel = StringUtil.getNullStr(prop.getProperty(Keys.MQ_SENDER_CHANNEL)); +// String receiverChannel = StringUtil.getNullStr(prop.getProperty(Keys.MQ_RECEIVER_CHANNEL)); +// +// MQChannelChecker checker = new MQChannelChecker(); +// +// if (senderChannel.equals("") && receiverChannel.equals("")) { +// return checker.checkChannel(prop, prop.getProperty(Keys.MQ_CHANNEL)); +// } else { +// boolean isSenderAlive = true; +// boolean isReceiverAlive = true; +// +// if (!senderChannel.equals("")) { +// isSenderAlive = checker.checkChannel(prop, senderChannel); +// } +// +// if (!receiverChannel.equals("")) { +// isReceiverAlive = checker.checkChannel(prop, receiverChannel); +// } +// +// return (isSenderAlive && isReceiverAlive); +// } +// } +//} diff --git a/src/main/java/com/eactive/eai/control/JMSQueueReceiver.java b/src/main/java/com/eactive/eai/control/JMSQueueReceiver.java new file mode 100644 index 0000000..7248440 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/JMSQueueReceiver.java @@ -0,0 +1,121 @@ +package com.eactive.eai.control; + +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.QueueReceiver; +import javax.jms.QueueSession; +import javax.jms.TextMessage; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.jms.JmsServiceLocator; +import com.eactive.eai.common.util.Logger; + +public class JMSQueueReceiver { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private QueueConnectionFactory factory; + private QueueConnection con = null; + private QueueSession ses = null; + private Queue queue = null; + private String jms_connectionfactory; + private String queue_name; + + public java.io.Serializable receive(String queueConnectionFactory, String queueName, String traceNumber, int timeout) throws Exception { + + init(queueConnectionFactory, queueName); + QueueReceiver receiver = null; + + try { + if (con != null && ses != null) { + + if(traceNumber != null && traceNumber.length() > 0) { + receiver = ses.createReceiver(queue, "JMSCorrelationID = '" + traceNumber + "'"); + } + else { + receiver = ses.createReceiver(queue); + } + Message message = (Message)receiver.receive(timeout); + + if (message == null) { + String[] msgArgs = new String[2]; + msgArgs[0] = queueName; + msgArgs[1] = traceNumber; + String rspErrorCode = "RECEAICJR001"; + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); + throw new JMSQueueReceiverTimeOutException (rspErrorMsg); + } + + if (message instanceof ObjectMessage) { + if(logger.isInfo()) logger.info("MESSAGE IS ObjectMessage"); + return ((ObjectMessage)message).getObject(); + } + else if (message instanceof TextMessage) { + if(logger.isInfo()) logger.info("MESSAGE IS TextMessage"); + return ((TextMessage)message).getText(); + } + else { + if(logger.isInfo()) logger.info("MESSAGE IS ELSEMESSAGE"); + return ""; + } + } + else { + throw new JMSException(new StringBuffer("연결되지 않음 TARGET >> localhost").append("에 대한 수신...").toString()); + } + } catch (Exception e) { + logger.error("receive error", e); + throw e; + } finally { + if (receiver != null) try { receiver.close(); receiver = null; } catch (Throwable e) { + logger.error("receiver.close error", e); + } + close(); + } + } + + public void init(String queueConnectionFactory, String queueName) { + jms_connectionfactory = queueConnectionFactory; + queue_name = queueName; + startQueueConnection(); + } + + public void close() { + closeQueueConnection(); + } + + private void startQueueConnection() { + try { + JmsServiceLocator locator = JmsServiceLocator.getInstance(); + factory = locator.getQueueConnectionFactory(jms_connectionfactory); + + if(factory == null) { + throw new Exception("QueueConnectionFactory is NULL - " + jms_connectionfactory); + } + con = factory.createQueueConnection(); + if(con == null) { + throw new Exception("createQueueConnection is NULL - " + jms_connectionfactory); + } + ses = con.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); + queue = (Queue)locator.getQueue(queue_name); + + con.start(); + } catch (Throwable e) { +// e.printStackTrace(); + logger.error("startQueueConnection error", e); + closeQueueConnection(); + } + } + private void closeQueueConnection() { + if (ses != null) try { ses.close(); ses = null; } catch (Throwable e) { + logger.error("ses.close error", e); + } + if (con != null) try { con.stop(); } catch (Throwable e) { + logger.error("con.stop error", e); + } + if (con != null) try { con.close(); con = null; } catch (Throwable e) { + logger.error("con.close error", e); + } + } +} diff --git a/src/main/java/com/eactive/eai/control/JMSQueueReceiverTimeOutException.java b/src/main/java/com/eactive/eai/control/JMSQueueReceiverTimeOutException.java new file mode 100644 index 0000000..6c61402 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/JMSQueueReceiverTimeOutException.java @@ -0,0 +1,12 @@ +package com.eactive.eai.control; + +public class JMSQueueReceiverTimeOutException extends Exception +{ + public JMSQueueReceiverTimeOutException() { + super("JMSQueueReceiverTimeOutException is occured."); + } + + public JMSQueueReceiverTimeOutException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/control/JMSQueueSender.java b/src/main/java/com/eactive/eai/control/JMSQueueSender.java new file mode 100644 index 0000000..bfca05f --- /dev/null +++ b/src/main/java/com/eactive/eai/control/JMSQueueSender.java @@ -0,0 +1,87 @@ +package com.eactive.eai.control; + +import javax.jms.JMSException; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.QueueSender; +import javax.jms.QueueSession; +import javax.jms.TextMessage; + +import com.eactive.eai.common.jms.JmsServiceLocator; +import com.eactive.eai.common.util.Logger; + + +public class JMSQueueSender { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private QueueConnectionFactory factory; + private QueueConnection con = null; + private QueueSession ses = null; + private QueueSender qsender; + private Queue queue = null; + private TextMessage msg; + private ObjectMessage objmsg; + + private String jms_connectionfactory; + private String queue_name; + + public void send(String queueConnectionFactory, String queueName, String message, String id) throws JMSException { + init(queueConnectionFactory, queueName); + if(ses !=null) msg = ses.createTextMessage(); + if(id!=null) msg.setJMSCorrelationID(id); + msg.setText(message); + qsender.send(msg); + closeQueueConnection(); + } + + public void sendObject(String queueConnectionFactory, String queueName, java.io.Serializable message, String id) throws JMSException { + + init(queueConnectionFactory, queueName); + if(ses !=null) objmsg = ses.createObjectMessage(); + if(id!=null) objmsg.setJMSCorrelationID(id); + objmsg.setObject(message); + qsender.send(objmsg); + closeQueueConnection(); + } + + public void init(String queueConnectionFactory, String queueName) { + jms_connectionfactory = queueConnectionFactory; + queue_name = queueName; + startQueueConnection(); + } + + + public void close() { + closeQueueConnection(); + } + + private void startQueueConnection() { + try { + JmsServiceLocator locator = JmsServiceLocator.getInstance(); + + factory = locator.getQueueConnectionFactory(jms_connectionfactory); + if(factory == null) throw new Exception("factory not found - " + jms_connectionfactory); + con = factory.createQueueConnection(); + if(con == null) throw new Exception("createQueueConnection return null"); + ses = con.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); + if(ses == null) throw new Exception("createQueueSession return null"); + queue = (Queue)locator.getQueue(queue_name); + qsender = ses.createSender(queue); + con.start(); + } catch (Throwable e) { + closeQueueConnection(); + } + } + private void closeQueueConnection() { + if (ses != null) try { ses.close(); ses = null; } catch (Throwable e) { + logger.debug(e.toString()); + } + if (con != null) try { con.stop(); } catch (Throwable e) { + logger.debug(e.toString()); + } + if (con != null) try { con.close(); con = null; } catch (Throwable e) { + logger.debug(e.toString()); + } + } +} diff --git a/src/main/java/com/eactive/eai/control/JMSTopicReceiver.java b/src/main/java/com/eactive/eai/control/JMSTopicReceiver.java new file mode 100644 index 0000000..007e483 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/JMSTopicReceiver.java @@ -0,0 +1,169 @@ +package com.eactive.eai.control; + +import java.io.ByteArrayOutputStream; + +import javax.jms.BytesMessage; +import javax.jms.JMSException; +import javax.jms.Message; +import javax.jms.ObjectMessage; +import javax.jms.TextMessage; +import javax.jms.Topic; +import javax.jms.TopicConnection; +import javax.jms.TopicConnectionFactory; +import javax.jms.TopicSession; +import javax.jms.TopicSubscriber; +import javax.naming.Context; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.jms.JmsServiceLocator; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +public class JMSTopicReceiver { + static final long serialVersionUID = 1L; + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + static final String JMSRES_CONTROL_ERROR = "RECEAIORC001"; + static final String JMSRES_CONNNECTION_FAIL = "RECEAIORC100"; + static final String JMSRES_TIME_OUT = "RECEAIORC200"; + + private TopicConnectionFactory factory; + private TopicConnection con = null; + private TopicSession ses = null; + private Topic topic = null; + private String jms_connectionfactory; + private String topic_name; + + private static String topic_surfix; + + static + { + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + String serverName = eaiServerManager.getLocalServerName(); + + if(serverName != null) { + //juns 서버명 변경에 따른 인스턴스 룰 추출변경 + //ex)EAIDSG_i11 => EAIDS01_i01 + //topic_surfix = "_" +serverName.substring(serverName.length()-4); + topic_surfix = "_" + serverName.substring(serverName.length()-5, serverName.length()-4) + + serverName.substring(serverName.length()-1, serverName.length()); + } + } + + public java.lang.Object receive(String topicConnectionFactory, String topicName, String traceNumber, int timeout) throws java.lang.Exception { + jms_connectionfactory = topicConnectionFactory; + topic_name = topicName + topic_surfix; + startTopicConnection(); + + TopicSubscriber subscriber = null; + + try { + if (con != null && ses != null) { + subscriber = ses.createSubscriber(topic, "JMSCorrelationID = '" + traceNumber + "'", true); + + Message message = (Message)subscriber.receive(timeout); + + if (message == null) { + if (logger.isError()) logger.error("JmsResponseControl]요청에 대한 응답을 수신하지 못했습니다. JMSCorrelationID["+traceNumber+"]"); + throw new Exception(JMSRES_TIME_OUT); + } + + if (message instanceof ObjectMessage) { + return ((ObjectMessage)message).getObject(); + } + else if (message instanceof TextMessage) { + return ((TextMessage)message).getText(); + } + else if (message instanceof BytesMessage) { + return getBytesMessage((BytesMessage)message); + } + else { + return null; + } + } + else { + if (logger.isError()) logger.error("Topic Connection Failed [" + topicConnectionFactory + "]"); + throw new JMSException(JMSRES_CONNNECTION_FAIL); + } + } catch (Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, JMSRES_CONTROL_ERROR)); + } finally { + if (subscriber != null) { + try { subscriber.close(); subscriber = null; } + catch (Throwable e) { + if (logger.isWarn()) logger.warn("subscriber.close Failed", e); + } + } + close(); + } + } + + private byte[] getBytesMessage(BytesMessage message) throws Exception { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + byte[] buff = new byte[100]; + int getSize = -1; + try { + while(true) { + getSize = message.readBytes(buff); + if(getSize > 0) { + bos.write(buff, 0, getSize); + } + else { + break; + } + } + return bos.toByteArray(); + } catch(Exception e) { + throw new Exception("Read ByteMessage Error : " +e.getMessage()); + } finally { + try { + if(bos != null) bos.close(); + } catch(Exception ex) { + if (logger.isWarn()) logger.warn("bos.close Failed", ex); + } + } + + } + public void init() { + //jms_connectionfactory = context.getControlAttribute("jc:jms-topic-receive", "jms-factory-jndi"); + //topic_name = context.getControlAttribute("jc:jms-topic-receive", "jms-topic-jndi"); + jms_connectionfactory = ""; + topic_name = ""; + + startTopicConnection(); + } + + public void close() { + closeTopicConnection(); + } + + private void startTopicConnection() { + Context ctx = null; + try { + JmsServiceLocator locator = JmsServiceLocator.getInstance(); + + factory = locator.getTopicConnectionFactory(jms_connectionfactory); + if(factory == null) throw new Exception("factory not found - " + jms_connectionfactory); + con = factory.createTopicConnection(); + if(con == null) throw new Exception("createQueueConnection return null"); + ses = con.createTopicSession(false, TopicSession.AUTO_ACKNOWLEDGE); + if(ses == null) throw new Exception("createTopicSession return null"); + topic = locator.getTopic(topic_name); + con.start(); + } catch (Throwable e) { + logger.error("startTopicConnection", e ); + closeTopicConnection(); + if (ctx != null) try { ctx.close(); ctx = null; } catch (Throwable ex) { + logger.warn("ctx.close error"); + } + } + } + private void closeTopicConnection() { + if (ses != null) try { ses.close(); ses = null; } catch (Throwable e) { + logger.warn("ses.close error"); + } + if (con != null) try { con.stop(); } catch (Throwable e) { + logger.warn("con.stop error"); + } + } +} diff --git a/src/main/java/com/eactive/eai/control/JtcSender.java b/src/main/java/com/eactive/eai/control/JtcSender.java new file mode 100644 index 0000000..8a22085 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/JtcSender.java @@ -0,0 +1,35 @@ +package com.eactive.eai.control; + +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; + +public class JtcSender { + + static final String WEBT_CONTROL_ERROR = "RECEAIOWC001"; + + public static byte[] callService(String adapterGroupName, Properties prop, Object message, Properties tempProp) throws java.lang.Exception + { + byte[] resBytes; + try { + //new socket 과 old socket을 분기 하기 위해서 + String protocol = (String)prop.getProperty("protocol"); + + + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = null; + adapter = factory.getElinkAdapter(com.eactive.eai.adapter.Keys.TYPE_JTC); + if(prop==null) { + prop = new Properties(); + } + if(prop.getProperty("ADAPTER_GROUP_NAME") == null) { + prop.setProperty("ADAPTER_GROUP_NAME", adapterGroupName); + } + resBytes = (byte[])adapter.callService(adapterGroupName, prop, message, tempProp); + } catch(Exception e) { + throw e; + } + return resBytes; + } +} diff --git a/src/main/java/com/eactive/eai/control/LogSender.java b/src/main/java/com/eactive/eai/control/LogSender.java new file mode 100644 index 0000000..8915f9e --- /dev/null +++ b/src/main/java/com/eactive/eai/control/LogSender.java @@ -0,0 +1,34 @@ +package com.eactive.eai.control; + +import java.util.Properties; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.logger.EAILogSender; +import com.eactive.eai.common.message.EAIMessage; + +public class LogSender { + + static final String LS_CONTROL_ERROR = "RECEAIOLC001"; + + public static void send(int logPssSno, EAIMessage eaiMsg, Properties altKeyProp) + throws java.lang.Exception + { + // DBLogTransactionLogger 로 로직 이동함 + // Transaction tx = null; + try { +// tx = TxHelper.getTransactionManager().suspend(); + eaiMsg.setLogPssSno(logPssSno); + EAILogSender.send(eaiMsg, altKeyProp); + } + catch(Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, LS_CONTROL_ERROR)); + } finally { +// if(tx!=null) { +// try { +// TxHelper.getTransactionManager().resume(tx); +// } catch(Exception e) { +// } +// } + } + } +} diff --git a/src/main/java/com/eactive/eai/control/SNASender.java b/src/main/java/com/eactive/eai/control/SNASender.java new file mode 100644 index 0000000..3d3f6b8 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/SNASender.java @@ -0,0 +1,34 @@ +package com.eactive.eai.control; + +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; +import com.eactive.eai.adapter.wca.exception.WCAException; +import com.eactive.eai.common.exception.ExceptionUtil; + +public class SNASender { + static final long serialVersionUID = 1L; + + public static byte[] callService(String adapterGroupName, Properties prop, Object message,Properties tempProp) + throws Exception + { + byte[] resBytes; + try { + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = factory.getElinkAdapter(com.eactive.eai.adapter.Keys.TYPE_SNA); + resBytes = (byte[])adapter.callService(adapterGroupName, prop, message, tempProp); + } + catch(WCAException wcae) { +// String errCode = wcae.getErrorReturnCode(); +// throw new Exception(errCode); + throw new Exception(wcae.getErrorReturnCode() + ":" + wcae.getMessage()); + + } + catch(Exception e) { + throw new Exception(ExceptionUtil.getErrorCode(e, "RECEAIOSC001")); + } + + return resBytes; + } +} diff --git a/src/main/java/com/eactive/eai/control/SocketSender.java b/src/main/java/com/eactive/eai/control/SocketSender.java new file mode 100644 index 0000000..9f92156 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/SocketSender.java @@ -0,0 +1,42 @@ +package com.eactive.eai.control; + +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.common.util.Logger; + +public class SocketSender { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static final String SOCK_CONTROL_ERROR = "RECEAIOSC001"; + + public static byte[] callService(String adapterGroupName, Properties prop, Object message, Properties tempProp) throws java.lang.Exception + { + byte[] resBytes; + try { + //new socket 과 old socket을 분기 하기 위해서 +// String protocol = (String)prop.getProperty("protocol"); + + + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = null; + adapter = factory.getElinkAdapter(com.eactive.eai.adapter.Keys.TYPE_NET2); + if(prop==null) { + prop = new Properties(); + } + if(tempProp==null) { + tempProp = new Properties(); + } + if(tempProp.getProperty(Keys.OUT_ADAPTER_GROUP_NAME) == null) { + tempProp.setProperty(Keys.OUT_ADAPTER_GROUP_NAME, adapterGroupName); + } + resBytes = (byte[])adapter.callService(adapterGroupName, prop, message, tempProp); + } catch(Exception e) { + logger.error("callService error", e); + //throw new Exception(ExceptionUtil.getErrorCode(e, SOCK_CONTROL_ERROR)); + throw e; + } + return resBytes; + } +} diff --git a/src/main/java/com/eactive/eai/control/TasSocketSender.java b/src/main/java/com/eactive/eai/control/TasSocketSender.java new file mode 100644 index 0000000..bb5d564 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/TasSocketSender.java @@ -0,0 +1,58 @@ +package com.eactive.eai.control; + +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.tas.TASUtil; +import com.eactive.eai.common.util.Logger; + +public class TasSocketSender { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static final String SOCK_CONTROL_ERROR = "RECEAIOSC001"; + + public static byte[] callService(String adapterGroupName, Properties prop, Object message, Properties tempProp) throws java.lang.Exception + { + byte[] resBytes; + try { + //new socket 과 old socket을 분기 하기 위해서 +// String protocol = (String)prop.getProperty("protocol"); + String tasBizCode = (String)prop.getProperty(EAIMessageKeys.TAS_BIZ_CODE); + + if(tasBizCode == null) { + throw new Exception("TAS_BIZ_CODE 값이 전달되지 않았습니다."); + } + + if(prop==null) { + prop = new Properties(); + } + + byte[] tasRequest = TASUtil.addTasHeader((byte[])message, tasBizCode) ; + + // + // 업무별어댑터 일 경우 어댑터의 업무코드를 등록하고 + // 대표어댑터 일 경우에는 어댑터명을 어떻게 조회할지 확인 필요 +// AdapterGroupVO tasInfoAdapter = manager.getTasInfoAdapterGroupVO(tasBizCode, Keys.ADAPTER_OUT); + + prop.setProperty("ADAPTER_GROUP_NAME", adapterGroupName); + + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = null; + adapter = factory.getElinkAdapter(com.eactive.eai.adapter.Keys.TYPE_NET2); + resBytes = (byte[])adapter.callService(adapterGroupName, prop, tasRequest, tempProp); + + // TODO : 응답메시지에도 헤더가 있는지 확인필요 + // 2019.07.25 응답에도 헤더(업무코드)가 있는 것으로 확인 + if(resBytes != null && resBytes.length > 3) { + resBytes = TASUtil.removeTasHeader(resBytes); + } + + } catch(Exception e) { + logger.error("callService error",e); + //throw new Exception(ExceptionUtil.getErrorCode(e, SOCK_CONTROL_ERROR)); + throw e; + } + return resBytes; + } +} diff --git a/src/main/java/com/eactive/eai/control/Transform.java b/src/main/java/com/eactive/eai/control/Transform.java new file mode 100644 index 0000000..ef81fca --- /dev/null +++ b/src/main/java/com/eactive/eai/control/Transform.java @@ -0,0 +1,45 @@ +package com.eactive.eai.control; + +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.TransformService; + +public class Transform { + static final long serialVersionUID = 1L; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + /** + * + * isMath 는 대량 입력/출력 일때 참조를 무시 + * @param infoKey + * @param isReq + * @param transformName + * @param sources + * @param isMath + * @return + * @throws java.lang.Exception + */ + public static Object transform(String infoKey, boolean isReq, String transformName, Object[] sources, boolean isMass) + throws java.lang.Exception { + if(esbLogger.isInfo()) esbLogger.info(infoKey +" Transform START: " + transformName); + Object obj = TransformService.transform(infoKey, isReq, transformName, sources,isMass); + if(esbLogger.isInfo()) esbLogger.info(infoKey +" Transform End: " + transformName); + return obj; + } + + public static Object transformSingleForMass(String infoKey, boolean isReq, String transformName, Object sources) throws Exception{ + return transform(infoKey, isReq, transformName,new Object[]{sources},true); + } + public static Object transformSingle(String infoKey, boolean isReq, String transformName, Object sources) + throws java.lang.Exception { + return transform(infoKey, isReq, transformName,new Object[]{sources},false); + } + + public static Object transformComp(String infoKey, boolean isReq, String transformName, Object[] sources, String[] layoutNames) + throws Exception { + if(esbLogger.isInfo()) esbLogger.info(infoKey +" Transform START : " + transformName); + Object obj = TransformService.transformComp(infoKey, isReq, transformName, sources, layoutNames); + if(esbLogger.isInfo()) esbLogger.info(infoKey +" Transform END : " + transformName); + return obj; + } +} diff --git a/src/main/java/com/eactive/eai/control/TuxedoCArraySender.java b/src/main/java/com/eactive/eai/control/TuxedoCArraySender.java new file mode 100644 index 0000000..19a2419 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/TuxedoCArraySender.java @@ -0,0 +1,123 @@ +package com.eactive.eai.control; +//package com.eactive.eai.control; +// +//import javax.ejb.CreateException; +//import javax.ejb.SessionBean; +//import javax.ejb.SessionContext; +//import javax.naming.Context; +//import javax.naming.InitialContext; +//import javax.naming.NamingException; +//import javax.transaction.Transaction; +//import javax.transaction.TransactionManager; +//import weblogic.transaction.TxHelper; +// +//import weblogic.wtc.jatmi.TPException; +//import weblogic.wtc.jatmi.TPReplyException; +//import weblogic.wtc.jatmi.TypedCArray; +//import weblogic.wtc.jatmi.Reply; +//import weblogic.wtc.gwt.TuxedoConnectionFactory; +//import weblogic.wtc.gwt.TuxedoConnection; +//import weblogic.wtc.jatmi.ApplicationToMonitorInterface; +// +//public class TuxedoCArraySender { +// private static final long serialVersionUID = 1L; +// private int tpurcode; +// private int tperrno; +// +// public int gettpurcode() { +// return tpurcode; +// } +// +// public int gettperrno() { +// return tperrno; +// } +// +// public byte[] service(String svcName, boolean isSync, boolean isXA, byte[] request) +// throws TPException, TPReplyException { +// Context ctx; +// TuxedoConnectionFactory tcf = null; +// TuxedoConnection tc = null; +// TypedCArray tca; +// Reply reply; +// +// //----------------------------------------------------------------- +// // 1. Tuxedo의 TuxedoConnectionFactory를 생성한다. +// //----------------------------------------------------------------- +// try { +// ctx = new InitialContext(); +// tcf = (TuxedoConnectionFactory)ctx.lookup("tuxedo.services.TuxedoConnection"); +// } catch (NamingException ne) { +// // Could not get the tuxedo object, throw TPENOENT +// throw new TPException(TPException.TPENOENT, +// "Could not get TuxedoConnectionFactory : " + ne); +// } +// +// Transaction tx = null; +// +// TransactionManager tm = null; +// try { +// //----------------------------------------------------------------- +// // 1. TX Begin. +// //----------------------------------------------------------------- +// // Suspend Orginal transaction +// tx = TxHelper.getTransactionManager().suspend(); +// if(isXA) { +// tm = (javax.transaction.TransactionManager) +// ctx.lookup("javax.transaction.TransactionManager"); +// tm.begin(); +// } +// +// //----------------------------------------------------------------- +// // 2. TUXEDO 서비스를 호출한다. +// // 3. tpurcode를 확인해서 commit/rollback 한다. +// //----------------------------------------------------------------- +// tc = tcf.getTuxedoConnection(); +// +// int datasize = request.length; +// tca = new TypedCArray(datasize); +// tca.carray = request; +// if(isSync) { +// reply = tc.tpcall(svcName, tca, ApplicationToMonitorInterface.TPNOTRAN); +// tca = (TypedCArray)reply.getReplyBuffer(); +// if(tm != null) tm.commit(); +// return (tca.carray); +// } +// else { +// tc.tpacall(svcName, tca, ApplicationToMonitorInterface.TPNOREPLY); +// return null; +// } +// +// } catch (NamingException ne) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// ne.printStackTrace(); +// throw new TPException(TPException.TPENOENT, +// "Could not get TuxedoConnectionFactory : " + ne); +// } catch (TPReplyException tre) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// tperrno = tre.gettperrno(); +// tre.printStackTrace(); +// throw tre; +// } catch (TPException te) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// tperrno = te.gettperrno(); +// te.printStackTrace(); +// throw te; +// } catch (Exception ex) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// ex.printStackTrace(); +// throw new TPException(TPException.TPESYSTEM, "Exception: " + ex); +// } +// finally { +// // Closing the association with Tuxedo +// if(tc != null) tc.tpterm(); +// +// if(tx != null) { +// try { +// TxHelper.getTransactionManager().resume(tx); +// } catch(Exception e) { +// } +// } +// } +// } +// +//} diff --git a/src/main/java/com/eactive/eai/control/TuxedoFmlSender.java b/src/main/java/com/eactive/eai/control/TuxedoFmlSender.java new file mode 100644 index 0000000..feced25 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/TuxedoFmlSender.java @@ -0,0 +1,250 @@ +package com.eactive.eai.control; +//package com.eactive.eai.control; +// +//import javax.naming.Context; +//import javax.naming.InitialContext; +//import javax.naming.NamingException; +//import javax.transaction.Transaction; +//import javax.transaction.TransactionManager; +// +//import weblogic.transaction.TxHelper; +//import weblogic.wtc.gwt.TuxedoConnection; +//import weblogic.wtc.gwt.TuxedoConnectionFactory; +//import weblogic.wtc.jatmi.ApplicationToMonitorInterface; +//import weblogic.wtc.jatmi.CallDescriptor; +//import weblogic.wtc.jatmi.Reply; +//import weblogic.wtc.jatmi.TPException; +//import weblogic.wtc.jatmi.TPReplyException; +//import weblogic.wtc.jatmi.TypedFML; +//import weblogic.wtc.jatmi.TypedFML32; +// +//public class TuxedoFmlSender { +// private static final long serialVersionUID = 1L; +// private int tpurcode; +// private int tperrno; +// +// +// public int gettpurcode() { +// return tpurcode; +// } +// +// public int gettperrno() { +// return tperrno; +// } +// +// public TypedFML32 service(String svcName, boolean isSync, boolean isXA, TypedFML32 infml) throws Exception +// { +// +// Context ctx = null; +// TuxedoConnectionFactory tcf = null; +// TuxedoConnection tc = null; +// Reply reply; +// +// Transaction tx = null; +// TransactionManager tm = null; +// +// try { +// tx = TxHelper.getTransactionManager().suspend(); +// +// ctx = new InitialContext(); +// +// //----------------------------------------------------------------- +// // 0. TX Begin if XA +// //----------------------------------------------------------------- +// if(isXA) { +// tm = (javax.transaction.TransactionManager) +// ctx.lookup("javax.transaction.TransactionManager"); +// tm.begin(); +// } +// +// //----------------------------------------------------------------- +// // 1. Tuxedo의 TuxedoConnectionFactory를 생성한다. +// //----------------------------------------------------------------- +// tcf = (TuxedoConnectionFactory) ctx.lookup("tuxedo.services.TuxedoConnection"); +// tc = tcf.getTuxedoConnection(); +// +// //----------------------------------------------------------------- +// // 2. TUXEDO 서비스를 호출한다. +// //----------------------------------------------------------------- +// if(isSync) { +// if(isXA) { +// reply = tc.tpcall(svcName, infml, ApplicationToMonitorInterface.TPTRAN); +// } +// else { +// reply = tc.tpcall(svcName, infml, ApplicationToMonitorInterface.TPNOTRAN); +// } +// tpurcode = reply.gettpurcode(); +// if(isXA) { +// if(tpurcode < 0) { +// tm.rollback(); +// } +// else { +// tm.commit(); +// } +// } +// //----------------------------------------------------------------- +// // 3. tpurcode를 확인해서 commit/rollback 한다. +// //----------------------------------------------------------------- +// +// return (TypedFML32)reply.getReplyBuffer(); +// } +// else { +// tc.tpacall(svcName, infml, ApplicationToMonitorInterface.TPNOREPLY); +// return null; +// } +// +// } catch (NamingException ne) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// ne.printStackTrace(); +// throw new TPException(TPException.TPENOENT, +// "Could not get TuxedoConnectionFactory : " + ne); +// } catch (TPReplyException tre) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// tperrno = tre.gettperrno(); +// tre.printStackTrace(); +// throw tre; +// } catch (TPException te) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// tperrno = te.gettperrno(); +// te.printStackTrace(); +// throw te; +// } catch (Exception ex) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// ex.printStackTrace(); +// throw new TPException(TPException.TPESYSTEM, "Exception: " + ex); +// } +// finally { +// // Closing the association with Tuxedo +// if(tc != null) tc.tpterm(); +// +// if(tx!=null) { +// try { +// TxHelper.getTransactionManager().resume(tx); +// } catch(Exception e) { +// } +// } +// } +// } +// +// public TypedFML32 TPFWDSVCXA(TypedFML32 infml) throws Exception +// { +// +// Context ctx = null; +// TuxedoConnectionFactory tcf; +// TuxedoConnection tuxConnection; +// Reply reply; +// +// Transaction tx = null; +// +// TransactionManager tm = null; +// try { +// tx = TxHelper.getTransactionManager().suspend(); +// +// ctx = new InitialContext(); +// +// //----------------------------------------------------------------- +// // 1. Tuxedo의 TuxedoConnectionFactory를 생성한다. +// //----------------------------------------------------------------- +// tcf = (TuxedoConnectionFactory) ctx.lookup("tuxedo.services.TuxedoConnection"); +// tuxConnection = tcf.getTuxedoConnection(); +// +// //----------------------------------------------------------------- +// // 2. TUXEDO 서비스를 호출한다. +// //----------------------------------------------------------------- +// reply = tuxConnection.tpcall("mnEaicomn_ms", infml, ApplicationToMonitorInterface.TPNOTRAN); +// tuxConnection.tpterm(); +// //----------------------------------------------------------------- +// // 3. tpurcode를 확인해서 commit/rollback 한다. +// //----------------------------------------------------------------- +// tpurcode = reply.gettpurcode(); +////System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"); +////System.out.println("TuxedoFmlSender] TPFWDSVCXA tpurcode["+tpurcode+"]"); +////System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"); +// +// return (TypedFML32)reply.getReplyBuffer(); +// } catch (NamingException ne) { +// ne.printStackTrace(); +// throw new TPException(TPException.TPENOENT, +// "Could not get TuxedoConnectionFactory : " + ne); +// } catch (TPReplyException tre) { +// tperrno = tre.gettperrno(); +// tre.printStackTrace(); +// throw tre; +// } catch (TPException te) { +// tperrno = te.gettperrno(); +// te.printStackTrace(); +// throw te; +// } catch (Exception ex) { +// ex.printStackTrace(); +// throw new TPException(TPException.TPESYSTEM, "Exception: " + ex); +// } +// finally { +// if(tx!=null) { +// try { +// TxHelper.getTransactionManager().resume(tx); +// } catch(Exception e) { +// } +// } +// } +// } +// +// public TypedFML32 TPFWDSVCNXA(TypedFML32 infml) throws Exception +// { +// Context ctx = null; +// TuxedoConnectionFactory tcf; +// TuxedoConnection tuxConnection; +// Reply reply; +// +// Transaction tx = null; +// +// TransactionManager tm = null; +// try { +// tx = TxHelper.getTransactionManager().suspend(); +// +// ctx = new InitialContext(); +// +// //----------------------------------------------------------------- +// // 1. Tuxedo의 TuxedoConnectionFactory를 생성한다. +// //----------------------------------------------------------------- +// tcf = (TuxedoConnectionFactory) ctx.lookup("tuxedo.services.TuxedoConnection"); +// tuxConnection = tcf.getTuxedoConnection(); +// +// //----------------------------------------------------------------- +// // 2. TUXEDO 서비스를 호출한다. +// //----------------------------------------------------------------- +// reply = tuxConnection.tpcall("mnEaicomn_ss", infml, ApplicationToMonitorInterface.TPNOTRAN); +// tuxConnection.tpterm(); +// //----------------------------------------------------------------- +// // 3. tpurcode를 확인해서 commit/rollback 한다. +// //----------------------------------------------------------------- +// tpurcode = reply.gettpurcode(); +////System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"); +////System.out.println("TuxedoFmlSender] TPFWDSVCNXA tpurcode["+tpurcode+"]"); +////System.out.println("$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$"); +// return (TypedFML32)reply.getReplyBuffer(); +// } catch (NamingException ne) { +// ne.printStackTrace(); +// throw new TPException(TPException.TPENOENT, +// "Could not get TuxedoConnectionFactory : " + ne); +// } catch (TPReplyException tre) { +// tperrno = tre.gettperrno(); +// tre.printStackTrace(); +// throw tre; +// } catch (TPException te) { +// tperrno = te.gettperrno(); +// te.printStackTrace(); +// throw te; +// } catch (Exception ex) { +// ex.printStackTrace(); +// throw new TPException(TPException.TPESYSTEM, "Exception: " + ex); +// } +// finally { +// if(tx!=null) { +// try { +// TxHelper.getTransactionManager().resume(tx); +// } catch(Exception e) { +// } +// } +// } +// } +//} diff --git a/src/main/java/com/eactive/eai/control/TuxedoStringSender.java b/src/main/java/com/eactive/eai/control/TuxedoStringSender.java new file mode 100644 index 0000000..a8b9b89 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/TuxedoStringSender.java @@ -0,0 +1,119 @@ +package com.eactive.eai.control; +//package com.eactive.eai.control; +// +//import javax.naming.Context; +//import javax.naming.InitialContext; +//import javax.naming.NamingException; +//import javax.transaction.Transaction; +//import javax.transaction.TransactionManager; +//import weblogic.transaction.TxHelper; +// +//import weblogic.wtc.jatmi.TPException; +//import weblogic.wtc.jatmi.TPReplyException; +//import weblogic.wtc.jatmi.Reply; +//import weblogic.wtc.jatmi.TypedString; +//import weblogic.wtc.gwt.TuxedoConnectionFactory; +//import weblogic.wtc.gwt.TuxedoConnection; +//import weblogic.wtc.jatmi.ApplicationToMonitorInterface; +// +//public class TuxedoStringSender { +// private static final long serialVersionUID = 1L; +// private int tpurcode; +// private int tperrno; +// +// public int gettpurcode() { +// return tpurcode; +// } +// +// public int gettperrno() { +// return tperrno; +// } +// +// public byte[] service(String svcName, boolean isSync, boolean isXA, byte[] request) +// throws TPException, TPReplyException { +// Context ctx; +// TuxedoConnectionFactory tcf = null; +// TuxedoConnection tc = null; +// TypedString tString; +// Reply reply; +// +// //----------------------------------------------------------------- +// // 1. Tuxedo의 TuxedoConnectionFactory를 생성한다. +// //----------------------------------------------------------------- +// try { +// ctx = new InitialContext(); +// tcf = (TuxedoConnectionFactory)ctx.lookup("tuxedo.services.TuxedoConnection"); +// } catch (NamingException ne) { +// // Could not get the tuxedo object, throw TPENOENT +// throw new TPException(TPException.TPENOENT, +// "Could not get TuxedoConnectionFactory : " + ne); +// } +// +// Transaction tx = null; +// +// TransactionManager tm = null; +// try { +// //----------------------------------------------------------------- +// // 1. TX Begin. +// //----------------------------------------------------------------- +// // Suspend Orginal transaction +// tx = TxHelper.getTransactionManager().suspend(); +// if(isXA) { +// tm = (javax.transaction.TransactionManager) +// ctx.lookup("javax.transaction.TransactionManager"); +// tm.begin(); +// } +// +// //----------------------------------------------------------------- +// // 2. TUXEDO 서비스를 호출한다. +// // 3. tpurcode를 확인해서 commit/rollback 한다. +// //----------------------------------------------------------------- +// tc = tcf.getTuxedoConnection(); +// +// tString = new TypedString(new String(request)); +// if(isSync) { +// reply = tc.tpcall(svcName, tString, ApplicationToMonitorInterface.TPNOTRAN); +// tString = (TypedString)reply.getReplyBuffer(); +// if(tm != null) tm.commit(); +// String sMsg = tString.getStringBuffer().toString(); +// return (sMsg.getBytes()); +// } +// else { +// tc.tpacall(svcName, tString, ApplicationToMonitorInterface.TPNOREPLY); +// return null; +// } +// +// } catch (NamingException ne) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// ne.printStackTrace(); +// throw new TPException(TPException.TPENOENT, +// "Could not get TuxedoConnectionFactory : " + ne); +// } catch (TPReplyException tre) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// tperrno = tre.gettperrno(); +// tre.printStackTrace(); +// throw tre; +// } catch (TPException te) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// tperrno = te.gettperrno(); +// te.printStackTrace(); +// throw te; +// } catch (Exception ex) { +// try { if(tm != null) tm.rollback(); } catch(Exception e) { } +// ex.printStackTrace(); +// throw new TPException(TPException.TPESYSTEM, "Exception: " + ex); +// } +// finally { +// // Closing the association with Tuxedo +// if(tc != null) tc.tpterm(); +// +// if(tx != null) { +// try { +// TxHelper.getTransactionManager().resume(tx); +// } catch(Exception e) { +// } +// } +// } +// } +// +//} diff --git a/src/main/java/com/eactive/eai/control/WebSocketSender.java b/src/main/java/com/eactive/eai/control/WebSocketSender.java new file mode 100644 index 0000000..4caaa98 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/WebSocketSender.java @@ -0,0 +1,45 @@ +package com.eactive.eai.control; + +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; +import com.eactive.eai.common.util.Logger; + +public class WebSocketSender { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + static final String SOCK_CONTROL_ERROR = "RECEAIOSC001"; + + public static byte[] callService(String adapterGroupName, Properties prop, Object message, Properties tempProp) throws java.lang.Exception + { + byte[] resBytes; + try { + //new socket 과 old socket을 분기 하기 위해서 + String protocol = (String)prop.getProperty("protocol"); + + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = null; +// if(protocol == null || protocol.trim().length() ==0) { +// adapter = factory.getWLIAdapter(com.eactive.eai.adapter.Keys.TYPE_NET); +// } +// else { + adapter = factory.getElinkAdapter(com.eactive.eai.adapter.Keys.TYPE_WSK); +// } + if(prop==null) { + prop = new Properties(); + } + if(tempProp==null) { + tempProp = new Properties(); + } + if(tempProp.getProperty("ADAPTER_GROUP_NAME") == null) { + tempProp.setProperty("ADAPTER_GROUP_NAME", adapterGroupName); + } + resBytes = (byte[])adapter.callService(adapterGroupName, prop, message, tempProp); + } catch(Exception e) { + if (logger.isError()) logger.error(e.getMessage(),e); + //throw new Exception(ExceptionUtil.getErrorCode(e, SOCK_CONTROL_ERROR)); + throw e; + } + return resBytes; + } +} diff --git a/src/main/java/com/eactive/eai/control/WebTSender.java b/src/main/java/com/eactive/eai/control/WebTSender.java new file mode 100644 index 0000000..5427231 --- /dev/null +++ b/src/main/java/com/eactive/eai/control/WebTSender.java @@ -0,0 +1,35 @@ +package com.eactive.eai.control; + +import java.util.Properties; + +import com.eactive.eai.adapter.ElinkAdapter; +import com.eactive.eai.adapter.ElinkAdapterFactory; + +public class WebTSender { + + static final String WEBT_CONTROL_ERROR = "RECEAIOWC001"; + + public static byte[] callService(String adapterGroupName, Properties prop, Object message, Properties tempProp) throws java.lang.Exception + { + byte[] resBytes; + try { + //new socket 과 old socket을 분기 하기 위해서 + String protocol = (String)prop.getProperty("protocol"); + + + ElinkAdapterFactory factory = ElinkAdapterFactory.newInstance(); + ElinkAdapter adapter = null; + adapter = factory.getElinkAdapter(com.eactive.eai.adapter.Keys.TYPE_WBT); + if(prop==null) { + prop = new Properties(); + } + if(prop.getProperty("ADAPTER_GROUP_NAME") == null) { + prop.setProperty("ADAPTER_GROUP_NAME", adapterGroupName); + } + resBytes = (byte[])adapter.callService(adapterGroupName, prop, message, tempProp); + } catch(Exception e) { + throw e; + } + return resBytes; + } +} diff --git a/src/main/java/com/eactive/eai/env/ConfigKeys.java b/src/main/java/com/eactive/eai/env/ConfigKeys.java new file mode 100644 index 0000000..dd81dab --- /dev/null +++ b/src/main/java/com/eactive/eai/env/ConfigKeys.java @@ -0,0 +1,29 @@ +package com.eactive.eai.env; + +public interface ConfigKeys { + public static final String USE_INTERNAL_QUEUE = "use.internal.queue"; + public static final String USE_INTERNAL_TOPIC = "use.internal.topic"; + public static final String USE_CACHE_STORE = "use.cache.store"; + + public static final String LOGGER_ASYNC_ACTIVE = "logger.async.active"; + public static final String LOGGER_ASYNC_ACTIVE_DEFAULT = "true"; + + public static final String LOGGER_ASYNC_POOL_INITONSTARTUP = "logger.async.pool.initonstartup"; + public static final String LOGGER_ASYNC_MAXPOOLS = "logger.async.pool.maxsize"; + public static final String LOGGER_ASYNC_INITPOOLS = "logger.async.pool.initsize"; + public static final String LOGGER_ASYNC_QUEUES = "logger.async.queue.size"; + public static final String LOGGER_ASYNC_WORKERS = "logger.async.worker.size"; + + public static final String LOGGER_ASYNC_WAITSTRATEGY = "logger.async.worker.waitstrategy"; + public static final String LOGGER_ASYNC_WAITSTRATEGY_BLOCK = "BLOCK"; + public static final String LOGGER_ASYNC_WAITSTRATEGY_BUSYSPIN = "BUSYSPIN"; + public static final String LOGGER_ASYNC_WAITSTRATEGY_TIME = "TIME"; + public static final String LOGGER_ASYNC_WAITSTRATEGY_SLEEP = "SLEEP"; + public static final String LOGGER_ASYNC_WAITSTRATEGY_YIELD = "YIELD"; + + public static final String HTTP_ASYNC_DEFAULT_DUMMY_DATA = "http.async.default.dummy.data"; + public static final String HTTP_ASYNC_DUMMY_DATA_PREFIX = "http.async.dummy.data."; + + public static final String HTTP_CLIENT_URL_REPLACE_NAME = "http.client.url.replace.name"; + +} diff --git a/src/main/java/com/eactive/eai/env/ElinkConfig.java b/src/main/java/com/eactive/eai/env/ElinkConfig.java new file mode 100644 index 0000000..e8d88b5 --- /dev/null +++ b/src/main/java/com/eactive/eai/env/ElinkConfig.java @@ -0,0 +1,304 @@ +package com.eactive.eai.env; + +import java.util.Enumeration; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.util.ContainerUtil; + +@Component +@PropertySource("/WEB-INF/properties/env.common.properties") +public class ElinkConfig implements ConfigKeys { + // message handling options + private static boolean useInternalQueue = true; + private static boolean useCacheTopic = true; + private static boolean useCacheStore = true; + + // async logging options + private static boolean useAsyncLogging = true; + private static boolean asyncInitOnstartup = true; + private static int asyncPoolMaxSize = 10; + private static int asyncPoolInitSize = 8; + private static int asyncQueueSize = 1024; + private static int asyncWorkers = 16; + + private static String waitStrategy = LOGGER_ASYNC_WAITSTRATEGY; + + private static ConcurrentHashMap asyncDummyData = new ConcurrentHashMap(); + private static String asyncDefaultDummyData = ""; + + private static String httpClientUrlReplaceName =""; + + @Autowired + private Environment env; + +// static { +// reload(); +// } + + private ElinkConfig() { + + } + + + public static String getConfigLog() { + StringBuilder sb = new StringBuilder(); + sb.append( "[ElinkConfig]\n"); + sb.append( ">> Async Transaction Configuration\n"); + sb.append( String.format("%s = %s\n", USE_INTERNAL_QUEUE, useInternalQueue) ); + sb.append( String.format("%s = %s\n", USE_INTERNAL_TOPIC, useCacheTopic) ); + sb.append( String.format("%s = %s\n", USE_CACHE_STORE, useCacheStore) ); + sb.append( ">> Async Logging Configuration\n"); + sb.append( String.format("%s = %s\n", LOGGER_ASYNC_ACTIVE, useAsyncLogging) ); + sb.append( String.format("%s = %s\n", LOGGER_ASYNC_POOL_INITONSTARTUP, asyncInitOnstartup) ); + sb.append( String.format("%s = %s\n", LOGGER_ASYNC_MAXPOOLS, asyncPoolMaxSize) ); + sb.append( String.format("%s = %s\n", LOGGER_ASYNC_INITPOOLS, asyncPoolInitSize) ); + sb.append( String.format("%s = %s\n", LOGGER_ASYNC_QUEUES, asyncQueueSize) ); + sb.append( String.format("%s = %s\n", LOGGER_ASYNC_WORKERS, asyncWorkers) ); + sb.append( String.format("%s = %s\n", LOGGER_ASYNC_WAITSTRATEGY, waitStrategy) ); + sb.append(">> Async Dummy Configuration\n"); + sb.append(String.format("%s = %s\n", HTTP_ASYNC_DEFAULT_DUMMY_DATA, asyncDefaultDummyData)); + for (String key : asyncDummyData.keySet()) { + sb.append(String.format("%s = %s\n", HTTP_ASYNC_DUMMY_DATA_PREFIX + key, asyncDummyData.get(key))); + } + return sb.toString(); + + } + + @PostConstruct + public void reload() { + String sBoolean = null; + String sCount = null; + + try { + sBoolean = env.getProperty(USE_INTERNAL_QUEUE); + useInternalQueue = Boolean.valueOf(sBoolean); + } catch (Exception ex) { + useInternalQueue = true; + } + + try { + sBoolean = env.getProperty(USE_INTERNAL_TOPIC, "true"); + useCacheTopic = Boolean.valueOf(sBoolean); + } catch (Exception ex) { + useCacheTopic = true; + } + + try { + sBoolean = env.getProperty(USE_CACHE_STORE, "true"); + useCacheStore = Boolean.valueOf(sBoolean); + } catch (Exception ex) { + useCacheStore = true; + } + + try { + sBoolean = env.getProperty(LOGGER_ASYNC_ACTIVE, LOGGER_ASYNC_ACTIVE_DEFAULT); + useAsyncLogging = Boolean.valueOf(sBoolean); + } catch (Exception ex) { + useAsyncLogging = true; + } + + try { + sBoolean = env.getProperty(LOGGER_ASYNC_POOL_INITONSTARTUP, "true"); + asyncInitOnstartup = Boolean.valueOf(sBoolean); + } catch (Exception ex) { + asyncInitOnstartup = true; + } + + try { + sCount = env.getProperty(LOGGER_ASYNC_MAXPOOLS, "10"); + asyncPoolMaxSize = Integer.parseInt(sCount); + if(asyncPoolMaxSize < 1) { + asyncPoolMaxSize = 1; + } + } catch (Exception ex) { + asyncPoolMaxSize = 10; + } + + try { + sCount = env.getProperty(LOGGER_ASYNC_INITPOOLS, "8"); + asyncPoolInitSize = Integer.parseInt(sCount); + if(asyncPoolInitSize < 1) { + asyncPoolInitSize = 1; + } + } catch (Exception ex) { + asyncPoolInitSize = 8; + } + + if(asyncPoolInitSize > asyncPoolMaxSize) { + asyncPoolInitSize = asyncPoolMaxSize; + } + + try { + sCount = env.getProperty(LOGGER_ASYNC_QUEUES, "1024"); + asyncQueueSize = Integer.parseInt(sCount); + if (asyncQueueSize < 2) { + asyncQueueSize = 2; + } + if (Integer.bitCount(asyncQueueSize) != 1) { + asyncQueueSize = (int)Math.pow(2, Math.getExponent(asyncQueueSize)); + } + } catch (Exception ex) { + asyncQueueSize = 1024; + } + + + try { + sCount = env.getProperty(LOGGER_ASYNC_WORKERS, "16"); + asyncWorkers = Integer.parseInt(sCount); + if (asyncWorkers < 1) { + asyncWorkers = 1; + } + } catch (Exception ex) { + asyncWorkers = 16; + } + + try { + waitStrategy = env.getProperty(LOGGER_ASYNC_WAITSTRATEGY, LOGGER_ASYNC_WAITSTRATEGY_TIME); + } catch (Exception ex) { + waitStrategy = LOGGER_ASYNC_WAITSTRATEGY_TIME; + } + try { + asyncDefaultDummyData = System.getProperty(HTTP_ASYNC_DEFAULT_DUMMY_DATA, ""); + } catch (Exception ex) { + asyncDefaultDummyData = ""; + } + + // TODO : check usage & replace other config + Properties sysProps = System.getProperties(); + for (Enumeration e = sysProps.keys(); e.hasMoreElements();) { + String key = (String) e.nextElement(); + if (key != null && key.startsWith(HTTP_ASYNC_DUMMY_DATA_PREFIX)) { + String data = (String) sysProps.get(key); + if (data == null) + data = ""; + asyncDummyData.put(key.replace(HTTP_ASYNC_DUMMY_DATA_PREFIX, ""), data); + } + } + try { + httpClientUrlReplaceName = env.getProperty(HTTP_CLIENT_URL_REPLACE_NAME, "TRAN_CODE"); + } catch (Exception ex) { + httpClientUrlReplaceName = "TRAN_CODE"; + } + + } + + public static boolean isUseInternalQueue() { + return (ContainerUtil.get() == ContainerUtil.TOMCAT || useInternalQueue); + } + + public static void setUseInternalQueue(boolean useInternalQueue) { + ElinkConfig.useInternalQueue = useInternalQueue; + } + + public static boolean isUseCacheTopic() { + return (ContainerUtil.get() == ContainerUtil.TOMCAT || useCacheTopic); + } + + public static void setUseCacheTopic(boolean useCacheTopic) { + ElinkConfig.useCacheTopic = useCacheTopic; + } + + public static boolean isUseCacheStore() { + return useCacheStore; + } + + public static void setUseCacheStore(boolean useCacheStore) { + ElinkConfig.useCacheStore = useCacheStore; + } + + public static boolean isUseAsyncLogging() { + return useAsyncLogging; + } + + public static void setUseAsyncLogging(boolean useAsyncLogging) { + ElinkConfig.useAsyncLogging = useAsyncLogging; + } + + public static int getAsyncPoolMaxSize() { + return asyncPoolMaxSize; + } + + public static boolean isAsyncInitOnstartup() { + return asyncInitOnstartup; + } + + public static void setAsyncInitOnstartup(boolean asyncInitOnstartup) { + ElinkConfig.asyncInitOnstartup = asyncInitOnstartup; + } + + public static void setAsyncPoolMaxSize(int asyncPoolMaxSize) { + ElinkConfig.asyncPoolMaxSize = asyncPoolMaxSize; + } + + public static int getAsyncPoolInitSize() { + return asyncPoolInitSize; + } + + public static void setAsyncPoolInitSize(int asyncPoolInitSize) { + ElinkConfig.asyncPoolInitSize = asyncPoolInitSize; + } + + public static int getAsyncQueueSize() { + return asyncQueueSize; + } + + public static void setAsyncQueueSize(int asyncQueueSize) { + ElinkConfig.asyncQueueSize = asyncQueueSize; + } + + public static int getAsyncWorkers() { + return asyncWorkers; + } + + public static void setAsyncWorkers(int asyncWorkers) { + ElinkConfig.asyncWorkers = asyncWorkers; + } + + public static String getWaitStrategy() { + return waitStrategy; + } + + public static void setWaitStrategy(String waitStrategy) { + ElinkConfig.waitStrategy = waitStrategy; + } + + public static String getAsyncDummyData(String type) { + if (type == null) + return asyncDefaultDummyData; + String d = asyncDummyData.get(type); + if (d == null) + return asyncDefaultDummyData; + return asyncDummyData.get(type); + } + + public static String getAsyncDummyDataForAdapterGroup(String adapterGroupName) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO agvo = null; + try { + agvo = adapterManager.getAdapterGroup(adapterGroupName); + } catch (DAOException e) { + return getAsyncDummyData(null); + } + String adptrMsgPtrnCd = null; + if (agvo != null) { + adptrMsgPtrnCd = agvo.getAdptrMsgPtrnCd(); + } + return getAsyncDummyData(adptrMsgPtrnCd); + } + public static String getHttpClientUrlReplaceName() { + return httpClientUrlReplaceName; + } + + +} diff --git a/src/main/java/com/eactive/eai/env/SystemPropConfig.java b/src/main/java/com/eactive/eai/env/SystemPropConfig.java new file mode 100644 index 0000000..48eb84a --- /dev/null +++ b/src/main/java/com/eactive/eai/env/SystemPropConfig.java @@ -0,0 +1,42 @@ +package com.eactive.eai.env; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +import javax.annotation.PostConstruct; +import javax.servlet.ServletContext; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.context.ServletContextAware; + +@Configuration +public class SystemPropConfig implements ServletContextAware { + + private ServletContext servletContext; + + private final String SYSTEM_PROP_FILE_PATH = "/WEB-INF/properties/env.system.properties"; + + @Override + public void setServletContext(ServletContext servletContext) { + this.servletContext = servletContext; + } + + @PostConstruct + public void loadlPropertiesToSystemProp() { + System.out.println("loadPropertiesToSystemProp: "+SYSTEM_PROP_FILE_PATH); + Properties sysProp = new Properties(); + try(InputStream is = servletContext.getResourceAsStream(SYSTEM_PROP_FILE_PATH)){ + sysProp.load(is); + sysProp.forEach((key, value) -> { + if (StringUtils.isBlank(System.getProperty((String) key))) { + System.setProperty((String) key, (String) value); + System.out.println("Set system prop: "+key+"="+value); + } + }); + } catch (Throwable th) { + System.err.println(SYSTEM_PROP_FILE_PATH+" load failed. - "+ th.getMessage()); + } + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/action/RouteAction.java b/src/main/java/com/eactive/eai/flowcontrol/action/RouteAction.java new file mode 100644 index 0000000..5478eb1 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/action/RouteAction.java @@ -0,0 +1,10 @@ +package com.eactive.eai.flowcontrol.action; + +public interface RouteAction { + /** + * EAI 서비스코드별 Routing 정보를 위한 값을 추출하는 기능을 수행한다. + */ + public String[] getRouteKeys(byte[] message) throws Exception; + + public String getDescription(); +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/action/RouteActionException.java b/src/main/java/com/eactive/eai/flowcontrol/action/RouteActionException.java new file mode 100644 index 0000000..5881ac6 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/action/RouteActionException.java @@ -0,0 +1,11 @@ +package com.eactive.eai.flowcontrol.action; + +public class RouteActionException extends Exception { + public RouteActionException() { + super("RouteActionException is occured."); + } + + public RouteActionException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/action/RouteActionFactory.java b/src/main/java/com/eactive/eai/flowcontrol/action/RouteActionFactory.java new file mode 100644 index 0000000..d28f633 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/action/RouteActionFactory.java @@ -0,0 +1,20 @@ +package com.eactive.eai.flowcontrol.action; + +import com.eactive.eai.common.util.Logger; + +public class RouteActionFactory { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static RouteAction createAction(String actionName) throws RouteActionException { + RouteAction action = null; + try { + Class cl = Class.forName(actionName); + action = (RouteAction)cl.newInstance(); + } catch(Exception e) { + logger.error("Cannot create a RouteAction.", e); + throw new RouteActionException("Cannot create a RouteAction. - "+actionName); + } + return action; + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/action/RouteActionSupport.java b/src/main/java/com/eactive/eai/flowcontrol/action/RouteActionSupport.java new file mode 100644 index 0000000..b818e71 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/action/RouteActionSupport.java @@ -0,0 +1,84 @@ +package com.eactive.eai.flowcontrol.action; + +import com.eactive.eai.common.util.Logger; + +public class RouteActionSupport implements RouteAction { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = null; + + return keys; + } + + public int strncmp(String src, String value, int length) { + int result = -1; + + if(src == null || value == null) { + return -1; + } + + if(src.length() < length) { + return -1; + } + + if(src.startsWith(value)) { + result = 0; + } + return result; + } + + public String strncpy(String src, String value, int startPos) { + + if(value == null || value.length() < 1) { + return src; + } + StringBuffer sb = new StringBuffer(); + sb.append(src.substring(0,startPos)); + sb.append(value); + sb.append( src.substring(startPos+value.length()) ); + return sb.toString(); + } + + public String strncpy(byte[] src, int startPos, int length) { + + + if(src == null || src.length <(startPos + length)) { + return ""; + } + + byte[] resBytes = new byte[length]; + + System.arraycopy(src, startPos, resBytes, 0, resBytes.length ); + + return new String(resBytes); + } + + public boolean bytesncmp(byte[] src, int startPos, String value) { + + if(value == null || value.length() < 1) { + return false; + } + + byte[] valueBytes = value.getBytes(); + int valueBytesLength = valueBytes.length; + + if(src == null || src.length <(startPos + valueBytesLength)) { + return false; + } + + byte[] cmpareBytes = new byte[valueBytesLength]; + + System.arraycopy(src, startPos, cmpareBytes, 0, cmpareBytes.length ); + if(value.equals(new String(cmpareBytes))) { + return true; + } + + return false; + } + + public String getDescription() { + return ""; + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/activemq/DefaultQueueConsumer.java b/src/main/java/com/eactive/eai/flowcontrol/activemq/DefaultQueueConsumer.java new file mode 100644 index 0000000..4265db0 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/activemq/DefaultQueueConsumer.java @@ -0,0 +1,132 @@ +package com.eactive.eai.flowcontrol.activemq; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.routing.ElinkESBProcessProxy; +import com.eactive.eai.common.routing.RoutingManager; +import com.eactive.eai.common.routing.RoutingVO; +import com.eactive.eai.common.util.Logger; + +import javax.jms.*; +import java.util.Enumeration; +import java.util.Properties; +import java.lang.IllegalStateException; + +public class DefaultQueueConsumer implements Runnable, ExceptionListener { + + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + Connection connection = null; + Session session = null; + MessageConsumer consumer = null; + String name = null; + String queue = null; + boolean run = true; + + public DefaultQueueConsumer(String name, Connection con, String queue) { + this.connection = con; + try { + this.name = name; + this.queue = queue; + connection.start(); + connection.setExceptionListener(this); + + // Create a Session + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Create the destination (Topic or Queue) + Destination destination = session.createQueue(queue); + consumer = session.createConsumer(destination); + } catch (JMSException e) { + logger.error(e); + } + } + + @Override + public void run() { + EAIMessage eaiMessage = null; + while(run) { + try { + Message message = consumer.receive(2000); + + ObjectMessage omsg = null; + + if(message == null) { +// logger.warn(name + " -> EMPTY MESSAGE..."); + continue; + } + + if(message instanceof ObjectMessage) { + omsg = (ObjectMessage)message; + } else { + throw new RuntimeException(name+" Invlid JMS Message Type. - "+message); + } + + try { + eaiMessage = (EAIMessage)omsg.getObject(); + } catch(Exception e) { + throw new RuntimeException(name+" Invlid value object in ObjectMessage. - "+e.getMessage() ); + } + + RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm()); + String serviceURI = routingVO.getSyncRoutingPath(); + boolean isLocal = true; + + Properties prop = new Properties(); + try { + Enumeration en = omsg.getPropertyNames(); + for (; en.hasMoreElements(); ) { + String propName = (String)en.nextElement(); + try { + String propValue = omsg.getStringProperty(propName); + prop.setProperty(propName, propValue); + } catch (MessageFormatException e) { + prop.put(propName, omsg.getObjectProperty(propName)); + } + } + } catch(JMSException e) { + throw new RuntimeException(name+" onMessage Error. - "+e.getMessage()); + } + + try { + logger.debug("ActiveMQ Receiver : " + eaiMessage); + eaiMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, prop); + } catch(Exception e) { + throw new RuntimeException(name+" onMessage Error. - "+e.getMessage()); + } + } + catch(IllegalStateException ise) { + logger.error(name+" IllegalStateException = " + ise.getMessage(), ise); + + } + catch(JMSException e) { + logger.error(name+" JMSException = " + e.getMessage(), e); + run = false; + } + catch(RuntimeException e) { + logger.error(name+" RuntimeException = " + e.getMessage(), e); + } + } + } + + public void stop() { + run = false; + if(consumer != null) + try { + consumer.close(); + } catch (JMSException e) { } + if(session != null) + try { + session.close(); + } catch (JMSException e) { } + if(connection != null) + try { + connection.close(); + } catch (JMSException e) { } + } + + @Override + public void onException(JMSException arg0) { + logger.error("JMS Exception occured. Shutting down client."); + stop(); + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/activemq/QueueConsumerService.java b/src/main/java/com/eactive/eai/flowcontrol/activemq/QueueConsumerService.java new file mode 100644 index 0000000..2381b70 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/activemq/QueueConsumerService.java @@ -0,0 +1,120 @@ +package com.eactive.eai.flowcontrol.activemq; + +import com.eactive.eai.common.util.Logger; +import org.apache.activemq.ActiveMQConnectionFactory; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +import javax.jms.Connection; +import javax.jms.Session; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class QueueConsumerService implements InitializingBean, DisposableBean { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + // uri = "vm://localhost?broker.persistent=false&broker.useJmx=false" + // uri = "tcp://localhost:61617"" + private String uri; + private String queue; + private int maxThread; + + Connection connection = null; + Session[] sessions = null; + DefaultQueueConsumer[] consumers = null; + + ExecutorService es = null; + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getQueue() { + return queue; + } + + public void setQueue(String queue) { + this.queue = queue; + } + + public int getMaxThread() { + return maxThread; + } + + public void setMaxThread(int maxThread) { + this.maxThread = maxThread; + } + + @Override + public void afterPropertiesSet() throws Exception { + startConsumer(); + } + + @Override + public void destroy() throws Exception { + stopConsumer(); + } + + public void startConsumer() { + try { + ActiveMQConnectionFactory connectionFactory = new ActiveMQConnectionFactory(uri); + connectionFactory.setTrustAllPackages(true); + + es = Executors.newFixedThreadPool(maxThread); + + connection = connectionFactory.createConnection(); + connection.start(); + + consumers = new DefaultQueueConsumer[maxThread]; + + for(int i=0; i EMPTY MESSAGE..."); + continue; + } + + if(message instanceof ObjectMessage) { + omsg = (ObjectMessage)message; + } else { + throw new RuntimeException(name+" Invlid JMS Message Type. - "+message); + } + + try { + eaiMessage = (EAIMessage)omsg.getObject(); + } catch(Exception e) { + throw new RuntimeException(name+" Invlid value object in ObjectMessage. - "+e.getMessage() ); + } + + RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm()); + String serviceURI = routingVO.getSyncRoutingPath(); + boolean isLocal = true; + + Properties prop = new Properties(); + try { + Enumeration en = omsg.getPropertyNames(); + for (; en.hasMoreElements(); ) { + String propName = (String)en.nextElement(); + String propValue = omsg.getStringProperty(propName); + prop.setProperty(propName, propValue); + } + } catch(JMSException e) { + throw new RuntimeException(name+" onMessage Error. - "+e.getMessage()); + } + + try { + logger.debug("JEUS JMS Receiver : " + eaiMessage); + eaiMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, prop); + } catch(Exception e) { + throw new RuntimeException(name+" onMessage Error. - "+e.getMessage()); + } + } + catch(IllegalStateException ise) { + logger.error(name+" IllegalStateException = " + ise.getMessage(), ise); + + } + catch(JMSException e) { + logger.error(name+" JMSException = " + e.getMessage(), e); + run = false; + } + catch(RuntimeException e) { + logger.error(name+" RuntimeException = " + e.getMessage(), e); + } + } + } + + public void stop() { + run = false; + if(consumer != null) + try { + consumer.close(); + } catch (JMSException e) { } + if(session != null) + try { + session.close(); + } catch (JMSException e) { } + if(connection != null) + try { + connection.close(); + } catch (JMSException e) { } + } + + @Override + public void onException(JMSException arg0) { + logger.error("JMS Exception occured. Shutting down client."); + stop(); + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jeus/QueueConsumerService.java b/src/main/java/com/eactive/eai/flowcontrol/jeus/QueueConsumerService.java new file mode 100644 index 0000000..d4444a6 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jeus/QueueConsumerService.java @@ -0,0 +1,103 @@ +package com.eactive.eai.flowcontrol.jeus; + +import com.eactive.eai.common.util.Logger; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +import javax.jms.Connection; +import javax.jms.QueueConnectionFactory; +import javax.jms.Session; +import javax.naming.InitialContext; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class QueueConsumerService implements InitializingBean, DisposableBean { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private String uri; + private String queue; + private int maxThread; + + Connection connection = null; + Session[] sessions = null; + DefaultQueueConsumer[] consumers = null; + + public final static String JNDI_FACTORY = ""; + + ExecutorService es = null; + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getQueue() { + return queue; + } + + public void setQueue(String queue) { + this.queue = queue; + } + + public int getMaxThread() { + return maxThread; + } + + public void setMaxThread(int maxThread) { + this.maxThread = maxThread; + } + + @Override + public void afterPropertiesSet() throws Exception { + startConsumer(); + } + + @Override + public void destroy() throws Exception { + stopConsumer(); + } + + public void startConsumer() { + try { + InitialContext ctx = new InitialContext(); + QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx.lookup(uri); + es = Executors.newFixedThreadPool(maxThread); + + connection = connectionFactory.createConnection(); + connection.start(); + + consumers = new DefaultQueueConsumer[maxThread]; + + for(int i=0; i 2) { +// instid = serverName.substring(serverName.length()-2, serverName.length()); +// } +// } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[ FCActiveMqReceiver INFO ]"); + sb.append("\nReveciver Name = " + this.receiverName); + sb.append(", Queue Name = " + this.queueName); + sb.append(", Error Queue Name = " + this.errorQueueName); + sb.append(", Recever Count = " + this.receiverCount); + sb.append(", Delay Time(ms) = " + this.errorDelayTimeMs); + sb.append(", Retry Count = " + this.retryCount); + sb.append(", Selector = " + this.messageSelector); + sb.append(", Description = " + this.description); + + return sb.toString(); + } + + public FCActiveMqReceiver(String rcvName, String qname, String errorqname, int rcvCount, int delayMs, int retryCnt, + boolean isTx, int ackMode, String msgSelector, String descr) throws Exception { + + queueName = qname; + errorQueueName = errorqname; + receiverName = rcvName; + receiverCount = rcvCount; + errorDelayTimeMs = delayMs; + retryCount = retryCnt; + messageSelector = msgSelector; + description = descr; + + // trim space + if (queueName != null) + queueName = queueName.trim(); + if (errorQueueName != null) + errorQueueName = errorQueueName.trim(); + if (receiverName != null) + receiverName = receiverName.trim(); + if (messageSelector != null) + messageSelector = messageSelector.trim(); + +// this.isTx = isTx; + threadDowned = new boolean[receiverCount]; + connection = new Connection[receiverCount]; + receiverObj = new ReceiverObject[receiverCount]; + receiverThread = new Thread[receiverCount]; + + String clientId = receiverName; + + String connectionUrl = AmqPooledConnectionFactory.CONNECTION_URI; + + if (logger.isInfo()) + logger.info("FCActiveMqReceiver Connection : " + connectionUrl); + + try { + factory = new ActiveMQConnectionFactory(connectionUrl); + factory.setTrustAllPackages(true); + + // Create the connections + for (int i = 0; i < receiverCount; i++) { + // create each connection + connection[i] = factory.createConnection(); + + // clientId = receiverName + instid + "-" + i; +// clientId = receiverName + "-" + i; + + receiverObj[i] = new ReceiverObject(rcvName, i, connection[i], queueName, this.messageSelector, + this.errorQueueName, this.errorDelayTimeMs, this.retryCount, connectionUrl); + receiverObj[i].setName(clientId); + if (logger.isDebug()) + logger.debug("[" + new java.util.Date() + "] Receiver Thread : [" + clientId + "] " + queueName); + receiverThread[i] = new Thread(receiverObj[i]); + receiverThread[i].setDaemon(true);// avoids thread leaks if + receiverThread[i].start(); + } + } catch (Exception e) { + if (logger.isError()) + logger.error(" Exception while in constructor : ", e); + close(); + throw e; + } + + } + + /** + * Start receiving for all receivers + */ + public synchronized void startReceiving() throws Exception { + + if (!allThreadDowned) { + throw new Exception("Thread Started Already !"); + } + + try { + + allThreadDowned = false; + } catch (Exception jmse) { + if (logger.isError()) { + logger.error("FCQueueReceiver: JMSException while in startReceiving() method : ", jmse); + } + close(); + throw jmse; + } + + } + + /** + * Clear any messages received after the connection was started but before the + * user starts the test. + */ + public synchronized void clearReceived() { + // Clear Counter + for (int i = 0; i < receiverObj.length; i++) { + receiverObj[i].clearCount(); + } + } + + /** + * Stop sending for all Receiver threads + */ + public synchronized void stopReceiving() { + // Cleanup each ReceiverObj (stops sending and causes thread to exit) + for (int i = 0; i < receiverObj.length; i++) { + // stops each ReceiverObject + if (receiverObj[i] != null) + receiverObj[i].stopReceiver(); + receiverObj[i].stopThread(); + } + } + + public String[][] getStatus() { + String[][] receiveStatus = new String[receiverObj.length][4]; + for (int i = 0; i < receiverObj.length; i++) { + if (receiverObj[i] != null) { + receiveStatus[i][0] = receiverObj[i].getName(); + receiveStatus[i][1] = "" + receiverObj[i].msgCounter; + receiveStatus[i][2] = "" + receiverObj[i].msgSuccessCounter; + receiveStatus[i][3] = "" + receiverObj[i].receiverStatus; + } + } + return receiveStatus; + } + + public String[] getMessageCount() { + String[] receiveStatus = new String[2]; + int receivedTotal = 0; + int successTotal = 0; + + for (int i = 0; i < receiverObj.length; i++) { + if (receiverObj[i] != null) { + receivedTotal += receiverObj[i].msgCounter; + successTotal += receiverObj[i].msgSuccessCounter; + } + } + receiveStatus[0] = "" + receivedTotal; + receiveStatus[1] = "" + successTotal; + + return receiveStatus; + } + + /** + * Closes all connections which in turn stops the receivers and close + */ + public void close() { + // Close all the connections + for (int i = 0; i < connection.length; i++) { + try { + if (connection[i] != null) + connection[i].close(); + } catch (Exception ex) { + if (logger.isError()) { + logger.error("In close(): Caught Exception trying to close connection(s)", ex); + } + } + } + } + + // //////////////////////////////////////////////////////////////////////// + /** + * Inner class: ReceiverObject is an ASYNCHRONOUS receiver. + */ + // //////////////////////////////////////////////////////////////////////// + private class ReceiverObject extends Thread implements ExceptionListener { + private String recvName = null; + + private String queueName = null; + // Channel + private Connection connection = null; + Session session = null; + MessageConsumer consumer = null; + + private int id; // identifies the ReceiverObject + + private int msgCounter = 0; // keeps track of messages + + private int msgSuccessCounter = 0; + + private int receiverStatus = 0; // 0 - wait, 1 - running, 2 - retry + + private Object lockCounter = new Object();// used to synchronize + // updates of the message + // counter + + private boolean keepRunning = false; // used to exit the sending loop + // in the run method + + private String messageSelector = ""; + + private String errorQueueName = ""; + + private int errorDelayTimeMs = 0; + + private int retryCount = 0; + + private String queueConFactory = ""; + + /** + * Construct a ReceiverObject param id - the id number should be unique for each + * ReceiverObject param sess - the session object under which the receiver is + * created param q - the Queue object to receiver from + */ + public ReceiverObject(String recvName, int id, Connection connection, String queueName, String messageSelector, + String errorQueueName, int errorDelayMs, int retryCnt, String connectionUri) throws Exception { + init(recvName, id, connection, queueName, messageSelector, errorQueueName, errorDelayMs, retryCnt, + connectionUri); + } + + public void init(String recvName, int sid, Connection connection, String queueName, String selector, + String errQueueName, int deplayMs, int retryCnt, String qConFactory) throws Exception { + this.recvName = recvName; + this.id = sid; + this.connection = connection; + this.queueName = queueName; + this.messageSelector = selector; + this.errorQueueName = errQueueName; + this.errorDelayTimeMs = deplayMs; + this.retryCount = retryCnt; + this.queueConFactory = qConFactory; + + logger.info("recvName=" + this.recvName + ",messageSelector=" + this.messageSelector); + try { + this.connection.start(); + this.connection.setExceptionListener(this); + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + Destination destination = session.createQueue(queueName); + consumer = session.createConsumer(destination); + } catch (Exception jmse) { + if (logger.isError()) + logger.error(this.getName() + + "] In ReceiverObject constructor: JMSException while setting up receiverObj[" + id + "]" + + recvName, jmse); + close(); + throw jmse; + } + } + + /** + * Get number of message received since last get + * + * return totaSinceLastGet total number of messages received since the last get + */ + public int getMsgCount() { + synchronized (lockCounter) { + return msgCounter; + } + } + + public void setMsgCount(int msgCounter) { + synchronized (lockCounter) { + this.msgCounter = msgCounter; + } + } + + /** + * Clear any messages received + */ + public void clearCount() { + synchronized (lockCounter) { + if (logger.isError()) { + logger.error(this.getName() + "] Clearing id: [" + id + "] clearing: " + msgCounter); + } + // reset counter + msgCounter = 0; + msgSuccessCounter = 0; + } + } + + /** + * Stop the receiver + */ + public void stopReceiver() { + keepRunning = false; + // stop Receiver from sending which causes thread to exit run() method + // and thus finish. + if (consumer != null) + try { + consumer.close(); + } catch (JMSException e) { + } + if (session != null) + try { + session.close(); + } catch (JMSException e) { + } + if (connection != null) + try { + connection.close(); + } catch (JMSException e) { + } + } + + public void stopThread() { + // super.stop(); + } + + public void run() { + if (Thread.currentThread().getName().startsWith("Thread-")) { + Thread.currentThread().setName(queueName + "-" + Thread.currentThread().getName()); + } + keepRunning = true; + threadDowned[id] = false; + EAIMessage eaiMessage = null; + + while (keepRunning) { + try { + receiverStatus = 0; + + Message message = consumer.receive(2000); + + if (message == null) { +// Thread.sleep(500); + continue; + } + + synchronized (lockCounter) { + receiverStatus = 1; + msgCounter++; + } + + ObjectMessage omsg = null; + + if (message == null) { +// logger.warn(name + " -> EMPTY MESSAGE..."); + continue; + } + + if (message instanceof ObjectMessage) { + omsg = (ObjectMessage) message; + } else { + throw new RuntimeException("Invlid JMS Message Type. - " + message); + } + + try { + eaiMessage = (EAIMessage) omsg.getObject(); + } catch (Exception e) { + throw new RuntimeException(this.getName() + "] EAI메시지가 아닙니다. - " + e.getMessage()); + } + +// String guidLogPrefix = "ActiveMQ Receiver] GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + String guidLogPrefix = "ActiveMQ Receiver] GUID[" + + eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) + "] UUID[" + + eaiMessage.getSvcOgNo() + "] "; + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + this.getName() + "] receiverObj[" + id + "] Executed - " + + eaiMessage.getEAISvcCd() + ":" + eaiMessage.getSvcOgNo()); + } + + RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm()); + String serviceURI = routingVO.getSyncRoutingPath(); + boolean isLocal = true; + + Properties prop = new Properties(); + try { + Enumeration en = omsg.getPropertyNames(); + while (en.hasMoreElements()) { + String propName = (String) en.nextElement(); + Object objProp = omsg.getObjectProperty(propName); + prop.put(propName, objProp);// HttpAdapterServiceRest 의 INBOUND_HEADER 항목 고려해서 변경 + } + } catch (Exception e) { + throw new RuntimeException(guidLogPrefix + this.getName() + "] 프라퍼티 설정에러 - " + e.getMessage()); + } + + EAIMessage resEAIMessage = null; + + try { + // EAI 거래처리 Error 이고 retry count가 있으면 회수만큼 재시도 + // errorDelayTimeMs > 0 면 sleep + int retry = 1; + // retry count 만큼 반복한다. + // -1 : 무한대 retry + // 0 : 처리되지 않는다. + + if (this.retryCount == 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] SKIP Execute EAISvcCd (" + + eaiMessage.getEAISvcCd() + ") Retry Count - " + this.retryCount); + } + continue; // 처리를 중단한다. + } else if (this.retryCount > 1) { + receiverStatus = 2; + } + + while (((retry <= this.retryCount) || (this.retryCount == -1)) && keepRunning) { + resEAIMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, + prop); + + if (resEAIMessage == null) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + + "] response EAIMessage is NULL. SKIP Retry Count - " + this.retryCount); + } + break; + } + + if (MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) { + break; + } else { + if ((this.retryCount > 0) && (retry <= this.retryCount)) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Call Error(" + + resEAIMessage.getRspErrCd() + ") Retry - " + retry + "/" + + this.retryCount); + } + // 다음 처리전에 delay를 준다. + if (this.errorDelayTimeMs > 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Delay Before Retry - " + + this.errorDelayTimeMs); + } + try { + Thread.sleep(this.errorDelayTimeMs); + } catch (Exception e) { + + } + } + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] FlowControl Call Error(" + + resEAIMessage.getRspErrCd() + ") No Retry"); + } + } + } + retry++; + + } + + } catch (Exception e) { + if (logger.isError()) { + if (resEAIMessage == null) { + logger.error( + guidLogPrefix + this.getName() + "] FlowControl Call Error " + e.getMessage(), + e); + } else { + logger.error(guidLogPrefix + this.getName() + "] FlowControl Call Error(" + + resEAIMessage.getRspErrCd() + ") " + e.getMessage(), e); + } + } + } + + // increment message counter + synchronized (lockCounter) { + msgSuccessCounter++; + } + + // EAI 거래처리 Error 면 + // errorQueueName 이 있으면 redirect + // errorDelayTimeMs > 0 면 sleep + if (resEAIMessage != null && (!MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd()))) { + if (this.errorQueueName != null && this.errorQueueName.length() > 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Redirect Messsage to - " + + this.errorQueueName); + } + JMSSender.sendToQueue(eaiMessage, queueConFactory, this.errorQueueName, prop); + } + } + // 다음 처리 전에 delay를 준다. + if (this.errorDelayTimeMs > 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Delay Before Receive Next Message - " + + this.errorDelayTimeMs); + } + try { + Thread.sleep(this.errorDelayTimeMs); + } catch (Exception e) { + + } + } + + } catch (Exception ex) { + if (logger.isError()) { + logger.error(this.getName() + "] JMSException for receiverObj[" + id + "] - " + ex.getMessage(), + ex); + } + try { + // -------------------------------------------- + // Set Error + if (eaiMessage != null) { + String[] msgArgs = new String[1]; + msgArgs[0] = eaiMessage.getEAISvcCd(); + String rspErrorCode = "RECEAIFQR001"; // [EAI 서비스코드:{1}] 큐수신자가 플로우컨트롤 호출 중 오류 발생 + String rspErrorMsg = ExceptionUtil.make(ex, rspErrorCode, msgArgs); +// eaiMessage.setRspErrCd(rspErrorCode); +// eaiMessage.setRspErrMsg(rspErrorMsg); + eaiMessage.setRspErr(rspErrorCode,rspErrorMsg); + // -------------------------------------------- +// String mesgDmanDvcd = eaiMessage.getKbMsg().getKBHeader().getTelgmDmndDstcd(); +// String mesgDmanDvcd = eaiMessage.getExtMsg().getSendRecv(); + String mesgDmanDvcd = eaiMessage.getMapper() + .getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(mesgDmanDvcd)) { + // 응답인 경우 + eaiMessage.setLogPssSno(400); + } else { + // 요청 인경우 + eaiMessage.setLogPssSno(200); + } + EAILogSender.send(eaiMessage, null); + } else { + throw new Exception("EAIMessage is NULL"); + } + } catch (Exception e) { + if (logger.isError()) + logger.error(this.getName() + "] ErrorLogging :" + e.getMessage()); + } + + // auto reconnect so wait 10 seconds + try { + Thread.sleep(10000); + } catch (Exception e) { + // Do nothing + } + } + } // end of while + + // if Stop Event Occurred + if (!keepRunning) { + threadDowned[id] = true; + synchronized (this) { + boolean tmpDowned = false; + for (int j = 0; j < threadDowned.length; j++) { + if (threadDowned[j] == true) { + tmpDowned = true; + } else { + tmpDowned = false; + break; + } + } + + if (tmpDowned) { + allThreadDowned = true; + } + } + } + + } // end of run + + @Override + public void onException(JMSException arg0) { + logger.error("JMS Exception occured. Shutting down client."); + stopReceiver(); + } + + }// end of inner class ReceiverObject +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiver.java b/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiver.java new file mode 100644 index 0000000..1fd73f8 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiver.java @@ -0,0 +1,706 @@ +package com.eactive.eai.flowcontrol.jms; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.Properties; + +import javax.jms.JMSException; +import javax.jms.ObjectMessage; +import javax.jms.Queue; +import javax.jms.QueueConnection; +import javax.jms.QueueConnectionFactory; +import javax.jms.QueueReceiver; +import javax.jms.QueueSession; +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.logger.EAILogSender; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.ElinkESBProcessProxy; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.routing.RoutingManager; +import com.eactive.eai.common.routing.RoutingVO; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.JMSSender; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class FCQueueReceiver { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + // ------------------------------------ + // Rule Var + // ------------------------------------ + private String receiverName; + private String queueName; + private String errorQueueName; + private int receiverCount; + private int errorDelayTimeMs; + private int retryCount; + private String messageSelector = ""; + private String description; + + // ------------------------------------ + // Used for Test + // ------------------------------------ + public static final boolean isSingleApplication = false; + public final static String JNDI_FACTORY = "weblogic.jndi.WLInitialContextFactory"; + + // ------------------------------------ + // Objects needed for JMS clients + // ------------------------------------ + private QueueConnectionFactory factory; + private QueueConnection[] connection; + private QueueSession[] session; + private ReceiverObject[] receiverObj = null; + private boolean isTx = false; + + // ------------------------------------ + // Thread Runtime Info + // ------------------------------------ + private Thread[] receiverThread = null; + private boolean[] threadDowned = null; + public boolean allThreadDowned = true; + + private static String instid = "11"; + static { + instid = EAIServerManager.getInstance().getInstId(); + } + + // For Local Test with Single Application + private static InitialContext getInitialContext(String url) throws NamingException { + Hashtable env = new Hashtable<>(); + env.put(Context.INITIAL_CONTEXT_FACTORY, JNDI_FACTORY); + env.put(Context.PROVIDER_URL, url); + return new InitialContext(env); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[ FCQueueReceiver INFO ]"); + sb.append("\nReveciver Name = " + this.receiverName); + sb.append(", Queue Name = " + this.queueName); + sb.append(", Error Queue Name = " + this.errorQueueName); + sb.append(", Recever Count = " + this.receiverCount); + sb.append(", Delay Time(ms) = " + this.errorDelayTimeMs); + sb.append(", Retry Count = " + this.retryCount); + sb.append(", Selector = " + this.messageSelector); + sb.append(", Description = " + this.description); + + return sb.toString(); + } + + public FCQueueReceiver(String rcvName, String qname, String errorqname, int rcvCount, int delayMs, int retryCnt, + boolean isTx, int ackMode, String msgSelector, String descr) throws Exception { + + queueName = qname; + errorQueueName = errorqname; + receiverName = rcvName; + receiverCount = rcvCount; + errorDelayTimeMs = delayMs; + retryCount = retryCnt; + messageSelector = msgSelector; + description = descr; + + // trim space + if (queueName != null) + queueName = queueName.trim(); + if (errorQueueName != null) + errorQueueName = errorQueueName.trim(); + if (receiverName != null) + receiverName = receiverName.trim(); + if (messageSelector != null) + messageSelector = messageSelector.trim(); + + this.isTx = isTx; + threadDowned = new boolean[receiverCount]; + connection = new QueueConnection[receiverCount]; + session = new QueueSession[receiverCount]; + receiverObj = new ReceiverObject[receiverCount]; + receiverThread = new Thread[receiverCount]; + + Queue[] queue = new Queue[receiverCount]; + + InitialContext ctx = null; + + String clientId = receiverName; + + String queueConFactory = ""; + try { + if (isSingleApplication) { + if (logger.isDebug()) + logger.debug("Local Application Test"); + ctx = getInitialContext("t3://localhost:7001"); + queueConFactory = "TestConnectionFactory"; + } else { + ctx = new InitialContext(); + PropManager propManager = PropManager.getInstance(); + queueConFactory = propManager.getProperty(RouteKeys.GROUP_NAME, + RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY); + + } + } catch (Exception e) { + if (logger.isError()) + logger.error("FCQueueReceiver: get InitialContext Error", e); + throw e; + } + + if (logger.isDebug()) + logger.debug(queueConFactory); + + try { + // Create the connections + for (int i = 0; i < receiverCount; i++) { + factory = (QueueConnectionFactory) ctx.lookup(queueConFactory); + // create each connection + connection[i] = factory.createQueueConnection(); + + // Auto Reconnection with WebLogic Function + // ((weblogic.jms.extensions.WLConnection) + // connection[i]).setReconnectPolicy("all"); + + clientId = receiverName + instid + "-" + i; + + // connection[i].setClientID(clientId); + + session[i] = connection[i].createQueueSession(isTx, ackMode); + queue[i] = (Queue) ctx.lookup(queueName); + receiverObj[i] = new ReceiverObject(i, session[i], queue[i], this.messageSelector, this.errorQueueName, + this.errorDelayTimeMs, this.retryCount, queueConFactory); + receiverObj[i].setName(clientId); + if (logger.isDebug()) + logger.debug("[" + new java.util.Date() + "] Receiver Thread : [" + clientId + "] " + queue[i]); + receiverThread[i] = new Thread(receiverObj[i]); + receiverThread[i].setDaemon(true);// avoids thread leaks ifz + } +// } catch(weblogic.jms.common.InvalidClientIDException icid) { +// if(logger.isError()) logger.error("Duplicate ClientID Exception while in constructor : "); +// icid.printStackTrace(); +// close(); +// throw icid; + } catch (Exception e) { + if (logger.isError()) + logger.error(" Exception while in constructor", e); + close(); + throw e; + } + + } + + /** + * Start receiving for all receivers + */ + public synchronized void startReceiving() throws Exception { + + if (!allThreadDowned) { + throw new Exception("Thread Started Already !"); + } + + try { + for (int i = 0; i < connection.length; i++) { + connection[i].start(); + } + + for (int i = 0; i < receiverThread.length; i++) { + receiverThread[i].start(); + } + allThreadDowned = false; + } catch (JMSException jmse) { + logger.error("FCQueueReceiver: JMSException while in startReceiving() method", jmse); + close(); + throw jmse; + } + + } + + /** + * Clear any messages received after the connection was started but before the + * user starts the test. + */ + public synchronized void clearReceived() { + // Clear Counter + for (int i = 0; i < receiverObj.length; i++) { + receiverObj[i].clearCount(); + } + } + + /** + * Stop sending for all Receiver threads + */ + public synchronized void stopReceiving() { + // Cleanup each ReceiverObj (stops sending and causes thread to exit) + for (int i = 0; i < receiverObj.length; i++) { + // stops each ReceiverObject + if (receiverObj[i] != null) + receiverObj[i].stopReceiver(); + receiverObj[i].stopThread(); + } + } + + public String[][] getStatus() { + String[][] receiveStatus = new String[receiverObj.length][4]; + for (int i = 0; i < receiverObj.length; i++) { + if (receiverObj[i] != null) { + receiveStatus[i][0] = receiverObj[i].getName(); + receiveStatus[i][1] = "" + receiverObj[i].msgCounter; + receiveStatus[i][2] = "" + receiverObj[i].msgSuccessCounter; + receiveStatus[i][3] = "" + receiverObj[i].receiverStatus; + } + } + return receiveStatus; + } + + public String[] getMessageCount() { + String[] receiveStatus = new String[2]; + int receivedTotal = 0; + int successTotal = 0; + + for (int i = 0; i < receiverObj.length; i++) { + if (receiverObj[i] != null) { + receivedTotal += receiverObj[i].msgCounter; + successTotal += receiverObj[i].msgSuccessCounter; + } + } + receiveStatus[0] = "" + receivedTotal; + receiveStatus[1] = "" + successTotal; + + return receiveStatus; + } + + /** + * Closes all connections which in turn stops the receivers and exits JVM + */ + public void close() { + if (isTx) { + for (int k = 0; k < session.length; k++) { + try { + if (session[k] != null) { + session[k].rollback(); + } + } catch (JMSException jmse) { + logger.warn("Exception rolling back session " + k, jmse); + } + } + } + + // Close all the connections before exiting the application + for (int i = 0; i < connection.length; i++) { + try { + if (connection[i] != null) + connection[i].close(); + } catch (JMSException jmse) { + logger.error("In close(): Caught JMSException trying to close connection(s)", jmse); + } + } + } + + // //////////////////////////////////////////////////////////////////////// + /** + * Inner class: ReceiverObject is an ASYNCHRONOUS receiver. + */ + // //////////////////////////////////////////////////////////////////////// + private class ReceiverObject extends Thread { + + // Session + private QueueSession qsession = null; // session to use for receiving + + private QueueReceiver qreceiver = null; // reciever object to use + // for receiving + + private Queue queue = null; // queue object to receive from + + private int id; // identifies the ReceiverObject + + private int msgCounter = 0; // keeps track of messages + + private int msgSuccessCounter = 0; + + private int receiverStatus = 0; // 0 - wait, 1 - running, 2 - retry + + private Object lockCounter = new Object();// used to synchronize + // updates of the message + // counter + + private boolean keepRunning = false; // used to exit the sending loop + // in the run method + + private String messageSelector = ""; + + private String errorQueueName = ""; + + private int errorDelayTimeMs = 0; + + private int retryCount = 0; + + private String queueConFactory = ""; + + /** + * Construct a ReceiverObject param id - the id number should be unique for each + * ReceiverObject param sess - the session object under which the receiver is + * created param q - the Queue object to receiver from + */ + public ReceiverObject(int id, QueueSession sess, Queue q, String messageSelector, String errorQueueName, + int errorDelayMs, int retryCnt, String qConFactory) throws Exception { + init(id, sess, q, messageSelector, errorQueueName, errorDelayMs, retryCnt, qConFactory); + } + + public void init(int sid, QueueSession sess, Queue q, String selector, String errQueueName, int deplayMs, + int retryCnt, String qConFactory) throws Exception { + id = sid; + qsession = sess; + queue = q; + messageSelector = selector; + errorQueueName = errQueueName; + errorDelayTimeMs = deplayMs; + retryCount = retryCnt; + queueConFactory = qConFactory; + + try { + + if (messageSelector == null || messageSelector.trim().length() == 0) { + qreceiver = qsession.createReceiver(queue); + } else { + qreceiver = qsession.createReceiver(queue, messageSelector); + } + } catch (JMSException jmse) { + if (logger.isWarn()) + logger.warn(this.getName() + + "] In ReceiverObject constructor: JMSException while setting up receiverObj[" + id + "]", + jmse); + close(); + throw jmse; + } + } + + /** + * Get number of message received since last get + * + * return totaSinceLastGet total number of messages received since the last get + */ + public int getMsgCount() { + synchronized (lockCounter) { + return msgCounter; + } + } + + public void setMsgCount(int msgCounter) { + synchronized (lockCounter) { + this.msgCounter = msgCounter; + } + } + + /** + * Clear any messages received + */ + public void clearCount() { + synchronized (lockCounter) { + if (logger.isWarn()) + logger.warn(this.getName() + "] Clearing id: [" + id + "] clearing: " + msgCounter); + // reset counter + msgCounter = 0; + msgSuccessCounter = 0; + } + } + + /** + * Stop the receiver + */ + public void stopReceiver() { + // stop Receiver from sending which causes thread to exit run() method + // and thus finish. + keepRunning = false; + } + + public void stopThread() { + // super.stop(); + } + + @Override + public void run() { + if (Thread.currentThread().getName().startsWith("Thread-")) { + Thread.currentThread().setName(queueName + "-" + Thread.currentThread().getName()); + } + keepRunning = true; + threadDowned[id] = false; + javax.jms.Message msg = null; + ObjectMessage omsg = null; + EAIMessage eaiMessage = null; + + while (keepRunning) { + try { + receiverStatus = 0; + eaiMessage = null; + + msg = qreceiver.receive(1000); + if (msg == null) { + continue; + } + + synchronized (lockCounter) { + receiverStatus = 1; + msgCounter++; + } + + if (msg instanceof ObjectMessage) { + omsg = (ObjectMessage) msg; + } else { + throw new RuntimeException(this.getName() + "] 지원하지않는 메시지 - " + msg); + } + + try { + eaiMessage = (EAIMessage) omsg.getObject(); + } catch (Exception e) { + throw new RuntimeException(this.getName() + "] EAI메시지가 아닙니다. - " + e.getMessage()); + } + +// String guidLogPrefix = "Queue Receiver] GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + String guidLogPrefix = "Queue Receiver] GUID[" + + eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) + "] UUID[" + + eaiMessage.getSvcOgNo() + "] "; + + if (esbLogger.isInfo()) { + esbLogger.info(guidLogPrefix + this.getName() + "] receiverObj[" + id + "] Executed - " + + eaiMessage.getEAISvcCd()); + } + + RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm()); + String serviceURI = routingVO.getSyncRoutingPath(); + boolean isLocal = true; + + Properties prop = new Properties(); + try { + Enumeration en = omsg.getPropertyNames(); + while (en.hasMoreElements()) { + String propName = (String) en.nextElement(); + Object objProp = omsg.getObjectProperty(propName); + prop.put(propName, objProp);// HttpAdapterServiceRest 의 INBOUND_HEADER 항목 고려해서 변경 + } + } catch (JMSException e) { + throw new RuntimeException(guidLogPrefix + this.getName() + "] 프라퍼티 설정에러 - " + e.getMessage()); + } + + EAIMessage resEAIMessage = null; + + try { + // EAI 거래처리 Error 이고 retry count가 있으면 회수만큼 재시도 + // errorDelayTimeMs > 0 면 sleep + int retry = 1; + // retry count 만큼 반복한다. + // -1 : 무한대 retry + // 0 : 처리되지 않는다. + + if (this.retryCount == 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] SKIP Execute EAISvcCd (" + + eaiMessage.getEAISvcCd() + ") Retry Count - " + this.retryCount); + } + continue; // 처리를 중단한다. + } else if (this.retryCount > 1) { + receiverStatus = 2; + } + + while (((retry <= this.retryCount) || (this.retryCount == -1)) && keepRunning) { + resEAIMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, + prop); + + if (resEAIMessage == null) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + + "] response EAIMessage is NULL. SKIP Retry Count - " + this.retryCount); + } + break; + } + + if (MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) { + break; + } else { + if ((this.retryCount > 0) && (retry <= this.retryCount)) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Call Error(" + + resEAIMessage.getRspErrCd() + ") Retry - " + retry + "/" + + this.retryCount); + } + // 다음 처리전에 delay를 준다. + if (this.errorDelayTimeMs > 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Delay Before Retry - " + + this.errorDelayTimeMs); + } + try { + Thread.sleep(this.errorDelayTimeMs); + } catch (Exception e) { + logger.warn("sleep error", e); + } + } + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] FlowControl Call Error(" + + resEAIMessage.getRspErrCd() + ") No Retry"); + } + } + } + retry++; + + } // while(retry <= this.retryCount) + + } catch (Exception e) { + if (logger.isError()) { + logger.error(guidLogPrefix + this.getName() + "] FlowControl Call Error", e); + } + } + + if (msg != null) { + if (isTx) { + try { + qsession.commit(); + } catch (JMSException jmse) { + throw jmse; + } + } + // increment message counter + synchronized (lockCounter) { + msgSuccessCounter++; + } + msg = null; + } + + if (resEAIMessage != null) { + // EAI 거래처리 Error 면 + // errorQueueName 이 있으면 redirect + // errorDelayTimeMs > 0 면 sleep + if (!MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) { + if (this.errorQueueName != null && this.errorQueueName.length() > 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Redirect Messsage to - " + + this.errorQueueName); + } + JMSSender.sendToQueue(eaiMessage, queueConFactory, this.errorQueueName, prop); + } + } + } + // 다음 처리 전에 delay를 준다. + if (this.errorDelayTimeMs > 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Delay Before Receive Next Message - " + + this.errorDelayTimeMs); + } + try { + Thread.sleep(this.errorDelayTimeMs); + } catch (Exception e) { + logger.warn("sleep error", e); + } + } + } catch (Exception jmse) { + if (msg != null) { + msg = null; + } + if (logger.isError()) { + logger.error( + this.getName() + "] JMSException for receiverObj[" + id + "] - " + jmse.getMessage(), + jmse); + } + + if (eaiMessage != null) { + // -------------------------------------------- + // Set Error + String[] msgArgs = new String[1]; + msgArgs[0] = eaiMessage.getEAISvcCd(); + String rspErrorCode = "RECEAIFQR001"; // [EAI 서비스코드:{1}] 큐수신자가 플로우컨트롤 호출 중 오류 발생 + String rspErrorMsg = ExceptionUtil.make(jmse, rspErrorCode, msgArgs); +// eaiMessage.setRspErrCd(rspErrorCode); +// eaiMessage.setRspErrMsg(rspErrorMsg); + eaiMessage.setRspErr(rspErrorCode,rspErrorMsg); + // -------------------------------------------- +// String telgmDmndDstcd = eaiMessage.getKbMsg().getKBHeader().getTelgmDmndDstcd(); +// String telgmDmndDstcd = eaiMessage.getExtMsg().getSendRecv(); + String telgmDmndDstcd = eaiMessage.getMapper() + .getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd)) { + // 응답인 경우 + eaiMessage.setLogPssSno(400); + } else { + // 요청 인경우 + eaiMessage.setLogPssSno(200); + } + + try { + EAILogSender.send(eaiMessage, null); + } catch (Exception e) { + if (logger.isError()) + logger.error(this.getName() + "] ErrorLogging :" + e.getMessage()); + } + } + // auto reconnect so wait 10 seconds + try { + Thread.sleep(10000); + } catch (Exception e) { + logger.warn("sleep error", e); + } + } catch (Throwable rte) { + if (logger.isError()) { + logger.error(this.getName() + "] runtime exception for receiverObj[" + id + "] - " + + rte.getMessage(), rte); + } + + if (eaiMessage != null) { + // -------------------------------------------- + // Set Error + String[] msgArgs = new String[1]; + msgArgs[0] = eaiMessage.getEAISvcCd(); + String rspErrorCode = "RECEAIFQR001"; // [EAI 서비스코드:{1}] 플로우컨트롤 호출 중 오류가 발생 + String rspErrorMsg = ExceptionUtil.make(rte, rspErrorCode, msgArgs); +// eaiMessage.setRspErrCd(rspErrorCode); +// eaiMessage.setRspErrMsg(rspErrorMsg); + eaiMessage.setRspErr(rspErrorCode,rspErrorMsg); + // -------------------------------------------- +// String telgmDmndDstcd = eaiMessage.getKbMsg().getKBHeader().getTelgmDmndDstcd(); +// String telgmDmndDstcd = eaiMessage.getExtMsg().getSendRecv(); + String telgmDmndDstcd = eaiMessage.getMapper() + .getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd)) { + // 응답인 경우 + eaiMessage.setLogPssSno(400); + } else { + // 요청 인경우 + eaiMessage.setLogPssSno(200); + } + + try { + EAILogSender.send(eaiMessage, null); + + } catch (Exception e) { + if (logger.isError()) + logger.error(this.getName() + "] ErrorLogging :" + e.getMessage()); + } + } + } + } // end of while + + // if Stop Event Occurred + if (!keepRunning) { + threadDowned[id] = true; + synchronized (this) { + boolean tmpDowned = false; + for (int j = 0; j < threadDowned.length; j++) { + if (threadDowned[j] == true) { + tmpDowned = true; + } else { + tmpDowned = false; + break; + } + } + + if (tmpDowned) { + allThreadDowned = true; + } + } + } + + } // end of run + + }// end of inner class ReceiverObject +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverDAO.java b/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverDAO.java new file mode 100644 index 0000000..154b3c4 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverDAO.java @@ -0,0 +1,69 @@ +package com.eactive.eai.flowcontrol.jms; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.flowcontrol.jms.FCQueueReceiver; +import com.eactive.eai.flowcontrol.jms.loader.FCQueueReceiverLoader; +import com.eactive.eai.flowcontrol.jms.mapper.FCQueueReceiverMapper; + +@Service +@Transactional +public class FCQueueReceiverDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private FCQueueReceiverLoader fcQueueReceiverEntityService; + + @Autowired + private FCQueueReceiverMapper fcQueueReceiverMapper; + + public Map getAllReceivers() throws DAOException { + boolean isScalable = BooleanUtils.toBoolean(System.getProperty("scalable")); + String serverName =""; + if(isScalable) { + serverName ="ALL"; + }else { + serverName = EAIServerManager.getInstance().getLocalServerName(); + } + try { + Map fCQueueMap = new HashMap<>(); + Stream fcQueuesReceivers = fcQueueReceiverEntityService.loadAll(serverName); + logger.info("[ @@ Load FCQueueReceiver Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + fcQueuesReceivers.forEach(e -> { + FCQueueReceiverVO fcQueueReceiverVO = fcQueueReceiverMapper.toVo(e); + fCQueueMap.put(fcQueueReceiverVO.getReceiverName(), fcQueueReceiverVO); + logger.info("@ " + fcQueueReceiverVO.toString()); + }); + + logger.info("[>>Load FCQueueReceiver Configuration - ended ]"); + return fCQueueMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICCM101")); + } + } + + public FCQueueReceiverVO getReceiver(String queRcverName) throws DAOException { + + try { + FCQueueReceiver fcQueueReceiver = fcQueueReceiverEntityService.getById(queRcverName); + FCQueueReceiverVO fcQueueReceiverVO = fcQueueReceiverMapper.toVo(fcQueueReceiver); + logger.info("@ " + fcQueueReceiverVO.toString()); + return fcQueueReceiverVO; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICCM101")); + } + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverManager.java b/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverManager.java new file mode 100644 index 0000000..910b33d --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverManager.java @@ -0,0 +1,406 @@ +package com.eactive.eai.flowcontrol.jms; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import javax.jms.Session; + +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.activemq.AmqPooledConnectionFactory; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.env.ElinkConfig; + +@Component +public class FCQueueReceiverManager implements Lifecycle { + public static final int MQ_ACTIVEMQ = 0; + public static final int MQ_JMS = 1; + public static final int MQ_RABBITMQ = 2; + + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private Map receiverVos = new HashMap<>(); + private HashMap receivers = new HashMap<>(); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + private boolean started; + + @Autowired + FCQueueReceiverDAO fcQueueReceiverDAO; + + public static FCQueueReceiverManager getInstance() { + return ApplicationContextProvider.getContext().getBean(FCQueueReceiverManager.class); + } + + private String getConnectionURL() { + String connectionUrl = PropManager.getInstance().getProperty(RouteKeys.GROUP_NAME, + RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY); + if (connectionUrl == null || ElinkConfig.isUseInternalQueue()) { + connectionUrl = AmqPooledConnectionFactory.CONNECTION_URI; + } + + return connectionUrl; + } + + private int getMqType() { + String connectionUri = getConnectionURL(); + int type = MQ_ACTIVEMQ; + + if (connectionUri == null) { + return MQ_ACTIVEMQ; + } + + if (connectionUri.startsWith("tcp:")) { + type = MQ_ACTIVEMQ; + } else if (connectionUri.startsWith("vm:")) { + type = MQ_ACTIVEMQ; + } else if (connectionUri.startsWith("amqp:")) { + type = MQ_RABBITMQ; + } else { + type = MQ_JMS; + } + + return type; + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICFM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + receiverVos = fcQueueReceiverDAO.getAllReceivers(); + } catch (DAOException e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICFM202")); + } + + Iterator it = receiverVos.keySet().iterator(); + String key = ""; + while (it.hasNext()) { + key = it.next(); + FCQueueReceiverVO vo = receiverVos.get(key); + try { + if ("1".equals(vo.getBascQueRcverYn())) { + startReceiver(vo.getReceiverName(), vo.getQueueName(), vo.getErrorQueueName(), + vo.getReceiverCount(), vo.getErrorDelayTimeMs(), vo.getRetryCount(), + vo.getMessageSelector(), vo.getDescription()); + } else { + if (logger.isWarn()) { + logger.warn("FCQueueReceiverManager] Error Occurred while start FCReceiver[" + + vo.getReceiverName() + "] 사용안함 "); + } + } + } catch (Exception e) { + logger.error("FCQueueReceiverManager] Error Occured while start FCReceiver[" + key + + "] continue start : Error - " + e.getMessage()); + } + } + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICFM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + Iterator it = receiverVos.keySet().iterator(); + String key = ""; + while (it.hasNext()) { + key = it.next(); + try { + stopReceiver(key); + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn("FCQueueReceiverManager] Error Occurred while stop FCReceiver[" + key + + "] continue start : Error - " + e.getMessage()); + } + } + } + receiverVos.clear(); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public FCQueueReceiverVO getFCQueueReceiver(String receiverName) { + if (receiverName == null) + return null; + return receiverVos.get(receiverName); + } + + public void loadFCQueueReceiver(String queRcverName) throws Exception { + FCQueueReceiverVO vo = null; + try { + boolean isScalable = BooleanUtils.toBoolean(System.getProperty("scalable")); + String localServerName =""; + if(isScalable) { + localServerName ="ALL"; + }else { + localServerName = EAIServerManager.getInstance().getLocalServerName(); + } + + vo = fcQueueReceiverDAO.getReceiver(queRcverName); + + if (this.receivers.get(vo.getReceiverName()) != null) { + stopReceiver(vo.getReceiverName()); + } + + if (localServerName.equals(vo.getEaiSevrInstncName())) { + receiverVos.put(vo.getReceiverName(), vo); + if ("1".equals(vo.getBascQueRcverYn())) { + startReceiver(vo.getReceiverName(), vo.getQueueName(), vo.getErrorQueueName(), + vo.getReceiverCount(), vo.getErrorDelayTimeMs(), vo.getRetryCount(), + vo.getMessageSelector(), vo.getDescription()); + } else { + if (logger.isWarn()) { + logger.warn("FCQueueReceiverManager] Error Occurred while start FCReceiver[" + + vo.getReceiverName() + "] 사용안함 "); + } + } + } + + } catch (Exception e) { + String message = ""; + if (vo != null) { + message = "FCQueueReceiverManager] Error Occurred while start FCReceiver[" + vo.getReceiverName() + + "] - " + e.getMessage(); + } else { + message = "FCQueueReceiverManager] Error Occurred while start FCReceiver[" + queRcverName + "] - " + + e.getMessage(); + } + logger.error(message, e); + + throw new Exception(message); + } + } + + public void setFCQueueReceiver(FCQueueReceiverVO vo) throws Exception { + try { + receiverVos.put(vo.getReceiverName(), vo); + + if (this.receivers.get(vo.getReceiverName()) != null) { + stopReceiver(vo.getReceiverName()); + } + + startReceiver(vo.getReceiverName(), vo.getQueueName(), vo.getErrorQueueName(), vo.getReceiverCount(), + vo.getErrorDelayTimeMs(), vo.getRetryCount(), vo.getMessageSelector(), vo.getDescription()); + } catch (Exception e) { + String message = "FCQueueReceiverManager] Error Occurred while start FCReceiver[" + vo.getReceiverName() + + "] - " + e.getMessage(); + logger.error(message, e); + throw new Exception(message); + } + } + + public void removeFCQueueReceiver(String receiverName) throws Exception { + try { + stopReceiver(receiverName); + receiverVos.remove(receiverName); + } catch (Exception e) { + String message = "FCQueueReceiverManager] Error Occurred while stop FCReceiver[" + receiverName + "] - " + + e.getMessage() + "] - " + e.getMessage(); + logger.error(message, e); + throw new Exception(message); + } + } + + public Map getAllFCQueueReceiverVos() { + return this.receiverVos; + } + + // ------------------------------------------------------------------- + // receiver control Method + // ------------------------------------------------------------------- + public void startReceiver(String receiverName, String QueueName, String errorQueueName, int receiverCount, + int deplayMs, int retryCnt, String selector, String descr) throws Exception { + try { + + int type = getMqType(); + + switch (type) { + case MQ_RABBITMQ: + FCRabbitMqReceiver rabbitMqReceiverApp = new FCRabbitMqReceiver(receiverName, QueueName, errorQueueName, + receiverCount, deplayMs, retryCnt, false, // TxMode + 1, // (Session.AUTO_ACKNOWLEDGE) + selector, descr); + + rabbitMqReceiverApp.startReceiving(); + receivers.put(receiverName, rabbitMqReceiverApp); + logger.warn("FCRabbitMqReceiver Start - " + rabbitMqReceiverApp); + break; + case MQ_JMS: + FCQueueReceiver receiverApp = new FCQueueReceiver(receiverName, QueueName, errorQueueName, + receiverCount, deplayMs, retryCnt, false, // TxMode + Session.AUTO_ACKNOWLEDGE, selector, descr); + + receiverApp.startReceiving(); + receivers.put(receiverName, receiverApp); + logger.warn("FCQueueReceiverManager] Start - " + receiverName); + break; + default: + FCActiveMqReceiver activeMqReceiverApp = new FCActiveMqReceiver(receiverName, QueueName, errorQueueName, + receiverCount, deplayMs, retryCnt, false, // TxMode + 1, // (Session.AUTO_ACKNOWLEDGE) + selector, descr); + + activeMqReceiverApp.startReceiving(); + receivers.put(receiverName, activeMqReceiverApp); + logger.warn("FCActiveMqReceiver Start - " + activeMqReceiverApp); + break; + } + } catch (Exception e) { + logger.error("FCQueueReceiverManager] Start Error", e); + throw e; + } + } + + public void startReceiver(String receiverName) throws Exception { + try { + FCQueueReceiverVO vo = fcQueueReceiverDAO.getReceiver(receiverName); + + startReceiver(vo.getReceiverName(), vo.getQueueName(), vo.getErrorQueueName(), vo.getReceiverCount(), + vo.getErrorDelayTimeMs(), vo.getRetryCount(), vo.getMessageSelector(), vo.getDescription()); + logger.warn("FCQueueReceiverManager] Start - " + receiverName); + } catch (Exception e) { + logger.error("FCQueueReceiverManager] Error ", e); + throw e; + } + } + + public void stopReceiver(String receiverName) throws Exception { + try { + Object receiverObj = receivers.get(receiverName); + + if (receiverObj instanceof FCQueueReceiver) { + FCQueueReceiver receiverApp = (FCQueueReceiver) receiverObj; + receiverApp.stopReceiving(); + receiverApp.close(); + receivers.remove(receiverName); + logger.warn("FCQueueReceiverManager] FCQueueReceiver Stopped - " + receiverName); + + } else if (receiverObj instanceof FCActiveMqReceiver) { + FCActiveMqReceiver receiverApp = (FCActiveMqReceiver) receiverObj; + receiverApp.stopReceiving(); + receiverApp.close(); + receivers.remove(receiverName); + logger.warn("FCQueueReceiverManager] Receiver Stopped - " + receiverName); + + } else if (receiverObj instanceof FCRabbitMqReceiver) { + FCRabbitMqReceiver receiverApp = (FCRabbitMqReceiver) receiverObj; + receiverApp.stopReceiving(); + receiverApp.close(); + receivers.remove(receiverName); + logger.warn("FCQueueReceiverManager] FCRabbitMqReceiver Stopped - " + receiverName); + } + } catch (Exception e) { + logger.error("FCQueueReceiverManager] Receiver Stop error", e); + throw e; + } + } + + // 개별 Queue Receiver의 Thread별 건수 조회 + public String[][] getMonitorData(String receiverName) throws Exception { + String[][] status = null; + // 0 : receiver Thread Name + // 1 : 메시지 처리건수 + // 2 : 메시지 성공건수 + // 3 : 현재상태 (0 - wait, 1 - running, 2 - retry) + try { + FCQueueReceiver receiverApp = (FCQueueReceiver) receivers.get(receiverName); + if (receiverApp != null) { + status = receiverApp.getStatus(); + } else { + throw new Exception("Receiver Already Stopped - " + receiverName); + } + + } catch (Exception e) { + logger.error("FCQueueReceiverManager] getMonitorData error", e); + throw e; + } + return status; + } + + // Queue Receiver의 전체 건수 조회 + public String[][] getMonitorData() throws Exception { + String[][] status = new String[receivers.size()][3]; + try { + int i = 0; + for (Map.Entry entry : receivers.entrySet()) { + String receiverName = entry.getKey(); + FCQueueReceiver receiverApp = (FCQueueReceiver) entry.getValue(); + + if (receiverApp != null) { + String[] counter = receiverApp.getMessageCount(); + status[i][0] = receiverName; + status[i][1] = counter[0]; // 메시지 건수 + status[i][2] = counter[1]; // 성공건수 + } else { + status[i][0] = receiverName; + status[i][1] = "0"; + status[i][2] = "0"; + } + i++; + } + } catch (Exception e) { + logger.error("FCQueueReceiverManager] getMonitorData error", e); + throw e; + } + return status; + } + + public void resetCount(String receiverName) throws Exception { + try { + FCQueueReceiver receiverApp = (FCQueueReceiver) receivers.get(receiverName); + if (receiverApp != null) { + receiverApp.clearReceived(); + } else { + throw new Exception("Receiver Already Stopped - " + receiverName); + } + + } catch (Exception e) { + logger.error("FCQueueReceiverManager] resetCount error", e); + throw e; + } + } + + public String[] getAllReceiverNames() { + String[] receiverName = new String[receivers.size()]; + Iterator it = receivers.keySet().iterator(); + for (int i = 0; it.hasNext(); i++) { + receiverName[i] = it.next(); + } + return receiverName; + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverVO.java b/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverVO.java new file mode 100644 index 0000000..8629c4a --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverVO.java @@ -0,0 +1,108 @@ +package com.eactive.eai.flowcontrol.jms; + +import java.io.Serializable; + + +public class FCQueueReceiverVO implements Serializable { + private static final long serialVersionUID = 1L; + + private String receiverName ; // Receiver Name + private String queueName ; // Queue Name + private String errorQueueName ; // Error Queue Name + private int receiverCount ; // Receiver 수 + private int errorDelayTimeMs; // 에러 발생시 delay 타임(ms) + private int retryCount ; // 에러큐에 대한 retry 회수 + private String messageSelector ; // Selector + private String bascQueRcverYn ; // 기본큐수신자여부 ( 1-Default, 0 - Not) + private String description ; // 설명 + + private String eaiSevrInstncName; // 서버인스탄스명 + + public String getEaiSevrInstncName() { + return eaiSevrInstncName; + } + + public void setEaiSevrInstncName(String eaiSevrInstncName) { + this.eaiSevrInstncName = eaiSevrInstncName; + } + + public FCQueueReceiverVO() { + receiverCount = 1; + errorDelayTimeMs = 0; + retryCount = 0; + messageSelector = ""; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getMessageSelector() { + return messageSelector; + } + + public void setMessageSelector(String messageSelector) { + this.messageSelector = messageSelector; + } + + public String getQueueName() { + return queueName; + } + + public void setQueueName(String queueName) { + this.queueName = queueName; + } + + public int getReceiverCount() { + return receiverCount; + } + + public void setReceiverCount(int receiverCount) { + this.receiverCount = receiverCount; + } + + public String getReceiverName() { + return receiverName; + } + + public void setReceiverName(String receiverName) { + this.receiverName = receiverName; + } + + public int getErrorDelayTimeMs() { + return errorDelayTimeMs; + } + + public void setErrorDelayTimeMs(int errorDelayTimeMs) { + this.errorDelayTimeMs = errorDelayTimeMs; + } + + public String getErrorQueueName() { + return errorQueueName; + } + + public void setErrorQueueName(String errorQueueName) { + this.errorQueueName = errorQueueName; + } + + public int getRetryCount() { + return retryCount; + } + + public void setRetryCount(int retryCount) { + this.retryCount = retryCount; + } + + public String getBascQueRcverYn() { + return bascQueRcverYn; + } + + public void setBascQueRcverYn(String bascQueRcverYn) { + this.bascQueRcverYn = bascQueRcverYn; + } + +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/FCRabbitMqReceiver.java b/src/main/java/com/eactive/eai/flowcontrol/jms/FCRabbitMqReceiver.java new file mode 100644 index 0000000..89d52e4 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/FCRabbitMqReceiver.java @@ -0,0 +1,605 @@ +package com.eactive.eai.flowcontrol.jms; + +import java.util.HashMap; +import java.util.Properties; + +import org.apache.commons.lang.SerializationUtils; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.logger.EAILogSender; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.ElinkESBProcessProxy; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.routing.RoutingManager; +import com.eactive.eai.common.routing.RoutingVO; +import com.eactive.eai.common.util.JMSSender; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.ext.eai.common.stdmessage.STDMessageKeys; +import com.rabbitmq.client.Channel; +import com.rabbitmq.client.Connection; +import com.rabbitmq.client.ConnectionFactory; +import com.rabbitmq.client.GetResponse; + +public class FCRabbitMqReceiver { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private String receiverName; + private String queueName; + private String errorQueueName; + private int receiverCount; + private int errorDelayTimeMs; + private int retryCount; + private String messageSelector = ""; + private String description; + + // ------------------------------------ + // Used for Test + // ------------------------------------ + public static final boolean isSingleApplication = false; + + // ------------------------------------ + // Objects needed for RabbitMQ clients + // ------------------------------------ + private ConnectionFactory factory; + private Connection[] connection; + private Channel[] channel; + private ReceiverObject[] receiverObj = null; + +// private boolean isTx = false; +// private static final DecimalFormat dFormat = new DecimalFormat("#0.0"); + + // ------------------------------------ + // Thread Runtime Info + // ------------------------------------ + private Thread[] receiverThread = null; + private boolean[] threadDowned = null; + public boolean allThreadDowned = true; + +// private static String instid = "11"; + static { +// String serverName = System.getProperty(Keys.WLI_SERVER_KEY); +// if(serverName != null && serverName.length() > 2) { +// instid = serverName.substring(serverName.length()-2, serverName.length()); +// } + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("[ FCRabbitMqReceiver INFO ]"); + sb.append("\nReveciver Name = " + this.receiverName); + sb.append(", Queue Name = " + this.queueName); + sb.append(", Error Queue Name = " + this.errorQueueName); + sb.append(", Recever Count = " + this.receiverCount); + sb.append(", Delay Time(ms) = " + this.errorDelayTimeMs); + sb.append(", Retry Count = " + this.retryCount); + sb.append(", Selector = " + this.messageSelector); + sb.append(", Description = " + this.description); + + return sb.toString(); + } + + public FCRabbitMqReceiver(String rcvName, String qname, String errorqname, int rcvCount, int delayMs, int retryCnt, + boolean isTx, int ackMode, String msgSelector, String descr) throws Exception { + + queueName = qname; + errorQueueName = errorqname; + receiverName = rcvName; + receiverCount = rcvCount; + errorDelayTimeMs = delayMs; + retryCount = retryCnt; + messageSelector = msgSelector; + description = descr; + + // trim space + if (queueName != null) + queueName = queueName.trim(); + if (errorQueueName != null) + errorQueueName = errorQueueName.trim(); + if (receiverName != null) + receiverName = receiverName.trim(); + if (messageSelector != null) + messageSelector = messageSelector.trim(); + + threadDowned = new boolean[receiverCount]; + connection = new Connection[receiverCount]; + channel = new Channel[receiverCount]; + receiverObj = new ReceiverObject[receiverCount]; + receiverThread = new Thread[receiverCount]; + + String clientId = receiverName; + + String connectionUrl = ""; + try { + if (isSingleApplication) { + if (logger.isDebug()) + logger.debug("Local Application Test"); + connectionUrl = "amqp://guest:guest@localhost:5672"; + } else { + PropManager propManager = PropManager.getInstance(); + connectionUrl = propManager.getProperty(RouteKeys.GROUP_NAME, + RouteKeys.ROUTING_QUEUE_CONNECTION_FACTORY); + + } + } catch (Exception e) { + if (logger.isError()) + logger.error("FCQueueReceiver: get InitialContext Error : ", e); + throw e; + } + + if (logger.isInfo()) + logger.info("RabbitMQ Connection : " + connectionUrl); + + try { + // Create the connections + for (int i = 0; i < receiverCount; i++) { + factory = new ConnectionFactory(); + factory.setUri(connectionUrl); + // create each connection + connection[i] = factory.newConnection(); + + // clientId = receiverName + instid + "-" + i; +// clientId = receiverName + "-" + i; + + channel[i] = connection[i].createChannel(); + channel[i].queueDeclare(queueName, false, false, false, null); + + receiverObj[i] = new ReceiverObject(rcvName, i, channel[i], queueName, this.messageSelector, + this.errorQueueName, this.errorDelayTimeMs, this.retryCount, connectionUrl); + receiverObj[i].setName(clientId); + if (logger.isDebug()) + logger.debug("[" + new java.util.Date() + "] Receiver Thread : [" + clientId + "] " + queueName); + receiverThread[i] = new Thread(receiverObj[i]); + receiverThread[i].setDaemon(true);// avoids thread leaks if + } + } catch (Exception e) { + if (logger.isError()) + logger.error(" Exception while in constructor : ", e); + close(); + throw e; + } + + } + + public synchronized void startReceiving() throws Exception { + + if (!allThreadDowned) { + throw new Exception("Thread Started Already !"); + } + + try { + allThreadDowned = false; + } catch (Exception jmse) { + if (logger.isError()) { + logger.error("FCQueueReceiver: JMSException while in startReceiving() method : ", jmse); + } + close(); + throw jmse; + } + + } + + public synchronized void clearReceived() { + // Clear Counter + for (int i = 0; i < receiverObj.length; i++) { + receiverObj[i].clearCount(); + } + } + + public synchronized void stopReceiving() { + // Cleanup each ReceiverObj (stops sending + for (int i = 0; i < receiverObj.length; i++) { + // stops each ReceiverObject + if (receiverObj[i] != null) + receiverObj[i].stopReceiver(); + receiverObj[i].stopThread(); + } + } + + public String[][] getStatus() { + String[][] receiveStatus = new String[receiverObj.length][4]; + for (int i = 0; i < receiverObj.length; i++) { + if (receiverObj[i] != null) { + receiveStatus[i][0] = receiverObj[i].getName(); + receiveStatus[i][1] = "" + receiverObj[i].msgCounter; + receiveStatus[i][2] = "" + receiverObj[i].msgSuccessCounter; + receiveStatus[i][3] = "" + receiverObj[i].receiverStatus; + } + } + return receiveStatus; + } + + public String[] getMessageCount() { + String[] receiveStatus = new String[2]; + int receivedTotal = 0; + int successTotal = 0; + + for (int i = 0; i < receiverObj.length; i++) { + if (receiverObj[i] != null) { + receivedTotal += receiverObj[i].msgCounter; + successTotal += receiverObj[i].msgSuccessCounter; + } + } + receiveStatus[0] = "" + receivedTotal; + receiveStatus[1] = "" + successTotal; + + return receiveStatus; + } + + /** + * Closes all connections which in turn stops the receivers and exits JVM + */ + public void close() { + for (int k = 0; k < channel.length; k++) { + try { + if (channel[k] != null) { + channel[k].close(); + } + } catch (Exception ex) { + if (logger.isError()) { + logger.error("Exceptionchannel " + k + " message is " + ex.getMessage()); + } + } + } + + // Close all the connections before exiting the application + for (int i = 0; i < connection.length; i++) { + try { + if (connection[i] != null) + connection[i].close(); + } catch (Exception ex) { + if (logger.isError()) { + logger.error("In exit(): Caught Exception trying to close connection(s)", ex); + } + } + } + } + + // //////////////////////////////////////////////////////////////////////// + /** + * Inner class: ReceiverObject is an ASYNCHRONOUS receiver. + */ + // //////////////////////////////////////////////////////////////////////// + private class ReceiverObject extends Thread { + private String recvName = null; + + private String queueName = null; + // Channel + private Channel channel = null; + + private int id; // identifies the ReceiverObject + + private int msgCounter = 0; // keeps track of messages + + private int msgSuccessCounter = 0; + + private int receiverStatus = 0; // 0 - wait, 1 - running, 2 - retry + + private Object lockCounter = new Object();// used to synchronize + // updates of the message + // counter + + private boolean keepRunning = false; // used to exit the sending loop + // in the run method + + private String messageSelector = ""; + + private String errorQueueName = ""; + + private int errorDelayTimeMs = 0; + + private int retryCount = 0; + + private String queueConFactory = ""; + + /** + * Construct a ReceiverObject param id - the id number should be unique for each + * ReceiverObject param sess - the session object under which the receiver is + * created param q - the Queue object to receiver from + */ + public ReceiverObject(String recvName, int id, Channel channel, String queueName, String messageSelector, + String errorQueueName, int errorDelayMs, int retryCnt, String connectionUri) throws Exception { + init(recvName, id, channel, queueName, messageSelector, errorQueueName, errorDelayMs, retryCnt, + connectionUri); + } + + public void init(String recvName, int sid, Channel channel, String queueName, String selector, + String errQueueName, int deplayMs, int retryCnt, String qConFactory) throws Exception { + this.recvName = recvName; + this.id = sid; + this.channel = channel; + this.queueName = queueName; + this.messageSelector = selector; + this.errorQueueName = errQueueName; + this.errorDelayTimeMs = deplayMs; + this.retryCount = retryCnt; + this.queueConFactory = qConFactory; + + try { + logger.info("recvName=" + this.recvName + ",messageSelector=" + this.messageSelector); + } catch (Exception jmse) { + if (logger.isError()) + logger.error(this.getName() + + "] In ReceiverObject constructor: JMSException while setting up receiverObj[" + id + "]", + jmse); + close(); + throw jmse; + } + } + + /** + * Get number of message received since last get + * + * return totaSinceLastGet total number of messages received since the last get + */ + public int getMsgCount() { + synchronized (lockCounter) { + return msgCounter; + } + } + + public void setMsgCount(int msgCounter) { + synchronized (lockCounter) { + this.msgCounter = msgCounter; + } + } + + public void clearCount() { + synchronized (lockCounter) { + if (logger.isError()) { + logger.error(this.getName() + "] Clearing id: [" + id + "] clearing: " + msgCounter); + } + // reset counter + msgCounter = 0; + msgSuccessCounter = 0; + } + } + + public void stopReceiver() { + // stop Receiver from sending which causes thread to exit run() method + // and thus finish. + keepRunning = false; + } + + public void stopThread() { + // super.stop(); + } + + @Override + public void run() { + if (Thread.currentThread().getName().startsWith("Thread-")) { + Thread.currentThread().setName(queueName + "-" + Thread.currentThread().getName()); + } + keepRunning = true; + threadDowned[id] = false; + EAIMessage eaiMessage = null; + + while (keepRunning) { + try { + receiverStatus = 0; + + GetResponse response = channel.basicGet(queueName, false); + + if (response == null) { + Thread.sleep(500); + continue; + } + + synchronized (lockCounter) { + receiverStatus = 1; + msgCounter++; + } + + byte[] body = response.getBody(); + + try { + eaiMessage = (EAIMessage) SerializationUtils.deserialize(body); + } catch (Exception e) { + throw new RuntimeException(this.getName() + "] EAI메시지가 아닙니다. - " + e.getMessage()); + } + +// String guidLogPrefix = "RabbitMQ Receiver] GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + String guidLogPrefix = "RabbitMQ Receiver] GUID[" + + eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) + "] UUID[" + + eaiMessage.getSvcOgNo() + "] "; + + if (logger.isDebug()) { + logger.debug(this.getName() + "] receiverObj[" + id + "] Executed - " + eaiMessage.getEAISvcCd() + + ":" + eaiMessage.getSvcOgNo()); + } + + RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm()); + String serviceURI = routingVO.getSyncRoutingPath(); + boolean isLocal = true; + + HashMap headers = (HashMap) response.getProps().getHeaders(); + + Properties prop = new Properties(); + try { + if (headers != null) { + for (String key : headers.keySet()) { + String propName = key; + String propValue = (String) headers.get(propName); + prop.setProperty(propName, propValue); + } + } + } catch (Exception e) { + throw new RuntimeException(this.getName() + "] 프라퍼티 설정에러 - " + e.getMessage()); + } + + EAIMessage resEAIMessage = null; + + channel.basicAck(response.getEnvelope().getDeliveryTag(), false); + + try { + // EAI 거래처리 Error 이고 retry count가 있으면 회수만큼 재시도 + // errorDelayTimeMs > 0 면 sleep + int retry = 1; + // retry count 만큼 반복한다. + // -1 : 무한대 retry + // 0 : 처리되지 않는다. + + if (this.retryCount == 0) { + if (logger.isWarn()) { + logger.warn(this.getName() + "] SKIP Execute EAISvcCd (" + eaiMessage.getEAISvcCd() + + ") Retry Count - " + this.retryCount); + } + continue; // 처리를 중단한다. + } else if (this.retryCount > 1) { + receiverStatus = 2; + } + + while (((retry <= this.retryCount) || (this.retryCount == -1)) && keepRunning) { + resEAIMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, + prop); + + if (resEAIMessage == null) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + + "] response EAIMessage is NULL. SKIP Retry Count - " + this.retryCount); + } + break; + } + + if (MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) { + break; + } else { + if ((this.retryCount > 0) && (retry <= this.retryCount)) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Call Error(" + + resEAIMessage.getRspErrCd() + ") Retry - " + retry + "/" + + this.retryCount); + } + // 다음 처리전에 delay를 준다. + if (this.errorDelayTimeMs > 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Delay Before Retry - " + + this.errorDelayTimeMs); + } + try { + Thread.sleep(this.errorDelayTimeMs); + } catch (Exception e) { + } + } + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] FlowControl Call Error(" + + resEAIMessage.getRspErrCd() + ") No Retry"); + } + } + } + retry++; + + } // while(retry <= this.retryCount) + + } catch (Exception e) { + if (resEAIMessage != null && logger.isError()) { + logger.error(guidLogPrefix + this.getName() + "] FlowControl Call Error(" + + resEAIMessage.getRspErrCd() + ") " + e.getMessage(), e); + } + } + + if (response != null) { + // increment message counter + synchronized (lockCounter) { + msgSuccessCounter++; + } + response = null; + } + + if (resEAIMessage != null) { + // EAI 거래처리 Error 면 + // errorQueueName 이 있으면 redirect + // errorDelayTimeMs > 0 면 sleep + if (!MessageUtil.checkRspErrCd(resEAIMessage.getRspErrCd())) { + if (this.errorQueueName != null && this.errorQueueName.length() > 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Redirect Messsage to - " + + this.errorQueueName); + } + JMSSender.sendToQueue(eaiMessage, queueConFactory, this.errorQueueName, prop); + } + } + } + // 다음 처리 전에 delay를 준다. + if (this.errorDelayTimeMs > 0) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + this.getName() + "] Delay Before Receive Next Message - " + + this.errorDelayTimeMs); + } + try { + Thread.sleep(this.errorDelayTimeMs); + } catch (Exception e) { + } + } + + } catch (Exception ex) { + if (logger.isError()) { + logger.error(this.getName() + "] JMSException for receiverObj[" + id + "] - " + ex.getMessage(), + ex); + } + + if (eaiMessage != null) { + // -------------------------------------------- + // Set Error + String[] msgArgs = new String[1]; + msgArgs[0] = eaiMessage.getEAISvcCd(); + String rspErrorCode = "RECEAIFQR001"; // [EAI 서비스코드:{1}] 큐수신자가 플로우컨트롤 호출 중 오류 발생 + String rspErrorMsg = ExceptionUtil.make(ex, rspErrorCode, msgArgs); +// eaiMessage.setRspErrCd(rspErrorCode); +// eaiMessage.setRspErrMsg(rspErrorMsg); + eaiMessage.setRspErr(rspErrorCode,rspErrorMsg); + // -------------------------------------------- +// String mesgDmanDvcd = eaiMessage.getKbMsg().getKBHeader().getTelgmDmndDstcd(); +// String mesgDmanDvcd = eaiMessage.getExtMsg().getSendRecv(); + String mesgDmanDvcd = eaiMessage.getMapper() + .getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(mesgDmanDvcd)) { + // 응답인 경우 + eaiMessage.setLogPssSno(400); + } else { + // 요청 인경우 + eaiMessage.setLogPssSno(200); + } + + try { + EAILogSender.send(eaiMessage, null); + } catch (Exception e) { + if (logger.isError()) + logger.error(this.getName() + "] ErrorLogging :" + e.getMessage()); + } + } + // auto reconnect so wait 10 seconds + try { + Thread.sleep(10000); + } catch (Exception e) { + // Do nothing + } + } + } // end of while + + // if Stop Event Occurred + if (!keepRunning) { + threadDowned[id] = true; + synchronized (this) { + boolean tmpDowned = false; + for (int j = 0; j < threadDowned.length; j++) { + if (threadDowned[j]) { + tmpDowned = true; + } else { + tmpDowned = false; + break; + } + } + + if (tmpDowned) { + allThreadDowned = true; + } + } + } + + } // end of run + + }// end of inner class ReceiverObject +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/QueueMonitorDAO.java b/src/main/java/com/eactive/eai/flowcontrol/jms/QueueMonitorDAO.java new file mode 100644 index 0000000..cb3a7e0 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/QueueMonitorDAO.java @@ -0,0 +1,59 @@ +package com.eactive.eai.flowcontrol.jms; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.BooleanUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.flowcontrol.jms.QueueMonitor; +import com.eactive.eai.flowcontrol.jms.loader.QueueMonitorLoader; +import com.eactive.eai.flowcontrol.jms.mapper.QueueMonitorMapper; + +@Service +@Transactional +public class QueueMonitorDAO extends BaseDAO { + + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + QueueMonitorLoader queueMonitorLoader; + + @Autowired + QueueMonitorMapper queueMonitorMapper; + + public Map getAllQueue() throws DAOException { + boolean isScalable = BooleanUtils.toBoolean(System.getProperty("scalable")); + String serverName =""; + if(isScalable) { + serverName ="ALL"; + }else { + serverName = EAIServerManager.getInstance().getLocalServerName(); + } + try { + Map queueMonitorMap = new HashMap<>(); + logger.info("[ @@ Load QueueMonitor Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + List queueMonitors = queueMonitorLoader + .findByIdEaisevrinstncname(serverName); + + for (QueueMonitor queueMonitor : queueMonitors) { + QueueMonitorVO queueMonitorVO = queueMonitorMapper.toVo(queueMonitor); + queueMonitorMap.put(queueMonitorVO.getQueueName() + queueMonitorVO.getSevrInstncName(), queueMonitorVO); + logger.info("@ " + queueMonitorVO.toString()); + } + logger.info("[>>Load QueueMonitor getInflowMap Configuration - ended ]"); + return queueMonitorMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICCM101")); + } + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/QueueMonitorManager.java b/src/main/java/com/eactive/eai/flowcontrol/jms/QueueMonitorManager.java new file mode 100644 index 0000000..9d3c530 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/QueueMonitorManager.java @@ -0,0 +1,127 @@ +package com.eactive.eai.flowcontrol.jms; + +import java.util.HashMap; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +@Component +public class QueueMonitorManager implements Lifecycle { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private Map queueVos = new HashMap<>(); + + @Autowired + QueueMonitorDAO queueMonitorDAO; + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private boolean started; + + public static QueueMonitorManager getInstance() { + return ApplicationContextProvider.getContext().getBean(QueueMonitorManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICFM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + queueVos = queueMonitorDAO.getAllQueue(); + } catch (DAOException e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICFM202")); + } + started = true; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + // Validate and update our current component state + if (!started) + throw new LifecycleException("RECEAICFM203"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + queueVos.clear(); + started = false; + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public QueueMonitorVO getQueueMonitor(String qName) { + if (qName == null) + return null; + return queueVos.get(qName); + } + + public void setQueueMonitor(QueueMonitorVO vo) throws Exception { + try { + QueueMonitorVO queueVo = queueVos.get(vo.getQueueName()); + if (queueVo == null) { + queueVos.put(vo.getQueueName(), vo); + } else { + queueVo.setMaxCount(vo.getMaxCount()); + + queueVo.setQueBzwkCtnt(vo.getQueBzwkCtnt()); + queueVo.setQueUseYn(vo.getQueUseYn()); + queueVo.setQueUsagDstcd(vo.getQueUsagDstcd()); + queueVo.setBzwkDstcd(vo.getBzwkDstcd()); + queueVo.setQueBzwkDtalsCtnt(vo.getQueBzwkDtalsCtnt()); + queueVo.setSevrInstncName(vo.getSevrInstncName()); + queueVos.put(queueVo.getQueueName(), queueVo); + + } + } catch (Exception e) { + String message = "QueueMonitorManager] Error Occurred while setQueueMonitor[" + vo.getQueueName() + "] - " + + e.getMessage(); + logger.error(message, e); + throw new Exception(message); + } + } + + public void removeQueueMonitor(String qName) throws Exception { + try { + queueVos.remove(qName); + } catch (Exception e) { + String message = "QueueMonitorManager] Error Occurred while remove[" + qName + "] - " + e.getMessage() + + "] - " + e.getMessage(); + logger.error(message, e); + throw new Exception(message); + } + } + + public Map getAllQueueMonitorVos() { + return this.queueVos; + } + +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/QueueMonitorVO.java b/src/main/java/com/eactive/eai/flowcontrol/jms/QueueMonitorVO.java new file mode 100644 index 0000000..447af8c --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/QueueMonitorVO.java @@ -0,0 +1,144 @@ +package com.eactive.eai.flowcontrol.jms; + +import java.io.Serializable; + +public class QueueMonitorVO implements Serializable { + + private static final long serialVersionUID = 1L; + + private String queueName; // Queue Name + + private long currentCount; // 모니터링 현재값 + private long previousCount; // 모니터링 이전값 + private long maxCount; // EAI큐임계치값 + + private String queBzwkCtnt; // EAI큐업무내용 + private String queUseYn; // 큐사용여부 + private String queUsagDstcd; // 큐용도구분코드 + private String bzwkDstcd; // EAI업무구분코드 + private String queBzwkDtalsCtnt; // EAI큐업무세부내용 + private String sevrInstncName; // EAI서버인스턴스명 + + public QueueMonitorVO(String qName, long max) { + queueName = qName; + currentCount = 0; + previousCount = 0; + maxCount = max; + } + + public long getCurrentCount() { + return currentCount; + } + + public void setCurrentCount(long currentCount) { + this.previousCount = this.currentCount; + this.currentCount = currentCount; + } + + public long getMaxCount() { + return maxCount; + } + + public void setMaxCount(long maxCount) { + this.maxCount = maxCount; + } + + public long getPreviousCount() { + return previousCount; + } + + public void setPreviousCount(long previousCount) { + this.previousCount = previousCount; + } + + public String getQueueName() { + return queueName; + } + + public void setQueueName(String queueName) { + this.queueName = queueName; + } + + public int checkCount() { + int status = 0; // 정상상태 + + // 이상 Alert + if ((previousCount < maxCount) && (currentCount >= maxCount)) { + status = 1; + } + // 이상상태 계속 + else if ((previousCount >= maxCount) && (currentCount >= maxCount)) { + status = 2; + } + // 이상상태 복구 Alert + else if ((previousCount >= maxCount) && (currentCount < maxCount)) { + status = 3; + } + + return status; + } + + public String getBzwkDstcd() { + return bzwkDstcd; + } + + public void setBzwkDstcd(String bzwkDstcd) { + this.bzwkDstcd = bzwkDstcd; + } + + public String getQueBzwkCtnt() { + return queBzwkCtnt; + } + + public void setQueBzwkCtnt(String queBzwkCtnt) { + this.queBzwkCtnt = queBzwkCtnt; + } + + public String getQueBzwkDtalsCtnt() { + return queBzwkDtalsCtnt; + } + + public void setQueBzwkDtalsCtnt(String queBzwkDtalsCtnt) { + this.queBzwkDtalsCtnt = queBzwkDtalsCtnt; + } + + public String getQueUsagDstcd() { + return queUsagDstcd; + } + + public void setQueUsagDstcd(String queUsagDstcd) { + this.queUsagDstcd = queUsagDstcd; + } + + public String getQueUseYn() { + return queUseYn; + } + + public void setQueUseYn(String queUseYn) { + this.queUseYn = queUseYn; + } + + public String getSevrInstncName() { + return sevrInstncName; + } + + public void setSevrInstncName(String sevrInstncName) { + this.sevrInstncName = sevrInstncName; + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("queueName=").append(queueName).append(","); + sb.append("currentCount=").append(currentCount).append(","); + sb.append("previousCount=").append(previousCount).append(","); + sb.append("maxCount=").append(maxCount).append(","); + sb.append("queBzwkCtnt=").append(queBzwkCtnt).append(","); + sb.append("queUseYn=").append(queUseYn).append(","); + sb.append("queUsagDstcd=").append(queUsagDstcd).append(","); + sb.append("bzwkDstcd=").append(bzwkDstcd).append(","); + sb.append("queBzwkDtalsCtnt=").append(queBzwkDtalsCtnt).append(","); + sb.append("sevrInstncName=").append(sevrInstncName); + return sb.toString(); + } + +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/mapper/FCQueueReceiverMapper.java b/src/main/java/com/eactive/eai/flowcontrol/jms/mapper/FCQueueReceiverMapper.java new file mode 100644 index 0000000..8c5f422 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/mapper/FCQueueReceiverMapper.java @@ -0,0 +1,29 @@ +package com.eactive.eai.flowcontrol.jms.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import com.eactive.eai.data.entity.onl.flowcontrol.jms.FCQueueReceiver; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; +import com.eactive.eai.flowcontrol.jms.FCQueueReceiverVO; + +@Mapper(config = BaseMapperConfig.class) +public interface FCQueueReceiverMapper extends GenericMapper { + @Mapping(source = "quercvername", target = "receiverName") + @Mapping(source = "bascquercveryn", target = "bascQueRcverYn") + @Mapping(source = "eaisevrinstncname", target = "eaiSevrInstncName") + @Mapping(source = "nonsyncztranobstclquename", target = "errorQueueName") + @Mapping(source = "nonsyncztranquename", target = "queueName") + @Mapping(source = "quemsgselctctnt", target = "messageSelector") + @Mapping(source = "quercvercnt", target = "receiverCount") + @Mapping(source = "quercverdtalsctnt", target = "description") + @Mapping(source = "senddlayttmval", target = "errorDelayTimeMs") + @Mapping(source = "sendretralnotms", target = "retryCount") + @Override + FCQueueReceiverVO toVo(FCQueueReceiver entity); + + @InheritInverseConfiguration + FCQueueReceiver toEntity(FCQueueReceiverVO vo); +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/jms/mapper/QueueMonitorMapper.java b/src/main/java/com/eactive/eai/flowcontrol/jms/mapper/QueueMonitorMapper.java new file mode 100644 index 0000000..cb09ac5 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/jms/mapper/QueueMonitorMapper.java @@ -0,0 +1,27 @@ +package com.eactive.eai.flowcontrol.jms.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +import com.eactive.eai.data.entity.onl.flowcontrol.jms.QueueMonitor; +import com.eactive.eai.data.mapper.BaseMapperConfig; +import com.eactive.eai.data.mapper.GenericMapper; +import com.eactive.eai.flowcontrol.jms.QueueMonitorVO; + +@Mapper(config = BaseMapperConfig.class) +public interface QueueMonitorMapper extends GenericMapper { + @Mapping(source = "id.nonsyncztranquename", target = "queueName") + @Mapping(source = "id.eaisevrinstncname", target = "sevrInstncName") + @Mapping(source = "eaibzwkdstcd", target = "bzwkDstcd") + @Mapping(source = "eaiquebzwkctnt", target = "queBzwkCtnt") + @Mapping(source = "eaiquebzwkdtalsctnt", target = "queBzwkDtalsCtnt") + @Mapping(source = "eaiquecrtcnmvlval", target = "maxCount") + @Mapping(source = "queusagdstcd", target = "queUsagDstcd") + @Mapping(source = "queuseyn", target = "queUseYn") + @Override + QueueMonitorVO toVo(QueueMonitor entity); + + @InheritInverseConfiguration + QueueMonitor toEntity(QueueMonitorVO vo); +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/websphere/DefaultQueueConsumer.java b/src/main/java/com/eactive/eai/flowcontrol/websphere/DefaultQueueConsumer.java new file mode 100644 index 0000000..07cf697 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/websphere/DefaultQueueConsumer.java @@ -0,0 +1,131 @@ +package com.eactive.eai.flowcontrol.websphere; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.routing.ElinkESBProcessProxy; +import com.eactive.eai.common.routing.RoutingManager; +import com.eactive.eai.common.routing.RoutingVO; +import com.eactive.eai.common.util.Logger; + +import javax.jms.*; +import java.util.Enumeration; +import java.util.Properties; +import java.lang.IllegalStateException; + +public class DefaultQueueConsumer implements Runnable, ExceptionListener { + + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + Connection connection = null; + Session session = null; + MessageConsumer consumer = null; + String name = null; + String queue = null; + boolean run = true; + + public DefaultQueueConsumer(String name, Connection con, String queue) { + this.connection = con; + try { + this.name = name; + this.queue = queue; + connection.start(); + connection.setExceptionListener(this); + + // Create a Session + session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + + // Create the destination (Topic or Queue) + Destination destination = session.createQueue(queue); + consumer = session.createConsumer(destination); + } catch (JMSException e) { + logger.error(e); + } + } + + @Override + public void run() { + EAIMessage eaiMessage = null; + while(run) { + try { + Message message = consumer.receive(2000); + + ObjectMessage omsg = null; + + if(message == null) { +// logger.warn(name + " -> EMPTY MESSAGE..."); + continue; + } + + if(message instanceof ObjectMessage) { + omsg = (ObjectMessage)message; + } else { + throw new RuntimeException(name+" Invlid JMS Message Type. - "+message); + } + + try { + eaiMessage = (EAIMessage)omsg.getObject(); + } catch(Exception e) { + throw new RuntimeException(name+" Invlid value object in ObjectMessage. - "+e.getMessage() ); + } + +// String guidLogPrefix = "GUID["+eaiMessage.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+eaiMessage.getSvcOgNo()+"] "; + String guidLogPrefix = "GUID["+ eaiMessage.getMapper().getGuid(eaiMessage.getStandardMessage()) +"] UUID["+eaiMessage.getSvcOgNo()+"] "; + + RoutingVO routingVO = RoutingManager.getInstance().getRoutingVO(eaiMessage.getFlwCntlRtnNm()); + String serviceURI = routingVO.getSyncRoutingPath(); + boolean isLocal = true; + + Properties prop = new Properties(); + try { + Enumeration en = omsg.getPropertyNames(); + for (; en.hasMoreElements(); ) { + String propName = (String)en.nextElement(); + String propValue = omsg.getStringProperty(propName); + prop.setProperty(propName, propValue); + } + } catch(JMSException e) { + throw new RuntimeException(name+" onMessage Error. - "+e.getMessage()); + } + + try { + if(logger.isInfo()) logger.info("Websphere JMS Receiver : " + guidLogPrefix + eaiMessage); + eaiMessage = ElinkESBProcessProxy.callElinkESBProcess(serviceURI, eaiMessage, isLocal, prop); + } catch(Exception e) { + throw new RuntimeException("Websphere JMS Receiver : " + guidLogPrefix +name+" onMessage Error. - "+e.getMessage()); + } + } + catch(IllegalStateException ise) { + logger.error(name+" IllegalStateException = " + ise.getMessage(), ise); + + } + catch(JMSException e) { + logger.error(name+" JMSException = " + e.getMessage(), e); + run = false; + } + catch(RuntimeException e) { + logger.error(name+" RuntimeException = " + e.getMessage(), e); + } + } + } + + public void stop() { + run = false; + if(consumer != null) + try { + consumer.close(); + } catch (JMSException e) { } + if(session != null) + try { + session.close(); + } catch (JMSException e) { } + if(connection != null) + try { + connection.close(); + } catch (JMSException e) { } + } + + @Override + public void onException(JMSException arg0) { + logger.error("JMS Exception occured. Shutting down client."); + stop(); + } +} diff --git a/src/main/java/com/eactive/eai/flowcontrol/websphere/QueueConsumerService.java b/src/main/java/com/eactive/eai/flowcontrol/websphere/QueueConsumerService.java new file mode 100644 index 0000000..57d4d46 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontrol/websphere/QueueConsumerService.java @@ -0,0 +1,121 @@ +package com.eactive.eai.flowcontrol.websphere; + +import com.eactive.eai.common.util.Logger; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.beans.factory.InitializingBean; + +import javax.jms.Connection; +import javax.jms.QueueConnectionFactory; +import javax.jms.Session; +import javax.naming.InitialContext; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class QueueConsumerService implements InitializingBean, DisposableBean { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private String uri; + private String queue; + private int maxThread; + + Connection connection = null; + Session[] sessions = null; + DefaultQueueConsumer[] consumers = null; + + public final static String JNDI_FACTORY = "com.ibm.websphere.naming.WsninittialContextFactory"; + + ExecutorService es = null; + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public String getQueue() { + return queue; + } + + public void setQueue(String queue) { + this.queue = queue; + } + + public int getMaxThread() { + return maxThread; + } + + public void setMaxThread(int maxThread) { + this.maxThread = maxThread; + } + + @Override + public void afterPropertiesSet() throws Exception { + startConsumer(); + } + + @Override + public void destroy() throws Exception { + stopConsumer(); + } + + public void startConsumer() { + try { + InitialContext ctx = new InitialContext(); + QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx.lookup(uri); + + es = Executors.newFixedThreadPool(maxThread); + + connection = connectionFactory.createConnection(); + connection.start(); + + consumers = new DefaultQueueConsumer[maxThread]; + + for(int i=0; i= 1) { + try { + long msgSndTm = System.currentTimeMillis(); + + Long threadData = (Long) local.get(); + long processTm = msgSndTm - threadData.longValue(); + if (esbLogger.isInfo()) + esbLogger.info( + guidLogPrefix + " End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("clientReturn", e); + } + } + return resEaiMsg; + } + + public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) { + this.reqEaiMsg = reqEaiMsg; + this.callProp = callProp; + + if (this.reqEaiMsg == null) + return; + + svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); + guidLogPrefix = "B2BFCProcess] GUID[" + getGuid(reqEaiMsg) + "] UUID[" + this.reqEaiMsg.getSvcOgNo() + "] "; + + if (svrLogLevel >= 1) { + try { + long msgRcvTm = System.currentTimeMillis(); + local.set(new Long(msgRcvTm)); + if (esbLogger.isInfo()) { + esbLogger.info(guidLogPrefix + " started... - EAI Server Log Level is INFO"); + } + } catch (Exception e) { + logger.warn("callService", e); + } + } + + try { + flow(); + } catch (Exception e) { + printExceptionMessage(e); + if (isSourceAsync()) { + logSenderCtrlSend(); + callExceptionHandler(); + } + } + } + + public void flow() throws Exception { + if (!isRealCall()) { + return; + } + init(); + // B2BOutboud Mapping + setRoute(); + setAdptrInstiCode(); + ifRouterProcess(); + setGUID(); + + // ASYNC-SYNC + if (checkServiceMsgSize()) { + setCurrentService(); + ifRouterProcessResponse(); + } + } + + public void ifRouterProcess() throws Exception { + try { + EAIMessage reqMsg = (EAIMessage) ObjectUtil.deepCopy(this.reqEaiMsg); + this.resEaiMsg = IFRouter.process(reqMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + // ---------------------------------------------------- + // 기동시스템이 Async 거래의 OUtbound에서 오류가 발생할 경우 + // ExceptionHandler를 통해 응답메시지를 전송한다. + // --------------------------------------------------- + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + try { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.resEaiMsg.getStandardMessage().setBizData(bizData, inboundCharset); + ExceptionHandler.handle(this.resEaiMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " ExceptionHandler Call Error :" + e.getMessage()); + } + } + } + } + + public void ifRouterProcessResponse() throws Exception { + try { + String returnServiceId = this.resEaiMsg.getMapper().getReturnServiceId(this.resEaiMsg.getStandardMessage()); + this.resEaiMsg.getMapper().setServiceId(this.resEaiMsg.getStandardMessage(), returnServiceId); + this.resEaiMsg = IFRouter.process(this.resEaiMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR100"; + String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs); + + logger.error(guidLogPrefix + " " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + this.logPssSeq = com.eactive.eai.common.logger.Keys.LOG_SEQ_4; + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } + } + + public void logSenderCtrlSend() { + String telgmDmndDstcd = reqEaiMsg.getMapper().getSendRecvDivision(reqEaiMsg.getStandardMessage()); // S|R + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd)) { + this.logPssSeq = com.eactive.eai.common.logger.Keys.LOG_SEQ_4; + } else { + this.logPssSeq = com.eactive.eai.common.logger.Keys.LOG_SEQ_2; + } + + try { + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " AA Exception Logging Error :" + e.getMessage()); + } + } + + public boolean checkServiceMsgSize() { + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) && reqEaiMsg.getSvcMsgs().size() > 1) { + return true; + } else { + return false; + } + } + + public void setCurrentService() throws Exception { + String keyMgtMsgVl = resEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " AS 응답 keyMgtMsgVl[" + keyMgtMsgVl + "]"); + } + resEaiMsg.setSvcPssSeq(resEaiMsg.getSvcPssSeq() + 1); + resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); + + // AS 응답거래 라우팅 + try { + // Service Routing + String[] b2bKeys = B2BExtractor.getB2BRouteKeyValues(this.resEaiMsg.getEAISvcCd(), + this.resEaiMsg.getSvcPssSeq(), + this.resEaiMsg.getStandardMessage().getBizData(), getInboundCharset()); + String mappedKey = "DEFAULT"; + if (b2bKeys != null && b2bKeys.length > 0) { + for (int i = 0; i < b2bKeys.length; i++) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : B2B RouteKey [" + b2bKeys[i] + "]"); + EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BService(b2bKeys[i], this.resEaiMsg); + if (mappedEaiMsg != null) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : EAISVCCD[" + this.resEaiMsg.getEAISvcCd() + + "] B2B RouteKey [" + b2bKeys[i] + "]의 서비스메시지를 매핑함"); + this.resEaiMsg = mappedEaiMsg; + mappedKey = b2bKeys[i]; + break; + } + } + } else { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : 조회된 서비스 라우팅 키가 없습니다."); + // 기동이 내부표준이 아닌 경우 기관코드로 라우팅 하도록 수정 + if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.resEaiMsg.getStdMsgUsgCls())) { + String instCd = this.resEaiMsg.getMapper().getInstCode(this.resEaiMsg.getStandardMessage()); + if (instCd == null || instCd.trim().length() == 0) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : 내부표준의 대외기관코드의 값이 없음"); + } else { + String extBizCode = this.resEaiMsg.getExtBizCd(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : B2B RouteKey 인터페이스 대외업무구분코드 [" + extBizCode + "]"); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : B2B RouteKey 내부표준의 대외기관코드 [" + instCd + "]"); + EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BService( (extBizCode+instCd), this.resEaiMsg); + if (mappedEaiMsg != null) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : EAISVCCD[" + this.resEaiMsg.getEAISvcCd() + + "] B2B RouteKey [" + extBizCode + instCd + "]의 서비스메시지를 매핑함"); + this.reqEaiMsg = mappedEaiMsg; + mappedKey = extBizCode + instCd; + } + } + } + } + + // Adapter Routing + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : B2B Service RouteKey [" + mappedKey + "]"); + + String[] adapterRouteKeys = B2BExtractor.getB2BAdapterRouteKeyValues(this.resEaiMsg.getEAISvcCd(), + this.resEaiMsg.getSvcPssSeq(), + this.resEaiMsg.getStandardMessage().getBizData() + , getInboundCharset()); + if (adapterRouteKeys != null && adapterRouteKeys.length > 0) { + for (int i = 0; i < adapterRouteKeys.length; i++) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : B2B Adapter RouteKey [" + adapterRouteKeys[i] + "]"); + EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BAdapter(mappedKey, adapterRouteKeys[i], + this.resEaiMsg, this.callProp); + if (mappedEaiMsg != null) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " AS 응답거래 : EAISVCCD[" + this.resEaiMsg.getEAISvcCd() + + "] B2B Adapter RouteKey [" + adapterRouteKeys[i] + "]의 어댑터를 매핑함"); + } + this.resEaiMsg = mappedEaiMsg; + break; + } else { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " AS 응답거래 : EAISVCCD[" + this.resEaiMsg.getEAISvcCd() + + "] B2B Adapter RouteKey [" + adapterRouteKeys[i] + "] Not Found"); + } + } + } + } else { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS 응답거래 : 조회된 어댑터 라우팅 키가 없습니다."); + } + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " AS 응답거래 : B2B Serice Routing Set Error :" + e.getMessage()); + String[] msgArgs = new String[1]; + msgArgs[0] = this.resEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " AS 응답거래 : " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + // 기동이 표준인 경우만 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) { + setReturnType(resEaiMsg, STDMessageKeys.SEND_RECV_CD_RECV); + } + } + + public boolean isOutboundCall() { + return true; + } + + public void init() throws Exception { + try { + String guid = this.reqEaiMsg.getMapper().getGuid(this.reqEaiMsg.getStandardMessage()); + String guidseq = this.reqEaiMsg.getMapper().getGuidSeq(this.reqEaiMsg.getStandardMessage()); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + this.reqEaiMsg.getMapper().nextGuidSeq(this.reqEaiMsg.getStandardMessage()); + guidseq = this.reqEaiMsg.getMapper().getGuidSeq(this.reqEaiMsg.getStandardMessage()); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + this.resEaiMsg = this.reqEaiMsg; + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR003"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + + String srcAdapterGroupName = reqEaiMsg.getSngSysItfTp(); + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(srcAdapterGroupName); + + if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_FROMTAS.equals(reqEaiMsg.getTranType()) + && inAdptGrpVO == null) { + logger.info(guidLogPrefix + "- TAS 기동거래 [" + srcAdapterGroupName + "] = " + MessageType.ASC); + } else { + if (inAdptGrpVO == null) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF003"; + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + "(어댑터그룹 미등록/미사용 - " + + srcAdapterGroupName + ")"; + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + } + } + + public void printExceptionMessage(Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " ExceptionPath : " + e.getMessage()); + } + + public boolean isSourceAsync() { + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + return true; + } else { + return false; + } + } + + public void callExceptionHandler() { + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + String inAdapterMsgType = inAdptGrpVO.getMessageType(); + if (EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + byte[] asc = CodeConversion.meToMixedAsc(bizData.getBytes()); + try { + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.reqEaiMsg.getStandardMessage().setBizData(new String(asc), inboundCharset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + } + ExceptionHandler.handle(this.reqEaiMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " ExceptionHandler Call Error", e); + } + } + + public boolean isRealCall() { + if (this.callProp != null) { + String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); + if (mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { + logger.warn(guidLogPrefix + " Warming Up Called"); + return false; + } else { + return true; + } + } else { + return true; + } + } + + private String getInboundCharset() { + String srcAdapterGroupName = reqEaiMsg.getSngSysItfTp(); + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(srcAdapterGroupName); + String charset = StringUtils.defaultIfBlank(inAdptGrpVO.getMessageEncode(), Charset.defaultCharset().name()); + return charset; + } + + public void setRoute() throws Exception { + String adapterGroupName; + try { + // Service Routing + String[] b2bKeys = B2BExtractor.getB2BRouteKeyValues(this.reqEaiMsg.getEAISvcCd(), + this.reqEaiMsg.getSvcPssSeq() + , this.reqEaiMsg.getStandardMessage().getBizData(), getInboundCharset()); + + String mappedKey = "DEFAULT"; + if (b2bKeys != null && b2bKeys.length > 0) { + for (int i = 0; i < b2bKeys.length; i++) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " B2B RouteKey [" + b2bKeys[i] + "]"); + EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BService(b2bKeys[i], this.reqEaiMsg); + if (mappedEaiMsg != null) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " EAISVCCD[" + this.reqEaiMsg.getEAISvcCd() + + "] B2B RouteKey [" + b2bKeys[i] + "]의 서비스메시지를 매핑함"); + this.reqEaiMsg = mappedEaiMsg; + mappedKey = b2bKeys[i]; + break; + } + } + } else { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " 조회된 서비스 라우팅 키가 없습니다."); + + // 기동이 내부 표준인 경우 기관코드로 라우팅 하도록 수정 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) { + String instCd = this.reqEaiMsg.getMapper().getInstCode(this.reqEaiMsg.getStandardMessage()); + + if (instCd == null || instCd.trim().length() == 0) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " 내부표준의 대외기관코드의 값이 없음"); + } else { + String extBizCode = this.reqEaiMsg.getExtBizCd(); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " B2B RouteKey 인터페이스의 대외업무구분코드 [" + extBizCode + "]"); + logger.debug(guidLogPrefix + " B2B RouteKey 내부표준의 대외기관코드 [" + instCd + "]"); + } + EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BService(extBizCode + instCd, this.reqEaiMsg); + if (mappedEaiMsg != null) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " EAISVCCD[" + this.reqEaiMsg.getEAISvcCd() + + "] B2B RouteKey [" + instCd + "]의 서비스메시지를 매핑함"); + this.reqEaiMsg = mappedEaiMsg; + mappedKey = extBizCode + instCd; + } + } + } + } + + // EAI서비스코드 앞 3자리와 he03의 PSVSYSBZWKDSTCD 의 앞 3자리가 다른경우 추출 + PropManager pMan = PropManager.getInstance(); + String differenceLog = pMan.getProperty("DIFFERENCE", "LOG_YN", "Y"); + if ("Y".equals(differenceLog)) { + if (this.reqEaiMsg != null && this.reqEaiMsg.getCurrentSvcMsg() != null) { + + String eaiSvcName = this.reqEaiMsg.getEAISvcCd(); + String instCd = getInstCode(this.reqEaiMsg); + String biz = this.reqEaiMsg.getCurrentSvcMsg().getPsvBwkSysNm(); + String keys = ""; + String apcode = ""; + + if (eaiSvcName != null && eaiSvcName.trim().length() >= 3) { + apcode = eaiSvcName.trim().substring(0, 3); + } + + if (b2bKeys != null && b2bKeys.length > 0) { + for (String k : b2bKeys) { + keys += "," + k; + } + } + keys = "[" + keys + "]"; + if (biz != null) { + biz = biz.trim(); + } + if (apcode != null && biz != null) { + if (!biz.equals(apcode)) { + logger.error("B2BFCProcess] difference apcode set apcode=" + apcode + ", bwksysnm=" + biz + + ", eaisvcname=" + eaiSvcName + ", keys=" + keys + ", instCd=" + instCd); + } + } else { + logger.error("B2BFCProcess] difference apcode set apcode=" + apcode + ", bwksysnm=" + biz + + ", eaisvcname=" + eaiSvcName + ", keys=" + keys + ", instCd=" + instCd); + } + } + } + + // Adapter Routing + if (logger.isDebug()) + logger.debug(guidLogPrefix + " B2B Service RouteKey [" + mappedKey + "]"); + + String[] adapterRouteKeys = B2BExtractor.getB2BAdapterRouteKeyValues(this.reqEaiMsg.getEAISvcCd(), + this.reqEaiMsg.getSvcPssSeq() + , this.reqEaiMsg.getStandardMessage().getBizData() + , getInboundCharset()); + if (adapterRouteKeys != null && adapterRouteKeys.length > 0) { + for (int i = 0; i < adapterRouteKeys.length; i++) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " B2B Adapter RouteKey [" + adapterRouteKeys[i] + "]"); + } + EAIMessage mappedEaiMsg = B2BServiceMapper.setB2BAdapter(mappedKey, adapterRouteKeys[i], + this.reqEaiMsg, this.callProp); + if (mappedEaiMsg != null) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " EAISVCCD[" + this.reqEaiMsg.getEAISvcCd() + + "] B2B Adapter RouteKey [" + adapterRouteKeys[i] + "]의 어댑터를 매핑함 - " + + callProp.getProperty(Keys.OUT_ADAPTER_GROUP_NAME)); + } + this.reqEaiMsg = mappedEaiMsg; + break; + } else { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " EAISVCCD[" + this.reqEaiMsg.getEAISvcCd() + + "] B2B Adapter RouteKey [" + adapterRouteKeys[i] + "] Not Found"); + } + } + } else { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " 조회된 어댑터 라우팅 키가 없습니다."); + } + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " B2B Serice Routing Set Error :" + e.getMessage()); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + try { + adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() + && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType())) { + PropManager manager = PropManager.getInstance(); + Properties prop = manager.getProperties(RouteKeys.SIM); + + if (reqEaiMsg.getCurrentSvcMsg().isSyncItfTp()) { + adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_SYNC, "_SIM_OU_HTT_SyC"); + } else { + adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_ASYNC, "_SIM_OU_HTT_AsC"); + } + } else { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + + if (adptGrpVO == null) { + throw new Exception("수동어댑터[" + adapterGroupName + "]가 사용 중이 아님"); + } + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR003"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + // AA가 아니고 기동이 KB표준이 아닌 경우 Adapter의 timeout값을 설정한다. + try { + String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && !(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls()))) { + // SA 또는 SNA Adapter일 경우에 는 SA Timeout값을 설정 + if ((EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + || Keys.TYPE_SNA.equals(adptGrpVO.getType())) { + int saTimeoutSec = this.reqEaiMsg.getCurrentSvcMsg().getTmoVl(); + if (logger.isDebug()) + logger.debug("BaseFCProcess] SA TimeoutValue [" + saTimeoutSec + "]"); + setTimeout(this.reqEaiMsg, "" + saTimeoutSec); + } else { + int timeout = ServiceUtil.getTimeoutValue(adapterGroupName); + if (logger.isDebug()) + logger.debug("BaseFCProcess] Target Adapter TimeoutValue [" + timeout + "]"); + if (timeout > 0) { + if (logger.isDebug()) + logger.debug("BaseFCProcess] Set Adapter TimeoutValue [" + timeout + "] to KBMessage"); + setTimeout(this.reqEaiMsg, "" + timeout); + } + } + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn("BaseFCProcess] Get Adapter TimeoutValue Error - " + e.getMessage(), e); + } + } + } + + public void setAdptrInstiCode() throws Exception { + String groupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(groupName); + + if (adptGrpVO != null) { + String adptrInstiCode = adptGrpVO.getAdptrInstiCode(); + if (adptrInstiCode != null && !"".equals(adptrInstiCode)) { + reqEaiMsg.setAdptrInstiCode(adptrInstiCode); + } + } + } + + public void setGUID() throws Exception { + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + + if ((!(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) + && !(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp))) + || ((com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) + && (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) + && EAIMessageKeys.SYNC_SVC.equals(psvItfTp)))) { + String prcssRtdTranCd = mapper.getReturnServiceId(standardMessage); + + if (prcssRtdTranCd != null && prcssRtdTranCd.length() >= 14) { + String telgmRecvTranCd = prcssRtdTranCd.substring(4, 14); + mapper.setServiceId(standardMessage, telgmRecvTranCd); + } else { + if (logger.isInfo()) { + logger.info(guidLogPrefix + "- PrcssRtdTranCd Length < 14 [" + prcssRtdTranCd + "]"); + } + } + } + + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) + && (STDMessageKeys.RECOVER_YN_YES + .equals(this.reqEaiMsg.getMapper().getRecoverYn(this.reqEaiMsg.getStandardMessage())))) { + String reqOgtranGuIdNo = this.reqEaiMsg.getMapper().getOrgGuid(this.reqEaiMsg.getStandardMessage()); + mapper.setOrgGuid(standardMessage, reqOgtranGuIdNo); + if (logger.isInfo()) { + logger.info(guidLogPrefix + " OgtranGuIdNo 복원 " + this.reqEaiMsg.getSvcOgNo() + " OgtranGuIdNo [" + + mapper.getOrgGuid(standardMessage) + "]"); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/flowcontroller/BaseFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/BaseFCProcess.java new file mode 100644 index 0000000..8f31090 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/BaseFCProcess.java @@ -0,0 +1,473 @@ +package com.eactive.eai.flowcontroller; + +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.EAITable; +import com.eactive.eai.common.exception.ExceptionHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.IFRouter; +import com.eactive.eai.common.routing.Process; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.ObjectUtil; +import com.eactive.eai.common.util.ServiceUtil; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.service.InterfaceMapper; +import com.eactive.eai.transformer.function.util.CodeConversion; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class BaseFCProcess extends Process { + public String adptrMsgPtrnCd; + + public java.lang.String adapterGroupName; + + public int logPssSeq; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public java.util.Properties callProp; + + public EAIMessage resEaiMsg; + + public com.eactive.eai.common.message.EAIMessage reqEaiMsg; + + static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + private int svrLogLevel; + private static ThreadLocal local = new ThreadLocal(); + + String guidLogPrefix = ""; + + static final long serialVersionUID = 1L; + + public EAIMessage clientReturn() { + if (svrLogLevel >= 1) { + try { + long msgSndTm = System.currentTimeMillis(); + + Long threadData = (Long) local.get(); + long processTm = msgSndTm - threadData.longValue(); + if (esbLogger.isInfo()) + esbLogger.info( + guidLogPrefix + "End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("clientReturn", e); + } + } + return resEaiMsg; + } + + public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) { + this.reqEaiMsg = reqEaiMsg; + this.callProp = callProp; + + if (this.reqEaiMsg == null) + return; + svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); + + guidLogPrefix = "BaseFCProcess] GUID[" + getGuid(reqEaiMsg) + "] UUID[" + this.reqEaiMsg.getSvcOgNo() + "] "; + + if (svrLogLevel >= 1) { + try { + long msgRcvTm = System.currentTimeMillis(); + local.set(new Long(msgRcvTm)); + + if (esbLogger.isInfo()) + esbLogger.info(guidLogPrefix + " started... - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("callService", e); + } + } + + try { + flow(); + } catch (Exception e) { + printExceptionMessage(e); + if (isSourceAsync()) { + logSenderCtrlSend(); + callExceptionHandler(); + } + return; + } + } + + public void flow() throws Exception { + if (!isRealCall()) { + return; + } + // 초기화 + init(); + // Outbound 프로세스 호출 + ifRouterProcess(); + // GUID설정 + setGUID(); + // ASYNC-SYNC모델 + if (checkServiceMsgSize()) { + // ServiceMessage설정 + setCurrentService(); + // 응답메시지전송 + ifRouterProcessResponse(); + } + } + + public void ifRouterProcess() throws Exception { + try { +// this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); + EAIMessage reqMsg = (EAIMessage) ObjectUtil.deepCopy(this.reqEaiMsg); + this.resEaiMsg = IFRouter.process(reqMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + // ---------------------------------------------------- + // 기동시스템이 Async 거래의 OUtbound에서 오류가 발생할 경우 + // ExceptionHandler를 통해 응답메시지를 전송한다. + // ---------------------------------------------------- + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + try { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.resEaiMsg.getStandardMessage().setBizData(bizData, inboundCharset); + ExceptionHandler.handle(this.resEaiMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + "ExceptionHandler Call Error :" + e.getMessage()); + } + } + } + } + + public void ifRouterProcessResponse() throws Exception { + try { + // 20220405 + // AS거래에서 처리결과수신서비스ID를 서비스ID로 넣어준다. + String returnServiceId = this.resEaiMsg.getMapper().getReturnServiceId(this.resEaiMsg.getStandardMessage()); + this.resEaiMsg.getMapper().setServiceId(this.resEaiMsg.getStandardMessage(), returnServiceId); + + this.resEaiMsg = IFRouter.process(this.resEaiMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF100"; + String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + this.logPssSeq = 400; + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } + } + + public void logSenderCtrlSend() { + String telgmDmndDstcd = reqEaiMsg.getMapper().getSendRecvDivision(reqEaiMsg.getStandardMessage()); + + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd)) { + this.logPssSeq = 400; + } else { + this.logPssSeq = 200; + } + + try { + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + "AA Exception Logging Error :" + e.getMessage()); + } + } + + public boolean checkServiceMsgSize() { + // Outbound Error일 경우 + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) && reqEaiMsg.getSvcMsgs().size() > 1) { + return true; + } else { + return false; + } + } + + public void setCurrentService() throws Exception { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "ASYNC-SYNC CALLED"); + // --------------------------------------------------------------- + // AS의 경우 다음 서비스메시지(AS 응답)에 키관리메시지내용을 복사한다. + // --------------------------------------------------------------- + String keyMgtMsgVl = resEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + "AS 응답 keyMgtMsgVl[" + keyMgtMsgVl + "]"); + resEaiMsg.setSvcPssSeq(resEaiMsg.getSvcPssSeq() + 1); + resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); + // --------------------------------------------------------------- + + // 기동이 표준인 경우만 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) { +// resEaiMsg = ExtMessageConverter.setAsyncSyncResponseForStandard(guidLogPrefix, reqEaiMsg, resEaiMsg); + setReturnType(resEaiMsg, STDMessageKeys.SEND_RECV_CD_RECV); + } + + } + + public boolean isOutboundCall() { + return true; + } + + public void init() throws Exception { + // ------------------------------------------- + // eLink 내부에서는 GUID 진행번호를 분리 + // ExtMessage 에서는 분리 + // STDMessage 에서는 사이트에 맞게 변경처리 + // ------------------------------------------- + InterfaceMapper mapper = this.reqEaiMsg.getMapper(); + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + this.resEaiMsg = this.reqEaiMsg; + + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + // 등록된 어댑터가 실제 존재하지 않는 경우 : 2009.04.03 + if (adptGrpVO == null) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF003"; + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + "(어댑터그룹 미등록/미사용 - " + + this.adapterGroupName + ")"; + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + String adapterType = adptGrpVO.getType(); + if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType()) + // RESTAdapter는 교체하지 않는다 + && !StringUtils.equals(adapterType, "RST")) { +// this.adptrMsgPtrnCd = com.eactive.eai.adapter.Keys.IF_NONSTANDARD; +// adapterType = Keys.TYPE_NET2; + PropManager manager = PropManager.getInstance(); + Properties prop = manager.getProperties(RouteKeys.SIM); + + if (reqEaiMsg.getCurrentSvcMsg().isSyncItfTp()) { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_SYNC, "_SIM_OU_HTT_SyC"); + } else { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_ASYNC, "_SIM_OU_HTT_AsC"); + } + } else { +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + + // failover 사용시에는 제거 되어야됨 +// if(adptGrpVO.nextAdapterVO() == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFBF002"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) +// + ","+this.adapterGroupName; +// if (logger.isError()) logger.error( guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorCode); +// } + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); + adapterType = adptGrpVO.getType(); + } + + String svcTsmtUsgTp = ""; // 기동 호출방식 + String psvItfTp = ""; // 수동 호출방식 + + // 2009.03.11 + // AA가 아니고 기동이 표준이 아닌 경우 + // Adapter의 timeout값을 설정한다. + try { + svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && !(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls()))) { + // SA 또는 SNA Adapter일 경우에 는 SA Timeout값을 설정 + if ((EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + || Keys.TYPE_SNA.equals(adapterType)) { + int saTimeoutSec = this.reqEaiMsg.getCurrentSvcMsg().getTmoVl(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " SA TimeoutValue [" + saTimeoutSec + "]"); +// this.reqEaiMsg.getKbMsg().getKBHeader().setGnrzToutCrtcNmvl(""+saTimeoutSec); + this.reqEaiMsg.getMapper().setTimeout(this.reqEaiMsg.getStandardMessage(), "" + saTimeoutSec); + } else { + int timeout = ServiceUtil.getTimeoutValue(adapterGroupName); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " Target Adapter TimeoutValue [" + timeout + "]"); + if (timeout > 0) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "Set Adapter TimeoutValue [" + timeout + "] to STDMessage"); +// this.reqEaiMsg.getKbMsg().getKBHeader().setGnrzToutCrtcNmvl(""+timeout); + this.reqEaiMsg.getMapper().setTimeout(this.reqEaiMsg.getStandardMessage(), "" + timeout); + } + } + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + "Get Adapter TimeoutValue Error - " + e.getMessage(), e); + } + } + + // ----------------------------------------------------- + // TheK 요건 : SNA송신 비동기 응답거래시 수신거래코드를 EAI에서 매핑함 (20190522) + String srcAdapterGroupName = reqEaiMsg.getSngSysItfTp(); +// AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(srcAdapterGroupName); + String inAdapterMsgType = MessageType.ASC; + if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_FROMTAS.equals(reqEaiMsg.getTranType()) + && inAdptGrpVO == null) { + logger.info(guidLogPrefix + "- TAS 기동거래 [" + srcAdapterGroupName + "] = " + MessageType.ASC); + } else { + if (inAdptGrpVO == null) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF003"; + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + "(어댑터그룹 미등록/미사용 - " + + srcAdapterGroupName + ")"; + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + inAdapterMsgType = inAdptGrpVO.getMessageType(); + } + } + + public void printExceptionMessage(Exception e) { + // Exception e = this.context.getExceptionInfo().getException(); + if (logger.isError()) + logger.error(guidLogPrefix + "ExceptionPath : " + e.getMessage(), e); + } + + public boolean isSourceAsync() { + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + return true; + } else { + return false; + } + } + + public void callExceptionHandler() { + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + String inAdapterMsgType = inAdptGrpVO.getMessageType(); + if (EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + byte[] asc = CodeConversion.meToMixedAsc(bizData.getBytes()); + try { + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.reqEaiMsg.getStandardMessage().setBizData(new String(asc), inboundCharset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + } + ExceptionHandler.handle(this.reqEaiMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + "ExceptionHandler Call Error", e); + } + } + + public boolean isRealCall() { + if (this.callProp != null) { + String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); + if (mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { + logger.warn(guidLogPrefix + "Warming Up Called"); + return false; + } else { + return true; + } + } else { + return true; + } + } + + public void setGUID() throws Exception { + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + + if ((!(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) + && !(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp))) + || ((com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) + && (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) + && EAIMessageKeys.SYNC_SVC.equals(psvItfTp)))) { + String prcssRtdTranCd = mapper.getReturnServiceId(standardMessage); + + if (prcssRtdTranCd != null && prcssRtdTranCd.length() >= 14) { +// String cicsTrncd = prcssRtdTranCd.substring(0, 4); + String telgmRecvTranCd = prcssRtdTranCd.substring(4, 14); + mapper.setServiceId(standardMessage, telgmRecvTranCd); + } else { + if (logger.isInfo()) { + logger.info(guidLogPrefix + "- PrcssRtdTranCd Length < 14 [" + prcssRtdTranCd + "]"); + } + } + } + + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) + && (STDMessageKeys.RECOVER_YN_YES + .equals(this.reqEaiMsg.getMapper().getRecoverYn(this.reqEaiMsg.getStandardMessage())))) { + String reqOgtranGuIdNo = this.reqEaiMsg.getMapper().getOrgGuid(this.reqEaiMsg.getStandardMessage()); + mapper.setOrgGuid(standardMessage, reqOgtranGuIdNo); + if (logger.isInfo()) { + logger.info(guidLogPrefix + " OgtranGuIdNo 복원 " + this.reqEaiMsg.getSvcOgNo() + " OgtranGuIdNo [" + + mapper.getOrgGuid(standardMessage) + "]"); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/flowcontroller/C2RFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/C2RFCProcess.java new file mode 100644 index 0000000..7808b59 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/C2RFCProcess.java @@ -0,0 +1,531 @@ +package com.eactive.eai.flowcontroller; + +import java.util.Properties; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.EAITable; +import com.eactive.eai.common.exception.ExceptionHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.IFRouter; +import com.eactive.eai.common.routing.Process; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.C2RServiceMapper; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.ObjectUtil; +import com.eactive.eai.common.util.ServiceUtil; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.service.InterfaceMapper; +import com.eactive.eai.transformer.function.util.CodeConversion; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class C2RFCProcess extends Process { + public String adptrMsgPtrnCd; + + public java.lang.String adapterGroupName; + + public int logPssSeq; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public java.util.Properties callProp; + + public EAIMessage resEaiMsg; + + public com.eactive.eai.common.message.EAIMessage reqEaiMsg; + + static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + private int svrLogLevel; + private static ThreadLocal local = new ThreadLocal(); // 경과시간 동기화를 위한 ThreadLocal + + static final long serialVersionUID = 1L; + + String guidLogPrefix = ""; + + public C2RFCProcess() { + + } + + public EAIMessage clientReturn() { + if (svrLogLevel >= 1) { + try { + long msgSndTm = System.currentTimeMillis(); + + Long threadData = (Long) local.get(); + long processTm = msgSndTm - threadData.longValue(); + if (esbLogger.isInfo()) + esbLogger.info(guidLogPrefix + " End... - elapse time : " + processTm + + "(ms) - EAI Server Log Level is INFO"); + } catch (Exception e) { + } + } + return resEaiMsg; + } + + public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) { + this.reqEaiMsg = reqEaiMsg; + this.callProp = callProp; + + if (this.reqEaiMsg == null) + return; + + svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); + + guidLogPrefix = "B2BFCProcess] GUID[" + getGuid(reqEaiMsg) + "] UUID[" + this.reqEaiMsg.getSvcOgNo() + "] "; + + if (svrLogLevel >= 1) { + try { + long msgRcvTm = System.currentTimeMillis(); + local.set(new Long(msgRcvTm)); + if (esbLogger.isInfo()) + esbLogger.info(guidLogPrefix + " started... - EAI Server Log Level is INFO"); + } catch (Exception e) { + } + } + try { + flow(); + } catch (Exception e) { + printExceptionMessage(e); + if (isSourceAsync()) { + logSenderCtrlSend(); + callExceptionHandler(); + } + return; + } + } + + public void flow() throws Exception { + // isRealCall + if (!isRealCall()) { + return; + } + // 초기화 + init(); + // B2BOutboud Mapping + setRoute(); + + // Outbound 프로세스 호출 + ifRouterProcess(); + + // GUID설정 + setGUID(); + + // ASYNC-SYNC모델 + if (checkServiceMsgSize()) { + // ServiceMessage설정 + setCurrentService(); + // 응답메시지전송 + ifRouterProcess1(); + } + clientReturn(); + } + + public void ifRouterProcess() throws Exception { + try { + // call by ref 문제로 deepCopy로 해결 - 200 변환에 의해 변경되는 문제 + EAIMessage reqMsg = (EAIMessage) ObjectUtil.deepCopy(this.reqEaiMsg); + this.resEaiMsg = IFRouter.process(reqMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + // ---------------------------------------------------- + // 기동시스템이 Async 거래의 OUtbound에서 오류가 발생할 경우 + // ExceptionHandler를 통해 응답메시지를 전송한다. + // ---------------------------------------------------- + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + try { + // 변경없이 요청 EAI메시지를 전달하도록 수정 + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + try { + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.resEaiMsg.getStandardMessage().setBizData(bizData, inboundCharset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + + ExceptionHandler.handle(this.resEaiMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " ExceptionHandler Call Error :" + e.getMessage()); + } + } + } + } + + public void ifRouterProcess1() throws Exception { + try { + // 신보/기보 때문에 추가함 2013-01-03 + // AS거래에서 처리결과수신서비스ID를 서비스ID로 넣어준다. + // this.resEaiMsg.getStdMsg().getSTDCommon().setSrvcId(this.resEaiMsg.getStdMsg().getSTDCommon().getProcsRsltRcmsSrvcId()); + this.resEaiMsg = IFRouter.process(this.resEaiMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR100"; + String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + // AS 응답송신 중 에러가 밸생할 경우 400 에러로그를 남기도록 수정 + this.logPssSeq = 400; + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } + } + + public void logSenderCtrlSend() { + String returnType = getReturnType(reqEaiMsg); // S|R + + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + this.logPssSeq = 400; + } else { + this.logPssSeq = 200; + } + + try { + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " AA Exception Logging Error :" + e.getMessage()); + } + } + + public boolean checkServiceMsgSize() { + // Outbound Error일 경우 + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) && reqEaiMsg.getSvcMsgs().size() > 1) { + return true; + } else { + return false; + } + } + + public void setCurrentService() throws Exception { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " ASYNC-SYNC CALLED"); + + // AS의 경우 다음 서비스메시지(AS 응답)에 키관리메시지내용을 복사한다. + String keyMgtMsgVl = resEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " AS Response keyMgtMsgVl[" + keyMgtMsgVl + "]"); + resEaiMsg.setSvcPssSeq(resEaiMsg.getSvcPssSeq() + 1); + resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); + + // AS 응답거래 라우팅 + try { + String srvcId = getServiceId(this.resEaiMsg); // 서비스ID + String psvItfTp = this.resEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + if (srvcId == null || srvcId.trim().length() == 0 || srvcId.trim().length() <= 3) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " STDMessage ServiceId not found"); + } else { +// String reqSysCode = this.resEaiMsg.getExtMsg().getFullHeaderString("systemHeader.DMND_SYS_CD"); // 요청시스템코드(서비스ID 앞의 3자리 시용에서 요청시스템코드로 변경함) + String reqSysCode = getReqSysCode(this.resEaiMsg); + String type = ""; + if (EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) { + type = "A"; + } else { + type = "S"; + } + String key = reqSysCode + type; + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " C2R RouteKey STDMessage ServiceID [" + srvcId + "]"); + if (logger.isDebug()) + logger.debug( + guidLogPrefix + " C2R RouteKey STDMessage systemHeader.DMND_SYS_CD [" + reqSysCode + "]"); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " C2R RouteKey STDMessage Sync/Async [" + type + "]"); + EAIMessage mappedEaiMsg = C2RServiceMapper.setC2RService(key, this.resEaiMsg); + if (mappedEaiMsg != null) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " EAISVCCD[" + this.resEaiMsg.getEAISvcCd() + "] C2R RouteKey [" + + key + "] ServiceMessage mapping"); + this.resEaiMsg = mappedEaiMsg; + } + } + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " AS Response : B2B Serice Routing Set Error :" + e.getMessage()); + String[] msgArgs = new String[1]; + msgArgs[0] = this.resEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " AS Response : " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + // 기동이 표준인 경우만 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) { +// resEaiMsg = ExtMessageConverter.setAsyncSyncResponseForStandard(guidLogPrefix, reqEaiMsg, resEaiMsg); + setReturnType(resEaiMsg, STDMessageKeys.SEND_RECV_CD_RECV); + } + } + + public boolean isOutboundCall() { + return true; + } + + public void init() throws Exception { + try { + InterfaceMapper mapper = this.reqEaiMsg.getMapper(); + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + String guid = getGuid(reqEaiMsg); + String guidseq = getGuidSeq(reqEaiMsg); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = getGuidSeq(reqEaiMsg); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + this.resEaiMsg = this.reqEaiMsg; + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR003"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + } + + public void printExceptionMessage(Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " ExceptionPath : " + e.getMessage()); + } + + public boolean isSourceAsync() { + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + return true; + } else { + return false; + } + + } + + public void callExceptionHandler() { + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + String inAdapterMsgType = inAdptGrpVO.getMessageType(); + if (EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + byte[] asc = CodeConversion.meToMixedAsc(bizData.getBytes()); + try { + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.reqEaiMsg.getStandardMessage().setBizData(new String(asc), inboundCharset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + } + ExceptionHandler.handle(this.reqEaiMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " ExceptionHandler Call Error :" + e.getMessage()); + } + } + + public boolean isRealCall() { + if (this.callProp != null) { + String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); + if (mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { + System.out.println(guidLogPrefix + " Warming Up Called"); + return false; + } else { + return true; + } + } else { + return true; + } + } + + public void setRoute() throws Exception { + try { + String srvcId = getServiceId(this.reqEaiMsg); + String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + + if (srvcId == null || srvcId.trim().length() == 0 || srvcId.trim().length() <= 3) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " STDMessage ServiceID not found"); + } else { +// String reqSysCode = this.resEaiMsg.getExtMsg().getFullHeaderString("systemHeader.DMND_SYS_CD"); // 요청시스템코드(서비스ID 앞의 3자리 시용에서 요청시스템코드로 변경함) + String reqSysCode = getReqSysCode(this.resEaiMsg); + String type = ""; + if (EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) { + type = "A"; + } else { + type = "S"; + } + String key = reqSysCode + type; + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " C2R RouteKey STDMessage ServiceID [" + srvcId + "]"); + if (logger.isDebug()) + logger.debug( + guidLogPrefix + " C2R RouteKey STDMessage systemHeader.DMND_SYS_CD [" + reqSysCode + "]"); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " C2R RouteKey STDMessage Sync/Async [" + type + "]"); + + EAIMessage mappedEaiMsg = C2RServiceMapper.setC2RService(key, this.reqEaiMsg); + if (mappedEaiMsg != null) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " EAISVCCD[" + this.reqEaiMsg.getEAISvcCd() + "] C2R RouteKey [" + + key + "] ServiceMessage mapping"); + this.reqEaiMsg = mappedEaiMsg; + } + } + + } catch (Exception e) { + // TO-DO + if (logger.isError()) + logger.error(guidLogPrefix + " B2B Serice Routing Set Error :" + e.getMessage()); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + try { + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() + && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType())) { +// this.adptrMsgPtrnCd = com.eactive.eai.adapter.Keys.IF_NONSTANDARD; + PropManager manager = PropManager.getInstance(); + Properties prop = manager.getProperties(RouteKeys.SIM); + + if (reqEaiMsg.getCurrentSvcMsg().isSyncItfTp()) { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_SYNC, "_SIM_OU_HTT_SyC"); + } else { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_ASYNC, "_SIM_OU_HTT_AsC"); + } + } else { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + // 등록된 어댑터가 실제 존재하지 않는 경우 : 2009.04.03 + if (adptGrpVO == null) { + throw new Exception("수동어댑터[" + this.adapterGroupName + "]가 사용 중이 아님"); + } + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBR003"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + // 2009.03.11 + // AA가 아니고 기동이 표준이 아닌 경우 + // Adapter의 timeout값을 설정한다. + try { + String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && !(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls()))) { + // SA 또는 SNA Adapter일 경우에 는 SA Timeout값을 설정 + if ((EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + || Keys.TYPE_SNA.equals(adptGrpVO.getType())) { + int saTimeoutSec = this.reqEaiMsg.getCurrentSvcMsg().getTmoVl(); + if (logger.isDebug()) + logger.debug("BaseFCProcess] SA TimeoutValue [" + saTimeoutSec + "]"); + setTimeout(this.reqEaiMsg, "" + saTimeoutSec); + } else { + int timeout = ServiceUtil.getTimeoutValue(adapterGroupName); + if (logger.isDebug()) + logger.debug("BaseFCProcess] Target Adapter TimeoutValue [" + timeout + "]"); + if (timeout > 0) { + if (logger.isDebug()) + logger.debug("BaseFCProcess] Set Adapter TimeoutValue [" + timeout + "] to STDMessage"); + setTimeout(this.reqEaiMsg, "" + timeout); + } + } + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn("BaseFCProcess] Get Adapter TimeoutValue Error - " + e.getMessage(), e); + } + } + } + + public void setGUID() throws Exception { + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + + // ------------------------------------------------------ + // AA거래 가 아니고 (SS, AS, SA 일 때 모두 처리한다) + // 기동이 KB내부표준이고 + // 원거래 복원여부가 ‘1’인 경우에 + // => 원거래 GUID를 EAI에서 기동에서 수신된 원거래 GUID로 복원한다. + // ------------------------------------------------------ + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) + && (STDMessageKeys.RECOVER_YN_YES.equals(getRecoverYn(this.reqEaiMsg)) ) ) { + String reqOgtranGuIdNo = getOrgGuid(this.reqEaiMsg); + mapper.setOrgGuid(standardMessage, reqOgtranGuIdNo); + if (logger.isInfo()) { + logger.info(guidLogPrefix + " OgtranGuIdNo 복원 " + this.reqEaiMsg.getSvcOgNo() + " OgtranGuIdNo [" + + mapper.getOrgGuid(standardMessage) + "]"); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/flowcontroller/CompFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/CompFCProcess.java new file mode 100644 index 0000000..a0fee60 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/CompFCProcess.java @@ -0,0 +1,524 @@ +package com.eactive.eai.flowcontroller; + +import java.util.Properties; + +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.EAITable; +import com.eactive.eai.common.exception.ExceptionHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.IFRouter; +import com.eactive.eai.common.routing.Process; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.ObjectUtil; +import com.eactive.eai.common.util.ServiceUtil; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.service.InterfaceMapper; +import com.eactive.eai.transformer.function.util.CodeConversion; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class CompFCProcess extends Process { + public String adptrMsgPtrnCd; + + public java.lang.String adapterGroupName; + + public int logPssSeq; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public java.util.Properties callProp; + + public EAIMessage resEaiMsg; + + public com.eactive.eai.common.message.EAIMessage reqEaiMsg; + + static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + private int svrLogLevel; + private static ThreadLocal local = new ThreadLocal(); // 경과시간 동기화를 위한 ThreadLocal + + String guidLogPrefix = ""; + + static final long serialVersionUID = 1L; + + public EAIMessage clientReturn() { + if (svrLogLevel >= 1) { + try { + long msgSndTm = System.currentTimeMillis(); + + Long threadData = (Long) local.get(); + long processTm = msgSndTm - threadData.longValue(); + if (esbLogger.isInfo()) + esbLogger.info( + guidLogPrefix + "End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("clientReturn", e); + } + } + return resEaiMsg; + } + + public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) { + this.reqEaiMsg = reqEaiMsg; + this.callProp = callProp; + + if (this.reqEaiMsg == null) + return; + svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); + +// guidLogPrefix = "BaseFCProcess] GUID["+reqEaiMsg.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+this.reqEaiMsg.getSvcOgNo()+"] "; + guidLogPrefix = "BaseFCProcess] GUID[" + getGuid(reqEaiMsg) + "] UUID[" + this.reqEaiMsg.getSvcOgNo() + "] "; + + if (svrLogLevel >= 1) { + try { + long msgRcvTm = System.currentTimeMillis(); + local.set(new Long(msgRcvTm)); + + if (esbLogger.isInfo()) + esbLogger.info(guidLogPrefix + " started... - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("callService", e); + } + } + + try { + flow(); + } catch (Exception e) { + printExceptionMessage(e); + if (isSourceAsync()) { + logSenderCtrlSend(); + callExceptionHandler(); + } + return; + } + } + + public void flow() throws Exception { + // isRealCall + if (!isRealCall()) { + return; + } + // 초기화 + init(); + // Outbound 프로세스 호출 + ifRouterProcess(); + // GUID설정 + setGUID(); +// if (checkServiceMsgSize()){ +// callMultiProcess(); +// } + } + +// public void callMultiProcess() throws Exception{ +// +// if (logger.isDebug()) logger.debug( guidLogPrefix + "ASYNC-SYNC CALLED"); +// //--------------------------------------------------------------- +// // AS의 경우 다음 서비스메시지(AS 응답)에 키관리메시지내용을 복사한다. +// //--------------------------------------------------------------- +// String keyMgtMsgVl = resEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); +// if(logger.isDebug()) logger.debug( guidLogPrefix + "AS 응답 keyMgtMsgVl["+keyMgtMsgVl+"]"); +// +// EAIMessage newReqEaiMsg = SerializationUtils.clone(this.reqEaiMsg); +// newReqEaiMsg.setSvcPssSeq( newReqEaiMsg.getSvcPssSeq() + 1 ); +// newReqEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// //--------------------------------------------------------------- +// +// // 기동이 표준인 경우만 +//// if(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(newReqEaiMsg.getStdMsgUsgCls())){ +//// resEaiMsg = ExtMessageConverter.setAsyncSyncResponseForStandard(guidLogPrefix, reqEaiMsg, resEaiMsg); +//// } +// +// try { +// this.resEaiMsg = IFRouter.process(newReqEaiMsg, this.callProp); +// } catch(Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFBF100"; +// String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// //throw new RuntimeException(rspErrorCode); +// // 2009.11.26 : 정길영과장 요청 +// // AS 응답송신 중 에러가 밸생할 경우 400 에러로그를 남기도록 수정 +// this.logPssSeq = 400; +// LogSender.send(this.logPssSeq, this.resEaiMsg, null); +// } +// } + + public void ifRouterProcess() throws Exception { + try { + String keyMgtMsgVl = null; + JSONObject totalResDataObject = new JSONObject(); + + for (int i = 0; i < reqEaiMsg.getSvcMsgs().size(); i++) { + EAIMessage reqMsg = (EAIMessage) ObjectUtil.deepCopy(this.reqEaiMsg); + reqMsg.setSvcPssSeq(i + 1); + if (keyMgtMsgVl != null) + reqMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); + this.resEaiMsg = IFRouter.process(reqMsg, this.callProp); +// byte[] resBytes = (byte[]) this.resEaiMsg.getExtMsg().getBizData()[0]; + String bizData = this.resEaiMsg.getStandardMessage().getBizData(); + +// ServiceMessage svcMsg = reqMsg.getSvcMsg(i); +// String encode = null; +// if("1".equals(svcMsg.getBsRspCnvEn()) && StringUtils.isNotBlank(svcMsg.getBsRspCnvMsgID())) { +// Layout layout = TransformManager.getManager().getTransform(svcMsg.getBsRspCnvMsgID()).getSourceLayout(0); +// if("UJSON".equals(layout.getLayoutType().getName())) { +// encode = "utf-8"; +// } else { +// encode = "euc-kr"; +// } +// } +// +// if(StringUtils.isBlank(encode)) { +// AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(svcMsg.getPsvSysItfTp()); +// encode = MessageUtil.isUTF8(gvo.getMessageType()) ? "utf-8": "ms949"; +// } +// String resString = new String(resBytes, encode); + +// totalResDataObject.putAll((JSONObject)JSONValue.parse(resString)); + + totalResDataObject.putAll((JSONObject) JSONValue.parse(bizData)); + keyMgtMsgVl = resEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + } + + AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(this.adapterGroupName); + +// String encode = MessageUtil.isUTF8(gvo.getMessageType()) ? "utf-8" : "ms949"; +// this.resEaiMsg.getExtMsg().getBizData()[0] = totalResDataObject.toJSONString().getBytes(encode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + } + + public void ifRouterProcessResponse() throws Exception { + try { + this.reqEaiMsg.setSvcPssSeq(2); + this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); +// this.resEaiMsg.getExtMsg().setSendRecv(STDMessageKeys.SEND_RECV_CD_SEND); + setReturnType(this.resEaiMsg, STDMessageKeys.SEND_RECV_CD_SEND); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF100"; + String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + // throw new RuntimeException(rspErrorCode); + // 2009.11.26 : 정길영과장 요청 + // AS 응답송신 중 에러가 밸생할 경우 400 에러로그를 남기도록 수정 + this.logPssSeq = 400; + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } + } + + public void logSenderCtrlSend() { +// String telgmDmndDstcd = kbmessage.getKBHeader().getTelgmDmndDstcd(); + String returnType = getReturnType(reqEaiMsg); + + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + this.logPssSeq = 400; + } else { + this.logPssSeq = 200; + } + + try { + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + "AA Exception Logging Error :" + e.getMessage()); + } + } + + public boolean checkServiceMsgSize() { + // Outbound Error일 경우 + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) && reqEaiMsg.getSvcMsgs().size() > 1) { + return true; + } else { + return false; + } + } + + public void setCurrentService() throws Exception { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "ASYNC-SYNC CALLED"); + // --------------------------------------------------------------- + // AS의 경우 다음 서비스메시지(AS 응답)에 키관리메시지내용을 복사한다. + // --------------------------------------------------------------- + String keyMgtMsgVl = resEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + "AS 응답 keyMgtMsgVl[" + keyMgtMsgVl + "]"); + resEaiMsg.setSvcPssSeq(resEaiMsg.getSvcPssSeq() + 1); + resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); + // --------------------------------------------------------------- + + // 기동이 표준인 경우만 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) { +// resEaiMsg = ExtMessageConverter.setAsyncSyncResponseForStandard(guidLogPrefix, reqEaiMsg, resEaiMsg); + setReturnType(resEaiMsg, STDMessageKeys.SEND_RECV_CD_RECV); + } + + } + + public boolean isOutboundCall() { + return true; + } + + public void init() throws Exception { + InterfaceMapper mapper = this.reqEaiMsg.getMapper(); + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + String adapterType = ""; + this.resEaiMsg = this.reqEaiMsg; + + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType())) { +// this.adptrMsgPtrnCd = com.eactive.eai.adapter.Keys.IF_NONSTANDARD; +// adapterType = Keys.TYPE_NET2; + PropManager manager = PropManager.getInstance(); + Properties prop = manager.getProperties(RouteKeys.SIM); + + if (reqEaiMsg.getCurrentSvcMsg().isSyncItfTp()) { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_SYNC, "_SIM_OU_HTT_SyC"); + } else { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_ASYNC, "_SIM_OU_HTT_AsC"); + } + } else { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + // 등록된 어댑터가 실제 존재하지 않는 경우 : 2009.04.03 + if (adptGrpVO == null) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF003"; + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + "(어댑터그룹 미등록/미사용 - " + + this.adapterGroupName + ")"; + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + // failover 사용시에는 제거 되어야됨 +// if(adptGrpVO.nextAdapterVO() == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFBF002"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) +// + ","+this.adapterGroupName; +// if (logger.isError()) logger.error( guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorCode); +// } + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); + adapterType = adptGrpVO.getType(); + } + + String svcTsmtUsgTp = ""; // 기동 호출방식 + String psvItfTp = ""; // 수동 호출방식 + + // 2009.03.11 + // AA가 아니고 기동이 표준이 아닌 경우 + // Adapter의 timeout값을 설정한다. + try { + svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && !(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls()))) { + // SA 또는 SNA Adapter일 경우에 는 SA Timeout값을 설정 + if ((EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + || Keys.TYPE_SNA.equals(adapterType)) { + int saTimeoutSec = this.reqEaiMsg.getCurrentSvcMsg().getTmoVl(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " SA TimeoutValue [" + saTimeoutSec + "]"); +// this.reqEaiMsg.getKbMsg().getKBHeader().setGnrzToutCrtcNmvl(""+saTimeoutSec); + setTimeout(this.reqEaiMsg, "" + saTimeoutSec); + } else { + int timeout = ServiceUtil.getTimeoutValue(adapterGroupName); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " Target Adapter TimeoutValue [" + timeout + "]"); + if (timeout > 0) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "Set Adapter TimeoutValue [" + timeout + "] to STDMessage"); +// this.reqEaiMsg.getKbMsg().getKBHeader().setGnrzToutCrtcNmvl(""+timeout); + setTimeout(this.reqEaiMsg, "" + timeout); + } + } + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + "Get Adapter TimeoutValue Error - " + e.getMessage(), e); + } + } + + // ----------------------------------------------------- + // TheK 요건 : SNA송신 비동기 응답거래시 수신거래코드를 EAI에서 매핑함 (20190522) + String srcAdapterGroupName = reqEaiMsg.getSngSysItfTp(); + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(srcAdapterGroupName); + String inAdapterMsgType = MessageType.ASC; + if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_FROMTAS.equals(reqEaiMsg.getTranType()) + && inAdptGrpVO == null) { + logger.info(guidLogPrefix + "- TAS 기동거래 [" + srcAdapterGroupName + "] = " + MessageType.ASC); + } else { + if (inAdptGrpVO == null) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF003"; + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + "(어댑터그룹 미등록/미사용 - " + + srcAdapterGroupName + ")"; + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + inAdapterMsgType = inAdptGrpVO.getMessageType(); + } + } + + public void printExceptionMessage(Exception e) { + // Exception e = this.context.getExceptionInfo().getException(); + if (logger.isError()) + logger.error(guidLogPrefix + "ExceptionPath : " + e.getMessage(), e); + } + + public boolean isSourceAsync() { + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + return true; + } else { + return false; + } + } + + public void callExceptionHandler() { + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + String inAdapterMsgType = inAdptGrpVO.getMessageType(); + if (EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + byte[] asc = CodeConversion.meToMixedAsc(bizData.getBytes()); + try { + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.reqEaiMsg.getStandardMessage().setBizData(new String(asc), inboundCharset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + } + ExceptionHandler.handle(this.reqEaiMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + "ExceptionHandler Call Error", e); + } + } + + public boolean isRealCall() { + if (this.callProp != null) { + String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); + if (mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { + logger.warn(guidLogPrefix + "Warming Up Called"); + return false; + } else { + return true; + } + } else { + return true; + } + } + +// private String getAdapterType(String adapterGroupName) { +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); +// return adptGrpVO.getType(); +// } + + public void setGUID() throws Exception { + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + + if ((!(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) + && !(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp))) + || ((com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) + && (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) + && EAIMessageKeys.SYNC_SVC.equals(psvItfTp)))) { + String prcssRtdTranCd = mapper.getReturnServiceId(standardMessage); + + if (prcssRtdTranCd != null && prcssRtdTranCd.length() >= 14) { + String cicsTrncd = prcssRtdTranCd.substring(0, 4); + String telgmRecvTranCd = prcssRtdTranCd.substring(4, 14); + mapper.setServiceId(standardMessage, telgmRecvTranCd); + } else { + if (logger.isInfo()) { + logger.info(guidLogPrefix + "- PrcssRtdTranCd Length < 14 [" + prcssRtdTranCd + "]"); + } + } + } + + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) + && (STDMessageKeys.RECOVER_YN_YES + .equals(getRecoverYn(this.reqEaiMsg)) ) ) { + String reqOgtranGuIdNo = getOrgGuid(this.reqEaiMsg); + mapper.setOrgGuid(standardMessage, reqOgtranGuIdNo); + if (logger.isInfo()) { + logger.info(guidLogPrefix + " OgtranGuIdNo 복원 " + this.reqEaiMsg.getSvcOgNo() + " OgtranGuIdNo [" + + mapper.getOrgGuid(standardMessage) + "]"); + } + } + } +} diff --git a/src/main/java/com/eactive/eai/flowcontroller/CompMRFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/CompMRFCProcess.java new file mode 100644 index 0000000..44135b6 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/CompMRFCProcess.java @@ -0,0 +1,919 @@ +//package com.eactive.eai.flowcontroller; +// +//import com.bea.control.ServiceBrokerControl; +//import com.bea.jpd.JpdContext; +//import com.bea.wli.jpd.CallbackInterface; +//import com.eactive.eai.common.EAIKeys; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.message.*; +//import com.eactive.eai.common.routing.IFRouter; +//import com.eactive.eai.common.routing.RoutingVO; +//import com.eactive.eai.common.util.Logger; +//import com.eactive.eai.common.util.MessageUtil; +//import com.eactive.eai.util.JpdExceptionUtil; +//import com.eactive.eai.adapter.Keys; +//import com.eactive.eai.common.EAITable; +//import com.eactive.eai.common.exception.ExceptionHandler; +//import com.eactive.eai.common.kesa.KESAMessage; +//import com.eactive.eai.common.routing.RoutingManager; +//import com.eactive.eai.transformer.function.util.CodeConversion; +//import com.eactive.eai.transformer.transform.TransformManager; +//import java.util.HashMap; +//import java.util.Vector; +//import com.bea.wli.common.Protocol; +//import com.eactive.eai.control.LogSender; +//import com.eactive.eai.control.Transform; +//import com.eactive.eai.common.kbmessage.*; +// +///** +// * @jpd:process process:: +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * :: +// */ +// +//@Protocol(httpSoap=false) +//@com.bea.wli.jpd.Process(process = " "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+"") +//public class CompMRFCProcess implements com.bea.jpd.ProcessDefinition +//{ +// public java.lang.Object reqOutMsg; +// +// public int nextSvcSeq; +// +// public String tranName; +// +// public java.lang.Object outObject; +// +//// public java.lang.Object[] scrObjects; +// +// public java.lang.String comTranName; +// +// public java.lang.String kesaCd; +// public int logPssSeq; +// +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// public java.util.Properties callProp; +// +// public EAIMessage resEaiMsg; +// +// public EAIMessage compEaiMsg; +// +// public EAIMessage compResEaiMsg; +// +// public com.eactive.eai.common.message.EAIMessage reqEaiMsg; +// +// public int svcMsgSize; //서비스 메시지 수 +// +// public int callCount; //아웃바운드가 호출된 카운트 +// +// public int count; //보상처리 거래 카운트 +// +// public int resultCount; //요청 응답 메시지와 변환을 위한 레이아웃 목록 배열의 인덱스 +// +// public int compListIdx; //보상처리 거래 등록 배열의 인덱스 +// +// public int[] compList; //보상거래 처리가 등록된 서비스 목록 +// +// public String reqUUID; +// +// public String keyMgtMsgVl ; +// +// public boolean existNextSvcMsg; +// +// public String[] reqLayoutNames; //처리된 결과와 요청 메시지를 병합변환 하기 위한 레이아웃 리스트 +// +// public java.lang.Object[] reqScrObjects; //처리된 결과와 요청 메시지를 병합변환 하기 위한 데이터 리스트 +// +// public java.lang.Object[] transSourceMsg; //실제 호출된 Outbound 수 만큼의 소스 메시지를 저장하기 위한 리스트 +// +// public java.lang.String[] transLayoutNames; +// +// private final static String OUTBOUND_FC_TYPE = "F"; +// +// public boolean isFC; //마지막 서비스 메시지가 FC인지 설정하는 플래그 +// +// public HashMap resultScrLayouts; +// +// public int sourceCount; +// +// /** +// * for Server Log Level - by kscheon +// * start +// */ +// static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); +// private int svrLogLevel; +// private static ThreadLocal local = new ThreadLocal(); //경과시간 동기화를 위한 ThreadLocal +// /** +// * for Server Log Level - by kscheon +// * end +// */ +// +// static final long serialVersionUID = 1L; +// +// @com.bea.wli.jpd.Callback() +// public Callback callback; +// +// /* +// * 이 주석 위의 영역에는 디자인 뷰에서 만든 변수 선언이 포함되어 있습니다. +// * 이 주석 아래의 영역에는 디자인 뷰에서 만든 컨트롤 선언이 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 완전히 지원됩니다. +// * 경고: 애플리케이션에서 이미 사용하고 있는 프로세스 변수와 컨트롤 선언을 변경하는 +// * 경우 사용 중인 모든 위치에서 해당 선언을 업데이트하지 않으면 애플리케이션에서 +// * 오류가 발생할 수 있습니다. +// */ +// +// /** +// * @common:context +// */ +// @com.bea.wli.jpd.Context() +// JpdContext context; //(..컨트롤 삽입 표식 - 이 라인을 수정하지 마십시오.) +// +// /* +// * 이 주석 아래의 영역에는 프로세스 언어의 통신 노드에서 참조하는 java 메소드가 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 부분적으로 지원됩니다. +// * 경고: 메소드 본문에 코드를 추가할 수 있지만 보호 섹션 블록 주석의 외부 +// * 합니다. 이 주석 내의 코드를 수정하면 이 코드를 생성한 디자인 뷰 빌더에서 +// * 정보를 볼 수 없습니다. +// */ +// +// +// public EAIMessage clientReturn() +// { +// +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * start +// */ +// if(svrLogLevel >= 1) { +// try{ +// long msgSndTm = System.currentTimeMillis(); +// +// Long threadData = (Long)local.get(); +// long processTm = msgSndTm - threadData.longValue(); +// if (esbLogger.isInfo()) esbLogger.info("CompMRFCProcess] End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); +// } catch (Exception e) { +// } +// } +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * end +// */ +// +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // return +// return resEaiMsg; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// +// +// +// public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // parameter assignment +// this.reqEaiMsg = reqEaiMsg; +// this.callProp = callProp; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// +// if(this.reqEaiMsg == null) return; +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * start +// */ +// svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); +// +// +// if(svrLogLevel >= 1) { +// try{ +// long msgRcvTm = System.currentTimeMillis(); +// local.set(new Long(msgRcvTm)); +// +// if (esbLogger.isInfo()) esbLogger.info("CompMRFCProcess] started... - EAI Server Log Level is INFO"); +// }catch(Exception e){ +// } +// } +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * end +// */ +// +// } +// +// public void ifRouterProcess4() throws Exception +// { +// logger.debug("CompMRFCProcess] 보상거래를 호출합니다"); +// String compEaisvcCd = this.reqEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd(); +// Object[] compObj = new Object[1]; +// if (compEaisvcCd !=null) { +// try { +// compEaiMsg = EAIMessageManager.getInstance().getEAIMessage(compEaisvcCd); +// compEaiMsg.setSvcOgNo(reqUUID); +// compEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// +//// compEaiMsg.setBizMsg(this.reqEaiMsg.getBizMsg()); +// compObj[0] = reqScrObjects[0]; +// compEaiMsg.setBizMsg(compObj); +// +// compEaiMsg = MessageUtil.makeCompEAIMessage(compEaiMsg, reqEaiMsg); +// +// compResEaiMsg = compEaiMsg; +// callProp.setProperty(EAIKeys.CALL_COMP_KEY, EAIKeys.CALL_COMP_VALUE); //보상거래 프로퍼티 설정 +// callProp.setProperty(EAIKeys.CALL_COMP_SVC_SEQ, ""+this.reqEaiMsg.getSvcPssSeq()); +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFMR005"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// //this.resEaiMsg.setRspErrCd(rspErrorCode); +// // this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// //throw new RuntimeException(rspErrorCode); +// } +// } else { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFMR006"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] "+rspErrorMsg); +// // this.resEaiMsg.setRspErrCd(rspErrorCode); +// // this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// try{ +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.compResEaiMsg = IFRouter.process(this.compEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFMR007"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.compResEaiMsg.setRspErrCd(rspErrorCode); +// this.compResEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// +// } +// logger.debug("CompMRFCProcess] 보상거래를 호출을 마칩니다."); +// } +// +// public void transformCtrlTransformComp() throws Exception +// { +// try { +// this.tranName = this.reqEaiMsg.getSvcMsg(svcMsgSize -1).getBsRspCnvMsgID(); +// logger.debug("CompMRFCProcess] 정상응답 변환을 위한 변환 이름 - "+ tranName); +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.outObject = Transform.transformComp(this.kesaCd, true, this.tranName, this.transSourceMsg, this.transLayoutNames); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFMR004"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorCode); +// } +// } +// +// public void ifRouterProcess() throws Exception +// { +// logger.debug("CompMRFCProcess] 아웃바운드를 호출합니다. - " +this.reqEaiMsg.getCurrentSvcMsg().getOutbRtnNm()); +// try{ +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getCurrentSvcMsg().getSvcPssSeq(); +// String rspErrorCode = "RECEAIFMR002"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// //throw new Exception(rspErrorCode); +// } +// +// logger.debug("CompMRFCProcess] 아웃바운드를 호출 수행을 마칩니다.."); +// } +// +// public void transformCtrlTransformComp1() throws Exception +// { +// logger.debug("CompMRFCProcess] FC 타입에 대한 다음메시지 변환을 수행합니다. "); +// tranName = this.reqEaiMsg.getCurrentSvcMsg().getCnvMsgID(); +// reqScrObjects[1] = this.resEaiMsg.getBizMsg()[0]; +// //layerNames[0]의 데이터는 이전 처리된 서비스메시지의 변환에서 추출함 - init 메소드에서 설정 했음 +// +// this.resEaiMsg.setRspErrCd(EAIMessageKeys.EAI_DEFAULT_CODE); +// +// try{ +// reqLayoutNames[1] = getLayoutName (this.resEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID(), this.resEaiMsg.getCurrentSvcMsg().getBsRspCnvEn()); +// if(logger.isDebug()) { +// logger.debug("CompMRFCProcess] this.resEaiMsg.getCurrentSvcMsg().getSvcPssSeq() = " +this.resEaiMsg.getSvcPssSeq()); +// logger.debug("CompMRFCProcess] reqLayoutNames[0] = " +reqLayoutNames[0]); +// logger.debug("CompMRFCProcess] reqLayoutNames[1] = " +reqLayoutNames[1]); +// } +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFMR009"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// } +// try { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.reqOutMsg = Transform.transformComp(this.kesaCd, true, this.tranName, this.reqScrObjects, this.reqLayoutNames); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFMR011"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// } +// +// callCount++; +// } +// +// public void ifRouterProcess1() throws Exception +// { +// logger.debug("CompMRFCProcess] 아웃바운드를 호출합니다. - " +this.reqEaiMsg.getCurrentSvcMsg().getOutbRtnNm()); +// +// try{ +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getCurrentSvcMsg().getSvcPssSeq(); +// String rspErrorCode = "RECEAIFMR002"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// //throw new Exception(rspErrorCode); +// } +// +// logger.debug("CompMRFCProcess] 아웃바운드를 호출 수행을 마칩니다.."); +// } +// +// public void ifRouterProcess11() throws Exception +// { +// logger.debug("CompMRFCProcess] 아웃바운드를 호출합니다. - " +this.reqEaiMsg.getCurrentSvcMsg().getOutbRtnNm()); +// +// try{ +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getCurrentSvcMsg().getSvcPssSeq(); +// String rspErrorCode = "RECEAIFMR002"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// //throw new Exception(rspErrorCode); +// } +// +// logger.debug("CompMRFCProcess] 아웃바운드를 호출 수행을 마칩니다.."); +// } +// +// @CallbackInterface() +// public interface Callback extends ServiceBrokerControl //(..영역 끝 표식 - 이 라인을 수정하지 마십시오.) +// { +// } +// +// /* +// * 이 주석 아래에 삽입한 코드는 디자인 뷰에서 만든 수행 또는 조건 노드에 해당하는 +// * 메소드용입니다. +// * +// * 여기에서 코드를 수정하거나 새로 추가하십시오. +// */ +// +// +// +// public boolean checkServiceMsgSize() +// { +// // Outbound Error일 경우 +// if( MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) && +// reqEaiMsg.getSvcMsgs().size() > 1 ) { +// return true; +// } +// else { +// return false; +// } +// } +// +// +// public boolean isOutboundCall() +// { +// return true; +// } +// +// +// public void init() throws Exception +// { +// this.resEaiMsg = this.reqEaiMsg; +// +// callCount = 1; +// count = 0; +// compListIdx = 0; +// resultCount = 0; +// sourceCount = 0; +// +// existNextSvcMsg = true; +// isFC = false; +// +// this.reqUUID = this.reqEaiMsg.getSvcOgNo(); //보상거래에 원래의 UUID 설정을 위해 저장 +// +// //----------------------------------------------- +// // KBMessage 표준으로 변경함 2008.05.08 +// //----------------------------------------------- +// //this.kesaCd = this.reqEaiMsg.getKesaMsg().getCService(); +// this.kesaCd = this.reqEaiMsg.getKbMsg().getKBCommon().getTelgmRecvTranCd(); +// //----------------------------------------------- +// this.keyMgtMsgVl = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); +// +// try { +// this.svcMsgSize = this.reqEaiMsg.getSvcMsgs().size(); +// }catch (Exception e) { +// logger.error ("CompMRFCProcess] 요청 메시지에서 서비스메시지를 가져올 수 없습니다."); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFMR001"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } +// TransformManager manager = null; +// try{ +// manager = TransformManager.getManager(); +// com.eactive.eai.transformer.transform.Transform transform = manager.getTransform(this.reqEaiMsg.getCurrentSvcMsg().getCnvMsgID()); +// reqLayoutNames = new String[2]; //요청메시지와 응답메시지 변환을 위한 소스 레이아웃 +// reqLayoutNames[0] = transform.getSourceLayout(0).getName(); +// logger.debug("CompMRFCProcess] layerNames[0] - "+reqLayoutNames[0]); +// +// reqScrObjects = new Object[2]; +// reqScrObjects[0] = this.reqEaiMsg.getBizMsg()[0]; +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFMR009"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// } +// +// try{ +// String outName = this.reqEaiMsg.getSvcMsg(svcMsgSize-1).getOutbRtnNm(); +// RoutingManager rm = RoutingManager.getInstance(); +// RoutingVO vo = rm.getRoutingVO(outName); +// String layerDstcd = vo.getLayerDstcd(); +// +// if (!OUTBOUND_FC_TYPE.equals(layerDstcd) ) { +// logger.error("CompMRFCProcess] 결과 메시지를 변환하기 위한 서비스 메시지가 등록되어 있지 않습니다."); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFMR012"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorCode); +// } else { +// this.resultScrLayouts = new HashMap(); +// +// String resultTransform = this.reqEaiMsg.getSvcMsg(svcMsgSize-1).getBsRspCnvMsgID(); +// +// manager = TransformManager.getManager(); +// com.eactive.eai.transformer.transform.Transform transform = manager.getTransform(resultTransform); +// String sourceLayout = ""; +// +// if (transform == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = resultTransform; +// String rspErrorCode = "RECEAIFMR008"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } else { +// sourceCount = transform.getSourceLayoutCount(); +// transSourceMsg = new Object[sourceCount]; +// transLayoutNames = new String[sourceCount]; +// +// for (int i=0; i 0 ) { +// if (compListIdx == count) { +// logger.debug("CompMRFCProcess] 실행할 보상거래가 없습니다.- compListIdx == count [ " +compListIdx + " ] "); +// return false; +// }else if (this.compList[count] >0) { //보상거래 처리가 등록된 서비스 메시지 이면 보상거래 처 +// logger.debug("CompMRFCProcess] 실행할 보상거래가 있습니다. [ this.compList[" +count+" ] - "+ this.compList[count]); +// this.reqEaiMsg.setSvcPssSeq(this.compList[count]); //보상거래를 위해 처리된 순서대로 서비스메시지를 설정 +// count++; +// return true; +// } else { +// logger.debug("CompMRFCProcess] 실행할 보상거래가 없습니다. [ " + this.compList[count] + "- " +count+" ] "); +// return false; +// } +// +// } else { +// logger.debug("CompMRFCProcess] 실행할 보상거래가 없습니다."); +// return false; +// } +// +// } +// +// public boolean existNextSvc() +// { +// logger.debug("CompMRFCProcess] 다음 서비스 메시지를 확인합니다. ." ); +// if (!existNextSvcMsg) { +// logger.debug("CompMRFCProcess] 호출할 다음 서비스 메시지가 없습니다." ); +// return false; +// } +// logger.debug("CompMRFCProcess] callCount : "+callCount); +// if (callCount == this.svcMsgSize){ //MR의 경우 마지막 서비스 메시지는 결과메시지를 설정함 +// return false; +// } +// else { +// this.reqEaiMsg.setSvcPssSeq(callCount); +// this.reqEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// return true; +// } +// } +// +// +// public void setErrorMessage() throws Exception +// { +// logger.debug("CompMRFCProcess ] 오류 응답 메시지를 수신했습니다. "+ this.resEaiMsg.getBizMsg()[0].toString()); +// +// } +// +// public void setResponseMessage() throws Exception +// { +// logger.debug("CompMRFCProcess ] 정상 응답 메시지를 수신했습니다. "+ this.resEaiMsg.getBizMsg()[0].toString()); +// Object[] obj = new Object[1]; +// obj[0] = this.outObject; +// this.resEaiMsg.setBizMsg(obj); +// this.resEaiMsg.setSvcPssSeq(this.svcMsgSize); +// this.resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// } +// +// +// public boolean isBsResponse() +// { +// // 업무오류와 정상코드가 동일하므로 제거해야함 : 2008.06.03 +// //if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) || EAIMessageKeys.BWK_ERRMSG_CODE.equals(resEaiMsg.getRspErrCd())){ +// if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())){ +// logger.debug("CompMRFCProcess ] 오류 응답 메시지를 수신했습니다. "); +// return false; +// } +// else { +// logger.debug("CompMRFCProcess ] 정상 응답 메시지를 수신했습니다. "); +// return true; +// } +// } +// +// private String getLayoutName (String transformName, String yn) throws Exception{ +// TransformManager manager = TransformManager.getManager(); +// com.eactive.eai.transformer.transform.Transform transform = manager.getTransform(transformName); +// String layoutName = ""; +// if (transform == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = transformName; +// String rspErrorCode = "RECEAIFMR008"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } else { +// if(logger.isDebug()) { +// logger.debug("CompMRFCProcess] transformName =" + transformName); +// logger.debug("CompMRFCProcess] yn =" + yn ); +// } +// if("1".equals(yn)) { +// layoutName = transform.getTargetLayout().getName(); +// } +// else { +// layoutName = transform.getSourceLayout(0).getName(); +// } +// } +// +// return layoutName; +// +// } +// +// +// public void setCompensationResult() throws Exception +// { +// //보강거래 처리에서 오류가 발생한경우에 대한 처리절차 추가 필요 +// if(!MessageUtil.checkRspErrCd(this.compResEaiMsg.getRspErrCd())) { //보상거래 처리시 오류가 발생한 경우 +// logger.error("CompMRFCProcess ] 보상거래 처리시 오류가 발생했습니다 - " + this.compResEaiMsg.getRspErrCd() +" - " + this.compResEaiMsg.getRspErrMsg()); +// } else { +// logger.info ( "CompMRFCProcess ] 보상거래 처리가 정상적으로 처리되었습니다. - [ "+ this.compEaiMsg.getEAISvcCd()+" ] "); +// } +// +// } +// +// public boolean isFCType() +// { +// logger.debug("CompMRFCProcess ] 다음 서비스 메시지가 FC타입인지 확인합니다."); +// String outName = this.reqEaiMsg.getCurrentSvcMsg().getOutbRtnNm(); +// RoutingManager rm = RoutingManager.getInstance(); +// RoutingVO vo = rm.getRoutingVO(outName); +// String layerDstcd = vo.getLayerDstcd(); +// +// if (OUTBOUND_FC_TYPE.equals(layerDstcd) ) { +// if (outName.equals(this.reqEaiMsg.getFlwCntlRtnNm())){ //자기 자신의 FC와 동일한지 확인 +// logger.debug("CompMRFCProcess ] 다음 서비스 메시지가 FC타입입니다.."); +// this.isFC = true; +// return true; +// } +// else { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFMR010"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// logger.error("CompMRFCProcess ] FC 설정이 잘못 되었습니다."); +// return false; +// } +// } +// else { +// logger.debug("CompMRFCProcess ] 다음 서비스 메시지가 FC타입이 아닙니다."); +// return false; +// } +// } +// +// +// public boolean isCallOutBound() +// { +// if (isFC) { +// // 업무오류와 정상코드가 동일하므로 제거해야함 : 2008.06.03 +// //if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) || EAIMessageKeys.BWK_ERRMSG_CODE.equals(resEaiMsg.getRspErrCd())){ +// if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())){ +// logger.debug("CompMRFCProcess ] 다음 요청메시지 변환 중 오류가 발생했습니다. "); +// existNextSvcMsg = false; +// return false; +// } +// else { +// logger.debug("CompMRFCProcess ] 다음 요청메시지 변환이 정상 적으로 수행 되었습니다."); +// Object obj[] = new Object[1]; +// obj[0] = reqOutMsg; +// this.reqEaiMsg.setBizMsg(obj); +// +// this.reqEaiMsg.setSvcPssSeq(this.reqEaiMsg.getCurrentSvcMsg().getNxtSvcPssSeq()); +// this.reqEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// +// isFC = false; +// return true; +// } +// } else { +// return true; +// } +// } +// +// +// +// public void setResMessage() throws Exception +// { +// logger.debug("CompMRFCProcess] 응답메시지를 응답 메시지 리스트에 설정합니다. - [ "+ (callCount) +" ] 번째 호출입니다." ); +// +// try { +// +// // 업무오류와 정상코드가 동일하므로 제거해야함 : 2008.06.03 +// //if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) || EAIMessageKeys.BWK_ERRMSG_CODE.equals(resEaiMsg.getRspErrCd())){ +// if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())){ +// logger.debug("CompMRFCProcess] 오류응답 메시지를 수신했습니다. "); +// existNextSvcMsg = false; +// +// //String tranClassify = this.resEaiMsg.getKesaMsg().getCTranClassify(); +// String telgmDmndDstcd = this.resEaiMsg.getKbMsg().getKBHeader().getTelgmDmndDstcd(); +// if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { +// +// //if (EAIKeys.TR_RES.equals(tranClassify) || EAIKeys.TR_CANCEL_RES.equals(tranClassify) || EAIKeys.TR_NET_RES.equals(tranClassify) || EAIKeys.TR_SYSTEMINFO_RES.equals(tranClassify)){ +// if(KBMessageKeys.TELGMDMNDDSTCD_RECV.equals(telgmDmndDstcd)) { +// if (this.reqEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd() != null && this.reqEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd().length() > 0) { +// if (this.compList == null ){ +// logger.debug("CompMRFCProcess ] 보상거래를 위한 목록을 생성합니다."); +// this.compList = new int[svcMsgSize]; +// } +// this.compList[compListIdx] = this.reqEaiMsg.getCurrentSvcMsg().getSvcPssSeq(); +// logger.debug("CompMRFCProcess ] 보상거래를 위한 목록에 등록 합니다.- " +this.reqEaiMsg.getCurrentSvcMsg().getSvcPssSeq()); +// compListIdx++; +// } +// } +// +// } +// } else { +// +// if (this.reqEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd() != null && this.reqEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd().length() > 0) { +// if (this.compList == null ){ +// logger.debug("CompMRFCProcess] 보상거래를 위한 목록을 생성합니다."); +// this.compList = new int[svcMsgSize]; +// } +// this.compList[compListIdx] = this.reqEaiMsg.getCurrentSvcMsg().getSvcPssSeq(); +// logger.debug("CompMRFCProcess] 보상거래를 위한 목록에 등록 합니다.- " +this.reqEaiMsg.getCurrentSvcMsg().getSvcPssSeq()); +// compListIdx++; +// } +// +// String layoutName = getLayoutName (reqEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID(), reqEaiMsg.getCurrentSvcMsg().getBsRspCnvEn()); +// +// if (this.resultScrLayouts.get(layoutName) != null ){ +// if(logger.isDebug()) logger.debug("CompMRFCProcess] 응답메시지 설정 - "+ layoutName); +// transSourceMsg[resultCount] = this.resEaiMsg.getBizMsg()[0]; +// transLayoutNames[resultCount] = layoutName; +// resultCount++; +// } +// } +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFMR003"; +// e.printStackTrace(); +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// //throw new Exception(rspErrorCode); +// } +// callCount++; //호출카운트 증가 +// } +//} diff --git a/src/main/java/com/eactive/eai/flowcontroller/CompRRFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/CompRRFCProcess.java new file mode 100644 index 0000000..f7661d5 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/CompRRFCProcess.java @@ -0,0 +1,961 @@ +package com.eactive.eai.flowcontroller; +//package com.eactive.eai.flowcontroller; +// +//import com.bea.control.ServiceBrokerControl; +//import com.bea.jpd.JpdContext; +//import com.bea.data.RawData; +//import com.bea.wli.control.broker.MessageBroker; +//import com.bea.wli.jpd.Callback; +//import com.bea.wli.jpd.CallbackInterface; +//import com.bea.xml.XmlObjectList; +//import org.apache.beehive.controls.api.bean.Control; +//import org.apache.beehive.controls.api.events.EventHandler; +//import org.apache.xmlbeans.XmlObject; +//import com.eactive.eai.adapter.AdapterGroupVO; +//import com.eactive.eai.adapter.AdapterManager; +//import com.eactive.eai.adapter.AdapterVO; +//import com.eactive.eai.common.EAIKeys; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.message.*; +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.routing.IFRouter; +//import com.eactive.eai.common.routing.RoutingVO; +//import com.eactive.eai.common.util.Logger; +//import com.eactive.eai.common.util.MessageUtil; +//import com.eactive.eai.util.JpdExceptionUtil; +//import com.eactive.eai.adapter.Keys; +//import com.eactive.eai.common.EAITable; +//import com.eactive.eai.common.exception.ExceptionHandler; +//import com.eactive.eai.common.kesa.KESAMessage; +//import com.eactive.eai.common.routing.RoutingManager; +//import com.eactive.eai.transformer.function.util.CodeConversion; +//import com.eactive.eai.transformer.transform.TransformManager; +//import java.util.HashMap; +//import java.util.Iterator; +//import com.bea.wli.common.Protocol; +//import com.eactive.eai.control.LogSender; +//import com.eactive.eai.control.Transform; +//import com.eactive.eai.common.kbmessage.*; +//import com.eactive.eai.common.bpa.RuleManager; +// +///** +// * @jpd:process process:: +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * :: +// */ +// +//@Protocol(httpSoap=false) +//@com.bea.wli.jpd.Process(process = " "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+"") +//public class CompRRFCProcess implements com.bea.jpd.ProcessDefinition +//{ +// public java.lang.String[] layerNames; +// +// public int nextSvcSeq; +// +// public String tranName; +// +// public java.lang.Object outObject; +// +// public java.lang.Object[] scrObjects; +// +// public java.lang.String comTranName; +// +// public java.lang.String kesaCd; +// +// public int logPssSeq; +// +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// public java.util.Properties callProp; +// +// public EAIMessage resEaiMsg; +// +// public EAIMessage compEaiMsg; //보상거래 요청 메시지 +// +// public EAIMessage compResEaiMsg; //보상거래 응답 메시지 +// +// public Object[] orgBizData; //보상거래시 요청할 원기동 메시지 +// +// public com.eactive.eai.common.message.EAIMessage reqEaiMsg; +// +// //public java.lang.String nextSvcScr; +// +// public boolean isFistSvcMsg; +// +// public boolean existNextSvcMsg; //다음 서비스 메시지 유무 +// +// public int svcMsgSize; //서비스 메시지 수 +// +//// public int[] calledSvcMsgSeq; //수행되었던 서비스메시지 처리번호 +// +// public int callCount; //보상거래 등록 카운트 +// +// public int count; //보상처리 거래 카운트 +// +// public String reqUUID; +// +// public int[] compList ; //보상거래가 필요한 서비스메시지 처리번호 목록 +// +// public String keyMgtMsgVl ; +// +// public boolean isFinalFC; //마지막 서비스 메시지가 FC인지 설정하는 플래그 +// +// public boolean isFC; +// +// private final static String OUTBOUND_FC_TYPE = "F"; +// +// public boolean nonNextSvcMsg; +// +// //public int sourceCount; +// +// //public java.lang.Object[] transSourceMsg; //실제 호출된 Outbound 수 만큼의 소스 메시지를 저장하기 위한 리스트 +// +// //public java.lang.String[] transLayoutNames; +// +// public int resultCount; +// +// /** +// * for Server Log Level - by kscheon +// * start +// */ +// static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); +// private int svrLogLevel; +// private static ThreadLocal local = new ThreadLocal(); //경과시간 동기화를 위한 ThreadLocal +// /** +// * for Server Log Level - by kscheon +// * end +// */ +// +// static final long serialVersionUID = 1L; +// +// @com.bea.wli.jpd.Callback() +// public Callback callback; +// +// /* +// * 이 주석 위의 영역에는 디자인 뷰에서 만든 변수 선언이 포함되어 있습니다. +// * 이 주석 아래의 영역에는 디자인 뷰에서 만든 컨트롤 선언이 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 완전히 지원됩니다. +// * 경고: 애플리케이션에서 이미 사용하고 있는 프로세스 변수와 컨트롤 선언을 변경하는 +// * 경우 사용 중인 모든 위치에서 해당 선언을 업데이트하지 않으면 애플리케이션에서 +// * 오류가 발생할 수 있습니다. +// */ +// +// +// /** +// * @common:context +// */ +// @com.bea.wli.jpd.Context() +// JpdContext context; //(..컨트롤 삽입 표식 - 이 라인을 수정하지 마십시오.) +// +// /* +// * 이 주석 아래의 영역에는 프로세스 언어의 통신 노드에서 참조하는 java 메소드가 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 부분적으로 지원됩니다. +// * 경고: 메소드 본문에 코드를 추가할 수 있지만 보호 섹션 블록 주석의 외부 +// * 합니다. 이 주석 내의 코드를 수정하면 이 코드를 생성한 디자인 뷰 빌더에서 +// * 정보를 볼 수 없습니다. +// */ +// +// +// public EAIMessage clientReturn() +// { +// +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * start +// */ +// if(svrLogLevel >= 1) { +// try{ +// long msgSndTm = System.currentTimeMillis(); +// +// Long threadData = (Long)local.get(); +// long processTm = msgSndTm - threadData.longValue(); +// if (esbLogger.isInfo()) esbLogger.info("CompRRFCProcess] End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); +// } catch (Exception e) { +// } +// } +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * end +// */ +// +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // return +// return resEaiMsg; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// +// +// +// public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // parameter assignment +// this.reqEaiMsg = reqEaiMsg; +// this.callProp = callProp; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// +// if(this.reqEaiMsg == null) return; +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * start +// */ +// svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); +// +// +// if(svrLogLevel >= 1) { +// try{ +// long msgRcvTm = System.currentTimeMillis(); +// local.set(new Long(msgRcvTm)); +// +// if (esbLogger.isInfo()) esbLogger.info("CompRRFCProcess] started... - EAI Server Log Level is INFO"); +// }catch(Exception e){ +// } +// } +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * end +// */ +// +// } +// +// public void ifRouterProcess4() throws Exception +// { +// logger.debug("CompRRFCProcess] 보상거래를 호출합니다"); +// String compEaisvcCd = this.reqEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd(); +// if (compEaisvcCd !=null) { +// try { +// compEaiMsg = EAIMessageManager.getInstance().getEAIMessage(compEaisvcCd); +// compEaiMsg.setSvcOgNo(reqUUID); +// compEaiMsg.setBizMsg(orgBizData); +// compEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// +// compEaiMsg = MessageUtil.makeCompEAIMessage(compEaiMsg, reqEaiMsg); +// +// compResEaiMsg = compEaiMsg; +// callProp.setProperty(EAIKeys.CALL_COMP_KEY, EAIKeys.CALL_COMP_VALUE); //보상거래 프로퍼티 설정 +// callProp.setProperty(EAIKeys.CALL_COMP_SVC_SEQ, ""+this.reqEaiMsg.getSvcPssSeq()); +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFRR004"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// //this.resEaiMsg.setRspErrCd(rspErrorCode); +// // this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// } else { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFRR005"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] "+rspErrorMsg); +// // this.resEaiMsg.setRspErrCd(rspErrorCode); +// // this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// try { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.compResEaiMsg = IFRouter.process(this.compEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFRR006"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.compResEaiMsg.setRspErrCd(rspErrorCode); +// this.compResEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// +// } +// +// logger.debug("CompRRFCProcess] 보상거래를 호출을 마칩니다."); +// } +// +// +// public void ruleManagerCtrlGetNextServiceSeq() throws Exception +// { +// logger.debug("CompRRFCProcess] 다음서비스메시지를 추출합니다."); +// +// Object[] objs = new Object[1]; +// objs[0] = this.resEaiMsg.getBizMsg()[0]; +// this.reqEaiMsg.setBizMsg(objs); +// +// try{ +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.nextSvcSeq = RuleManager.getNextServieSeq(this.reqEaiMsg); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFRR003"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// +// existNextSvcMsg = false; //다음 서비스메시지 추출에서 오류가 발생하면 반복 루틴을 종료하도록 한다. +// } +// +// if (this.nextSvcSeq > 0) { +// +// this.reqEaiMsg.setSvcPssSeq(this.nextSvcSeq); +// this.reqEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// existNextSvcMsg = true; +// } else if (this.nextSvcSeq == -1){ +// if ( this.reqEaiMsg.getCurrentSvcMsg().getNxtSvcPssSeq() > 0) { +// this.reqEaiMsg.setSvcPssSeq(this.reqEaiMsg.getCurrentSvcMsg().getNxtSvcPssSeq()); +// this.reqEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// existNextSvcMsg = true; +// } else { +// existNextSvcMsg = false; +// } +// } else { +// existNextSvcMsg = false; +// } +// logger.debug("CompRRFCProcess] 다음서비스메시지를 추출 했습니다. - " + existNextSvcMsg); +// } +// +// +// public void transformCtrlTransformComp() throws Exception +// { +// logger.debug("CompRRFCProcess] FC 타입에 대한 다음메시지 변환을 수행합니다. "); +// try { +// if (this.reqEaiMsg.getCurrentSvcMsg().getNxtSvcPssSeq() == 0 ){ +// logger.debug("CompRRFCProcess] 마지막 결과 메시지 변환을 위한 FC 입니다."); +// +// this.isFinalFC = true; +// this.nonNextSvcMsg = true; +// +// tranName = this.reqEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID(); +// } else { +// tranName = this.reqEaiMsg.getCurrentSvcMsg().getCnvMsgID(); +// } +// +// TransformManager manager = TransformManager.getManager(); +// com.eactive.eai.transformer.transform.Transform transform = manager.getTransform(tranName); +// String sourceLayout = ""; +// +// String resTransform = getLayoutName(this.resEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID()); +// +// if (transform == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = tranName; +// String rspErrorCode = "RECEAIFRR008"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] " +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } else { +// int sourceCount = transform.getSourceLayoutCount(); +// +// Object obj = scrObjects[0]; +// String reqlayoutName = layerNames[0]; +// +// scrObjects = new Object[sourceCount]; +// layerNames = new String[sourceCount]; +// +// for (int i=0; i 1 ) { +// return true; +// } +// else { +// return false; +// } +// } +// +// +// public boolean isOutboundCall() +// { +// return true; +// } +// +// +// public void init() throws Exception +// { +// this.resEaiMsg = this.reqEaiMsg; +// existNextSvcMsg = true; +// isFinalFC = false; +// isFC = false; +// nonNextSvcMsg = false; +// isFistSvcMsg = true; +// +// callCount = 0; +// count = 0; +// resultCount = 0; +// +// this.reqUUID = this.reqEaiMsg.getSvcOgNo(); //보상거래에 원래의 UUID 설정을 위해 저장 +// //----------------------------------------------- +// // KBMessage 표준으로 변경함 2008.05.08 +// //----------------------------------------------- +// //this.kesaCd = this.reqEaiMsg.getKesaMsg().getCService(); +// this.kesaCd = this.reqEaiMsg.getKbMsg().getKBCommon().getTelgmRecvTranCd(); +// //----------------------------------------------- +// +// this.orgBizData = new Object[1]; +// orgBizData[0] = this.reqEaiMsg.getBizMsg()[0]; //보상거래의 요청메시지에 원기동의 요청메시지를 설정 +// +// scrObjects = new Object[2]; //요청메시지와 응답메시지 변환을 위한 소스 오브젝트 +// +// this.keyMgtMsgVl = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); +// +// try { +// this.svcMsgSize = this.reqEaiMsg.getSvcMsgs().size(); +// }catch (Exception e) { +// logger.error ("CompRRFCProcess] 요청 메시지에서 서비스메시지를 가져올 수 없습니다."); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFRR001"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// +// } +// +// try{ +// TransformManager manager = TransformManager.getManager(); +// com.eactive.eai.transformer.transform.Transform transform = manager.getTransform(this.reqEaiMsg.getCurrentSvcMsg().getCnvMsgID()); +// layerNames = new String[2]; //요청메시지와 응답메시지 변환을 위한 소스 레이아웃 +// +// layerNames[0] = transform.getSourceLayout(0).getName(); +// scrObjects[0] = this.reqEaiMsg.getBizMsg()[0]; +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFRR008"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// } +// } +// +// public void printExceptionMessage() throws Exception +// { +// Exception e = this.context.getExceptionInfo().getException(); +// if (logger.isError()) logger.error("CompRRFCProcess] ExceptionPath : "+e.getMessage()); +// +// +// } +// +// public boolean isSourceAsync() +// { +// if(EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) ) { +// return true; +// } +// else { +// return false; +// } +// +// } +// +// public boolean isRealCall() +// { +// if(this.callProp != null) { +// String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); +// if(mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { +// logger.debug("CompRRFCProcess] Warming Up Called"); +// return false; +// } +// else { +// return true; +// } +// } +// else { +// return true; +// } +// } +// +// +// public boolean isCompensation() +// { +// //------------------------------ +// // TO-DO +// // 보상거래가 등록된 서비스메시지가 하나라도 있으면 수행 +// //------------------------------ +// logger.debug("CompRRFCProcess] 보상거래 유무를 확인합니다"); +// +// if (this.compList != null ) { //보상거래가 등록된 서비스가 하나라도 있으면 +// logger.debug("CompRRFCProcess] 보상거래가 등록되어 있습니다."); +// return true; +// } +// else { +// return false; +// } +// } +// +// +// public boolean existNextCom() +// { +// //------------------------------ +// // TO-DO +// // 보상거래 서비스코드가 등록된 경우만 실행 +// //------------------------------ +// logger.debug("CompRRFCProcess] 실행할 보상거래가 있는지 확인합니다."); +// if (callCount > 0 ) { +// if (callCount == count) { +// return false; +// } +// else if (this.compList[count] >0) { //보상거래 처리가 등록된 서비스 메시지 이면 보상거래 처리 +// logger.debug("CompRRFCProcess] 실행할 보상거래가 있습니다. [ " +count+" ] - "+ this.compList[count]); +// this.reqEaiMsg.setSvcPssSeq(this.compList[count]); //보상거래를 위해 처리된 순서대로 서비스메시지를 설정 +// count++; +// return true; +// } +// else { +// return false; +// } +// +// } +// else { +// return false; +// } +// } +// +// +// public boolean isNonError() +// { +// // 업무오류와 정상코드가 동일하므로 제거해야함 : 2008.06.03 +// //if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) || EAIMessageKeys.BWK_ERRMSG_CODE.equals(resEaiMsg.getRspErrCd())){ +// if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())){ +// return false; +// } else { +// return true; +// } +// } +// +// public boolean isFirstSvcMsg() +// { +// if (this.svcMsgSize <= 0){ +// logger.error("CompRRFCProcess] 해당 복합거래에 대한 ServiceMessage가 없습니다.- "+reqEaiMsg.getEAISvcCd()); +// } +// if (isFistSvcMsg){ +// isFistSvcMsg = false; +// logger.debug("CompRRFCProcess] 첫번째 서비스 메시지 입니다."); +// return true; +// } else { +// logger.debug("CompRRFCProcess] 첫번째 이후 서비스 메시지 입니다."); +// return false; +// } +// +// } +// +// public boolean existNextSvc() +// { +// return existNextSvcMsg; +// } +// +// +// public void setErrorMessage() throws Exception +// { +// logger.debug("CompRRFCProcess ] 오류 응답 메시지를 수신했습니다. "+ this.resEaiMsg.getBizMsg()[0].toString()); +// } +// +// public void setResponseMessage() throws Exception +// { +// logger.debug("CompRRFCProcess ] 정상 응답 메시지를 수신했습니다. "+ this.resEaiMsg.getBizMsg()[0].toString()); +// +// } +// +// public void setCompensationResult() throws Exception +// { +// //보강거래 처리에서 오류가 발생한경우에 대한 처리절차 추가 필요 +// if(!MessageUtil.checkRspErrCd(this.compResEaiMsg.getRspErrCd())) { //보상거래 처리시 오류가 발생한 경우 +// logger.error("CompRRFCProcess ] 보상거래 처리시 오류가 발생했습니다 - " + this.compResEaiMsg.getRspErrCd() +" - " + this.compResEaiMsg.getRspErrMsg()); +// } else { +// logger.info ( "CompRRFCProcess ] 보상거래 처리가 정상적으로 처리되었습니다. - [ "+ this.compEaiMsg.getEAISvcCd()+" ] "); +// } +// +// } +// +// public boolean isFCType() +// { +// if(existNextSvcMsg){ +// logger.debug("CompRRFCProcess ] 다음 서비스 메시지가 FC타입인지 확인합니다."); +// String outName = this.reqEaiMsg.getCurrentSvcMsg().getOutbRtnNm(); +// RoutingManager rm = RoutingManager.getInstance(); +// RoutingVO vo = rm.getRoutingVO(outName); +// String layerDstcd = vo.getLayerDstcd(); +// +// if (OUTBOUND_FC_TYPE.equals(layerDstcd) ) { +// if (outName.equals(this.reqEaiMsg.getFlwCntlRtnNm())){ //자기 자신의 FC와 동일한지 확인 +// logger.debug("CompRRFCProcess ] 다음 서비스 메시지가 FC타입입니다.."); +// isFC = true; +// return true; +// } +// else { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFRR009"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] " +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// logger.error("CompRRFCProcess ] FC 설정이 잘못 되었습니다."); +// return false; +// } +// } +// else { +// logger.debug("CompRRFCProcess ] 다음 서비스 메시지가 FC타입이 아닙니다."); +// return false; +// } +// } else { +// this.nonNextSvcMsg = true; +// return false; +// } +// } +// +// private String getLayoutName (String transformName) throws Exception{ +// TransformManager manager = TransformManager.getManager(); +// com.eactive.eai.transformer.transform.Transform transform = manager.getTransform(transformName); +// String layoutName = ""; +// if (transform == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = transformName; +// String rspErrorCode = "RECEAIFRR008"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] " +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } else { +// layoutName = transform.getTargetLayout().getName(); +// } +// +// return layoutName; +// +// } +// /* +// private void makeTransformSource() throws Exception { +// +// String outName = this.reqEaiMsg.getCurrentSvcMsg().getOutbRtnNm(); +// RoutingManager rm = RoutingManager.getInstance(); +// RoutingVO vo = rm.getRoutingVO(outName); +// String layerDstcd = vo.getLayerDstcd(); +// +// if (OUTBOUND_FC_TYPE.equals(layerDstcd) ) { +// String resultTransform = this.reqEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID(); +// TransformManager manager = TransformManager.getManager(); +// Transform transform = manager.getTransform(resultTransform); +// +// String reslayout =getLayoutName (this.resEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID()); +// +// if (transform == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = resultTransform; +// String rspErrorCode = "RECEAIFRR010"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompRRFCProcess] " +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +//// throw new RuntimeException(rspErrorCode); +// } else { +// sourceCount = transform.getSourceLayoutCount(); +// transSourceMsg = new Object[sourceCount]; +// transLayoutNames = new String[sourceCount]; +// +// String scrName = ""; +// +// for (int i=0; i 0) { +// if (this.compList == null ){ +// this.compList = new int[svcMsgSize]; +// } +// this.compList[callCount] = this.reqEaiMsg.getCurrentSvcMsg().getSvcPssSeq(); +// logger.debug("CompRRFCProcess] 보상거래를 등록 합니다. - " + this.compList[callCount]); +// callCount++; +// } +// } +// } +// } else { +// if (this.reqEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd() != null && this.reqEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd().length() > 0) { +// if (this.compList == null ){ +// this.compList = new int[svcMsgSize]; +// } +// this.compList[callCount] = this.reqEaiMsg.getCurrentSvcMsg().getSvcPssSeq(); +// logger.debug("CompRRFCProcess] 보상거래를 등록 합니다. - " + this.compList[callCount]); +// callCount++; +// } +// } +// } +//} +// diff --git a/src/main/java/com/eactive/eai/flowcontroller/PCompFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/PCompFCProcess.java new file mode 100644 index 0000000..3f26503 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/PCompFCProcess.java @@ -0,0 +1,360 @@ +package com.eactive.eai.flowcontroller; +//package com.eactive.eai.flowcontroller; +// +//import com.bea.control.ServiceBrokerControl; +//import com.bea.jpd.JpdContext; +//import com.bea.data.RawData; +//import com.bea.wli.control.broker.MessageBroker; +//import com.bea.wli.jpd.Callback; +//import com.bea.wli.jpd.CallbackInterface; +//import com.bea.xml.XmlObjectList; +//import org.apache.beehive.controls.api.bean.Control; +//import org.apache.beehive.controls.api.events.EventHandler; +//import org.apache.xmlbeans.XmlObject; +//import com.eactive.eai.adapter.AdapterGroupVO; +//import com.eactive.eai.adapter.AdapterManager; +//import com.eactive.eai.adapter.AdapterVO; +//import com.eactive.eai.common.EAIKeys; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.message.*; +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.routing.IFRouter; +//import com.eactive.eai.common.routing.RoutingVO; +//import com.eactive.eai.common.util.Logger; +//import com.eactive.eai.common.util.MessageUtil; +//import com.eactive.eai.util.JpdExceptionUtil; +//import com.eactive.eai.adapter.Keys; +//import com.eactive.eai.common.EAITable; +//import com.eactive.eai.common.exception.ExceptionHandler; +//import com.eactive.eai.common.kesa.KESAMessage; +//import com.eactive.eai.transformer.function.util.CodeConversion; +//import javax.transaction.Transaction; +//import weblogic.transaction.TxHelper; +//import com.bea.wli.common.Protocol; +//import com.eactive.eai.control.*; +// +///** +// * @jpd:process process:: +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * :: +// */ +// +//@Protocol(httpSoap=false) +//@com.bea.wli.jpd.Process(process = " "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+" "+"") +//public class PCompFCProcess implements com.bea.jpd.ProcessDefinition +//{ +// public java.io.Serializable outMessage; +// +// public int timeout; +// +// public java.lang.String colId; +// +// public java.lang.String queueName; +// +// public java.lang.String queueConnectName; +// +// public java.lang.String recvData; +// +// public String adptrMsgPtrnCd; // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 +// +// public java.lang.String adapterGroupName; +// +// public int logPssSeq; +// +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// public java.util.Properties callProp; +// +// public EAIMessage resEaiMsg; +// +// public com.eactive.eai.common.message.EAIMessage reqEaiMsg; +// +// /** +// * for Server Log Level - by kscheon +// * start +// */ +// static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); +// private int svrLogLevel; +// private static ThreadLocal local = new ThreadLocal(); //경과시간 동기화를 위한 ThreadLocal +// /** +// * for Server Log Level - by kscheon +// * end +// */ +// +// static final long serialVersionUID = 1L; +// +// @com.bea.wli.jpd.Callback() +// public Callback callback; +// +// /* +// * 이 주석 위의 영역에는 디자인 뷰에서 만든 변수 선언이 포함되어 있습니다. +// * 이 주석 아래의 영역에는 디자인 뷰에서 만든 컨트롤 선언이 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 완전히 지원됩니다. +// * 경고: 애플리케이션에서 이미 사용하고 있는 프로세스 변수와 컨트롤 선언을 변경하는 +// * 경우 사용 중인 모든 위치에서 해당 선언을 업데이트하지 않으면 애플리케이션에서 +// * 오류가 발생할 수 있습니다. +// */ +// +// /** +// * @common:control +// */ +// @Control() +// private com.eactive.eai.flowcontroller.PCompMRFCProcessPControl pCompMRFCProcessCtrl; +// +// +// /** +// * @common:context +// */ +// @com.bea.wli.jpd.Context() +// JpdContext context; //(..컨트롤 삽입 표식 - 이 라인을 수정하지 마십시오.) +// +// /* +// * 이 주석 아래의 영역에는 프로세스 언어의 통신 노드에서 참조하는 java 메소드가 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 부분적으로 지원됩니다. +// * 경고: 메소드 본문에 코드를 추가할 수 있지만 보호 섹션 블록 주석의 외부 +// * 합니다. 이 주석 내의 코드를 수정하면 이 코드를 생성한 디자인 뷰 빌더에서 +// * 정보를 볼 수 없습니다. +// */ +// +// +// public EAIMessage clientReturn() +// { +// +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * start +// */ +// if(svrLogLevel >= 1) { +// try{ +// long msgSndTm = System.currentTimeMillis(); +// +// Long threadData = (Long)local.get(); +// long processTm = msgSndTm - threadData.longValue(); +// if (esbLogger.isInfo()) esbLogger.info("PCompFCProcess] End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); +// } catch (Exception e) { +// } +// } +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * end +// */ +// +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // return +// return resEaiMsg; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// +// +// +// public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // parameter assignment +// this.reqEaiMsg = reqEaiMsg; +// this.callProp = callProp; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// +// if(this.reqEaiMsg == null) return; +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * start +// */ +// svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); +// +// +// if(svrLogLevel >= 1) { +// try{ +// long msgRcvTm = System.currentTimeMillis(); +// local.set(new Long(msgRcvTm)); +// +// if (esbLogger.isInfo()) esbLogger.info("BaseFCProcess] started... - EAI Server Log Level is INFO"); +// }catch(Exception e){ +// } +// } +// /** +// * ServerLog Level이 info인경우 로깅 - by kscheon +// * end +// */ +// +// } +// +// +// public void pCompMRFCProcessCtrlCallService() throws Exception +// { +// try { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.recvData = pCompMRFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM101"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } +// +// } +// +// public void pCompMRFCProcessCtrlCallService1() throws Exception +// { +// logger.debug("PCompFCProcess] PCompMRFCProcess 호출 수행합니다... ["+System.currentTimeMillis()+"]"); +// Transaction t = TxHelper.getTransactionManager().suspend() ; +// +// try{ +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.recvData = pCompMRFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM102"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompFCProcess] PCompMRFCProcess 호출 수행을 마칩니다... ["+System.currentTimeMillis()+"]"); +// TxHelper.getTransactionManager().resume(t); +// +// } +// +// public void jmsQueueReceiverCtrlReceive() throws Exception +// { +// logger.debug("PCompFCProcess] 응답메시지를 수신합니다.... ["+System.currentTimeMillis()+"]"); +// try{ +// JMSQueueReceiver jmsQueueReceiverCtrl = new JMSQueueReceiver(); +// +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.outMessage = jmsQueueReceiverCtrl.receive(this.queueConnectName, this.queueName, this.colId, this.timeout); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM103"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompFCProcess] 응답메시지를 수신했습니다.... ["+System.currentTimeMillis()+"]"); +// } +// +// @CallbackInterface() +// public interface Callback extends ServiceBrokerControl //(..영역 끝 표식 - 이 라인을 수정하지 마십시오.) +// { +// } +// +// /* +// * 이 주석 아래에 삽입한 코드는 디자인 뷰에서 만든 수행 또는 조건 노드에 해당하는 +// * 메소드용입니다. +// * +// * 여기에서 코드를 수정하거나 새로 추가하십시오. +// */ +// +// +// public void init() throws Exception +// { +// logger.debug("PCompFCProcess ] 초기화를 실행합니다."); +// this.resEaiMsg = this.reqEaiMsg; +// +// this.queueConnectName = EAIKeys.PCOMP_CON_FACTORY; +// this.queueName = EAIKeys.PCOMP_RES_QUEUE; +// this.colId = this.reqEaiMsg.getSvcOgNo(); +// timeout = 0; +// +// logger.debug("PCompFCProcess ] 초기화를 실행을 마칩니다."); +// +// } +// +// public void printExceptionMessage() throws Exception +// { +// Exception e = this.context.getExceptionInfo().getException(); +// if (logger.isError()) logger.error("PCompFCProcess] ExceptionPath : "+e.getMessage()); +// +// +// } +// +// public boolean isRealCall() +// { +// if(this.callProp != null) { +// String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); +// if(mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { +// logger.debug("PCompFCProcess] Warming Up Called"); +// return false; +// } +// else { +// return true; +// } +// } +// else { +// return true; +// } +// } +// +// +// public void setResponseMessage() throws Exception +// { +// logger.debug("PCompFCProcess] 응답메시지를 설정합니다....."); +// if(this.outMessage instanceof EAIMessage) { +// this.resEaiMsg = (EAIMessage) this.outMessage; +// } +// else { +// logger.error ("PCompFCProcess] 응답 메시지의 형식이 EAIMessage 가 아닙니다. "); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM104"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorCode); +// } +// logger.debug("PCompFCProcess] 응답메시지를 설정을 마칩니다....."); +// } +//} diff --git a/src/main/java/com/eactive/eai/flowcontroller/PCompMRFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/PCompMRFCProcess.java new file mode 100644 index 0000000..a3aa743 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/PCompMRFCProcess.java @@ -0,0 +1,1611 @@ +package com.eactive.eai.flowcontroller; +//package com.eactive.eai.flowcontroller; +// +//import com.bea.control.ServiceBrokerControl; +//import com.bea.jpd.JpdContext; +//import com.bea.data.RawData; +//import com.bea.wli.control.broker.MessageBroker; +//import com.bea.wli.jpd.Callback; +//import com.bea.wli.jpd.CallbackInterface; +//import com.bea.xml.XmlObjectList; +//import org.apache.beehive.controls.api.bean.Control; +//import org.apache.beehive.controls.api.events.EventHandler; +//import org.apache.xmlbeans.XmlObject; +//import com.eactive.eai.adapter.AdapterGroupVO; +//import com.eactive.eai.adapter.AdapterManager; +//import com.eactive.eai.common.EAIKeys; +//import com.eactive.eai.common.EAITable; +//import com.eactive.eai.common.exception.ExceptionHandler; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.message.EAIMessage; +//import com.eactive.eai.common.message.EAIMessageKeys; +//import com.eactive.eai.common.message.EAIMessageManager; +//import com.eactive.eai.common.routing.RoutingManager; +//import com.eactive.eai.common.routing.RoutingVO; +//import com.eactive.eai.common.util.Logger; +//import com.eactive.eai.common.util.MessageUtil; +//import com.eactive.eai.transformer.function.util.CodeConversion; +//import com.eactive.eai.transformer.transform.TransformManager; +//import java.util.HashMap; +//import java.util.Properties; +//import com.eactive.eai.control.*; +//import com.eactive.eai.common.routing.IFRouter; +//import com.eactive.eai.common.kbmessage.KBMessageKeys; +// +// +///** +// * @jpd:process process:: +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * true +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * :: +// * @jws:protocol java-call="true" jms-soap="false" +// */ +//@com.bea.wli.common.Protocol(javaCall = true, +// jmsSoap = false, httpSoap = false) +//@com.bea.wli.jpd.Process(process = " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " true " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// "") +//public class PCompMRFCProcess implements com.bea.jpd.ProcessDefinition +//{ +// public java.lang.String[] layoutNames; +// +// public java.lang.String ack; +// +// //public Properties callProps; +// +// public java.io.Serializable outMessages; +// +// public java.lang.String errTranName; +// +// public java.lang.String comTranName; +// +// public java.lang.Object outObject; +// +// public java.lang.Object[] scrObjects; +// +// public java.lang.String tranName; +// +// public java.lang.String kesaCd; +// +// public java.io.Serializable recvData; +// +// public int timeout; +// +// public java.lang.String colId; +// +// public java.lang.String resQueueName; +// +// public java.lang.String resOutQueueName; +// +// public java.lang.String queueConnectName; +// +// public java.lang.String pCompOutResult; +// +// public com.eactive.eai.common.message.EAIMessage resEaiMsg; +// +// public java.util.Properties callProp; +// +// public com.eactive.eai.common.message.EAIMessage reqEaiMsg; +// +// public EAIMessage compEaiMsg; //보상거래 요청 메시지 +// +// public EAIMessage compResEaiMsg; //보상거래 응답 메시지 +// +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// public int svcMsgSize; +// +// public int count; +// +// public int[] compList; +// +// public int compCount; +// +// public int calledCount; //보상거래 등록 카운트 +// +// public String keyMgtMsgVl ; +// +// static final long serialVersionUID = 1L; +// +// @com.bea.wli.jpd.Callback() +// public Callback callback; +// +// public boolean isComp; +// +// public boolean returnErrorMsg; +// +// public String errMsg; +// +// public String errCode; +// +// public Object[] errBizMsg; +// +// private final static String OUTBOUND_FC_TYPE = "F"; +// +// public HashMap resultScrLayouts; +// +// public int sourceCount; +// +// public int resultCount; +// +// +// /* +// * 이 주석 위의 영역에는 디자인 뷰에서 만든 변수 선언이 포함되어 있습니다. +// * 이 주석 아래의 영역에는 디자인 뷰에서 만든 컨트롤 선언이 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 완전히 지원됩니다. +// * 경고: 애플리케이션에서 이미 사용하고 있는 프로세스 변수와 컨트롤 선언을 변경하는 +// * 경우 사용 중인 모든 위치에서 해당 선언을 업데이트하지 않으면 애플리케이션에서 +// * 오류가 발생할 수 있습니다. +// */ +// +// /** +// * @common:control +// */ +// @Control() +// private com.eactive.eai.flowcontroller.PCompOutFCProcessPControl pCompOutFCProcessCtrl; +// +// +// /** +// * @common:context +// */ +// @com.bea.wli.jpd.Context() +// JpdContext context; //(..컨트롤 삽입 표식 - 이 라인을 수정하지 마십시오.) +// +// /* +// * 이 주석 아래의 영역에는 프로세스 언어의 통신 노드에서 참조하는 java 메소드가 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 부분적으로 지원됩니다. +// * 경고: 메소드 본문에 코드를 추가할 수 있지만 보호 섹션 블록 주석의 외부 +// * 합니다. 이 주석 내의 코드를 수정하면 이 코드를 생성한 디자인 뷰 빌더에서 +// * 정보를 볼 수 없습니다. +// */ +// +// +// public java.lang.String clientReturn() +// { +// ack = "PCompMRFCProcess ] callService Called"; +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // return +// return ack; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// +// +// +// public void pCompOutFCProcessCtrlCallService() throws Exception +// { +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM201"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// } +// +// public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // parameter assignment +// this.reqEaiMsg = reqEaiMsg; +// this.callProp = callProp; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// +// public void pCompOutFCProcessCtrlCallService11() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다...... 1"); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = "" + +// this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess]PCompOutFCProcess 호출을 마칩니다 ......1"); +// } +// +// public void pCompOutFCProcessCtrlCallService21() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다......2"); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = "" + +// this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// +// logger.debug("PCompMRFCProcess]PCompOutFCProcess 호출을 마칩니다.....2"); +// } +// +// public void pCompOutFCProcessCtrlCallService31() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다......3"); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = "" + +// this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출을 마칩니다......3"); +// } +// +// public void pCompOutFCProcessCtrlCallService41() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다......4"); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = "" + +// this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출을 마칩니다......4"); +// } +// +// public void jmsQueueReceiverCtrlReceive1() throws Exception +// { +// logger.debug("PCompMRFCProcess] OutQueue로부터 데이터를 수신합니다."); +// +// try +// { +// JMSQueueReceiver jmsQueueReceiverCtrl = new JMSQueueReceiver(); +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.recvData = jmsQueueReceiverCtrl.receive(this.queueConnectName, this.resOutQueueName, this.colId, this.timeout); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// }catch (Exception e) { +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM204"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// +// logger.debug("PCompMRFCProcess] OutQueue로부터 데이터를 수신했습니다."); +// } +// +// public void transformCtrlTransformComp1() throws Exception +// { +// logger.debug("PCompMRFCProcess] 정상응답 변환을 시작합니다."); +// this.tranName = this.reqEaiMsg.getSvcMsg(svcMsgSize - 1).getBsRspCnvMsgID(); +// logger.debug("PCompMRFCProcess] 변환명 [ " + +// tranName + +// " ] "); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.outObject = Transform.transformComp(this.kesaCd, true, this.tranName, this.scrObjects, this.layoutNames); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM207"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] 정상응답 변환을 마칩니다."); +// } +// +// +// public void jmsQueueSenderCtrlSendObject1() throws Exception +// { +// +// //오류응답 메시지를 수신했거나 EAI 오류가 발생한 경우 Exception Handelr로 전송한 EAI메시지를 반환한다. +// if (returnErrorMsg) +// { +// logger.debug("PCompMRFCProcess] 오류 응답 메시지를 Queue로 전송합니다."); +// logger.debug("PCompMRFCProcess] errMsg - " + +// errMsg); +// +// this.reqEaiMsg.setRspErrCd(errCode); +// this.reqEaiMsg.setRspErrMsg(errMsg); +// this.reqEaiMsg.setBizMsg(errBizMsg); +// this.outMessages = this.reqEaiMsg; +// } +// else +// { +// logger.debug("PCompMRFCProcess] 정상 응답 메시지를 Queue로 전송합니다."); +// this.outMessages = this.resEaiMsg; +// } +// try +// { +// JMSQueueSender jmsQueueSenderCtrl = new JMSQueueSender(); +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // method call +// jmsQueueSenderCtrl.sendObject(this.queueConnectName, this.resQueueName, this.outMessages, this.colId); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM211"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); //async type 이므로 throw하지 않고 응답메시지에 에러 코드를 set해서 넘김 +// } +// logger.debug("PCompMRFCProcess] 응답 메시지를 Queue로 전송을 마칩니다."); +// } +// +// public void jmsQueueSenderCtrlSendObject() throws Exception +// { +// logger.debug("PCompMRFCProcess] 오류응답 메시지를 Queue로 전송합니다."); +// try +// { +// this.resEaiMsg.setSvcPssSeq(this.svcMsgSize); +// this.resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// this.outMessages = this.resEaiMsg; +// JMSQueueSender jmsQueueSenderCtrl = new JMSQueueSender(); +// +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // method call +// jmsQueueSenderCtrl.sendObject(this.queueConnectName, this.resQueueName, this.outMessages, this.colId); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM211"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// } +// logger.debug("PCompMRFCProcess] 오류응답 메시지를 Queue로 전송을 마칩니다."); +// } +// +// public void pCompOutFCProcessCtrlCallService411() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다......4"); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = "" + +// this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출을 마칩니다......4"); +// } +// +// public void pCompOutFCProcessCtrlCallService5() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다......5"); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = "" + +// this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출을 마칩니다......5"); +// } +// +// public void pCompOutFCProcessCtrlCallService6() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다......6"); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = "" + +// this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompMRFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출을 마칩니다......6"); +// } +// +// public void pCompOutFCProcessCtrlCallService7() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다......7"); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출을 마칩니다......7" ); +// } +// +// public void pCompOutFCProcessCtrlCallService8() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다......8" ); +// try{ +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출을 마칩니다......8" ); +// } +// +// public void pCompOutFCProcessCtrlCallService9() throws Exception +// { +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출합니다......9" ); +// try{ +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.pCompOutResult = pCompOutFCProcessCtrl.callService(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM203"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] PCompOutFCProcess를 호출을 마칩니다......9" ); +// } +// +// public void iFRouterProcess() throws Exception +// { +// logger.debug("PCompMRFCProcess] 보상거래를 호출합니다"); +// String compEaisvcCd = this.reqEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd(); +// +// if (compEaisvcCd !=null) { +// try { +// compEaiMsg = EAIMessageManager.getInstance().getEAIMessage(compEaisvcCd); +// compEaiMsg.setSvcOgNo(colId); +// compEaiMsg.setBizMsg(this.reqEaiMsg.getBizMsg()); +// compEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// +// compEaiMsg = MessageUtil.makeCompEAIMessage(compEaiMsg, reqEaiMsg); +// +// compResEaiMsg = compEaiMsg; +// callProp.setProperty(EAIKeys.CALL_COMP_KEY, EAIKeys.CALL_COMP_VALUE); //보상거래 프로퍼티 설정 +// callProp.setProperty(EAIKeys.CALL_COMP_SVC_SEQ, ""+this.reqEaiMsg.getSvcPssSeq()); +// logger.debug("PCompMRFCProcess] callProp.getProperty(EAIKeys.CALL_COMP_SVC_SEQ) : " + callProp.getProperty(EAIKeys.CALL_COMP_SVC_SEQ)); +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM208"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(rspErrorMsg); +// logger.debug("PCompMRFCProcess] 보상거래 호출을 위한 EAI 메세지 생성중 에러가 발생했습니다"); +// e.printStackTrace(); +// //this.resEaiMsg.setRspErrCd(rspErrorCode); +// // this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// } else { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = ""+this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM209"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompMRFCProcess] "+rspErrorMsg); +// //this.resEaiMsg.setRspErrCd(rspErrorCode); +// //this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new RuntimeException(rspErrorCode); +// } +// try { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.compResEaiMsg = IFRouter.process(this.compEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM210"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(rspErrorMsg); +// e.printStackTrace(); +// this.compEaiMsg.setRspErrCd(rspErrorCode); +// this.compEaiMsg.setRspErrMsg(rspErrorMsg); +// //throw new RuntimeException(rspErrorCode); +// +// } +// +// logger.debug("PCompMRFCProcess] 보상거래를 호출을 마칩니다."); +// +// } +// +// @CallbackInterface() +// public interface Callback extends ServiceBrokerControl //(..영역 끝 표식 - 이 라인을 수정하지 마십시오.) +// { +// } +// +// /* +// * 이 주석 아래에 삽입한 코드는 디자인 뷰에서 만든 수행 또는 조건 노드에 해당하는 +// * 메소드용입니다. +// * +// * 여기에서 코드를 수정하거나 새로 추가하십시오. +// */ +// +// +// public boolean isRealCall() +// { +// if(this.callProp != null) { +// String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); +// if(mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { +// logger.debug("PCompMRFCProcess] Warming Up Called"); +// return false; +// } +// else { +// return true; +// } +// } +// else { +// return true; +// } +// } +// +// +// public boolean isCall() +// { +// if (svcMsgSize == 1 && count ==1 ){ +// this.reqEaiMsg.setSvcPssSeq(count); +// this.reqEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// this.count++; +// return true; +// } else if (count >= svcMsgSize ) { +// return false; +// } else { +// this.reqEaiMsg.setSvcPssSeq(count); +// this.reqEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// this.count++; +// logger.debug("PCompMRFCProcess ] reqEaiMsg.getSvcPssSeq : [ "+reqEaiMsg.getSvcPssSeq()+" ] "); +// return true; +// } +// } +// +// +// public boolean existReciveData() +// { +// logger.debug("PCompMRFCProcess] 수신할 데이터를 확인 합니다." ); +// if(count == 1) { +// logger.debug("PCompMRFCProcess] 수신할 데이터가 없습니다. "); +// return false; +// } else { +// logger.debug("PCompMRFCProcess] 데이터를 수신합니다. [ "+ (count-1)+" ]"); +// +// count--; +// return true; +// } +// } +// +// public boolean isCompensation() +// { +// if (this.compList != null ) { //보상거래가 등록된 서비스가 하나라도 있으면 +// return true; +// } +// else { +// return false; +// } +// } +// +// +// public boolean existComTran() +// { +// logger.debug("PCompMRFCProcess] 실행할 보상거래가 있는지 확인합니다."); +// if (calledCount > 0 ) { +// if (calledCount == compCount) { +// logger.debug("PCompMRFCProcess] 실행할 보상거래가 없습니다.- callCount == compCount [ " +calledCount + " ] "); +// return false; +// }else if (this.compList[compCount] >0) { //보상거래 처리가 등록된 서비스 메시지 이면 보상거래 처 +// logger.debug("PCompMRFCProcess] 실행할 보상거래가 있습니다. [ this.compList[" +compCount+" ] - "+ this.compList[compCount]); +// this.reqEaiMsg.setSvcPssSeq(this.compList[compCount]); //보상거래를 위해 처리된 순서대로 서비스메시지를 설정 +// compCount++; +// return true; +// } else { +// logger.debug("PCompMRFCProcess] 실행할 보상거래가 없습니다. [ " + this.compList[compCount] + " ] "); +// return false; +// } +// +// } else { +// logger.debug("PCompMRFCProcess] 실행할 보상거래가 없습니다."); +// return false; +// } +// } +// +// +// +// +// public boolean isRealCall1() +// { +// if(this.callProp != null) { +// String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); +// if(mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { +// logger.debug("PCompMRFCProcess] Warming Up Called"); +// return false; +// } +// else { +// return true; +// } +// } +// else { +// return true; +// } +// +// } +// +// public boolean isBsResponse() +// { +// if(!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) ) { +// return false; +// } +// else { +// return true; +// } +// } +// +// +// private String getLayoutName (String transformName) throws Exception{ +// TransformManager manager = TransformManager.getManager(); +// com.eactive.eai.transformer.transform.Transform transform = manager.getTransform(transformName); +// String layoutName = ""; +// if (transform == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = transformName; +// String rspErrorCode = "RECEAIFPM212"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } else { +// layoutName = transform.getTargetLayout().getName(); +// } +// +// return layoutName; +// +// } +// +// public void init() throws Exception +// { +// logger.debug("PCompMRFCProcess] 초기화를 실행합니다." ); +// this.resEaiMsg = this.reqEaiMsg; +// +// sourceCount = 0; +// resultCount = 0; +// +// this.queueConnectName = EAIKeys.PCOMP_CON_FACTORY; +// this.resQueueName = EAIKeys.PCOMP_RES_QUEUE; +// this.resOutQueueName = EAIKeys.PCOMP_OUT_RES_QUEUE; +// +// try { +// this.colId = this.reqEaiMsg.getSvcOgNo(); +// //----------------------------------------------- +// // KBMessage 표준으로 변경함 2008.05.08 +// //----------------------------------------------- +// //this.kesaCd = this.reqEaiMsg.getKesaMsg().getCService(); +// this.kesaCd = this.reqEaiMsg.getKbMsg().getKBCommon().getTelgmRecvTranCd(); +// //----------------------------------------------- +// this.svcMsgSize = this.reqEaiMsg.getSvcMsgs().size(); +// this.keyMgtMsgVl = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM202"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompMRFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } +// +// try{ +// String outName = this.reqEaiMsg.getSvcMsg(svcMsgSize-1).getOutbRtnNm(); +// RoutingManager rm = RoutingManager.getInstance(); +// RoutingVO vo = rm.getRoutingVO(outName); +// String layerDstcd = vo.getLayerDstcd(); +// +// if (!OUTBOUND_FC_TYPE.equals(layerDstcd) ) { +// logger.error("PCompMRFCProcess] 결과 메시지를 변환하기 위한 서비스 메시지가 등록되어 있지 않습니다."); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM213"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorCode); +// }else { +// this.resultScrLayouts = new HashMap(); +// +// String resultTransform = this.reqEaiMsg.getSvcMsg(svcMsgSize-1).getBsRspCnvMsgID(); +// +// TransformManager manager = TransformManager.getManager(); +// com.eactive.eai.transformer.transform.Transform transform = manager.getTransform(resultTransform); +// String sourceLayout = ""; +// +// com.eactive.eai.transformer.transform.Transform scrTransform = manager.getTransform(this.reqEaiMsg.getCurrentSvcMsg().getCnvMsgID()); +// String scrLayout = scrTransform.getSourceLayout(0).getName(); +// +// if (transform == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = resultTransform; +// String rspErrorCode = "RECEAIFMR008"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("CompMRFCProcess] " +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } else { +// sourceCount = transform.getSourceLayoutCount(); +// scrObjects = new Object[sourceCount]; +// layoutNames = new String[sourceCount]; +// +// for (int i=0; i 0) { +// timeout = (timeout + 5) * 1000; +// } +// +// logger.debug("PCompMRFCProcess] 초기화를 실행을 마칩니다." ); +// +// } +// +// public boolean existReciveData1() +// { +// logger.debug("PCompMRFCProcess] 수신할 데이터를 확인 합니다." ); +// if(count == 1) { +// logger.debug("PCompMRFCProcess] 수신할 데이터가 없습니다. "); +// return false; +// } else { +// logger.debug("PCompMRFCProcess] 데이터를 수신합니다. "); +// +// count--; +// return true; +// } +// +// } +// +// public void setQueueResopnse() throws Exception +// { +// logger.debug("PCompMRFCProcess] 응답메시지를 응답 메시지 리스트에 설정합니다. -" ); +// +// if(this.recvData instanceof EAIMessage) { +// this.resEaiMsg = (EAIMessage) this.recvData; +// logger.debug("PCompMRFCProcess] 응답메시지의 서비스 처리 순서 - " +resEaiMsg.getSvcPssSeq()); +// try { +// /* +// // 업무오류와 정상코드가 동일하므로 제거해야함 : 2008.06.03 +// //if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) || EAIMessageKeys.BWK_ERRMSG_CODE.equals(resEaiMsg.getRspErrCd())){ +// if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())){ +// logger.debug("PCompMRFCProcess] if (EAIMessageKeys.BWK_ERRMSG_CODE.equals(resEaiMsg.getRspErrCd()))"); +// this.scrObjects[resEaiMsg.getSvcPssSeq()-1] = resEaiMsg.getBizMsg()[0]; +// if (resEaiMsg.getCurrentSvcMsg().getErrRspCnvMsgID() != null && resEaiMsg.getCurrentSvcMsg().getErrRspCnvMsgID().length() > 0) { +// this.layoutNames[resEaiMsg.getSvcPssSeq()-1] = getLayoutName(resEaiMsg.getCurrentSvcMsg().getErrRspCnvMsgID()); +// } +// for (int i = 0 ; i 0) { +// this.layoutNames[i] = getLayoutName (reqEaiMsg.getSvcMsg(i+1).getErrRspCnvMsgID()); +// } else { +// this.layoutNames[i] = ""; +// } +// } +// } else {*/ +//// this.scrObjects[resEaiMsg.getSvcPssSeq()-1] = this.resEaiMsg.getBizMsg()[0]; +//// this.layoutNames[resEaiMsg.getSvcPssSeq()-1] = getLayoutName (resEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID()); +// +// String layoutName = getLayoutName (resEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID()); +// +// if (this.resultScrLayouts.get(layoutName) != null ){ +// scrObjects[resultCount] = this.resEaiMsg.getBizMsg()[0]; +// layoutNames[resultCount] = layoutName; +// resultCount++; +// } +// +// /* }*/ +// }catch (Exception e) { +// e.printStackTrace(); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM205"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +//// throw new Exception(rspErrorCode); +// } +// } +// else { +// logger.error ("PCompMRFCProcess] 응답 메시지의 형식이 EAIMessage 가 아닙니다. "); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM206"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompMRFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// // throw new Exception(rspErrorCode); +// } +// logger.debug("PCompMRFCProcess] 응답메시지를 메시지를 설정을 마칩니다." ); +// +// } +// +// public boolean isBsResponse1() +// { +//// // 업무오류와 정상코드가 동일하므로 제거해야함 : 2008.06.03 +// //if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) || EAIMessageKeys.BWK_ERRMSG_CODE.equals(resEaiMsg.getRspErrCd())){ +// //if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())){ +// if (returnErrorMsg) { +// //returnErrorMsg = true; +// return false; +// +// } +// else { +// return true; +// } +// +// } +// +// public void setResponseMessage() throws Exception +// { +// logger.debug("PCompMRFCProcess ] 정상 응답 메시지를 수신했습니다. "+ this.resEaiMsg.getBizMsg()[0].toString()); +// Object[] obj = new Object[1]; +// obj[0] = this.outObject; +// this.resEaiMsg.setBizMsg(obj); +// this.resEaiMsg.setSvcPssSeq(this.svcMsgSize); +// this.resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); +// +// } +// +// public boolean isCompensation1() +// { +// if (this.isComp) { //보상거래가 등록된 서비스 메시지에서 에러가 발생되면 +// logger.debug("PCompMRFCProcess ] 보상거래가 등록되어 있습니다. "); +// return true; +// } +// else { +// logger.debug("PCompMRFCProcess ] 등록된 보상거래가 등록되어 없습니다. "); +// return false; +// } +// +// } +// +// public boolean existComTran1() +// { +// if (calledCount > 0 ) { +// if (calledCount == compCount) { +// logger.debug("PCompMRFCProcess ] 호출할 보상거래가 없습니다. "); +// return false; +// } +// else if (this.compList[compCount] >0) { //보상거래 처리가 등록된 서비스 메시지 이면 보상거래 처리 +// this.reqEaiMsg.setSvcPssSeq(this.compList[compCount]); //보상거래를 위해 처리된 순서대로 서비스메시지를 설정 +// logger.debug("PCompMRFCProcess ] 처리될 보상거래 서비스 처리순서는 [ " +this.compList[compCount] + " ] "); +// compCount++; +// return true; +// } +// else { +// logger.debug("PCompMRFCProcess ] this.compList[compCount] <= 0"); +// return false; +// } +// +// } +// else { +// logger.debug("PCompMRFCProcess ] calledCount <= 0"); +// return false; +// } +// +// } +// +// public void setCompResponse() throws Exception +// { +// +// //보강거래 처리에서 오류가 발생한경우에 대한 처리절차 추가 필요 +// if(!MessageUtil.checkRspErrCd(this.compResEaiMsg.getRspErrCd())) { //보상거래 처리시 오류가 발생한 경우 +// logger.error("PCompMRFCProcess ] 보상거래 처리시 오류가 발생했습니다 - " + this.compResEaiMsg.getRspErrCd() +" - " + this.compResEaiMsg.getRspErrMsg()); +// } else { +// logger.info ( "PCompMRFCProcess ] 보상거래 처리가 정상적으로 처리되었습니다. - [ "+ this.compEaiMsg.getEAISvcCd()+" ] "); +// } +// +// } +// +// public void setErrorMessage() throws Exception +// { +// logger.debug("PCompMRFCProcess ] 오류 응답 메시지를 수신했습니다. "+ this.resEaiMsg.getBizMsg()[0].toString()); +// +// +// } +// +// public void printExceptionMessage() throws Exception +// { +// Exception e = this.context.getExceptionInfo().getException(); +// if (logger.isError()) logger.error("PCompMRFCProcess] ExceptionPath : "+e.getMessage()); +// +// } +// +// public boolean isSourceAsync() +// { +// if(EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) ) { +// return true; +// } +// else { +// return false; +// } +// +// +// } +// +// public void callExceptionHandler() throws Exception +// { +// try { +// //---------------------------------------------------------- +// // INBOUND ADAPTER 가 SNA - EBCDIC 메시지를 사용할 경우 +// // 업무메시지를 ASCII로 통변환하여 ExceptionHandler로 전달한다. +// //---------------------------------------------------------- +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); +// String inAdapterMsgType = inAdptGrpVO.getMessageType(); +// if(EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { +// Object[] bizObjs = this.reqEaiMsg.getBizMsg(); +// if(bizObjs != null && bizObjs[0] instanceof byte[]) { +// bizObjs[0] = CodeConversion.meToMixedAsc((byte[])bizObjs[0]); +// } +// this.reqEaiMsg.setBizMsg(bizObjs); +// } +// +// //------------------------------------------- +// // 표준메시지로 변경 2008.05.08 +// //------------------------------------------- +// //this.resEaiMsg.getKesaMsg().setCTranClassify(EAIKeys.TR_RES); //0200 set +// this.resEaiMsg.getKbMsg().getKBHeader().setTelgmDmndDstcd(KBMessageKeys.TELGMDMNDDSTCD_RECV); +// +// //---------------------------------------------------------- +// ExceptionHandler.handle(this.reqEaiMsg); +// } catch(Exception e) { +// if (logger.isError()) logger.error("PCompMRFCProcess] ExceptionHandler Call Error :" + e.getMessage()); +// } +// +// } +// +// public void setCompList() throws Exception +// { +// +// // 업무오류와 정상코드가 동일하므로 제거해야함 : 2008.06.03 +// //if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) || EAIMessageKeys.BWK_ERRMSG_CODE.equals(resEaiMsg.getRspErrCd())){ +// if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())){ +// logger.debug("PCompMRFCProcess] 오류응답 메시지를 수신했습니다. "); +// +// errMsg = this.resEaiMsg.getRspErrMsg(); +// errCode = this.resEaiMsg.getRspErrCd(); +// this.errBizMsg = this.resEaiMsg.getBizMsg(); +// returnErrorMsg = true; +// +// //String tranClassify = this.resEaiMsg.getKesaMsg().getCTranClassify(); +// String telgmDmndDstcd = this.resEaiMsg.getKbMsg().getKBHeader().getTelgmDmndDstcd(); +// if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { +// //if (EAIKeys.TR_RES.equals(tranClassify) || EAIKeys.TR_CANCEL_RES.equals(tranClassify) || EAIKeys.TR_NET_RES.equals(tranClassify) || EAIKeys.TR_SYSTEMINFO_RES.equals(tranClassify)){ +// if(KBMessageKeys.TELGMDMNDDSTCD_RECV.equals(telgmDmndDstcd)) { +// if (this.resEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd() != null && this.resEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd().length() > 0) { +// +// if (this.compList == null ){ +// this.compList = new int[svcMsgSize]; +// } +// this.compList[calledCount] = this.resEaiMsg.getSvcPssSeq(); +// +// calledCount++; +// isComp = true; //보상거래가 등록된 서비스 메시지에서 에러가 발생되면 +// +// logger.error("PCompMRFCProcess] 보상거래 목록에 등록할 서비스 처리 순서는 [ "+ this.resEaiMsg.getSvcPssSeq()+" ] 입니다." ); +// } +// } +// } +// } else { //처리결과가 정상이면 보상거래 등록 +// +// if (this.resEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd() != null && this.resEaiMsg.getCurrentSvcMsg().getCpnsSvcPssCd().length() > 0) { +// if (this.compList == null ){ +// this.compList = new int[svcMsgSize]; +// } +// this.compList[calledCount] = this.resEaiMsg.getSvcPssSeq(); +// +// calledCount++; +// isComp = true; //보상거래가 등록된 서비스 메시지에서 에러가 발생되면 +// +// logger.error("PCompMRFCProcess] 보상거래 목록에 등록할 서비스 처리 순서는 [ "+ this.resEaiMsg.getSvcPssSeq()+" ] 입니다." ); +// } +// } +// } +// +// public void callExceptionHandle() throws Exception +// { +// //---------------------------------------------------- +// // 기동시스템이 Async 거래의 OUtbound에서 오류가 발생할 경우 +// // ExceptionHandler를 통해 응답메시지를 전송한다. +// //---------------------------------------------------- +// +// if( EAIMessageKeys.ASYNC_SVC.equals( this.reqEaiMsg.getSvcTsmtUsgTp() ) ) { +// logger.debug("ExceptionHandler를 호출합니다. "); +// if( ! MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) ) { +// try { +// //---------------------------------------------------------- +// // INBOUND ADAPTER 가 SNA - EBCDIC 메시지를 사용할 경우 +// // 업무메시지를 ASCII로 통변환하여 ExceptionHandler로 전달한다. +// //---------------------------------------------------------- +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); +// String inAdapterMsgType = inAdptGrpVO.getMessageType(); +// if(EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { +// Object[] bizObjs = this.reqEaiMsg.getBizMsg(); +// if(bizObjs != null && bizObjs[0] instanceof byte[]) { +// bizObjs[0] = CodeConversion.meToMixedAsc((byte[])bizObjs[0]); +// } +// this.reqEaiMsg.setBizMsg(bizObjs); +// } +// //---------------------------------------------------------- +// ExceptionHandler.handle(this.reqEaiMsg); +// } catch(Exception e) { +// if (logger.isError()) logger.error("PCompMRFCProcess] ExceptionHandler Call Error :" + e.getMessage()); +// } +// } +// logger.debug("ExceptionHandler를 호출합니다. "); +// } +// +// } +// +//} diff --git a/src/main/java/com/eactive/eai/flowcontroller/PCompMRFCProcessPControl.java b/src/main/java/com/eactive/eai/flowcontroller/PCompMRFCProcessPControl.java new file mode 100644 index 0000000..0e64dff --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/PCompMRFCProcessPControl.java @@ -0,0 +1,24 @@ +package com.eactive.eai.flowcontroller; +//package com.eactive.eai.flowcontroller; +// +//import com.bea.control.ServiceControl; +//import org.apache.beehive.controls.api.bean.ControlExtension; +// +///** +// * @jc:location uri="/Process/com/eactive/eai/flowcontroller/PCompMRFCProcess.jpd" +// * @editor-info:link autogen-style="pCtrl" source="PCompMRFCProcess.jpd" autogen="true" +// */ +//@ControlExtension() +//@ServiceControl.Location() +//@com.bea.wli.common.control.Location(uri = "/Process/com/eactive/eai/flowcontroller/PCompMRFCProcess.jpd") +//public interface PCompMRFCProcessPControl extends com.bea.control.ProcessControl +//{ +// /** +// * @jc:conversation phase="start" +// */ +// @com.bea.wli.common.Conversation(value = com.bea.wli.common.Conversation.Phase.START) +// public java.lang.String callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp); +// +// public PCompMRFCProcessPControl create(); +//} +// diff --git a/src/main/java/com/eactive/eai/flowcontroller/PCompOutFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/PCompOutFCProcess.java new file mode 100644 index 0000000..cba26ed --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/PCompOutFCProcess.java @@ -0,0 +1,284 @@ +package com.eactive.eai.flowcontroller; +//package com.eactive.eai.flowcontroller; +// +//import com.bea.control.ServiceBrokerControl; +//import com.bea.jpd.JpdContext; +//import com.bea.data.RawData; +//import com.bea.wli.control.broker.MessageBroker; +//import com.bea.wli.jpd.Callback; +//import com.bea.wli.jpd.CallbackInterface; +//import com.bea.xml.XmlObjectList; +//import org.apache.beehive.controls.api.bean.Control; +//import org.apache.beehive.controls.api.events.EventHandler; +//import org.apache.xmlbeans.XmlObject; +//import com.eactive.eai.common.EAIKeys; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.message.EAIMessage; +//import com.eactive.eai.common.util.Logger; +//import com.eactive.eai.control.*; +//import com.eactive.eai.common.routing.IFRouter; +// +///** +// * @jpd:process process:: +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * :: +// * @jws:protocol java-call="false" jms-soap="false" +// */ +//@com.bea.wli.common.Protocol(javaCall = false, +// jmsSoap = false, httpSoap = false) +//@com.bea.wli.jpd.Process(process = " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// "") +//public class PCompOutFCProcess implements com.bea.jpd.ProcessDefinition +//{ +// public java.lang.String colId; +// +// public java.io.Serializable outMessage; +// +// public java.lang.String queueName; +// +// public java.lang.String queueConName; +// +// public java.lang.String ack; +// +// public com.eactive.eai.common.message.EAIMessage resEaiMsg; +// +// public java.util.Properties callProp; +// +// public com.eactive.eai.common.message.EAIMessage reqEaiMsg; +// +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// static final long serialVersionUID = 1L; +// +// @com.bea.wli.jpd.Callback() +// public Callback callback; +// +// /* +// * 이 주석 위의 영역에는 디자인 뷰에서 만든 변수 선언이 포함되어 있습니다. +// * 이 주석 아래의 영역에는 디자인 뷰에서 만든 컨트롤 선언이 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 완전히 지원됩니다. +// * 경고: 애플리케이션에서 이미 사용하고 있는 프로세스 변수와 컨트롤 선언을 변경하는 +// * 경우 사용 중인 모든 위치에서 해당 선언을 업데이트하지 않으면 애플리케이션에서 +// * 오류가 발생할 수 있습니다. +// */ +// +// /** +// * @common:context +// */ +// @com.bea.wli.jpd.Context() +// JpdContext context; //(..컨트롤 삽입 표식 - 이 라인을 수정하지 마십시오.) +// +// /* +// * 이 주석 아래의 영역에는 프로세스 언어의 통신 노드에서 참조하는 java 메소드가 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 부분적으로 지원됩니다. +// * 경고: 메소드 본문에 코드를 추가할 수 있지만 보호 섹션 블록 주석의 외부 +// * 합니다. 이 주석 내의 코드를 수정하면 이 코드를 생성한 디자인 뷰 빌더에서 +// * 정보를 볼 수 없습니다. +// */ +// +// +// +// +// +// public void jmsQueueSenderCtrlSendObject() throws Exception +// { +// logger.debug("PCompOutFCProcess] 응답 메시지를 Queue에 전송합니다.."); +// this.outMessage = this.resEaiMsg; +// JMSQueueSender jmsQueueSenderCtrl = new JMSQueueSender(); +// +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // method call +// jmsQueueSenderCtrl.sendObject(this.queueConName, this.queueName, this.outMessage, this.colId); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// logger.debug("PCompOutFCProcess] 응답 메시지를 Queue에 전송을 마칩니다.."); +// } +// +// public java.lang.String clientReturn() +// { +// this.ack = "PCompOutFCProcess] callService Called"; +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // return +// return ack; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// +// +// +// public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // parameter assignment +// this.reqEaiMsg = reqEaiMsg; +// this.callProp = callProp; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// +// +// +// public void ifRouterCtrlProcess1() throws Exception +// { +// logger.debug("PCompOutFCProcess] outbound를 호출합니다.."); +// try +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// catch (Exception e) +// { +// String[] msgArgs = new String[2]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// msgArgs[1] = "" + +// this.reqEaiMsg.getSvcPssSeq(); +// String rspErrorCode = "RECEAIFPM301"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) +// logger.error("PCompOutFCProcess] " + +// rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +//// throw new RuntimeException(rspErrorCode); //async type 이므로 throw하지 않고 응답메시지에 에러 코드를 set해서 넘김 +// } +// logger.debug("PCompOutFCProcess] outbound를 호출을 마칩니다.."); +// } +// +// public void jmsQueueSenderCtrlSendObject1() throws Exception +// { +// logger.debug("PCompOutFCProcess] 응답 메시지를 Queue에 전송합니다.."); +// this.outMessage = this.resEaiMsg; +// try +// { +// JMSQueueSender jmsQueueSenderCtrl = new JMSQueueSender(); +// +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // method call +// jmsQueueSenderCtrl.sendObject(this.queueConName, this.queueName, this.outMessage, this.colId); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// }catch (Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFPM302"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error("PCompOutFCProcess] "+rspErrorMsg); +// e.printStackTrace(); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } +// logger.debug("PCompOutFCProcess] 응답 메시지를 Queue에 전송을 마칩니다.." ); +// } +// +// +// @CallbackInterface() +// public interface Callback extends ServiceBrokerControl //(..영역 끝 표식 - 이 라인을 수정하지 마십시오.) +// { +// } +// +// /* +// * 이 주석 아래에 삽입한 코드는 디자인 뷰에서 만든 수행 또는 조건 노드에 해당하는 +// * 메소드용입니다. +// * +// * 여기에서 코드를 수정하거나 새로 추가하십시오. +// */ +// +// +// public boolean isRealCall() +// { +// if(this.callProp != null) { +// String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); +// if(mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { +// logger.debug("PCompOutFCProcess] Warming Up Called"); +// return false; +// } +// else { +// return true; +// } +// } +// else { +// return true; +// } +// +// } +// +// public void init() throws Exception +// { +// logger.debug("PCompOutFCProcess] 초기화를 수행합니다.." ); +// this.resEaiMsg = this.reqEaiMsg; +// +// this.queueConName = EAIKeys.PCOMP_CON_FACTORY; +// this.queueName = EAIKeys.PCOMP_OUT_RES_QUEUE; +// +// this.colId = this.reqEaiMsg.getSvcOgNo(); +// logger.debug("PCompOutFCProcess] 초기화를 마칩니다.." ); +// +// } +// +// public void printExceptionMessage() throws Exception +// { +// Exception e = this.context.getExceptionInfo().getException(); +// +// if (logger.isError()) logger.error("PCompOutFCProcess] ExceptionPath : "+e.getMessage()); +// try { +// JMSQueueSender jmsQueueSenderCtrl = new JMSQueueSender(); +// jmsQueueSenderCtrl.sendObject(this.queueConName, this.queueName, this.resEaiMsg, this.colId); +// } catch(Exception ex) { +// if (logger.isError()) logger.error("PCompOutFCProcess] ExceptionPath Error: "+ex.getMessage()); +// ex.printStackTrace(); +// } +// +// } +//} diff --git a/src/main/java/com/eactive/eai/flowcontroller/PCompOutFCProcessPControl.java b/src/main/java/com/eactive/eai/flowcontroller/PCompOutFCProcessPControl.java new file mode 100644 index 0000000..964dc7a --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/PCompOutFCProcessPControl.java @@ -0,0 +1,24 @@ +package com.eactive.eai.flowcontroller; +//package com.eactive.eai.flowcontroller; +// +//import com.bea.control.ServiceControl; +//import org.apache.beehive.controls.api.bean.ControlExtension; +// +///** +// * @jc:location uri="/Process/com/eactive/eai/flowcontroller/PCompOutFCProcess.jpd" +// * @editor-info:link autogen-style="pCtrl" source="PCompOutFCProcess.jpd" autogen="true" +// */ +//@ControlExtension() +//@ServiceControl.Location() +//@com.bea.wli.common.control.Location(uri = "/Process/com/eactive/eai/flowcontroller/PCompOutFCProcess.jpd") +//public interface PCompOutFCProcessPControl extends com.bea.control.ProcessControl +//{ +// /** +// * @jc:conversation phase="start" +// */ +// @com.bea.wli.common.Conversation(value = com.bea.wli.common.Conversation.Phase.START) +// public java.lang.String callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp); +// +// public PCompOutFCProcessPControl create(); +//} +// diff --git a/src/main/java/com/eactive/eai/flowcontroller/PubFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/PubFCProcess.java new file mode 100644 index 0000000..6fe7a70 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/PubFCProcess.java @@ -0,0 +1,443 @@ +package com.eactive.eai.flowcontroller; + +import java.util.Iterator; +import java.util.Properties; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.EAITable; +import com.eactive.eai.common.exception.ExceptionHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.routing.IFRouter; +import com.eactive.eai.common.routing.Process; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.ServiceUtil; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.service.InterfaceMapper; +import com.eactive.eai.transformer.function.util.CodeConversion; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class PubFCProcess extends Process { + public String adptrMsgPtrnCd; + + public java.lang.String adapterGroupName; + + public int logPssSeq; + + public int callCount; + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public java.util.Properties callProp; + + public EAIMessage resEaiMsg; + + public com.eactive.eai.common.message.EAIMessage reqEaiMsg; + + static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + private int svrLogLevel; + private static ThreadLocal local = new ThreadLocal(); + + static final long serialVersionUID = 1L; + + String guidLogPrefix = ""; + + public EAIMessage clientReturn() { + if (svrLogLevel >= 1) { + try { + long msgSndTm = System.currentTimeMillis(); + + Long threadData = (Long) local.get(); + long processTm = msgSndTm - threadData.longValue(); + if (esbLogger.isInfo()) + esbLogger.info( + guidLogPrefix + " End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("clientReturn", e); + } + } + return resEaiMsg; + } + + public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) { + this.reqEaiMsg = reqEaiMsg; + this.callProp = callProp; + if (this.reqEaiMsg == null) + return; + + svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); + +// guidLogPrefix = guidLogPrefix + " GUID["+reqEaiMsg.getKbMsg().getKBHeader().getGuIdNo()+"]"; + guidLogPrefix = guidLogPrefix + " GUID[" + getGuid(reqEaiMsg) + "]"; + + if (svrLogLevel >= 1) { + try { + long msgRcvTm = System.currentTimeMillis(); + local.set(new Long(msgRcvTm)); + if (esbLogger.isInfo()) + esbLogger.info(guidLogPrefix + " started... - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("callService", e); + } + } + + try { + flow(); + } catch (Exception e) { + printExceptionMessage(e); + if (isSourceAsync()) { + logSenderCtrlSend(); + callExceptionHandler(); + } + return; + } + } + + public void flow() throws Exception { + // isRealCall + if (!isRealCall()) { + return; + } + // 초기화 + init(); + // Outbound 프로세스 호출 + ifRouterProcess(); + + while (isNextServiceExist()) { + // GUID설정 + setGUID(); + // ServiceMessage 설정 + setCurrentService(); + // Outbound 호출 + ifRouterProcessEach(); + } + } + + public void ifRouterProcess() throws Exception { + try { + this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + this.callCount++; + // ---------------------------------------------------- + // 기동시스템이 Async 거래의 OUtbound에서 오류가 발생할 경우 + // ExceptionHandler를 통해 응답메시지를 전송한다. + // ---------------------------------------------------- + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + try { +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); +// String inAdapterMsgType = inAdptGrpVO.getMessageType(); +//// Object[] bizObjs = this.reqEaiMsg.getBizMsg(); +// Object[] bizObjs = this.reqEaiMsg.getExtMsg().getBizData(); +// if(EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { +// if(bizObjs != null && bizObjs[0] instanceof byte[]) { +// bizObjs[0] = CodeConversion.meToMixedAsc((byte[])bizObjs[0]); +// } +// } +//// this.resEaiMsg.setBizMsg(bizObjs); +// this.resEaiMsg.getExtMsg().setBizData(bizObjs); + + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.resEaiMsg.getStandardMessage().setBizData(bizData, inboundCharset); + + ExceptionHandler.handle(this.resEaiMsg); + // ---------------------------------------------------------- + + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " ExceptionHandler Call Error :" + e.getMessage()); + } + } + } + } + + public void ifRouterProcessEach() throws Exception { + try { + this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF100"; + String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + // throw new RuntimeException(rspErrorCode); + } + this.callCount++; + } + + public void logSenderCtrlSend() { +// String telgmDmndDstcd = extmessage.getSendRecv(); + String returnType = getReturnType(reqEaiMsg); + + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + this.logPssSeq = 400; + } else { + this.logPssSeq = 200; + } + + try { + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " AA Exception Logging Error :" + e.getMessage()); + } + } + + public boolean checkServiceMsgSize() { + // Outbound Error일 경우 + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) && reqEaiMsg.getSvcMsgs().size() > 1) { + return true; + } else { + return false; + } + } + + public boolean isOutboundCall() { + return true; + } + + public void init() throws Exception { + InterfaceMapper mapper = this.reqEaiMsg.getMapper(); + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " set PROCESS_TYPE [" + EAIMessageKeys.PUBLISH_PROCESS + "]"); + this.reqEaiMsg.setSvcPssTp(EAIMessageKeys.PUBLISH_PROCESS); + this.callCount = 0; + this.reqEaiMsg.setSvcPssSeq(1); + + this.resEaiMsg = this.reqEaiMsg; + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + // 등록된 어댑터가 실제 존재하지 않는 경우 : 2009.04.03 + if (adptGrpVO == null) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF001"; + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + "(Adapter Not Found - " + + this.adapterGroupName + ")"; + if (logger.isError()) + logger.error(guidLogPrefix + " " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); + + // 2009.03.11 + // AA가 아니고 기동이 KB표준이 아닌 경우 + // Adapter의 timeout값을 설정한다. + try { + String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && !(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls()))) { + // SA 또는 SNA Adapter일 경우에 는 SA Timeout값을 설정 + if ((EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + || Keys.TYPE_SNA.equals(adptGrpVO.getType())) { + int saTimeoutSec = this.reqEaiMsg.getCurrentSvcMsg().getTmoVl(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " SA TimeoutValue [" + saTimeoutSec + "]"); + setTimeout(this.reqEaiMsg, "" + saTimeoutSec); + } else { + int timeout = ServiceUtil.getTimeoutValue(adapterGroupName); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " Target Adapter TimeoutValue [" + timeout + "]"); + if (timeout > 0) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " Set Adapter TimeoutValue [" + timeout + "] to KBMessage"); + setTimeout(this.reqEaiMsg, "" + timeout); + } + } + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " Get Adapter TimeoutValue Error - ", e); + } + } + } + + public void printExceptionMessage(Exception e) { + // Exception e = this.context.getExceptionInfo().getException(); + if (logger.isError()) + logger.error(guidLogPrefix + " ExceptionPath : " + e.getMessage()); + } + + public boolean isSourceAsync() { + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + return true; + } else { + return false; + } + } + + public void callExceptionHandler() { + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + String inAdapterMsgType = inAdptGrpVO.getMessageType(); + if (EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + byte[] asc = CodeConversion.meToMixedAsc(bizData.getBytes()); + try { + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.reqEaiMsg.getStandardMessage().setBizData(new String(asc), inboundCharset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + } + ExceptionHandler.handle(this.reqEaiMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " ExceptionHandler Call Error :" + e.getMessage()); + } + } + + public boolean isRealCall() { + if (this.callProp != null) { + String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); + if (mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { + logger.warn(guidLogPrefix + " Warming Up Called"); + return false; + } else { + return true; + } + } else { + return true; + } + } + + public boolean isNextServiceExist() { + if ((reqEaiMsg.getSvcMsgs().size() > 1) && (reqEaiMsg.getSvcMsgs().size() > this.callCount)) { + return true; + } else { + return false; + } + } + + private String getAdapterType(String adapterGroupName) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + return adptGrpVO.getType(); + } + + private boolean isNKESA(String adapterGroupName) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterPropManager manager = AdapterPropManager.getInstance(); + + AdapterGroupVO adptGrpVO = null; + AdapterVO adptVO = null; + + adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + if (adptGrpVO == null || !Keys.TYPE_HTTP.equals(adptGrpVO.getType())) + return false; + + Iterator adapters = adptGrpVO.getAdapters(); + if(adapters != null && adapters.hasNext()) { + adptVO = adptGrpVO.getAdapters().next(); + } + if (adptVO == null) return false; + + Properties httpProp = (Properties) manager.getProperties(adptVO.getPropGroupName()).clone(); + String method = httpProp.getProperty(HttpClientAdapterServiceKey.METHOD); + if ("NKESA".equals(method)) return true; + else return false; + } + + public void setGUID() throws Exception { + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + String svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // 기동 호출방식 + String psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 수동 호출방식 + + if ((!(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) + && !(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp))) + || ((com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) + && (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) + && EAIMessageKeys.SYNC_SVC.equals(psvItfTp)))) { + String prcssRtdTranCd = mapper.getReturnServiceId(standardMessage); + + if (prcssRtdTranCd != null && prcssRtdTranCd.length() >= 14) { + String cicsTrncd = prcssRtdTranCd.substring(0, 4); + String telgmRecvTranCd = prcssRtdTranCd.substring(4, 14); + mapper.setServiceId(standardMessage, telgmRecvTranCd); + } else { + if (logger.isInfo()) { + logger.info(guidLogPrefix + "- PrcssRtdTranCd Length < 14 [" + prcssRtdTranCd + "]"); + } + } + } + + if (!(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) + && (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.reqEaiMsg.getStdMsgUsgCls())) + && (STDMessageKeys.RECOVER_YN_YES.equals(getRecoverYn(this.reqEaiMsg)) ) ) { + String reqOgtranGuIdNo = getOrgGuid(this.reqEaiMsg); + mapper.setOrgGuid(standardMessage, reqOgtranGuIdNo); + if (logger.isInfo()) { + logger.info(guidLogPrefix + " OgtranGuIdNo 복원 " + this.reqEaiMsg.getSvcOgNo() + " OgtranGuIdNo [" + + mapper.getOrgGuid(standardMessage) + "]"); + } + } + } + + public void setCurrentService() throws Exception { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " Outound Service Call - "); + String keyMgtMsgVl = reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " keyMgtMsgVl[" + keyMgtMsgVl + "]"); + reqEaiMsg.setSvcPssSeq(reqEaiMsg.getSvcPssSeq() + 1); + reqEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); + } +} diff --git a/src/main/java/com/eactive/eai/flowcontroller/StartFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/StartFCProcess.java new file mode 100644 index 0000000..fbb0a87 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/StartFCProcess.java @@ -0,0 +1,389 @@ +package com.eactive.eai.flowcontroller; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.EAITable; +import com.eactive.eai.common.exception.ExceptionHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.routing.IFRouter; +import com.eactive.eai.common.routing.Process; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.service.InterfaceMapper; +import com.eactive.eai.transformer.function.util.CodeConversion; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class StartFCProcess extends Process { + public String adptrMsgPtrnCd; // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 + + public java.lang.String adapterGroupName; + + public int logPssSeq; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public java.util.Properties callProp; + + public EAIMessage resEaiMsg; + + public com.eactive.eai.common.message.EAIMessage reqEaiMsg; + + static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + private int svrLogLevel; + private static ThreadLocal local = new ThreadLocal(); + + static final long serialVersionUID = 1L; + + String guidLogPrefix = ""; + + public EAIMessage clientReturn() { + if (svrLogLevel >= 1) { + try { + long msgSndTm = System.currentTimeMillis(); + + Long threadData = (Long) local.get(); + long processTm = msgSndTm - threadData.longValue(); + if (esbLogger.isInfo()) + esbLogger.info( + guidLogPrefix + " End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.error("clientReturn", e); + } + } + return resEaiMsg; + } + + public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) { + this.reqEaiMsg = reqEaiMsg; + this.callProp = callProp; + + if (this.reqEaiMsg == null) + return; + + svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); + +// guidLogPrefix = guidLogPrefix + "GUID["+reqEaiMsg.getKbMsg().getKBHeader().getGuIdNo()+"]"; + guidLogPrefix = guidLogPrefix + "GUID[" + getGuid(reqEaiMsg) + "]"; + + if (svrLogLevel >= 1) { + try { + long msgRcvTm = System.currentTimeMillis(); + local.set(new Long(msgRcvTm)); + + if (esbLogger.isInfo()) + esbLogger.info(guidLogPrefix + " started... - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.error("callService error", e); + } + } + + try { + flow(); + } catch (Exception e) { + // 에러처리 + printExceptionMessage(e); + // ASYNC + if (isSourceAsync()) { + // Async-로그 + logSenderCtrlSend(); + // ExcetpionHandler 호출 + callExceptionHandler(); + } + return; + + } + } + + public void flow() throws Exception { + // isRealCall + if (!isRealCall()) { + return; + } + // 초기화 + init(); + // Start Target Adapter + startTargetAdapter(); + // Outbound 프로세스 호출 + ifRouterProcess(); + // GUID설정 + setGUID(); + // ASYNC-SYNC모델 + if (checkServiceMsgSize()) { + // ServiceMessage설정 + setCurrentService(); + // 응답메시지전송 + ifRouterProcessResponse(); + } + } + + public void ifRouterProcess() throws Exception { + try { + this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + "" + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + // ---------------------------------------------------- + // 기동시스템이 Async 거래의 OUtbound에서 오류가 발생할 경우 + // ExceptionHandler를 통해 응답메시지를 전송한다. + // ---------------------------------------------------- + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + try { +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); +// String inAdapterMsgType = inAdptGrpVO.getMessageType(); +//// Object[] bizObjs = this.reqEaiMsg.getBizMsg(); +// Object[] bizObjs = this.reqEaiMsg.getExtMsg().getBizData(); +// if(EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { +// if(bizObjs != null && bizObjs[0] instanceof byte[]) { +// bizObjs[0] = CodeConversion.meToMixedAsc((byte[])bizObjs[0]); +// } +// } +//// this.resEaiMsg.setBizMsg(bizObjs); +// this.resEaiMsg.getExtMsg().setBizData(bizObjs); + + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.resEaiMsg.getStandardMessage().setBizData(bizData, inboundCharset); + ExceptionHandler.handle(this.resEaiMsg); + // ---------------------------------------------------------- + + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + "ExceptionHandler Call Error :" + e.getMessage()); + } + } + } + } + + public void ifRouterProcessResponse() throws Exception { + try { + this.resEaiMsg = IFRouter.process(this.resEaiMsg, this.callProp); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF100"; + String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + "" + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + // throw new RuntimeException(rspErrorCode); + } + } + + public void logSenderCtrlSend() { + String returnType = getReturnType(reqEaiMsg); + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + this.logPssSeq = 400; + } else { + this.logPssSeq = 200; + } + + try { + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + "AA Exception Logging Error :" + e.getMessage()); + } + } + + public boolean checkServiceMsgSize() { + // Outbound Error일 경우 + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) && reqEaiMsg.getSvcMsgs().size() > 1) { + return true; + } else { + return false; + } + } + + public void setCurrentService() throws Exception { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "ASYNC-SYNC CALLED"); + // --------------------------------------------------------------- + // AS의 경우 다음 서비스메시지(AS 응답)에 키관리메시지내용을 복사한다. + // --------------------------------------------------------------- + String keyMgtMsgVl = resEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + "AS 응답 keyMgtMsgVl[" + keyMgtMsgVl + "]"); + resEaiMsg.setSvcPssSeq(resEaiMsg.getSvcPssSeq() + 1); + resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); + // --------------------------------------------------------------- + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 + + // SA Type의 요청 Outbound가 비표준일 경우 + // KESA Header의 값을 바꾼다. (0200 -> TR_RES) + + } + + public boolean isOutboundCall() { + return true; + } + + public void init() throws Exception { + InterfaceMapper mapper = this.reqEaiMsg.getMapper(); + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + this.resEaiMsg = this.reqEaiMsg; + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + } + + public void printExceptionMessage(Exception e) { + // Exception e = this.context.getExceptionInfo().getException(); + if (logger.isError()) + logger.error(guidLogPrefix + "ExceptionPath : " + e.getMessage()); + } + + public boolean isSourceAsync() { + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + return true; + } else { + return false; + } + } + + public void callExceptionHandler() { + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + String inAdapterMsgType = inAdptGrpVO.getMessageType(); + if (EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { +//// Object[] bizObjs = this.reqEaiMsg.getBizMsg(); +// Object[] bizObjs = this.reqEaiMsg.getExtMsg().getBizData(); +// if(bizObjs != null && bizObjs[0] instanceof byte[]) { +// bizObjs[0] = CodeConversion.meToMixedAsc((byte[])bizObjs[0]); +// } +//// this.reqEaiMsg.setBizMsg(bizObjs); +// this.reqEaiMsg.getExtMsg().setBizData(bizObjs); + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + byte[] asc = CodeConversion.meToMixedAsc(bizData.getBytes()); + try { + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.reqEaiMsg.getStandardMessage().setBizData(new String(asc), inboundCharset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + } + // ---------------------------------------------------------- + ExceptionHandler.handle(this.reqEaiMsg); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + "ExceptionHandler Call Error :" + e.getMessage()); + } + } + + public boolean isRealCall() { + if (this.callProp != null) { + String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); + if (mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { + logger.warn(guidLogPrefix + "Warming Up Called"); + return false; + } else { + return true; + } + } else { + return true; + } + } + + public void setGUID() throws Exception { + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ Current GUID [" + guid + "][" + guidseq + "]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " REQ ADD PATHSEQ GUID [" + guid + "][" + guidseq + "]"); + + } + + public void startTargetAdapter() throws Exception { + try { + String srcAdapterGroupName = this.reqEaiMsg.getSngSysItfTp(); + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO srcAdapterGroup = adapterManager.getAdapterGroupVO(srcAdapterGroupName); + + String[] srcAdapterNames = srcAdapterGroup.getAdapterNames(); + + if (srcAdapterNames != null && srcAdapterNames.length > 0) { + AdapterVO srcAdapter = srcAdapterGroup.getAdapterVO(srcAdapterNames[0]); + String adapterPropGroupName = srcAdapter.getPropGroupName(); + // PropManager manager = PropManager.getInstance(); + AdapterPropManager manager = AdapterPropManager.getInstance(); + + String adptrPropVal = manager.getProperty(adapterPropGroupName, "inisafe.related.adapter.groups"); + if (logger.isDebug()) + logger.debug(guidLogPrefix + "" + adapterPropGroupName + " : inisafe.related.adapter.groups -> " + + adptrPropVal); + + if (adptrPropVal != null && adptrPropVal.trim().length() > 0) { + String[] adapter_list = adptrPropVal.split(","); + for (int p = 0; p < adapter_list.length; p++) { + String[] adapterNames = adapterManager.getAdapterGroupVO(adapter_list[p]).getAdapterNames(); + for (int i = 0; i < adapterNames.length; i++) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "startTargetAdapter :" + adapter_list[p] + " " + + adapterNames[i]); + try { + adapterManager.getAdapterGroupVO(adapter_list[p]).getAdapterVO(adapterNames[i]).start(); + } catch (Exception ex) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + "startTargetAdapter Fail :" + adapter_list[p] + " " + + adapterNames[i], ex); + } + } + } + } + } else { + if (logger.isDebug()) + logger.debug( + guidLogPrefix + "inisafe.related.adapter.groups NOT FOUND :" + srcAdapterGroupName); + } + } else { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "srcAdapter NOT FOUND :" + srcAdapterGroupName); + } + } catch (Exception e) { + if (logger.isError()) { + logger.error(guidLogPrefix + "startTargetAdapter Error", e); + } + } + } + +} diff --git a/src/main/java/com/eactive/eai/flowcontroller/StopFCProcess.java b/src/main/java/com/eactive/eai/flowcontroller/StopFCProcess.java new file mode 100644 index 0000000..1454328 --- /dev/null +++ b/src/main/java/com/eactive/eai/flowcontroller/StopFCProcess.java @@ -0,0 +1,384 @@ +package com.eactive.eai.flowcontroller; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.EAITable; +import com.eactive.eai.common.exception.ExceptionHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.routing.IFRouter; +import com.eactive.eai.common.routing.Process; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.service.InterfaceMapper; +import com.eactive.eai.transformer.function.util.CodeConversion; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class StopFCProcess extends Process +{ + public String adptrMsgPtrnCd; // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 + + public java.lang.String adapterGroupName; + + public int logPssSeq; + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public java.util.Properties callProp; + + public EAIMessage resEaiMsg; + + public com.eactive.eai.common.message.EAIMessage reqEaiMsg; + + static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + private int svrLogLevel; + private static ThreadLocal local = new ThreadLocal(); //경과시간 동기화를 위한 ThreadLocal + + static final long serialVersionUID = 1L; + + String guidLogPrefix = ""; + + public EAIMessage clientReturn() + { + if(svrLogLevel >= 1) { + try{ + long msgSndTm = System.currentTimeMillis(); + + Long threadData = (Long)local.get(); + long processTm = msgSndTm - threadData.longValue(); + if (esbLogger.isInfo()) esbLogger.info( guidLogPrefix + " End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("clientReturn", e); + } + } + return resEaiMsg; + } + + public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) + { + this.reqEaiMsg = reqEaiMsg; + this.callProp = callProp; + + if(this.reqEaiMsg == null) return; + + svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); + +// guidLogPrefix = guidLogPrefix + " GUID["+reqEaiMsg.getKbMsg().getKBHeader().getGuIdNo()+"]"; + guidLogPrefix = guidLogPrefix + " GUID["+reqEaiMsg.getMapper().getGuid(reqEaiMsg.getStandardMessage())+"]"; + + if(svrLogLevel >= 1) { + try{ + long msgRcvTm = System.currentTimeMillis(); + local.set(new Long(msgRcvTm)); + + if (esbLogger.isInfo()) esbLogger.info( guidLogPrefix + " started... - EAI Server Log Level is INFO"); + }catch(Exception e){ + logger.warn("callService", e); + } + } + + try{ + flow(); + }catch (Exception e){ + //에러처리 + printExceptionMessage(e); + //ASYNC + if (isSourceAsync()){ + //Async-로그 + logSenderCtrlSend(); + //ExcetpionHandler 호출 + callExceptionHandler(); + } + return; + + } + } + + public void flow() throws Exception { + //isRealCall + if (!isRealCall()){ + return ; + } + //초기화 + init(); + //Outbound 프로세스 호출 + ifRouterProcess(); + //GUID설정 + setGUID(); + //ASYNC-SYNC모델 + if (checkServiceMsgSize()){ + //ServiceMessage설정 + setCurrentService(); + //응답메시지전송 + ifRouterProcessResponse(); + } + //Stop Target Adapter + stopTargetAdapter(); + } + + public void ifRouterProcess() throws Exception + { + try { + this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); + } catch(Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) logger.error( guidLogPrefix + "" + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorCode); + } + + //---------------------------------------------------- + // 기동시스템이 Async 거래의 OUtbound에서 오류가 발생할 경우 + // ExceptionHandler를 통해 응답메시지를 전송한다. + //---------------------------------------------------- + if( EAIMessageKeys.ASYNC_SVC.equals( this.reqEaiMsg.getSvcTsmtUsgTp() ) ) { + if( ! MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) ) { + try { + //---------------------------------------------------------- + // INBOUND ADAPTER 가 SNA - EBCDIC 메시지를 사용할 경우 + // 업무메시지를 ASCII로 통변환하여 ExceptionHandler로 전달한다. + // 2007.06.01 : 데이터 전달방식 수정 DHLEE + //---------------------------------------------------------- +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); +// String inAdapterMsgType = inAdptGrpVO.getMessageType(); +//// Object[] bizObjs = this.reqEaiMsg.getBizMsg(); +// Object[] bizObjs = this.reqEaiMsg.getExtMsg().getBizData(); +// if(EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { +// if(bizObjs != null && bizObjs[0] instanceof byte[]) { +// bizObjs[0] = CodeConversion.meToMixedAsc((byte[])bizObjs[0]); +// } +// } +//// this.resEaiMsg.setBizMsg(bizObjs); +// this.resEaiMsg.getExtMsg().setBizData(bizObjs); + + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.resEaiMsg.getStandardMessage().setBizData(bizData, inboundCharset); + ExceptionHandler.handle(this.resEaiMsg); + //---------------------------------------------------------- + + } catch(Exception e) { + if (logger.isError()) logger.error( guidLogPrefix + "ExceptionHandler Call Error :" + e.getMessage()); + } + } + } + } + + public void ifRouterProcessResponse() throws Exception + { + try { + this.resEaiMsg = IFRouter.process(this.resEaiMsg, this.callProp); + } catch(Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIFBF100"; + String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs); + if (logger.isError()) logger.error( guidLogPrefix + "" + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + //throw new RuntimeException(rspErrorCode); + } + } + + public void logSenderCtrlSend() + { + String telgmDmndDstcd = reqEaiMsg.getMapper().getSendRecvDivision(reqEaiMsg.getStandardMessage()); + if(STDMessageKeys.SEND_RECV_CD_RECV.equals(telgmDmndDstcd)) { + // 응답인 경우 + this.logPssSeq = 400; + } + else { + // 요청 인경우 + this.logPssSeq = 200; + } + + try { + LogSender.send(this.logPssSeq, this.resEaiMsg, null); + } catch(Exception e) { + if (logger.isError()) logger.error( guidLogPrefix + "AA Exception Logging Error :" + e.getMessage()); + } + } + + public boolean checkServiceMsgSize() + { + // Outbound Error일 경우 + if( MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) && + reqEaiMsg.getSvcMsgs().size() > 1 ) { + return true; + } + else { + return false; + } + } + + public void setCurrentService() throws Exception + { + if (logger.isDebug()) logger.debug( guidLogPrefix + "ASYNC-SYNC CALLED"); + //--------------------------------------------------------------- + // AS의 경우 다음 서비스메시지(AS 응답)에 키관리메시지내용을 복사한다. + //--------------------------------------------------------------- + String keyMgtMsgVl = resEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if(logger.isDebug()) logger.debug( guidLogPrefix + "AS 응답 keyMgtMsgVl["+keyMgtMsgVl+"]"); + resEaiMsg.setSvcPssSeq( resEaiMsg.getSvcPssSeq() + 1 ); + resEaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(keyMgtMsgVl); + //--------------------------------------------------------------- + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 + + // SA Type의 요청 Outbound가 비표준일 경우 + // KESA Header의 값을 바꾼다. (0200 -> TR_RES) + } + + public boolean isOutboundCall() + { + return true; + } + + public void init() throws Exception + { + InterfaceMapper mapper = this.reqEaiMsg.getMapper(); + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) logger.debug( guidLogPrefix + " REQ Current GUID ["+guid+ "]["+guidseq+"]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) logger.debug( guidLogPrefix + " REQ ADD PATHSEQ GUID ["+guid+ "]["+guidseq+"]"); + + this.resEaiMsg = this.reqEaiMsg; + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + } + + public void printExceptionMessage(Exception e) + { + //Exception e = this.context.getExceptionInfo().getException(); + if (logger.isError()) logger.error( guidLogPrefix + "ExceptionPath : "+e.getMessage()); + } + + public boolean isSourceAsync() + { + if(EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) ) { + return true; + } + else { + return false; + } + } + + public void callExceptionHandler() + { + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + String inAdapterMsgType = inAdptGrpVO.getMessageType(); + if(EAITable.EBCDIC_TYPE.equals(inAdapterMsgType)) { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + byte[] asc = CodeConversion.meToMixedAsc(bizData.getBytes()); + try { + String inboundCharset = callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + this.reqEaiMsg.getStandardMessage().setBizData(new String(asc), inboundCharset); + } catch (Exception e) { + logger.error("setBizData error", e); + } + } + ExceptionHandler.handle(this.reqEaiMsg); + } catch(Exception e) { + if (logger.isError()) logger.error( guidLogPrefix + "ExceptionHandler Call Error :" + e.getMessage()); + } + } + + public boolean isRealCall() + { + if(this.callProp != null) { + String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); + if(mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { + logger.warn( guidLogPrefix + "Warming Up Called"); + return false; + } + else { + return true; + } + } + else { + return true; + } + } + + public void setGUID() throws Exception { + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + String guid = mapper.getGuid(standardMessage); + String guidseq = mapper.getGuidSeq(standardMessage); + + if (logger.isDebug()) logger.debug( guidLogPrefix + " REQ Current GUID ["+guid+ "]["+guidseq+"]"); + mapper.nextGuidSeq(standardMessage); + guidseq = mapper.getGuidSeq(standardMessage); + if (logger.isDebug()) logger.debug( guidLogPrefix + " REQ ADD PATHSEQ GUID ["+guid+ "]["+guidseq+"]"); + } + + public void stopTargetAdapter() throws Exception { + try { + String srcAdapterGroupName = this.reqEaiMsg.getSngSysItfTp(); + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO srcAdapterGroup = adapterManager.getAdapterGroupVO( srcAdapterGroupName ); + + String[] srcAdapterNames = srcAdapterGroup.getAdapterNames(); + + if(srcAdapterNames != null && srcAdapterNames.length > 0) { + AdapterVO srcAdapter = srcAdapterGroup.getAdapterVO(srcAdapterNames[0]); + String adapterPropGroupName = srcAdapter.getPropGroupName(); + //PropManager manager = PropManager.getInstance(); + AdapterPropManager manager = AdapterPropManager.getInstance(); + + String adptrPropVal = manager.getProperty(adapterPropGroupName, "inisafe.related.adapter.groups"); + if (logger.isDebug()) logger.debug( guidLogPrefix + " " + adapterPropGroupName + " : inisafe.related.adapter.groups -> " + adptrPropVal); + + if(adptrPropVal != null && adptrPropVal.trim().length() > 0) { + String[] adapter_list = adptrPropVal.split(","); + for(int p=0; p +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * +// * :: +// */ +//@Protocol(httpSoap=false) +//@com.bea.wli.jpd.Process(process = " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// " " + +// "") +//public class TimerFCProcess implements com.bea.jpd.ProcessDefinition +//{ +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// public java.util.Properties callProp; +// +// public EAIMessage resEaiMsg; +// +// public com.eactive.eai.common.message.EAIMessage reqEaiMsg; +// +// static final long serialVersionUID = 1L; +// +// @com.bea.wli.jpd.Callback() +// public Callback callback; +// +// public TimerAdminVO timerAdminVO; +// +// public String MsgTrceColTxt = ""; +// +// /* +// * 이 주석 위의 영역에는 디자인 뷰에서 만든 변수 선언이 포함되어 있습니다. +// * 이 주석 아래의 영역에는 디자인 뷰에서 만든 컨트롤 선언이 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 완전히 지원됩니다. +// * 경고: 애플리케이션에서 이미 사용하고 있는 프로세스 변수와 컨트롤 선언을 변경하는 +// * 경우 사용 중인 모든 위치에서 해당 선언을 업데이트하지 않으면 애플리케이션에서 +// * 오류가 발생할 수 있습니다. +// */ +// +// /** +// * @common:context +// */ +// @com.bea.wli.jpd.Context() +// JpdContext context; //(..컨트롤 삽입 표식 - 이 라인을 수정하지 마십시오.) +// +// /* +// * 이 주석 아래의 영역에는 프로세스 언어의 통신 노드에서 참조하는 java 메소드가 포함되어 있습니다. +// * +// * 이 영역의 코드는 자동으로 생성됩니다. +// * +// * 이 코드 영역에서는 양방향 편집이 부분적으로 지원됩니다. +// * 경고: 메소드 본문에 코드를 추가할 수 있지만 보호 섹션 블록 주석의 외부 +// * 합니다. 이 주석 내의 코드를 수정하면 이 코드를 생성한 디자인 뷰 빌더에서 +// * 정보를 볼 수 없습니다. +// */ +// +// +// public EAIMessage clientReturn() +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // return +// return resEaiMsg; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// +// +// +// public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties callProp) +// { +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // parameter assignment +// this.reqEaiMsg = reqEaiMsg; +// this.callProp = callProp; +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// public void ifRouterProcess1() throws Exception +// { +// if (logger.isDebug()) +// logger.debug("TimerFCProcess] ifRouterProcess cancel "); +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// +// public void ifRouterProcess3() throws Exception +// { +// +// if (logger.isDebug()) logger.debug("TimerFCProcess] ifRouterProcess resend "); +// //this.resEaiMsg = this.reqEaiMsg; +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// +// } +// +// +// public void ifRouterProcess2() throws Exception +// { +// if (logger.isDebug()) logger.debug("TimerFCProcess] ifRouterProcess timeout "); +// //#START: CODE GENERATED - PROTECTED SECTION - you can safely add code above this comment in this method. #// +// // input transform +// // return method call +// this.resEaiMsg = IFRouter.process(this.reqEaiMsg, this.callProp); +// // output transform +// // output assignments +// //#END : CODE GENERATED - PROTECTED SECTION - you can safely add code below this comment in this method. #// +// } +// +// @CallbackInterface() +// public interface Callback extends ServiceBrokerControl //(..영역 끝 표식 - 이 라인을 수정하지 마십시오.) +// { +// } +// +// /* +// * 이 주석 아래에 삽입한 코드는 디자인 뷰에서 만든 수행 또는 조건 노드에 해당하는 +// * 메소드용입니다. +// * +// * 여기에서 코드를 수정하거나 새로 추가하십시오. +// */ +// +// +// +// public boolean CancelTransactionGB() +// { +// +// if (timerAdminVO.getCnclTranEn().equals("1")){ +// if (logger.isDebug()) logger.debug("TimerFCProcess] CancelTransactionGB true"); +// return true; +// }else{ +// if (logger.isDebug()) logger.debug("TimerFCProcess] CancelTransactionGB false"); +// return false; +// } +// +// } +// +// +// public void PreSetting() throws Exception +// { +// if (logger.isDebug()) logger.debug("TimerFCProcess] PreSetting"); +// String timerAdminName = callProp.getProperty(TimerKeys.TIMER_ADMIN_NAME); +// TimerManager timerManager = TimerManager.getInstance(); +// timerAdminVO = timerManager.getTimerAdminRule(timerAdminName); +// +// String timerInfoName = callProp.getProperty(TimerKeys.TIMER_ADMIN_NAME); +// MsgTrceColTxt = callProp.getProperty(TimerKeys.MSG_TRCE_COL_TXT ); +// } +// +// public boolean TimeoutTransactionGB() +// { +// if ( timerAdminVO.getTmoTranTrsYn().equals("1")){ +// return true; +// }else{ +// return false; +// } +// } +// +// public void CancelSetting() throws Exception +// { +// reqEaiMsg.setSvcPssSeq(1); +// +// //Timeout table 상태 변경 +// DAOFactory daoFactory = DAOFactory.newInstance(); +// TimerDAO dao = null; +// Transaction tx = null; +// try { +// tx = TxHelper.getTransactionManager().suspend(); +// dao = (TimerDAO)daoFactory.create(TimerDAO.class); +// dao.updateTimerInfoStatusSend(MsgTrceColTxt,TimerKeys.STATUS_FLAG_CANCEL_RUN); +// } catch(Exception e) { +// e.printStackTrace(); +// String rspErrorCode = "RECEAIFTF001"; +// String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode); +// if (logger.isError()) logger.error("TimerFCProcess] " + rspErrorMsg); +// throw new Exception(orgErrorCode); +// }finally { +// if(tx!=null) { +// try { +// TxHelper.getTransactionManager().resume(tx); +// } catch(Exception e) { +// } +// } +// } +// } +// +// public void ReSendSetting() throws Exception +// { +// if (logger.isDebug()) { +// logger.debug("TimerFCProcess] ReSendSetting start "); +// logger.debug("TimerFCProcess] ReSendSetting "+MsgTrceColTxt); +// } +// reqEaiMsg.setSvcPssSeq(1); +// +// //Timeout table 상태 변경 +// DAOFactory daoFactory = DAOFactory.newInstance(); +// TimerDAO dao = null; +// Transaction tx = null; +// try { +// tx = TxHelper.getTransactionManager().suspend(); +// dao = (TimerDAO)daoFactory.create(TimerDAO.class); +// +// dao.updateTimerInfoStatusSend(MsgTrceColTxt,TimerKeys.STATUS_FLAG_RESEND_RUN); +// +// } catch(Exception e) { +// e.printStackTrace(); +// String rspErrorCode = "RECEAIFTF002"; +// String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode); +// if (logger.isError()) logger.error("TimerFCProcess] " + rspErrorMsg); +// throw new Exception(orgErrorCode); +// }finally { +// if(tx!=null) { +// try { +// TxHelper.getTransactionManager().resume(tx); +// } catch(Exception e) { +// } +// } +// } +// if (logger.isDebug()) logger.debug("TimerFCProcess] ReSendSetting end "); +// } +// public void RollBack() throws Exception +// { +// Exception e = context.getExceptionInfo().getException(); +// e.printStackTrace(); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIFTF003"; +// String orgErrorCode = ExceptionUtil.getErrorCode(e, rspErrorCode); +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, orgErrorCode, msgArgs); +// if (logger.isError()) logger.error("TimerFCProcess] " + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// +// //TimerInfo table 상태 변경 +// DAOFactory daoFactory = DAOFactory.newInstance(); +// TimerDAO dao = null; +// Transaction tx = null; +// try { +// tx = TxHelper.getTransactionManager().suspend(); +// dao = (TimerDAO)daoFactory.create(TimerDAO.class); +// dao.updateTimerInfoStatusSend(MsgTrceColTxt,TimerKeys.STATUS_FLAG_ERROR); +// +// } catch(Exception e1) { +// e.printStackTrace(); +// String rspErrorCode1 = "RECEAIFTF004"; +// String orgErrorCode1 = ExceptionUtil.getErrorCode(e, rspErrorCode1); +// String rspErrorMsg1 = ExceptionUtil.make(rspErrorCode1, orgErrorCode1); +// if (logger.isError()) logger.error("TimerFCProcess] " + rspErrorMsg1); +// throw new Exception(orgErrorCode); +// }finally { +// if(tx!=null) { +// try { +// TxHelper.getTransactionManager().resume(tx); +// } catch(Exception e1) { +// } +// } +// } +// } +// +// +// +// +// public void TimeoutSetting() throws Exception +// { +// reqEaiMsg.setSvcPssSeq(2); +// } +// +// +// +// public void printExceptionMessage() throws Exception +// { +// Exception e = this.context.getExceptionInfo().getException(); +// String rspErrorCode1 = "RECEAIFTF005"; +// String orgErrorCode1 = ExceptionUtil.getErrorCode(e, rspErrorCode1); +// String rspErrorMsg1 = ExceptionUtil.make(rspErrorCode1, orgErrorCode1); +// if (logger.isError()) logger.error("TimerFCProcess] " + rspErrorMsg1); +// e.printStackTrace(); +// +// Object[] objs = new Object[1]; +// objs[0] = null; +// this.resEaiMsg.setBizMsg(objs); +// +// +// } +// +// public boolean isRealCall() +// { +// if(this.callProp != null) { +// String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); +// if(mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { +// System.out.println("TimerFCProcess] Warming Up Called"); +// return false; +// } +// else { +// return true; +// } +// } +// else { +// return true; +// } +// } +// +//} diff --git a/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoDAO.java b/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoDAO.java new file mode 100644 index 0000000..1f10ccf --- /dev/null +++ b/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoDAO.java @@ -0,0 +1,75 @@ +package com.eactive.eai.httpouttlsinfo; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.httpouttlsinfo.HttpOutTlsInfo; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Stream; + +@Service +@Transactional +public class HttpOutTlsInfoDAO extends BaseDAO { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private HttpOutTlsInfoLoader httpOutTlsInfoLoader; + + private HttpOutTlsInfoMapper httpOutTlsInfoMapper; + + @Autowired + public HttpOutTlsInfoDAO(HttpOutTlsInfoLoader httpOutTlsInfoLoader, + HttpOutTlsInfoMapper httpOutTlsInfoMapper) { + + this.httpOutTlsInfoLoader = httpOutTlsInfoLoader; + this.httpOutTlsInfoMapper = httpOutTlsInfoMapper; + } + + public Map getAllHttpOutTlsInfos() throws DAOException { + + try { + Stream httpOutTlsInfos = httpOutTlsInfoLoader.loadAll(); + Map httpOutTlsInfoVOMap = new HashMap<>(); + + logger.info("[ @@ Load HttpOutTlsInfo Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + httpOutTlsInfos.forEach(httpOutTlsInfo -> { + HttpOutTlsInfoVO httpOutTlsInfoVO = httpOutTlsInfoMapper.toVo(httpOutTlsInfo); + logger.info("@ " + httpOutTlsInfoVO.toString()); + httpOutTlsInfoVOMap.put(httpOutTlsInfo.getClientId(), httpOutTlsInfoVO); + }); + + logger.info("[>>Load HttpOutTlsInfo Configuration - ended ]"); + return httpOutTlsInfoVOMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICMM101")); + } + } + + public HttpOutTlsInfoVO getHttpOutTlsInfo(String clientId) throws Exception { + + try { + logger.info("[ @@ Load HttpOutTlsInfo getHttpOutTlsInfo Configuration - starting >>>>>>>>>>>>>>>>> ]"); + + HttpOutTlsInfo httpOutTlsInfo = httpOutTlsInfoLoader.findById(clientId) + .orElseThrow(() -> new DAOException("HttpOutTlsInfo not found for clientId: " + clientId)); + + HttpOutTlsInfoVO httpOutTlsInfoVO = httpOutTlsInfoMapper.toVo(httpOutTlsInfo); + + if(logger.isInfo()) { + logger.info("@ " + httpOutTlsInfoVO.toString()); + logger.info("[>>Load HttpOutTlsInfo getHttpOutTlsInfo Configuration - ended ]"); + } + return httpOutTlsInfoVO; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICBM205")); + } + } + +} diff --git a/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoManager.java b/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoManager.java new file mode 100644 index 0000000..6a78b99 --- /dev/null +++ b/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoManager.java @@ -0,0 +1,126 @@ +package com.eactive.eai.httpouttlsinfo; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +public class HttpOutTlsInfoManager implements Lifecycle { + + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private Map httpOutTlsInfoMap = new HashMap<>(); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private boolean started; + + @Autowired + private HttpOutTlsInfoDAO httpOutTlsInfoDAO; + + public static HttpOutTlsInfoManager getInstance() { + return ApplicationContextProvider.getContext().getBean(HttpOutTlsInfoManager.class); + } + + @Override + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAIAAC015"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICKM202")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws DAOException { + httpOutTlsInfoMap.clear(); + httpOutTlsInfoMap.putAll(httpOutTlsInfoDAO.getAllHttpOutTlsInfos()); + } + + + @Override + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICKM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + httpOutTlsInfoMap.clear(); + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("HttpOutTlsInfoManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("HttpOutTlsInfoManager] reload all finished ..."); + } + } + + public synchronized void reload(String clientId) throws Exception { + if (logger.isWarn()) { + logger.warn("HttpOutTlsInfoManager] reload Started ..."); + } + HttpOutTlsInfoVO httpOutTlsInfoVO = httpOutTlsInfoDAO.getHttpOutTlsInfo(clientId);// eaiSvcCd + httpOutTlsInfoMap.put(clientId, httpOutTlsInfoVO); + + if (logger.isWarn()) { + logger.warn("HttpOutTlsInfoManager] reload finished ..."); + } + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public HttpOutTlsInfoVO getHttpOutTlsInfo(String clientId) { + return httpOutTlsInfoMap.get(clientId); + } + + public void setHttpOutTlsInfo(String clientId, HttpOutTlsInfoVO httpOutTlsInfoVO) { + httpOutTlsInfoMap.put(clientId, httpOutTlsInfoVO); + } + + public void removeHttpOutTlsInfo(String clientId) { + httpOutTlsInfoMap.remove(clientId); + } + + public String[] getAllClientIds() { + Set keySet = this.httpOutTlsInfoMap.keySet(); + String[] names = keySet.toArray(new String[keySet.size()]); + Arrays.sort(names); + return names; + } +} diff --git a/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoMapper.java b/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoMapper.java new file mode 100644 index 0000000..a7fe17f --- /dev/null +++ b/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoMapper.java @@ -0,0 +1,19 @@ +package com.eactive.eai.httpouttlsinfo; + +import com.eactive.eai.data.entity.onl.httpouttlsinfo.HttpOutTlsInfo; +import com.eactive.eai.data.mapper.GenericMapper; +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface HttpOutTlsInfoMapper extends GenericMapper { + + @Override + HttpOutTlsInfoVO toVo(HttpOutTlsInfo entity); + + @InheritInverseConfiguration + @Override + HttpOutTlsInfo toEntity(HttpOutTlsInfoVO vo); + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoVO.java b/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoVO.java new file mode 100644 index 0000000..24f549a --- /dev/null +++ b/src/main/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoVO.java @@ -0,0 +1,103 @@ +package com.eactive.eai.httpouttlsinfo; + +import java.io.Serializable; +import java.time.LocalDateTime; + +public class HttpOutTlsInfoVO implements Serializable { + + private static final long serialVersionUID = 1L; + + private String clientId; // 클라이언트 ID + private String storeType; // 스토어 타입 + private String keystoreFilename; // 키스토어 파일명 + private String keystoreInfo; // 키스토어 정보 + private String keystorePassword; // 키스토어 비밀번호 + private String truststoreFilename; // 트러스트스토어 파일명 + private String truststoreInfo; // 트러스트스토어 정보 + private String truststorePassword; // 트러스트스토어 비밀번호 + private LocalDateTime createdAt; // 생성일시 + private LocalDateTime updatedAt; // 수정일시 + + // Getters and Setters + + public String getClientId() { + return clientId; + } + + public void setClientId(String clientId) { + this.clientId = clientId; + } + + public String getStoreType() { + return storeType; + } + + public void setStoreType(String storeType) { + this.storeType = storeType; + } + + public String getKeystoreFilename() { + return keystoreFilename; + } + + public void setKeystoreFilename(String keystoreFilename) { + this.keystoreFilename = keystoreFilename; + } + + public String getKeystoreInfo() { + return keystoreInfo; + } + + public void setKeystoreInfo(String keystoreInfo) { + this.keystoreInfo = keystoreInfo; + } + + public String getKeystorePassword() { + return keystorePassword; + } + + public void setKeystorePassword(String keystorePassword) { + this.keystorePassword = keystorePassword; + } + + public String getTruststoreFilename() { + return truststoreFilename; + } + + public void setTruststoreFilename(String truststoreFilename) { + this.truststoreFilename = truststoreFilename; + } + + public String getTruststoreInfo() { + return truststoreInfo; + } + + public void setTruststoreInfo(String truststoreInfo) { + this.truststoreInfo = truststoreInfo; + } + + public String getTruststorePassword() { + return truststorePassword; + } + + public void setTruststorePassword(String truststorePassword) { + this.truststorePassword = truststorePassword; + } + + public LocalDateTime getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(LocalDateTime createdAt) { + this.createdAt = createdAt; + } + + public LocalDateTime getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(LocalDateTime updatedAt) { + this.updatedAt = updatedAt; + } + +} diff --git a/src/main/java/com/eactive/eai/inbound/action/ActionException.java b/src/main/java/com/eactive/eai/inbound/action/ActionException.java new file mode 100644 index 0000000..c736ba3 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/ActionException.java @@ -0,0 +1,12 @@ +package com.eactive.eai.inbound.action; + +public class ActionException extends Exception +{ + public ActionException() { + super("ActionException is occured."); + } + + public ActionException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/inbound/action/ActionFactory.java b/src/main/java/com/eactive/eai/inbound/action/ActionFactory.java new file mode 100644 index 0000000..f05ec3a --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/ActionFactory.java @@ -0,0 +1,43 @@ +package com.eactive.eai.inbound.action; + +public class ActionFactory +{ + /* + private static HashMap actions = new HashMap(); + + private ActionFactory() { + } + + public static RequestAction createAction(String actionName) throws ActionException { + RequestAction action = (RequestAction)actions.get(actionName); + if(action == null) { + try { + Class cl = Class.forName(actionName); + action = (RequestAction)cl.newInstance(); + actions.put(actionName,action); + } catch(Exception e) { + throw new ActionException("Cannot create a RequestAction. - "+actionName); + } + } + + return action; + } + */ + //-------------------------------------------------------------------- + // 200703.29 : DHLEE + // DefaultRequestAction 읠 중복사용으로 인한 DATA 공유문제 + //-------------------------------------------------------------------- + private ActionFactory() { + } + + public static RequestAction createAction(String actionName) throws ActionException { + RequestAction action = null; + try { + Class cl = Class.forName(actionName); + action = (RequestAction)cl.newInstance(); + } catch(Exception e) { + throw new ActionException("Cannot create a RequestAction. - "+actionName); + } + return action; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/action/AdapterGroupBizRequestAction.java b/src/main/java/com/eactive/eai/inbound/action/AdapterGroupBizRequestAction.java new file mode 100644 index 0000000..e5ef2be --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/AdapterGroupBizRequestAction.java @@ -0,0 +1,78 @@ +package com.eactive.eai.inbound.action; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.MessageKeyExtractor; + +/** +* 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 EAI메시지를 생성하기 위한 키값을 추출 +* 2. 처리 개요 : +* - 어뎁터의 업무그룹명을 키값앞에 추가한다. +* - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class AdapterGroupBizRequestAction extends RequestActionSupport +{ + + /** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 표준메시지를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @return String 비표준메시지의 메시지키값 + * @exception + **/ + public String[] perform(Object message) throws ActionException + { +// byte[] tmp = null; + String key[] = null; + /** + * _BPM_OU_NET_AsC{KOF} 값추출시 BPM 추출 + * _BPM_OU_NET_AsC 값추출시 BPM 추출 + */ + String adptGrpName = adapterGroupName; + + if (adptGrpName != null && adptGrpName.length() >= 4 ){ + adptGrpName = adptGrpName.substring(1,4); + } + + if (logger.isDebug()) { + if(message instanceof byte[]) { +// tmp = (byte[])message; + logger.debug(adapterName+"] received data >> ["+ new String((byte[])message) +"]"); + + }else if (message instanceof String) { +// tmp = ((String)message).getBytes(); + logger.debug(adapterName+"] received data >> ["+ (String)message +"]"); + } + else{ + logger.debug(adapterName+"] received data >> ["+ message +"]"); +// throw new ActionException(ExceptionUtil.getErrorCode(null, "RECEAIIRA001")); + } + } + + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message, true, true); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + + + + for(int i=0; i= 4 + ){ + chnl = adptGrpName.substring(1,4); + } + if (adptGrpName != null + && adptGrpName.length() >= 4 + && adptGrpName.indexOf("{") >= 0 + && adptGrpName.indexOf("}") >= 0 + && adptGrpName.indexOf("{") < adptGrpName.indexOf("}") + ){ + int start = adptGrpName.indexOf("{")+1; + int end = adptGrpName.indexOf("}"); + inst = adptGrpName.substring(start,end); + } + if ("".equals(chnl) && "".equals(inst)){ + ; + }else{ + adptGrpName = chnl + inst; + } + + + if(message instanceof byte[]) { + tmp = (byte[])message; + }else if (message instanceof String) { + tmp = ((String)message).getBytes(); + }else{ + throw new ActionException(ExceptionUtil.getErrorCode(null, "RECEAIIRA001")); + } + + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, tmp, true, true); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + + if (logger.isDebug()) logger.debug(adapterName+"] received data >> ["+ new String(tmp)+"]"); + + for(int i=0; i> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + for(int i=0; i> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + for(int i=0; i> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + return key; + } + + public String getDescription() { + return "키추출방식 : 추출키값"; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/action/RequestAction.java b/src/main/java/com/eactive/eai/inbound/action/RequestAction.java new file mode 100644 index 0000000..e92e3a9 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/RequestAction.java @@ -0,0 +1,19 @@ +package com.eactive.eai.inbound.action; + +import java.util.Properties; + +public interface RequestAction +{ + /** + * Inbound Adapter 이름을 초기화 한다. + */ + public void setAdapterInfo(String adapterGroupName, String adapterName, Properties prop); + + /** + * input message로 부터 업무 Key 필드를 생성 반환한다. + */ + public String[] perform(Object message) throws ActionException; + + public String getDescription(); + +} diff --git a/src/main/java/com/eactive/eai/inbound/action/RequestActionSupport.java b/src/main/java/com/eactive/eai/inbound/action/RequestActionSupport.java new file mode 100644 index 0000000..7e8a3ff --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/RequestActionSupport.java @@ -0,0 +1,64 @@ +package com.eactive.eai.inbound.action; + +import java.util.Properties; + +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.messagekey.MessageKeyFldVO; +import com.eactive.eai.common.messagekey.MessageKeyManager; +import com.eactive.eai.common.messagekey.MessageKeyVO; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageKeyExtractor; +import com.eactive.eai.common.util.MessageUtil; + +public class RequestActionSupport implements RequestAction +{ + protected String adapterGroupName; + protected String adapterName; + protected Properties prop; + + protected Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + + public void setAdapterInfo(String adapterGroupName,String adapterName, Properties prop) + { + this.adapterGroupName = adapterGroupName; + this.adapterName = adapterName; + this.prop = prop; + } + + public String[] perform(Object message) throws ActionException + { + byte[] tmp = null; + String[] key = null; + + if(message instanceof byte[]) { + tmp = (byte[])message; + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ new String(tmp)); + } else { + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + return key; + } + + @Override + public String getDescription() { + return "Action Decription"; + } + + public String getEaiBizCodeFromAdapterName(String adapterGroupName) { + String eaiBizCode = null; + + if(adapterGroupName != null && adapterGroupName.length() > 4) { + eaiBizCode = adapterGroupName.substring(1, 4); + } + return eaiBizCode; + } + +// public static void main(String[] argv) { +// RequestActionSupport s = new RequestActionSupport(); +// String adapterGroupName = "_ERF_IN_NET_AsS{KFTC}"; +// String eaiBizCode = s.getEaiBizCodeFromAdapterName(adapterGroupName); +// System.out.println(adapterGroupName + "=>" + eaiBizCode); +// } +} diff --git a/src/main/java/com/eactive/eai/inbound/action/RestAdapterMethodHeaderRequestAction.java b/src/main/java/com/eactive/eai/inbound/action/RestAdapterMethodHeaderRequestAction.java new file mode 100644 index 0000000..a83b6ee --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/RestAdapterMethodHeaderRequestAction.java @@ -0,0 +1,77 @@ +package com.eactive.eai.inbound.action; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.impl.HttpAdapterServiceRest; +import com.eactive.eai.common.messagekey.MessageKeyFldVO; +import com.eactive.eai.common.messagekey.MessageKeyGroupVO; +import com.eactive.eai.common.messagekey.MessageKeyManager; +import com.eactive.eai.common.messagekey.MessageKeyVO; +import com.eactive.eai.inbound.action.ActionException; +import com.eactive.eai.inbound.action.RequestActionSupport; + +import java.util.List; +import java.util.Properties; + +public class RestAdapterMethodHeaderRequestAction extends RequestActionSupport { + public static final String STEMSG_METHOD_DELIMITER = ":"; + + public static final String STEMSG_SERVICE_HEADER_DELIMITER = "^"; + + public static final String STEMSG_HEADER_SEPARATOR = ";"; + + /** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 표준메시지를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @return String 비표준메시지의 메시지키값 + * @exception + **/ + public String[] perform(Object message) throws ActionException { + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + String adptGrpName = adptGrpVO.getName(); + + String requestMethod = prop.getProperty(HttpAdapterServiceRest.PROPERTIES_NAME_HTTP_REQUEST_METHOD); + + String keyCode = adptGrpName + "I"; + MessageKeyManager manager = MessageKeyManager.getInstance(); + MessageKeyVO msgKey = manager.getMessageKey(keyCode); + List alMsgGroups = msgKey.getAlMsgGroups(); + int groupSize = alMsgGroups.size(); + + Properties inboundheader = (Properties) prop.get(HttpAdapterServiceKey.INBOUND_HEADER); + String[] keys = new String[groupSize]; + + if (logger.isInfo()) { + logger.info("MessageKeyExtractor] CURRENT RULE [{}]", keyCode); + } + + String baseMessageKey = adptGrpName + STEMSG_METHOD_DELIMITER + requestMethod + STEMSG_SERVICE_HEADER_DELIMITER; + + for (int g = 0; g < groupSize; g++) { + MessageKeyGroupVO groupVo = msgKey.getMessageKeyGroup(g); + int fldSize = groupVo.getMessageKeyFldLength(); + String[] keyBuffer = new String[fldSize]; + + for (int i = 0; i < fldSize; i++) { + MessageKeyFldVO keyFld = groupVo.getMessageKeyFld(i); + String tmpKey = inboundheader.getProperty(keyFld.getBwkColNm().toLowerCase(),""); + keyBuffer[i] = tmpKey; + } + String currentKey = baseMessageKey + String.join(STEMSG_HEADER_SEPARATOR, keyBuffer); + keys[g] = currentKey; + if (logger.isInfo()) { + logger.info("MessageKeyExtractor] CURRENT RULE[{}] KEY [{}]", keyCode,currentKey); + } + } + + return keys; + } + +} diff --git a/src/main/java/com/eactive/eai/inbound/action/RestAdapterMethodUrlRequestAction.java b/src/main/java/com/eactive/eai/inbound/action/RestAdapterMethodUrlRequestAction.java new file mode 100644 index 0000000..c0a4ec1 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/RestAdapterMethodUrlRequestAction.java @@ -0,0 +1,79 @@ +package com.eactive.eai.inbound.action; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.impl.HttpAdapterServiceRest; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.MessageKeyExtractor; +import com.eactive.eai.inbound.action.ActionException; +import com.eactive.eai.inbound.action.RequestActionSupport; +import org.apache.commons.lang3.StringUtils; + +public class RestAdapterMethodUrlRequestAction extends RequestActionSupport { + + /** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 표준메시지를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @return String 비표준메시지의 메시지키값 + * @exception + **/ + public String[] perform(Object message) throws ActionException { + String[] key = null; + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + String adptGrpName = adptGrpVO.getName(); + + if (StringUtils.equals(adptGrpVO.getType(), Keys.TYPE_HTTP_CUSTOM) + || StringUtils.equals(adptGrpVO.getType(), Keys.TYPE_REST)) { + try { + String requestMethod = prop + .getProperty(HttpAdapterServiceRest.PROPERTIES_NAME_HTTP_REQUEST_METHOD); + + // /api/v1/public/getUserInfo.svc + String inboundUri = prop.getProperty(HttpAdapterServiceKey.INBOUND_EXTURI); + String apiPath = prop.getProperty(HttpAdapterServiceKey.API_PATH); + + // /getUserInfo.svc + String apiUri = org.apache.commons.lang.StringUtils.removeStart(inboundUri, apiPath); + // _TST_IN_RST_SyS|POST:getUserInfo.svc + String apiKey = adptGrpName + ":" + requestMethod + "|" + StringUtils.removeStart(apiUri, "/"); + + return new String[] { apiKey }; + } catch (Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + } + + if (message instanceof byte[]) { + try { + key = MessageKeyExtractor.getMessageKeyValueForRest(this.adapterGroupName, message, prop, "url", true); + } catch (Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isDebug()) + logger.debug(adapterName + "] received data >> [" + new String((byte[]) message) + "]"); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValueForRest(this.adapterGroupName, message, prop, "url", true); + } catch (Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isDebug()) + logger.debug(adapterName + "] received data >> [" + message + "]"); + } + + for (int i = 0; i < key.length; i++) { + key[i] = adptGrpName.trim() + key[i]; + } + + return key; + } + +} diff --git a/src/main/java/com/eactive/eai/inbound/action/RestDataAdapterGroupParseRequestAction.java b/src/main/java/com/eactive/eai/inbound/action/RestDataAdapterGroupParseRequestAction.java new file mode 100644 index 0000000..f904717 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/RestDataAdapterGroupParseRequestAction.java @@ -0,0 +1,78 @@ +package com.eactive.eai.inbound.action; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageKeyExtractor; + +/** +* 1. 기능 : Rest Url 추출 용 +* 2. 처리 개요 : +* - 어뎁터의 업무그룹코드를 키값앞에 추가한다. +* - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class RestDataAdapterGroupParseRequestAction extends RequestActionSupport +{ + /** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 표준메시지를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @return String 비표준메시지의 메시지키값 + * @exception + **/ + public String[] perform(Object message) throws ActionException + { + String[] key = null; + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + String adptGrpName = adptGrpVO.getName(); + if (adptGrpName != null && adptGrpName.length() >= 4) { + String chnl = adptGrpName.substring(1, 4); + if (adptGrpName.indexOf("{") >= 0 && adptGrpName.indexOf("}") >= 0 + && adptGrpName.indexOf("{") < adptGrpName.indexOf("}")) { + int start = adptGrpName.indexOf("{") + 1; + int end = adptGrpName.indexOf("}"); + String inst = adptGrpName.substring(start, end); + adptGrpName = chnl + inst; + } else { + adptGrpName = chnl; + } + } + + if(message instanceof byte[]) { + try { + key = MessageKeyExtractor.getMessageKeyValueForRest(this.adapterGroupName, message, prop, "data", true); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isDebug()) logger.debug(adapterName+"] received data >> ["+ new String((byte[])message)+"]"); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValueForRest(this.adapterGroupName, message, prop, "data", true); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isDebug()) logger.debug(adapterName+"] received data >> ["+ message+"]"); + } + + + + for(int i=0; i= 4) { + String chnl = adptGrpName.substring(1, 4); + if (adptGrpName.indexOf("{") >= 0 && adptGrpName.indexOf("}") >= 0 + && adptGrpName.indexOf("{") < adptGrpName.indexOf("}")) { + int start = adptGrpName.indexOf("{") + 1; + int end = adptGrpName.indexOf("}"); + String inst = adptGrpName.substring(start, end); + adptGrpName = chnl + inst; + } else { + adptGrpName = chnl; + } + } + + if(message instanceof byte[]) { + try { + key = MessageKeyExtractor.getMessageKeyValueForRest(this.adapterGroupName, message, prop, "header", true); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isDebug()) logger.debug(adapterName+"] received data >> ["+ new String((byte[])message)+"]"); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValueForRest(this.adapterGroupName, message, prop, "header", true); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isDebug()) logger.debug(adapterName+"] received data >> ["+ message+"]"); + } + + + + for(int i=0; i> [" + new String((byte[]) message) + "]"); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValueForRest(this.adapterGroupName, message, prop, "header", + true); + } catch (Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isDebug()) + logger.debug(adapterName + "] received data >> [" + message + "]"); + } + + return key; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/action/RestUrlAdapterGroupParseRequestAction.java b/src/main/java/com/eactive/eai/inbound/action/RestUrlAdapterGroupParseRequestAction.java new file mode 100644 index 0000000..e4133be --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/RestUrlAdapterGroupParseRequestAction.java @@ -0,0 +1,103 @@ +package com.eactive.eai.inbound.action; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.impl.HttpAdapterServiceRest; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.MessageKeyExtractor; + +/** +* 1. 기능 : Rest Url 추출 용 +* 2. 처리 개요 : +* - 어뎁터의 업무그룹코드를 키값앞에 추가한다. +* - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class RestUrlAdapterGroupParseRequestAction extends RequestActionSupport { + + /** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 표준메시지를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @return String 비표준메시지의 메시지키값 + * @exception + **/ + public String[] perform(Object message) throws ActionException { + String[] key = null; + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + String adptGrpName = adptGrpVO.getName(); + if (adptGrpName != null && adptGrpName.length() >= 4) { + String chnl = adptGrpName.substring(1, 4); + //EIMS에서 지원하지 않아 주석 처리 +// if (adptGrpName.indexOf("{") >= 0 && adptGrpName.indexOf("}") >= 0 +// && adptGrpName.indexOf("{") < adptGrpName.indexOf("}")) { +// int start = adptGrpName.indexOf("{") + 1; +// int end = adptGrpName.indexOf("}"); +// String inst = adptGrpName.substring(start, end); +// adptGrpName = chnl + inst; +// } else { +// adptGrpName = chnl; +// } + adptGrpName = chnl; + } + + if (StringUtils.equals(adptGrpVO.getType(), Keys.TYPE_HTTP_CUSTOM) + || StringUtils.equals(adptGrpVO.getType(), Keys.TYPE_REST)) { + try { + String requestMethod = prop + .getProperty(HttpAdapterServiceRest.PROPERTIES_NAME_HTTP_REQUEST_METHOD); + + // /api/v1/public/getUserInfo.svc + String apiUri = prop.getProperty(HttpAdapterServiceKey.INBOUND_EXTURI); + + // MDIKFTC:POST/api/v1/public/getUserInfo.svc + // String apiKey = adptGrpName + ":" + requestMethod + "/" + StringUtils.removeStart(apiUri, "/"); + // MDIKFTCPOST/api/v1/public/getUserInfo.svc + String apiKey = adptGrpName + requestMethod + "/" + StringUtils.removeStart(apiUri, "/"); + + return new String[] { apiKey }; + } catch (Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + } + + if (message instanceof byte[]) { + try { + key = MessageKeyExtractor.getMessageKeyValueForRest(this.adapterGroupName, message, prop, "url", true); + } catch (Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isDebug()) + logger.debug(adapterName + "] received data >> [" + new String((byte[]) message) + "]"); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValueForRest(this.adapterGroupName, message, prop, "url", true); + } catch (Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isDebug()) + logger.debug(adapterName + "] received data >> [" + message + "]"); + } + + for (int i = 0; i < key.length; i++) { + key[i] = adptGrpName.trim() + key[i]; + } + + return key; + } + +} diff --git a/src/main/java/com/eactive/eai/inbound/action/RestUrlParseRequestAction.java b/src/main/java/com/eactive/eai/inbound/action/RestUrlParseRequestAction.java new file mode 100644 index 0000000..4a9259a --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/action/RestUrlParseRequestAction.java @@ -0,0 +1,47 @@ +package com.eactive.eai.inbound.action; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.impl.HttpAdapterServiceRest; +import com.eactive.eai.common.exception.ExceptionUtil; + +/** +* 1. 기능 : Rest Url 추출 용 +* 2. 처리 개요 : +* - 어뎁터의 업무그룹코드를 키값앞에 추가한다. +* - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class RestUrlParseRequestAction extends RequestActionSupport { + /** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 표준메시지를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @return String 비표준메시지의 메시지키값 + * @exception + **/ + public String[] perform(Object message) throws ActionException { + try { + String requestMethod = prop.getProperty(HttpAdapterServiceRest.PROPERTIES_NAME_HTTP_REQUEST_METHOD); + + // /api/v1/public/getUserInfo.svc + String apiUri = prop.getProperty(HttpAdapterServiceKey.INBOUND_EXTURI); + + // POST/api/v1/public/getUserInfo.svc + String apiKey = requestMethod + "/" + StringUtils.removeStart(apiUri, "/"); + + return new String[] { apiKey }; + } catch (Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + } +} diff --git a/src/main/java/com/eactive/eai/inbound/error/InboundErrorInfoDAO.java b/src/main/java/com/eactive/eai/inbound/error/InboundErrorInfoDAO.java new file mode 100644 index 0000000..546619b --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/error/InboundErrorInfoDAO.java @@ -0,0 +1,85 @@ +package com.eactive.eai.inbound.error; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.agent.encryption.EncryptionManager; +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ScpDbAgentUtil; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.data.entity.onl.inbound.error.InboundErrorInfo; +import com.eactive.eai.inbound.error.loader.InboundErrorInfoLoader; +import com.eactive.eai.inbound.error.mapper.InboundErrorInfoMapper; + +@Service +@Transactional +public class InboundErrorInfoDAO extends BaseDAO { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private InboundErrorInfoLoader inboundErrorInfoLoader; + + @Autowired + private InboundErrorInfoMapper inboundErrorInfoMapper; + + public void addInboundErrorInfo(InboundErrorInfoVO vo) throws DAOException { + EncryptionManager manager = EncryptionManager.getInstance(); + String bzwkDataCtnt = vo.getBwkDataTxt(); + + // 업무데이터를 암호화할 경우 길이가 늘어나는 문제가 있으므로 double check 함 + if ("Y".equalsIgnoreCase(manager.getEncryptYN())) { + if (bzwkDataCtnt.length() > 2000) { + bzwkDataCtnt = StringUtil.chunkString(bzwkDataCtnt, 2000); + } + + String encbzwkDataCtnt = null; + try { + encbzwkDataCtnt = ScpDbAgentUtil.ScpEncB64( + PropManager.getInstance().getProperties(ScpDbAgentUtil.EXT_MODULE), bzwkDataCtnt, "EUC-KR"); + } catch (Exception e) { + logger.error("addInboundErrorInfo] scpdb_agent encryption Error - " + e.getMessage()); + } + + // double check + if (encbzwkDataCtnt != null && encbzwkDataCtnt.length() > 4000) { + bzwkDataCtnt = StringUtil.chunkString(bzwkDataCtnt, 500); + try { + encbzwkDataCtnt = ScpDbAgentUtil.ScpEncB64( + PropManager.getInstance().getProperties(ScpDbAgentUtil.EXT_MODULE), bzwkDataCtnt, "EUC-KR"); + bzwkDataCtnt = encbzwkDataCtnt; + } catch (Exception e) { + logger.error("addInboundErrorInfo] scpdb_agent encryption Error - " + e.getMessage()); + } + } + } else { + bzwkDataCtnt = StringUtil.chunkString(bzwkDataCtnt, 4000); + } + + try { + vo.setErrTm((vo.getErrTm()).substring(0, 16)); + vo.setErrTxt(StringUtil.chunkString(vo.getErrTxt(), 4000)); + + String bizKey = vo.getBzwkSvcKeyName(); + if (bizKey == null) { + bizKey = ""; + } + else { + if (bizKey.length() > 40) + bizKey = bizKey.substring(0, 40); + } + vo.setBzwkSvcKeyName(bizKey); + + InboundErrorInfo entity = inboundErrorInfoMapper.toEntity(vo); + inboundErrorInfoLoader.save(entity); + } catch (Exception e) { + logger.error(e); + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAIIEI001"), e); + } + } + +} diff --git a/src/main/java/com/eactive/eai/inbound/error/InboundErrorInfoVO.java b/src/main/java/com/eactive/eai/inbound/error/InboundErrorInfoVO.java new file mode 100644 index 0000000..99c5c16 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/error/InboundErrorInfoVO.java @@ -0,0 +1,106 @@ +package com.eactive.eai.inbound.error; + +import java.io.Serializable; + +public class InboundErrorInfoVO implements Serializable { + + private String eaiSvcSno; // EAI서비스일련번호[TSEAICM04.EAISvcSerno] + private String adptBwkGrpNm; // 어댑터업무그룹명[TSEAICM04.AdptrBzwkGroupName] + private String errDstcd; // EAI에러구분코드[TSEAICM04.EAIErrDstcd] + private String eaiSvcCd; // EAI서비스코드 + private String errCd; // EAI에러코드[TSEAICM04.EAIErrCd] + private String errTxt; // EAI에러내용[TSEAICM04.EAIErrCtnt] + private String errTm; // 에러발생시각[TSEAICM04.ErrOccurHMS] + private String bwkDataTxt; // 업무데이터내용[TSEAICM04.BzwkDataCtnt] + private String eaiSvrInstNm; // EAI서버인스턴스명[TSEAICM04.EAIsevrInstncName] + private String bzwkSvcKeyName; // 업무서비스키명[TSEAICM04.BZWKSVCKEYNAME] + + public String getAdptBwkGrpNm() { + return adptBwkGrpNm; + } + + public void setAdptBwkGrpNm(String adptBwkGrpNm) { + this.adptBwkGrpNm = adptBwkGrpNm; + } + + public String getBwkDataTxt() { + return bwkDataTxt; + } + + public void setBwkDataTxt(String bwkDataTxt) { + this.bwkDataTxt = bwkDataTxt; + } + + public String getEaiSvcSno() { + return eaiSvcSno; + } + + public void setEaiSvcSno(String eaiSvcSno) { + this.eaiSvcSno = eaiSvcSno; + } + + public String getEaiSvrInstNm() { + return eaiSvrInstNm; + } + + public void setEaiSvrInstNm(String eaiSvrInstNm) { + this.eaiSvrInstNm = eaiSvrInstNm; + } + + public String getErrCd() { + return errCd; + } + + public void setErrCd(String errCd) { + this.errCd = errCd; + } + + public String getErrDstcd() { + return errDstcd; + } + + public void setErrDstcd(String errDstcd) { + this.errDstcd = errDstcd; + } + + public String getErrTm() { + return errTm; + } + + public void setErrTm(String errTm) { + this.errTm = errTm; + } + + public String getErrTxt() { + return errTxt; + } + + public void setErrTxt(String errTxt) { + this.errTxt = errTxt; + } + + public String getEaiSvcCd() { + return eaiSvcCd; + } + + public void setEaiSvcCd(String eaiSvcCd) { + this.eaiSvcCd = eaiSvcCd; + } + + public String getBzwkSvcKeyName() { + return bzwkSvcKeyName; + } + + public void setBzwkSvcKeyName(String bzwkSvcKeyName) { + this.bzwkSvcKeyName = bzwkSvcKeyName; + } + + @Override + public String toString() { + return "InboundErrorInfoVO [eaiSvcSno=" + eaiSvcSno + ", adptBwkGrpNm=" + adptBwkGrpNm + ", eaiSvcCd=" + + eaiSvcCd + ", errCd=" + errCd + ", errTxt=" + errTxt + ", errTm=" + errTm + ", bwkDataTxt=" + + bwkDataTxt + ", eaiSvrInstNm=" + eaiSvrInstNm + ", errDstcd=" + errDstcd + ", bzwkSvcKeyName=" + + bzwkSvcKeyName + "]"; + } + +} diff --git a/src/main/java/com/eactive/eai/inbound/error/InboundErrorKeys.java b/src/main/java/com/eactive/eai/inbound/error/InboundErrorKeys.java new file mode 100644 index 0000000..0237a69 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/error/InboundErrorKeys.java @@ -0,0 +1,23 @@ +package com.eactive.eai.inbound.error; + +public interface InboundErrorKeys { + // SNA DFS Message + public static final String SNA_DFS = "SD"; + + // SNA TIME-OUT Message + public static final String SNA_TIMEOUT = "ST"; + + // SNA Error Message + public static final String SNA_ERROR = "SE"; + + // SNA Other Error MEssage + public static final String SNA_OTHER = "SO"; + + // Inbound Adapter를 통한 비정상 메시지 수신 + public static final String IN_UNKNOWN = "IU"; + + // Inbound Request Dispatcher에서 EAI메시지를 생성하기전 오류발생 + public static final String IN_ERROR = "IE"; + + public static final String TAS_START = "TS"; +} diff --git a/src/main/java/com/eactive/eai/inbound/error/mapper/InboundErrorInfoMapper.java b/src/main/java/com/eactive/eai/inbound/error/mapper/InboundErrorInfoMapper.java new file mode 100644 index 0000000..e00dc01 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/error/mapper/InboundErrorInfoMapper.java @@ -0,0 +1,30 @@ +package com.eactive.eai.inbound.error.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.data.entity.onl.inbound.error.InboundErrorInfo; +import com.eactive.eai.data.mapper.GenericMapper; +import com.eactive.eai.inbound.error.InboundErrorInfoVO; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface InboundErrorInfoMapper extends GenericMapper { + @Mapping(source = "eaisvcserno", target = "eaiSvcSno") + @Mapping(source = "adptrbzwkgroupname", target = "adptBwkGrpNm") + @Mapping(source = "eaierrdstcd", target = "errDstcd") + @Mapping(source = "eaierrcd", target = "errCd") + @Mapping(source = "eaierrctnt", target = "errTxt") + @Mapping(source = "erroccurhms", target = "errTm") + @Mapping(source = "bzwkdatactnt", target = "bwkDataTxt") + @Mapping(source = "eaisevrinstncname", target = "eaiSvrInstNm") + @Mapping(source = "eaisvcname", target = "eaiSvcCd") + @Mapping(source = "bzwksvckeyname", target = "bzwkSvcKeyName") + @Override + InboundErrorInfoVO toVo(InboundErrorInfo entity); + + @InheritInverseConfiguration + InboundErrorInfo toEntity(InboundErrorInfoVO vo); +} + diff --git a/src/main/java/com/eactive/eai/inbound/filter/AdapterFilter.java b/src/main/java/com/eactive/eai/inbound/filter/AdapterFilter.java new file mode 100644 index 0000000..e9a64c7 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/AdapterFilter.java @@ -0,0 +1,19 @@ +package com.eactive.eai.inbound.filter; + +public interface AdapterFilter +{ + /** + * Adapter 이름을 초기화 한다. + */ + public void setAdapterInfo(String adapterGroupName,String adapterName); + + /** + * 요청 데이타를 변환한다. + */ + public Object requestPerform(Object message) throws AdapterFilterException; + + /** + * 응답 데이타를 변환한다. + */ + public Object responsePerform(Object message) throws AdapterFilterException; +} diff --git a/src/main/java/com/eactive/eai/inbound/filter/AdapterFilterException.java b/src/main/java/com/eactive/eai/inbound/filter/AdapterFilterException.java new file mode 100644 index 0000000..97ee9e4 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/AdapterFilterException.java @@ -0,0 +1,12 @@ +package com.eactive.eai.inbound.filter; + +public class AdapterFilterException extends Exception +{ + public AdapterFilterException() { + super("FilterException is occured."); + } + + public AdapterFilterException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/inbound/filter/AdapterFilterFactory.java b/src/main/java/com/eactive/eai/inbound/filter/AdapterFilterFactory.java new file mode 100644 index 0000000..7f08282 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/AdapterFilterFactory.java @@ -0,0 +1,19 @@ +package com.eactive.eai.inbound.filter; + + +public class AdapterFilterFactory +{ + private AdapterFilterFactory() { + } + + public static AdapterFilter createFilter(String filterName) throws AdapterFilterException { + AdapterFilter action = null; + try { + Class cl = Class.forName(filterName); + action = (AdapterFilter)cl.newInstance(); + } catch(Exception e) { + throw new AdapterFilterException("Cannot create a FilterAction. - "+filterName); + } + return action; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/filter/AdapterFilterSupport.java b/src/main/java/com/eactive/eai/inbound/filter/AdapterFilterSupport.java new file mode 100644 index 0000000..71f450a --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/AdapterFilterSupport.java @@ -0,0 +1,32 @@ +package com.eactive.eai.inbound.filter; + +import com.eactive.eai.common.util.Logger; + +public class AdapterFilterSupport implements AdapterFilter +{ + protected String adapterGroupName; + protected String adapterName; + + protected Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + + public void setAdapterInfo(String adapterGroupName,String adapterName) + { + this.adapterGroupName = adapterGroupName; + this.adapterName = adapterName; + } + + @Override + public Object requestPerform(Object message) throws AdapterFilterException { + + return null; + } + + @Override + public Object responsePerform(Object message) throws AdapterFilterException { + + return null; + } + + +} diff --git a/src/main/java/com/eactive/eai/inbound/filter/InboundAsyncZipFilter.java b/src/main/java/com/eactive/eai/inbound/filter/InboundAsyncZipFilter.java new file mode 100644 index 0000000..e41a64d --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/InboundAsyncZipFilter.java @@ -0,0 +1,14 @@ +package com.eactive.eai.inbound.filter; + + +public class InboundAsyncZipFilter extends ZipFilter +{ + + @Override + public Object requestPerform(Object message) throws AdapterFilterException { + if (message instanceof byte[] ){ + return decomp((byte[])message); + } + return message; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/filter/InboundSyncZipFilter.java b/src/main/java/com/eactive/eai/inbound/filter/InboundSyncZipFilter.java new file mode 100644 index 0000000..7107be7 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/InboundSyncZipFilter.java @@ -0,0 +1,21 @@ +package com.eactive.eai.inbound.filter; + + +public class InboundSyncZipFilter extends ZipFilter +{ + @Override + public Object requestPerform(Object message) throws AdapterFilterException { + if (message instanceof byte[] ){ + return decomp((byte[])message); + } + return message; + } + + @Override + public Object responsePerform(Object message) throws AdapterFilterException { + if (message instanceof byte[]){ + return comp((byte[])message); + } + return message; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/filter/OutboundAsyncZipFilter.java b/src/main/java/com/eactive/eai/inbound/filter/OutboundAsyncZipFilter.java new file mode 100644 index 0000000..4e9a9f0 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/OutboundAsyncZipFilter.java @@ -0,0 +1,14 @@ +package com.eactive.eai.inbound.filter; + + +public class OutboundAsyncZipFilter extends ZipFilter +{ + + @Override + public Object requestPerform(Object message) throws AdapterFilterException { + if (message instanceof byte[] ){ + return comp((byte[])message); + } + return message; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/filter/OutboundSyncZipFilter.java b/src/main/java/com/eactive/eai/inbound/filter/OutboundSyncZipFilter.java new file mode 100644 index 0000000..dc35822 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/OutboundSyncZipFilter.java @@ -0,0 +1,21 @@ +package com.eactive.eai.inbound.filter; + + +public class OutboundSyncZipFilter extends ZipFilter +{ + + @Override + public Object requestPerform(Object message) throws AdapterFilterException { + if (message instanceof byte[] ){ + return comp((byte[])message); + } + return message; + } + @Override + public Object responsePerform(Object message) throws AdapterFilterException { + if (message instanceof byte[] ){ + return decomp((byte[])message); + } + return message; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/filter/ZIPUtil.java b/src/main/java/com/eactive/eai/inbound/filter/ZIPUtil.java new file mode 100644 index 0000000..b2a182f --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/ZIPUtil.java @@ -0,0 +1,92 @@ +package com.eactive.eai.inbound.filter; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +public class ZIPUtil { + + public static byte[] compress(byte[] message){ + byte[] obj = null; + ByteArrayOutputStream os = null; + GZIPOutputStream gos = null; + BufferedOutputStream bos = null; + try{ + os = new ByteArrayOutputStream(); + gos = new GZIPOutputStream(os); + bos = new BufferedOutputStream(gos); + bos.write(message); + + bos.close(); + gos.close(); + os.close(); + + obj = os.toByteArray(); + + }catch(Exception e){ + obj = message; + }finally{ + if (bos!=null) try {bos.close();} catch (IOException e) {} + if (gos!=null) try {gos.close();} catch (IOException e) {} + if (os!=null) try {os.close();} catch (IOException e) {} + } + return obj; + } + + + public static byte[] decompress(byte[] message){ + byte[] obj = null; + ByteArrayInputStream is = null; + GZIPInputStream gis = null; + BufferedInputStream bis = null; + ByteArrayOutputStream os = null; + + try{ + is = new ByteArrayInputStream(message); + gis = new GZIPInputStream(is); + bis = new BufferedInputStream(gis); + os = new ByteArrayOutputStream(); + + byte[] buffer = new byte[1024]; + + int length; + while((length = bis.read(buffer)) > 0) { + os.write(buffer, 0, length); + } + os.close(); + bis.close(); + gis.close(); + is.close(); + obj = os.toByteArray(); + }catch(Exception e){ + obj = message; + }finally { + if (os!=null) try {os.close();} catch (IOException e) {} + if (bis!=null) try {bis.close();} catch (IOException e) {} + if (gis!=null) try {gis.close();} catch (IOException e) {} + if (is!=null) try {is.close();} catch (IOException e) {} + + } + + return obj; + } + +// public static void main(String[] args) throws Exception{ +// //전체 +// //byte[] message = "00001048 000DEVCHAP_0120120509140619000002002SR10 EAI 000000 000IFWFW555555IFWCD950112TSTSYNC A2 S Y 0000 0000 0000000000000000000000000000000 KORN000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000N0000000000000000000000000000000000000000000000000000000000000000000000000000000000000FILLER IBS IO00000036IFW 0000100010@@".getBytes(); +// //150byte 이후만 +// byte[] message = "000IFWFW555555IFWCD950112TSTSYNC A2 S Y 0000 0000 0000000000000000000000000000000 KORN000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000N0000000000000000000000000000000000000000000000000000000000000000000000000000000000000FILLER IBS IO00000036IFW 0000100010@@".getBytes(); +// byte[] com = (byte[]) ZIPUtil.compress(message); +// System.out.println("compress="+ new String(com)); +// byte[] decom= (byte[]) ZIPUtil.decompress(com); +// System.out.println("decompress="+new String(decom)); +// +// ; +// +// } + +} diff --git a/src/main/java/com/eactive/eai/inbound/filter/ZipFilter.java b/src/main/java/com/eactive/eai/inbound/filter/ZipFilter.java new file mode 100644 index 0000000..0706c1e --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/filter/ZipFilter.java @@ -0,0 +1,100 @@ +package com.eactive.eai.inbound.filter; + +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.Logger; + +public class ZipFilter implements AdapterFilter +{ + private static Integer HEADER_LENGTH = 150; + private static Integer HEADER_LL_LENGTH = 8; + + protected String adapterGroupName; + protected String adapterName; + + protected Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + + public void setAdapterInfo(String adapterGroupName,String adapterName) + { + this.adapterGroupName = adapterGroupName; + this.adapterName = adapterName; + } + + @Override + public Object requestPerform(Object message) throws AdapterFilterException { + return message; + } + + @Override + public Object responsePerform(Object message) throws AdapterFilterException { + return message; + } + protected byte[] comp(byte[] msg){ + byte[] result = null; + if (msg != null && msg.length > HEADER_LENGTH ){ + byte[] header = splitHeader(msg); + byte[] data = splitData(msg); + byte[] comp = ZIPUtil.compress(data); + result = concatStdmessage(header,comp); + return result; + } + return msg; + } + protected byte[] decomp(byte[] msg){ + byte[] result = null; + if (msg != null && msg.length > HEADER_LENGTH ){ + byte[] header = splitHeader(msg); + byte[] data = splitData(msg); + byte[] decomp = ZIPUtil.decompress(data); + result = concatStdmessage(header,decomp); + return result; + } + return msg; + + } + protected byte[] splitHeader(byte[] message){ + byte[] header = new byte[HEADER_LENGTH]; + System.arraycopy(message, 0, header, 0, HEADER_LENGTH); + return header; + + } + protected byte[] splitData(byte[] message){ + byte[] data = new byte[message.length-HEADER_LENGTH]; + System.arraycopy(message, HEADER_LENGTH, data, 0, data.length); + return data; + } + protected byte[] concatStdmessage(byte[] header,byte[] data){ + + int iLen = header.length+data.length; + byte[] result = new byte[iLen]; + + /** + * header 와 압축해제한 데이타를 합침 + */ + System.arraycopy(header, 0, result, 0, HEADER_LENGTH); + System.arraycopy(data, 0, result, HEADER_LENGTH, data.length); + + + /** + * 길이보정 + */ + String len = CommonLib.getFormatString(iLen,HEADER_LL_LENGTH); + System.arraycopy(len.getBytes(), 0, result,0, HEADER_LL_LENGTH); + return result; + } + + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// ZipFilter filter = new ZipFilter(); +// byte[] message = "00001048 000DEVCHAP_0120120509140619000002002SR10 EAI 000000 000IFWFW555555IFWCD950112TSTSYNC A2 S Y 0000 0000 0000000000000000000000000000000 KORN000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000000000000000N0000000000000000000000000000000000000000000000000000000000000000000000000000000000000FILLER IBS IO00000036IFW 0000100010@@".getBytes(); +// byte[] com = (byte[]) filter.responsePerform(message); +// System.out.println("compress="+ new String(com)); +// byte[] decom= (byte[]) filter.requestPerform(com); +// System.out.println("decompress="+new String(decom)); +// } + +} diff --git a/src/main/java/com/eactive/eai/inbound/processor/GWRequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/GWRequestProcessor.java new file mode 100644 index 0000000..11ad1ee --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/processor/GWRequestProcessor.java @@ -0,0 +1,303 @@ +package com.eactive.eai.inbound.processor; + + +import java.nio.charset.Charset; +import java.util.Properties; +import java.util.UUID; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.MDC; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.common.routing.GWRemoteProxyClient; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.control.HttpSender; +import com.eactive.eai.control.SocketSender; + +public class GWRequestProcessor extends RequestProcessorSupport { + + static final String OUTBOUND_ADAPTER_GROUP_NAME = "OUTBOUND_ADAPTER_GROUP_NAME"; + static final String PAIR_ADAPTER = "PAIR_ADAPTER"; + static final String PAIR_ADAPTER_HEADER_PREFIX = "PA_"; + static Logger logger = Logger.getLogger(Logger.LOGGER_SIFT); + + protected Object hookup(Object message, Properties prop, long msgRcvTm) throws Exception { + + String inboundAdapterGroupName = prop.getProperty(Processor.ADAPTER_GROUP_NAME); + logger.debug("GWRequestProcessor] inboundAdapterGroupName: {}", inboundAdapterGroupName); + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inboundAdptGrpVO = adapterManager.getAdapterGroupVO(inboundAdapterGroupName); + + String inboundAdapterName = prop.getProperty(Processor.ADAPTER_NAME); + AdapterVO inboundAdapterVO = inboundAdptGrpVO.getAdapterVO(inboundAdapterName); + + MDC.put(Logger.DISCRIMINATOR, inboundAdapterGroupName); + logger.info(" " + getLogMessage(message)); + logger.debug(CommonLib.getDumpMessage(message)); + MDC.remove(Logger.DISCRIMINATOR); + + AdapterPropManager adapterPropManager = AdapterPropManager.getInstance(); + Properties inboundProp = adapterPropManager.getProperties(inboundAdapterVO.getPropGroupName()); + + String transactionId = null; + String instanceId = EAIServerManager.getInstance().getLocalServerName(); + + //set pair adapter + String pairAdapter = inboundProp.getProperty(PAIR_ADAPTER); + if (StringUtils.isNotBlank(inboundAdptGrpVO.getPairAdapterYn()) && "1".equals(inboundAdptGrpVO.getPairAdapterYn()) + && StringUtils.isNoneBlank(pairAdapter)) { + transactionId = PAIR_ADAPTER_HEADER_PREFIX + UUID.randomUUID().toString().substring(0, 7); + GWSessionManager.getInstance().adapterIn(transactionId, pairAdapter); + logger.debug("GWRequestProcessor] transactionId|pairAdapter: {}, {}", transactionId, pairAdapter); + } + + //set use same session + String sessionId = prop.getProperty("SESSION_ID"); + if (StringUtils.isNotBlank(sessionId)) { + transactionId = sessionId; + logger.debug("GWRequestProcessor] transactionId|sessionId: {}", sessionId); + } + + //get Outbound Adapter Group + Object resObject = null; + String outboundAdapterGroupName = inboundAdptGrpVO.getLinkedAdapterGroup(); + AdapterGroupVO outboundAdptGrpVO = adapterManager.getAdapterGroupVO(outboundAdapterGroupName); + String outboundAdapterType = outboundAdptGrpVO.getType(); //HTT, HTC, NET + + //response header + String responseTransactionId = prop.getProperty(HttpClientAdapterServiceKey.TRANSACTION_ID); + String responseInstanceId = prop.getProperty(HttpClientAdapterServiceKey.INSTANCE_ID); + if (StringUtils.isNotBlank(responseTransactionId) && StringUtils.isNotBlank(responseInstanceId)) { + if (!responseInstanceId.equals(instanceId)) { + logger.warn("GWRequestProcessor] intanceId not matched.[{}<{}>], call Remote Proxy", outboundAdapterGroupName, responseTransactionId); + resObject = callRemoteProxy(message, outboundAdapterGroupName, responseTransactionId, responseInstanceId); + + return resObject; + } + + if (!GWSessionManager.getInstance().isExists(responseTransactionId)) { + logger.error("GWRequestProcessor] No matched transactionId[{}], at {}", responseTransactionId, responseInstanceId); + throw new Exception("No matched transactionId.[" + responseTransactionId + "]"); + } + + logger.debug("GWRequestProcessor] responseTransactionId: {}", responseTransactionId); + } + + AdapterVO adptVO = outboundAdptGrpVO.nextAdapterVO(); + // 가용 Adapter가 없는 경우 + if (adptVO == null) { +// throw new Exception("No adapters available.[" + outboundAdapterGroupName + "]"); + logger.warn("GWRequestProcessor] No adapters available.[{}], call Remote Proxy", outboundAdapterGroupName); + resObject = callRemoteProxy(message, outboundAdapterGroupName); + } else { + Properties outboundProp = adapterPropManager.getProperties(adptVO.getPropGroupName()); + + Properties tempProp = new Properties(); + tempProp.setProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_OUT, + StringUtils.defaultIfBlank(outboundAdptGrpVO.getMessageEncode(), Charset.defaultCharset().name())); + + MDC.put(Logger.DISCRIMINATOR, outboundAdapterGroupName); + logger.info(" " + getLogMessage(message)); + logger.debug(CommonLib.getDumpMessage(message)); + MDC.remove(Logger.DISCRIMINATOR); + + try { + if (outboundAdapterType.equals(Keys.TYPE_HTTP) || outboundAdapterType.equals(Keys.TYPE_HTTP_CUSTOM)) { + tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME, outboundAdapterGroupName); + + //set header + if (StringUtils.isNotBlank(pairAdapter) || StringUtils.isNotBlank(sessionId)) { + String adapterHeader = "{ \"" + HttpClientAdapterServiceKey.TRANSACTION_ID + "\", \"" + transactionId + "\" }," + + "{ \"" + HttpClientAdapterServiceKey.INSTANCE_ID + "\", \"" + instanceId + "\" }"; + outboundProp.put(HttpClientAdapterServiceKey.ADAPTER_HEADER, adapterHeader); + } + + //set pair adapter + if (StringUtils.isNotBlank(responseTransactionId) && responseTransactionId.startsWith(PAIR_ADAPTER_HEADER_PREFIX)) { + tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_NAME, GWSessionManager.getInstance().getAdapter(responseTransactionId)); + GWSessionManager.getInstance().adapterOut(responseTransactionId);; + } else { + tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_NAME, adptVO.getName()); + } + + resObject = HttpSender.callService(outboundAdapterGroupName, outboundProp, message, tempProp); + } else if (outboundAdapterType.equals(Keys.TYPE_NET2)) { + tempProp.setProperty(Keys.OUT_ADAPTER_GROUP_NAME, outboundAdapterGroupName); + + //set pair adapter + if (StringUtils.isNotBlank(responseTransactionId) && responseTransactionId.startsWith(PAIR_ADAPTER_HEADER_PREFIX)) { + tempProp.setProperty(Keys.OUT_ADAPTER_NAME, GWSessionManager.getInstance().getAdapter(responseTransactionId)); + GWSessionManager.getInstance().adapterOut(responseTransactionId);; + } else { + tempProp.setProperty(Keys.OUT_ADAPTER_NAME, adptVO.getName()); + //set session + if (StringUtils.isNotBlank(responseTransactionId)) { + tempProp.setProperty(HttpClientAdapterServiceKey.TRANSACTION_ID, responseTransactionId); + } + } + + resObject = SocketSender.callService(outboundAdapterGroupName, outboundProp, message, tempProp); + } + } catch(Exception e) { + logger.warn("GW.Sender] callService " + e.getMessage(), e); + logger.warn("call Remote Proxy"); +// resObject = e.getMessage(); + resObject = callRemoteProxy(message, outboundAdapterGroupName); + } + + if (resObject != null) { + MDC.put(Logger.DISCRIMINATOR, outboundAdapterGroupName); + logger.info(" " + getLogMessage(resObject)); + logger.debug(CommonLib.getDumpMessage(resObject)); + MDC.remove(Logger.DISCRIMINATOR); + } + } + + if (resObject != null) { + MDC.put(Logger.DISCRIMINATOR, inboundAdapterGroupName); + logger.info(" " + getLogMessage(resObject)); + logger.debug(CommonLib.getDumpMessage(resObject)); + MDC.remove(Logger.DISCRIMINATOR); + } + + return resObject; + } + + public static Object callService(Object message, Properties callProp) throws Exception { + String outboundAdapterGroupName = callProp.getProperty(OUTBOUND_ADAPTER_GROUP_NAME); + String transactionId = callProp.getProperty(HttpClientAdapterServiceKey.TRANSACTION_ID); + logger.debug("GWRequestProcessor.callService] transactionId: {}", transactionId); + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO outboundAdptGrpVO = adapterManager.getAdapterGroupVO(outboundAdapterGroupName); + String outboundAdapterType = outboundAdptGrpVO.getType(); //HTT, HTC, NET + + AdapterVO adptVO = outboundAdptGrpVO.nextAdapterVO(); + // 가용 Adapter가 없는 경우 + if (adptVO == null) { + throw new Exception("GWRequestProcessor] No adapters available.[" + outboundAdapterGroupName + "]"); + } + + Object resObject = null; + AdapterPropManager manager = AdapterPropManager.getInstance(); + Properties outboundProp = manager.getProperties(adptVO.getPropGroupName()); + Properties tempProp = new Properties(); + tempProp.setProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_OUT, + StringUtils.defaultIfBlank(outboundAdptGrpVO.getMessageEncode(), Charset.defaultCharset().name())); + + MDC.put(Logger.DISCRIMINATOR, outboundAdapterGroupName); + logger.info(" " + getLogMessage(message)); + logger.debug(CommonLib.getDumpMessage(message)); + MDC.remove(Logger.DISCRIMINATOR); + + if (outboundAdapterType.equals(Keys.TYPE_HTTP) || outboundAdapterType.equals(Keys.TYPE_HTTP_CUSTOM)) { + tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME, outboundAdapterGroupName); + + //set pair adapter + if (StringUtils.isNotBlank(transactionId) && transactionId.startsWith(PAIR_ADAPTER_HEADER_PREFIX)) { + tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_NAME, GWSessionManager.getInstance().getAdapter(transactionId)); + GWSessionManager.getInstance().adapterOut(transactionId);; + } else { + tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_NAME, adptVO.getName()); + } + + resObject = HttpSender.callService(outboundAdapterGroupName, outboundProp, message, tempProp); + } else if (outboundAdapterType.equals(Keys.TYPE_NET2)) { + tempProp.setProperty(Keys.OUT_ADAPTER_GROUP_NAME, outboundAdapterGroupName); + + //set pair adapter + if (StringUtils.isNotBlank(transactionId) && transactionId.startsWith(PAIR_ADAPTER_HEADER_PREFIX)) { + tempProp.setProperty(Keys.OUT_ADAPTER_NAME, GWSessionManager.getInstance().getAdapter(transactionId)); + GWSessionManager.getInstance().adapterOut(transactionId);; + } else { + tempProp.setProperty(Keys.OUT_ADAPTER_NAME, adptVO.getName()); + //set session + if (StringUtils.isNotBlank(transactionId)) { + tempProp.setProperty(HttpClientAdapterServiceKey.TRANSACTION_ID, transactionId); + } + } + + resObject = SocketSender.callService(outboundAdapterGroupName, outboundProp, message, tempProp); + } + + if (resObject != null) { + MDC.put(Logger.DISCRIMINATOR, outboundAdapterGroupName); + logger.info(" " + getLogMessage(resObject)); + logger.debug(CommonLib.getDumpMessage(resObject)); + MDC.remove(Logger.DISCRIMINATOR); + } + + return resObject; + } + + public static String getLogMessage(Object obj) { + String message = null; + int size = 0; + if(obj instanceof byte[]) { + message = new String((byte[]) obj); + size = ((byte[]) obj).length; + } + else if(obj instanceof String) { + message = (String) obj; +// size = (((String) obj).getBytes()).length; + size = ((String) obj).length(); + } + + StringBuffer logMessage = new StringBuffer(); + logMessage.append("size[" + size + "], message[" + message + "]"); + + return logMessage.toString(); + } + + public String getRemoteCallUrl(String instanceId) { + EAIServerManager mgr = EAIServerManager.getInstance(); + EAIServerVO server, backupSvr = null; + if (instanceId == null) { + server = mgr.getEAIServer(mgr.getLocalServerName()); + backupSvr = mgr.getEAIServer(server.getFailoverSvr()); + } else { + backupSvr = mgr.getEAIServer(instanceId); + } + + + StringBuffer urlBuf = new StringBuffer(); + urlBuf.append(EAIServerVO.IIOP_PROTOCOL).append("://"); + urlBuf.append(backupSvr.getAddress()).append(":"); + urlBuf.append(backupSvr.getRmiPort()); + + return urlBuf.toString(); + } + + public Object callRemoteProxy(Object message, String outboundAdapterGroupName) { + return callRemoteProxy(message, outboundAdapterGroupName, null, null); + } + + private Object callRemoteProxy(Object message, String outboundAdapterGroupName, String responseTransactionId, String responseInstanceId) { + Properties callProp = new Properties(); + callProp.setProperty(RouteKeys.REMOTE_CALL_URL, getRemoteCallUrl(responseInstanceId)); + callProp.setProperty(OUTBOUND_ADAPTER_GROUP_NAME, outboundAdapterGroupName); + if (responseTransactionId != null) + callProp.setProperty(HttpClientAdapterServiceKey.TRANSACTION_ID, responseTransactionId); + + Object resObject = null; + + try { + resObject = GWRemoteProxyClient.callProxyBean(message, callProp); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return resObject; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/inbound/processor/GWSessionManager.java b/src/main/java/com/eactive/eai/inbound/processor/GWSessionManager.java new file mode 100644 index 0000000..919b43b --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/processor/GWSessionManager.java @@ -0,0 +1,91 @@ +package com.eactive.eai.inbound.processor; + +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.mina.common.IoSession; +import com.eactive.eai.common.util.Logger; + +public class GWSessionManager { + private static final Logger logger = Logger.getLogger(Logger.LOGGER_SIFT); + + private static volatile GWSessionManager instance; + private final ConcurrentHashMap sessionMap; + private final ConcurrentHashMap adapterMap; + + private GWSessionManager() { + this.sessionMap = new ConcurrentHashMap<>(); + this.adapterMap = new ConcurrentHashMap<>(); + } + + public static GWSessionManager getInstance() { + if (instance == null) { + synchronized (GWSessionManager.class) { + if (instance == null) { + instance = new GWSessionManager(); + } + } + } + return instance; + } + + public ConcurrentHashMap getSessionList() { + return sessionMap; + } + + public synchronized void sessionIn(String sessionId, IoSession session) throws Exception { + logger.info("GWSessionManager ] sessionIn - [{}, {}]", sessionId, (session != null) ? session.toString() : "null"); + if (sessionId != null && session != null) { + sessionMap.put(sessionId, session); + } + } + + public synchronized void sessionOut(String sessionId) { + logger.info("GWSessionManager ] sessionOut - [{}]", sessionId); + if (sessionId != null && sessionMap.containsKey(sessionId)) { + sessionMap.remove(sessionId); + } + } + + public synchronized IoSession getSession(String sessionId) { + if (sessionId != null) { + IoSession session = sessionMap.get(sessionId); + logger.info("GWSessionManager ] getSession - [{}, {}]", sessionId, (session != null) ? session.toString() : "null"); + return session; + } + return null; + } + + public ConcurrentHashMap getAdapterList() { + return adapterMap; + } + + public synchronized void adapterIn(String adapterId, String adapterName) throws Exception { + logger.info("GWSessionManager ] adapterIn - [{}, {}]", adapterId, adapterName); + if (adapterId != null && adapterName != null) { + adapterMap.put(adapterId, adapterName); + } + } + + public synchronized void adapterOut(String adapterId) { + logger.info("GWSessionManager ] adapterOut - [{}]", adapterId); + if (adapterId != null && adapterMap.containsKey(adapterId)) { + adapterMap.remove(adapterId); + } + } + + public synchronized String getAdapter(String adapterId) { + if (adapterId != null) { + String adapterName = adapterMap.get(adapterId); + logger.info("GWSessionManager ] getAdapter - [{}, {}]", adapterId, adapterName); + return adapterName; + } + return null; + } + + public boolean isExists(String transactionId) { + if (getSession(transactionId) != null || getAdapter(transactionId) != null) { + return true; + } + return false; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/processor/ProcessVO.java b/src/main/java/com/eactive/eai/inbound/processor/ProcessVO.java new file mode 100644 index 0000000..ae2c47c --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/processor/ProcessVO.java @@ -0,0 +1,157 @@ +package com.eactive.eai.inbound.processor; + +import com.eactive.eai.common.message.EAIMessageKeys; + +/** + * request process 에서 사용하기 위한 vo + * + * 추후에는 전역 Context용도로 쓰일수 있음 + * + * @author short11 + * + */ +public class ProcessVO +{ + //unknow 메시지정보 시작 + private String uuid = null;// + private String adapterGroupName = null;// + private String adapterName = null;// + + private String eaiSvcCd = null;// + private boolean isTasStarted = false;// + private long errTm = 0;// + private String errTypeCode = null;// + //에러정보 + private String rspErrorCode = EAIMessageKeys.EAI_DEFAULT_CODE; + private String rspErrorMsg = null; + + //server정보 + private String serverName = null;// + + private String selectedKey = null; + //unknow 메시지정보 종료 + + + //프라퍼티정보 + private String actionName = null;// + private String stdMsgTypeCode = null;// // [K, N] 값을 가짐 : Standard, Non-Standard + + //어댑터정보 + private String adptrMsgType = null;// + private String inAdapterOsidInstiNo = null;// + private String testMasterYn = null;// + private String bidInterface = null;// + private String inAdapterUserEmpid = null;// + + public String getUuid() { + return uuid; + } + public void setUuid(String uuid) { + this.uuid = uuid; + } + public String getAdapterGroupName() { + return adapterGroupName; + } + public void setAdapterGroupName(String adapterGroupName) { + this.adapterGroupName = adapterGroupName; + } + public String getAdapterName() { + return adapterName; + } + public void setAdapterName(String adapterName) { + this.adapterName = adapterName; + } + public String getEaiSvcCd() { + return eaiSvcCd; + } + public void setEaiSvcCd(String eaiSvcCd) { + this.eaiSvcCd = eaiSvcCd; + } + public boolean isTasStarted() { + return isTasStarted; + } + public void setTasStarted(boolean isTasStarted) { + this.isTasStarted = isTasStarted; + } + public long getErrTm() { + return errTm; + } + public void setErrTm(long errTm) { + this.errTm = errTm; + } + + public String getErrTypeCode() { + return errTypeCode; + } + public void setErrTypeCode(String errTypeCode) { + this.errTypeCode = errTypeCode; + } + public String getActionName() { + return actionName; + } + public void setActionName(String actionName) { + this.actionName = actionName; + } + public String getStdMsgTypeCode() { + return stdMsgTypeCode; + } + public void setStdMsgTypeCode(String stdMsgTypeCode) { + this.stdMsgTypeCode = stdMsgTypeCode; + } + public String getAdptrMsgType() { + return adptrMsgType; + } + public void setAdptrMsgType(String adptrMsgType) { + this.adptrMsgType = adptrMsgType; + } + public String getInAdapterOsidInstiNo() { + return inAdapterOsidInstiNo; + } + public void setInAdapterOsidInstiNo(String inAdapterOsidInstiNo) { + this.inAdapterOsidInstiNo = inAdapterOsidInstiNo; + } + public String getRspErrorCode() { + return rspErrorCode; + } + public void setRspErrorCode(String rspErrorCode) { + this.rspErrorCode = rspErrorCode; + } + public String getRspErrorMsg() { + return rspErrorMsg; + } + public void setRspErrorMsg(String rspErrorMsg) { + this.rspErrorMsg = rspErrorMsg; + } + + public String getTestMasterYn() { + return testMasterYn; + } + public void setTestMasterYn(String testMasterYn) { + this.testMasterYn = testMasterYn; + } + public String getServerName() { + return serverName; + } + public void setServerName(String serverName) { + this.serverName = serverName; + } + public String getBidInterface() { + return bidInterface; + } + public void setBidInterface(String bidInterface) { + this.bidInterface = bidInterface; + } + public String getSelectedKey() { + return selectedKey; + } + public void setSelectedKey(String selectedKey) { + this.selectedKey = selectedKey; + } + public String getInAdapterUserEmpid() { + return inAdapterUserEmpid; + } + public void setInAdapterUserEmpid(String inAdapterUserEmpid) { + this.inAdapterUserEmpid = inAdapterUserEmpid; + } + +} diff --git a/src/main/java/com/eactive/eai/inbound/processor/Processor.java b/src/main/java/com/eactive/eai/inbound/processor/Processor.java new file mode 100644 index 0000000..cc13aa5 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/processor/Processor.java @@ -0,0 +1,19 @@ +package com.eactive.eai.inbound.processor; + +import java.util.Properties; + +public interface Processor +{ + public static final String ADAPTER_GROUP_NAME = "ADAPTER_GROUP_NAME"; + public static final String ADAPTER_NAME = "ADAPTER_NAME"; + + public static final String STD_MESSAGE = "STD_MESSAGE"; + public static final String REQUEST_ACTION = "REQUEST_ACTION"; + + public static final String MESSAGE_TYPE = "MESSAGE_TYPE"; + + public static final String TAS_ADAPTER_GROUP_NAME = "TAS_ADAPTER_GROUP_NAME"; + + public Object execute(Object message, Properties prop) throws Exception; + +} diff --git a/src/main/java/com/eactive/eai/inbound/processor/ProcessorFactory.java b/src/main/java/com/eactive/eai/inbound/processor/ProcessorFactory.java new file mode 100644 index 0000000..08b21d1 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/processor/ProcessorFactory.java @@ -0,0 +1,35 @@ +package com.eactive.eai.inbound.processor; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.message.StandardMessageUtil; + +@SuppressWarnings("unchecked") +public class ProcessorFactory +{ + private static Processor processor ; + static{ + Class processorClass = null; + try { + if (Keys.EAI_SYSTEM_TYPE_GW.equals(System.getProperty(Keys.EAI_SYSTEM_TYPE))) { + processorClass = (Class) Class.forName("com.eactive.eai.inbound.processor.GWRequestProcessor"); + } else if (StringUtils.isBlank(StandardMessageUtil.requestProcessorClass)) { + processorClass = (Class) Class.forName("com.eactive.eai.inbound.processor.RequestProcessor"); + } else { + processorClass = (Class) Class.forName(StandardMessageUtil.requestProcessorClass); + } + + processor = processorClass.newInstance(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private ProcessorFactory() { + } + + public static Processor newInstance() { + return processor; + } +} diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java new file mode 100644 index 0000000..eb38a42 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessor.java @@ -0,0 +1,1377 @@ +package com.eactive.eai.inbound.processor; + +import java.util.Calendar; +import java.util.Properties; +import java.util.Set; + +import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.util.*; +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpStatus; + +import com.eactive.eai.authserver.service.OAuth2Manager; +import com.eactive.eai.authserver.vo.ClientVO; +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.Keys; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceSupport; +import com.eactive.eai.common.bizkey.BizKeyManager; +import com.eactive.eai.common.bizkey.BizKeyVO; +import com.eactive.eai.common.dao.DAOFactory; +import com.eactive.eai.common.errorcode.ErrorCodeHandler; +import com.eactive.eai.common.exception.ExceptionHandler; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.inflow.Bucket; +import com.eactive.eai.common.inflow.InflowControlDAO; +import com.eactive.eai.common.inflow.InflowControlUtil; +import com.eactive.eai.common.inflow.InflowTargetVO; +import com.eactive.eai.common.logger.EAILogSender; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.EAIMessageManager; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.restrict.RestrictInfoManager; +import com.eactive.eai.common.restrict.RestrictInfoVO; +import com.eactive.eai.common.routing.FlowRouter; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +//import com.eactive.eai.common.stdmessage.STDMessageManager; +import com.eactive.eai.common.stdmessage.STDMessageMapper; +import com.eactive.eai.inbound.action.ActionException; +import com.eactive.eai.inbound.action.ActionFactory; +import com.eactive.eai.inbound.action.RequestAction; +import com.eactive.eai.inbound.error.InboundErrorKeys; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.StandardMessageUtil; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.mapper.MessageMapper; +import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.message.service.InterfaceMapper; +import com.eactive.eai.util.SimHeaderUtil; +import com.ext.eai.common.stdmessage.STDMessageKeys; +//import org.apache.commons.lang3.StringUtils; +//import org.springframework.http.HttpStatus; + +//import java.util.Calendar; +//import java.util.Properties; + +/** + * 1. 기능 : Inbound Adapter를 통해 전달 받은 메시지를 EAIMessage로 변환하고 + * FlowControl로 전달하는 기능을 제공한다. + * 2. 처리 개요 : + * - ExtMessage 생성 + * - EAIMessage 생성 + * - 요청 거래로깅 + * - FlowControl 호출 + * - 응답 거래로깅 + * 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : + * @since : + * : + */ + +public class RequestProcessor extends RequestProcessorSupport { + + private static String instid = null; + private static String serverName = null; + //private static boolean isPEAIServer = true; + + static { + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + serverName = eaiServerManager.getLocalServerName(); + + //isPEAIServer = eaiServerManager.isPEAIServer(); + instid = eaiServerManager.getGroupInstId(); + } + + private ProcessVO setVO(Properties prop,long msgRcvTm) throws RequestProcessorException{ + String actionName = prop.getProperty(Processor.REQUEST_ACTION); + String adapterGroupName = prop.getProperty(Processor.ADAPTER_GROUP_NAME); + String adapterName = prop.getProperty(Processor.ADAPTER_NAME); + String adptrMsgPtrnCd = prop.getProperty(Processor.STD_MESSAGE); + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + + String adptrMsgType = ""; + String inAdapterOsidInstiNo = ""; + + if(adptGrpVO == null) { + logger.warn("Inbound Adapter is NULL - " +adapterGroupName); + throw new RequestProcessorException("inbound adapter is null : "+ adapterGroupName); + } + + adptrMsgType = adptGrpVO.getMessageType(); + + // Adapter의 기관코드를 얻어온다. + inAdapterOsidInstiNo = adptGrpVO.getOsidInstiNo(); + // Adapter의 텔러번호를 얻어온다. ※JBBEXT※ 추가필요 20210202 + String inAdapterUserEmpid = "";//adptGrpVO.getUserEmpid(); + String bidInterface = adptGrpVO.getBidInterface(); + String testMasterYn = adptGrpVO.getTestMasterYn(); + + // UUID 생성 : UUID = server구분4자리 + UUID + String uuid = ""; + + if(instid != null) { + uuid = instid + UUIDGenerator.getUUID(); + if (logger.isDebug()) logger.debug("RequestProcessor] UUID ["+uuid+"]"); + } + else { + String rspErrorCode = "RECEAIIRP030"; + String rspErrorMsg = ErrorCodeHandler.getMessage(rspErrorCode); + if (logger.isError()) logger.error(rspErrorMsg); + throw new RequestProcessorException(rspErrorMsg); + } + + ProcessVO vo = new ProcessVO(); + vo.setAdapterGroupName(adapterGroupName); + vo.setAdapterName(adapterName); + vo.setActionName(actionName); + vo.setStdMsgTypeCode(adptrMsgPtrnCd); + vo.setTasStarted(false); + vo.setAdptrMsgType(adptrMsgType); + vo.setInAdapterOsidInstiNo(inAdapterOsidInstiNo); + vo.setUuid(uuid); + vo.setServerName(serverName); + vo.setBidInterface(bidInterface); + vo.setErrTm(msgRcvTm); + vo.setTestMasterYn(testMasterYn); + vo.setInAdapterUserEmpid(inAdapterUserEmpid); + + return vo; + } + + + /** + * 1. 기능 : Inbound Adapter를 통해 전달 맏은 메시지를 EAIMessage로 변환하고 + * FlowControl로 전달하는 기능을 제공한다. + * 2. 처리 개요 : + * - STDMessage 생성 + * - EAIMessage 생성 + * - 요청 거래로깅 + * - FlowControl 호출 + * - 응답 거래로깅 + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @param prop 호출시 전달할 Property 값(추후 확장을 위해) + * @param msgRcvTm 메시지 수신시각 + * @return Object + * @throws Exception + **/ + protected Object hookup(Object message, Properties prop, long msgRcvTm) throws Exception { + EAIMessage retEaiMsg = null; + + ProcessVO vo = setVO(prop, msgRcvTm); + prop.setProperty(TransactionContextKeys.TRANSACTION_UUID, vo.getUuid()); + + String inboundCharset = prop.getProperty(Keys.CHARSET_KEY_IN); + + // Unknown Message 로깅시 표준메시지일 경우 원본 자체를 남기기 위해 변수로 저장한다. + // logUnknownMessage 호출시 사용하도록 함 + Object orgMessage = null; + try { + if (message instanceof String) { + orgMessage = message; + } else if (message instanceof byte[]) { +// orgMessage = ObjectUtil.deepCopy(message); + orgMessage = (byte[])message; + } + } catch (Exception e1) { + logger.error("deep copy error : " + e1.getMessage(), e1); + } + + // 2. StandardMessage 생성 + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + InterfaceMapper mapper = standardManager.getMapper(); + StandardMessage subMessage = null; + + if(Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode())) { + if (logger.isDebug()) logger.debug("RequestProcessor] Get Message from INPUT MESSAGE"); + try { + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(vo.getAdptrMsgType()); + reader.parse(standardMessage, message); + // 표준전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(inboundCharset); + standardManager.getMessageCoordinator().coordinateAfterParsing(standardMessage, vo, prop); + + } catch(Exception e) { + vo.setRspErrorCode("RECEAIIRP008"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{ e.getMessage()})); + vo.setErrTypeCode(InboundErrorKeys.IN_UNKNOWN); + if (logger.isError()) logger.error(vo.getRspErrorMsg(), e); + logUnknownMessage(vo,orgMessage); + throw new RequestProcessorException(vo.getRspErrorMsg()); + } + } + else { + try { + if(eaiServerManager.isTASEnabledEAIServer() && Keys.TESTMASTER_TAS.equals(vo.getTestMasterYn())) { //비표준 시뮬레이터 + if (logger.isDebug()) logger.debug("RequestProcessor] Get STDMessage from SIM Header data"); + if (message instanceof byte[]) { + vo = SimHeaderUtil.getSimHeader(vo, (byte[])message); + message = SimHeaderUtil.getSimData((byte[])message); + + String adpterGroup = vo.getAdapterGroupName();//여기서는 SIM 어댑터 + //인터페이스ID로 어댑터명 추출 + EAIMessageManager eaiMsgManager = EAIMessageManager.getInstance(); + EAIMessage tmpMsg = eaiMsgManager.getEAIMessage(vo.getEaiSvcCd()); + if (tmpMsg != null){ + adpterGroup = tmpMsg.getSngSysItfTp(); //인터페이스에 설정된 어댑터로 변경 + } + + if (StringUtils.isNotBlank(adpterGroup)) { + AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(adpterGroup); + String inAdapterUserEmpid = gvo.getOsidInstiNo(); // 사용자ID로 변경되야됨 + vo.setInAdapterUserEmpid(inAdapterUserEmpid); + } + // read from Rule + standardMessage = StandardMessageUtil.getStandardMessageFromRule(message, vo, inboundCharset, prop); + } + } + else { + // 1. 전문 고유번호 추출 - RequestAction 실행 + String[] keys = null; + + if(vo.getActionName() != null ) { + try { + RequestAction action = ActionFactory.createAction(vo.getActionName()); + action.setAdapterInfo(vo.getAdapterGroupName(), vo.getAdapterName(), prop); + keys = action.perform(message); + } + catch(Exception ex) { + if(Keys.IF_SUBSTANDARD.equals(vo.getStdMsgTypeCode())) { + if (logger.isWarn()) logger.warn("RequestProcessor] SUBSTANDARD Skip messageKey Error", ex); + } + else { + throw ex; + } + } + } else { + if (logger.isInfo()) logger.info("RequestProcessor] The RequestAction is null in Adapter properties. - "+vo.getAdapterName()); + } + + if (keys != null) { + if (logger.isDebug() ) { + for(int i=0; i duplicationKeys = org.springframework.util.StringUtils.commaDelimitedListToSet(duplicationKey); + if (duplicationKeys.contains(channelTypeCd)){ + // 중복체크 + boolean isDup = false; + try { + DuplicationGuidLogUtil.insert(guid + guidSeq, channelTypeCd, vo, orgMessage); + } catch (Exception e) { + isDup = true; + } + if (isDup) { + vo.setRspErrorCode("RECEAIIRP130"); + vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), new String[] { channelTypeCd, guid + guidSeq})); + vo.setErrTypeCode(InboundErrorKeys.IN_UNKNOWN); + if (logger.isError()) logger.error(vo.getRspErrorMsg()); + logUnknownMessage(vo, orgMessage); + return getInboundErrorResponse(prop, standardMessage, mapper, vo.getRspErrorCode(), vo.getRspErrorMsg(), inboundCharset); + } + } + } + } + } + prop.setProperty(TransactionContextKeys.GUID, guid); + + // INBOUND_HEADER 가 NULL인 경우는 HTTP가 아닌것으로 간주함. + if(prop.get(HttpClientAdapterServiceKey.INBOUND_HEADER) != null) { + HttpAdapterExtraLogUtil.insertHttpAdapterExtraLog(vo.getUuid(), 100, + prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME), + prop.getProperty(HttpClientAdapterServiceKey.ADAPTER_NAME), + (Properties) prop.get(HttpClientAdapterServiceKey.INBOUND_HEADER), + prop.getProperty(HttpClientAdapterServiceKey.INBOUND_EXTURI), + prop.getProperty(HttpClientAdapterServiceKey.INBOUND_METHOD)); + } + + EAIMessage eaiMsg = null; + try { + EAIMessageManager eaiMsgManager = EAIMessageManager.getInstance(); + eaiMsg = eaiMsgManager.getEAIMessage(vo.getEaiSvcCd()); + } + catch(Exception e) { + vo.setRspErrorCode("RECEAIIRP020"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()})); + vo.setErrTypeCode(InboundErrorKeys.IN_ERROR); + if (logger.isError()) logger.error(vo.getRspErrorMsg()); + logUnknownMessage(vo,orgMessage); + return getInboundErrorResponse(prop, standardMessage, mapper, vo.getRspErrorCode(), vo.getRspErrorMsg(), inboundCharset); + } + + if(eaiMsg == null) { + vo.setRspErrorCode("RECEAIIRP020"); + vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), vo.getEaiSvcCd() )); + vo.setErrTypeCode(InboundErrorKeys.IN_ERROR); + if (logger.isError()) logger.error(vo.getRspErrorMsg()); + logUnknownMessage(vo,orgMessage); + return getInboundErrorResponse(prop, standardMessage, mapper, vo.getRspErrorCode(), vo.getRspErrorMsg(), inboundCharset); + } + + // set standardMessage & mapper to EAIMessage + eaiMsg.setStandardMessage(standardMessage); + eaiMsg.setMapper(mapper); + eaiMsg.setClientId(prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID)); + eaiMsg.setClientIp(prop.getProperty(HttpAdapterServiceKey.INBOUND_CLIENT_IP)); + String psvItfTp = eaiMsg.getCurrentSvcMsg().getPsvItfTp(); + svrLogLevel = eaiMsg.getSvrLogLvl(); + if(svrLogLevel >= 1) { + if (esbLogger.isInfo()) esbLogger.info("RequestProcessor] started... - EAI Server Log Level is INFO"); + } + + // 3-1. 수신메시지와 초기값을 EAIMessage에 설정한다. + // 메시지 수신시각 설정 + eaiMsg.setMsgRcvTm(vo.getErrTm()); + String svcTsmtUsgTp = eaiMsg.getSvcTsmtUsgTp(); + prop.setProperty(HttpAdapterServiceKey.INBOUND_SYNC_ASYNC_TYPE, svcTsmtUsgTp); + + //------------------------------------------------- + // 시스템운영환경구분코드 매핑 + // 차세대 표준 EAI + // PROD O P + // DR R P + // STAGING S S + // DEVELOP D D + //------------------------------------------------- + + String sysOperEvirnDstcd = mapper.getOperationEnv(standardMessage);//운영환경 구분코드 + if( !(Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode())) ) { + if (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp)) { + mapper.setSyncAsyncType(standardMessage, STDMessageKeys.SYNC_ASYNC_CD_ASYNC); + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(mapper.getSendRecvDivision(standardMessage))) { + // 정상셋팅 + String procsRsltDvcd = mapper.getResponseType(standardMessage); + if (StringUtils.isBlank(procsRsltDvcd)) { + mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_N); + } + } + } else if (EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp)) { + mapper.setSyncAsyncType(standardMessage, STDMessageKeys.SYNC_ASYNC_CD_SYNC); + } + } + + + // NON STANDARD guid 설정 + // 표준 Prod 기동 시스템의 UUID가 setting 안되어 있으면 Error + // 표준 개발,테스트 기동시스템의 UUID가 Setting 안되어 있으면 EAI에서 Setting + String intgraTelgmUniqno = mapper.getGuid(standardMessage); + if( Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode()) ) { + if(StringUtils.isEmpty(intgraTelgmUniqno)) { + // 표준 Prod 기동 시스템에서 UUID 셋팅 안한 경우 예외 처리 + vo.setRspErrorCode("RECEAIIRP011"); + vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), vo.getEaiSvcCd() )); + if (logger.isError()) logger.error(vo.getRspErrorMsg()); + return getInboundErrorResponse(prop, standardMessage, mapper, vo.getRspErrorCode(), vo.getRspErrorMsg(), inboundCharset); + } + } + else { + if (logger.isDebug()) logger.debug("RequestProcessor] IF_NONSTANDARD MESSAGE 통합전문일련번호 - " + + guid + guidSeq); + } + + String guidLogPrefix = "RequestProcessor] GUID[" + guid + "][" + guidSeq + "] UUID["+vo.getUuid()+"] "; + if(svrLogLevel >= 1) { + if (esbLogger.isInfo()) esbLogger.info(guidLogPrefix + " START"); + } + + if(logger.isInfo()) logger.info(guidLogPrefix); + + // Inbound AdapterGroup Name 설정 + eaiMsg.setSngSysItfTp(vo.getAdapterGroupName()); + eaiMsg.setSvcOgNo(vo.getUuid()); + // Current EAIServerInstanceName setting + eaiMsg.setEAISvrInstNm(serverName); + // StringServiceClassification setting (ESBFW | TIMER | EXCEPTION) + eaiMsg.setSngSvcCls(STARTING_SERVICE_KEY); + eaiMsg.setStdMsgUsgCls(vo.getStdMsgTypeCode()); + + //---------------------------------------------- + // LogSequence 설정 + // 요청거래의 경우 100 + // 응답거래의 경우 300으로 설정한다. + //---------------------------------------------- + if(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) ) { + if( STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + eaiMsg.setLogPssSno(300); + } + else { + eaiMsg.setLogPssSno(100); + } + } + else { + eaiMsg.setLogPssSno(100); + } + + if(Keys.IF_SUBSTANDARD.equals(vo.getStdMsgTypeCode())) { + // 응답시 복원을 위해 저장 + eaiMsg.setSubMessage(subMessage); + if(subMessage !=null && logger.isDebug()) { + logger.debug( String.format("RequestProcessorSupport] SUBSTANDARD-LOGGING SAVE UUID: %s, LOGSEQ: %s, HEADER: %s", + eaiMsg.getSvcOgNo(), eaiMsg.getLogPssSno(), subMessage.toFixedString(false)) ); + } + } + + try { + eaiMsg.setRspErrCd(vo.getRspErrorCode()); + } catch(Exception e) { + vo.setRspErrorCode("RECEAIIRP040"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()})); +// eaiMsg.setRspErrCd(vo.getRspErrorCode()); +// eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); + eaiMsg.setRspErr(vo.getRspErrorCode(),vo.getRspErrorMsg()); + + try { + EAILogSender.send(eaiMsg, null); + if (logger.isError()) logger.error(guidLogPrefix + " : Log 성공 - " + vo.getRspErrorMsg()); + } catch(Exception ex) { + if (logger.isError()) logger.error(guidLogPrefix + " : Log 실패 - " + vo.getRspErrorMsg()); + } + prop.setProperty(EAIMessageKeys.ELINK_RET_CODE, eaiMsg.getRspErrCd()); + return getInboundErrorResponse(prop, standardMessage, mapper, vo.getRspErrorCode(), vo.getRspErrorMsg(), inboundCharset); + } + + if( EAIMessageKeys.TRANTYPE_STOP.equals(eaiMsg.getTranType()) ) { + try { + EAILogSender.send(eaiMsg, null); + if (logger.isError()) logger.error(guidLogPrefix + " : TRANTYPE_STOP : "+vo.getEaiSvcCd()+", DB Log 성공"); + } catch(Exception ex) { + if (logger.isError()) logger.error(guidLogPrefix + " : TRANTYPE_STOP: "+vo.getEaiSvcCd()+", DB Log 실패"); + } + return null; + } + + // 5. 추적관리필드 추출 + // 동기호출이 아닌 경우에 추적관리필드를 추출하여 EAIMessage에 설정한다. + String traceKey = ""; + try { + /* + * 20220321 AS CASE 분리 + * 요청일 경우에는 OutboundAdapter의 표준/비표준을 기준으로 추출 + * 응답일 경우에는 InboundAdapter의 표준/비표준을 기준으로 추출 + * 표준일 경우 GUID를 추출키로 사용 + * 비표준일 경우 전문추적키를 사용 + */ + if( EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp) ) { + String outboundAdapterGroupName = eaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + boolean isRecv = STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType); + String messageTypeCd ; + if(isRecv) { + messageTypeCd = vo.getStdMsgTypeCode(); + }else { + AdapterGroupVO outboundAdapterGvo = AdapterManager.getInstance().getAdapterGroupVO(outboundAdapterGroupName); + String outboundMessageType = outboundAdapterGvo.getAdptrMsgPtrnCd(); + messageTypeCd = outboundMessageType; + } + + if(Keys.IF_STANDARD.equals(messageTypeCd)) { + if (logger.isDebug()) logger.debug(guidLogPrefix + " : STANDARD Interface - STDMessage HEADER TraceKey [" + traceKey + "] 에서 추출"); + traceKey = guid; + } else { + traceKey = BizKeyExtractor.getBizKeyValue(eaiMsg.getEAISvcCd(), null, receivedBizData); + if (logger.isDebug()) logger.debug(guidLogPrefix + " : NONSTANDARD Interface - Message IntgraTelgmUniqNo set to traceKey ["+traceKey+"]"); + } + } else { + // SA, AA 거래인경우에만 TraceKey를 추출한다 + if( EAIMessageKeys.ASYNC_SVC.equals(psvItfTp) ) { + if(Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode())) { + BizKeyManager manager = BizKeyManager.getInstance(); + BizKeyVO bizKey = manager.getBizKey(vo.getEaiSvcCd()+"TR"); + + if(bizKey == null) { + traceKey = guid; + if (logger.isDebug()) logger.debug(guidLogPrefix + " : 표준 - STDMessage HEADER에서 추출 TraceKey [" + traceKey + "]"); + } else { + traceKey = BizKeyExtractor.getBizKeyValue(eaiMsg.getEAISvcCd(), null, receivedBizData); + if (logger.isDebug()) logger.debug(guidLogPrefix + " : 표준 - Rule을 통해 추출 TraceKey [" + traceKey + "]"); + } + // messageID 가 있으나 TR 룰이 등록되지 않은 경우 guid 를 추출한다. + if(StringUtils.isEmpty(traceKey)) { + traceKey = guid; + } + } else { + if(FAIL_MSG_RECEIVER.equals(vo.getAdapterGroupName())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " : IF_NONSTANDARD Message SKIP TRACEKEY Extract - "+vo.getAdapterGroupName()); + } + } + else { + traceKey = BizKeyExtractor.getBizKeyValue(eaiMsg.getEAISvcCd(), null, receivedBizData); + } + if (logger.isDebug()) logger.debug(guidLogPrefix + " : IF_NONSTANDARD Message IntgraTelgmUniqno set to traceKey ["+traceKey+"]"); + } + + if (!BizKeyExtractor.isHex(eaiMsg.getEAISvcCd()) && traceKey != null) { + traceKey = traceKey.trim(); + } + // AA의 응답메시지가 timer관리 대상인 경우 Timer처리 Table의 상태를 변경한다. + if(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp)) { + // AA의 응답메시지일 경우 정상처리Flag를 설정한다. + eaiMsg.setRspErrCd(EAIMessageKeys.EAI_SUCCESS_CODE); + } + // SA 거래의 타이아웃시간이 0일 경우 기본값으로 59초(59*1000 ms)로 설정하도록 한다. + if(EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) + && (eaiMsg.getCurrentSvcMsg().getTmoVl() <= 0) ) { + if (logger.isWarn()) logger.warn(guidLogPrefix + " : Current SA TimeOut["+eaiMsg.getCurrentSvcMsg().getTmoVl()+"] - " + vo.getUuid()); + eaiMsg.getCurrentSvcMsg().setTmoVl( 59 ); // seconds + if (logger.isWarn()) logger.warn(guidLogPrefix + " : RESET Default SA TimeOut["+eaiMsg.getCurrentSvcMsg().getTmoVl()+"] - " + vo.getUuid()); + } + } + else { + // SS, AS의 경우 GUID를 TraceKey로 사용한다. + traceKey = guid; + if (!BizKeyExtractor.isHex(eaiMsg.getEAISvcCd()) && traceKey != null) { + traceKey = traceKey.trim(); + } + } + } + if(StringUtils.isBlank(traceKey)){ + traceKey = guid; + } + if (logger.isInfo()) logger.info(guidLogPrefix + " : TraceKey [" + traceKey + "]"); + eaiMsg.getCurrentSvcMsg().setKeyMgtMsgVl(traceKey); + } catch(Exception e) { + vo.setRspErrorCode("RECEAIIRP050"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()})); +// eaiMsg.setRspErrCd(vo.getRspErrorCode()); +// eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); + eaiMsg.setRspErr(vo.getRspErrorCode(),vo.getRspErrorMsg()); + + try { + EAILogSender.send(eaiMsg, null); + if (logger.isError()) logger.error(guidLogPrefix + " : DB Log 성공 - " + vo.getRspErrorMsg()); + } catch(Exception ex) { + if (logger.isError()) logger.error(guidLogPrefix + " : DB Log 실패 - " + vo.getRspErrorMsg()); + } + try { + retEaiMsg = ExceptionHandler.handle(eaiMsg); + Object retMsgObject = receivedBizData; + prop.setProperty(EAIMessageKeys.ELINK_RET_CODE, retEaiMsg.getRspErrCd()); + return getReturnObject(retEaiMsg, retMsgObject, retMsgObject, vo.getStdMsgTypeCode() + , vo.getAdptrMsgType(), vo.getUuid(), inboundCharset); + } catch(Exception ehe) { + if (logger.isError()) logger.error(guidLogPrefix + " : ExceptionHandler Call Error : " + e.getMessage()); + throw new RequestProcessorException(vo.getRspErrorMsg()); + } + } + + //---------------------------------------------- + // 비동기-비동기 거래 && 기동이 표준이 아닌 경우 + // 원거래복원 여부가 '1' 일 경우에 + // STDMessage를 복원한다. + //---------------------------------------------- + String recoverYn = mapper.getRecoverYn(standardMessage); + if(logger.isDebug()) { + logger.debug(guidLogPrefix + " : STDMessage 복원 Flag ["+recoverYn+"]"); + } + + if(EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTp) && + !Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode()) && + STDMessageKeys.RECOVER_YN_YES.equals(recoverYn) && + STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType) + ) { + try { + if(logger.isDebug()) { + logger.debug(guidLogPrefix + " : STDMessage 복원 실행 KEY["+traceKey+"]"); + } + if(StringUtils.isEmpty(traceKey)) { + throw new Exception(guidLogPrefix + " : Invalid traceKey Error["+traceKey+"]"); + } + String extBizCode = eaiMsg.getExtBizCd(); + + String restoredString = STDMessageMapper.getStoredMessageFixedHeader(traceKey, extBizCode); + if(restoredString != null) { + //복원시 outbound Adapter 메시지 타입 기준으로 reader를 셋팅한다. + String outboundAdapterGroupName = eaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO outAdptGrpVO = adapterManager.getAdapterGroupVO(outboundAdapterGroupName); + + StandardMessage restoredStandardMessage = standardManager.getStandardMessage(); + StandardReader restoredReader = standardManager.getReader(outAdptGrpVO.getMessageType()); + restoredReader.parse(restoredStandardMessage, restoredString); + standardManager.getMessageCoordinator().coordinateAfterRestored(restoredStandardMessage, standardMessage); + restoredStandardMessage.setBizData(standardMessage.getBizDataBytes(), standardMessage.getBizDataCharset()); + + eaiMsg.setStandardMessage(restoredStandardMessage); + } + else { + throw new Exception("요청 내부표준전문의 원거래 복원필드 항목이 ‘1’로 세팅되지 않았거나, 응답전문의 복원 KEY["+traceKey+"] 값이 일치하지 않음"); + } + } + catch(Exception e) { + if(logger.isError()) { + logger.error(e.toString(), e); + } + vo.setRspErrorCode("RECEAIIRP055"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()})); +// eaiMsg.setRspErrCd(vo.getRspErrorCode()); +// eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); + eaiMsg.setRspErr(vo.getRspErrorCode(),vo.getRspErrorMsg()); + + try { + EAILogSender.send(eaiMsg, null); + if (logger.isError()) logger.error(guidLogPrefix + " : DB Log 성공 - " + vo.getRspErrorMsg()); + } catch(Exception ex) { + if (logger.isError()) logger.error(guidLogPrefix + " : DB Log 실패 - " + vo.getRspErrorMsg()); + } + try { + retEaiMsg = ExceptionHandler.handle(eaiMsg); + Object retMsgObject = receivedBizData; + prop.setProperty(EAIMessageKeys.ELINK_RET_CODE, retEaiMsg.getRspErrCd()); + return getReturnObject(retEaiMsg, retMsgObject, retMsgObject, vo.getStdMsgTypeCode() + , vo.getAdptrMsgType(), vo.getUuid(), inboundCharset); + + } catch(Exception ehe) { + if (logger.isError()) logger.error(guidLogPrefix + " : ExceptionHandler Call Error : " + e.getMessage()); + throw new RequestProcessorException(vo.getRspErrorMsg()); + } + } + } + + if(logger.isInfo()) logger.info(guidLogPrefix + " : TRAN_TYPE - " + eaiMsg.getTranType()); + // 6. ALT-KEY 테이블의 검색키필드를 추출하여 로그에 넘겨준다 + // Logger의 Property로 설정한다 + String[] altKeys = new String[4]; + try { + // 메시지 ID가 정의되지 않은 경우 오류메시지를 리턴한다. + if(FAIL_MSG_RECEIVER.equals(vo.getAdapterGroupName())) { + if (logger.isDebug()) logger.debug(guidLogPrefix + " : SKIP ALTKEY Extract - " + vo.getAdapterGroupName()); + } + else { + altKeys = BizKeyExtractor.getAltKeyValues(eaiMsg.getEAISvcCd(), null, receivedBizData); + } + } catch(Exception e) { + vo.setRspErrorCode("RECEAIIRP060"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()})); + +// eaiMsg.setRspErrCd(vo.getRspErrorCode()); +// eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); + eaiMsg.setRspErr(vo.getRspErrorCode(),vo.getRspErrorMsg()); + + try { + EAILogSender.send(eaiMsg, null); + if (logger.isError()) logger.error(guidLogPrefix + " : DB Log 성공 - " + vo.getRspErrorMsg(), e); + } catch(Exception ex) { + if (logger.isError()) logger.error(guidLogPrefix + " : DB Log 실패 - " + vo.getRspErrorMsg(), e); + } + try { + retEaiMsg = ExceptionHandler.handle(eaiMsg); + Object retMsgObject = retEaiMsg.getStandardMessage().getBizData(); + prop.setProperty(EAIMessageKeys.ELINK_RET_CODE, retEaiMsg.getRspErrCd()); + return getReturnObject(retEaiMsg, receivedBizData, retMsgObject, vo.getStdMsgTypeCode(), vo.getAdptrMsgType(), vo.getUuid(), inboundCharset); + } catch(Exception ehe) { + if (logger.isError()) logger.error(guidLogPrefix + " : ExceptionHandler Call Error : " + e.getMessage()); + throw new RequestProcessorException(vo.getRspErrorMsg()); + } + } + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " : LOG_ALT_KEY1 [" + altKeys[0] + "]"); + logger.debug(guidLogPrefix + " : LOG_ALT_KEY2 [" + altKeys[1] + "]"); + logger.debug(guidLogPrefix + " : LOG_ALT_KEY3 [" + altKeys[2] + "]"); + logger.debug(guidLogPrefix + " : LOG_ALT_KEY4 [" + altKeys[3] + "]"); + } + Properties altKeyProp = new Properties(); + + if(altKeys != null && altKeys.length > 0) { + if(altKeys[0] == null) altKeys[0] = ""; + if(altKeys[1] == null) altKeys[1] = ""; + if(altKeys[2] == null) altKeys[2] = ""; + if(altKeys[3] == null) altKeys[3] = ""; + altKeyProp.setProperty(com.eactive.eai.common.logger.Keys.LOG_ALT_KEY1, altKeys[0]); + altKeyProp.setProperty(com.eactive.eai.common.logger.Keys.LOG_ALT_KEY2, altKeys[1]); + altKeyProp.setProperty(com.eactive.eai.common.logger.Keys.LOG_ALT_KEY3, altKeys[2]); + altKeyProp.setProperty(com.eactive.eai.common.logger.Keys.LOG_ALT_KEY4, altKeys[3]); + } + //---------------------------------------------- + // 6.1 업체코드 추출하여 로그에 넘겨준다 ( 요건추가 2019-03-26 ) + // Logger의 Property로 설정한다 + // 거래 방향이 내부이면 SourceAdapter 에서 추출 + // 거래 방향이 외부이면 TargetAdapter 에서 추출 + // 내부는 1 , 외부는 2,3,4 의 값이 나올수 있음 + //---------------------------------------------- + String companyCode = ""; + String adptrInstiCode = ""; + try{ + String companyCodeData = null; + boolean isEbcdic = false; + if (eaiServerManager.isFEP()) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(vo.getAdapterGroupName()); + //내부방향 + if(STDMessageKeys.DIRECTION_IN.equals(MessageUtil.getInExDivision(mapper.getInExDivision(standardMessage), eaiMsg.getInternalExternalDvcd()))){ //내부방향 + companyCodeData = adptGrpVO.getCompanyCodeData(); + adptrInstiCode = adptGrpVO.getAdptrInstiCode(); + }else{//외부방향 + AdapterGroupVO targetAdapterGroupVO = adapterManager.getAdapterGroupVO(eaiMsg.getCurrentSvcMsg().getPsvSysItfTp()); + //Sync-Async 응답에서 Adapter가 없는 경우 + if (targetAdapterGroupVO != null){ + companyCodeData = targetAdapterGroupVO.getCompanyCodeData(); + adptrInstiCode = targetAdapterGroupVO.getAdptrInstiCode(); + } + } + } + + if (companyCodeData != null){ + if(MessageType.EBC.equals(vo.getAdptrMsgType())) { + isEbcdic = true; + }else{ + isEbcdic = false; + } + companyCode = BizKeyExtractor.getBizKeyCode(companyCodeData, receivedBizData, isEbcdic); + } + }catch(Exception e){ + vo.setRspErrorCode("RECEAIIRP060"); //신규 에러 코드 추출해야됨 + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode() )); +// eaiMsg.setRspErrCd(vo.getRspErrorCode()); +// eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); + eaiMsg.setRspErr(vo.getRspErrorCode(),vo.getRspErrorMsg()); + } + if(companyCode != null && !"".equals(companyCode)) { + eaiMsg.setCompanyCode(companyCode); + }else{ + eaiMsg.setCompanyCode(""); + } + if(adptrInstiCode != null && !"".equals(adptrInstiCode)) { + eaiMsg.setAdptrInstiCode(adptrInstiCode); + }else{ + eaiMsg.setAdptrInstiCode(""); + } + // 6.2 업무데이터 길이를 추출하여 로그에 넘겨준다 + // Logger의 Property로 설정한다 + String data = receivedBizData; + if( data != null ) { + eaiMsg.setSplizLength(data.getBytes().length); + }else{ + eaiMsg.setSplizLength(0); + } + + // 7. Service Flag, ACKON 처리 + //---------------------------------------------------------- + // 거래통제로직 + // 2009.08.19 + // 거래통제 정보를 조회하여 동기거래인 경우 응답메시지를 조립하여 전달하고 + // 비동기 거래인 경우 에러 응답처리 한다. + // 동기 표준인 경우 : 거래통제에러코드 설정 + // 동기 표준이 아닌 경우 : EAI에서 정의한 동일한 에러응답메시지 전달 + //---------------------------------------------------------- + RestrictInfoManager rManager = RestrictInfoManager.getInstance(); + RestrictInfoVO rVo = rManager.getRestrictInfoVO(eaiMsg.getEAISvcCd()); + + // 기관코드로 한번더 Check 해야 함 : 2009.10.30 + + String instCode = mapper.getInstCode(standardMessage); + String ctrlNameDstcd = "1"; // EAI 서비스코드에 의한 통제 + + boolean isCheckRestrictTime = false; + + if(rVo == null) { + // 2011.01.04 기관코드 비정상 처리 수정 + if(instCode != null && instCode.trim().length() > 0) { + rVo = rManager.getRestrictInfoVO(instCode); + } + if(rVo != null) { + isCheckRestrictTime = checkRestrictTime(rVo); + if(isCheckRestrictTime) { + if (logger.isInfo()) { + logger.info(guidLogPrefix + " : 거래통제 기관코드["+instCode+"] EAI서비스코드 ["+eaiMsg.getEAISvcCd()+"] GUID["+ guid +"]"); + } + ctrlNameDstcd = "2"; + } + } + } else { + isCheckRestrictTime = checkRestrictTime(rVo); + if (logger.isInfo() && isCheckRestrictTime) { + logger.info(guidLogPrefix + " : 거래통제 EAI 서비스코드 ["+eaiMsg.getEAISvcCd()+"] GUID["+ guid +"]"); + } + } + + // APP 별 거래 제한 처리 + boolean isBlockedApp = false; + String clientId = prop.getProperty(HttpAdapterServiceSupport.PROPERTIES_NAME_CLIENT_ID); + if(StringUtils.isNotBlank(clientId)) { + ClientVO clientVO = OAuth2Manager.getInstance().getClientVO(clientId); + if("0".equals(clientVO.getAppStatus())){ + isBlockedApp = true; + } + } + + if(isBlockedApp || (rVo != null && isCheckRestrictTime)) { + // 거래통제 대상 거래일 경우 '1'로 설정한다. + eaiMsg.setSvcTmEn(EAIMessageKeys.YES_FLAG); + vo.setRspErrorCode(EAIMessageKeys.EAI_BLOCKED_CODE); + vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()})); + +// eaiMsg.setRspErrCd(vo.getRspErrorCode()); +// eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); + eaiMsg.setRspErr(vo.getRspErrorCode(),vo.getRspErrorMsg()); + + // 거래통제 로그에 로그생성 + try { + RestrictInfoManager.getInstance().addResrtictLog(eaiMsg.getBwkCls(), DatetimeUtil.getCurrentTime(eaiMsg.getMsgRcvTm()), + eaiMsg.getSvcOgNo(), eaiServerManager.getLocalServerName(), + eaiMsg.getEAISvcCd(), instCode, ctrlNameDstcd); + } catch(Exception ex) { + if (logger.isError()) { + StringBuilder sb = new StringBuilder(); + sb.append("EAIBzwkDstcd [" +eaiMsg.getBwkCls() +"]\n"); + sb.append("MsgDpstYMS [" +DatetimeUtil.getCurrentTime(eaiMsg.getMsgRcvTm()) +"]\n"); + sb.append("EAISvcSerno [" +eaiMsg.getSvcOgNo() +"]\n"); + sb.append("EAISevrInstncName [" +eaiServerManager.getLocalServerName() +"]\n"); + sb.append("EAISvcName [" +eaiMsg.getEAISvcCd() +"]\n"); + sb.append("EAIOsidInstiCd [" +instCode +"]\n"); + sb.append("EAICtrlNameDstcd [" +ctrlNameDstcd +"]\n"); + logger.error(guidLogPrefix + " 거래통제건수 Log 실패 - "+ ex.toString() + "\n" + sb.toString()); + } + } + + try { + EAILogSender.send(eaiMsg, altKeyProp); + if (logger.isError()) logger.error(guidLogPrefix + " : 거래통제 Log 성공 - " + vo.getRspErrorMsg()); + } catch(Exception ex) { + if (logger.isError()) logger.error(guidLogPrefix + " : 거래통제 Log 실패 - " + vo.getRspErrorMsg()); + } + + if(EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp)) { + // 거래통제 응답 로그 + eaiMsg.setLogPssSno(400); + mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV); + + // Add pathSeq + if (logger.isInfo()) logger.info( guidLogPrefix + "RES Current GUID ["+ guid + "]["+ guidSeq +"]"); + guidSeq = mapper.nextGuidSeq(standardMessage); + if (logger.isInfo()) logger.info( guidLogPrefix + "RES ADD PATHSEQ GUID ["+ guid + "]["+ guidSeq +"]"); + + //거래통제에 따른 응답 + Object restrictResponse = getRestrictedResponse(eaiMsg, receivedBizData + , vo.getStdMsgTypeCode(), vo.getAdptrMsgType(), vo.getUuid(), inboundCharset); + if (Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode())) { + eaiMsg.getStandardMessage().setBizData(receivedBizData, inboundCharset); + } else { + eaiMsg.getStandardMessage().setBizData(restrictResponse, inboundCharset); + } + try { + EAILogSender.send(eaiMsg, null); + if (logger.isError()) logger.error(guidLogPrefix + " : 거래통제 Log 성공 - " + vo.getRspErrorMsg()); + } catch(Exception ex) { + if (logger.isError()) logger.error(guidLogPrefix + " : 거래통제 Log 실패 - " + vo.getRspErrorMsg()); + } + + return restrictResponse; + } + else { + // ExceptionHandler에 의해 에러 응답송신 + try { + ExceptionHandler.handle(eaiMsg); + } + catch(Exception ee) { + if (logger.isError()) logger.error(guidLogPrefix + " : 거래통제 비동기 에러응답송신 실패 - " + ee.toString()); + } + return null; + } + } + + // 7.1 유량제어 처리 + // 유량제어 정보를 조회 하여 비동기 거래인 경우만 처리한다. + if (InflowControlUtil.isTargetOfInflowControl(eaiServerManager, eaiMsg)) { + Bucket bucket = InflowControlUtil.getBucket(); + + String blockedType = ""; + if (!bucket.isAdapterPass(vo.getAdapterGroupName())) { + blockedType += "A"; + } + if (!bucket.isInterfacePass(vo.getEaiSvcCd())) { + blockedType += "I"; + } + + if (blockedType.length() > 0) { + InflowTargetVO inflowTargetVO = null; + if (blockedType.startsWith("A")) { + inflowTargetVO = bucket.getAdapterInflowThreashold(vo.getAdapterGroupName()); + } else { + inflowTargetVO = bucket.getInterfaceInflowThreashold(vo.getEaiSvcCd()); + } + // 에러처리 + vo.setRspErrorCode(EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE); + vo.setRspErrorMsg(ExceptionUtil.make(vo.getRspErrorCode(), vo.getEaiSvcCd() ) + ", " + + inflowTargetVO.toString()); + +// eaiMsg.setRspErrCd(vo.getRspErrorCode()); +// eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); + eaiMsg.setRspErr(vo.getRspErrorCode(),vo.getRspErrorMsg()); + + try { + Properties inFlowProp = PropManager.getInstance().getProperties("INFLOW"); + String controlInflowHistory = inFlowProp.getProperty("inflow.control.history.yn", "N"); + if (StringUtils.equalsIgnoreCase(controlInflowHistory, "Y") && inflowTargetVO != null) { + DAOFactory factory = DAOFactory.newInstance(); +// InflowControlDAO restrictDao = (InflowControlDAO) factory.create(InflowControlDAO.class); +// InflowControlDAO를 서비스로 만들어서 factory.create로 하면 안됨. + InflowControlDAO restrictDao = (InflowControlDAO) ApplicationContextProvider.getContext().getBean(InflowControlDAO.class); + restrictDao.addInflowServicetLog(eaiMsg.getBwkCls(), + DatetimeUtil.getCurrentTime(eaiMsg.getMsgRcvTm()), eaiMsg.getSvcOgNo(), + eaiServerManager.getLocalServerName(), eaiMsg.getEAISvcCd(), vo.getAdapterGroupName(), + inflowTargetVO.getThresholdPerSecond(), inflowTargetVO.getThreshold(), + inflowTargetVO.getThresholdTimeUnit()); + } + } catch (Exception ex) { + if (logger.isError()) { + StringBuilder sb = new StringBuilder(); + sb.append("EAIBzwkDstcd [" + eaiMsg.getBwkCls() + "]\n"); + sb.append("MsgDpstYMS [" + DatetimeUtil.getCurrentTime(eaiMsg.getMsgRcvTm()) + "]\n"); + sb.append("EAISvcSerno [" + eaiMsg.getSvcOgNo() + "]\n"); + sb.append("EAISevrInstncName [" + eaiServerManager.getLocalServerName() + "]\n"); + sb.append("EAISvcName [" + eaiMsg.getEAISvcCd() + "]\n"); + sb.append("ADPTRBZWKGROUPNAME[" + vo.getAdapterGroupName() + "]\n"); + sb.append("InflowTargetVO [" + inflowTargetVO.toString() + "]\n"); + + logger.error(guidLogPrefix + " 유량제어 건수 Log 실패 - " + ex.toString() + "\n" + sb.toString()); + } + } + + try { + EAILogSender.send(eaiMsg, altKeyProp); + if (logger.isError()) + logger.error(guidLogPrefix + " : 유량제어 Log 성공 - " + vo.getRspErrorMsg()); + } catch (Exception ex) { + if (logger.isError()) + logger.error(guidLogPrefix + " : 유량제어 Log 실패 - " + vo.getRspErrorMsg()); + } + + if (EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp)) { + // 유량제어 응답 로그 + eaiMsg.setLogPssSno(400); + mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV); + + // Add pathSeq + if (logger.isInfo()) + logger.info(guidLogPrefix + "RES Current GUID [" + guid + "][" + guidSeq + "]"); + guidSeq = mapper.nextGuidSeq(standardMessage); + if (logger.isInfo()) + logger.info(guidLogPrefix + "RES ADD PATHSEQ GUID [" + guid + "][" + guidSeq + "]"); + + Object restrictResponse = getRestrictedResponse(eaiMsg, receivedBizData, vo.getStdMsgTypeCode(), + vo.getAdptrMsgType(), vo.getUuid(), inboundCharset); + if (Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode())) { + eaiMsg.getStandardMessage().setBizData(receivedBizData, inboundCharset); + } else { + eaiMsg.getStandardMessage().setBizData(restrictResponse, inboundCharset); + } + try { + EAILogSender.send(eaiMsg, null); + if (logger.isError()) + logger.error(guidLogPrefix + " : 유량제어 Log 성공 - " + vo.getRspErrorMsg()); + } catch (Exception ex) { + if (logger.isError()) + logger.error(guidLogPrefix + " : 유량제어 Log 실패 - " + vo.getRspErrorMsg()); + } + + AdapterGroupVO adptGrpVO = AdapterManager.getInstance().getAdapterGroupVO(vo.getAdapterGroupName()); + if (!Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode()) && StringUtils.equalsAny(adptGrpVO.getType(), + Keys.TYPE_REST, Keys.TYPE_HTTP, Keys.TYPE_HTTP_CUSTOM)) { + throw new HttpStatusException(eaiMsg.getRspErrMsg(), eaiMsg.getRspErrCd(), + HttpStatus.TOO_MANY_REQUESTS.value()); + } else { + return restrictResponse; + } + } else { + // ExceptionHandler에 의해 에러 응답송신 + try { + ExceptionHandler.handle(eaiMsg); + } catch (Exception ee) { + if (logger.isError()) + logger.error(guidLogPrefix + " : 유량제어 비동기 에러응답송신 실패 - " + ee.toString()); + } + return null; + } + } + } + + // 장애전문 전송 - 모든 변환을 안함으로 설정 + if(FAIL_MSG_RECEIVER.equals(vo.getAdapterGroupName())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " : 장애전문전송 EAI서비스코드 ["+eaiMsg.getEAISvcCd()+"] GUID["+ guid +"]"); + } + eaiMsg.getCurrentSvcMsg().setCnvEn("0"); + eaiMsg.getCurrentSvcMsg().setBsRspCnvEn("0"); + eaiMsg.getCurrentSvcMsg().setErrRspCnvEn("0"); + + // 전문의 앞 30자리를 짤라서 업무데이터로 인식 + // 전문은 항상 ASCII 전문이어야 한다. + String failData = null; + if(receivedBizData != null && receivedBizData.length() > 30) { + failData = receivedBizData.substring( 0,30 ); + } + else { + failData = receivedBizData; + } + standardMessage.setBizData(failData, inboundCharset); + } + + // 8. 수신 거래로그 Logging + if (logger.isInfo()) logger.info(guidLogPrefix + " : LOG(" + eaiMsg.getLogPssSno() + ") EAIMessage : "+eaiMsg.getEAISvcCd()); + try { + EAILogSender.send(eaiMsg, altKeyProp); + } catch(Exception e) { + vo.setRspErrorCode("RECEAIIRP080"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()})); + if (logger.isError()) logger.error(vo.getRspErrorMsg()); + } + + // 9. FlowRouter 호출 : SS, SA - Method Call, SA의 응답거래 - TOPIC, AA,AS - QUEUE + try { + if (logger.isInfo()) { + logger.info(guidLogPrefix + eaiMsg.getEAISvcCd() + + " : 기동 ["+svcTsmtUsgTp +"],수동 ["+psvItfTp +"], 전문요청구분코드 [" + returnType + "]"); + } + if( EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) ) { + if( EAIMessageKeys.ASYNC_SVC.equals(psvItfTp) && + STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType) + ) { + + standardMessage.setBizData(orgMessage, inboundCharset); + prop.setProperty(RouteKeys.ROUTING_TYPE, RouteKeys.ROUT_TOPIC); + prop.setProperty(RouteKeys.TRACE_KEY, eaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl()); + + } + else { + prop.setProperty(RouteKeys.ROUTING_TYPE, RouteKeys.ROUT_CALL); + } + } + // AA, AS + else { + prop.setProperty(RouteKeys.ROUTING_TYPE, RouteKeys.ROUT_QUEUE); + } + + if(svrLogLevel >= 1 && esbLogger.isInfo()) { + esbLogger.info(guidLogPrefix + " : FlowControl ROUTING_TYPE [" + prop.getProperty(RouteKeys.ROUTING_TYPE) + "]"); + } + + retEaiMsg = FlowRouter.process(eaiMsg, prop); + + // 응답메시지에 Error Code기 설정되어 있을 경우 + // ExceptionHandler를 통해 응답메시지를 생성한다. + if(retEaiMsg != null && !MessageUtil.checkRspErrCd(retEaiMsg.getRspErrCd())) { + //Timeout이 발생했을 경우 처리 추가됨 short11 + //Timeout이 발생했을 경우 요청거래의 bizmsg를 응담거래의 bizmsg에 넣어준다. +// if (STDMessageKeys.SEND_RECV_CD_SEND.equals(returnType)){ +// retEaiMsg.getStandardMessage().setBizData(receivedBizData, inboundCharset); +// } + retEaiMsg = ExceptionHandler.handle(retEaiMsg); + } + } catch(Exception e) { + vo.setRspErrorCode("RECEAIIRP090"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()})); + + if (logger.isError()) logger.error(guidLogPrefix + " : " + vo.getRspErrorMsg()); +// eaiMsg.setRspErrCd(vo.getRspErrorCode()); +// eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); + eaiMsg.setRspErr(vo.getRspErrorCode(),vo.getRspErrorMsg()); + try { + retEaiMsg = ExceptionHandler.handle(eaiMsg); + } catch(Exception ehe) { + if (logger.isError()) logger.error(guidLogPrefix + " : ExceptionHandler Call Error : " + e.getMessage()); + throw new RequestProcessorException(vo.getRspErrorMsg()); + } + } + + // TODO : StandardMessage -> SubMessage + if(Keys.IF_SUBSTANDARD.equals(vo.getStdMsgTypeCode())) { + StandardMessage stdMessage = retEaiMsg.getStandardMessage(); + try { + MessageMapper versionMapper = standardManager.getVersionMapper(); + subMessage = versionMapper.convertToSub(stdMessage, subMessage); + subMessage.setBizDataCharset(inboundCharset); + retEaiMsg.setSubMessage(subMessage); + + if(subMessage !=null && logger.isDebug()) { + logger.debug( String.format("RequestProcessorSupport] SUBSTANDARD-LOGGING SAVE UUID: %s, LOGSEQ: %s, HEADER: %s", + retEaiMsg.getSvcOgNo(), retEaiMsg.getLogPssSno(), subMessage.toFixedString(false)) ); + } + } catch (Exception e) { + logger.error("convertToSub failed.", e); + } + } + + // 10. 응답 거래로그 Logging + if(EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && + STDMessageKeys.SEND_RECV_CD_SEND.equals(returnType) ) { + try { + retEaiMsg.setLogPssSno(400); + String retGuid = mapper.getGuid(retEaiMsg.getStandardMessage()); + String retGuidSeq = mapper.getGuidSeq(retEaiMsg.getStandardMessage()); + String newGuid = retGuid + StringUtils.defaultString(StringUtils.leftPad(retGuidSeq, UUIDGenerator.GUID_SEQ_LENGTH, '0')); + mapper.setGuid(retEaiMsg.getStandardMessage(), newGuid); + mapper.setSendTime(retEaiMsg.getStandardMessage(), DatetimeUtil.getCurrentTimeMillis()); + + EAILogSender.send(retEaiMsg, null); + } catch(Exception e) { + vo.setRspErrorCode("RECEAIIRP100"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()} )); + if (logger.isError()) logger.error(guidLogPrefix + " : " + vo.getRspErrorMsg()); + } + if (logger.isInfo()) logger.info(guidLogPrefix + " : LOG(" + eaiMsg.getLogPssSno() + ") EAIMessage : "+eaiMsg.getEAISvcCd()); + } + + // 11. 비동기 거래의 경우 Return NULL + if(svrLogLevel >= 1 && esbLogger.isInfo()) { + esbLogger.info(guidLogPrefix + " : RETURN svcTsmtUsgTp ["+svcTsmtUsgTp+"]"); + } + + // 기동시스템과 Sync 이고 요청거래인 경우 + if(EAIMessageKeys.SYNC_SVC.equals(svcTsmtUsgTp) && + STDMessageKeys.SEND_RECV_CD_SEND.equals(returnType) ) { + prop.put(HttpAdapterServiceKey.STANDARD_MESSAGE_OBJECT, retEaiMsg.getStandardMessage()); + Object retMsgObject = retEaiMsg.getStandardMessage().getBizData(); + //sync 시뮬레이터 때문에 추가됨 juns 20211029 + if (eaiServerManager.isTASEnabledEAIServer() && Keys.TESTMASTER_TAS.equals(vo.getTestMasterYn())) { //비표준 시뮬레이터 + if (retMsgObject instanceof byte[]){ + byte[] retMsg = (byte[]) retMsgObject; + byte[] addSimMsg = null; + try { + addSimMsg = SimHeaderUtil.addSimHeader(retEaiMsg.getEAISvcCd(),instCode, retMsg); + } catch (Exception e) { + e.printStackTrace(); + addSimMsg = retMsg; + } + retMsgObject = addSimMsg; + } + } + prop.setProperty(EAIMessageKeys.ELINK_RET_CODE, retEaiMsg.getRspErrCd()); + + if (!MessageUtil.checkRspErrCd(retEaiMsg.getRspErrCd())) { + if (!Keys.IF_STANDARD.equals(vo.getStdMsgTypeCode()) + && StringUtils.equalsAny(vo.getAdptrMsgType(), MessageType.JSON, MessageType.XML)) { + throw new HttpStatusException(retEaiMsg.getRspErrMsg(), retEaiMsg.getRspErrCd(), + HttpStatus.INTERNAL_SERVER_ERROR.value()); + } + } + + return getReturnObject(retEaiMsg, receivedBizData, retMsgObject, vo.getStdMsgTypeCode(), vo.getAdptrMsgType(), vo.getUuid(), inboundCharset); + } + // ACKON 처리 : 현재 수신메시지를 응답메시지로 전달함 + else if(EAIMessageKeys.ACKONLY_SVC.equals(svcTsmtUsgTp)) { + try { + return receivedBizData; + } catch(Exception e) { + vo.setRspErrorCode("RECEAIIRP071"); + vo.setRspErrorMsg(ExceptionUtil.make(e, vo.getRspErrorCode(), new String[]{vo.getEaiSvcCd()})); + +// eaiMsg.setRspErrCd(vo.getRspErrorCode()); +// eaiMsg.setRspErrMsg(vo.getRspErrorMsg()); + eaiMsg.setRspErr(vo.getRspErrorCode(),vo.getRspErrorMsg()); + try { + EAILogSender.send(eaiMsg, altKeyProp); + if (logger.isError()) logger.error(guidLogPrefix + " : DB Log 성공 - " + vo.getRspErrorMsg()); + } catch(Exception ex) { + if (logger.isError()) logger.error(guidLogPrefix + " : DB Log 실패 - " + vo.getRspErrorMsg()); + } + throw new RequestProcessorException(vo.getRspErrorMsg()); + + } + } + else { + // 비동기 거래, S-A의 응답거래시에는 NULL을 리턴 + return null; + } + } + + private String getInboundErrorResponse(Properties prop, StandardMessage standardMessage, InterfaceMapper mapper + , String errCode, String errMsg, String charset) { + String errorResponse = null; + + String adptrMsgPtrnCd = prop.getProperty(Processor.STD_MESSAGE); + String messageType = prop.getProperty(Processor.MESSAGE_TYPE); + + if(standardMessage == null) { + errorResponse = ExceptionHandler.handle(errMsg); + logger.error("getInboundErrorResponse STDMessage is NULL adptrMsgPtrnCd["+adptrMsgPtrnCd+"] messageType["+messageType + +"] response["+errorResponse+"]"); + } + else { + String guid = mapper.getGuid(standardMessage); + logger.error(guid +" - getInboundErrorResponse adptrMsgPtrnCd["+adptrMsgPtrnCd+"] messageType["+messageType+"]"); + + if(Keys.IF_STANDARD.equals(adptrMsgPtrnCd)) { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + standardManager.getMessageCoordinator().coordinateBeforeInboundErrorResponse(standardMessage); + errorResponse = getInboundErrorResponseForStandard(standardMessage, mapper, errCode, errMsg, charset,messageType); + } + else { + errorResponse = ExceptionHandler.handle(errMsg); + logger.error(guid +" - getInboundErrorResponse [" + errorResponse +"]"); + } + } + return errorResponse; + } + + private String getInboundErrorResponseForStandard(StandardMessage standardMessage, InterfaceMapper mapper, + String errCode, String errMsg, String charset, String messageType) { + mapper.nextGuidSeq(standardMessage); + mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV); + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + standardManager.getMessageCoordinator().coordinateSetStandardMessageError(standardMessage, mapper, errCode, errMsg); + //mapper.setErrorCode(standardMessage, errCode); + //mapper.setErrorMsg(standardMessage, errMsg); + String result = null; + try { + result = standardMessage.getDataString(messageType, charset); + }catch(Exception e) { + + } + return result; + } + + public boolean checkRestrictTime(RestrictInfoVO rVo) { + String[] params = rVo.getEAICtrlDsticCtnt().split("\\|"); + if(params == null) + return true; + Calendar calendar = Calendar.getInstance(); + int hour = calendar.get(Calendar.HOUR_OF_DAY); + int minute = calendar.get(Calendar.MINUTE); + + String end = params.length > 6 ? params[6] : null; + String start = params.length > 5 ? params[5] : null; + + if(StringUtils.isNotBlank(start)) { + int targetHour = Integer.parseInt(start.substring(0, 2)); + int targetMinute = Integer.parseInt(start.substring(2, 4)); + if(hour < targetHour || (hour == targetHour && minute < targetMinute)) { + return false; + } + } + if(StringUtils.isNotBlank(end) && !"0000".equals(end)) { + int targetHour = Integer.parseInt(end.substring(0, 2)); + int targetMinute = Integer.parseInt(end.substring(2, 4)); + if(hour > targetHour || (hour == targetHour && minute >= targetMinute)) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessorException.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessorException.java new file mode 100644 index 0000000..3694a8e --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessorException.java @@ -0,0 +1,12 @@ +package com.eactive.eai.inbound.processor; + +public class RequestProcessorException extends Exception +{ + public RequestProcessorException() { + super("RequestProcessorException is occured."); + } + + public RequestProcessorException(String msg) { + super(msg); + } +} diff --git a/src/main/java/com/eactive/eai/inbound/processor/RequestProcessorSupport.java b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessorSupport.java new file mode 100644 index 0000000..0f93eb1 --- /dev/null +++ b/src/main/java/com/eactive/eai/inbound/processor/RequestProcessorSupport.java @@ -0,0 +1,556 @@ +package com.eactive.eai.inbound.processor; + + +import java.io.UnsupportedEncodingException; +import java.nio.charset.Charset; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.http.HttpStatus; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException; +import com.eactive.eai.common.exception.ExceptionHandler; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.InboundErrorLogger; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.inbound.error.InboundErrorInfoVO; +import com.eactive.eai.inbound.error.InboundErrorKeys; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.mapper.MessageMapper; +import com.eactive.eai.transformer.util.IConv; + +/** + * 1. 기능 : Inbound Adapter를 통해 전달 받은 메시지를 EAIMessage로 변환하고 + * FlowControl로 전달하는 기능을 제공한다. + * 2. 처리 개요 : + * - STDMessage 생성 + * - EAIMessage 생성 + * - 요청 거래로깅 + * - FlowControl 호출 + * - 응답 거래로깅 + * 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : + * @since : + * : + */ + +public abstract class RequestProcessorSupport implements Processor +{ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + protected static final String SERVICE_FLAG_MESSAGE = "SERVICE BLOCKED BY EAI SYSTEM"; + protected static final String STARTING_SERVICE_KEY = "ESBFW"; + + // 장애전문송신용 EAI 수신 가상어댑터 명 + protected static final String FAIL_MSG_RECEIVER = "FAIL_MSG_RECEIVER"; + + private static int rcvCount; + private static int errCount; + + private static boolean EAI_SERVICE_FLAG = true; + + static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + protected int svrLogLevel; + private static ThreadLocal local = new ThreadLocal(); //경과시간 동기화를 위한 ThreadLocal + + public RequestProcessorSupport() { + } + + public boolean isEAIServiceFlag() { + return EAI_SERVICE_FLAG; + } + + public void setEAIServiceFlag(boolean serviceFlag) { + EAI_SERVICE_FLAG = serviceFlag; + } + + public static int rcvCount() { + return rcvCount; + } + + public static int errCount() { + return errCount; + } + + public synchronized static void resetCount() { + rcvCount = 0; + errCount = 0; + } + + private synchronized void increaseRcvCount() { + rcvCount++; + } + + public synchronized void increaseErrCount() { + errCount++; + } + + /** + * 1. 기능 : RequestDispatcher에서 호출하기 위한 메소드로 내부의 hookup을 호출한다 + * 2. 처리 개요 : + * - 메시지수신시각설정 + * - hookup 호출 + * - 요청 거래로깅 + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @param prop 호출시 전달할 Property 값(추후 확장을 위해) + * @return Object + * @throws JwtAuthException + * @exception + **/ + public Object execute(Object message, Properties prop) throws HttpStatusException + { + long msgRcvTm = System.currentTimeMillis(); + increaseRcvCount(); + local.set(new Long(msgRcvTm)); + + if (logger.isDebug()) logger.debug("RequestProcessor] starting - "+prop); + Object result = null; + String encode = "euc-kr"; + String messageType = ""; + try { + messageType = prop.getProperty(Processor.MESSAGE_TYPE); + encode = prop.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + result = hookup(message, prop, msgRcvTm); + return result; + //return message; + } catch(HttpStatusException e) { + throw e; + } catch(Exception e) { + increaseErrCount(); + esbLogger.error("execute error", e); + String msg = ""; + if (StringUtils.equalsAny(messageType, MessageType.JSON, MessageType.XML)) { + throw new HttpStatusException(e.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR.value()); + } else { + msg = ExceptionHandler.handle(e.getMessage()); + } + + if(message instanceof byte[]) { + byte[] response = null; +// if(MessageUtil.isUTF8(messageType)) { +// encode = "utf-8"; +// } + try { + response = msg.getBytes(encode); + } + catch(Exception ex) { + return msg.getBytes(); + } + return response; + } + else { + return msg; + } + } finally { + long msgSndTm = System.currentTimeMillis(); + if (logger.isDebug()) logger.debug("RequestProcessor] EAI 처리시각["+(msgSndTm-msgRcvTm)+" msec] - "+prop); + if(svrLogLevel >= 1) { + try{ + Long threadData = (Long)local.get(); + long processTm = msgSndTm - threadData.longValue(); + if (esbLogger.isInfo()) esbLogger.info("RequestProcessor] End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); + }catch (Exception e){ + logger.warn("execute", e); + } + } + } + } + + /** + * 1. 기능 : 미확인 메시지에 대한 로그 + * 2. 처리 개요 : + * - Inbound Adapter를 통해 수신된 메시지에 대한 Rule을 확인할 수 없는 경우 로그출력 + * 3. 주의사항 + * + * @param uuid EAI서비스일련번호 + * @param adapterGroupName Inbound Adapter 그룹명 + * @param adapterName Inbound Adapter 명 + * @param errCode 에러코드 + * @param errMsg 에러내용 + * @param errTm 에러발생시각 + * @param svcInstNm EAI서버인스턴스명 + * @param message Inbound Adapter가 수신받은 메시지 Object + * @exception + **/ + protected void logUnknownMessage(String uuid, String adapterGroupName, String + adapterName, String bzwkSvcKeyName, String eaiSvcCd, boolean isTasStarted, + String errCode, String errMsg, long errTm, String svcInstNm,String errDstCd, Object message) { + String msg = null; + + if(errDstCd == null || errDstCd.length() ==0) { + errDstCd = "ND"; + } + + if(isTasStarted) { + errDstCd = InboundErrorKeys.TAS_START; + } + + InboundErrorInfoVO errorInfoVO = new InboundErrorInfoVO(); + errorInfoVO.setEaiSvcSno(uuid); // EAI서비스일련번호 + errorInfoVO.setAdptBwkGrpNm(adapterGroupName); // 어댑터업무그룹명 + errorInfoVO.setEaiSvcCd(eaiSvcCd); + errorInfoVO.setErrCd(errCode); // 에러코드 + errorInfoVO.setErrTxt(errMsg); // 에러내용 + errorInfoVO.setErrTm(DatetimeUtil.getCurrentTime(errTm)); // 에러발생시각 + errorInfoVO.setErrDstcd(errDstCd); + errorInfoVO.setBzwkSvcKeyName(bzwkSvcKeyName); + + if(message == null) { + msg = "null"; + } + else { + if(message instanceof byte[]) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO srcAdapterGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + + // TAS 거래일 경우 NULL일 수 있음 + if(srcAdapterGrpVO == null) { + msg = new String((byte[])message); + } + else { +// String srcAdapterMsgType = srcAdapterGrpVO.getMessageType(); +// if( MessageUtil.isUTF8(srcAdapterMsgType) ) { +// try { +// msg = new String((byte[])message, UJSONMessage.encode); +// } catch (UnsupportedEncodingException e) { +// logger.warn("msg encode error", e); +// msg = new String((byte[])message); } +// } +// else { +// msg = new String((byte[])message); +// } + + String charset = StringUtils.defaultIfBlank(srcAdapterGrpVO.getMessageEncode(), Charset.defaultCharset().name()); + try { + msg = new String((byte[])message, charset); + } catch (UnsupportedEncodingException e) { + logger.warn("msg encode error", e); + msg = new String((byte[])message); + } + } + + } + else if(message instanceof String) { + msg = (String)message; + } + else { + msg = "invaild message ["+message.getClass().getName()+"] "+message.toString(); + } + } + + errorInfoVO.setBwkDataTxt(msg); // 업무데이터내용 + errorInfoVO.setEaiSvrInstNm(svcInstNm); // EAI서버인스턴스명 + + InboundErrorLogger.error(errorInfoVO); + + if (logger.isError()) { + logger.error("======================================================================" ); + logger.error(" RequestDispatcher] GET UNKNOWN MESSAGE"); + logger.error(" ADAPTER GROUP NAME [" + adapterGroupName + "]"); + logger.error(" EAISVCNAME [" + eaiSvcCd + "]"); + logger.error(" ADAPTER NAME [" + adapterName + "]"); + logger.error("======================================================================" ); +// logger.error("<< MESSAGE DUMP >>"); +// String[] dump = CommonLib.makeDumpFormat( msg.getBytes() ); +// for(int i=0; i< dump.length; i++) { +// logger.error(dump[i]); +// } +// logger.error("======================================================================" ); + } + + } + protected void logUnknownMessage(ProcessVO vo, Object orgMessage) { + if(MessageType.EBC.equals(vo.getAdptrMsgType())) { + logUnknownMessage(vo.getUuid(), vo.getAdapterGroupName(), vo.getAdapterName(), vo.getSelectedKey(), vo.getEaiSvcCd(), vo.isTasStarted(), + vo.getRspErrorCode(), vo.getRspErrorMsg(), vo.getErrTm(), vo.getServerName(),vo.getErrTypeCode(), IConv.ebcdicToASCII((byte[])orgMessage)); + }else{ + logUnknownMessage(vo.getUuid(), vo.getAdapterGroupName(), vo.getAdapterName(), vo.getSelectedKey(), vo.getEaiSvcCd(), vo.isTasStarted(), + vo.getRspErrorCode(), vo.getRspErrorMsg(), vo.getErrTm(), vo.getServerName(),vo.getErrTypeCode(), orgMessage); + } + } + + + /** + * 1. 기능 : ServiceFlag의 설정에 대한 경고메시지를 생성하여 리턴한다. + * 2. 처리 개요 : + * - 메시지의 유형에 따라 ServieFlag 메시지를 리턴한다. + * 3. 주의사항 + * + * @param inObj 요청메시지 + * @return Object + **/ +// private Object makeServiceFlagMessage(Object inObj) { +// Object retObject = null; +// +// if(inObj instanceof byte[]) { +// retObject = SERVICE_FLAG_MESSAGE.getBytes(); +// } +// else if(inObj instanceof byte[]) { +// retObject = SERVICE_FLAG_MESSAGE; +// } +// else { +// retObject = SERVICE_FLAG_MESSAGE; +// } +// return retObject; +// } + + /** + * 1. 기능 : 응답메시지 오브젝트에 따라 응답메시지를 생성하여 리턴 + * 2. 처리 개요 : + * - Adapter메시지패턴에 따라 응답메시지를 생성하여 리턴 + * 3. 주의사항 + * + * @param retEaiMsg 응답EAI메시지 + * @param message Object 타입의 요청메시지 + * @param retMsgObject 응답메시지오브젝트 + * @param adptrMsgPtrnCd Adapter메시지패턴 - [S, N, C] 값을 가짐 : Standard, Non-Standard, Custom + * @param adptrMsgType Adapter 메시지 타입 - XML, ASC, FML, EBC + * @param uuid 거래에 대한 Unique ID - 로깅을 위한 값 + * @return Object + **/ + + public static Object getReturnObject(EAIMessage retEaiMsg, Object message, Object retMsgObject, + String adptrMsgPtrnCd, String adptrMsgType, String uuid, String charset) { + + if(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(adptrMsgPtrnCd)) { + StandardMessage stdMessage = retEaiMsg.getStandardMessage(); + try { + stdMessage.setBizData(retMsgObject, charset); + } catch (Exception e) { + logger.error("setBizData failed.", e); + } + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + standardManager.getMessageCoordinator().coordinateInReturnObject(stdMessage); +/* + +// if(MessageType.JSON.equals(adptrMsgType) +// || MessageType.UJSON.equals(adptrMsgType)) { + if(MessageType.JSON.equals(adptrMsgType)) { + return stdMessage.toJson(); + } +// else if(MessageType.XML.equals(adptrMsgType) +// || MessageType.UXML.equals(adptrMsgType)) { + else if(MessageType.XML.equals(adptrMsgType)) { + return stdMessage.toXML(); + } + else if(MessageType.ASC.equals(adptrMsgType)) { + return stdMessage.toFixedString(charset); + } + else if(MessageType.EBC.equals(adptrMsgType)) { + logger.error("Unsupported message type - " + MessageType.EBC); + } +// else if(MessageUtil.isUTF8(adptrMsgType)) { +// return stdMessage.toJson(); +// } + else { + return retMsgObject; + } + return retMsgObject; +*/ + String obj = null; + try { + obj = stdMessage.getDataString(adptrMsgType, charset); + }catch(Exception e) { + + } + if(obj == null) return retMsgObject; + return obj; + } + else if(com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(adptrMsgPtrnCd)) { + StandardMessage stdMessage = retEaiMsg.getStandardMessage(); + StandardMessage subMessage = retEaiMsg.getSubMessage(); + try { + subMessage.setBizData(retMsgObject, charset); + } catch (Exception e) { + logger.error("setBizData failed.", e); + } + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + standardManager.getMessageCoordinator().coordinateInReturnObject(stdMessage); + + if(MessageType.JSON.equals(adptrMsgType)) { + return subMessage.toJson(); + } + else if(MessageType.XML.equals(adptrMsgType)) { + return subMessage.toXML(); + } + else if(MessageType.ASC.equals(adptrMsgType)) { + return subMessage.toFixedString(charset); + } + else if(MessageType.EBC.equals(adptrMsgType)) { + logger.error("Unsupported message type - " + MessageType.EBC); + } + else { + return retMsgObject; + } + return retMsgObject; + } + else { + // 비표준 XML일 경우 XML Header Tag의 존재여부를 확인하여 없는 경우 추가해야 한다. +// if(MessageType.XML.equals(adptrMsgType) || MessageType.UXML.equals(adptrMsgType)) { + if(MessageType.XML.equals(adptrMsgType)) { +// String encode = MessageType.XML_ENCODE; +// if(MessageType.UXML.equals(adptrMsgType)) { +// encode = MessageType.UXML_ENCODE; +// } + if(retMsgObject == null) { + return ""; + } + else if(message instanceof String) { + String xmlString = (String)retMsgObject; + if(xmlString.indexOf("") == -1) { + xmlString = "" + + xmlString; + } + return xmlString; + } + else if(message instanceof byte[]) { + String xmlString = null; + try { + xmlString = new String( (byte[])retMsgObject, charset ); + } catch (UnsupportedEncodingException e) { + xmlString = new String( (byte[])retMsgObject); + } + if(xmlString.indexOf("") == -1) { + xmlString = "" + + xmlString; + } + byte[] responseBytes = null; + try { + responseBytes = xmlString.getBytes(charset); + } catch (UnsupportedEncodingException e) { + responseBytes = xmlString.getBytes(); + } + return responseBytes; + } else { + return retMsgObject; + } + }else if(MessageType.JSON.equals(adptrMsgType)) { + if(retMsgObject == null) { + return "{}"; + }else if(retMsgObject instanceof byte[]) { + byte[] bytesObject = (byte[])retMsgObject; + if(bytesObject.length == 0) { + return "{}"; + } + }else if(retMsgObject instanceof String) { + String stringObject = (String)retMsgObject; + if(StringUtils.isBlank(stringObject)) { + return "{}"; + } + } + + return retMsgObject; + }else { + return retMsgObject; + } + } + } + + protected Object getRestrictedResponse(EAIMessage retEaiMsg, Object message, + String adptrMsgPtrnCd, String adptrMsgType, String uuid, String charset) { + if(com.eactive.eai.adapter.Keys.IF_STANDARD.equals(adptrMsgPtrnCd)) { + return getRestrictedResponse(retEaiMsg, message, adptrMsgType, uuid, charset); + } + else { + String eaiRestrictedRespose = ""; + if (StringUtils.equals(retEaiMsg.getRspErrCd(), EAIMessageKeys.EAI_INFLOW_BLOCKED_CODE)) { + eaiRestrictedRespose = "It was not processed by flow control.[" + retEaiMsg.getEAISvcCd() + "]"; + } else { + eaiRestrictedRespose = "It was not processed by transaction control.[" + retEaiMsg.getEAISvcCd() + "]"; + } + if(MessageType.XML.equals(adptrMsgType)) { + return MessageUtil.makeXmlErrorMessage(retEaiMsg.getRspErrCd(), retEaiMsg.getRspErrMsg(), charset); + } else if (MessageType.JSON.equals(adptrMsgType)) { + return MessageUtil.makeJsonErrorMessage(retEaiMsg.getRspErrCd(), retEaiMsg.getRspErrMsg()); + } else { + try { + return eaiRestrictedRespose.getBytes(charset); + } catch (UnsupportedEncodingException e) { + return eaiRestrictedRespose.getBytes(); + } + } + } + } + + private static Object getRestrictedResponse(EAIMessage retEaiMsg, Object message, + String adptrMsgType, String uuid, String charset) { + StandardMessage stdMessage = retEaiMsg.getStandardMessage(); + //InterfaceMapper mapper = retEaiMsg.getMapper(); +// String errorMessage = ExceptionUtil.make(retEaiMsg.getRspErrCd(), new String[]{retEaiMsg.getEAISvcCd()}); +// mapper.setErrorCode(stdMessage, STDMessageKeys.ERROR_CODE_VALUE); +// mapper.setErrorMsg(stdMessage, errorMessage); + //mapper.setErrorCode(stdMessage, retEaiMsg.getRspErrCd()); + //mapper.setErrorMsg(stdMessage, retEaiMsg.getRspErrMsg()); + + // 표준메시지에 BizData 셋팅할 필요 없을듯(요청 BizData 리턴) +// try { +// stdMessage.setBizData(errorMessage, charset); +// } catch (Exception e) { +// logger.error("setBizData failed.", e); +// } +/* +// if(MessageType.JSON.equals(adptrMsgType) +// || MessageType.UJSON.equals(adptrMsgType)) { + if(MessageType.JSON.equals(adptrMsgType)) { + return stdMessage.toJson(); + } +// else if(MessageType.XML.equals(adptrMsgType) +// || MessageType.UXML.equals(adptrMsgType)) { + else if(MessageType.XML.equals(adptrMsgType)) { + return stdMessage.toXML(); + } + else if(MessageType.ASC.equals(adptrMsgType)) { + return stdMessage.toFixedString(charset); + } + else if(MessageType.EBC.equals(adptrMsgType)) { + logger.error("Unsupported message type - " + MessageType.EBC); + } +// else if(MessageUtil.isUTF8(adptrMsgType)) { +// return stdMessage.toJson(); +// } + else { + return message; + } + return message; +*/ + String obj = null; + try { + obj = stdMessage.getDataString(adptrMsgType, charset); + }catch(Exception e) { + + } + if(obj==null) return message; + return obj; + } + + /** + * 1. 기능 : Inbound Adapter를 통해 전달 받은 메시지를 EAIMessage로 변환하고 + * FlowControl로 전달하는 기능을 제공한다. + * 2. 처리 개요 : + * - KBMessage 생성 + * - EAIMessage 생성 + * - 요청 거래로깅 + * - FlowControl 호출 + * - 응답 거래로깅 + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @param prop 호출시 전달할 Property 값(추후 확장을 위해) + * @param msgRcvTm 메시지 수신시각 + * @return Object + * @exception RequestProcessorException + **/ + abstract protected Object hookup(Object message, Properties prop, long msgRcvTm) throws RequestProcessorException, Exception ; +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/message/EncodingVar.java b/src/main/java/com/eactive/eai/message/EncodingVar.java new file mode 100644 index 0000000..e2e0595 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/EncodingVar.java @@ -0,0 +1,46 @@ +package com.eactive.eai.message; + +public class EncodingVar { + //FlatReader String -<-> bytes encoding + public static String flatEncoding ="euc-kr"; + + //StandardItem XML encoding + public static String xmlEncoding ="utf-8"; + public static String jsonEncoding ="utf-8"; + +// performance를 위해 static으로 변경 후 commented +// +// private static EncodingVar instance; +// +// public static EncodingVar getInstance() { +// if(instance == null) { +// synchronized(EncodingVar.class) { +// if(instance == null) { +// instance = new EncodingVar(); +// } +// } +// } +// return instance; +// } + +// public String getFlatEncoding() { +// return flatEncoding; +// } +// public void setFlatEncoding(String flatEncoding) { +// EncodingVar.flatEncoding = flatEncoding; +// } +// public String getValueEncoding() { +// return valueEncoding; +// } +// public void setValueEncoding(String valueEncoding) { +// EncodingVar.valueEncoding = valueEncoding; +// } +// public String getXmlEncoding() { +// return xmlEncoding; +// } +// public void setXmlEncoding(String xmlEncoding) { +// EncodingVar.xmlEncoding = xmlEncoding; +// } + + +} diff --git a/src/main/java/com/eactive/eai/message/StandardDataType.java b/src/main/java/com/eactive/eai/message/StandardDataType.java new file mode 100644 index 0000000..83fedb8 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/StandardDataType.java @@ -0,0 +1,8 @@ +package com.eactive.eai.message; + +public interface StandardDataType { + public final int STRING = 1; + public final int NUMBER = 2; + public final int ZZ_STRING = 11; + public final int LL_NUMBER = 12; +} diff --git a/src/main/java/com/eactive/eai/message/StandardFieldType.java b/src/main/java/com/eactive/eai/message/StandardFieldType.java new file mode 100644 index 0000000..b1dd547 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/StandardFieldType.java @@ -0,0 +1,6 @@ +package com.eactive.eai.message; + +public interface StandardFieldType { + public final int ELEMENT = 1; + public final int ATTRIBUTE = 2; +} diff --git a/src/main/java/com/eactive/eai/message/StandardItem.java b/src/main/java/com/eactive/eai/message/StandardItem.java new file mode 100644 index 0000000..f8a74ab --- /dev/null +++ b/src/main/java/com/eactive/eai/message/StandardItem.java @@ -0,0 +1,1258 @@ +package com.eactive.eai.message; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.Serializable; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; + +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageLayoutItem; +import com.eactive.eai.transformer.util.ByteUtil; +import org.apache.commons.lang3.SerializationUtils; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StandardItem implements Serializable, Cloneable { + private static final long serialVersionUID = -4430144517271735912L; + static Logger logger = LoggerFactory.getLogger(StandardItem.class); + LinkedHashMap childs = new LinkedHashMap(); + ArrayList> list = new ArrayList>(); + + ArrayList values = new ArrayList(); + + // FIX-ME : check encoding + // String <-> byte[] charset +// private static String encode = "ms949"; //"euc-kr"; +// private static String encodeXml = "utf-8"; +// private static String encodeJson = "utf-8"; + + public static int ITEM_COUNT = 11; + String name; + int level; // 0 : root ~ n + int type; // 1: Message, 2: Field, 3:Group, 4 : Grid, 5 : Field Array, 9 : BIZ DATA + int size; // array size + int fieldType; // 1: ELEMENT, 2: ATTRIBUTE, + int length; + int dataType; // 1: String, 2: Number, 11: ZZ String, 12: Length Number + String refPath; + String refValue; + String value; + String desc = ""; + boolean isHidden =false; + + byte[] bytesValue = null; + + // configuration options + // if data is null, convert to empty-space + private static boolean NULL_TO_SPACE = true; + + // if add json root item with message name + private static boolean ADD_JSON_ROOT = false; + + static { + resetSystemParameters(); + } + public static void resetSystemParameters() { + try { + NULL_TO_SPACE = Boolean.parseBoolean( System.getProperty("standard.message.nulltospace", "true") ); + } + catch(Exception ex) { + ; + } + try { + ADD_JSON_ROOT = Boolean.parseBoolean( System.getProperty("standard.message.addjsonroot", "false") ); + } + catch(Exception ex) { + ; + } + } + + public StandardItem() { + + } + + public StandardItem(String name, int level, int type, int size, int fieldType, int length, + int dataType, String refPath, String refValue, String value, String desc) { + super(); + initValues(name, level, type, size, fieldType, length, dataType, refPath, refValue, value, desc); + } + + public StandardItem(String name, int level, int type, int size, int length, int dataType, String value, String desc) { + super(); + initValues(name, level, type, size, 0, length, dataType, null, null, value, desc); + } + public StandardItem(String name, int level, int type, int size, int length, int dataType, String value) { + super(); + initValues(name, level, type, size, 0, length, dataType, null, null, value, null); + } + + public StandardItem(String name, int level, int type, int length, int dataType, String value, String desc) { + super(); + initValues(name, level, type, 1, 0, length, dataType, null, null, value, desc); + } + + public StandardItem(String name, int level, int type, int length, int dataType, String value) { + super(); + initValues(name, level, type, 1, 0, length, dataType, null, null, value, null); + } + + public void initValues(String name, int level, int type, int size, int fieldType, int length, + int dataType, String refPath, String refValue, String value, String desc) { + this.name = name; + this.level = level; + this.type = type; + this.size = size; + this.fieldType = fieldType; + this.length = length; + this.dataType = dataType; + this.refPath = refPath; + this.refValue = refValue; + setValue(value); + if(desc != null) this.desc = desc; + } + + public StandardItem(String[] values) throws Exception { + if(values == null || values.length < ITEM_COUNT-1) { + throw new Exception("invalid StandardItem defination values : " + (values==null? "":values.length)); + } + this.name = values[0].trim(); + this.level = Integer.parseInt(values[1].trim()); + this.type = Integer.parseInt(values[2].trim()); + this.size = Integer.parseInt(values[3].trim());; + this.fieldType = Integer.parseInt(values[4].trim()); + this.length = Integer.parseInt(values[5].trim());; + this.dataType = Integer.parseInt(values[6].trim()); + this.refPath = values[7].trim(); + this.refValue = values[8].trim(); + setValue(values[9]); + if(values.length == ITEM_COUNT) { + setDesc(values[10].trim()); + } + else { + setDesc(values[0].trim()); + } + } + + public StandardItem(StandardMessageLayoutItem entityItem) { + this.name = entityItem.getItemName(); + this.level = entityItem.getItemLevel(); + this.type = entityItem.getItemType(); + this.size = entityItem.getArraySize(); + this.fieldType = entityItem.getFieldType(); + this.length = entityItem.getDataLength(); + this.dataType = entityItem.getDataType(); + this.refPath = entityItem.getRefFieldPath(); + this.refValue = entityItem.getRefValue(); + setValue(entityItem.getDefaultValue()); + setDesc(entityItem.getItemDesc()); + } + + public void addItem (StandardItem item) { + childs.put(item.getName(), item); + } + + public void addArrayItem(int index, StandardItem item) { + if( !childs.containsKey(item.getName()) ) { + childs.put(item.getName(), item); + } + // add last + if(list.size() == index) { + LinkedHashMap items = new LinkedHashMap(); + items.put(item.getName(), item); + list.add(items); + } + else if(list.size() > index) { + list.get(index).put(item.getName(), item); + } + else { + logger.debug("index too big : index={} / array size={}", index, list.size()); + } + } + public void addArray(LinkedHashMap items) { + list.add(items); + } + + public LinkedHashMap getArrayChilds(int index, boolean createNew) { + if(index == list.size()) { +// logger.debug("@@ add cloned childs in array item={}, index={}", this.name, index); + if(createNew) { + list.add((LinkedHashMap)(SerializationUtils.clone(childs)) ); + } + else { + return null; + } + } + else if(index > list.size()) { + return null; + } + return list.get(index); + } + + public LinkedHashMap getChilds() { + return childs; + } + + public ArrayList getChildsList() { + ArrayList childList = new ArrayList(childs.values()); + return childList; + } + + public void setChilds(LinkedHashMap childs) { + this.childs = childs; + } + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public int getType() { + return type; + } + public void setType(int type) { + this.type = type; + } + + public int getFieldType() { + return fieldType; + } + + public void setFieldType(int fieldType) { + this.fieldType = fieldType; + } + + public int getSize() { + return size; + } + + public void setSize(int size) { + this.size = size; + } + + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getDataType() { + return dataType; + } + public void setDataType(int dataType) { + this.dataType = dataType; + } + + public String getRefPath() { + return refPath; + } + + public void setRefPath(String refPath) { + this.refPath = refPath; + } + + public String getRefValue() { + return refValue; + } + + public void setRefValue(String refValue) { + this.refValue = refValue; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getValue() { + return value; + } + + public boolean isHidden() { + return isHidden; + } + + public void setHidden(boolean isHidden) { + this.isHidden = isHidden; + } + + protected String toTypeValue(String svalue) { + if(svalue == null) return svalue; + + if(dataType == StandardDataType.STRING || dataType == StandardDataType.ZZ_STRING) { + return svalue; + } + else { + char[] charValues = svalue.trim().toCharArray(); + int i = 0; + for(; i< charValues.length; i++) { + if(charValues[i] == '0' || charValues[i] == ' ') { + continue; + } + break; + } + return new String(charValues, i, (charValues.length - i)); + } + } + + public void setValue(String value) { + this.value = toTypeValue(value); + this.bytesValue = null; //value와 bytesValue의 불일치 때문 jun's 20231101 + } + + public void addValue(String value) { + values.add(toTypeValue(value)); + } + + public void addBytesValue(byte[] bytesValue) { +// this.bytesValue = bytesValue; + String svalue = null; + try { + String encoding = EncodingVar.flatEncoding; +// logger.debug("Encoding : {}", encoding ); + svalue = new String(bytesValue, encoding); + } catch (UnsupportedEncodingException e) { + svalue = new String(bytesValue); + } + addValue(toTypeValue(svalue)); + } + +// public byte[] getBytesValue() { +// if(bytesValue != null) { +// return bytesValue; +// } +// else { +// try { +// String encoding = EncodingVar.flatEncoding; +//// logger.debug("Encoding : {}", encoding ); +// this.bytesValue = value.getBytes(encoding); +// } catch (UnsupportedEncodingException e) { +// this.bytesValue = value.getBytes(); +// } +// return bytesValue; +// } +// } + + public byte[] getBytesValue(String charset) { + if (bytesValue == null || bytesValue.length == 0) { + if(value == null) return new byte[0]; + try { +// logger.debug("Encoding : {}", charset ); + this.bytesValue = value.getBytes(charset); + } catch (UnsupportedEncodingException e) { + this.bytesValue = value.getBytes(); + } + return bytesValue; + } + else { + return bytesValue; + } + } + + public void setBytesValue(byte[] bytesValue) { + this.bytesValue = bytesValue; + } + + public void setBytesValue(byte[] bytesValue, String charset) { + try { + logger.debug("charset : {}", charset ); + this.value = toTypeValue(new String(bytesValue, charset)); + } catch (UnsupportedEncodingException e) { + this.value = toTypeValue(new String(bytesValue)); + } + + } + + protected String getLevelIndent() { + StringBuilder sb = new StringBuilder(); + for(int i=0; i 0) { + for(int i=0; i keyIter = null;; + switch(getType()) { + case StandardType.MESSAGE : + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + sb.append("\n").append(item.toString()); + } + break; +// case StandardType.FIELD : +// break; + case StandardType.GROUP : + if (isHidden) break; + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + sb.append("\n").append(item.toString()); + } + break; + case StandardType.GRID : + if (isHidden) break; + for(int p=0; p group = list.get(p); + keyIter = group.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = group.get(key); + sb.append("\n").append(item.toString()); + } + } + break; +// case StandardType.FARRAY : +// break; +// case StandardType.BIZDATA : +// break; + default : + break; + } + return sb.toString(); + } + + public String toCSVString() { + StringBuilder sb = new StringBuilder(); + + if(level == 0) { + sb.append("#name,level,type,size,fieldType,length,dataType,refPath,refValue,value,desc\n"); + } + sb.append(name); + sb.append(","); + sb.append(level); + sb.append(","); + sb.append(type); + sb.append(","); + sb.append(size); + sb.append(","); + sb.append(fieldType); + sb.append(","); + sb.append(length); + sb.append(","); + sb.append(dataType); + sb.append(","); + sb.append(refPath); + sb.append(","); + sb.append(refValue); + sb.append(","); + sb.append(value); + sb.append(","); + sb.append(desc); + sb.append("\n"); + Iterator keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + sb.append(item.toCSVString()); + } + return sb.toString(); + } + + public ArrayList toList() { + ArrayList list = new ArrayList(); + ArrayList childList = null; + switch(getType()) { + case StandardType.MESSAGE : + list.add(this); + childList = new ArrayList(childs.values()); + for(int i=0; i(childs.values()); + for(int i=0; i map = getArrayChilds(ai, false); + childList = new ArrayList(map.values()); + for(int i=0; i toLogList() { + return toLogList(false); + } + + public ArrayList toLogList(boolean withBizData) { + ArrayList list = new ArrayList(); + ArrayList childList = null; + switch(getType()) { + case StandardType.MESSAGE : +// list.add(toLogItem(this)); + childList = new ArrayList(childs.values()); + for(int i=0; i(childs.values()); + for(int i=0; i map = getArrayChilds(ai, withBizData); + childList = new ArrayList(map.values()); + for(int i=0; i toLogFlatList() { + return toLogFlatList(false); + } + + public ArrayList toLogFlatList(boolean withBizData) { + ArrayList list = new ArrayList(); + ArrayList childList = null; + switch (getType()) { + case StandardType.MESSAGE: + childList = new ArrayList(childs.values()); + for (int i = 0; i < childList.size(); i++) { + list.addAll(childList.get(i).toLogFlatList(withBizData)); + } + break; + case StandardType.FIELD: + list.add(toLogFlatItem(this)); + break; + case StandardType.GROUP: + if (isHidden) + break; + list.add(toLogFlatItem(this)); + childList = new ArrayList(childs.values()); + for (int i = 0; i < childList.size(); i++) { + list.addAll(childList.get(i).toLogFlatList(withBizData)); + } + break; + case StandardType.GRID: + if (isHidden) + break; + list.add(toLogFlatItem(this)); + int arraySize = getSize(); + for (int ai = 0; ai < arraySize; ai++) { + LinkedHashMap map = getArrayChilds(ai, withBizData); + childList = new ArrayList(map.values()); + for (int i = 0; i < childList.size(); i++) { + list.addAll(childList.get(i).toLogFlatList(withBizData)); + } + } + break; + case StandardType.FARRAY: + list.add(toLogFlatItem(this)); + break; + case StandardType.BIZDATA: + if (withBizData) + list.add(toLogFlatItem(this)); + break; + default: + break; + } + return list; + } + + protected String toJsonValue() { + return toJsonValue(this.value); + } + + protected String toJsonValue(String svalue) { + if(dataType == StandardDataType.STRING || dataType == StandardDataType.ZZ_STRING) { + if(svalue == null) { + if(NULL_TO_SPACE) return "\"\""; + else return null; + } + return "\"" + JSONObject.escape(svalue) + "\""; + } + else { + if(StringUtils.isEmpty(svalue)) { + return "0"; + } + else { + return JSONObject.escape(svalue) ; + } + } + } + + public String toJson() { + return toJson(false, true); + } + public String toPrettyJson() { + return toJson(true, true); + } + + public String toJson(boolean showPretty, boolean withBizData) { + StringBuilder sb = new StringBuilder(); + Iterator keyIter = null; + switch(getType()) { + case StandardType.MESSAGE : + sb.append("{"); +// if root name add + if(ADD_JSON_ROOT) sb.append("\"").append( name ).append("\"").append(":{"); +// if(showPretty) sb.append("\n"); + keyIter = childs.keySet().iterator(); + int i=0; + String part = null; + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + + part = item.toJson(showPretty, withBizData); + if(StringUtils.isNotEmpty(part)) { + if(i>0) sb.append(","); + if(showPretty) sb.append("\n"); + sb.append(part); + i++; + } + } + if(ADD_JSON_ROOT) sb.append("}"); + if(showPretty) sb.append("\n"); + sb.append("}"); + break; + case StandardType.FIELD : + if(StringUtils.isEmpty(this.value)) break; + if(showPretty) sb.append(getLevelIndent()); + sb.append("\"").append(name).append("\":").append(toJsonValue()); + break; + case StandardType.GROUP : + // skip variable group + if( getSize() == 0) { + break; + } + if (isHidden) break; + if(showPretty) sb.append(getLevelIndent()); + sb.append("\"").append(name).append("\":{"); + keyIter = childs.keySet().iterator(); + int g=0; + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + part = item.toJson(showPretty, withBizData); + if(StringUtils.isNotEmpty(part)) { + if(g>0) sb.append(","); + if(showPretty) sb.append("\n"); + sb.append(part); + g++; + } + } + if(showPretty) { + sb.append("\n"); + sb.append(getLevelIndent()); + } + sb.append("}"); + break; + case StandardType.GRID : + if(showPretty) { + sb.append(getLevelIndent()); + } + if (isHidden) break; + sb.append("\"").append(name).append("\":["); +// if(showPretty) sb.append("\n"); + for(int p=0; p group = list.get(p); + keyIter = group.keySet().iterator(); + int ai=0; + if(showPretty) { + sb.append("\n"); + sb.append(getLevelIndent()); + } + if(p>0) sb.append(","); + sb.append("{"); + while(keyIter.hasNext()) { + if(ai>0) sb.append(","); + String key = keyIter.next(); + StandardItem item = group.get(key); + if(showPretty) sb.append("\n"); + sb.append(item.toJson(showPretty, withBizData)); + ai++; + } + + if(showPretty) { + sb.append("\n"); + sb.append(getLevelIndent()).append("}"); + } + else { + sb.append("}"); + } + } +// if(showPretty) { +// sb.append("\n"); +// sb.append(getLevelIndent()); +// } + sb.append("]"); + break; + case StandardType.FARRAY : + if(showPretty) { + sb.append(getLevelIndent()); + } + sb.append("\"").append(name).append("\":["); +// if(showPretty) sb.append("\n"); + for(int p=0; p0) sb.append(","); + sb.append(toJsonValue(values.get(p))); + } +// if(showPretty) { +// sb.append("\n"); +// sb.append(getLevelIndent()); +// } + sb.append("]"); + break; + case StandardType.BIZDATA : + if(withBizData) { + if(showPretty) sb.append(getLevelIndent()); + sb.append("\"").append(name).append("\":"); + if(StringUtils.isEmpty(getValue())) { +// sb.append(toJsonValue(null)); + sb.append("{}"); + } + else { + // 업무데이터가 Json인지 확인 + String jsonString = getValue(); + if(jsonString.startsWith("{") || jsonString.startsWith("[")) {//배열로 시작하는게 있어서 + sb.append(jsonString); + } + else { + sb.append(toJsonValue()); + } + } + } + else { + return null; + } + break; + default : + break; + } + return sb.toString(); + } + + private String toStartTag(String nodeName) { + StringBuilder sb = new StringBuilder(); + sb.append("<").append(nodeName).append(">"); + return sb.toString(); + } + private String toEndTag(String nodeName) { + StringBuilder sb = new StringBuilder(); + sb.append(""); + return sb.toString(); + } + + protected String toXmlValue() { + return value; + } + + public String toXML() { + String encoding = EncodingVar.xmlEncoding; +// logger.debug("Encoding : {}", encoding ); + return toXML(encoding, false); + } + + public String toPrettyXML() { + String encoding = EncodingVar.xmlEncoding; +// logger.debug("Encoding : {}", encoding ); + return toXML(encoding, true); + } + + // FIX-ME : Attribute와 Element가 혼합된 Group/Array는 현재 처리 불가함. + // XML의 Attribute Group일 경우 Group과 Item의 FieldType은 모두 1 로 설정되어야 함. + // 향후 XMLParser로 생성하는 방안은 고려해 봐야 함. + public String toXML(String encode, boolean showPretty) { + StringBuilder sb = new StringBuilder(); + Iterator keyIter = null; + switch(getType()) { + case StandardType.MESSAGE : + sb.append(""); + if(showPretty) sb.append("\n"); + + sb.append(toStartTag(name)); + + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + sb.append(item.toXML(encode, showPretty)); + } + + if(showPretty) sb.append("\n"); + sb.append(toEndTag(name)); + break; + case StandardType.FIELD : + if(fieldType == StandardFieldType.ELEMENT) { + if(showPretty) { + sb.append("\n"); + sb.append(getLevelIndent()); + } + sb.append(toStartTag(name)); + sb.append(toXmlValue()); + sb.append(toEndTag(name)); + } + else { + sb.append(" ").append(name).append("=\""); + sb.append(toXmlValue()).append("\"");; + } + break; + case StandardType.GROUP : + // skip variable group + if( getSize() == 0) { + break; + } + if (isHidden) break; + if(showPretty) { + sb.append("\n"); + sb.append(getLevelIndent()); + } + if(fieldType == 0) { + sb.append(toStartTag(name)); + } + else { + sb.append("<").append(name); + } + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + sb.append(item.toXML(encode, showPretty)); + } + + if(fieldType == 0) { + if(showPretty) { + sb.append("\n"); + sb.append(getLevelIndent()); + } + sb.append(toEndTag(name)); + } + else { + sb.append(" />");; + } + break; + case StandardType.GRID : + if(showPretty) { + sb.append(getLevelIndent()); + } + if (isHidden) break; + for(int p=0; p group = list.get(p); + keyIter = group.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = group.get(key); + sb.append(item.toXML(encode, showPretty)); + } + if(showPretty) { + sb.append("\n"); + sb.append(getLevelIndent()); + } + sb.append(toEndTag(name)); + } + break; + case StandardType.FARRAY : + if(showPretty) { + sb.append(getLevelIndent()); + } + for(int p=0; p keyIter = null; + try { + switch(getType()) { + case StandardType.MESSAGE : + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + totalSize +=item.getBytesDataLength(charset); + } + break; + case StandardType.FIELD : + totalSize += getLength(); + break; + case StandardType.GROUP : + // skip variable group + if( getSize() == 0 + //카카오뱅크 => 카카오카드 400응답시 아래 로직을 추가해야 전체건수에서 메시지부가 처리됨 + //메시지부 size 0 refPath refValue 사용 해서 있고 없고 처리 + && (StringUtils.isBlank(getRefPath()) + || StringUtils.isBlank(getRefValue())) + ) { + break; + } + if (isHidden) break; + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + totalSize +=item.getBytesDataLength(charset); + } + break; + case StandardType.GRID : + if( getSize() == 0 + //반복그리드 관련해서 추가되야됩 + && StringUtils.isBlank(getRefPath()) + && StringUtils.isBlank(getRefValue()) + ) { + break; + } + if (isHidden) break; + for(int p=0; p group = list.get(p); + keyIter = group.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = group.get(key); + totalSize +=item.getBytesDataLength(charset); + } + } + break; + case StandardType.FARRAY : + for(int p=0; p keyIter = null; +// logger.debug("Encoding : {}", charset); + try { + switch(getType()) { + case StandardType.MESSAGE : + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + bos.write(item.toByteArray(withBizData,charset)); //하위로 내려갈때 withBizDat 값이 없어져서 추가 jun's 20231101 + } + break; + case StandardType.FIELD : + if (getValue() == null) { + //데이타 타입에 따라서 패딩 변경 + if (dataType == StandardDataType.STRING || dataType == StandardDataType.ZZ_STRING) { + bos.write( ByteUtil.padding("", getLength(), (byte)' ')); + } else if (dataType == StandardDataType.NUMBER || dataType == StandardDataType.LL_NUMBER) { + bos.write( ByteUtil.padding("", getLength(), (byte)'0')); + }else { + bos.write( ByteUtil.padding(new byte[0], getLength()) ); + } + } else if (dataType == StandardDataType.STRING || dataType == StandardDataType.ZZ_STRING) { + bos.write( ByteUtil.padding(getBytesValue(charset), getLength()) ); + } else if (dataType == StandardDataType.NUMBER || dataType == StandardDataType.LL_NUMBER) { + bos.write( ByteUtil.padding(getBytesValue(charset), getLength(), (byte)'0', true) ); + } else { + bos.write( ByteUtil.padding(getBytesValue(charset), getLength()) ); + } + break; + case StandardType.GROUP : + // skip variable group + if( getSize() == 0 + //카카오뱅크 => 카카오카드 400응답시 아래 로직을 추가해야 전체건수에서 메시지부가 처리됨 + //메시지부 size 0 refPath refValue 사용 해서 있고 없고 처리 + && (StringUtils.isBlank(getRefPath()) + || StringUtils.isBlank(getRefValue())) + ) { + break; + } + if (isHidden) break; + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + bos.write(item.toByteArray(withBizData,charset)); //하위로 내려갈때 withBizDat 값이 없어져서 추가 jun's 20231101 + } + break; + case StandardType.GRID : + if( getSize() == 0 + //반복그리드 관련해서 추가되야됩 + && StringUtils.isBlank(getRefPath()) + && StringUtils.isBlank(getRefValue()) + ) { + break; + } + if (isHidden) break; + for(int p=0; p group = list.get(p); + keyIter = group.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = group.get(key); + bos.write(item.toByteArray(withBizData, charset)); //하위로 내려갈때 withBizDat 값이 없어져서 추가 jun's 20231101 + } + } + break; + case StandardType.FARRAY : + for(int p=0; p> getList() { + return list; + } + + public void setList(ArrayList> list) { + this.list = list; + } + + public ArrayList getValues() { + return values; + } + + public void setValues(ArrayList values) { + this.values = values; + } + + private LinkedHashMap cloneMap(LinkedHashMap childs) { + if(childs == null) return childs; + LinkedHashMap newMap = new LinkedHashMap(); + for(String key:childs.keySet()) + try { + newMap.put(key, (StandardItem)childs.get(key).clone()); + } catch (CloneNotSupportedException e) { + ; + } + return newMap; + } + @Override + public Object clone() throws CloneNotSupportedException { + StandardItem cloned = (StandardItem)super.clone(); + + if(childs != null) { + cloned.childs = cloneMap(childs); + } + + if(list != null) { + ArrayList> clist = new ArrayList<>(); + for(int idx=0; idx)values.clone()); + } + + if(value != null) { + cloned.setValue(String.copyValueOf(value.toCharArray())); + } + + if(bytesValue != null) { + byte[] clonedBytes = new byte[bytesValue.length]; + System.arraycopy(bytesValue, 0, clonedBytes, 0, bytesValue.length); + cloned.setBytesValue(clonedBytes); + } + return cloned; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/message/StandardLogItem.java b/src/main/java/com/eactive/eai/message/StandardLogItem.java new file mode 100644 index 0000000..7b3f599 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/StandardLogItem.java @@ -0,0 +1,91 @@ +package com.eactive.eai.message; + +import java.io.Serializable; + +public class StandardLogItem implements Serializable, Cloneable { + String name; + int level; // 0 : root ~ n + int type; // 0: Message, 1: Field, 2:Group, 3 : Grid, 4 : Field Array, 9 : BIZ DATA + int size; // array size + int fieldType; // 0: ELEMENT, 1: ATTRIBUTE, + int length; + int dataType; // 0: String, 1: Number, 10: ZZ String, 11: Length Number + String refPath; + String refValue; + String value; + String desc = ""; + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public int getLevel() { + return level; + } + public void setLevel(int level) { + this.level = level; + } + public int getType() { + return type; + } + public void setType(int type) { + this.type = type; + } + public int getSize() { + return size; + } + public void setSize(int size) { + this.size = size; + } + public int getFieldType() { + return fieldType; + } + public void setFieldType(int fieldType) { + this.fieldType = fieldType; + } + public int getLength() { + return length; + } + public void setLength(int length) { + this.length = length; + } + public int getDataType() { + return dataType; + } + public void setDataType(int dataType) { + this.dataType = dataType; + } + public String getRefPath() { + return refPath; + } + public void setRefPath(String refPath) { + this.refPath = refPath; + } + public String getRefValue() { + return refValue; + } + public void setRefValue(String refValue) { + this.refValue = refValue; + } + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } + public String getDesc() { + return desc; + } + public void setDesc(String desc) { + this.desc = desc; + } + @Override + public String toString() { + return "StandardLogItem [name=" + name + ", level=" + level + ", type=" + type + ", size=" + size + + ", fieldType=" + fieldType + ", length=" + length + ", dataType=" + dataType + ", refPath=" + refPath + + ", refValue=" + refValue + ", value=" + value + ", desc=" + desc + "]"; + } + + +} diff --git a/src/main/java/com/eactive/eai/message/StandardMessage.java b/src/main/java/com/eactive/eai/message/StandardMessage.java new file mode 100644 index 0000000..007e82b --- /dev/null +++ b/src/main/java/com/eactive/eai/message/StandardMessage.java @@ -0,0 +1,546 @@ +package com.eactive.eai.message; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.message.filter.MessageFilter; + +public class StandardMessage extends StandardItem { + private static final long serialVersionUID = 8250470942348479859L; + static Logger logger = LoggerFactory.getLogger(StandardMessage.class); + int readPosition = 0; + + private String serviceKey = null; + + private String bizDataCharset = null; + + private String bizDataPath = null; + private String llDataPath = null; + private String zzDataPath = null; + + private MessageFilter flatFilter = null; + + public String getBizDataCharset() { + return bizDataCharset; + } + + public void setBizDataCharset(String bizDataCharset) { + this.bizDataCharset = bizDataCharset; + } + + public MessageFilter getFlatFilter() { + return flatFilter; + } + + public void setFlatFilter(MessageFilter flatFilter) { + this.flatFilter = flatFilter; + } + + public String getServiceKey() { + return serviceKey; + } + + public void setServiceKey(String serviceKey) { + this.serviceKey = serviceKey; + } + + public String getBizDataPath() { + return bizDataPath; + } + + public void setBizDataPath(String bizDataPath) { + this.bizDataPath = bizDataPath; + } + + + public String getLlDataPath() { + return llDataPath; + } + + public void setLlDataPath(String llDataPath) { + this.llDataPath = llDataPath; + } + + public String getZzDataPath() { + return zzDataPath; + } + + public void setZzDataPath(String zzDataPath) { + this.zzDataPath = zzDataPath; + } + + public String getBizData() throws Exception { + if(bizDataPath == null) { + throw new Exception("bizDataPath path not configured, check layout definition."); + } + StandardItem item = findItem(bizDataPath); + if(item == null) { + return null; + } + else { + return item.getValue(); + } + } + + public byte[] getBizDataBytes() throws Exception { + if(StringUtils.isEmpty(this.bizDataCharset)) { + throw new Exception("bizData Charset not defined or bizData not set yet."); + } + return getBizDataBytes(this.bizDataCharset); + } + + public byte[] getBizDataBytes(String charset) throws Exception { + if(bizDataPath == null) { + throw new Exception("bizDataPath path not configured, check layout definition."); + } + StandardItem item = findItem(bizDataPath); + if(item == null) { + return null; + } + else { + byte[] bizBytes = item.getBytesValue(charset); + if(StringUtils.isNotEmpty(bizDataCharset) && bizBytes != null && + bizDataCharset.equalsIgnoreCase(charset)){ + return bizBytes; + } + else { + String bizData = item.getValue(); + if(bizData != null) { + bizDataCharset = charset; + bizBytes = bizData.getBytes(charset); + item.setBytesValue(bizBytes); + return bizBytes; + } + else { + return null; + } + } + } + } + + public void setBizData(byte[] data, String charset) throws Exception { + if(bizDataPath == null) { + throw new Exception("bizDataPath path not configured, check layout definition."); + } + StandardItem item = findItem(bizDataPath); + if(item != null) { + if (data == null){ + item.setValue(null); + item.setBytesValue(null); + } + else{ + item.setBytesValue(data); + item.setValue(new String(data, charset)); + } + setBizDataCharset(charset); + } + } + + public void setBizData(String data, String charset) throws Exception { + if(bizDataPath == null) { + throw new Exception("bizDataPath path not configured, check layout definition."); + } + StandardItem item = findItem(bizDataPath); + if(item != null) { + if (data == null){ + item.setValue(null); + item.setBytesValue(null); + } + else{ + item.setValue(data); + item.setBytesValue(data.getBytes(charset)); + } + setBizDataCharset(charset); + } + } + + public void setBizData(Object data, String charset) throws Exception { + if(bizDataPath == null) { + throw new Exception("bizDataPath path not configured, check layout definition."); + } + StandardItem item = findItem(bizDataPath); + if(item != null) { + if (data == null){ + item.setValue(null); + item.setBytesValue(null); + setBizDataCharset(charset); + }else if (data instanceof String){ + setBizData((String)data, charset); + }else if (data instanceof byte[]){ + setBizData((byte[])data, charset); + }else { + throw new Exception("invalid data object. -" + data.getClass()); + } + setBizDataCharset(charset); + } + } + + // use only FlatReader + public void cutBizData(int zzSize) throws Exception { + if(bizDataPath == null) { + throw new Exception("bizDataPath path not configured, check layout definition."); + } + StandardItem item = findItem(bizDataPath); + if(item != null) { + byte[] bizDataBytes = item.getBytesValue(this.bizDataCharset); + int finalSize = bizDataBytes.length - zzSize; + + if(finalSize > 0) { + byte[] fbizDataBytes = new byte[finalSize]; + for(int i=0; i list = new ArrayList(); + CharSequence chars = source; + int start = 0, end = 0; + for(int i=0; i childItems = this.getChilds(); + for(int i=0; i< paths.length; i++) { + String itemName = paths[i]; + int arrayIndex = StandardMessageUtil.getArrayIndex(itemName); + + if(arrayIndex >= 0) { + itemName = StandardMessageUtil.getArrayName(itemName); + // if XML, use 1 base index + if( !zeroBase ) { + arrayIndex = arrayIndex -1; + } + } + try { + item = childItems.get(itemName); + } + catch(Exception ex) { + logger.error("get Child error : this=" + itemName, ex); + return null; + } + if(i< paths.length-1) { + if(item != null && item.getType() >StandardType.FIELD) { + if(arrayIndex >= 0) { + childItems = item.getArrayChilds(arrayIndex, createNew); + } + else { + childItems = item.getChilds(); + } + if(childItems == null) { + logger.warn("childItems not found : " + paths[i] +" / "+ path); + return null; + } + } + else { + logger.warn("group not found : " + paths[i] +" / "+ path); + return null; + } + } + } + if(item == null) { + logger.warn("Item not found : " + path); + return null; + } + else { + return item; + } + } + + // group1.group2.item1 + public String findItemValue(String path) { + StandardItem item = findItem(path); + if(item == null) { + return null; + } + else { + return item.getValue(); + } + } + + public void setData(String path, String value) { + StandardItem item = findItem(path); + if(item == null) { + return; + } + else { + item.setValue(value); + } + } + +// deprecated +// public String toFixedString() { +// return toFixedString(true, this.bizDataCharset); +// } + + public String toFixedString(String charset) { + return toFixedString(true, charset); + } + + public String toFixedString(boolean withBizData) { + return toFixedString(withBizData, this.bizDataCharset); + } + + public String toFixedString(boolean withBizData, String charset) { + byte[] bytes = toByteArray(withBizData, charset); + try { + logger.debug("Encoding : {}", charset ); + return new String(bytes, charset); + } catch (UnsupportedEncodingException e) { + logger.error("encoding fail, use default.", e); + return new String(bytes); + } + } + + public String toJson(boolean withBizData) { + return toJson(false, withBizData); + } + public String toPrettyJson(boolean withBizData) { + return toJson(true, withBizData); + } + + public byte[] toByteArray(String charset) { + return toByteArray(true, charset); + } + +// deprecated +// public byte[] toByteArray() { +// return toByteArray(true, this.bizDataCharset); +// } + + public String getDataString(String messageType, String charset) throws Exception { + if (MessageType.JSON.equals(messageType)) { + return toJson(); + } else if (MessageType.XML.equals(messageType)) { + return toXML(); + } else if (MessageType.ASC.equals(messageType)) { + return toFixedString(charset); + } else if (MessageType.EBC.equals(messageType)) { + logger.error("Unsupported message type - " + MessageType.EBC); + throw new Exception("Unsupported msgType - " + messageType); + } + return null; + } + + public byte[] getDataBytes(String messageType, String charset) throws Exception { + if (MessageType.JSON.equals(messageType)) { + return toJson().getBytes(charset); + } else if (MessageType.XML.equals(messageType)) { + return toXML().getBytes(charset); + } else if (MessageType.ASC.equals(messageType)) { + return toByteArray(charset); + } else if (MessageType.EBC.equals(messageType)) { + logger.error("Unsupported message type - " + MessageType.EBC); + throw new Exception("Unsupported msgType - " + messageType); + } + return null; + } + public byte[] toByteArray(boolean withBizData, String charset) { + //if(runFilter && flatFilter != null) { // runFilter 사용여부가 아니라 withBizData 여부여서 변경하고 Filter가 null이 아니면 로직수행으로 변경 + if( flatFilter != null) { + flatFilter.doFilter(this); + } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + Iterator keyIter = null; + try { + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + bos.write(item.toByteArray(withBizData, charset)); + } + return bos.toByteArray(); + } catch(Exception e) { + logger.error("toByteArray failed", e); + return new byte[0]; + } + finally { + if(bos != null) + try { + bos.close(); + } catch (IOException e) { + ; + } + } + } + + public int getBytesDataLength() { + return getBytesDataLength(this.bizDataCharset); + } + + public int getBytesDataLength(String charset) { + Iterator keyIter = null; + int totalSize = 0; + try { + keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + totalSize +=item.getBytesDataLength(charset); + } + return totalSize; + } catch(Exception e) { + logger.error("getBytesDataLength failed", e); + return totalSize; + } + finally { + } + } + + /** + * path로 하위에 있는 byte 길이 계산 + * + * @param path + * @return + */ + public int getBytesDataLengthForPath(String path) { + Iterator keyIter = null; + int totalSize = 0; + try { + StandardItem find = findItem(path); + keyIter = find.childs.keySet().iterator(); + while (keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = find.childs.get(key); + totalSize += item.getBytesDataLength(this.bizDataCharset); + } + return totalSize; + } catch (Exception e) { + logger.error("getBytesDataLength failed", e); + return totalSize; + } finally { + } + } + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getLevelTreeIndent()).append("StandardMessage [name=" + name + ", level=" + level + + ", type=" + type +// +", size=" + size + ", fieldType=" + fieldType +", length=" + length + ", dataType=" + dataType +// + ", refPath=" + refPath + ", refValue=" + refValue +// + ", value=" + value + + ", desc=" + desc + "]"); + if(bizDataPath != null) sb.append(", bizDataPath=" + bizDataPath); + if(llDataPath != null) sb.append(", llDataPath=" + llDataPath); + if(zzDataPath != null) sb.append(", zzDataPath=" + zzDataPath); + + + Iterator keyIter = childs.keySet().iterator(); + while(keyIter.hasNext()) { + String key = keyIter.next(); + StandardItem item = childs.get(key); + sb.append("\n").append(item.toString()); + } + return sb.toString(); + } + + @Override + public Object clone() throws CloneNotSupportedException { + StandardMessage cloned = (StandardMessage)super.clone(); + if(flatFilter != null) cloned.setFlatFilter(flatFilter); + return cloned; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/message/StandardMessageUtil.java b/src/main/java/com/eactive/eai/message/StandardMessageUtil.java new file mode 100644 index 0000000..ccb92b6 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/StandardMessageUtil.java @@ -0,0 +1,374 @@ +package com.eactive.eai.message; + +import java.util.ArrayList; +import java.util.Properties; +import java.util.Stack; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.stdmessage.STDMessageManager; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.inbound.processor.ProcessVO; +import com.eactive.eai.message.layout.CsvFileReader; +import com.eactive.eai.message.layout.DatabaseReader; +import com.eactive.eai.message.layout.LayoutReader; +import com.eactive.eai.message.manager.StandardMessageManager; + +public class StandardMessageUtil { + static Logger logger = LoggerFactory.getLogger(StandardMessageUtil.class); + + public static String requestProcessorClass = "com.eactive.eai.inbound.processor.RequestProcessor"; + + public static String REST_URL_ACTION1 = "com.eactive.eai.inbound.action.RestUrlAdapterGroupParseRequestAction"; + public static String REST_URL_ACTION2 = "com.eactive.eai.inbound.action.RestUrlParseRequestAction"; + + public StandardMessageUtil() { + } + + public static String getBizData(EAIMessage eaiMessage) throws Exception { +// InterfaceMapper mapper = eaiMessage.getMapper(); + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + return standardMessage.getBizData(); + } + + public static void setBizData(EAIMessage eaiMessage, String bizData, String charset) throws Exception { +// InterfaceMapper mapper = eaiMessage.getMapper(); + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + standardMessage.setBizData(bizData, charset); + } + + public static StandardMessage getStandardMessageFromRule(Object message, ProcessVO vo, String charset, Properties prop) throws Exception { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardMessage standardMessage = standardManager.getStandardMessage(); + + STDMessageManager stdMessageManager = STDMessageManager.getInstance(); + standardMessage = stdMessageManager.getSTDMessage(vo.getSelectedKey()); + if (standardMessage == null) { + // API 서비스일경우 PathVariable 지원 추가 + // ex) /api/account/{no} + if (StringUtils.equalsAny(vo.getActionName(), REST_URL_ACTION1, REST_URL_ACTION2)) { + standardMessage = stdMessageManager.getSTDMessageForPathVariable(vo.getSelectedKey()); + } + + if (standardMessage == null) { + return null; + } + } + + standardMessage.setBizData(message, charset); + standardManager.getMessageCoordinator().coordinateAfterCreateMessageByRule(standardMessage, vo, prop); + return standardMessage; + } + + /** + * API 서비스에서 실제 요청된 path를 설정된 PathVariable 형태의 key를 찾는다 + * ex) /api/bank/account/12345 --> /api/bank/account/{accountNo} + * @param key + * @param actionName + * @return + */ + public static String getMatchedKey(String key, String actionName) { + STDMessageManager stdMessageManager = STDMessageManager.getInstance(); + String[] keys = stdMessageManager.getAllSTDMessageKeys(); + for (String keyStr : keys) { + if (StringUtils.equals(key, keyStr)) { + return keyStr; + } + } + + if (StringUtils.equalsAny(actionName, REST_URL_ACTION1, REST_URL_ACTION2)) { + return stdMessageManager.getMatchedPathVariable(key); + } + + return null; + } + + public static StandardMessage generateMessageFromCsvFile() { + String filePath = "./resources/standard-layout.csv"; + return generateMessageFromCsvFile(filePath); + } + public static StandardMessage generateMessageFromCsvFile(String filePath) { + ArrayList list = null; + + try { + LayoutReader reader = new CsvFileReader(); + list = reader.parse(filePath); + } + catch(Exception ex) { + ex.printStackTrace(); + return null; + } + StandardMessage message = null; + try { + message = generate(list); + // message = generate_backup(list); + } catch (Exception e) { + e.printStackTrace(); + } + return message; + } + + public static StandardMessage generateMessageFromDb(String layoutName) { + ArrayList list = null; + try { + LayoutReader reader = ApplicationContextProvider.getContext().getBean(DatabaseReader.class); + list = reader.parse(layoutName); + } + catch(Exception ex) { + logger.error("", ex); + ex.printStackTrace(); + return null; + } + StandardMessage message = null; + try { + message = generate(list); + // message = generate_backup(list); + } catch (Exception e) { + logger.error("", e); + e.printStackTrace(); + } + return message; + } + + + // TODO : if Fixed Array, clone list item to length ? + public static StandardMessage generate_backup(ArrayList itemList) throws Exception { + StandardMessage message = new StandardMessage(); + Stack stack = new Stack(); + Stack stackPath = new Stack(); + int pLevel = 0; + StandardItem parent = message; + String parentPath = null; +// logger.debug("======================================================"); + for(int i=0; i< itemList.size(); i++) { + StandardItem item = itemList.get(i); + logger.debug("{} : item - {}", i, item); + // top level + if(item.getLevel() == 0) { + message.setName(item.getName()); + continue; + } + + if(item.getLevel() == 1) { + message.addItem(item); + } + else { + // get parent & add + int levelDiff = (item.getLevel() - pLevel); + if( levelDiff == 0) { + // do nothing + } + else if( levelDiff == 1) { + parent = stack.peek(); + parentPath = stackPath.peek(); +// logger.debug("<< PEEK = {}", parent.getName()); + } + else if(levelDiff < 0) { + while(item.getLevel() > parent.getLevel() + && !stack.isEmpty()) { + parent = stack.pop(); + parentPath = stackPath.pop(); +// logger.debug("<< POP = {}", parent.getName()); + } + } + else { + throw new Exception("item level error - "+ item.getName() +" level diff=" + levelDiff); + } + + if(parent.getType() == StandardType.GROUP) { +// logger.debug("add group child item - {}", item); + parent.addItem(item); + } + else if(parent.getType() == StandardType.GRID) { + parent.addArrayItem(0, item); + } + else { + throw new Exception("item parent is not GROUP/ARRAY : item - " + item); + } + } + + if(item.getType() == StandardType.BIZDATA) { + if(item.getLevel() == 1) { + message.setBizDataPath(item.getName()); + } + else { + message.setBizDataPath(getFullPath(parentPath , item.getName())); + } + logger.debug("@@@ BIZ DATA PATH = {}", message.getBizDataPath()); + } + + // if group/array,push to stack, pLevel + if(item.getType() > 1) { + logger.debug(">> PUSH = {}", item.getName()); + + if(parent.getLevel() == item.getLevel()) { +// logger.debug(">> POP revious sibling = {}", parent.getName()); + stack.pop(); + stackPath.pop(); + } + stackPath.push( getFullPath(parentPath , item.getName()) ); + stack.push(item); + } + else { + if(item.getDataType() == StandardDataType.LL_NUMBER) { + if(item.getLevel() == 1) { + message.setLlDataPath(item.getName()); + } + else { + message.setLlDataPath(getFullPath(parentPath , item.getName())); + } + logger.debug("@@@ LL_NUMBER PATH = {}", message.getLlDataPath()); + + } + else if(item.getDataType() == StandardDataType.ZZ_STRING) { + if(item.getLevel() == 1) { + message.setZzDataPath(item.getName()); + } + else { + message.setZzDataPath(getFullPath(parentPath , item.getName())); + } + logger.debug("@@@ ZZ_STRING PATH = {}", message.getZzDataPath()); + + } + } + pLevel = item.getLevel(); + } + return message; + } + + public static StandardMessage generate(ArrayList itemList) throws Exception { + int itemIdx = 0; + String parentPath = ""; + + if (itemList == null || itemList.size() == 0) { + return null; + } + + // MESSAGE 항목이 없다면 추가 + if (itemList.get(0).getType() != StandardType.MESSAGE) { + StandardItem rootItem = new StandardItem("StandardRoot", 0, StandardType.MESSAGE, 0, + StandardDataType.STRING, null); + itemList.add(0, rootItem); + } + + StandardMessage message = new StandardMessage(); + return (StandardMessage) setRecursiveItems(message, itemList, itemIdx, parentPath); + } + + private static StandardItem setRecursiveItems(StandardMessage message, ArrayList itemList, + int itemIdx, String parentPath) { + StandardItem curItem = itemList.get(itemIdx); + if (curItem.getType() == StandardType.MESSAGE) { + message.setName(curItem.getName()); + curItem = message; + } + + if (curItem.getLevel() <= 1) { + parentPath = ""; + } + + if (curItem.getType() == StandardType.MESSAGE || curItem.getType() == StandardType.GROUP + || curItem.getType() == StandardType.GRID) { + for (int i = itemIdx + 1; i < itemList.size(); i++) { // sub item 처리 + StandardItem item = itemList.get(i); + if (item.getLevel() <= curItem.getLevel()) { + break; + } + + if (item.getLevel() == curItem.getLevel() + 1) { + if (curItem.getType() == StandardType.GRID) { + curItem.addArrayItem(0, + setRecursiveItems(message, itemList, i, getFullPath(parentPath, curItem.getName()))); + } else { + curItem.addItem( + setRecursiveItems(message, itemList, i, getFullPath(parentPath, curItem.getName()))); + } + } + } + } else { + if (curItem.getType() == StandardType.BIZDATA) { + message.setBizDataPath(getFullPath(parentPath, curItem.getName())); + logger.debug("@@@ BIZ DATA PATH = {}", message.getBizDataPath()); + } + + if (curItem.getDataType() == StandardDataType.LL_NUMBER) { + message.setLlDataPath(getFullPath(parentPath, curItem.getName())); + logger.debug("@@@ LL_NUMBER PATH = {}", message.getLlDataPath()); + + } else if (curItem.getDataType() == StandardDataType.ZZ_STRING) { + message.setZzDataPath(getFullPath(parentPath, curItem.getName())); + logger.debug("@@@ ZZ_STRING PATH = {}", message.getZzDataPath()); + + } + } + + return curItem; + } + + private static String getFullPath(String parentPath, String itemName) { + if(parentPath == null || parentPath.length() == 0) { + return itemName; + } + return parentPath + "." + itemName; + } + + public static int getArrayIndex(String path) { + int index = -1; + + if(path.charAt(path.length()-1) != ']') { + return index; + } + int start = path.indexOf("["); + if(start > 0) { + String p = path.substring(start + 1, path.length()-1); + try { + index = Integer.parseInt(p); + } + catch(NumberFormatException e) { + ; + } + } + return index; + } + + public static String getArrayName(String path) { + if(path.charAt(path.length()-1) != ']') { + return path; + } + int start = path.indexOf("["); + if(start > 0) { + String p = path.substring(0, start); + return p; + } + else { + return path; + } + } + + public static void main(String[] args) { +// logger.debug("{}", getArrayIndex("group[10]")); +// logger.debug("{}", getArrayName("group[10]")); +// logger.debug("{}", getArrayIndex("group")); +// logger.debug("{}", getArrayName("group")); + +// String basePath = "D:\\Projects\\workspaces\\current_elink4.5_online_multi\\elink-online-multi\\"; + String basePath = "D:\\SOURCE\\v4.5-beta-multi\\elink-online-multi\\"; + + String filePath = basePath + "src\\main\\resources\\standard-layout.csv"; +// String filePath = basePath + "src\\main\\resources\\standard-layout-sbi.csv"; + + + StandardMessage stdmsg = generateMessageFromCsvFile(filePath); + System.out.println("==========================================================================="); + System.out.println(stdmsg.getChilds().size()); + System.out.println(stdmsg); + System.out.println("==========================================================================="); + System.out.println(stdmsg.getLlDataPath()); + System.out.println(stdmsg.getBizDataPath()); + System.out.println(stdmsg.getZzDataPath()); + System.out.println("==========================================================================="); + } +} diff --git a/src/main/java/com/eactive/eai/message/StandardType.java b/src/main/java/com/eactive/eai/message/StandardType.java new file mode 100644 index 0000000..153e90c --- /dev/null +++ b/src/main/java/com/eactive/eai/message/StandardType.java @@ -0,0 +1,10 @@ +package com.eactive.eai.message; + +public interface StandardType { + public final int MESSAGE = 1; + public final int FIELD = 2; + public final int GROUP = 3; + public final int GRID = 4; + public final int FARRAY = 5; + public final int BIZDATA = 9; +} diff --git a/src/main/java/com/eactive/eai/message/filter/FlatMessageFilter.java b/src/main/java/com/eactive/eai/message/filter/FlatMessageFilter.java new file mode 100644 index 0000000..442554d --- /dev/null +++ b/src/main/java/com/eactive/eai/message/filter/FlatMessageFilter.java @@ -0,0 +1,18 @@ +package com.eactive.eai.message.filter; + +import com.eactive.eai.message.StandardMessage; + +public class FlatMessageFilter implements MessageFilter { + + @Override + public StandardMessage doFilter(StandardMessage message) { + try { + int totalSize = message.getBytesDataLength(); + message.setLlData(String.valueOf(totalSize)); + } catch (Exception e) { + ; + } + return message; + } + +} diff --git a/src/main/java/com/eactive/eai/message/filter/MessageFilter.java b/src/main/java/com/eactive/eai/message/filter/MessageFilter.java new file mode 100644 index 0000000..15e1fce --- /dev/null +++ b/src/main/java/com/eactive/eai/message/filter/MessageFilter.java @@ -0,0 +1,9 @@ +package com.eactive.eai.message.filter; + +import java.io.Serializable; + +import com.eactive.eai.message.StandardMessage; + +public interface MessageFilter extends Serializable { + public StandardMessage doFilter(StandardMessage message); +} diff --git a/src/main/java/com/eactive/eai/message/layout/CsvFileReader.java b/src/main/java/com/eactive/eai/message/layout/CsvFileReader.java new file mode 100644 index 0000000..9f23349 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/layout/CsvFileReader.java @@ -0,0 +1,97 @@ +package com.eactive.eai.message.layout; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.InputStreamReader; +import java.util.ArrayList; + +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.message.StandardItem; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.StandardMessageUtil; + +public class CsvFileReader implements LayoutReader { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + String COMMA_DELIMITER = ","; + String COMMENT_HEADER = "#"; + + public CsvFileReader() { + } + + private BufferedReader getReader(String filePath) throws Exception { + BufferedReader reader = null; + if(logger.isInfoEnabled()) logger.info("getReader from filepath. read file = " + filePath); + try { + reader = new BufferedReader(new FileReader(filePath)); + return reader; + } + catch(Exception ex) { + if(logger.isWarnEnabled()) { +// logger.warn("getReader failed. read file = " +filePath, ex); + logger.warn("getReader failed. read file = " +filePath +", " + ex.getMessage()); + } + } + try { + if(logger.isInfoEnabled()) logger.info("getReader from classpath. read file = " + filePath); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + reader = new BufferedReader(new InputStreamReader(classLoader.getResourceAsStream(filePath)) ); + return reader; + } + catch(Exception ex) { + if(logger.isWarnEnabled()) { +// logger.warn("getReader failed. read classpath file = " + filePath, ex); + logger.warn("getReader failed. read classpath file = " + filePath + ", " + ex.getMessage()); + } + } + throw new Exception("file not found : " + filePath); + } + + @Override + public ArrayList parse(String filePath) throws Exception { + if(logger.isInfoEnabled()) logger.info("CsvFileReader read file = " + filePath); + + ArrayList list = new ArrayList(); + + int lineNo = 0; + try (BufferedReader br = getReader(filePath)) { + String line; + while ((line = br.readLine()) != null) { + lineNo++; + if(line.startsWith(COMMENT_HEADER)) { + if(logger.isDebugEnabled()) logger.debug(String.format("SKIP comment %s : %s", lineNo, line) ); + continue; + } + if(logger.isDebugEnabled()) logger.debug(String.format("Parsing line %s : %s", lineNo, line) ); + String[] values = line.split(COMMA_DELIMITER, StandardItem.ITEM_COUNT); + StandardItem item = new StandardItem(values); + list.add(item); + } + } + catch(Exception ex) { + throw new Exception(String.format("csv file %s parsing error lineNo=%d", filePath, lineNo), ex); + } + return list; + } + + public static void main(String[] args) { + ArrayList list = null; + String filePath = "./resources/standard-layout.csv"; + try { + LayoutReader reader = new CsvFileReader(); + list = (ArrayList) reader.parse(filePath); + } + catch(Exception ex) { + ex.printStackTrace(); + return; + } + StandardMessage message = null;; + try { + message = StandardMessageUtil.generate(list); + logger.debug("@toCSVString\n" + message.toCSVString()); + logger.debug("@toString\n" + message.toString()); + logger.debug("@toJson\n" + message.toJson()); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/com/eactive/eai/message/layout/DatabaseReader.java b/src/main/java/com/eactive/eai/message/layout/DatabaseReader.java new file mode 100644 index 0000000..2ba0eb2 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/layout/DatabaseReader.java @@ -0,0 +1,64 @@ +package com.eactive.eai.message.layout; + +import java.util.ArrayList; +import java.util.Collection; + +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.stdmessage.loader.StandardMessageLayoutDeployLoader; +import com.eactive.eai.common.stdmessage.loader.StandardMessageLayoutLoader; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageLayoutDeploy; +import com.eactive.eai.data.entity.onl.stdmessage.StandardMessageLayoutItem; +import com.eactive.eai.message.StandardItem; + +@Component +@Transactional +public class DatabaseReader implements LayoutReader { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private StandardMessageLayoutDeployLoader standardMessageLayoutDeployLoader; + + @Autowired + private StandardMessageLayoutLoader standardMessageLayoutLoader; + + @Override + public ArrayList parse(String layoutName) throws Exception { + logger.info("DB Reader Init"); + + boolean isMaster = false; + String targetLayoutName = null; + if(StringUtils.isBlank(layoutName)){ + StandardMessageLayoutDeploy deploy = standardMessageLayoutDeployLoader.findFirst(); + if(deploy != null){ + targetLayoutName = deploy.getLayoutName(); + isMaster = true; + } + }else{ + targetLayoutName = layoutName; + } + + ArrayList list = new ArrayList<>(); + if(StringUtils.isNotBlank(targetLayoutName)){ + //로그 적재 시 사용 될 표준전문 레아이아웃 명을 저장한다(현재 로그저장 아키텍처 개선방안이 없어 임시로 작성한 코드이다) + // SUB 표준전문 로딩으로 로직 수정함. + if(isMaster) { + System.setProperty("STANDARD_LAYOUT_NAME", targetLayoutName); + logger.info("DB Reader Target Layout Name - {}", targetLayoutName); + } + Collection entityList = standardMessageLayoutLoader.getById(targetLayoutName) + .getStandardMessageLayoutItems(); + + for (StandardMessageLayoutItem entityItem : entityList) { + StandardItem item = new StandardItem(entityItem); + list.add(item); + } + } + + return list; + } +} diff --git a/src/main/java/com/eactive/eai/message/layout/LayoutReader.java b/src/main/java/com/eactive/eai/message/layout/LayoutReader.java new file mode 100644 index 0000000..dcc02c9 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/layout/LayoutReader.java @@ -0,0 +1,9 @@ +package com.eactive.eai.message.layout; + +import java.util.ArrayList; + +import com.eactive.eai.message.StandardItem; + +public interface LayoutReader { + public ArrayList parse(String fileParh) throws Exception; +} diff --git a/src/main/java/com/eactive/eai/message/manager/StandardMessageManager.java b/src/main/java/com/eactive/eai/message/manager/StandardMessageManager.java new file mode 100644 index 0000000..34f1c23 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/manager/StandardMessageManager.java @@ -0,0 +1,450 @@ +package com.eactive.eai.message.manager; + +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang3.SerializationUtils; +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.message.EncodingVar; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.StandardMessageUtil; +import com.eactive.eai.message.filter.MessageFilter; +import com.eactive.eai.message.mapper.MessageMapper; +import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.message.service.InterfaceMapper; +import com.eactive.eai.message.service.StandardMessageCoordinator; + +public class StandardMessageManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static StandardMessageManager instance; + private boolean started; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + +/** +# standard-message-config.properties +# layout : StandardMessage layout definition +layout.file.type=CSV +layout.file.path=./resources/standard-layout.csv +# mapper : StandardMessage's fields getter/setter interface +mapper.class=com.eactive.eai.message.service.DefaultInterfaceMapper +mapper.definition=./resources/standard-message-mapping-config.properties +# reader : parsing input data to StandardMessage +reader.JSON=com.eactive.eai.message.parser.JsonReader +reader.XML=com.eactive.eai.message.parser.XmlReader +reader.FLAT=com.eactive.eai.message.parser.FlatReader +*/ + public static String STANDARD_MESSAGE_CONFIG = "standard.message.config"; + private String DEFAULT_CONFIG_PATH = "./resources/standard-message-config.properties"; + private String DEFAULT_CONFIG_FILE = "standard-message-config.properties"; + + private String LAYOUT_FILE_TYPE = "layout.file.type"; + private String LAYOUT_FILE_PATH = "layout.file.path"; + + private String LAYOUT_FILTER = "layout.filter.FLAT"; + + private String MAPPER_CLASS = "mapper.class"; + private String MAPPER_DEFINITION = "mapper.definition"; + private String READER_PREFIX = "reader."; + + private String ENCODE_FLAT = "encode.flat"; + private String ENCODE_XML = "encode.xml"; + private String ENCODE_JSON = "encode.json"; + + private String COORDINATOR_CLASS = "message.coordinator.class"; + private String DEFAULT_COORDINATOR_CLASS = "com.eactive.eai.message.service.DefaultStandardMessageCoordinator"; + private String REQUEST_PROCESSOR_CLASS = "requestProcessor.class"; + + private StandardMessage standardMessage = null; + private InterfaceMapper mapper; + private StandardMessageCoordinator messageCoordinator; + + private ConcurrentHashMap readerMap = null; + + private Map versionMap = new HashMap<>();; + private String VERSION_LAYOUT_NAME = "version.layout.name"; + private String VERSION_LAYOUT_FILTER = "version.layout.filter.FLAT"; + private String VERSION_MAPPER = "version.mapper"; + private String VERSION_MAPPING_DEFINATION = "version.mapper.definition"; + private MessageMapper versionMapper; + private StandardMessage versionMessage = null; + private String versionLayoutName = null; + + public Map getVersionMap() { + return versionMap; + } + + public void setVersionMap(Map versionMap) { + this.versionMap = versionMap; + } + + public String getVersionLayoutName() { + return versionLayoutName; + } + + public void setVersionLayoutName(String versionLayoutName) { + this.versionLayoutName = versionLayoutName; + } + + public synchronized StandardMessage getVersionMessage() { + if(versionMessage == null) return null; + try { + return (StandardMessage) versionMessage.clone(); + } catch (CloneNotSupportedException e) { + return SerializationUtils.clone(standardMessage); + } + } + + private StandardMessageManager() { + readerMap = new ConcurrentHashMap<>(); + } + + public static StandardMessageManager getInstance() { + return LazyHolder.INSTANCE; + } + private static class LazyHolder { + private static final StandardMessageManager INSTANCE = new StandardMessageManager(); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICMM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + init(); + } catch(Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e,"RECEAICMM202")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICMM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + readerMap.clear(); + readerMap = null; + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) + { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() + { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) + { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public synchronized StandardMessage getStandardMessage() { + try { + return (StandardMessage) standardMessage.clone(); + } catch (CloneNotSupportedException e) { + return SerializationUtils.clone(standardMessage); + } + } + + public MessageMapper getVersionMapper() { + return versionMapper; + } + + public void setVersionMapper(MessageMapper versionMapper) { + this.versionMapper = versionMapper; + } + + public InterfaceMapper getMapper() { + return mapper; + } + + public void setMapper(InterfaceMapper mapper) { + this.mapper = mapper; + } + + public StandardMessageCoordinator getMessageCoordinator() { + return messageCoordinator; + } + + public void setMessageCoordinator(StandardMessageCoordinator messageCoordinator) { + this.messageCoordinator = messageCoordinator; + } + + public synchronized void reload() throws Exception { + if(logger.isWarn()) { + logger.warn("StandardMessageManager] reload all started ..."); + } + init(); + if(logger.isWarn()) { + logger.warn("StandardMessageManager] reload all finished ..."); + } + } + + @SuppressWarnings("rawtypes") + private void initReaderFactory(Properties config) { + Class cl = null; + StandardReader reader = null; + + Set keys = config.keySet(); + + for(Object key: keys) { + String keyStr = (String)key; + if(keyStr.startsWith(READER_PREFIX)) { + String name = keyStr.substring(READER_PREFIX.length()); + String readerClassName = config.getProperty(keyStr); + + try { + cl = Class.forName(readerClassName); + reader = (StandardReader)cl.newInstance(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + if(logger.isWarn()) logger.warn(String.format("Invalid class path : %s %s", keyStr, readerClassName), e); + continue; + } + readerMap.put(name, reader); + if(logger.isWarn()) logger.warn(String.format("# Add reader : %s %s", keyStr, readerClassName)); + } + } + } + + public StandardReader getReader(String messageType) { + return readerMap.get(messageType); + } + + @SuppressWarnings("rawtypes") + public void init() throws Exception { + try { + Properties config = loadConfigFile(); + logger.debug(config.toString()); + + String encodeFlat = config.getProperty(ENCODE_FLAT, "euc-kr"); + String encodeXml = config.getProperty(ENCODE_XML, "utf-8"); + String encodeJson = config.getProperty(ENCODE_JSON, encodeXml); + String requestProcessorClass = config.getProperty(REQUEST_PROCESSOR_CLASS); + if(logger.isDebug()) { + logger.debug( "{} : {}", ENCODE_FLAT, encodeFlat ); + logger.debug( "{} : {}", ENCODE_XML, encodeXml ); + logger.debug( "{} : {}", ENCODE_JSON, encodeJson ); + logger.debug( "{} : {}", REQUEST_PROCESSOR_CLASS, requestProcessorClass ); + } + EncodingVar.flatEncoding = encodeFlat; + EncodingVar.xmlEncoding = encodeXml; + EncodingVar.jsonEncoding = encodeJson; + StandardMessageUtil.requestProcessorClass = requestProcessorClass; + + String layoutFileType = config.getProperty(LAYOUT_FILE_TYPE, "CSV"); + String path = config.getProperty(LAYOUT_FILE_PATH); + if(logger.isDebug()) { +// logger.debug( String.format("%s : %s", LAYOUT_FILE_TYPE, layoutFileType) ); +// logger.debug( String.format("%s : %s", LAYOUT_FILE_PATH, path) ); + logger.debug( "{} : {}", LAYOUT_FILE_TYPE, layoutFileType ); + logger.debug( "{} : {}", LAYOUT_FILE_PATH, path ); + } + + + if("CSV".contentEquals(layoutFileType.toUpperCase())) { + standardMessage = StandardMessageUtil.generateMessageFromCsvFile(path); + } else if(StringUtils.startsWithIgnoreCase(layoutFileType, "DB")) { + String layout = StringUtils.substring(layoutFileType, 3); + standardMessage = StandardMessageUtil.generateMessageFromDb(StringUtils.trimToNull(layout)); + } else { + standardMessage = StandardMessageUtil.generateMessageFromCsvFile(path); + } + + if(standardMessage != null) { + standardMessage.setReadPosition(0); + } + String flatFilterClass = config.getProperty(LAYOUT_FILTER); + logger.debug("{} : {}", LAYOUT_FILTER, flatFilterClass); + + String versionFlatFilterClass = config.getProperty(VERSION_LAYOUT_FILTER); + logger.debug("{} : {}", VERSION_LAYOUT_FILTER, versionFlatFilterClass); + + + if(StringUtils.isNotBlank(flatFilterClass)) { + try { + Class cl = Class.forName(flatFilterClass); + MessageFilter flatFilter = (MessageFilter)cl.newInstance(); + standardMessage.setFlatFilter(flatFilter); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + if(logger.isWarn()) logger.warn(String.format("configure %s : %s", LAYOUT_FILTER, flatFilterClass), e); + } + } + + String coordinatorClass = config.getProperty(COORDINATOR_CLASS, DEFAULT_COORDINATOR_CLASS); + logger.debug("{} : {}", COORDINATOR_CLASS, coordinatorClass); + try { + Class cl = Class.forName(coordinatorClass); + this.messageCoordinator = (StandardMessageCoordinator) cl.newInstance(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + if (logger.isWarn()) + logger.warn(String.format("configure %s : %s", COORDINATOR_CLASS, + config.getProperty(COORDINATOR_CLASS)), e); + } + + String mapperClass = config.getProperty(MAPPER_CLASS); + String mapperFilePath = config.getProperty(MAPPER_DEFINITION); + if(logger.isDebug()) logger.debug( String.format("%s : %s", MAPPER_CLASS, mapperClass) ); + if(logger.isDebug()) logger.debug( String.format("%s : %s", MAPPER_DEFINITION, mapperFilePath) ); + + if(mapperClass == null) { + throw new Exception("StandardMessageManager | config error, not found config : " + MAPPER_CLASS); + } + if(mapperFilePath == null) { + throw new Exception("StandardMessageManager | config error, not found config : " + MAPPER_DEFINITION); + } + + initReaderFactory(config); + + Class cl = null; + try { + cl = Class.forName(mapperClass); + mapper = (InterfaceMapper)cl.newInstance(); + Properties mapperMapPropties = loadConfigFileProperties(mapperFilePath); + HashMap map = propertyToMap(mapperMapPropties); + mapper.initPathMap(map); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + return; + } + if(logger.isDebug()) logger.debug("mapperClass : {}", mapper.getClass().getCanonicalName()); + + String versionMapperClass = config.getProperty(VERSION_MAPPER); + if(StringUtils.isEmpty(versionMapperClass)) { + versionMapperClass = "com.eactive.eai.message.mapper.DefaultMessageMapper"; + } + if(logger.isDebug()) logger.debug("version.mapper : {}", versionMapperClass); + try { + Class clazz = Class.forName(versionMapperClass); + versionMapper = (MessageMapper)clazz.newInstance(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + return; + } + if(logger.isDebug()) logger.debug("version.mapper class : {}", versionMapper.getClass().getCanonicalName()); + + String versionMapFilePath = config.getProperty(VERSION_MAPPING_DEFINATION); + if(logger.isDebug()) logger.debug( String.format("%s : %s", VERSION_MAPPING_DEFINATION, versionMapFilePath) ); + if(versionMapFilePath != null) { + Properties versionMapPropties = loadConfigFileProperties(versionMapFilePath); + versionMap = propertyToMap(versionMapPropties); + } + if(logger.isDebug()) logger.debug("versionMap size ="+ versionMap.size() ); + + versionLayoutName = config.getProperty(VERSION_LAYOUT_NAME); + if(logger.isDebug()) logger.debug( String.format("%s : %s", VERSION_LAYOUT_NAME, versionLayoutName) ); + if(versionLayoutName != null) { + versionMessage = StandardMessageUtil.generateMessageFromDb(versionLayoutName); + versionMessage.setReadPosition(0); + + if(StringUtils.isNotBlank(versionFlatFilterClass)) { + try { + Class vcl = Class.forName(versionFlatFilterClass); + MessageFilter versionFlatFilter = (MessageFilter)vcl.newInstance(); + versionMessage.setFlatFilter(versionFlatFilter); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + if(logger.isWarn()) logger.warn(String.format("configure %s : %s", VERSION_LAYOUT_FILTER, versionFlatFilterClass), e); + } + } + } + } + catch(Exception ex) { + ex.printStackTrace(); + logger.error("init failed", ex); + } + } + + private HashMap propertyToMap(Properties prop) { + HashMap retMap = new HashMap<>(); + for (Map.Entry entry : prop.entrySet()) { + retMap.put(String.valueOf(entry.getKey()).trim(), String.valueOf(entry.getValue()).trim()); + } + return retMap; + } + + private Properties loadConfigFile() throws Exception { + String configFile = getConfigFile(); + return loadConfigFileProperties(configFile); + } + + private Properties loadConfigFileProperties(String configFile) throws Exception { + try { + return loadFileProperties(configFile); + } + catch(Exception e) { +// logger.warn("StandardMessageManager | loadFileProperties failed. - " + configFile, e); + logger.warn("StandardMessageManager | loadFileProperties failed. - " + configFile +", " +e.getMessage()); + } + // try classpath file + return loadClassPathProperties(configFile); + } + + private Properties loadFileProperties(String filePath) throws Exception { + logger.debug("configFile : ", filePath); + Properties p = new Properties(); + try(InputStream in = new FileInputStream(filePath)) { + p.load(in); + return p; + } catch(Exception e) { + throw new Exception("StandardMessageManager | Cannot load config file. - " + filePath, e); + } + } + + private Properties loadClassPathProperties(String filePath) throws Exception { + Properties p = new Properties(); + ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); + logger.warn("StandardMessageManager | ClassLoader : load. - "+ filePath); + try( InputStream in = classLoader.getResourceAsStream(filePath) ) { + p.load(in); + return p; + } catch(Exception e) { + if(logger.isWarn()) { +// logger.warn("StandardMessageManager | ClassLoader : Cannot load config file. - " + filePath, e); + logger.warn("StandardMessageManager | ClassLoader : Cannot load config file. - " + filePath +", " +e.getMessage()); + } + } + + logger.warn("StandardMessageManager | ClassLoader : load default - "+ DEFAULT_CONFIG_FILE); + try( InputStream in = classLoader.getResourceAsStream(DEFAULT_CONFIG_FILE) ) { + p.load(in); + logger.warn("StandardMessageManager | ClassLoader : load default success - "+ DEFAULT_CONFIG_FILE); + return p; + } catch(Exception e) { + logger.error("StandardMessageManager | ClassLoader : Cannot load default config file. - " + DEFAULT_CONFIG_FILE, e); + throw new Exception("StandardMessageManager | ClassLoader : Cannot load default config file. - " + DEFAULT_CONFIG_FILE, e); + } + } + private String getConfigFile() { + String configFilePath = System.getProperty(STANDARD_MESSAGE_CONFIG); + if (StringUtils.isEmpty(configFilePath)) { + return DEFAULT_CONFIG_PATH; + } else { + return configFilePath; + } + } +} diff --git a/src/main/java/com/eactive/eai/message/mapper/DefaultMessageMapper.java b/src/main/java/com/eactive/eai/message/mapper/DefaultMessageMapper.java new file mode 100644 index 0000000..66e841b --- /dev/null +++ b/src/main/java/com/eactive/eai/message/mapper/DefaultMessageMapper.java @@ -0,0 +1,105 @@ +package com.eactive.eai.message.mapper; + +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.message.StandardItem; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.layout.LayoutReader; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.StandardReader; + +public class DefaultMessageMapper implements MessageMapper { + + public StandardMessage parseSub(String msgType, Object message) throws Exception { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardMessage subMessage = standardManager.getVersionMessage(); + StandardReader reader = standardManager.getReader(msgType); + reader.parse(subMessage, message); + return subMessage; + } + + public StandardMessage mapFromSub(StandardMessage subMessage, StandardMessage orgStandardMessage) throws Exception { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + Map mappingMap = standardManager.getVersionMap(); + StandardMessage standardMessage = null; + + if (orgStandardMessage == null) { + standardMessage = standardManager.getStandardMessage(); + } else { + standardMessage = orgStandardMessage; + } + + for (Map.Entry entry : mappingMap.entrySet()) { + map(subMessage, entry.getValue(), standardMessage, entry.getKey()); + } + return standardMessage; + } + + // Sub request inbound(100), Sub response outbound(300) + // parse sub -> mapping to standard + public StandardMessage mapFromSub(String msgType, Object message, StandardMessage orgStandardMessage) + throws Exception { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + + StandardMessage subMessage = parseSub(msgType, message); + + Map mappingMap = standardManager.getVersionMap(); + StandardMessage standardMessage = null; + + if (orgStandardMessage == null) { + standardMessage = standardManager.getStandardMessage(); + } else { + standardMessage = orgStandardMessage; + } + + for (Map.Entry entry : mappingMap.entrySet()) { + map(subMessage, entry.getValue(), standardMessage, entry.getKey()); + } + return standardMessage; + } + + // Sub response inbound(400), Sub request outbound(200) + public StandardMessage convertToSub(StandardMessage standardMessage) throws Exception { + return convertToSub(standardMessage, null); + } + + public StandardMessage convertToSub(StandardMessage standardMessage, StandardMessage subMessage) throws Exception { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + if (subMessage == null) { + subMessage = standardManager.getVersionMessage(); + } + Map mappingMap = standardManager.getVersionMap(); + // Standard -> Sub + for (Map.Entry entry : mappingMap.entrySet()) { + map(standardMessage, entry.getKey(), subMessage, entry.getValue()); + } + return subMessage; + } + + // Not used until now + public StandardMessage convertToStandard(StandardMessage subMessage, StandardMessage standardMessage) + throws Exception { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + Map mappingMap = standardManager.getVersionMap(); + // Sub -> Standard + for (Map.Entry entry : mappingMap.entrySet()) { + map(subMessage, entry.getValue(), standardMessage, entry.getKey()); + } + return standardMessage; + } + + public void map(StandardMessage sourceMessage, String sourcePath, StandardMessage targetMessage, + String targetPath) { + if (sourceMessage == null || StringUtils.isBlank(sourcePath) || targetMessage == null + || StringUtils.isBlank(targetPath)) { + return; + } + StandardItem sItem = sourceMessage.findItem(sourcePath); + StandardItem tItem = targetMessage.findItem(targetPath); + if (sItem != null && tItem != null) { + tItem.setValue(sItem.getValue()); + } + } +} diff --git a/src/main/java/com/eactive/eai/message/mapper/MessageMapper.java b/src/main/java/com/eactive/eai/message/mapper/MessageMapper.java new file mode 100644 index 0000000..22d5ac0 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/mapper/MessageMapper.java @@ -0,0 +1,23 @@ +package com.eactive.eai.message.mapper; + +import com.eactive.eai.message.StandardMessage; + +public interface MessageMapper { + public StandardMessage parseSub(String msgType, Object message) throws Exception; + + // Sub request inbound(100), Sub response outbound(300) + // parse sub -> mapping to standard + public StandardMessage mapFromSub(StandardMessage subMessage, StandardMessage orgStandardMessage) throws Exception; + + public StandardMessage mapFromSub(String msgType, Object message, StandardMessage orgStandardMessage) throws Exception; + + // Sub response inbound(400), Sub request outbound(200) + public StandardMessage convertToSub(StandardMessage standardMessage) throws Exception; + public StandardMessage convertToSub(StandardMessage standardMessage, StandardMessage subMessage) throws Exception; + + // Not used until now + public StandardMessage convertToStandard(StandardMessage subMessage, StandardMessage standardMessage) throws Exception; + + public void map(StandardMessage sourceMessage, String sourcePath, StandardMessage targetMessage, + String targetPath); +} diff --git a/src/main/java/com/eactive/eai/message/parser/FlatReader.java b/src/main/java/com/eactive/eai/message/parser/FlatReader.java new file mode 100644 index 0000000..76e29bc --- /dev/null +++ b/src/main/java/com/eactive/eai/message/parser/FlatReader.java @@ -0,0 +1,289 @@ +package com.eactive.eai.message.parser; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.LinkedHashMap; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.eactive.eai.message.EncodingVar; +import com.eactive.eai.message.StandardDataType; +import com.eactive.eai.message.StandardItem; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.StandardType; + +public class FlatReader implements StandardReader { + static Logger logger = LoggerFactory.getLogger(FlatReader.class); + private char FIELD_SEPARATOR = '.'; + private boolean ZERO_BASE_INDEX = true; + + public FlatReader() { + + } + + public StandardMessage parse(StandardMessage message, Object flatObject) throws Exception { + ArrayList list = message.toList(); + for(int i=0; i itemMap = new LinkedHashMap(); + + message.setReadPosition(0); + + traverse(message, message, srcbytes, null, itemMap); + int remain = srcbytes.length - message.getReadPosition(); + if(remain > 0) { + throw new Exception("flat message parsing error(overflow) remain size="+remain); + } + + message.setBizDataCharset(encoding); + logger.debug("setBizDataCharset : {}", encoding); + +// for(String key:itemMap.keySet()) { +// logger.debug("~ itemMap : {} => {}", key, itemMap.get(key) ); +// } + return message; + } + + private void traverse(StandardMessage message, StandardItem currentItem, byte[] srcbytes, String parentName + , LinkedHashMap itemMap){ + String fieldName = null; + ArrayList childList = null; + StandardItem item = null; + + int type = currentItem.getType(); + int start = message.getReadPosition(); + fieldName = genPath(parentName, currentItem.getName()); + logger.debug("<-> CALL path = " + fieldName); + switch(type) { + case StandardType.MESSAGE: + childList = currentItem.getChildsList(); + for(int i=0; i map = currentItem.getArrayChilds(ai, true); + if(map == null) { + logger.warn("Array create failed item path = {}", fieldName +"[" + ai +"]"); + continue; + } + childList = new ArrayList(map.values()); + for(int i=0; i childList = message.getChildsList(); +// int i=0; +// for(StandardItem item:childList) { +// logger.debug( i++ + " - "+ item.getLevel() + " : " +item.getName()); +// jsonNode.get(item.getName()); +// } + + // make json map(path, value) + LinkedHashMap itemMap = new LinkedHashMap(); + traverse(message, jsonNode, null, itemMap); + +// for(String key:itemMap.keySet()) { +// logger.debug("~ itemMap : " + key + " => " + itemMap.get(key)); +// } + return message; + } + + private void traverse(StandardMessage message, JsonNode currentNode, String parentName, LinkedHashMap itemMap){ + StandardItem currentItem = null; + String fieldName = null; + if(parentName != null) { + if(logger.isDebugEnabled()) logger.debug("$ findItem :: findItem="+ parentName); + currentItem = message.findItem(parentName, FIELD_SEPARATOR, ZERO_BASE_INDEX, true); + if(currentItem == null) { + if(logger.isDebugEnabled()) logger.debug("$ SKIP :: undefined path in StandardMessage node name="+ parentName); + return; + } + } + if(currentNode == null) { + if(logger.isDebugEnabled()) logger.debug("$ SKIP :: node is NULL name="+ parentName); + return; + } + + if( currentItem!=null && currentItem.getType() == StandardType.BIZDATA) { + String bizData = null; + if(currentNode.getNodeType() == JsonNodeType.STRING) { + bizData = currentNode.asText(); + } + else { + bizData = currentNode.toString(); + } + itemMap.put(parentName , bizData); + currentItem.setValue(bizData); + return; + } + + switch(currentNode.getNodeType()) { + case OBJECT: + if( currentItem != null && currentItem.getSize() == 0 + && StringUtils.isNotBlank(currentItem.getRefPath()) + && StringUtils.isNotBlank(currentItem.getRefValue()) ) { + String refItemValue = itemMap.get(currentItem.getRefPath()); + + if (logger.isDebugEnabled()) + logger.debug("@GROUP name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]", + currentItem.getName(), currentItem.getRefPath(), refItemValue, + currentItem.getRefValue()); + + if (refItemValue != null) refItemValue = refItemValue.trim(); + String refValue = currentItem.getRefValue(); + if (refValue.startsWith("!")) { // 느낌표가 들어가면 다음에 나오는게 아닌경우 + refValue = refValue.substring(1); + if (refValue.equals(refItemValue)) { + logger.warn("@GROUP name={} SKIPPED.", currentItem.getName()); + currentItem.setHidden(true); + break; + } else { + currentItem.setHidden(false); + } + } else { + if (!currentItem.getRefValue().equals(refItemValue)) { + if (logger.isDebugEnabled()) + logger.warn("@GROUP name={} SKIPPED.", currentItem.getName()); + currentItem.setHidden(true); + break; + } else { + currentItem.setHidden(false); + } + } + } + Iterator fieldNames = currentNode.fieldNames(); + while(fieldNames.hasNext()) { + fieldName = fieldNames.next(); + JsonNode fieldValue = currentNode.get(fieldName); + fieldName = genPath(parentName, fieldName); + traverse(message, fieldValue, fieldName, itemMap); + } + if(currentItem != null && currentItem.getSize() == 0) { + currentItem.setSize(1); + } + break; + case ARRAY: + if(logger.isDebugEnabled()) logger.debug("@ARRAY name={}, getLength={}, getRefPath={}, getRefValue=[{}]" + , currentItem.getName(), currentItem.getLength(), currentItem.getRefPath(), currentItem.getRefValue()); + if( currentItem != null && currentItem.getSize() == 0 + && StringUtils.isNotBlank(currentItem.getRefPath()) + && StringUtils.isNotBlank(currentItem.getRefValue()) ) { + String refItemValue = itemMap.get(currentItem.getRefPath()); + + if(logger.isDebugEnabled()) logger.debug("@ARRAY name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]" + , currentItem.getName(), currentItem.getRefPath(), refItemValue, currentItem.getRefValue()); + + if( !currentItem.getRefValue().equals(refItemValue) ) { + if(logger.isDebugEnabled()) logger.warn("@ARRAY name={} SKIPPED.", currentItem.getName()); + break; + } + } + ArrayNode arrayNode = (ArrayNode) currentNode; + for(int i = 0; i < arrayNode.size(); i++) { + JsonNode arrayElement = arrayNode.get(i); + traverse(message, arrayElement, parentName+"["+ i+"]", itemMap); + } + break; + default: + if(logger.isDebugEnabled()) logger.debug("parsing : " + parentName + "=" +currentNode.asText()); + itemMap.put(parentName , currentNode.asText()); + if(currentItem.getType() == StandardType.FARRAY) { + currentItem.addValue(currentNode.asText()); + } + else { + currentItem.setValue(currentNode.asText()); + } + + break; + } + } + + private String genPath(String parent, String nodeName) { + if(parent == null || parent.length() < 1) { + return nodeName; + } + return parent +FIELD_SEPARATOR + nodeName; + } + +// public static void main(String[] args) { +// } + +} diff --git a/src/main/java/com/eactive/eai/message/parser/ReaderType.java b/src/main/java/com/eactive/eai/message/parser/ReaderType.java new file mode 100644 index 0000000..786b11e --- /dev/null +++ b/src/main/java/com/eactive/eai/message/parser/ReaderType.java @@ -0,0 +1,10 @@ +package com.eactive.eai.message.parser; + +public interface ReaderType { + public final String FLAT = "FLAT"; + public final String ASC = "ASC"; + public final String XML = "XML"; + public final String UXML = "UXL"; + public final String JSON = "JSN"; + public final String UJSON = "UJN"; +} diff --git a/src/main/java/com/eactive/eai/message/parser/StandardReader.java b/src/main/java/com/eactive/eai/message/parser/StandardReader.java new file mode 100644 index 0000000..21b7888 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/parser/StandardReader.java @@ -0,0 +1,7 @@ +package com.eactive.eai.message.parser; + +import com.eactive.eai.message.StandardMessage; + +public interface StandardReader { + public StandardMessage parse(StandardMessage message, Object data) throws Exception; +} diff --git a/src/main/java/com/eactive/eai/message/parser/XmlReader.java b/src/main/java/com/eactive/eai/message/parser/XmlReader.java new file mode 100644 index 0000000..850d6a2 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/parser/XmlReader.java @@ -0,0 +1,197 @@ +package com.eactive.eai.message.parser; + +import java.io.StringReader; +import java.util.Iterator; +import java.util.LinkedHashMap; + +import org.apache.commons.lang3.StringUtils; +import org.dom4j.Attribute; +import org.dom4j.DocumentException; +import org.dom4j.Element; +import org.dom4j.Node; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.eactive.eai.message.EncodingVar; +import com.eactive.eai.message.StandardItem; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.StandardType; + +public class XmlReader implements StandardReader { + static Logger logger = LoggerFactory.getLogger(XmlReader.class); + private char FIELD_SEPARATOR = '/'; // XML use / + private boolean ZERO_BASE_INDEX = false; // 1 base + + private boolean BIZDATA_NAME_INCLUDE = true; + + public XmlReader() { + + } + + public StandardMessage parse(StandardMessage message, Object obj) throws Exception { + String xmlString; + if (obj instanceof byte[]) { + xmlString = new String((byte[]) obj, EncodingVar.xmlEncoding); + } else { + xmlString = (String) obj; + } + + org.dom4j.io.SAXReader saxReader = new org.dom4j.io.SAXReader(); + org.dom4j.Document document = null; + try { + document = saxReader.read(new StringReader(xmlString)); + } catch (DocumentException e) { + e.printStackTrace(); + throw e; + } + org.dom4j.Element root = document.getRootElement(); +// ArrayList list = message.toList(); +// for(int i=0; i childList = message.getChildsList(); +// int i=0; +// for(StandardItem item:childList) { +// logger.debug( i++ + " - "+ item.getLevel() + " : " +item.getName()); +// jsonNode.get(item.getName()); +// } + + // make json map(path, value) + LinkedHashMap itemMap = new LinkedHashMap(); + String rootName = root.getName(); + message.setName(rootName); + traverse(message, root, null, itemMap); +// for(String key:itemMap.keySet()) { +// logger.debug("~ itemMap : " + key + " => " + itemMap.get(key)); +// } + return message; + } + + private String getContent(org.dom4j.Element element) { + if (element.isTextOnly()) + return element.getText(); + StringBuilder sb = new StringBuilder(); + Element currElement = null; + Iterator iterator = element.elementIterator(); + while( iterator.hasNext() ) { + currElement = iterator.next(); + sb.append(currElement.asXML()); + } + return sb.toString(); + } + + private void traverse(StandardMessage message, org.dom4j.Element currentNode, String parentName, LinkedHashMap itemMap){ + StandardItem currentItem = null; + String fullPath = null; + String fieldName = null; + if(currentNode == null) { + if(logger.isDebugEnabled()) logger.debug("$ SKIP :: node is NULL name="+ parentName); + return; + } + Iterator i = currentNode.elementIterator(); + while (i.hasNext()) { + org.dom4j.Element child = (org.dom4j.Element) i.next(); +// if necessary, uncomment below 2 lines. +// QName qn = new QName(child.getName(),Namespace.NO_NAMESPACE); +// child.setQName(qn); + + fullPath = child.getUniquePath(); + fieldName = lastNodeName(fullPath); + + fieldName = genPath(parentName, fieldName); + currentItem = message.findItem(fieldName, FIELD_SEPARATOR, ZERO_BASE_INDEX, true); + if(currentItem == null) continue; + + if(currentItem.getType() == StandardType.BIZDATA) { + String bizData = null; + if(BIZDATA_NAME_INCLUDE) + bizData = getContent(child); + else + bizData = child.asXML(); + + itemMap.put(fieldName , bizData); + currentItem.setValue(bizData); +// item.setBizData(bizData); + return; + } + + switch(child.getNodeType()) { + case Node.ELEMENT_NODE: + if(logger.isDebugEnabled()) logger.debug("$ ELEMENT_NODE name="+ fieldName + ", fullPath="+ fullPath+ ", value="+ child.getStringValue()); + if(currentItem.getType() == StandardType.FIELD) { + itemMap.put(fieldName , child.getStringValue()); + currentItem.setValue(child.getStringValue()); + } + else if(currentItem.getType() == StandardType.FARRAY) { + itemMap.put(fieldName , child.getStringValue()); + currentItem.addValue(child.getStringValue()); + } + else { + if(logger.isDebugEnabled()) logger.debug("@GROUP name={}, getLength={}, getRefPath={}, getRefValue=[{}]" + , currentItem.getName(), currentItem.getLength(), currentItem.getRefPath(), currentItem.getRefValue()); + if( currentItem.getSize() == 0 + && StringUtils.isNotBlank(currentItem.getRefPath()) + && StringUtils.isNotBlank(currentItem.getRefValue()) ) { + String refItemValue = null; + StandardItem refItem = message.findItem(currentItem.getRefPath(), '.', true, false); + if(refItem != null) { + refItemValue = refItem.getValue(); + } + + if(logger.isDebugEnabled()) logger.debug("@GROUP name={}, getRefPath={}, refItemValue=[{}], getRefValue=[{}]" + , currentItem.getName(), currentItem.getRefPath(), refItemValue, currentItem.getRefValue()); + + if( !currentItem.getRefValue().equals(refItemValue) ) { + if(logger.isDebugEnabled()) logger.warn("@GROUP name={} SKIPPED.", currentItem.getName()); + break; + } + } + int attrCnt = child.attributeCount(); + for (int ai=0; ai itemPathMap = new HashMap(); + + public void initPathMap(HashMap map) { + itemPathMap = map; + } + + protected String getPath(String key) { + String path = itemPathMap.get(key); + if(StringUtils.isBlank(path)) { + logger.warn("message-mapping not defined key = {}", key); + } + return path; + } + + public DefaultInterfaceMapper() { + + } + + protected String getItemValue(StandardMessage standardMessage, String path) { + if(standardMessage == null || StringUtils.isBlank(path)) return null; + return standardMessage.findItemValue(path); + } + + protected void setItemValue(StandardMessage standardMessage, String path, String value) { + if(standardMessage == null || StringUtils.isBlank(path)) { + return; + } + StandardItem item = standardMessage.findItem(path); + if(item != null) item.setValue(value); + } + //------------------------------------------------------------ + // 표준전문과 Mapping 되는 항목을 모두 정의해야 함. + //------------------------------------------------------------ + @Override + public String getEaiSvcCode(StandardMessage standardMessage) { + String eaiSvcCode = null; + String interfaceId = getInterfaceId(standardMessage); + String returnType = getSendRecvDivision(standardMessage); // S | R + String inExDivision = getInExDivision(standardMessage); // 1 | 2 + // TODO : site에 맞게 조합해야 함. + eaiSvcCode = interfaceId + returnType + StringUtils.defaultString(inExDivision); + return eaiSvcCode; + } + + @Override + public String nextGuidSeq(StandardMessage standardMessage) { + String guidSeq = getGuidSeq(standardMessage); + if(guidSeq == null) return ""; + int seq = 0; + try { + seq = Integer.parseInt(guidSeq) + 1; + } + catch(NumberFormatException e) { + seq = 1; + } + guidSeq = Integer.toString(seq); + setGuidSeq(standardMessage, guidSeq); + return guidSeq; + } + + @Override + public String getServiceId(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(SERVICE_ID)); + } + + @Override + public void setServiceId(StandardMessage standardMessage, String serviceId) { + setItemValue(standardMessage,getPath(SERVICE_ID), serviceId); + } + + @Override + public String getReqSysCode(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(REQ_SYS_CODE)); + } + + @Override + public String getChannelTypeCd(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(CHANNEL_TYPE_CD)); + } + + @Override + public String getChannelDetailCd(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(CHANNEL_DETAIL_CD)); + } + + @Override + public String getSendTime(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(SEND_TIME)); + } + + @Override + public String getGuid(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(GUID)); + } + + @Override + public String getSystemType(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(SYSTEM_TYPE)); + } + + @Override + public String getRecvTime(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(RECV_TIME)); + } + + @Override + public String getReturnValue(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(RETURN_VALUE)); + } + + @Override + public String getOrgGuid(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(GUID_ORG)); + } + + @Override + public String getGuidSeq(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(GUID_SEQ)); + } + + @Override + public String getReturnServiceId(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(RETURN_SERVICE_ID)); + } + + @Override + public String getInterfaceId(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(INTERFACE_ID)); + } + + @Override + public String getSessionId(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(SESSION_ID)); + } + + @Override + public String getSendRecvDivision(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(SEND_RECV_DIVISION)); + } + + @Override + public String getInExDivision(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(IN_EX_DIVISION)); + } + + @Override + public String getOperationEnv(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(OPERATION_ENV)); + } + + @Override + public String getFirstReqIp(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(FIRST_REQ_IP)); + } + + @Override + public String getRecoverYn(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(RECOVER_YN)); + } + + @Override + public String getInstCode(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(INST_CODE)); + } + + @Override + public String getTimeout(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(TIMEOUT)); + } + + @Override + public String getErrorCode(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(ERROR_CODE)); + } + + @Override + public String getErrorMsg(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(ERROR_MSG)); + } + + @Override + public String getUserId(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(USER_ID)); + } + + @Override + public String getResponseType(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(RESPONSE_TYPE)); + } + + @Override + public String getSyncAsyncType(StandardMessage standardMessage) { + return getItemValue(standardMessage, getPath(SYNC_ASYNC_TYPE)); + } + + @Override + public void setReqSysCode(StandardMessage standardMessage, String reqSysCode) { + setItemValue(standardMessage,getPath(REQ_SYS_CODE), reqSysCode); + + } + + @Override + public void setChannelTypeCd(StandardMessage standardMessage, String channelTypeCd) { + setItemValue(standardMessage,getPath(CHANNEL_TYPE_CD), channelTypeCd); + + } + + @Override + public void setChannelDetailCd(StandardMessage standardMessage, String channelDetailCd) { + setItemValue(standardMessage,getPath(CHANNEL_DETAIL_CD), channelDetailCd); + + } + + @Override + public void setSendTime(StandardMessage standardMessage, String sendTime) { + setItemValue(standardMessage,getPath(SEND_TIME), sendTime); + } + + @Override + public void setGuid(StandardMessage standardMessage, String guid) { + setItemValue(standardMessage,getPath(GUID), guid); + } + + @Override + public void setSystemType(StandardMessage standardMessage, String systemType) { + setItemValue(standardMessage,getPath(SYSTEM_TYPE), systemType); + } + + @Override + public void setRecvTime(StandardMessage standardMessage, String recvTime) { + setItemValue(standardMessage,getPath(RECV_TIME), recvTime); + } + + @Override + public void setReturnValue(StandardMessage standardMessage, String returnValue) { + setItemValue(standardMessage,getPath(RETURN_VALUE), returnValue); + } + + @Override + public void setOrgGuid(StandardMessage standardMessage, String orgGuid) { + setItemValue(standardMessage,getPath(GUID_ORG), orgGuid); + } + + @Override + public void setGuidSeq(StandardMessage standardMessage, String guidSeq) { + setItemValue(standardMessage,getPath(GUID_SEQ), guidSeq); + } + + @Override + public void setReturnServiceId(StandardMessage standardMessage, String returnServiceId) { + setItemValue(standardMessage,getPath(RETURN_SERVICE_ID), returnServiceId); + } + + @Override + public void setInterfaceId(StandardMessage standardMessage, String interfaceId) { + setItemValue(standardMessage,getPath(INTERFACE_ID), interfaceId); + } + + @Override + public void setSessionId(StandardMessage standardMessage, String sessionId) { + setItemValue(standardMessage,getPath(SESSION_ID), sessionId); + } + + @Override + public void setSendRecvDivision(StandardMessage standardMessage, String sendRecvDivision) { + setItemValue(standardMessage,getPath(SEND_RECV_DIVISION), sendRecvDivision); + } + + @Override + public void setInExDivision(StandardMessage standardMessage, String inExDivision) { + setItemValue(standardMessage,getPath(IN_EX_DIVISION), inExDivision); + } + + @Override + public void setOperationEnv(StandardMessage standardMessage, String operationEnv) { + setItemValue(standardMessage,getPath(OPERATION_ENV), operationEnv); + } + + @Override + public void setFirstReqIp(StandardMessage standardMessage, String firstReqIp) { + setItemValue(standardMessage,getPath(FIRST_REQ_IP), firstReqIp); + } + + @Override + public void setRecoverYn(StandardMessage standardMessage, String recoverYn) { + setItemValue(standardMessage,getPath(RECOVER_YN), recoverYn); + } + + @Override + public void setInstCode(StandardMessage standardMessage, String instCode) { + setItemValue(standardMessage,getPath(INST_CODE), instCode); + } + + @Override + public void setTimeout(StandardMessage standardMessage, String timeout) { + setItemValue(standardMessage,getPath(TIMEOUT), timeout); + } + + @Override + public void setErrorCode(StandardMessage standardMessage, String errorCode) { + setItemValue(standardMessage,getPath(ERROR_CODE), errorCode); + } + + @Override + public void setErrorMsg(StandardMessage standardMessage, String errorMsg) { + setItemValue(standardMessage,getPath(ERROR_MSG), errorMsg); + } + + @Override + public void setUserId(StandardMessage standardMessage, String userId) { + setItemValue(standardMessage,getPath(USER_ID), userId); + } + + @Override + public void setResponseType(StandardMessage standardMessage, String responseType) { + setItemValue(standardMessage,getPath(RESPONSE_TYPE), responseType); + } + + @Override + public void setSyncAsyncType(StandardMessage standardMessage, String syncAsyncType) { + setItemValue(standardMessage,getPath(SYNC_ASYNC_TYPE), syncAsyncType); + } +} diff --git a/src/main/java/com/eactive/eai/message/service/DefaultStandardMessageCoordinator.java b/src/main/java/com/eactive/eai/message/service/DefaultStandardMessageCoordinator.java new file mode 100644 index 0000000..01a5cc4 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/service/DefaultStandardMessageCoordinator.java @@ -0,0 +1,76 @@ +package com.eactive.eai.message.service; + +import java.util.Properties; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.UUIDGenerator; +import com.eactive.eai.inbound.processor.ProcessVO; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class DefaultStandardMessageCoordinator implements StandardMessageCoordinator { + + @Override + public void coordinateAfterParsing(StandardMessage standardMessage, Object paramObject, Properties prop) { + } + + @Override + public void coordinateAfterCreateMessageByRule(StandardMessage standardMessage, Object paramObject, Properties prop) { + // guid 설정 + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + InterfaceMapper mapper = standardManager.getMapper(); + mapper.setGuid(standardMessage, UUIDGenerator.getGUID(eaiServerManager.getSystemType())); + } + + @Override + public void coordinateInReturnObject(StandardMessage standardMessage) { + } + + @Override + public void coordinateBeforeInboundErrorResponse(StandardMessage standardMessage) { + } + + @Override + public boolean coordinateSetStandardMessageError(StandardMessage standardMessage, InterfaceMapper mapper, + String errCode, String errMsg) { + if (errCode != null) { + mapper.setErrorCode(standardMessage, errCode); + } + if (errMsg != null) { + mapper.setErrorMsg(standardMessage, errMsg); + } + return true; + } + + @Override + public void coordinateAfterRestored(StandardMessage restoredMessage, StandardMessage responseMessage) { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + InterfaceMapper mapper = standardManager.getMapper(); + mapper.setSendRecvDivision(restoredMessage, STDMessageKeys.SEND_RECV_CD_RECV); + } + + @Override + public boolean coordinateIsWaitCheckForSync(StandardMessage responseMessage) { + return false; + } + + @Override + public int coordinateForTimeoutCodeToValue(EAIMessage eaiMessage) { + return eaiMessage.getCurrentSvcMsg().getTmoVl(); + } + + @Override + public boolean coordinateValidation(StandardMessage standardMessage, ProcessVO vo) { + return true; + } + + @Override + public void coordinateAfterRecvNonStdSyncResponse(StandardMessage responseMessage) { + + } + + +} diff --git a/src/main/java/com/eactive/eai/message/service/InterfaceMapper.java b/src/main/java/com/eactive/eai/message/service/InterfaceMapper.java new file mode 100644 index 0000000..d126fc8 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/service/InterfaceMapper.java @@ -0,0 +1,98 @@ +package com.eactive.eai.message.service; + +import java.io.Serializable; +import java.util.HashMap; + +import com.eactive.eai.message.StandardMessage; + +public interface InterfaceMapper extends Serializable { + // define mapping + String REQ_SYS_CODE = "REQ_SYS_CODE"; + String CHANNEL_TYPE_CD = "CHANNEL_TYPE_CD"; + String CHANNEL_DETAIL_CD = "CHANNEL_DETAIL_CD"; + String SEND_TIME = "SEND_TIME"; + String GUID = "GUID"; + String SYSTEM_TYPE = "SYSTEM_TYPE"; + String RECV_TIME = "RECV_TIME"; + String RETURN_VALUE = "RETURN_VALUE"; + String GUID_ORG = "GUID_ORG"; + String GUID_SEQ = "GUID_SEQ"; + String SERVICE_ID = "SERVICE_ID"; + String RETURN_SERVICE_ID = "RETURN_SERVICE_ID"; + String INTERFACE_ID = "INTERFACE_ID"; + String SESSION_ID = "SESSION_ID"; + String SEND_RECV_DIVISION = "SEND_RECV_DIVISION"; + String IN_EX_DIVISION = "IN_EX_DIVISION"; + String OPERATION_ENV = "OPERATION_ENV"; + String FIRST_REQ_IP = "FIRST_REQ_IP"; + String RECOVER_YN = "RECOVER_YN"; + String INST_CODE = "INST_CODE"; + String TIMEOUT = "TIMEOUT"; + String ERROR_CODE = "ERROR_CODE"; + String ERROR_MSG = "ERROR_MSG"; + String USER_ID = "USER_ID"; + String RESPONSE_TYPE = "RESPONSE_TYPE"; + String SYNC_ASYNC_TYPE = "SYNC_ASYNC_TYPE"; + + public void initPathMap(HashMap map); + //------------------------------------------------------------ + // 표준전문과 Mapping 되는 항목을 모두 정의해야 함. + //------------------------------------------------------------ + public String getEaiSvcCode(StandardMessage standardMessage); + public String nextGuidSeq(StandardMessage standardMessage); + + public String getReqSysCode (StandardMessage standardMessage); + public String getChannelTypeCd (StandardMessage standardMessage); + public String getChannelDetailCd (StandardMessage standardMessage); + public String getSendTime (StandardMessage standardMessage); + public String getGuid (StandardMessage standardMessage); + public String getSystemType (StandardMessage standardMessage); + public String getRecvTime (StandardMessage standardMessage); + public String getReturnValue (StandardMessage standardMessage); + public String getOrgGuid (StandardMessage standardMessage); + public String getGuidSeq (StandardMessage standardMessage); + public String getServiceId (StandardMessage standardMessage); + public String getReturnServiceId (StandardMessage standardMessage); + public String getInterfaceId (StandardMessage standardMessage); + public String getSessionId (StandardMessage standardMessage); + public String getSendRecvDivision (StandardMessage standardMessage); + public String getInExDivision (StandardMessage standardMessage); + public String getOperationEnv (StandardMessage standardMessage); + public String getFirstReqIp (StandardMessage standardMessage); + public String getRecoverYn (StandardMessage standardMessage); + public String getInstCode (StandardMessage standardMessage); + public String getTimeout (StandardMessage standardMessage); + public String getErrorCode (StandardMessage standardMessage); + public String getErrorMsg (StandardMessage standardMessage); + public String getUserId (StandardMessage standardMessage); + public String getResponseType (StandardMessage standardMessage); + public String getSyncAsyncType (StandardMessage standardMessage); + + public void setReqSysCode (StandardMessage standardMessage, String reqSysCode ); + public void setChannelTypeCd (StandardMessage standardMessage, String channelTypeCd ); + public void setChannelDetailCd (StandardMessage standardMessage, String channelDetailCd ); + public void setSendTime (StandardMessage standardMessage, String sendTime ); + public void setGuid (StandardMessage standardMessage, String guid ); + public void setSystemType (StandardMessage standardMessage, String systemType ); + public void setRecvTime (StandardMessage standardMessage, String recvTime ); + public void setReturnValue (StandardMessage standardMessage, String returnValue ); + public void setOrgGuid (StandardMessage standardMessage, String guidOrg ); + public void setGuidSeq (StandardMessage standardMessage, String guidSeq ); + public void setServiceId (StandardMessage standardMessage, String serviceId ); + public void setReturnServiceId (StandardMessage standardMessage, String returnServiceId ); + public void setInterfaceId (StandardMessage standardMessage, String interfaceId ); + public void setSessionId (StandardMessage standardMessage, String sessionId ); + public void setSendRecvDivision (StandardMessage standardMessage, String sendRecvDivision); + public void setInExDivision (StandardMessage standardMessage, String inExDivision ); + public void setOperationEnv (StandardMessage standardMessage, String operationEnv ); + public void setFirstReqIp (StandardMessage standardMessage, String firstReqIp ); + public void setRecoverYn (StandardMessage standardMessage, String recoverYn ); + public void setInstCode (StandardMessage standardMessage, String instCode ); + public void setTimeout (StandardMessage standardMessage, String timeout ); + public void setErrorCode (StandardMessage standardMessage, String errorCode ); + public void setErrorMsg (StandardMessage standardMessage, String errorMsg ); + public void setUserId (StandardMessage standardMessage, String userId ); + public void setResponseType (StandardMessage standardMessage, String responseType ); + public void setSyncAsyncType (StandardMessage standardMessage, String syncAsyncType ); + +} diff --git a/src/main/java/com/eactive/eai/message/service/InterfaceMessage.java b/src/main/java/com/eactive/eai/message/service/InterfaceMessage.java new file mode 100644 index 0000000..dd81abf --- /dev/null +++ b/src/main/java/com/eactive/eai/message/service/InterfaceMessage.java @@ -0,0 +1,54 @@ +package com.eactive.eai.message.service; + +import com.eactive.eai.message.StandardMessage; +/* + * Example of EAIMessage + */ +public class InterfaceMessage { + private InterfaceMapper mapper; + private StandardMessage standardMessage; + + public InterfaceMessage() { + } + + public InterfaceMapper getMapper() { + return mapper; + } + + public void setMapper(InterfaceMapper mapper) { + this.mapper = mapper; + } + + public StandardMessage getStandardMessage() { + return standardMessage; + } + + public void setStandardMessage(StandardMessage standardMessage) { + this.standardMessage = standardMessage; + } + + //------------------------------------------------------------ + // Service 정보에서 정의한 고정값들 + //------------------------------------------------------------ + private String interfaceCode; + private String interfaceType; + + public String getInterfaceCode() { + return interfaceCode; + } + + public void setInterfaceCode(String interfaceCode) { + this.interfaceCode = interfaceCode; + } + + public String getInterfaceType() { + return interfaceType; + } + + public void setInterfaceType(String interfaceType) { + this.interfaceType = interfaceType; + } + + + +} diff --git a/src/main/java/com/eactive/eai/message/service/StandardMessageCoordinator.java b/src/main/java/com/eactive/eai/message/service/StandardMessageCoordinator.java new file mode 100644 index 0000000..11df794 --- /dev/null +++ b/src/main/java/com/eactive/eai/message/service/StandardMessageCoordinator.java @@ -0,0 +1,100 @@ +package com.eactive.eai.message.service; + +import java.util.Properties; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.inbound.processor.ProcessVO; +import com.eactive.eai.message.StandardMessage; + +/** + * + */ +public interface StandardMessageCoordinator { + + /** + * 전달된 표준메시지 파싱후 후처리 + * + * @param standardMessage + * @param paramObject + */ + public void coordinateAfterParsing(StandardMessage standardMessage, Object paramObject, Properties prop); + + /** + * 비표준 메시지일경우 Rule정보로부터 표준메시지 생성후 후처리 + * + * @param standardMessage + * @param prop + */ + public void coordinateAfterCreateMessageByRule(StandardMessage standardMessage, Object paramObject, Properties prop); + + /** + * 표준 메시지일경우 ReturnObject 에서 처리 + * + * @param standardMessage + */ + public void coordinateInReturnObject(StandardMessage standardMessage); + + /** + * 인바운드에러에서 표준전문 오류응답주기전 + * + * @param standardMessage + */ + public void coordinateBeforeInboundErrorResponse(StandardMessage standardMessage); + + /** + * 표준전문 에러 셋팅 및 + * 응답이 true 일경우 업무데이터에 오류메시지 설정 (현재 JSON만 컨트롤) + * 응답이 false일경우 업무데이터에 null처리 + * + * @param standardMessage + * @param mapper + * @param errCode + * @param errMsg + * @return + */ + public boolean coordinateSetStandardMessageError(StandardMessage standardMessage, InterfaceMapper mapper, + String errCode, String errMsg); + + /** + * 표준전문 복원후 + * + * @param standardMessage + * @param errCode + * @param errMsg + */ + public void coordinateAfterRestored(StandardMessage restoredMessage, StandardMessage responseMessage); + + /** + * 표준전문 복원후 + * + * @param standardMessage + * @param errCode + * @param errMsg + * @return + */ + public boolean coordinateIsWaitCheckForSync(StandardMessage responseMessage); + + /** + * Timeout 값 + * + * @param eaiMessage + * @return 타임아웃값 + */ + public int coordinateForTimeoutCodeToValue(EAIMessage eaiMessage); + + /** + * 표준전문 validation + * @param standardMessage + * @param vo + * @return + */ + public boolean coordinateValidation(StandardMessage standardMessage, ProcessVO vo); + + + /** + * 비표준 동기 응답 수신 후 표준전문 처리 + * + * @param responseMessage + */ + public void coordinateAfterRecvNonStdSyncResponse(StandardMessage responseMessage); +} diff --git a/src/main/java/com/eactive/eai/outbound/AMQProcess.java b/src/main/java/com/eactive/eai/outbound/AMQProcess.java new file mode 100644 index 0000000..4e4473a --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/AMQProcess.java @@ -0,0 +1,731 @@ +package com.eactive.eai.outbound; + +import java.util.Properties; + +import javax.jms.JMSException; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.amq.AMQAdapterConstants; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.header.HeaderAction; +import com.eactive.eai.common.header.HeaderActionFactory; +import com.eactive.eai.common.header.HeaderActionKeys; +import com.eactive.eai.common.logger.Keys; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.stdmessage.STDMessageMapper; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.common.util.TranLogUtil; +import com.eactive.eai.common.worker.Future; +import com.eactive.eai.common.worker.ResponseMap; +import com.eactive.eai.control.AMQSender; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.control.Transform; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.StandardReader; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class AMQProcess extends DefaultProcess { + + @Override + public void logSenderCtrlSendReq() throws Exception { + try { + LogSender.send(this.logPssSno, this.reqEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + @Override + public void logSenderCtrlSendRes() throws Exception { + try { + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.resEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + @Override + public void outboundCtrlCallService() throws Exception { + // 인터페이스에 셋팅된 타임아웃설정 + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tempProp.put(INTERFACE_TIME_OUT, "" + this.timeout); + try { + this.resObject = AMQSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, + this.tempProp); + + // 응답코드에 대한 처리 + this.resEaiMsg = setResponseForOutbound(this.resEaiMsg); + + if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + this.resEaiMsg = setSendTime(this.resEaiMsg); + } + } catch (JMSException jmse) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAICUL001"; + String rspErrorMsg = ExceptionUtil.make(jmse, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, jmse); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + + @Override + public void outboundCtrlCallServiceAsync() throws Exception { + /** + * async에서는 인터페이스 값을 설정하지 않고 Adapter의 타임아웃을 쓰기위해서 설정하지 않음 + */ + try { + + + this.resObject = AMQSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, + this.tempProp); + } catch (JMSException jmse) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAICUL001"; + String rspErrorMsg = ExceptionUtil.make(jmse, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, jmse); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + + @Override + public void transControlTransformSingleRes() throws Exception { + try { + this.srcTranObject = this.resObject; + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, false, this.diURI, this.srcTranObject); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " 300 변환오류", e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP030"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + + @Override + public void transControlTransformSingleReq() throws Exception { + try { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + if (bizData != null && bizData.length() > 0) { + this.srcTranObject = bizData; + } + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, true, this.diURI, this.srcTranObject); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " 200 변환오류", e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP020"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + @Override + public void printCallError(Exception e1) throws Exception { + this.resObject = ""; + + if ("RECEAICUL001".equals(this.resEaiMsg.getRspErrCd())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " UUID[" + this.reqEaiMsg.getSvcOgNo() + "] Queue Transfer Error - " + + e1.getMessage()); + } + } else { + // REST 는 TEST Call을 할수 없음.20200813.최준호 + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " UUID[" + this.reqEaiMsg.getSvcOgNo() + "] 수동시스템 오류 "); + } + } + } + + @Override + public void setRcvLogInfo() throws Exception { + this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); // 300 + + this.prop = new Properties(); + if (this.isSuccess) { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.FALSE); + } else { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.TRUE); + } + + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " 내부표준 추출"); + try { + resEaiMsg = setRcvLogInfo(resEaiMsg, this.adptrMsgType, this.resObject, this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizData(); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) { + logger.error(guidLogPrefix + rspErrorMsg, e); + } +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "SUB표준 업무데이터 추출"); + try { + this.resEaiMsg = convertToStandardMessage(resEaiMsg, adptrMsgType, this.resObject, + this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizData(); + } catch (Exception e) { + e.printStackTrace(); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP031"; // 잘못된 내부표준메시지 수신[{1}] + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + } + } + + @Override + public void setTopicResult() throws Exception { + try { + this.jmsRespObject = future.value(this.timeout); + if (this.jmsRespObject == null) { + throw new Exception("RECEAIOHP010"); + } + resEaiMsg = setResponseForOutbound(this.resEaiMsg); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP010"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } finally { + if (jmsRespAction != null) { + this.jmsRespAction.doEnd(); + } + } + + if (this.jmsRespObject == null) { + this.resObject = new byte[0]; + } else if (this.jmsRespObject instanceof EAIMessage) { + EAIMessage topicEaiMsg = (EAIMessage) this.jmsRespObject; + this.resObject = topicEaiMsg.getStandardMessage().getBizDataBytes(); + } else if (this.jmsRespObject instanceof byte[]) { + this.resObject = (byte[]) this.jmsRespObject; + } else { + this.resObject = new byte[0]; + } + } + + @Override + public void checkResultMessage() throws Exception { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " SYNC - QUEUE RESPONSE MESSAGE : " + + MessageUtil.toAdapterTypeString(this.resObject, this.outboundCharset)); + } + } + + @Override + public void checkSendResult() throws Exception { + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " ASYNC - QUEUE RESPONSE MESSAGE : " + + MessageUtil.toAdapterTypeString(this.resObject, this.outboundCharset)); + } + } + } + + @Override + public void init() throws Exception { + this.prop = null; + this.adapterName = null; + this.resEaiMsg = this.reqEaiMsg; + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + + // DefaultProcess 이관시 누락된 부분 추가 + this.svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // Inbound 호출방식 + this.psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 호출방식 + + // 복합거래의 보상거래여부를 확인 + this.svcPssTp = this.reqEaiMsg.getSvcPssTp(); + this.svcPssSeq = this.reqEaiMsg.getSvcPssSeq(); + + if (this.callProp != null) { + logger.debug(guidLogPrefix + " COMP_VALUE[" + this.callProp.getProperty(EAIKeys.CALL_COMP_KEY) + "]"); + if (EAIKeys.CALL_COMP_VALUE.equals(this.callProp.getProperty(EAIKeys.CALL_COMP_KEY))) { + this.isComp = true; + try { + this.svcPssSeq = Integer.parseInt(this.callProp.getProperty(EAIKeys.CALL_COMP_SVC_SEQ)); + logger.debug(guidLogPrefix + " CALL_COMP_SVC_SEQ[" + this.svcPssSeq + "]"); + } catch (Exception e) { + logger.warn(guidLogPrefix + " CALL_COMP_SVC_SEQ Get Error"); + } + } else { + this.isComp = false; + } + } else { + this.isComp = false; + } + + String returnType = getReturnType(reqEaiMsg); + + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + this.logPssSno = 400; + } else { + this.logPssSno = TranLogUtil.getReqLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + } + + // Inbound Adapter mesageType + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + this.inAdapterMsgType = MessageType.ASC; + + if (inAdptGrpVO == null) { + if (logger.isWarn()) { + if (this.prop == null) { + logger.warn(guidLogPrefix + "Source Adapter is null, TAS Inbound "); + } else { + logger.warn(guidLogPrefix + "Source Adapter is null, TAS Inbound = " + + this.prop.getProperty(Processor.TAS_ADAPTER_GROUP_NAME)); + } + } + this.inAdapterMsgType = MessageType.ASC; + } else { + this.inAdapterMsgType = inAdptGrpVO.getMessageType(); + } + } + + @Override + public void setSendMsg() throws Exception { + try { + // 200 로그를 위한 변환된 메시지부를 설정 + this.reqEaiMsg.getStandardMessage().setBizData(tgtTranObject, this.outboundCharset); + + if (this.tgtTranObject instanceof String) { + this.reqObject = (String) this.tgtTranObject; + } else { + throw new Exception("Invlid Transform output message (" + this.tgtTranObject + ")"); + } + + AdapterGroupVO adptGrpVO = null; + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + if (adptGrpVO == null) { + throw new Exception("adapter group not found"); + } + + AdapterVO adptVO = adptGrpVO.nextAdapterVO(); + + if (adptVO == null) { + throw new Exception("adapter not found"); + } + this.adapterName = adptVO.getName(); + + this.adptrMsgType = adptGrpVO.getMessageType(); + + AdapterPropManager manager = AdapterPropManager.getInstance(); + this.outboundProp = (Properties) manager.getProperties(adptVO.getPropGroupName());// clone 안함으로 변경 + if (this.tempProp == null) { + this.tempProp = new Properties(); + } + this.tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME, this.adapterGroupName); + this.tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_NAME, adptVO.getName()); + + this.tempProp.setProperty(AMQAdapterConstants.TEMP_INTERFACE_RESPONSE_TYPE, this.psvItfTp); + this.tempProp.setProperty(AMQAdapterConstants.TEMP_MESSAGE_TYPE, this.adptrMsgType); + + String svcName = getServiceId(this.reqEaiMsg); + if (svcName == null) { + svcName = ""; + } else { + svcName = svcName.trim(); + } + this.tempProp.setProperty(HttpClientAdapterServiceKey.TRAN_CODE, svcName); + + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); + this.adptrMsgType = adptGrpVO.getMessageType(); + } catch (Exception e) { + throw new Exception("Target Adapter Fail (" + this.adapterGroupName + ") "); + } + + // 표준메시지 방식일 경우 KESA메시지에 업무메시지를 설정하여 전달한다. + // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + this.reqObject = makeStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, + this.outboundCharset); + } else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + this.reqObject = makeSubStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, + this.outboundCharset); + if (this.reqObject instanceof String) { + this.reqObject = ((String) this.reqObject).getBytes(this.outboundCharset); + } + } else { + // 변환을 수행하고 결과가 비표준 XML일 경우에만 + if (EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getCnvEn()) + && MessageType.XML.equals(adptGrpVO.getMessageType())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Add Xml Header Tag to NONSTANDARD XML Message"); + } + + String reqString = (String) this.reqObject; + if (!StringUtils.startsWith(reqString, "\n" + reqString; + this.reqObject = reqString; + } + } + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " HTTP NONSTANDARD Request Message : " + + MessageUtil.toAdapterTypeString(this.reqObject, this.inboundCharset)); + } + // TAS 선택시 시뮬레이터 url로 변경 + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType()) + && StringUtils.equals(adptGrpVO.getType(), "AMQ")) { + PropManager manager = PropManager.getInstance(); + Properties prop = manager.getProperties(RouteKeys.SIM); + String simAddr = prop.getProperty(RouteKeys.SIM_REST_MOCKSERVER); + if (StringUtils.isBlank(simAddr)) { + throw new Exception(String.format("Properties %s > %s not setted", RouteKeys.SIM, + RouteKeys.SIM_REST_MOCKSERVER)); + } + + String url = StringUtils.removeEnd(simAddr, "/") + "/mockapi/" + this.reqEaiMsg.getEAISvcCd(); + this.outboundProp.put(HttpClientAdapterServiceKey.URL, url); + logger.debug("simUrl=" + url); + } + + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP022"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + @Override + public void getTopicProperty() throws Exception { + PropManager propManager = PropManager.getInstance(); + + this.topicConFactory = propManager.getProperty(RouteKeys.GROUP_NAME, + RouteKeys.ROUTING_TOPIC_CONNECTION_FACTORY); + this.topicName = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC); + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tracekey = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + + if (ElinkConfig.isUseCacheTopic()) { + this.future = new Future(); + try { + ResponseMap.getInstance().put(this.tracekey, future); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the Cache Response Future. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } else { + jmsRespAction = new com.eactive.eai.common.worker.JMSListenerAction(this.topicConFactory, this.topicName, + this.timeout); + jmsRespAction.doInit(this.tracekey); + this.future = new Future(); + try { + jmsRespAction.doStart(future.getSlot()); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the JMSListenerAction. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + } + + @Override + public void performSend() throws Exception { + try { + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_SEND + "]"); + logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + + if (this.tgtTranObject instanceof byte[]) { + this.orgData = new byte[((byte[]) this.tgtTranObject).length]; + System.arraycopy(this.tgtTranObject, 0, this.orgData, 0, ((byte[]) this.tgtTranObject).length); + + this.tgtTranObject = action.excute(this.orgData, (byte[]) this.tgtTranObject, + HeaderActionKeys.MESSAGE_SEND, headerContolType); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " this.orgMessage" + + MessageUtil.toAdapterTypeString((byte[]) this.tgtTranObject, this.inboundCharset)); + } + + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); + } + + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP040"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + @Override + public void performRecv() throws Exception { + try { + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_RECV + "]"); + logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + String bizData = this.resEaiMsg.getStandardMessage().getBizData(); + + if (bizData != null && bizData.length() > 0) { + this.tgtTranObject = bizData; + } + + if (this.tgtTranObject instanceof byte[]) { + this.tgtTranObject = action.excute(this.orgData, (byte[]) this.tgtTranObject, + HeaderActionKeys.MESSAGE_RECV, headerContolType); + this.resEaiMsg.getStandardMessage().setBizData(tgtTranObject, this.inboundCharset); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " this.tgtTranObject" + + MessageUtil.toAdapterTypeString((byte[]) this.tgtTranObject, this.outboundCharset)); + } + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); + } + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP040"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + @Override + public void storeMessage() throws Exception { + // ---------------------------------------------- + // 비동기-비동기 거래 && + // 수동이 표준이 아닌 경우 + // 원거래복원 여부가 '1' 일 경우에 + // ---------------------------------------------- + String recoverYn = getRecoverYn(reqEaiMsg); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Message 복원 Flag [" + recoverYn + "]"); + } + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) + && !com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd) + && STDMessageKeys.RECOVER_YN_YES.equals(recoverYn)) { + + try { + String keyMgtMsgCtnt = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Message 복원 실행 KEY[" + keyMgtMsgCtnt + "]"); + } + String extBizCd = this.reqEaiMsg.getExtBizCd(); + STDMessageMapper.storeMessageHeader(keyMgtMsgCtnt, this.reqEaiMsg.getStandardMessage(), extBizCd, + this.inAdapterMsgType); + } catch (Exception e) { + if (logger.isError()) { + logger.error(guidLogPrefix + "Message 저장 중 에러 발생", e); + } + + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP011"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + // --------------------------------------------------------------------- + } + + @Override + public void getBizMessage() throws Exception { + // setRcvLogInfo() 에서 이미 호출됨 + } + + @Override + public void waitCheckForSync() throws Exception { + /** + * Sync - Sync 거래중 Wait 메시지가 올경우 대비 + * + * Async -Sync 는 Flow Control에서 처리 함 + */ + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd) && resObject != null) { + if (EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + try { + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(this.adptrMsgType); + reader.parse(standardMessage, resObject); + // 표준 전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(outboundCharset); + } catch (Exception e) { + logger.error("standardMessage parsing error " + e.getMessage(), e); + return; + } + boolean isWait = standardManager.getMessageCoordinator().coordinateIsWaitCheckForSync(standardMessage); + if (isWait) { + getTopicProperty(); + try { + // SA 응답 메시지 설정 + setTopicResult(); + } catch (Exception e) { + // Timeout + executeTimeout(); + } + } + } + } + } + + @Override + public void transControlHeaderTrnsformSinglesRes() throws Exception { + } +} diff --git a/src/main/java/com/eactive/eai/outbound/CICSNGBSProcess.java b/src/main/java/com/eactive/eai/outbound/CICSNGBSProcess.java new file mode 100644 index 0000000..4556676 --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/CICSNGBSProcess.java @@ -0,0 +1,1603 @@ +//package com.eactive.eai.outbound; +// +//import java.util.Properties; +// +//import org.apache.commons.lang.time.StopWatch; +// +//import com.eactive.eai.adapter.AdapterGroupVO; +//import com.eactive.eai.adapter.AdapterManager; +//import com.eactive.eai.adapter.AdapterVO; +//import com.eactive.eai.adapter.wca.SNAProperties; +//import com.eactive.eai.common.EAIKeys; +//import com.eactive.eai.common.exception.ExceptionUtil; +//import com.eactive.eai.common.header.HeaderAction; +//import com.eactive.eai.common.header.HeaderActionFactory; +//import com.eactive.eai.common.header.HeaderActionKeys; +//import com.eactive.eai.common.logger.Keys; +//import com.eactive.eai.common.message.EAIMessage; +//import com.eactive.eai.common.message.EAIMessageKeys; +//import com.eactive.eai.common.message.MessageType; +//import com.eactive.eai.common.property.PropManager; +//import com.eactive.eai.common.routing.Process; +//import com.eactive.eai.common.routing.RouteKeys; +//import com.eactive.eai.common.util.ContainerUtil; +//import com.eactive.eai.common.util.Logger; +//import com.eactive.eai.common.util.MessageKeyExtractor; +//import com.eactive.eai.common.util.MessageUtil; +//import com.eactive.eai.common.util.StringUtil; +//import com.eactive.eai.common.util.TranLogUtil; +//import com.eactive.eai.common.worker.Future; +//import com.eactive.eai.common.worker.ResponseMap; +//import com.eactive.eai.control.LogSender; +//import com.eactive.eai.control.SNASender; +//import com.eactive.eai.control.Transform; +//import com.eactive.eai.inbound.processor.Processor; +//import com.eactive.eai.transformer.function.util.CodeConversion; +//import com.eactive.eai.transformer.util.EbcdicDumpUtil; +//import com.eactive.eai.transformer.util.IConv; +//import com.kbstar.eai.common.kbmessage.KBMessage; +//import com.kbstar.eai.common.kbmessage.KBMessageKeys; +//import com.kbstar.eai.common.kbmessage.parser.KBMessageParser; +//import com.kbstar.eai.common.kbmessage.parser.KBMessageParserFactory; +//import com.kbstar.eai.common.kbmessage.parser.KBMessageParserType; +// +//public class CICSNGBSProcess extends Process +//{ +// public boolean isComp; +// public java.lang.String svcPssTp; +// public int svcPssSeq; +// +// public com.eactive.eai.common.worker.Future future; +// public com.eactive.eai.common.worker.JMSListenerAction jmsRespAction; +// +// public int timerInfoResult; +// +// public String inAdapterMsgType; // 송신어댑터 타입 +// public String adptrMsgPtrnCd; +// +//// public com.eactive.eai.timer.TimerInfoVO timerInfoVO; +// +// public java.lang.String topicName; +// +// public java.lang.String topicConFactory; +// +// public transient java.lang.Object jmsRespObject; +// +// public int timeout; +// +// public java.lang.String tracekey; +// +// public java.lang.String diURI; +// public java.lang.String adapterGroupName; +// public java.lang.String adapterName; +// public java.lang.String snaResponseDataType; +// +// static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// +// public Object tgtTranObject; +// +// public Object srcTranObject; +// +// public boolean isTgtTran; +// +// public boolean isSuccess; +// +// public byte[] crcFlag; +// +// //public byte[] orgBytes; +// public Object orgMessage; +// +// public byte [] orgData; +// +// public byte[] reqBytes; +// +// public byte[] resBytes; +// +// public byte[] capBytes; +// +// public java.util.Properties callProp; +// +// public java.lang.String svcTsmtUsgTp; +// public java.lang.String psvItfTp; +// +// public java.util.Properties prop; +// public java.util.Properties snaProp; +// +// public int logPssSno; +// +// public com.eactive.eai.common.message.EAIMessage resEaiMsg; +// +// public com.eactive.eai.common.message.EAIMessage reqEaiMsg; +// +// static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); +// private int svrLogLevel; +// private static ThreadLocal local = new ThreadLocal(); //경과시간 동기화를 위한 ThreadLocal +// +//// private long realPrcssTime = 0; +// +// static final long serialVersionUID = 1L; +// +// String guidLogPrefix = "CICSNGBSProcess] "; +// +// private long slowTranTime = 500L; // SNA 통신시간에 대한 SLA Time +// +// public com.eactive.eai.common.message.EAIMessage clientReturn() +// { +// if(svrLogLevel >= 1) { +// try { +// long msgSndTm = System.currentTimeMillis(); +// +// Long threadData = (Long)local.get(); +// long processTm = msgSndTm - threadData.longValue(); +// if (esbLogger.isInfo()) esbLogger.info(guidLogPrefix + " End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); +// } catch (Exception e) { +// logger.warn("clientReturn", e); +// } +// } +// return resEaiMsg; +// } +// +// public void callService(com.eactive.eai.common.message.EAIMessage reqEaiMsg, java.util.Properties prop) +// { +// this.reqEaiMsg = reqEaiMsg; +// this.callProp = prop; +// +// if(this.reqEaiMsg == null) return; +// svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); +// +// guidLogPrefix = "CICSNGBSProcess] GUID["+reqEaiMsg.getKbMsg().getKBHeader().getGuIdNo()+"] UUID["+this.reqEaiMsg.getSvcOgNo()+"] "; +// +// if(svrLogLevel >= 1) { +// try{ +// long msgRcvTm = System.currentTimeMillis(); +// local.set(new Long(msgRcvTm)); +// +// if (esbLogger.isInfo()) esbLogger.info(guidLogPrefix + " started... - EAI Server Log Level is INFO"); +// }catch (Exception e) { +// logger.warn("callService", e); +// } +// } +// +// try{ +// flow(); +// }catch (Exception e){ +// logger.warn("flow", e); +// } +// } +// public void flow() throws Exception { +// //WarmUp start +// if (!isRealCall()){ +// return; +// } +// //WarmUp end +// +// //송신전 처리 start +// try{ +// //초기화 +// init(); +// //호출방식추출 +// getCallType(); +// //Header컨트롤여부 +// if(isHeaderControl()){ +// //Header송신컨트롤로직 +// performSend(); +// } +// +// //송신변환 +// if (isSourceTransform()){ +// //수동메시지 변환 +// transControlTransformSingleReq(); +// }else{ +// //메시지 설정 +// setTgtTranObject(); +// } +// //표준전문생성 +// createStandardMsg(); +// }catch (Exception e){ +// //오류처리 +// checkErrorReturn(e); +// return; +// } +// //송신전 처리 end +// +// //송신전로그 +// logSenderCtrlSendReq(); +// +// //Sync-Async 호출 start +// if (isSNASync()){ +// try{ +// //Sync 호출 +// snaCallCtrlCallService(); +// }catch(Exception e1){ +// printCallError(e1); +// } +// //응답메시지확인 +// checkResultMessage(); +// }else{ +// //SA +// if (isSyncAsyncPattern()){ +// //응답환경설정 +// getTopicProperty(); +// } +// +// try{ +// //Async 호출 +// snaCallCtrlCallServiceAsync(); +// }catch (Exception e1){ +// printCallError(e1); +// } +// //송신결과확인 후 AA 요청거래로그 +// checkSendResult(); +// //SA +// if (isSyncAsyncPattern()){ +// try{ +// //SA응답메시지 설정 +// setTopicResult(); +// }catch(Exception e){ +// //Timeout +// executeTimeout(); +// } +// } +// //AA commented - Do nothing +//// if(isAsyncAsyncPattern()){ +//// //TimerInfo 설정 +//// setTimerInfo(); +//// //Timer 정보등록 +//// timerInfoControlTimerInfoInsert(); +//// } +// } +// +// //Sync-Async 호출 end +// +// //정상처리 확인 start +// //정상처리확인 +// if (checkSnaProperty()){ +// //동기거래 +// if(isSync()){ +// //응답로그값 설정 +// setRcvLogInfo(); +// //응답로그 +// logSenderCtrlSendRes(); +// //업무응답메시지추출 +// getBizMessage(); +// //업무 응답메시지 확인 +// boolean successReturn = isSuccessReturn(); +// if(logger.isDebug()) logger.debug(guidLogPrefix + " isSuccessReturn() >> ["+successReturn+"]"); +// if (successReturn){ +// //정상메시지변환 +// transformToSource(); +// }else{ +// //오류메시지변환 +// transformErrorToSource(); +// } +// +// if(logger.isDebug()) logger.debug(guidLogPrefix + " isTgtTranCall() >> ["+isTgtTranCall()+"]"); +// //응답변환 +// if(isTgtTranCall()){ +// //응답메시지변환 +// transControlTransformSingleRes(); +// //변환응답메시지설정 +// setConvertedMsg(); +// }else{ +// //응답메시지설정 +// setResMsg(); +// } +// //Header컨트롤여부 +// if(isHeaderControl()){ +// //Header수신컨트롤로직 +// performRecv(); +// } +// }else{ +// //비동기 거래 +// } +// }else{ +// //default +// //요청거래 +// if(isRequest()){ +// //오류메시지설정 +// setSNAErrorMessage(); +// //오류메시지로그 +// logSenderCtrlSendError(); +// }else{ +// //default +// } +// } +// //정상처리 확인 end +//// clientReturn(); +// } +// +// public void snaCallCtrlCallServiceAsync() throws Exception +// { +// try { +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); +// AdapterVO adptVO = adptGrpVO.nextAdapterVO(); +// +// // 가용 Adapter가 없는 경우 +// if(adptVO == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(this.adapterGroupName); +// String resMsg = ExceptionUtil.make("RECEAIOSA900", msgArgs); +// throw new Exception(resMsg); +// } +// this.adapterName = adptVO.getName(); +// +// snaProp.setProperty(SNAProperties.ADAPTER_NAME, this.adapterName); +// snaProp.setProperty(SNAProperties.TRAN_MODE, SNAProperties.TRAN_MODE_NONRESPONSE); +// +// StopWatch stopWatch = new StopWatch(); +// stopWatch.start(); +// this.resBytes = SNASender.callService(this.adapterGroupName, this.snaProp, this.reqBytes); +// stopWatch.stop(); +// if (stopWatch.getTime() > slowTranTime){ +// if (logger.isWarn()){ +// logger.warn(guidLogPrefix + " SNA TRAN_MODE_NONRESPONSE response time = " + stopWatch.toString()); +// } +// } +// } +// catch(Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA001"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix + " " + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorMsg); +// } +// } +// +// public void snaCallCtrlCallService() throws Exception +// { +// try { +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); +// AdapterVO adptVO = adptGrpVO.nextAdapterVO(); +// +// // 가용 Adapter가 없는 경우 +// if(adptVO == null) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = String.valueOf(this.adapterName); +// String resMsg = ExceptionUtil.make("RECEAIOSA900", msgArgs); +// throw new Exception(resMsg); +// } +// this.adapterName = adptVO.getName(); +// +// snaProp.setProperty(SNAProperties.ADAPTER_NAME, this.adapterName); +// snaProp.setProperty(SNAProperties.TRAN_MODE, SNAProperties.TRAN_MODE_RESPONSE); +// +// StopWatch stopWatch = new StopWatch(); +// stopWatch.start(); +// +// this.resBytes = SNASender.callService(this.adapterGroupName, this.snaProp, this.reqBytes); +// +// stopWatch.stop(); +// if (stopWatch.getTime() > slowTranTime){ +// if (logger.isWarn()){ +// logger.warn(guidLogPrefix + " SNA TRAN_MODE_RESPONSE response time = " + stopWatch.toString()); +// } +// } +// +// //--------------------------------------------------------------------- +// // 응답코드에 대한 처리 +// KBMessage kbmessage = this.resEaiMsg.getKbMsg(); +// kbmessage.getKBHeader().setTelgmDmndDstcd(KBMessageKeys.TELGMDMNDDSTCD_RECV); +// kbmessage.getKBCommon().setChannelCommonLen("0000"); +// kbmessage.getKBCommon().setInptMdiaPartlLen("0000"); +// //--------------------------------------------------------------------- +// +// } catch(Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA001"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix + " " + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorMsg); +// } +// } +// +// public void logSenderCtrlSendRes() throws Exception +// { +// try { +// LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); +// } catch(Exception e) { +// if (logger.isWarn()) logger.warn(guidLogPrefix + " EAI 서비스코드[" + this.resEaiMsg.getEAISvcCd() + "] " + this.logPssSno + " 거래로그 중 오류발생"); +// } +// } +// +// public void logSenderCtrlSendError() throws Exception +// { +// // AA 거래에 대한 로그를 하지 않도록 수정 - 2008.05.29 +// if(EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) || +// EAIMessageKeys.SYNC_SVC.equals(this.psvItfTp) ) { +// try { +// LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); +// } catch(Exception e) { +// if (logger.isWarn()) logger.warn(guidLogPrefix + " EAI 서비스코드[" + this.resEaiMsg.getEAISvcCd() + "] " + this.logPssSno + " 거래로그 중 오류발생"); +// } +// } +// else { +// if(logger.isDebug()) logger.debug(guidLogPrefix + " Skip Error Logging - AA"); +// } +// } +// +// public void logSenderCtrlSendReq() throws Exception +// { +// if( EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) && +// EAIMessageKeys.ASYNC_SVC.equals(this.psvItfTp)) { +// // 2010.01.18 Adapter 호출 후에 로그를 남기도록 한다. 정길영 차장 요청 +// if (logger.isInfo()) logger.info(guidLogPrefix + " EAI 서비스코드[" + this.reqEaiMsg.getEAISvcCd() + "] AA 거래로그 SKIP"); +//// realPrcssTime = System.currentTimeMillis(); +// } +// else { +// try { +// LogSender.send(this.logPssSno, this.reqEaiMsg, this.prop); +// } catch(Exception e) { +// if (logger.isWarn()) logger.warn(guidLogPrefix + " EAI 서비스코드[" + this.reqEaiMsg.getEAISvcCd() + "] " + this.logPssSno + " 거래로그 중 오류발생"); +// } +// } +// } +// +//// public void timerInfoControlTimerInfoInsert() throws Exception +//// { +//// try { +//// //this.timerInfoResult = TimerInfoInsert.timerInfoInsert(this.timerInfoVO); +//// } catch(Exception e) { +//// String[] msgArgs = new String[1]; +//// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +//// String rspErrorCode = "RECEAIOSA040"; +//// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +//// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg, e); +//// this.resEaiMsg.setRspErrCd(rspErrorCode); +//// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +//// } +//// } +// +// public void transControlTransformSingleRes() throws Exception +// { +// try { +// this.srcTranObject = this.resBytes; +// this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, false, this.diURI, this.srcTranObject); +// } catch(Exception e) { +// if (logger.isError()) logger.error(guidLogPrefix + " 300 변환오류", e); +// // 변환오류가 발생하면 응답메시지를 통변환해서 응답메시지에 설정한다. 2005.11.17 +// try { +// this.tgtTranObject = CodeConversion.meToMixedAsc((byte[])this.srcTranObject); +// } catch(Exception ex) { +// this.tgtTranObject = new byte[0]; +// } +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA020"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix +rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// } +// } +// +// public void transControlTransformSingleReq() throws Exception +// { +// try { +// this.srcTranObject = this.orgMessage; +// this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, true, this.diURI, this.srcTranObject); +// } catch(Exception e) { +// if (logger.isError()) logger.error(guidLogPrefix + " 200 변환오류", e); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA020"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix +rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorMsg); +// } +// } +// +// public boolean isSync() +// { +// // SS || SA || AS +// if(EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) || +// EAIMessageKeys.SYNC_SVC.equals(this.psvItfTp) ) { +// return true; +// } +// else { +// return false; +// } +// } +// +// public boolean checkSnaProperty() +// { +// if(!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { +// return false; +// } +// if(SNAProperties.DATA_TYPE_DFS.equals(this.snaResponseDataType) ) { +// if (logger.isError()) { +// logger.error("================================================================"); +// logger.error(guidLogPrefix + "SNA DFS MESSAGE RETURNED ERROR MSG : "+ IConv.ebcdicToASCIIEX(this.resBytes)); +// logger.error("================================================================"); +// } +// return false; +// } +// else if(SNAProperties.DATA_TYPE_TIMEOUT.equals(this.snaResponseDataType) ) { +// if (logger.isError()) { +// logger.error("================================================================"); +// logger.error(guidLogPrefix + "SNA TIMEOUT ERROR MSG : "+new String(this.resBytes)); +// logger.error("================================================================"); +// } +// return false; +// } +// else if(SNAProperties.DATA_TYPE_ERROR.equals(this.snaResponseDataType) ) { +// if (logger.isError()) { +// logger.error("================================================================"); +// logger.error(guidLogPrefix + " SNA ERROR MESSAGE RETURNED, ERROR MSG : "+new String(this.resBytes)); +// logger.error("================================================================"); +// } +// return false; +// } +// else { +// return true; +// } +// } +// +// public void printCallError(Exception e) throws Exception +// { +// //int retryRemains = this.context.getExceptionInfo().getRetriesRemaining(); +// //int retryCnt = this.context.getExceptionInfo().getRetryCount(); +// //if (logger.isWarn()) logger.warn(guidLogPrefix + " UUID["+this.reqEaiMsg.getSvcOgNo()+"] Retry SNA NON-Respose Call - ["+retryRemains+"/"+retryCnt+"]"); +// this.resBytes = new byte[0]; +// /* +// if(retryRemains == 0 && this.adapterName != null) { +// AdapterManager manager = AdapterManager.getInstance(); +// AdapterVO vo = manager.getAdapterVO(this.adapterGroupName, this.adapterName); +// vo.setStatus(false); +// } +// */ +// } +// +// public boolean isSuccessReturn() +// { +// try { +// // 2008.01.07 한진호대리 요청 +// // 표준헤더의 출력메시지 정보의 출력데이터 유형구분코드가 '02' 이고 +// // 오류변환이 있는 경우에 오류변환을 수행하도록 한다 +// KBMessage kbmsg = this.resEaiMsg.getKbMsg(); +// if(kbmsg.getKBCommon().getOutptDPtrnDstcd() != null +// && KBMessageKeys.OUTPTDPTRNDSTCD_ERR.equals(kbmsg.getKBCommon().getOutptDPtrnDstcd()) +// && EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvEn()) +// ) { +// if (logger.isInfo()) { +// logger.info(guidLogPrefix + " KB 표준헤더의 출력메시지 정보의 출력데이터 유형구분코드["+kbmsg.getKBCommon().getOutptDPtrnDstcd()+"]가 오류출력"); +// } +// this.isSuccess = false; +// } +// else { +// this.isSuccess = MessageKeyExtractor.isSuccessMessage(this.adapterGroupName, this.resBytes); +// } +// } catch(Exception e) { +// this.isSuccess = false; +// } +// +// return this.isSuccess; +// } +// +// public void setRcvLogInfo() throws Exception +// { +// //this.logPssSno = 300; +// this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); +// +// this.prop = new Properties(); +// if(this.isSuccess) { +// prop.setProperty(Keys.ERROR_MESSAGE, Keys.FALSE); +// } +// else { +// prop.setProperty(Keys.ERROR_MESSAGE, Keys.TRUE); +// } +// Object[] objs = new Object[1]; +// +// if(this.resBytes != null) { +// objs[0] = this.resBytes; +// +// //---------------------------------------------------------------- +// // 2009.07.13 강길수차장 +// // 300 로그시에 표준전문을 파싱하고 +// // 로그 업무데이터는 KB표준을 포함한 데이터를 남기도록 수정 +// //---------------------------------------------------------------- +// try { +// // KESA SEQ를 복원한다. +// String kesaSeq = this.reqEaiMsg.getKbMsg().getKesaSeq(); +// +// //KBMessage resKbmessage = KBMessageUtil.convert(this.resBytes, true); +// KBMessageParser parser = KBMessageParserFactory.createPaserFactory(KBMessageParserType.EBC.toString()); +// +// if(parser == null) { +// throw new Exception("Parser not found - " +KBMessageParserType.EBC.toString()); +// } +// KBMessage resKbmessage = parser.convert(this.resBytes); +// +// resKbmessage.setKesaSeq(kesaSeq); +// +// this.resEaiMsg.setKbMsg(resKbmessage); +// } +// catch(Exception e) { +// if (logger.isWarn()) { +// logger.warn(guidLogPrefix + " invalid Response KBMesage Length["+this.resBytes.length+"<="+KBMessageKeys.KBMESSAGE_HEADER_LEN_ZZ_LENGTH+"]"); +// logger.warn(new String(this.resBytes)); +// } +// } +// //---------------------------------------------------------------- +// } +// this.resEaiMsg.setBizMsg(objs); +// } +// +// public void transformErrorToSource() throws Exception +// { +// this.resEaiMsg.setRspErrCd(EAIMessageKeys.BWK_ERRMSG_CODE); +// +// // 2020.02.07 업무데이터가 Empty 이면 변환을 Skip한다. +//// if(MessageUtil.isBizDataEmpty(this.resBytes)) { +//// if (logger.isInfo()) logger.info(guidLogPrefix + "Error Response Message is EMPTY, Skip Transform."); +//// this.isTgtTran = false; +//// } +//// else +// if(EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvEn()) ) { +// this.isTgtTran = true; +// } +// else { +// this.isTgtTran = false; +// //-------------------------------------------------- +// // 2009.06.21 정길영 차장 요청사항 +// // 오류응답인 경우 에러변환이 없는 경우 에러로 처리함 +// //-------------------------------------------------- +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// if (logger.isError()) { +// logger.error(guidLogPrefix + " 오류응답변환 미등록 EAI서비스코드["+msgArgs[0]+"]"); +// } +// +// String rspErrorCode = "RECEAIOSA030"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, "오류응답변환 미등록 ", msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix +rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// //--------------------------------------------------- +// } +// +// this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvMsgID(); +// this.resEaiMsg.setRspnsChngMsgType(EAIMessageKeys.RSPNSCHNGMSGTYPE_ERR); +// } +// +// public void transformToSource() throws Exception +// { +// if(MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { +// this.resEaiMsg.setRspErrCd(EAIMessageKeys.EAI_SUCCESS_CODE); +// } +// +// // 2020.02.07 업무데이터가 Empty 이면 변환을 Skip한다. +//// if(MessageUtil.isBizDataEmpty(this.resBytes)) { +//// if (logger.isInfo()) logger.info(guidLogPrefix + "Response Message is EMPTY, Skip Transform."); +//// this.isTgtTran = false; +//// } +//// else +// if(EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getBsRspCnvEn()) ) { +// this.isTgtTran = true; +// this.resEaiMsg.setRspnsChngMsgType(EAIMessageKeys.RSPNSCHNGMSGTYPE_RES); +// } +// else { +// this.isTgtTran = false; +// } +// +// this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID(); +// } +// +// public boolean isSyncAsyncPattern() +// { +// if(!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) ) { +// return false; +// } +// else if(EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { +// return true; +// } +// else { +// return false; +// } +// } +// +// +// public void setTopicResult() throws Exception +// { +// try { +// if (logger.isWarn()) logger.warn(guidLogPrefix + "future.value S"); +// this.jmsRespObject = future.value(this.timeout); +// if (logger.isWarn()) logger.warn(guidLogPrefix + "future.value E"); +// if(this.jmsRespObject == null) { +// throw new Exception("RECEAIOSA010"); +// } +// KBMessage kbmessage = this.resEaiMsg.getKbMsg(); +// kbmessage.getKBHeader().setTelgmDmndDstcd(KBMessageKeys.TELGMDMNDDSTCD_RECV); +// kbmessage.getKBCommon().setChannelCommonLen("0000"); +// kbmessage.getKBCommon().setInptMdiaPartlLen("0000"); +// } catch(Exception e) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA010"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg, e); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new RuntimeException(rspErrorCode); +// } finally { +// this.jmsRespAction.doEnd(); +// } +// +// if(this.jmsRespObject == null) { +// this.resBytes = new byte[0]; +// } +// else if(this.jmsRespObject instanceof EAIMessage) { +// EAIMessage topicEaiMsg = (EAIMessage)this.jmsRespObject; +// this.resBytes = (byte[])topicEaiMsg.getBizMsg()[0]; +// } +// else if(this.jmsRespObject instanceof byte[]) { +// this.resBytes = (byte[])this.jmsRespObject; +// } +// else { +// this.resBytes = new byte[0]; +// } +// +// } +// +// public boolean isSNASync() +// { +// if(EAIMessageKeys.SYNC_SVC.equals(this.psvItfTp) ) { +// return true; +// } +// else { +// return false; +// } +// } +// +// +// public void setResMsg() throws Exception +// { +// if(EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getCnvEn()) ) { +// if(logger.isInfo()) { +// logger.info(guidLogPrefix + " : 응답변환이 없으나, 통변환처리함 (ebcdicToASCII)"); +// } +// Object[] objs = new Object[1]; +// byte[] ascBytes = IConv.ebcdicToASCII(this.resBytes).getBytes(); +// objs[0] = ascBytes; +// this.resEaiMsg.setBizMsg(objs); +// } +// else { +// if(logger.isInfo()) { +// logger.info(guidLogPrefix + " : 응답변환이 없음"); +// } +// } +// +// } +// +// public void checkResultMessage() throws Exception +// { +// this.snaResponseDataType = snaProp.getProperty(SNAProperties.DATA_TYPE); +// +// // 2010.01.18 응답메시지의 수동시스템서비스구분명에 LU정보를 저장 +// this.resEaiMsg.getCurrentSvcMsg().setPsvSysSvcCd(snaProp.getProperty(SNAProperties.LU_NAME)); +// +// if (logger.isDebug()) { +// logger.debug("======================================================================" ); +// logger.debug(guidLogPrefix + " >> SNA CALL RESPONSE Property "); // UUID +// logger.debug(">> TRAN_KEY ["+snaProp.getProperty(SNAProperties.TRAN_KEY) +"]" ); // UUID +// logger.debug(">> ADAPTER_GRP_NAME ["+snaProp.getProperty(SNAProperties.ADAPTER_GRP_NAME) +"]" ); // ADAPTER_GRP_NAME +// logger.debug(">> ADAPTER_NAME ["+snaProp.getProperty(SNAProperties.ADAPTER_NAME) +"]" ); // ADAPTER_NAME +// logger.debug(">> LU_NAME ["+snaProp.getProperty(SNAProperties.LU_NAME) +"]" ); // LU_NAME +// logger.debug(">> TRAN_MODE ["+snaProp.getProperty(SNAProperties.TRAN_MODE) +"]" ); // TRAN_MODE +// logger.debug(">> DATA_TYPE ["+ this.snaResponseDataType +"]" ); // DATA_TYPE +// logger.debug("======================================================================" ); +// } +// if(this.reqEaiMsg.getSvrLogLvl() == 2 ) { +// if (logger.isDebug()) { +// logger.debug("--------------------------------------------------------------"); +// logger.debug(guidLogPrefix + " SYNC - SNA RESPONSE EBCDIC MESSAGE "); +// logger.debug("--------------------------------------------------------------"); +//// EbcdicDumpUtil.printEbcdicDump(this.resBytes); +// if (this.resBytes == null) { +// logger.debug(guidLogPrefix + " resBytes is NULL"); +// } +// else { +// try { +// String[] str = EbcdicDumpUtil.makeEbcdicDumpFormat(this.resBytes); +// for(int i=0;i> SNA CALL RESPONSE Property" ); // UUID +// logger.debug(">> TRAN_KEY ["+snaProp.getProperty(SNAProperties.TRAN_KEY) +"]" ); // UUID +// logger.debug(">> ADAPTER_GRP_NAME ["+snaProp.getProperty(SNAProperties.ADAPTER_GRP_NAME) +"]" ); // ADAPTER_GRP_NAME +// logger.debug(">> ADAPTER_NAME ["+snaProp.getProperty(SNAProperties.ADAPTER_NAME) +"]" ); // ADAPTER_NAME +// logger.debug(">> LU_NAME ["+snaProp.getProperty(SNAProperties.LU_NAME) +"]" ); // LU_NAME +// logger.debug(">> TRAN_MODE ["+snaProp.getProperty(SNAProperties.TRAN_MODE) +"]" ); // TRAN_MODE +// logger.debug(">> DATA_TYPE ["+ this.snaResponseDataType +"]" ); // DATA_TYPE +// logger.debug("======================================================================" ); +// } +// +// if(!SNAProperties.DATA_TYPE_SEND_OK.equals(this.snaResponseDataType)) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA002"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg + ",SNA ResponseData : " +this.snaResponseDataType); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// } +// } +// +// this.reqEaiMsg.getCurrentSvcMsg().setPsvSysSvcCd(snaProp.getProperty(SNAProperties.LU_NAME)); +// +// if( EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) && +// EAIMessageKeys.ASYNC_SVC.equals(this.psvItfTp)) { +// // 2010.01.18 Adapter 호출 후에 로그를 남기도록 한다. 정길영 차장 요청 +// try { +// if (logger.isInfo()) { +// logger.info(guidLogPrefix + " EAI 서비스코드[" + this.reqEaiMsg.getEAISvcCd() +// + "] AA 거래로그 LU["+this.reqEaiMsg.getCurrentSvcMsg().getPsvSysSvcCd()+"]"); +// } +// +// // SNA 비동기 로그에 대한 실제 처리시간 저장시 사용 +//// Properties logProp = new Properties(); +//// logProp.setProperty(EAIMessageKeys.REAL_PRCSS_TIME, "" + this.realPrcssTime); +//// LogSender.send(this.logPssSno, this.reqEaiMsg, logProp); +// +// LogSender.send(this.logPssSno, this.reqEaiMsg, this.prop); +// } catch(Exception e) { +// if (logger.isWarn()) logger.warn(guidLogPrefix + " EAI 서비스코드[" + this.reqEaiMsg.getEAISvcCd() + "] AA 거래로그 중 오류발생"); +// } +// } +// } +// +// +// public boolean isTgtTranCall() +// { +// return this.isTgtTran; +// } +// +// +// public void setConvertedMsg() throws Exception +// { +// Object[] objs = new Object[1]; +// objs[0] = this.tgtTranObject; +// this.resEaiMsg.setBizMsg(objs); +// } +// +// +// +// public boolean isAsyncAsyncPattern() +// { +// KBMessage kbmessage = this.reqEaiMsg.getKbMsg(); +// String telgmDmndDstcd = kbmessage.getKBHeader().getTelgmDmndDstcd(); +// +// if(!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) ) { +// return false; +// } +// /* +// else if(EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) +// && EAIKeys.TR_REQ.equals(this.reqEaiMsg.getKesaMsg().getCTranClassify()) +// && (this.reqEaiMsg.getCurrentSvcMsg().getTmoVl() > 0)) { +// */ +// else if(EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) +// && KBMessageKeys.TELGMDMNDDSTCD_SEND.equals(telgmDmndDstcd) +// && (this.reqEaiMsg.getCurrentSvcMsg().getTmoVl() > 0)) { +// //------------------------------------------------- +// // Inbound Adapter 의 메시지타입이 ASCII, XML일 경우에만 +// // TIMER에 등록하도록 한다 - 2005.10.27 +// //------------------------------------------------- +// +// if( MessageType.ASC.equals(this.inAdapterMsgType) +// || MessageType.XML.equals(inAdapterMsgType) ) { +// return true; +// } +// else { +// return false; +// } +// } +// else { +// return false; +// } +// } +// +// +// public void setTimerInfo() throws Exception +// { +//// timerInfoVO = new TimerInfoVO(); +//// //업무구분코드 +//// //timerInfoVO.setBwkClsCd(this.reqEaiMsg.getBwkCls()); +//// //업무데이타 : 전문타입으로 ASCII String : 기동의 전문 Msg +//// if(this.orgMessage instanceof byte[]) { +//// timerInfoVO.setBwkDataTxt(new String((byte[])this.orgMessage)); +//// } +//// //요청 메시지 처리시간 = 메시지 처리 시간 : Send시의 시각 +//// //timerInfoVO.setClmMsgSndTm("2005010101010100"); +//// //메시지 처리 시간(전문의 거래일자 필드값) : Send시의 시각 +//// //timerInfoVO.setMsgPssTm("2005010101010100"); +//// //EAI Service Code +//// timerInfoVO.seteAISvcNm(this.reqEaiMsg.getEAISvcCd()); +//// +//// //KESA Message XML형태 : KESAMesage(XML) KESA-DATA 제외 +//// //timerInfoVO.setKesaMsgTxt(this.reqEaiMsg.getKesaMsg().toString("")); +//// // TODO : +//// timerInfoVO.setKesaMsgTxt(this.reqEaiMsg.getKbMsg().toXMLString("")); +//// +//// //메시지 추적필드내용 : EAI Header의 추적필드 +//// timerInfoVO.setMsgTrceColTxt(this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl()); +//// //타임아웃값 : EAI Header 값 +//// timerInfoVO.setTmoVl(this.reqEaiMsg.getCurrentSvcMsg().getTmoVl()); +//// // 표준메시지 사용여부 +//// timerInfoVO.setStndMsgUseYn(this.reqEaiMsg.getStdMsgUsgCls()); +// } +// +// public void init() throws Exception +// { +// // 복합거래의 보상거래여부를 확인 +// this.svcPssTp = this.reqEaiMsg.getSvcPssTp(); +// this.svcPssSeq = this.reqEaiMsg.getSvcPssSeq(); +// +// if(this.callProp != null) { +// logger.debug(guidLogPrefix + " COMP_VALUE["+this.callProp.getProperty(EAIKeys.CALL_COMP_KEY)+"]"); +// if(EAIKeys.CALL_COMP_VALUE.equals(this.callProp.getProperty(EAIKeys.CALL_COMP_KEY)) ) { +// this.isComp = true; +// try { +// this.svcPssSeq = Integer.parseInt(this.callProp.getProperty(EAIKeys.CALL_COMP_SVC_SEQ)); +// logger.debug(guidLogPrefix + " CALL_COMP_SVC_SEQ["+ this.svcPssSeq +"]"); +// } catch(Exception e) { +// logger.warn(guidLogPrefix + " CALL_COMP_SVC_SEQ Get Error"); +// } +// } +// else { +// this.isComp = false; +// } +// } +// else { +// this.isComp = false; +// } +// +// KBMessage kbmessage = reqEaiMsg.getKbMsg(); +// String telgmDmndDstcd = kbmessage.getKBHeader().getTelgmDmndDstcd(); +// +// this.prop = null; +// this.adapterName = null; +// this.resEaiMsg = this.reqEaiMsg; +// +// //this.kesaSvcCd = this.reqEaiMsg.getKesaMsg().getCService(); +//// this.kesaSvcCd = this.reqEaiMsg.getKbMsg().getKBCommon().getTelgmRecvTranCd(); +// +// this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); +// +// //-------------------------------------------------------- +// // 2009.10.27 강길수차장 +// // HOST 전송시에 전문형식구분코드를 고정길이(1)로 강제 Setting +// //-------------------------------------------------------- +// kbmessage.getKBHeader().setTelgmFmatDstcd("1"); +// //-------------------------------------------------------- +// +// if(KBMessageKeys.TELGMDMNDDSTCD_RECV.equals(telgmDmndDstcd)) { +// // 응답인 경우 +// this.logPssSno = 400; +// // 카드분사이후는 불필요한 로직임 제거함 (2019.09.19) +// //------------------------------------------------------- +// // 2010.01.12 강길수 차장 요청 +// // 호스트 거래 중 Async 응답일 경우 +// // KB 표준전문의 SysIDName 의 두번째 필드가 +// // Alphabet 이면 은행시스템 +// // Numeric 이면 카드시스템 +// // 으로 SNA Adapter 를 변경 +// //------------------------------------------------------- +//// String sysIdName = kbmessage.getKBHeader().getSysidName(); +//// if(logger.isDebug()) { +//// logger.debug(guidLogPrefix + " SNA Adapter Remapping sysIdName["+sysIdName+"] adapterGroupName["+this.adapterGroupName+"]"); +//// } +//// +//// if(sysIdName != null && sysIdName.trim().length() > 2) { +//// char idx = sysIdName.charAt(1); +//// boolean isBank = true; +//// boolean isBankAdapter = true; +//// boolean isBankNameExist = true; +//// +//// if(idx >= 0x30 && idx <= 0x39) { +//// isBank = false; +//// } +//// +//// int cardWordIndex = adapterGroupName.indexOf("CARD"); +//// int bankWordIndex = adapterGroupName.indexOf("BANK"); +//// +//// if(cardWordIndex >= 0) { +//// isBankAdapter = false; +//// } +//// +//// if(bankWordIndex < 0) { +//// isBankNameExist = false; +//// } +//// +//// // CARD -> BANK +//// if(isBank && isBankAdapter==false) { +//// // Change name to BANK Adapter +//// if(adapterGroupName.startsWith("_KAO")) { +//// adapterGroupName = adapterGroupName.replaceAll("CARD", "BANK"); +//// } +//// else { +//// adapterGroupName = adapterGroupName.substring(0,adapterGroupName.indexOf("{")); +//// } +//// } +//// // BANK -> CARD +//// else if(isBank==false && isBankAdapter) { +//// // Change name to CARD Adapter +//// if(isBankNameExist) { +//// adapterGroupName = adapterGroupName.replaceAll("BANK", "CARD"); +//// } +//// else { +//// adapterGroupName = adapterGroupName + "{CARD}"; +//// } +//// } +//// } +// this.reqEaiMsg.getCurrentSvcMsg().setPsvSysItfTp(adapterGroupName); +// //------------------------------------------------------- +// +// } +// else { +// // 요청 인경우 +// //this.logPssSno = 200; +// this.logPssSno = TranLogUtil.getReqLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); +// } +// +// //--------------------------------------------------------------------------------------------- +// // Inboud Adapter mesageType +// //----------------------------------------------------------------------------------------------- +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); +// this.inAdapterMsgType = MessageType.ASC; +// +// if(inAdptGrpVO == null) { +// if(logger.isWarn()) { +// String tasAdapterName = ""; +// if(this.callProp != null) tasAdapterName = this.callProp.getProperty(Processor.TAS_ADAPTER_GROUP_NAME); +// logger.warn(guidLogPrefix + "Source Adapter is null, TAS Inbound = "+ tasAdapterName); +// } +// this.inAdapterMsgType = MessageType.ASC; +// } +// else { +// this.inAdapterMsgType = inAdptGrpVO.getMessageType(); +// } +// //----------------------------------------------------------------------------------------------- +// +// } +// +// public void getCallType() throws Exception +// { +// this.svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // Inbound 호출방식 +// this.psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 호출방식 +// +// Object[] bizObj = this.reqEaiMsg.getBizMsg(); +// if(bizObj != null && bizObj.length > 0) { +// this.orgMessage = bizObj[0]; +// /* +// if(bizObj[0] instanceof byte[]) { +// this.orgBytes = (byte[])bizObj[0]; +// } +// else if(bizObj[0] instanceof String) { +// this.orgBytes = ((String)bizObj[0]).getBytes(); +// } +// else { +// this.orgBytes = new byte[0]; +// if (logger.isError()) logger.error(guidLogPrefix + " Invalid Service Message Object Recevied..."); +// } +// */ +// } +// +// } +// +// public boolean isSourceTransform() +// { +// try { +// // 2009.03.20 강길수차장 요청사항 +// // 표준헤더의 출력메시지 정보의 출력데이터 유형구분코드가 '02' 이고 +// // 오류변환이 있는 경우에 오류변환을 수행하도록 한다 +// KBMessage kbmsg = this.reqEaiMsg.getKbMsg(); +// +// // 2020.02.07 업무데이터가 Empty 이면 변환을 Skip한다. +//// if(MessageUtil.isBizDataEmpty(this.orgMessage)) { +//// if (logger.isInfo()) logger.info(guidLogPrefix + "Request Message is EMPTY, Skip Transform."); +//// return false; +//// } +//// else +// if(kbmsg.getKBCommon().getOutptDPtrnDstcd() != null +// && KBMessageKeys.OUTPTDPTRNDSTCD_ERR.equals(kbmsg.getKBCommon().getOutptDPtrnDstcd()) +// && EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvEn()) +// ) { +// this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvMsgID(); +// if (logger.isDebug()) { +// logger.debug(guidLogPrefix + " 요청변환(에러응답변환) 출력데이터 유형구분코드["+kbmsg.getKBCommon().getOutptDPtrnDstcd()+"] - " + this.diURI); +// } +// return true; +// } +// else { +// if( EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getCnvEn()) ) { +// this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getCnvMsgID(); +// +// //---------------------------------------------------------------- +// // 2009.12.29 정길영 차장 요청 +// // AA 응답 거래일 경우 기동어댑터의 정상응답 에러응답여부를 확인하여 +// // 오류응답일 경우 오류변환을 수행 +// //---------------------------------------------------------------- +// if(EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) && +// EAIMessageKeys.ASYNC_SVC.equals(this.psvItfTp) && +// KBMessageKeys.TELGMDMNDDSTCD_RECV.equals(reqEaiMsg.getKbMsg().getKBHeader().getTelgmDmndDstcd()) +// && EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvEn()) ) { +// String inAdapter = this.reqEaiMsg.getSngSysItfTp(); +// boolean successFlag = MessageKeyExtractor.isSuccessMessage(inAdapter, this.orgMessage); +// +// if(!successFlag) { +// this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvMsgID(); +// if (logger.isDebug()) { +// logger.debug(guidLogPrefix + " 요청변환(에러응답변환) - " + this.diURI); +// } +// } +// } +// //---------------------------------------------------------------- +// +// if (logger.isDebug()) { +// logger.debug(guidLogPrefix + " 요청변환 - " + this.diURI); +// } +// return true; +// } +// else { +// return false; +// } +// } +// } catch(Exception e) { +// return false; +// } +// +// } +// +// public void setTgtTranObject() throws Exception +// { +// this.tgtTranObject = this.orgMessage; +// //this.tgtTranObject = IConv.asciiToEBCDIC(new String(this.orgBytes)); +// } +// +// public void checkErrorReturn(Exception e1) throws Exception +// { +// try { +// //JpdExceptionUtil.printException(this.context); +// if(this.resEaiMsg == null) this.resEaiMsg = this.reqEaiMsg; +// +// // 에러코드가 설정되지 않은 경우 +// // 공통에러코드를 설정한다. +// // 2009.09.11 +// if(MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.resEaiMsg.getEAISvcCd(); +// //[EAI 서비스코드:{1}] 송신전 메시지 처리 중 에러 +// String rspErrorCode = "RECEAIOCO000"; +// String rspErrorMsg = ExceptionUtil.make(e1, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg, e1); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// } +// +// //this.logPssSno = TranLogUtil.getReqLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); +// LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); +// +// if(EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) ) { +// this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); +// LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); +// } +// } catch(Exception e) { +// if (logger.isWarn()) { +// logger.warn(guidLogPrefix + " 송신전 오류에 대한 처리로직 수행 중 오류가 발생", e); +// } +// } +// } +// +// public boolean isRealCall() +// { +// if(this.callProp != null) { +// String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); +// if(mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { +// logger.warn(guidLogPrefix + " Warming Up Called"); +// return false; +// } +// else { +// return true; +// } +// } +// else { +// return true; +// } +// } +// +// +// public void getBizMessage() throws Exception +// { +// //------------------------------------------------------- +// // 응답메시지가 NULL아 아닌 경우 +// //------------------------------------------------------- +// if(this.resBytes != null) { +// //--------------------------------------------------- +// // 응답메시지가 KB 차세대표준일 경우 KBMessage 를 데이터에서 추출하고 EAIMessage에 설정 한다. +// // 업무데이터를 추출한다 +// // 2009.07.13 업무데이터만 추출하도록 수정 +// //--------------------------------------------------- +// try { +// KBMessage resKbMsg = this.resEaiMsg.getKbMsg(); +// //---------------------------------------------- +// // 2009.10.27 정길영 차장 +// // 단말대기요구여부 = '1' +// // 채널구분코드 = '05' 일 경우 Dummy 가 응답으로 수신되므로 +// // 데이터가 zero-space 이며 응답변환없이 헤더만 전달하도록 한다. +// //---------------------------------------------- +// // 2011.07.07 정길영차장 수정 +// // 단말대기요구여부 = '1' +// // 채널세부업무구분코드 = '19'(공항환전) 일 경우 Dummy 가 응답으로 수신되므로 +// // 데이터가 zero-space 이며 응답변환없이 헤더만 전달하도록 한다. +// //---------------------------------------------- +// // 2016.05.13 KSH +// // 단말대기요구여부 = '1' +// // 채널구분코드 = '06' 채널세부업무구분코드 = '93'(퇴직연금) 일 경우 Dummy 가 응답으로 수신되므로 +// // 데이터가 zedo-space 이며 응답변환없이 헤더만 전달하도록 한다. +// //---------------------------------------------- +// if("1".equals(resKbMsg.getKBCommon().getTermlWaitRqstYn()) +// && "05".equals(resKbMsg.getKBCommon().getChnlDstcd()) || +// "1".equals(resKbMsg.getKBCommon().getTermlWaitRqstYn()) +// && "19".equals(resKbMsg.getKBCommon().getChnlDBzwkDstcd()) || +// "1".equals(resKbMsg.getKBCommon().getTermlWaitRqstYn()) +// && "06".equals(resKbMsg.getKBCommon().getChnlDstcd()) +// && "93".equals(resKbMsg.getKBCommon().getChnlDBzwkDstcd())) { +// if(logger.isInfo()) { +// logger.info(guidLogPrefix + " CICS DUMMY Response EAISvcName[" + +// this.resEaiMsg.getEAISvcCd() + "] UUID[" + +// this.resEaiMsg.getSvcOgNo() + "]" ); +// } +// this.resBytes = new byte[0]; +// this.resEaiMsg.getCurrentSvcMsg().setBsRspCnvEn("0"); +// this.resEaiMsg.getCurrentSvcMsg().setErrRspCnvEn("0"); +// } +// else { +// //this.resBytes = KBMessageUtil.getBytesDataValue(this.resEaiMsg.getKbMsg(), this.resBytes); +// //TODO 확인 필수....... +// KBMessageParser parser = KBMessageParserFactory.createPaserFactory(KBMessageParserType.EBC.toString()); +// if(parser == null) { +// throw new Exception("Parser not found - " +KBMessageParserType.EBC.toString()); +// } +// this.resBytes = parser.getDataValue(this.resBytes, false); +// } +// //---------------------------------------------- +// +// Object[] objs = new Object[1]; +// +// if(this.resBytes != null) { +// objs[0] = this.resBytes; +// } +// this.resEaiMsg.setBizMsg(objs); +// } +// catch(Exception e) { +// if (logger.isWarn()) { +// logger.warn(guidLogPrefix + " invalid Response KBMesage Length["+this.resBytes.length+"<="+KBMessageKeys.KBMESSAGE_HEADER_LEN_ZZ_LENGTH+"]"); +// logger.warn(new String(this.resBytes)); +// } +// } +// } +// } +// +// public void getTopicProperty() throws Exception +// { +// PropManager propManager = PropManager.getInstance(); +// +// this.topicConFactory = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC_CONNECTION_FACTORY); +// this.topicName = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC); +// this.timeout = (this.reqEaiMsg.getCurrentSvcMsg().getTmoVl()+ 3)* 1000; //180 * 1000; +// this.tracekey = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); +// +// //------------------------------------------------------ +// // JMS TOPIC Subscriber Init +// //------------------------------------------------------ +// if (ContainerUtil.get() == ContainerUtil.TOMCAT) { +// this.future = new Future(); +// try { +// ResponseMap.getInstance().put(this.tracekey, future); +// } catch(Exception e) { +// logger.error(guidLogPrefix + "Cannot start the Cache Response Future. - "+e.getMessage(), e); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA060"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorMsg); +// } +// } +// else { +// jmsRespAction = new com.eactive.eai.common.worker.JMSListenerAction(this.topicConFactory, this.topicName, this.timeout); +// jmsRespAction.doInit(this.tracekey); +// this.future = new Future(); +// try { +// jmsRespAction.doStart(future.getSlot()); +// } catch(Exception e) { +// logger.error(guidLogPrefix + "Cannot start the JMSListenerAction. - "+e.getMessage(), e); +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA060"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorMsg); +// } +// } +// } +// +// public void executeTimeout() throws Exception +// { +// this.jmsRespObject = new byte[0]; +// +// } +// +// public void createStandardMsg() throws Exception { +// +// AdapterManager adapterManager = AdapterManager.getInstance(); +// AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); +// if(adptGrpVO != null) { +// this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); +// } +// +// byte[] byteMsg = (byte[])this.tgtTranObject; +// //-------------------------------------------- +// // KB 표준전문일 경우 SNA 거래시 CAP을 붙이지 않는다 +// // KB 표준메시지 공통부가 CAP을 대신한다. +// //-------------------------------------------- +// // KBMessage & DATA +// KBMessage kbmessage = this.reqEaiMsg.getKbMsg(); +// this.reqBytes = kbmessage.toFixedEbcdicBytes(this.inAdapterMsgType, MessageType.EBC, byteMsg); +// //-------------------------------------------- +// +// if(this.reqEaiMsg.getSvrLogLvl() == 2 ) { +// if (logger.isDebug()) { +// logger.debug("--------------------------------------------------------------"); +// logger.debug(guidLogPrefix + " SNA SEND EBCDIC Message"); +// logger.debug("--------------------------------------------------------------"); +// if (this.reqBytes == null) { +// logger.debug(guidLogPrefix + " reqBytes is NULL"); +// } +// else { +// try { +// String[] str = EbcdicDumpUtil.makeEbcdicDumpFormat(this.reqBytes); +// for(int i=0;i 0) { +// snaProp.setProperty(SNAProperties.TRAN_TIMEOUT, new Integer(timeout).toString()); +// } +// } catch(Exception e) { +// if (logger.isWarn()) logger.warn(guidLogPrefix + " EAI 서비스코드["+this.reqEaiMsg.getEAISvcCd()+"] Invalid TIMEOUT Value ["+this.reqEaiMsg.getCurrentSvcMsg().getTmoVl()+"]"); +// } +// } +// +// public void setSNAErrorMessage() throws Exception { +// //this.logPssSno = 300; +// this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); +// +// Object[] objs = new Object[1]; +// +// if(!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd()) ) { +// objs[0] = (this.resBytes); +// } +// +// if(SNAProperties.DATA_TYPE_ERROR.equals(this.snaResponseDataType) ) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getSvcOgNo(); +// String rspErrorCode = "RECEAIOSA888"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + +// (this.resBytes == null ? "" : (", ERROR-" + new String(this.resBytes)) ); +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// objs[0] = (this.resBytes); +// } +// else if(SNAProperties.DATA_TYPE_TIMEOUT.equals(this.snaResponseDataType) ) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getSvcOgNo(); +// String rspErrorCode = "RECEAIOSA777"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + +// (this.resBytes == null ? "" : (", TIMEOUT-" + new String(this.resBytes)) ) ; +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// objs[0] = (IConv.ebcdicToASCII(this.resBytes).getBytes()); +// } +// else if(SNAProperties.DATA_TYPE_DFS.equals(this.snaResponseDataType) ) { +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getSvcOgNo(); +// String rspErrorCode = "RECEAIOSA999"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs) + +// (this.resBytes == null ? "" : (", DFS-" + IConv.ebcdicToASCII(this.resBytes)) ); +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// objs[0] = (IConv.ebcdicToASCII(this.resBytes).getBytes()); +// } +// +// this.resEaiMsg.setBizMsg(objs); +// +// } +// +// public boolean isRequest() { +// //---------------------------------------------- +// // 2008.05.29 - FILE 변경에 따른 BUG +// // AA 응답거래일 경우 +// // 에러 로그를 남기지 않는다. +// // AA 응답거래일 경우에는 FlowControl에서 ExceptionHandler에 의해 +// // 900 ERROR 로그를 남긴다. +// //---------------------------------------------- +// KBMessage kbmessage = reqEaiMsg.getKbMsg(); +// String telgmDmndDstcd = kbmessage.getKBHeader().getTelgmDmndDstcd(); +// // AA && RES +// if(EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) && +// EAIMessageKeys.ASYNC_SVC.equals(this.psvItfTp) && +// KBMessageKeys.TELGMDMNDDSTCD_RECV.equals(telgmDmndDstcd) +// ) { +// return false; +// } +// else { +// return true; +// } +// } +// +// public boolean isHeaderControl() { +// if(logger.isDebug()) { +// logger.debug(guidLogPrefix + " Header Control 여부 : [" + this.reqEaiMsg.getCurrentSvcMsg().getSupplDelYn() +"]"); +// logger.debug(guidLogPrefix + " Header Control Type : [" + this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd() +"]"); +// logger.debug(guidLogPrefix + " header Action Name : [" + this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName() +"]"); +// } +// +// String hdrCtrlDstcd = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); +// if (HeaderActionKeys.SUPPORT_Y.equals(StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getSupplDelYn()) ) +// && (HeaderActionKeys.DELETE_ADD_HEADER.equals(hdrCtrlDstcd) || HeaderActionKeys.ADD_DELETE_HEADER.equals(hdrCtrlDstcd) ) ){ +// return true; +// }else{ +// return false; +// } +// } +// +// public void performSend() throws Exception { +// try{ +// String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); +// String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()) ; +// +// if(logger.isDebug()) { +// logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); +// logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName +"]"); +// logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_SEND +"]"); +// logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType +"]"); +// } +// +// HeaderAction action = HeaderActionFactory.createAction(headerActionName); +// +// if(this.orgMessage instanceof byte[]) { +// this.orgData = new byte[((byte[])this.orgMessage).length]; +// System.arraycopy(this.orgMessage, 0, this.orgData, 0, ((byte[])this.orgMessage).length ); +// +// this.orgMessage = action.excute(this.orgData ,(byte[])this.orgMessage, HeaderActionKeys.MESSAGE_SEND, headerContolType ); +// +// if(logger.isDebug()) { +// logger.debug(guidLogPrefix + " this.orgMessage"+new String((byte[])this.orgMessage)); +// } +// +// }else{ +// if(logger.isWarn()) { +// logger.warn(guidLogPrefix + " byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.orgMessage); +// } +// +// } +// if(logger.isDebug()) { +// logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); +// } +// }catch(Exception e){ +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA030"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorMsg); +// } +// } +// +// public void performRecv() throws Exception { +// try{ +// String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); +// String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()) ; +// +// if(logger.isDebug()) { +// logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); +// logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName +"]"); +// logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_RECV +"]"); +// logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType +"]"); +// } +// +// HeaderAction action = HeaderActionFactory.createAction(headerActionName); +// Object bizObj[] = this.resEaiMsg.getBizMsg(); +// +// if(bizObj != null && bizObj.length > 0) { +// this.tgtTranObject = bizObj[0]; +// } +// +// +// if(this.tgtTranObject instanceof byte[]) { +// this.tgtTranObject = action.excute(this.orgData ,(byte[])this.tgtTranObject, HeaderActionKeys.MESSAGE_RECV, headerContolType ); +// bizObj[0] = this.tgtTranObject; +// this.resEaiMsg.setBizMsg(bizObj); +// +// if(logger.isDebug()) { +// logger.debug(guidLogPrefix + " this.tgtTranObject"+new String((byte[])this.tgtTranObject)); +// } +// +// }else{ +// if(logger.isWarn()) { +// logger.warn(guidLogPrefix + " byte[] 만 허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); +// } +// +// } +// if(logger.isDebug()) { +// logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); +// } +// }catch(Exception e){ +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// String rspErrorCode = "RECEAIOSA030"; +// String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// throw new Exception(rspErrorMsg); +// } +// } +//} diff --git a/src/main/java/com/eactive/eai/outbound/DefaultProcess.java b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java new file mode 100644 index 0000000..691e07a --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/DefaultProcess.java @@ -0,0 +1,929 @@ +package com.eactive.eai.outbound; + +import java.nio.charset.Charset; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.handler.AdapterErrorMessageHandler; +import com.eactive.eai.adapter.handler.AdapterErrorMessageHandlerFactory; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.header.HeaderActionKeys; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.routing.Process; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.submessage.SubMessageManager; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageKeyExtractor; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.common.util.TranLogUtil; +import com.eactive.eai.common.util.UUIDGenerator; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.message.StandardItem; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.mapper.MessageMapper; +import com.eactive.eai.message.service.InterfaceMapper; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public abstract class DefaultProcess extends Process { + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + protected static Logger esbLogger = Logger.getLogger(Logger.LOGGER_ESBFW); + + protected String guidLogPrefix = this.getClass().getSimpleName() + "] "; + + protected static ThreadLocal local = new ThreadLocal(); // 경과시간 동기화를 위한 ThreadLocal + + protected int svrLogLevel; + + protected EAIMessage resEaiMsg; + + protected EAIMessage reqEaiMsg; + + protected Properties callProp; + + protected Object tgtTranObject; + + protected int logPssSno; + + protected String svcTsmtUsgTp; + protected String psvItfTp; + + protected Properties prop; + protected Properties outboundProp; + protected Properties tempProp; + + protected boolean isComp; + protected String svcPssTp; + protected int svcPssSeq; + + protected Object jmsRespObject; + + protected boolean isSuccess; + + protected String adapterGroupName; + protected String adapterName; + + protected Object reqObject; + protected Object resObject; + protected String inboundCharset; + protected String outboundCharset; + + protected String adptrMsgPtrnCd; // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 + + protected String diURI; + + protected boolean isTgtTran; + + protected com.eactive.eai.common.worker.Future future; + protected com.eactive.eai.common.worker.JMSListenerAction jmsRespAction; + + protected String inAdapterMsgType; // 송신어댑터 타입 + protected String adptrMsgType; // 추가 + + protected String topicName; + + protected String topicConFactory; + + protected int timeout; + + protected String tracekey; + + protected Object srcTranObject; + + protected byte[] orgData; + + public EAIMessage clientReturn() { + if (svrLogLevel >= 1) { + try { + long msgSndTm = System.currentTimeMillis(); + + Long threadData = (Long) local.get(); + long processTm = msgSndTm - threadData.longValue(); + if (esbLogger.isInfo()) + esbLogger.info( + guidLogPrefix + " End... - 경과시간 : " + processTm + "(ms) - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("clientReturn", e); + } + } + return resEaiMsg; + } + + public void callService(EAIMessage reqEaiMsg, Properties prop) { + if (reqEaiMsg == null) { + return; + } + + if (StringUtils.equals(reqEaiMsg.getFlwCntlRtnNm(), "PUBFC")) { + try { + this.reqEaiMsg = (EAIMessage) reqEaiMsg.clone(); + if (prop != null) { + this.callProp = (Properties) prop.clone(); + } + } catch (Exception e) { + logger.warn("callService-1", e); + } + } else { + this.reqEaiMsg = reqEaiMsg; + this.callProp = prop; + } + + svrLogLevel = this.reqEaiMsg.getSvrLogLvl(); + + guidLogPrefix = this.getClass().getSimpleName() + "] GUID[" + + reqEaiMsg.getMapper().getGuid(reqEaiMsg.getStandardMessage()) + "] UUID[" + + this.reqEaiMsg.getSvcOgNo() + "] "; + + if (svrLogLevel >= 1) { + try { + long msgRcvTm = System.currentTimeMillis(); + local.set(new Long(msgRcvTm)); + + if (esbLogger.isInfo()) + esbLogger.info(guidLogPrefix + " started... - EAI Server Log Level is INFO"); + } catch (Exception e) { + logger.warn("callService", e); + } + } + + try { + // IN,OUT adapter의 charset. + this.inboundCharset = prop.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN); + // Queue에서 호출될때 설정이 없음 + if (StringUtils.isBlank(this.inboundCharset)) { + this.inboundCharset = this.reqEaiMsg.getStandardMessage().getBizDataCharset(); + } + + String outboundAdapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + AdapterGroupVO outboundAdapterGvo = AdapterManager.getInstance() + .getAdapterGroupVO(outboundAdapterGroupName); + prop.setProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_OUT, + StringUtils.defaultIfBlank(outboundAdapterGvo.getMessageEncode(), Charset.defaultCharset().name())); + this.outboundCharset = prop.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_OUT); + flow(); + } catch (Exception e) { + logger.warn("flow", e); + } finally { + if (jmsRespAction != null) { + this.jmsRespAction.doEnd(); + } + } + } + + public void flow() throws Exception { + // WarmUp start + if (!isRealCall()) { + return; + } + // WarmUp end + + // 송신전 처리 start + try { + // 초기화 + init(); + + // 송신변환 + if (isSourceTransform()) { + // 수동메시지 변환 + transControlTransformSingleReq(); + } else { + // 메시지 설정 + setTgtTranObject(); + } + // Header컨트롤여부 + if (isHeaderControl()) { + performSend(); + } + // 송신전 메시지 설정 + setSendMsg(); + } catch (Exception e) { + // 오류처리 + checkErrorReturn(e); + return; + } + // 송신전 처리 end + + // Sync-Async 호출 start + try { + // 아웃바운드 Sync 호출 + if (isOutboundSync()) { + // 송신전로그 + logSenderCtrlSendReq(); + try { + // Sync 호출 + outboundCtrlCallService(); + } catch (Exception e1) { + printCallError(e1); + } + // 응답메시지확인 + checkResultMessage(); + + // Sync 에서 Wait 올경우 체크 + waitCheckForSync(); + } else { + // SA + if (isSyncAsyncPattern()) { + // 응답환경설정 + getTopicProperty(); + } else { + // 복원저장 + storeMessage(); + } + // 송신전 로그 + logSenderCtrlSendReq(); + try { + // Async 호출 + outboundCtrlCallServiceAsync(); + } catch (Exception e1) { + printCallError(e1); + } + // 송신결과확인 + checkSendResult(); + // SA + if (isSyncAsyncPattern()) { + try { + // SA응답메시지 설정 + setTopicResult(); + } catch (Exception e) { + // Timeout + executeTimeout(); + } + } + // AA : commented - Do nothing +// else if (isAsyncAsyncPattern()){ +// //TimerInfo 설정 +// setTimerInfo(); +// //timerInforInsert +// timerInfoControlTimerInfoInsert(); +// } + } + } catch (Exception e) { + performSendError(); + } + // Sync-Async 호출 end + + // 정상처리 확인 start + // 정상처리확인 + if (checkOutboundTransaction()) { + // 동기거래 + if (isSync()) { + // 응답로그값 설정 + setRcvLogInfoExtend(); + // 응답로그 + logSenderCtrlSendRes(); + // 업무응답메시지추출 + getBizMessage(); + // 업무 응답메시지 확인 + boolean successReturn = isSuccessReturn(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + " isSuccessReturn() >> [" + successReturn + "]"); + if (successReturn) { + // 정상메시지변환 + transformToSource(); + } else { + // 오류메시지변환 + transformErrorToSource(); + } + if (logger.isDebug()) + logger.debug(guidLogPrefix + " isTgtTranCall() >> [" + isTgtTranCall() + "]"); + // 응답변환 + if (isTgtTranCall()) { + // 응답메시지변환 + transControlTransformSingleRes(); + // 변환응답메시지설정 + setConvertedMsg(); + } else { + // 응답메시지설정 + setResMsg(); + } + transControlHeaderTrnsformSinglesRes(); + // Header컨트롤여부 + if (isHeaderControl()) { + performRecv(); + } + } else { + // 비동기 거래 + } + } else { + // sync 오류시 추가 +// if (isSync()) { +// } + + // default + // 요청거래 + if (isRequest()) { + // 오류메시지설정 + setOutboundErrorMessage(); + // 오류메시지로그 + logSenderCtrlSendError(); + } else { + // default + } + } + } + + protected void setRcvLogInfoExtend() throws Exception { + setRcvLogInfo(); + + // 비표준만 셋팅함 표준은 위 코드에서 셋팅함 + if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + + // GUID SET + mapper.nextGuidSeq(standardMessage); + String guid = mapper.getGuid(standardMessage); + String guidSeq = mapper.getGuidSeq(standardMessage); + mapper.setGuid(standardMessage, + guid + StringUtils.defaultString(StringUtils.leftPad(guidSeq, UUIDGenerator.GUID_SEQ_LENGTH, '0'))); + + // 시스템구분 +// stdmsg.setData("stdheader.Inter_chn", EAIServerManager.getInstance().getSystemGubun()); + mapper.setReqSysCode(standardMessage, EAIServerManager.getInstance().getSystemGubun()); + + // 수신시각 설정 +// stdmsg.setData("stdheader.recv_tm", DatetimeUtil.getCurrentTimeMillis()); + mapper.setRecvTime(standardMessage, DatetimeUtil.getCurrentTimeMillis()); + // 전문응답구분 +// stdmsg.setData("stdheader.return_gubun", STDMessage.SEND_RECV_CD_RECV); + mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV); + // 처리결과 + String procsRsltDvcd = mapper.getResponseType(standardMessage); + if (StringUtils.isBlank(procsRsltDvcd)) { + mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_N); + } + standardMessage.setBizData(this.resObject, this.outboundCharset); + + StandardMessageManager.getInstance().getMessageCoordinator().coordinateAfterRecvNonStdSyncResponse(standardMessage); + } + + // inbound adapter로 참조데이터 전달 + if (this.tempProp.get(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP) != null) { + this.callProp.put(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP, + this.tempProp.get(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP)); + } + } + + /** + * WarmUp 여부 + * + * @return + */ + public boolean isRealCall() { + if (this.callProp != null) { + String mode = this.callProp.getProperty(EAIKeys.CALL_MODE_KEY); + if (mode != null && EAIKeys.CALL_MODE_WARMUP.equals(mode)) { + logger.warn(guidLogPrefix + " Warming Up Called"); + return false; + } else { + return true; + } + } else { + return true; + } + } + + public void setTgtTranObject() throws Exception { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + // if(bizData != null && bizData.length() > 0) { + if (bizData != null) { + this.tgtTranObject = bizData; + } + } + + /** + * 헤더 추가삭제/삭제추가 여부 + * + * @return + */ + public boolean isHeaderControl() { + // supplDelYn = Y && (da || ad) + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header Control 여부 : [" + this.reqEaiMsg.getCurrentSvcMsg().getSupplDelYn() + + "]"); + logger.debug(guidLogPrefix + " Header Control Type : [" + + this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd() + "]"); + logger.debug(guidLogPrefix + " header Action Name : [" + + this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName() + "]"); + } + + String hdrCtrlDstcd = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + if (HeaderActionKeys.SUPPORT_Y.equals(StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getSupplDelYn())) + && (HeaderActionKeys.DELETE_ADD_HEADER.equals(hdrCtrlDstcd) + || HeaderActionKeys.ADD_DELETE_HEADER.equals(hdrCtrlDstcd))) { + return true; + } else { + return false; + } + } + + public void checkErrorReturn(Exception e1) throws Exception { + try { + if (this.resEaiMsg == null) + this.resEaiMsg = this.reqEaiMsg; + + // 에러코드가 설정되지 않은 경우 + // 공통에러코드를 설정한다. + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.resEaiMsg.getEAISvcCd(); + // [EAI 서비스코드:{1}] 송신전 메시지 처리 중 에러 + String rspErrorCode = "RECEAIOCO000"; + String rspErrorMsg = ExceptionUtil.make(e1, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e1); + this.resEaiMsg.setRspErr(rspErrorCode, rspErrorMsg); + } + + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + if (EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + // 요청시 에러 발생해서 응답 설정필요 + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + standardManager.getMessageCoordinator().coordinateInReturnObject(this.resEaiMsg.getStandardMessage()); + this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + } + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " 송신전 오류애 대한 처리로직 수행 중 오류가 발생"); + logger.warn(e.getMessage()); + } + } + } + + public boolean isOutboundSync() { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "수동인터페이스 통신유형[" + this.psvItfTp + "]"); + if (EAIMessageKeys.SYNC_SVC.equals(this.psvItfTp)) { + return true; + } else { + return false; + } + } + + public boolean isSyncAsyncPattern() { + if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + return false; + } else if (EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + return true; + } else { + return false; + } + } + + public void performSendError() throws Exception { + try { + if (this.resEaiMsg == null) + this.resEaiMsg = this.reqEaiMsg; + + if(EAIMessageKeys.ASYNC_SVC.equals(this.resEaiMsg.getCurrentSvcMsg().getPsvItfTp())){ + return ; + } + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + + if (EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + } + + } catch (Exception e) { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + "송신에러 처리로직 수행 중 오류가 발생"); + logger.warn(e.getMessage()); + } + } + } + + public void executeTimeout() throws Exception { + this.jmsRespObject = new byte[0]; + + } + + public boolean checkOutboundTransaction() { + if (!MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + return false; + } else { + return true; + } + } + + public boolean isSync() { + // SS || SA + if (EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) + || EAIMessageKeys.SYNC_SVC.equals(this.psvItfTp)) { + return true; + } else { + return false; + } + } + + public boolean isSuccessReturn() { + try { + // 표준헤더의 출력메시지 정보의 출력데이터 유형구분코드가 '02' 이고 + // 오류변환이 있는 경우에 오류변환을 수행하도록 한다 + + /** + * NexCore 는 오류일경우 업무데이터가 없음 응답에 N이 아닐경우 ERROR로 설정(오류변환주석처리) + */ + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + + String responseType = mapper.getResponseType(standardMessage); + if ((com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd) + ||com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) + && responseType != null + && !STDMessageKeys.RESPONSE_TYPE_CODE_N.equals(responseType) + // && + // EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvEn()) + ) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " 표준헤더의 출력메시지 정보의 출력데이터 유형구분코드[" + responseType + "]가 오류출력"); + } + this.isSuccess = false; + } else { + this.isSuccess = MessageKeyExtractor.isSuccessMessage(this.adapterGroupName, this.resObject); + // 비표준인 경우 출력 데이터 유형구분코드를 EAI가 설정한다. + if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + if (this.isSuccess) { + mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_N); + } else { + mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_E); + } + } + } + } catch (Exception e) { + this.isSuccess = false; + } + return this.isSuccess; + } + + public void logSenderCtrlSendError() throws Exception { + try { + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + } catch (Exception e) { + if (logger.isWarn()) + logger.warn(guidLogPrefix + " EAI 서비스코드[" + this.resEaiMsg.getEAISvcCd() + "] " + this.logPssSno + + " 거래로그 중 오류발생"); + } + } + + public void transformToSource() throws Exception { + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + this.resEaiMsg.setRspErrCd(EAIMessageKeys.EAI_SUCCESS_CODE); + } + + // 2020.02.07 업무데이터가 Empty 이면 변환을 Skip한다. +// if(MessageUtil.isBizDataEmpty(this.resBytes)) { +// if (logger.isInfo()) logger.info(guidLogPrefix + "Response Message is EMPTY, Skip Transform."); +// this.isTgtTran = false; +// } +// else + if (EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getBsRspCnvEn())) { + this.isTgtTran = true; + this.resEaiMsg.setRspnsChngMsgType(EAIMessageKeys.RSPNSCHNGMSGTYPE_RES); + } else { + this.isTgtTran = false; + } + + this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getBsRspCnvMsgID(); + } + + public void transformErrorToSource() throws Exception { + this.resEaiMsg.setRspErrCd(EAIMessageKeys.BWK_ERRMSG_CODE); + + // 2020.02.07 업무데이터가 Empty 이면 변환을 Skip한다. +// if(MessageUtil.isBizDataEmpty(this.resBytes)) { +// if (logger.isInfo()) logger.info(guidLogPrefix + "Error Response Message is EMPTY, Skip Transform."); +// this.isTgtTran = false; +// } +// else + if (EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvEn())) { + this.isTgtTran = true; + } else { + this.isTgtTran = false; + /** + * 20210608 NexCore 는 오류일경우 업무데이터가 없음 에러 변환이 없기 때문에 isTgtTran 로 설정하면 변환을 안탐 + */ + +// //-------------------------------------------------- +// // 오류응답인 경우 에러변환이 없는 경우 에러로 처리함 +// //-------------------------------------------------- +// String[] msgArgs = new String[1]; +// msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); +// if (logger.isError()) { +// logger.error(guidLogPrefix + " 오류응답변환 미등록 EAI서비스코드["+msgArgs[0]+"]"); +// } +// +// String rspErrorCode = "RECEAIOHP030"; +// String rspErrorMsg = ExceptionUtil.make(rspErrorCode, "오류응답변환 미등록 ", msgArgs); +// if (logger.isError()) logger.error(guidLogPrefix + rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); +// //--------------------------------------------------- + } + + this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvMsgID(); + this.resEaiMsg.setRspnsChngMsgType(EAIMessageKeys.RSPNSCHNGMSGTYPE_ERR); + } + + public void setResMsg() throws Exception { + StandardMessage resStandardMessage = this.resEaiMsg.getStandardMessage(); + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + String responseType = mapper.getResponseType(resStandardMessage); + if(!STDMessageKeys.RESPONSE_TYPE_CODE_N.equals(responseType)){ + String inboudnAdapterGroupName = this.callProp.getProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME); + String inboudnAdapterName = this.callProp.getProperty(HttpClientAdapterServiceKey.ADAPTER_NAME); + if(StringUtils.isBlank(inboudnAdapterGroupName) || StringUtils.isBlank(inboudnAdapterName)) { + return; + } + + AdapterGroupVO inboundAdapterGroupVO = AdapterManager.getInstance().getAdapterGroupVO(inboudnAdapterGroupName); + AdapterVO inboundAdapterVO = AdapterManager.getInstance().getAdapterVO(inboudnAdapterGroupName, inboudnAdapterName); + String errorResponseHandlerClass = AdapterPropManager.getInstance().getProperty(inboundAdapterVO.getPropGroupName(), "ERR_MSG_HANDLER"); + if(StringUtils.isBlank(errorResponseHandlerClass)) { + return; + } + + logger.info(inboudnAdapterName+", Handle Error Message Class-"+errorResponseHandlerClass); + + AdapterErrorMessageHandler adapterErrorMessageHandler = AdapterErrorMessageHandlerFactory.createHandler(errorResponseHandlerClass); + + Object responseObj = adapterErrorMessageHandler.generateNonStandardErrorResponseMessage(inboudnAdapterGroupName, inboudnAdapterName, this.callProp, this.tgtTranObject, resStandardMessage); + if(responseObj != null) { + resStandardMessage.setBizData(responseObj, inboundAdapterGroupVO.getMessageEncode()); + } + } + } + + public boolean isTgtTranCall() { + return this.isTgtTran; + } + + public void setConvertedMsg() throws Exception { + this.resEaiMsg.getStandardMessage().setBizData(this.tgtTranObject, this.inboundCharset); + } + + public boolean isSourceTransform() { + try { + // 표준헤더의 출력메시지 정보의 출력데이터 유형구분코드가 '02' 이고 + // 오류변환이 있는 경우에 오류변환을 수행하도록 한다 + InterfaceMapper mapper = this.reqEaiMsg.getMapper(); + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + + String responseType = mapper.getResponseType(standardMessage); + String returnType = mapper.getSendRecvDivision(standardMessage); + + // 2025.03.28 responseType값이 없을때 return값이 " "로 설정되어 if문에서 true가 되어 에러응답변환 값으로 설정됨 + if (responseType != null && !"".equals(responseType.trim()) && !STDMessageKeys.RESPONSE_TYPE_CODE_N.equals(responseType) + && EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvEn())) { + this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvMsgID(); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " 요청변환(에러응답변환) 출력데이터 유형구분코드[" + responseType + "] - " + this.diURI); + } + return true; + } else { + if (EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getCnvEn())) { + this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getCnvMsgID(); + // ---------------------------------------------------------------- + // AA 응답 거래일 경우 기동어댑터의 정상응답 에러응답여부를 확인하여 + // 오류응답일 경우 오류변환을 수행 + // ---------------------------------------------------------------- + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) + && EAIMessageKeys.ASYNC_SVC.equals(this.psvItfTp) + && STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType) + && EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvEn())) { + String inAdapter = this.reqEaiMsg.getSngSysItfTp(); + boolean successFlag = MessageKeyExtractor.isSuccessMessage(inAdapter, + standardMessage.getBizData()); + + if (!successFlag) { + this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getErrRspCnvMsgID(); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " 요청변환(에러응답변환) - " + this.diURI); + } + } + } + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " 요청변환 - " + this.diURI); + } + return true; + } else { + return false; + } + } + } catch (Exception e) { + return false; + } + } + + public void setOutboundErrorMessage() throws Exception { + this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + + InterfaceMapper mapper = this.resEaiMsg.getMapper(); + StandardMessage standardMessage = this.resEaiMsg.getStandardMessage(); + + // 에러에 대한 응답메시지 + if(this.tempProp.get(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP) instanceof Map) { + Map map = (Map) this.tempProp.get(HttpAdapterServiceKey.OUTBOUND_PROPERTY_MAP); + this.resObject = map.get(HttpAdapterServiceKey.OUTBOUND_RESPONSE_MESSAGE); + } + standardMessage.setBizData(this.resObject, this.inboundCharset); + try { + mapper.nextGuidSeq(standardMessage); + mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV); + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + standardManager.getMessageCoordinator().coordinateSetStandardMessageError(standardMessage, mapper, + this.resEaiMsg.getRspErrCd(), this.resEaiMsg.getRspErrMsg()); + } catch (Exception e) { + logger.error(e.getMessage()); + } + } + + public boolean isRequest() { + // ---------------------------------------------- + // FILE 변경에 따른 BUG + // AA 응답거래일 경우 + // 에러 로그를 남기지 않는다. + // AA 응답거래일 경우에는 FlowControl에서 ExceptionHandler에 의해 + // 900 ERROR 로그를 남긴다. + // ---------------------------------------------- + InterfaceMapper mapper = reqEaiMsg.getMapper(); + StandardMessage standardMessage = reqEaiMsg.getStandardMessage(); + String returnType = mapper.getSendRecvDivision(standardMessage); + // AA && RES + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) + && EAIMessageKeys.ASYNC_SVC.equals(this.psvItfTp) + && STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + return false; + } else { + return true; + } + } + + protected int getTimeoutCodeToValue() throws Exception { +// PropManager propManager = PropManager.getInstance(); +// /** +// * TIMEOUT CODE 로 변경됨 +// * TIMEOUT_CODE : S : 30 +// * TIMEOUT_CODE : M : 90 +// * TIMEOUT_CODE : L : 180 +// * TIMEOUT_CODE : X : 300 +// * TIMEOUT_CODE : DEFAULT : S +// */ +//// this.timeout = this.reqEaiMsg.getCurrentSvcMsg().getTmoVl() * 1000; //180 * 1000; +// String timeoutCode = this.reqEaiMsg.getCurrentSvcMsg().getTimeoutCode(); //S/M/L/X +// if (StringUtils.isEmpty(timeoutCode)){ +// timeoutCode = propManager.getProperty("TIMEOUT_CODE", "DEFAULT" ); +// } +// String timeoutCodeValue = propManager.getProperty("TIMEOUT_CODE", timeoutCode ); //실제 값 +// +// int iTimeoutValue = 30; +// try{ +// iTimeoutValue = Integer.parseInt(timeoutCodeValue); +// }catch(Exception e){ +// +// } +// /** +// * TODO 20210826 타임아웃값 조정 +// * MCI 일경우 전체 타임아웃에서 5초 추가 +// * EAI 일경우 전체 타임아웃값 +// * FEP 일경우 전체 타임아웃은 무의미 +// */ +// if (EAIServerManager.getInstance().isMCI()){ +// iTimeoutValue += 5; +// } +// +// return iTimeoutValue; + // return this.reqEaiMsg.getCurrentSvcMsg().getTmoVl() * 1000; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + return standardManager.getMessageCoordinator().coordinateForTimeoutCodeToValue(this.reqEaiMsg); +// return this.reqEaiMsg.getCurrentSvcMsg().getTmoVl(); + } + + public abstract void logSenderCtrlSendReq() throws Exception; + + public abstract void logSenderCtrlSendRes() throws Exception; + + public abstract void outboundCtrlCallService() throws Exception; + + public abstract void outboundCtrlCallServiceAsync() throws Exception; + + public abstract void transControlTransformSingleRes() throws Exception; + + public abstract void transControlTransformSingleReq() throws Exception; + + public abstract void printCallError(Exception e1) throws Exception; + + public abstract void setRcvLogInfo() throws Exception; + + public abstract void setTopicResult() throws Exception; + + public abstract void checkResultMessage() throws Exception; + + public abstract void checkSendResult() throws Exception; + + public abstract void init() throws Exception; + + public abstract void setSendMsg() throws Exception; + + public abstract void getTopicProperty() throws Exception; + + public abstract void performSend() throws Exception; + + public abstract void performRecv() throws Exception; + + public abstract void storeMessage() throws Exception; + + public abstract void getBizMessage() throws Exception; + + public abstract void waitCheckForSync() throws Exception; + + public abstract void transControlHeaderTrnsformSinglesRes() throws Exception; + + protected Object makeSubStandardMessageData(EAIMessage eaiMessage, String msgType, Object bizObject, String charset) + throws Exception { + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardMessage standardMessage = eaiMessage.getStandardMessage(); + + String outboundAdapterGroupName = eaiMessage.getCurrentSvcMsg().getPsvSysItfTp(); + AdapterGroupVO outboundAdapterGvo = AdapterManager.getInstance().getAdapterGroupVO(outboundAdapterGroupName); + standardMessage.setBizData(bizObject, outboundAdapterGvo.getMessageEncode()); + + StandardMessage subMessage = standardManager.getVersionMessage(); + + SubMessageManager subManager = SubMessageManager.getInstance(); + String eaiSvcCode = eaiMessage.getEAISvcCd(); + Map subMap = subManager.getSubMessageMap(eaiSvcCode); + if (subMap != null) { + for (Map.Entry entry : subMap.entrySet()) { + if (logger.isDebug()) { + logger.debug(String.format("DefaultProcess] SUBSTANDARD-MAPPING path: %s, value: %s", + entry.getKey(), entry.getValue())); + } + StandardItem sItem = subMessage.findItem(entry.getKey()); + if (sItem != null) { + sItem.setValue(entry.getValue()); + } + } + } + + MessageMapper versionMapper = standardManager.getVersionMapper(); + subMessage = versionMapper.convertToSub(standardMessage, subMessage); + subMessage.setBizDataCharset(charset); + + eaiMessage.setSubMessage(subMessage); + if (logger.isDebug()) { + logger.debug(String.format("DefaultProcess] SUBSTANDARD-LOGGING SAVE UUID: %s, LOGSEQ: %s, HEADER: %s", + eaiMessage.getSvcOgNo(), this.logPssSno, subMessage.toFixedString(false))); + } + + if (MessageType.JSON.equals(msgType)) { + return subMessage.toJson(); + } else if (MessageType.XML.equals(msgType)) { + return subMessage.toXML(); + } else if (MessageType.ASC.equals(msgType)) { + return subMessage.toByteArray(charset); + } else { + throw new Exception("Unsupported msgType - " + msgType); + } + } + + protected EAIMessage convertToStandardMessage(EAIMessage eaiMessage, String msgType, Object message, String charset) + throws Exception { + InterfaceMapper mapper = eaiMessage.getMapper(); + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + MessageMapper versionMapper = standardManager.getVersionMapper(); + StandardMessage orgStandardMessage = eaiMessage.getStandardMessage(); + StandardMessage subMessage = versionMapper.parseSub(msgType, message); + subMessage.setBizDataCharset(charset); + eaiMessage.setSubMessage(subMessage); + if (logger.isDebug()) { + logger.debug(String.format("DefaultProcess] SUBSTANDARD-LOGGING SAVE UUID: %s, LOGSEQ: %s, HEADER: %s", + eaiMessage.getSvcOgNo(), this.logPssSno, subMessage.toFixedString(false))); + } + + StandardMessage standardMessage = versionMapper.mapFromSub(subMessage, orgStandardMessage); + + standardMessage.setBizDataCharset(charset); + standardManager.getMessageCoordinator().coordinateAfterParsing(standardMessage, null, new Properties()); + eaiMessage.setStandardMessage(standardMessage); + + mapper.setRecvTime(standardMessage, DatetimeUtil.getCurrentTimeMillis()); + return eaiMessage; + } +} diff --git a/src/main/java/com/eactive/eai/outbound/HTTPProcess.java b/src/main/java/com/eactive/eai/outbound/HTTPProcess.java new file mode 100644 index 0000000..dd2c8ac --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/HTTPProcess.java @@ -0,0 +1,833 @@ +package com.eactive.eai.outbound; + +import java.net.SocketTimeoutException; +import java.util.Properties; + +import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.util.PropertiesUtil; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.header.HeaderAction; +import com.eactive.eai.common.header.HeaderActionFactory; +import com.eactive.eai.common.header.HeaderActionKeys; +import com.eactive.eai.common.logger.Keys; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.stdmessage.STDMessageMapper; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.common.util.TranLogUtil; +import com.eactive.eai.common.worker.Future; +import com.eactive.eai.common.worker.ResponseMap; +import com.eactive.eai.control.HttpSender; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.control.Transform; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.util.SimHeaderUtil; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class HTTPProcess extends DefaultProcess { + static final long serialVersionUID = 1L; + protected static final String TIMEOUT_ERROR = "RECEAIOHP003"; + protected static final String STATUS_ERROR = "RECEAIOHP004"; + + protected final ObjectMapper objectMapper = new ObjectMapper().setSerializationInclusion(JsonInclude.Include.NON_NULL); + + public void outboundCtrlCallServiceAsync() throws Exception { + // async에서는 인터페이스 값을 설정하지 않고 Adapter의 타임아웃을 쓰기위해서 설정하지 않음 + try { + this.tempProp.put(HttpClientAdapterServiceKey.LOG_PROCESS_NO, this.logPssSno); + this.resObject = HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp); + } catch (SocketTimeoutException ste) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = TIMEOUT_ERROR; + String rspErrorMsg = ExceptionUtil.make(ste, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, ste); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (HttpStatusException hse) { + String[] msgArgs = new String[2]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + msgArgs[1] = Integer.toString(hse.getStatus()); + String rspErrorCode = STATUS_ERROR; + String rspErrorMsg = ExceptionUtil.make(hse, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, hse); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + + public void outboundCtrlCallService() throws Exception { + // 인터페이스에 셋팅된 타임아웃설정 + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tempProp.put(INTERFACE_TIME_OUT, "" + this.timeout); + try { + this.resObject = HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp); + // 응답코드에 대한 처리 + this.resEaiMsg = setResponseForOutbound(this.resEaiMsg); + if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + this.resEaiMsg = setSendTime(this.resEaiMsg); + } + } catch (SocketTimeoutException ste) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = TIMEOUT_ERROR; + String rspErrorMsg = ExceptionUtil.make(ste, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, ste); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (HttpStatusException hse) { + String[] msgArgs = new String[2]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + msgArgs[1] = Integer.toString(hse.getStatus()); + String rspErrorCode = STATUS_ERROR; + String rspErrorMsg = ExceptionUtil.make(hse, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, hse); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + + public void logSenderCtrlSendRes() throws Exception { + try { + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.resEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + public void logSenderCtrlSendReq() throws Exception { + try { + LogSender.send(this.logPssSno, this.reqEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + public void transControlTransformSingleRes() throws Exception { + try { + this.srcTranObject = this.resObject; + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, false, this.diURI, + this.srcTranObject); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " 300 변환오류", e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP030"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + + public void transControlTransformSingleReq() throws Exception { + try { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + if (bizData != null && bizData.length() > 0) { + this.srcTranObject = bizData; + } + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, true, this.diURI, this.srcTranObject); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " 200 변환오류", e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP020"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void printCallError(Exception e1) throws Exception { + this.resObject = new byte[0]; + + if (TIMEOUT_ERROR.equals(this.resEaiMsg.getRspErrCd())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " UUID[" + this.reqEaiMsg.getSvcOgNo() + + "] 수동시스템 Timeout이 발생함 - Adapter 상태 변경하지 않음 "); + } + } else if (STATUS_ERROR.equals(this.resEaiMsg.getRspErrCd())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " UUID[" + this.reqEaiMsg.getSvcOgNo() + + "] 수동시스템 Response status가 200이 아님 - Adapter 상태 변경하지 않음 "); + } + } else { + AdapterManager manager = AdapterManager.getInstance(); + AdapterVO vo = manager.getAdapterVO(this.adapterGroupName, this.adapterName); + if (vo != null) { + if (!StringUtils.isEmpty(vo.getTestCallClass())) { + vo.setStatus(false); + } + } + } + } + + public void setRcvLogInfo() throws Exception { + this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); // 300 + + this.prop = new Properties(); + if (this.isSuccess) { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.FALSE); + } else { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.TRUE); + } + + if(MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " 내부표준 추출"); + try { + // 응답전문으로 응답 구조체(resEaiMsg) SET + resEaiMsg = setRcvLogInfo(resEaiMsg, this.adptrMsgType, this.resObject, this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizDataBytes(); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "SUB표준 업무데이터 추출"); + try { + this.resEaiMsg = convertToStandardMessage(resEaiMsg, adptrMsgType, this.resObject, this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizDataBytes(); + } catch (Exception e) { + e.printStackTrace(); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP031"; // 잘못된 내부표준메시지 수신[{1}] + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + } + else { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() + && com.eactive.eai.adapter.Keys.TESTMASTER_TAS.equals(adptGrpVO.getTestMasterYn())) {// 비표준 시뮬레이터 + this.resObject = SimHeaderUtil.getSimData(this.resObject); + } + } + } + + public void setTopicResult() throws Exception { + try { + this.jmsRespObject = future.value(this.timeout); + if (this.jmsRespObject == null) { + if (logger.isError()) + logger.error(guidLogPrefix + "SYNC-ASYNC - HTTP setTopicResult jmsRespObject is null. timeout=" + + this.timeout); + throw new Exception("RECEAIOHP010"); + } + resEaiMsg = setResponseForOutbound(this.resEaiMsg); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP010"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } finally { + if (jmsRespAction != null) { + this.jmsRespAction.doEnd(); + } + } + + if (this.jmsRespObject == null) { + this.resObject = new byte[0]; + } else if (this.jmsRespObject instanceof EAIMessage) { + EAIMessage topicEaiMsg = (EAIMessage) this.jmsRespObject; + this.resObject = topicEaiMsg.getStandardMessage().getBizData(); + } else if (this.jmsRespObject instanceof byte[]) { + this.resObject = (byte[]) this.jmsRespObject; + } else { + this.resObject = new byte[0]; + } + } + + public void checkResultMessage() throws Exception { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " SYNC - HTTP RESPONSE MESSAGE : " + + MessageUtil.toAdapterTypeString(this.resObject, this.outboundCharset)); + } + + } + + public void checkSendResult() throws Exception { + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " ASYNC - HTTP RESPONSE MESSAGE : " + + MessageUtil.toAdapterTypeString(this.resObject, this.outboundCharset)); + } + } + } + + public void init() throws Exception { + this.prop = null; + + this.adapterName = this.callProp.getProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_NAME); + + this.resEaiMsg = this.reqEaiMsg; + this.tempProp = new Properties(); + + // GW 전달 로직 추가 + // tempProp로 넘겨서 하는 이유는 outboundProp가 clone 안하는 로직이라 outboundProp로 넘길시 문제의 소지가 있음 + String transactionId = callProp.getProperty(HttpClientAdapterServiceKey.TRANSACTION_ID); + String instanceId = callProp.getProperty(HttpClientAdapterServiceKey.INSTANCE_ID); + if (StringUtils.isNotBlank(transactionId) && StringUtils.isNotBlank(instanceId)) { + this.tempProp.put(HttpClientAdapterServiceKey.TRANSACTION_ID, transactionId); + this.tempProp.put(HttpClientAdapterServiceKey.INSTANCE_ID, instanceId); + } + + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp()); + if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType()) + // RESTAdapter는 교체하지 않는다 + && !StringUtils.equals(adptGrpVO.getType(), com.eactive.eai.adapter.Keys.TYPE_REST)) { + PropManager manager = PropManager.getInstance(); + Properties prop = manager.getProperties(RouteKeys.SIM); + + if (reqEaiMsg.getCurrentSvcMsg().isSyncItfTp()) { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_SYNC, "_SIM_OU_HTT_SyC"); + } else { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_ASYNC, "_SIM_OU_HTT_AsC"); + } + this.reqEaiMsg.getSvcMsg(0).setPsvSysItfTp(this.adapterGroupName); + } else { + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + } + + this.svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // Inbound 호출방식 + this.psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 호출방식 + + // 복합거래의 보상거래여부를 확인 + this.svcPssTp = this.reqEaiMsg.getSvcPssTp(); + this.svcPssSeq = this.reqEaiMsg.getSvcPssSeq(); + + if (this.callProp != null) { + logger.debug(guidLogPrefix + " COMP_VALUE[" + this.callProp.getProperty(EAIKeys.CALL_COMP_KEY) + "]"); + if (EAIKeys.CALL_COMP_VALUE.equals(this.callProp.getProperty(EAIKeys.CALL_COMP_KEY))) { + this.isComp = true; + try { + this.svcPssSeq = Integer.parseInt(this.callProp.getProperty(EAIKeys.CALL_COMP_SVC_SEQ)); + logger.debug(guidLogPrefix + " CALL_COMP_SVC_SEQ[" + this.svcPssSeq + "]"); + } catch (Exception e) { + logger.warn(guidLogPrefix + " CALL_COMP_SVC_SEQ Get Error"); + } + } else { + this.isComp = false; + } + } else { + this.isComp = false; + } + + String returnType = getReturnType(reqEaiMsg); + + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + this.logPssSno = 400; + } else { + this.logPssSno = TranLogUtil.getReqLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + } + + // Inbound Adapter mesageType + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + this.inAdapterMsgType = MessageType.ASC; + + if (inAdptGrpVO == null) { + if (logger.isWarn()) { + String tasAdapterName = ""; + if (this.callProp != null) + tasAdapterName = this.callProp.getProperty(Processor.TAS_ADAPTER_GROUP_NAME); + logger.warn(guidLogPrefix + "Source Adapter is null, TAS Inbound = " + tasAdapterName); + } + } else { + this.inAdapterMsgType = inAdptGrpVO.getMessageType(); + } + } + + public String getUrlSubString(String url, int length) { + try { + int start = 0; + if (url.startsWith("http://")) + start = 7; + if (url.length() > length + start) { + url = url.substring(start, length + start); + } else { + url = url.substring(start); + } + } catch (Exception ex) { + return ""; + } + return url; + } + + public void setSendMsg() throws Exception { + try { + // 200 로그를 위한 변환된 메시지부를 설정 + this.reqEaiMsg.getStandardMessage().setBizData(tgtTranObject, this.outboundCharset); + + this.reqObject = this.tgtTranObject; + + AdapterGroupVO adptGrpVO = null; + AdapterVO adptVO = null; + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + if (adptGrpVO == null) { + String msg = String.format("AdapterGroup not found. - groupName %s adapterName %s", adapterGroupName); + logger.error(msg); + throw new Exception(msg); + } + + if(StringUtils.isEmpty(this.adapterName)) { + adptVO = adptGrpVO.nextAdapterVO(); + } + else { + adptVO = adptGrpVO.getAdapterVO(adapterName); + } + + if (adptVO == null) { + String msg = String.format("Adapter not found. - groupName %s adapterName %s", adapterGroupName, adapterName); + logger.error(msg); + throw new Exception(msg); + } + this.tempProp.setProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_NAME, adptVO.getName()); + } + catch(Exception ex) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(this.adapterGroupName); + String resMsg = ExceptionUtil.make("RECEAIOHP900", msgArgs); + throw new Exception(resMsg, ex); + } + + try { + AdapterPropManager manager = AdapterPropManager.getInstance(); + this.outboundProp = manager.getProperties(adptVO.getPropGroupName());// clone 안함으로 변경 + this.tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME, this.adapterGroupName); + this.tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_NAME, adptVO.getName()); + + // MFC_FAILOVER : FAILOVER = Y 일 경우 무조건 2센터로 라우팅하도록 한다. (2020-08-27) + PropManager pmanager = PropManager.getInstance(); + String mfcFailOver = pmanager.getProperty("MFC_FAILOVER", "FAILOVER"); + + if (mfcFailOver != null && "Y".equals(mfcFailOver.toUpperCase())) { + String url2grp = this.outboundProp.getProperty(HttpClientAdapterServiceKey.URL_2GRP); + if (logger.isInfo()) + logger.info(guidLogPrefix + "MFC_FAILOVER URL_2GRP - " + url2grp); + if (url2grp != null && url2grp.trim().length() > 0) { + this.tempProp.setProperty(HttpClientAdapterServiceKey.URL, url2grp); + this.reqEaiMsg.getCurrentSvcMsg().setPsvSysSvcCd(getUrlSubString(url2grp, 20)); + } + if (logger.isInfo()) + logger.info(guidLogPrefix + "MFC_FAILOVER URL - " + + this.tempProp.getProperty(HttpClientAdapterServiceKey.URL)); + } else { + // 센터구분코드(2) 일 경우, URL_2GRP 로 URL 정보를 치환한다. (2020-07-23) + // DR일 경우에 대한 처리는 동일하게 +// if (STDMessageKeys.CNTERDSTCD_DR.equals(extmessage.getTargetGroup())) { +// String url_2grp = this.outboundProp.getProperty(HttpClientAdapterServiceKey.URL_2GRP); +// if (logger.isInfo()) +// logger.info(guidLogPrefix + "CNTERDSTCD URL_2GRP - " + url_2grp); +// if (url_2grp != null && url_2grp.trim().length() > 0) { +// this.tempProp.setProperty(HttpClientAdapterServiceKey.URL, url_2grp); +// this.reqEaiMsg.getCurrentSvcMsg().setPsvSysSvcCd(getUrlSubString(url_2grp, 20)); +// } +// if (logger.isInfo()) +// logger.info(guidLogPrefix + "CNTERDSTCD URL - " +// + this.tempProp.getProperty(HttpClientAdapterServiceKey.URL)); +// } + } + + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, TransactionContextKeys.TRANSACTION_UUID); + + String svcName = getServiceId(this.reqEaiMsg); + if (svcName == null) { + svcName = ""; + } else { + svcName = svcName.trim(); + } + this.tempProp.setProperty(HttpClientAdapterServiceKey.TRAN_CODE, svcName); + if (logger.isInfo()) + logger.info(guidLogPrefix + " HTTP NKESA svcName : " + svcName); + + // FRST_DMND_SYS_IP_VAL 로 라우팅하도록 함 + String operationEnv = getOperationEnv(this.reqEaiMsg); + if (com.eactive.eai.common.server.Keys.EAI_LOCAL.equals(operationEnv) + && EAIServerManager.getInstance().isMCI()) { + String firstServiceIp = getFirstRequestSysIp(this.reqEaiMsg); + this.tempProp.setProperty(HttpClientAdapterServiceKey.LOCAL_CALL, HttpClientAdapterServiceKey.LOCAL_CALL_Y); + this.tempProp.setProperty(HttpClientAdapterServiceKey.LOCAL_IP, firstServiceIp); + if (logger.isInfo()) + logger.info(guidLogPrefix + " HTTP NKESA LOCAL_CALL IP : " + firstServiceIp); + } + + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); + this.adptrMsgType = adptGrpVO.getMessageType(); + this.outboundProp.setProperty("MESSAGE_TYPE", this.adptrMsgType); + } catch (Exception e) { + throw new Exception("Target Adapter Fail (" + this.adapterGroupName + ") ", e); + } + + // 하나캐피탈 POC 관련 추가 + // 계정계 호출 url 표준헤더에서 가져와 셋팅 + String targetUrl = this.callProp.getProperty("HTTP_URL"); + if (StringUtils.isNotBlank(targetUrl)) { + this.outboundProp.setProperty("HTTP_URL", targetUrl); + } + + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + // StandardMessage object -> message (FLAT|XML|JSON|?) + String restOption = this.reqEaiMsg.getCurrentSvcMsg().getRestOption(); + setStandardRouteInfo(restOption); + this.reqObject = makeStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, this.outboundCharset); + } + else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + this.reqObject = makeSubStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, this.outboundCharset); + if(this.reqObject instanceof String) { + this.reqObject = ((String) this.reqObject).getBytes(this.outboundCharset); + } + } + else { + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() + && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType())) { + this.reqObject = SimHeaderUtil.addSimHeader(reqEaiMsg.getEAISvcCd(), getInstCode(reqEaiMsg), reqObject); + if(logger.isDebug()) logger.debug(guidLogPrefix + " SIM LOG " + this.reqObject); + } + + // 비표준 XML의 경우를 고려하여 XML Header의 유무를 확인 + // 변환을 수행하고 결과가 비표준 XML일 경우에만 + if (EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getCnvEn()) + && MessageType.XML.equals(adptGrpVO.getMessageType())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Add Xml Header Tag to NONSTANDARD XML Message"); + } + + if (this.reqObject instanceof String) { + String reqString = (String) this.reqObject; + if (!StringUtils.startsWith(reqString, "\n" + + reqString; + this.reqObject = reqString; + } + } + } + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " HTTP NONSTANDARD Request Message : " + + MessageUtil.toAdapterTypeString(this.reqObject, this.inboundCharset)); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP022"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void getTopicProperty() throws Exception { + PropManager propManager = PropManager.getInstance(); + + this.topicConFactory = propManager.getProperty(RouteKeys.GROUP_NAME, + RouteKeys.ROUTING_TOPIC_CONNECTION_FACTORY); + this.topicName = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC); +// this.timeout = this.reqEaiMsg.getCurrentSvcMsg().getTmoVl() * 1000; //180 * 1000; + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tracekey = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + + if (ElinkConfig.isUseCacheTopic()) { + this.future = new Future(); + try { + ResponseMap.getInstance().put(this.tracekey, future); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the Cache Response Future. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } else { + jmsRespAction = new com.eactive.eai.common.worker.JMSListenerAction(this.topicConFactory, this.topicName, + this.timeout); + jmsRespAction.doInit(this.tracekey); + this.future = new Future(); + try { + jmsRespAction.doStart(future.getSlot()); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the JMSListenerAction. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + } + + public void performSend() throws Exception { + try { + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_SEND + "]"); + logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + + if (this.tgtTranObject instanceof byte[]) { + this.orgData = new byte[((byte[]) this.tgtTranObject).length]; + System.arraycopy(this.tgtTranObject, 0, this.orgData, 0, ((byte[]) this.tgtTranObject).length); + + this.tgtTranObject = action.excute(this.orgData, (byte[]) this.tgtTranObject, + HeaderActionKeys.MESSAGE_SEND, headerContolType); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " this.orgMessage" + + MessageUtil.toAdapterTypeString((byte[]) this.tgtTranObject, this.inboundCharset)); + } + + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); + } + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP040"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void performRecv() throws Exception { + try { + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_RECV + "]"); + logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + String bizData = this.resEaiMsg.getStandardMessage().getBizData(); + + if (bizData != null && bizData.length() > 0) { + this.tgtTranObject = bizData; + } + + if (this.tgtTranObject instanceof byte[]) { + this.tgtTranObject = action.excute(this.orgData, (byte[]) this.tgtTranObject, + HeaderActionKeys.MESSAGE_RECV, headerContolType); + this.resEaiMsg.getStandardMessage().setBizData(tgtTranObject, this.inboundCharset); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " this.tgtTranObject" + + MessageUtil.toAdapterTypeString((byte[]) this.tgtTranObject, this.outboundCharset)); + } + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); + } + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP040"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void getBizMessage() throws Exception { + + } + + public void storeMessage() throws Exception { + // 비동기-비동기 거래 수동이 표준이 아닌 경우 + // 원거래복원 여부가 '1' 일 경우 + String recoverYn = getRecoverYn(reqEaiMsg); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Message 복원 Flag [" + recoverYn + "]"); + } + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) + && !com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd) + && STDMessageKeys.RECOVER_YN_YES.equals(recoverYn)) { + + try { + String keyMgtMsgCtnt = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Message 복원 실행 KEY[" + keyMgtMsgCtnt + "]"); + } + String extBizCd = this.reqEaiMsg.getExtBizCd(); + STDMessageMapper.storeMessageHeader(keyMgtMsgCtnt, this.reqEaiMsg.getStandardMessage(), extBizCd, this.inAdapterMsgType); + } catch (Exception e) { + if (logger.isError()) { + logger.error(guidLogPrefix + "Message 저장 중 에러 발생", e); + } + + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP011"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + } + + public void waitCheckForSync() throws Exception { + // Sync - Sync 거래중 Wait 메시지가 올경우 대비 + // Async -Sync 는 Flow Control에서 처리 함 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd) && resObject != null) { + if (EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + try { + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(this.adptrMsgType); + reader.parse(standardMessage, resObject); + //표준 전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(outboundCharset); + }catch(Exception e) { + logger.error("standardMessage parsing error " + e.getMessage(),e); + return ; + } + boolean isWait = standardManager.getMessageCoordinator().coordinateIsWaitCheckForSync(standardMessage); + if (isWait) { + getTopicProperty(); + try { + setTopicResult(); + }catch (Exception e) { + executeTimeout(); + } + } + } + } + } + + @Override + public void transControlHeaderTrnsformSinglesRes() throws Exception { + + } + + protected void setStandardRouteInfo(String routeOption) throws JsonProcessingException { + if(StringUtils.isBlank(routeOption)) { + return ; + } + JsonNode rootNode = objectMapper.readTree(routeOption); + JsonNode standardCommonFields = rootNode.get("standardCommonFields"); + + if (standardCommonFields != null && standardCommonFields.isObject()) { + standardCommonFields.fields().forEachRemaining(field -> { + String key = field.getKey(); + String value = field.getValue().asText(); + + StandardMessage standardMessage = this.reqEaiMsg.getStandardMessage(); + standardMessage.setData(key, value); + }); + } + } +} diff --git a/src/main/java/com/eactive/eai/outbound/LoopBackProcess.java b/src/main/java/com/eactive/eai/outbound/LoopBackProcess.java new file mode 100644 index 0000000..945919c --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/LoopBackProcess.java @@ -0,0 +1,186 @@ +package com.eactive.eai.outbound; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.control.Transform; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class LoopBackProcess extends DefaultProcess { + static final long serialVersionUID = 1L; + + public void flow() throws Exception { + if (!isRealCall()) { + return; + } + + init(); + // 송신전로그 + logSenderCtrlSendReq(); + + // 송신변환 + if (isSourceTransform()) { + // 수동메시지 변환 DI + transControlTransformSingleReq(); + // 응답메시지설정 + setTranMessage(); + } else { + // 메시지 설정 + setReturn(); + } + setReturnType(this.resEaiMsg, STDMessageKeys.SEND_RECV_CD_RECV); + // 응답로그설정 + logSenderCtrlSendRes(); + clientReturn(); + } + + public void transControlTransformSingleReq() throws Exception { + this.srcTranObject = this.reqObject; + this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getCnvMsgID(); + try { + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, true, this.diURI, this.srcTranObject); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " 200 변환오류"); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSA020"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); +// this.resEaiMsg.setRspErrCd(rspErrorCode); +// this.resEaiMsg.setRspErrMsg(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + + public void init() throws Exception { + this.logPssSno = 200; + this.prop = null; + this.adapterName = null; + this.resEaiMsg = this.reqEaiMsg; + + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + if (bizData != null && bizData.length() > 0) { + this.reqObject = bizData; + } + } + + public boolean isSourceTransform() { + if (EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getCnvEn())) { + return true; + } else { + return false; + } + } + + public void setReturn() throws Exception { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " 변환룰이 적용되지 않았으므로 요청메시지를 리턴합니다."); + this.resEaiMsg.getStandardMessage().setBizData("response", this.inboundCharset); + } + + public void setTranMessage() throws Exception { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " 변환룰이 적용되어 변환된 응답메시지를 리턴합니다."); + this.resEaiMsg.getStandardMessage().setBizData(resObject, this.inboundCharset); + } + + @Override + public void logSenderCtrlSendReq() throws Exception { + try { + LogSender.send(this.logPssSno, this.reqEaiMsg, this.prop); + } catch (Exception e) { + if (logger.isWarn()) + logger.warn(guidLogPrefix + " EAI 서비스코드[" + this.reqEaiMsg.getEAISvcCd() + "] 거래로그 중 오류발생"); + } + } + + @Override + public void logSenderCtrlSendRes() throws Exception { + this.logPssSno = 300; + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + + } + + @Override + public void outboundCtrlCallService() throws Exception { + + } + + @Override + public void outboundCtrlCallServiceAsync() throws Exception { + + } + + @Override + public void transControlTransformSingleRes() throws Exception { + + } + + @Override + public void printCallError(Exception e1) throws Exception { + + } + + @Override + public void setRcvLogInfo() throws Exception { + + } + + @Override + public void setTopicResult() throws Exception { + + } + + @Override + public void checkResultMessage() throws Exception { + + } + + @Override + public void checkSendResult() throws Exception { + + } + + @Override + public void setSendMsg() throws Exception { + + } + + @Override + public void getTopicProperty() throws Exception { + + } + + @Override + public void performSend() throws Exception { + + } + + @Override + public void performRecv() throws Exception { + + } + + @Override + public void storeMessage() throws Exception { + + } + + @Override + public void getBizMessage() throws Exception { + + } + + @Override + public void waitCheckForSync() throws Exception { + + } + + @Override + public void transControlHeaderTrnsformSinglesRes() throws Exception { + + } + +} diff --git a/src/main/java/com/eactive/eai/outbound/MessageLoggingProcess.java b/src/main/java/com/eactive/eai/outbound/MessageLoggingProcess.java new file mode 100644 index 0000000..b421c91 --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/MessageLoggingProcess.java @@ -0,0 +1,248 @@ +package com.eactive.eai.outbound; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; + +import org.apache.commons.lang.StringUtils; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.LogKeys; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.control.LogSender; + +public class MessageLoggingProcess extends DefaultProcess { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public int logSequence; +// public EAIMessage resEaiMsg; +// public EAIMessage reqEaiMsg; +// public java.util.Properties callProp; +// static final long serialVersionUID = 1L; + + public static final String LOG_DIR = "MsgReceiveDir"; + + @Override + public void flow() throws Exception { + // WarmUp start + if (!isRealCall()) { + return; + } + // WarmUp end + + // LogToFile + logToFile(); + // Condition + if (isAsyncAsyncIF()) { + // SendEAILog + logSenderSend(); + } + } + + public EAIMessage clientReturn() { + return this.reqEaiMsg; + } + + public void logSenderSend() throws Exception { + LogSender.send(this.logSequence, this.reqEaiMsg, this.callProp); + } + + public boolean isAsyncAsyncIF() { + + String svcTsmtUsgTP = reqEaiMsg.getSvcTsmtUsgTp(); + String psvItfTp = reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); + + if (EAIMessageKeys.ASYNC_SVC.equals(svcTsmtUsgTP) && EAIMessageKeys.ASYNC_SVC.equals(psvItfTp)) { + return true; + } else { + return false; + } + } + + public void logToFile() throws Exception { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isDebug()) + logger.debug("MessageLoggingProcess] executing logToFile method. ********************"); + FileWriter fw = null; + BufferedWriter bw = null; + try { + String sLogDirectory = PropManager.getInstance().getProperty(LogKeys.LOGGER_INFO, LogKeys.LOG_DIRECOTRY_PREFIX); + String rootPath = null; + boolean pathExist = true; + + if(StringUtils.isEmpty(sLogDirectory)) { + sLogDirectory = "."; + } + rootPath = sLogDirectory + File.separator + System.getProperty(Keys.SERVER_KEY) + File.separator + LOG_DIR; + File dir = new File(rootPath); + if (!dir.exists()) { + pathExist = dir.mkdir(); + } + if(!pathExist) { + logger.warn("log directory create failed skip file logging - " + rootPath); + return; + } + + String logFileName = DatetimeUtil.getCurrentTimeMillis() + "-" + this.reqEaiMsg.getSvcOgNo() + ".log"; + + File f = new File(dir, logFileName); + fw = new FileWriter(f); + bw = new BufferedWriter(fw); + + String charset = this.callProp.getProperty(com.eactive.eai.adapter.Keys.CHARSET_KEY_IN, "MS949"); + Object data = this.reqEaiMsg.getStandardMessage().getBizData(); + if (data == null) { + bw.write("BizMsg is null."); + } else if (data instanceof byte[]) { + byte[] buff = (byte[]) data; + bw.write(new String(buff, charset)); + } else if (data instanceof String) { + bw.write((String)data); + } else { + bw.write(data.toString()); + } + bw.flush(); + } catch (Exception e) { + logger.error("logToFile error", e); + throw e; + } finally { + this.logSequence = 400; + this.resEaiMsg = this.reqEaiMsg; + try { + if (bw != null) + bw.close(); + } catch (Exception e) { + } + try { + if (fw != null) + fw.close(); + } catch (Exception e) { + } + } + } + + @Override + public void logSenderCtrlSendReq() throws Exception { + + + } + + @Override + public void logSenderCtrlSendRes() throws Exception { + + + } + + @Override + public void outboundCtrlCallService() throws Exception { + + + } + + @Override + public void outboundCtrlCallServiceAsync() throws Exception { + + + } + + @Override + public void transControlTransformSingleRes() throws Exception { + + + } + + @Override + public void transControlTransformSingleReq() throws Exception { + + + } + + @Override + public void printCallError(Exception e1) throws Exception { + + + } + + @Override + public void setRcvLogInfo() throws Exception { + + + } + + @Override + public void setTopicResult() throws Exception { + + + } + + @Override + public void checkResultMessage() throws Exception { + + + } + + @Override + public void checkSendResult() throws Exception { + + + } + + @Override + public void init() throws Exception { + + + } + + @Override + public void setSendMsg() throws Exception { + + + } + + @Override + public void getTopicProperty() throws Exception { + + + } + + @Override + public void performSend() throws Exception { + + + } + + @Override + public void performRecv() throws Exception { + + + } + + @Override + public void storeMessage() throws Exception { + + + } + + @Override + public void getBizMessage() throws Exception { + + + } + + @Override + public void waitCheckForSync() throws Exception { + + + } + + @Override + public void transControlHeaderTrnsformSinglesRes() throws Exception { + + + } + +} diff --git a/src/main/java/com/eactive/eai/outbound/RESTProcess.java b/src/main/java/com/eactive/eai/outbound/RESTProcess.java new file mode 100644 index 0000000..1b2eb51 --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/RESTProcess.java @@ -0,0 +1,661 @@ +package com.eactive.eai.outbound; + +import java.net.SocketTimeoutException; +import java.util.Properties; + +import com.eactive.eai.common.TransactionContextKeys; +import com.eactive.eai.common.circuitBreaker.CircuitBreakerManager; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.util.PropertiesUtil; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ObjectNode; +import com.initech.core.util.PropertiesManager; +import io.github.resilience4j.circuitbreaker.CircuitBreaker; +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.http.HttpStatusException; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.adapter.http.dynamic.HttpAdapterServiceKey; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.header.HeaderAction; +import com.eactive.eai.common.header.HeaderActionFactory; +import com.eactive.eai.common.header.HeaderActionKeys; +import com.eactive.eai.common.logger.Keys; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.common.util.TranLogUtil; +import com.eactive.eai.common.worker.Future; +import com.eactive.eai.common.worker.ResponseMap; +import com.eactive.eai.control.HttpSender; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.control.Transform; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.inbound.processor.Processor; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class RESTProcess extends HTTPProcess { + static final long serialVersionUID = 1L; + + public void outboundCtrlCallServiceAsync() throws Exception { + // async에서는 인터페이스 값을 설정하지 않고 Adapter의 타임아웃을 쓰기위해서 설정하지 않음 + try { + this.tempProp.put(HttpClientAdapterServiceKey.LOG_PROCESS_NO, this.logPssSno); + this.resObject = HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, + this.tempProp); + } catch (SocketTimeoutException ste) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = TIMEOUT_ERROR; + String rspErrorMsg = ExceptionUtil.make(ste, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, ste); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (HttpStatusException hse) { + String[] msgArgs = new String[2]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + msgArgs[1] = Integer.toString(hse.getStatus()); + String rspErrorCode = STATUS_ERROR; + String rspErrorMsg = ExceptionUtil.make(hse, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, hse); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + public void outboundCtrlCallService() throws Exception { + // 인터페이스에 셋팅된 타임아웃설정 + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tempProp.put(INTERFACE_TIME_OUT, "" + this.timeout); + String circuitBreakerUseYn = PropManager.getInstance().getProperty("CircuitBreaker", "useYn"); + + try { + if("Y".equals(circuitBreakerUseYn)){ + String apiId = reqEaiMsg.getEAISvcCd(); + CircuitBreaker circuitBreaker = CircuitBreakerManager.getInstance().getCircuitBreaker(apiId); + + // ObjectMapper 인스턴스 생성 + ObjectMapper objectMapper = new ObjectMapper(); + + // 서킷 브레이커의 메트릭 정보와 상태 정보를 직접 Node로 변환 + ObjectNode combinedNode = objectMapper.createObjectNode(); + combinedNode.put("state", circuitBreaker.getState().toString()); + combinedNode.set("metrics", objectMapper.valueToTree(circuitBreaker.getMetrics())); + + logger.info("CircuitBreaker state "+combinedNode.toString()); + this.resObject = circuitBreaker.executeCallable(() -> HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp)); + }else{ + this.resObject = HttpSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp); + } + + this.resEaiMsg = setResponseForOutbound(this.resEaiMsg); + } catch (SocketTimeoutException ste) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = TIMEOUT_ERROR; + String rspErrorMsg = ExceptionUtil.make(ste, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, ste); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (HttpStatusException hse) { + String[] msgArgs = new String[2]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + msgArgs[1] = Integer.toString(hse.getStatus()); + String rspErrorCode = STATUS_ERROR; + String rspErrorMsg = ExceptionUtil.make(hse, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, hse); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + + public void logSenderCtrlSendRes() throws Exception { + try { + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.resEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + public void logSenderCtrlSendReq() throws Exception { + try { + LogSender.send(this.logPssSno, this.reqEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + public void transControlTransformSingleRes() throws Exception { + try { + this.srcTranObject = this.resObject; + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, false, this.diURI, this.srcTranObject); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " 300 변환오류", e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP030"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + + public void transControlTransformSingleReq() throws Exception { + try { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + if (bizData != null && bizData.length() > 0) { + this.srcTranObject = bizData; + } + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, true, this.diURI, this.srcTranObject); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " 200 변환오류", e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP020"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void printCallError(Exception e1) throws Exception { + this.resObject = new byte[0]; + + if (TIMEOUT_ERROR.equals(this.resEaiMsg.getRspErrCd())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " UUID[" + this.reqEaiMsg.getSvcOgNo() + + "] 수동시스템 Timeout이 발생함 - Adapter 상태 변경하지 않음 "); + } + } else if (STATUS_ERROR.equals(this.resEaiMsg.getRspErrCd())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " UUID[" + this.reqEaiMsg.getSvcOgNo() + + "] 수동시스템 Response status가 200이 아님 - Adapter 상태 변경하지 않음 "); + } + } else { + // REST 는 TEST Call을 할수 없음.20200813.최준호 + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " UUID[" + this.reqEaiMsg.getSvcOgNo() + "] 수동시스템 오류 "); + } + } + } + + public void setRcvLogInfo() throws Exception { + this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); // 300 + + this.prop = new Properties(); + if (this.isSuccess) { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.FALSE); + } else { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.TRUE); + } + + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " 내부표준 추출"); + try { + resEaiMsg = setRcvLogInfo(resEaiMsg, this.adptrMsgType, this.resObject, this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizData(); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) { + logger.error(guidLogPrefix + rspErrorMsg, e); + } + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "SUB표준 업무데이터 추출"); + try { + this.resEaiMsg = convertToStandardMessage(resEaiMsg, adptrMsgType, this.resObject, + this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizData(); + } catch (Exception e) { + e.printStackTrace(); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP031"; // 잘못된 내부표준메시지 수신[{1}] + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + } + } + + public void setTopicResult() throws Exception { + try { + this.jmsRespObject = future.value(this.timeout); + if (this.jmsRespObject == null) { + throw new Exception("RECEAIOHP010"); + } + resEaiMsg = setResponseForOutbound(this.resEaiMsg); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP010"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } finally { + if (jmsRespAction != null) { + this.jmsRespAction.doEnd(); + } + } + + if (this.jmsRespObject == null) { + this.resObject = new byte[0]; + } else if (this.jmsRespObject instanceof EAIMessage) { + EAIMessage topicEaiMsg = (EAIMessage) this.jmsRespObject; + this.resObject = topicEaiMsg.getStandardMessage().getBizDataBytes(); + } else if (this.jmsRespObject instanceof byte[]) { + this.resObject = (byte[]) this.jmsRespObject; + } else { + this.resObject = new byte[0]; + } + + } + + public void init() throws Exception { + this.prop = null; + this.tempProp = new Properties(); + this.adapterName = this.callProp.getProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_NAME); + + this.resEaiMsg = this.reqEaiMsg; + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + + // DefaultProcess 이관시 누락된 부분 추가 + this.svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // Inbound 호출방식 + this.psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 호출방식 + + // 복합거래의 보상거래여부를 확인 + this.svcPssTp = this.reqEaiMsg.getSvcPssTp(); + this.svcPssSeq = this.reqEaiMsg.getSvcPssSeq(); + + if (this.callProp != null) { + logger.debug(guidLogPrefix + " COMP_VALUE[" + this.callProp.getProperty(EAIKeys.CALL_COMP_KEY) + "]"); + if (EAIKeys.CALL_COMP_VALUE.equals(this.callProp.getProperty(EAIKeys.CALL_COMP_KEY))) { + this.isComp = true; + try { + this.svcPssSeq = Integer.parseInt(this.callProp.getProperty(EAIKeys.CALL_COMP_SVC_SEQ)); + logger.debug(guidLogPrefix + " CALL_COMP_SVC_SEQ[" + this.svcPssSeq + "]"); + } catch (Exception e) { + logger.warn(guidLogPrefix + " CALL_COMP_SVC_SEQ Get Error"); + } + } else { + this.isComp = false; + } + } else { + this.isComp = false; + } + + String returnType = getReturnType(reqEaiMsg); + + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + this.logPssSno = 400; + } else { + this.logPssSno = TranLogUtil.getReqLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + } + + // Inbound Adapter mesageType + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + this.inAdapterMsgType = MessageType.ASC; + + if (inAdptGrpVO == null) { + if (logger.isWarn()) { + if (this.prop == null) { + logger.warn(guidLogPrefix + "Source Adapter is null, TAS Inbound "); + } else { + logger.warn(guidLogPrefix + "Source Adapter is null, TAS Inbound = " + + this.prop.getProperty(Processor.TAS_ADAPTER_GROUP_NAME)); + } + } + this.inAdapterMsgType = MessageType.ASC; + } else { + this.inAdapterMsgType = inAdptGrpVO.getMessageType(); + } + } + + public void setSendMsg() throws Exception { + try { + // 200 로그를 위한 변환된 메시지부를 설정 + this.reqEaiMsg.getStandardMessage().setBizData(tgtTranObject, this.outboundCharset); + + if (this.tgtTranObject instanceof String) { + this.reqObject = (String) this.tgtTranObject; + } else { + throw new Exception("Invlid Transform output message (" + this.tgtTranObject + ")"); + } + + AdapterGroupVO adptGrpVO = null; + AdapterVO adptVO = null; + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + if (adptGrpVO == null) { + String msg = String.format("AdapterGroup not found. - groupName %s adapterName %s", adapterGroupName); + logger.error(msg); + throw new Exception(msg); + } + + + if(StringUtils.isEmpty(this.adapterName)) { + adptVO = adptGrpVO.nextAdapterVO(); + } + else { + adptVO = adptGrpVO.getAdapterVO(adapterName); + } + + if (adptVO == null) { + String msg = String.format("Adapter not found. - groupName %s adapterName %s", adapterGroupName, adapterName); + logger.error(msg); + throw new Exception(msg); + } + this.tempProp.setProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_NAME, adptVO.getName()); + } + catch(Exception ex) { + String[] msgArgs = new String[1]; + msgArgs[0] = String.valueOf(this.adapterGroupName); + String resMsg = ExceptionUtil.make("RECEAIOHP900", msgArgs); + throw new Exception(resMsg, ex); + } + String restOption = null; + try { + AdapterPropManager manager = AdapterPropManager.getInstance(); + this.outboundProp = manager.getProperties(adptVO.getPropGroupName());// clone 안함으로 변경 + this.tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME, this.adapterGroupName); + this.tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_NAME, adptVO.getName()); + + restOption = this.reqEaiMsg.getCurrentSvcMsg().getRestOption(); + if (restOption != null) { + this.tempProp.setProperty(HttpClientAdapterServiceKey.REST_OPTION, restOption); + } + String toutval = String.valueOf(this.reqEaiMsg.getCurrentSvcMsg().getTmoVl()); + if (StringUtils.isNotBlank(toutval)) { + this.tempProp.setProperty(HttpClientAdapterServiceKey.TOUTVAL, toutval); + } + + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, TransactionContextKeys.TRANSACTION_UUID); + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_HEADER); + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_METHOD); + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REWRITE_PATH); + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_QUERY_STRING); + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_PATH_VARIABLES); + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_REMOTE_ADDR); + PropertiesUtil.copyPropertyIfPresent(this.callProp, this.tempProp, HttpAdapterServiceKey.INBOUND_SCHEME); + + String svcName = getServiceId(this.reqEaiMsg); + if (svcName == null) { + svcName = ""; + } else { + svcName = svcName.trim(); + } + this.tempProp.setProperty(HttpClientAdapterServiceKey.TRAN_CODE, svcName); + + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); + this.adptrMsgType = adptGrpVO.getMessageType(); + this.outboundProp.setProperty("MESSAGE_TYPE", this.adptrMsgType); + } catch (Exception e) { + throw new Exception("Target Adapter Fail (" + this.adapterGroupName + ") ", e); + } + + // 표준메시지 방식일 경우 KESA메시지에 업무메시지를 설정하여 전달한다. + // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + setStandardRouteInfo(restOption); + this.reqObject = makeStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, this.outboundCharset); + } else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + this.reqObject = makeSubStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, + this.outboundCharset); + if (this.reqObject instanceof String) { + this.reqObject = ((String) this.reqObject).getBytes(this.outboundCharset); + } + } else { + // 변환을 수행하고 결과가 비표준 XML일 경우에만 + if (EAIMessageKeys.YES_FLAG.equals(this.reqEaiMsg.getCurrentSvcMsg().getCnvEn()) + && MessageType.XML.equals(adptGrpVO.getMessageType())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Add Xml Header Tag to NONSTANDARD XML Message"); + } + + String reqString = (String) this.reqObject; + if (!StringUtils.startsWith(reqString, "\n" + reqString; + this.reqObject = reqString; + } + } + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " HTTP NONSTANDARD Request Message : " + + MessageUtil.toAdapterTypeString(this.reqObject, this.inboundCharset)); + } + // TAS 선택시 시뮬레이터 url로 변경 + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType()) + && StringUtils.equals(adptGrpVO.getType(), "RST")) { + PropManager manager = PropManager.getInstance(); + Properties prop = manager.getProperties(RouteKeys.SIM); + String simAddr = prop.getProperty(RouteKeys.SIM_REST_MOCKSERVER); + if (StringUtils.isBlank(simAddr)) { + throw new Exception(String.format("Properties %s > %s not setted", RouteKeys.SIM, + RouteKeys.SIM_REST_MOCKSERVER)); + } + + String url = StringUtils.removeEnd(simAddr, "/") + "/mockapi/" + this.reqEaiMsg.getEAISvcCd(); + this.outboundProp.put(HttpClientAdapterServiceKey.URL, url); + logger.debug("simUrl=" + url); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP022"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void getTopicProperty() throws Exception { + PropManager propManager = PropManager.getInstance(); + + this.topicConFactory = propManager.getProperty(RouteKeys.GROUP_NAME, + RouteKeys.ROUTING_TOPIC_CONNECTION_FACTORY); + this.topicName = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC); + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tracekey = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + + if (ElinkConfig.isUseCacheTopic()) { + this.future = new Future(); + try { + ResponseMap.getInstance().put(this.tracekey, future); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the Cache Response Future. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } else { + jmsRespAction = new com.eactive.eai.common.worker.JMSListenerAction(this.topicConFactory, this.topicName, + this.timeout); + jmsRespAction.doInit(this.tracekey); + this.future = new Future(); + try { + jmsRespAction.doStart(future.getSlot()); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the JMSListenerAction. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + } + + public void performSend() throws Exception { + try { + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_SEND + "]"); + logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + + if (this.tgtTranObject instanceof byte[]) { + this.orgData = new byte[((byte[]) this.tgtTranObject).length]; + System.arraycopy(this.tgtTranObject, 0, this.orgData, 0, ((byte[]) this.tgtTranObject).length); + + this.tgtTranObject = action.excute(this.orgData, (byte[]) this.tgtTranObject, + HeaderActionKeys.MESSAGE_SEND, headerContolType); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " this.orgMessage" + + MessageUtil.toAdapterTypeString((byte[]) this.tgtTranObject, this.inboundCharset)); + } + + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); + } + + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP040"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void performRecv() throws Exception { + try { + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_RECV + "]"); + logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + String bizData = this.resEaiMsg.getStandardMessage().getBizData(); + + if (bizData != null && bizData.length() > 0) { + this.tgtTranObject = bizData; + } + + if (this.tgtTranObject instanceof byte[]) { + this.tgtTranObject = action.excute(this.orgData, (byte[]) this.tgtTranObject, + HeaderActionKeys.MESSAGE_RECV, headerContolType); + this.resEaiMsg.getStandardMessage().setBizData(tgtTranObject, this.inboundCharset); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " this.tgtTranObject" + + MessageUtil.toAdapterTypeString((byte[]) this.tgtTranObject, this.outboundCharset)); + } + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); + } + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP040"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void getBizMessage() throws Exception { + // setRcvLogInfo() 에서 이미 호출됨 + } + + public void storeMessage() throws Exception { + + } + +} diff --git a/src/main/java/com/eactive/eai/outbound/SocketProcess.java b/src/main/java/com/eactive/eai/outbound/SocketProcess.java new file mode 100644 index 0000000..cb08133 --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/SocketProcess.java @@ -0,0 +1,687 @@ +package com.eactive.eai.outbound; + +import java.util.Properties; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.EAIConnectException; +import com.eactive.eai.adapter.socket2.EAINoAvailableConnectionException; +import com.eactive.eai.adapter.socket2.EAITimeoutException; +import com.eactive.eai.adapter.socket2.SocketAdapterFacade; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.header.HeaderAction; +import com.eactive.eai.common.header.HeaderActionFactory; +import com.eactive.eai.common.header.HeaderActionKeys; +import com.eactive.eai.common.logger.Keys; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.stdmessage.STDMessageMapper; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.common.util.TranLogUtil; +import com.eactive.eai.common.worker.Future; +import com.eactive.eai.common.worker.ResponseMap; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.control.SocketSender; +import com.eactive.eai.control.Transform; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.StandardReader; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +public class SocketProcess extends DefaultProcess { + static final long serialVersionUID = 1L; + + public void logSenderCtrlSendReq() throws Exception { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "" + this.reqEaiMsg.getSvcOgNo() + " - " + this.logPssSno); + try { + LogSender.send(this.logPssSno, this.reqEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + public void logSenderCtrlSendRes() throws Exception { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "" + this.resEaiMsg.getSvcOgNo() + " - " + this.logPssSno); + try { + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.resEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + public void outboundCtrlCallService() throws Exception { + // 인터페이스에 셋팅된 타임아웃설정 + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tempProp.put(INTERFACE_TIME_OUT, "" + this.timeout); + try { + this.resObject = SocketSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, this.tempProp); + // 응답코드에 대한 처리 + this.resEaiMsg = setResponseForOutbound(this.resEaiMsg); + if (!com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + this.resEaiMsg = setSendTime(this.resEaiMsg); + } + } catch (EAIConnectException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (EAINoAvailableConnectionException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP003"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (EAITimeoutException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP004"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + + public void outboundCtrlCallServiceAsync() throws Exception { + /** + * async에서는 인터페이스 값을 설정하지 않고 Adapter의 타임아웃을 쓰기위해서 설정하지 않음 + */ + try { + this.resObject = SocketSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, + this.tempProp); + } catch (EAIConnectException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (EAINoAvailableConnectionException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP003"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (EAITimeoutException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP004"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + + public void transControlTransformSingleRes() throws Exception { + try { + this.srcTranObject = this.resObject; + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, false, this.diURI, this.srcTranObject); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP030"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + + public void transControlTransformSingleReq() throws Exception { + try { + String bizData = this.reqEaiMsg.getStandardMessage().getBizData(); + if (bizData != null && bizData.length() > 0) { + this.srcTranObject = bizData; + } + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, true, this.diURI, this.srcTranObject); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP020"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void printCallError(Exception e1) throws Exception { + this.resObject = new byte[0]; + } + + public void setRcvLogInfo() throws Exception { + // this.logPssSno = 300; + this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + + this.prop = new Properties(); + if (this.isSuccess) { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.FALSE); + } else { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.TRUE); + } + + // 표준메시지 파싱 + if(MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "내부표준 추출"); + try { + resEaiMsg = setRcvLogInfo(resEaiMsg, this.adptrMsgType, this.resObject, this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizDataBytes(); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP031"; // 잘못된 KB 내부표준메시지 수신[{1}] + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "SUB표준 업무데이터 추출"); + try { + this.resEaiMsg = convertToStandardMessage(resEaiMsg, adptrMsgType, this.resObject, this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizDataBytes(); + } catch (Exception e) { + e.printStackTrace(); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP031"; // 잘못된 내부표준메시지 수신[{1}] + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + } + } + + public void setTopicResult() throws Exception { + try { + this.jmsRespObject = future.value(this.timeout); + if (this.jmsRespObject == null) { + if (logger.isError()) + logger.error(guidLogPrefix + "SYNC-ASYNC - SOCKET setTopicResult jmsRespObject is null. timeout=" + + this.timeout); + throw new Exception("RECEAIOSP010"); + } + resEaiMsg = setResponseForOutbound(this.resEaiMsg); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP010"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } finally { + if (jmsRespAction != null) { + this.jmsRespAction.doEnd(); + } + } + + if (this.jmsRespObject == null) { + this.resObject = new byte[0]; + } else if (this.jmsRespObject instanceof EAIMessage) { + EAIMessage topicEaiMsg = (EAIMessage) this.jmsRespObject; + this.resObject = topicEaiMsg.getStandardMessage().getBizDataBytes(); + } else if (this.jmsRespObject instanceof byte[]) { + this.resObject = (byte[]) this.jmsRespObject; + } else { + this.resObject = new byte[0]; + } + } + + public void checkResultMessage() throws Exception { + // 동기방식거래를 비동기 방식의 어댑터로 할 경우 발생함 + if (this.resObject != null) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " SYNC - SOCKET RESPONSE MESSAGE +" + + MessageUtil.toAdapterTypeString(this.resObject, this.outboundCharset)); + + } else { + if (logger.isWarn()) + logger.warn(guidLogPrefix + " SYNC - SOCKET RESPONSE MESSAGE is NULL :" + + MessageUtil.toAdapterTypeString(this.resObject, this.outboundCharset)); + this.resObject = new byte[0]; + } + + } + + public void checkSendResult() throws Exception { + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " ASYNC - SOCKET SEND..."); + } + } + + public void init() throws Exception { + this.tempProp = new Properties(); + if (logger.isDebug()) + logger.debug(guidLogPrefix + "callProp [" + this.callProp + "]"); + + this.svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // Inbound 호출방식 + this.psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 호출방식 + + // 복합거래의 보상거래여부를 확인 + this.svcPssTp = this.reqEaiMsg.getSvcPssTp(); + this.svcPssSeq = this.reqEaiMsg.getSvcPssSeq(); + + if (this.callProp != null) { + logger.debug(guidLogPrefix + "COMP_VALUE[" + this.callProp.getProperty(EAIKeys.CALL_COMP_KEY) + "]"); + if (EAIKeys.CALL_COMP_VALUE.equals(this.callProp.getProperty(EAIKeys.CALL_COMP_KEY))) { + this.isComp = true; + try { + this.svcPssSeq = Integer.parseInt(this.callProp.getProperty(EAIKeys.CALL_COMP_SVC_SEQ)); + logger.debug(guidLogPrefix + "CALL_COMP_SVC_SEQ[" + this.svcPssSeq + "]"); + } catch (Exception e) { + logger.warn(guidLogPrefix + "CALL_COMP_SVC_SEQ Get Error"); + } + } else { + this.isComp = false; + } + } else { + this.isComp = false; + } + + String returnType = getReturnType(reqEaiMsg); + + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + this.logPssSno = 400; + } else { + this.logPssSno = TranLogUtil.getReqLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + } + + this.prop = null; + this.resEaiMsg = this.reqEaiMsg; + + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + this.adapterName = this.callProp.getProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_NAME); + + // 업무데이터에서 추출한 값을 KESA 개별부에 설정 (eb-Bank 관련) + // 송신전 메세지 설정(setSendMsg)에서 init으로 로직 이동 + AdapterManager adapterManager = AdapterManager.getInstance(); + + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + AdapterVO adptVO = null; + AdapterPropManager manager = AdapterPropManager.getInstance(); + + if (adptGrpVO != null) { + adptVO = adptGrpVO.nextAdapterVO(); + } + + if (adptVO == null) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + // RECEAIOSP003 - EAI 서비스코드[{1}] Socket Adapter 가용 connection 이 없는 오류 + String rspErrorCode = "RECEAIOSP003"; + String rspErrorMsg = ExceptionUtil.make(rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + + throw new Exception("가용한 어댑터가 없습니다.[" + this.adapterGroupName + "]"); + + } else { + this.outboundProp = manager.getProperties(adptVO.getPropGroupName()); + } + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 + this.adptrMsgType = adptGrpVO.getMessageType(); + + String currentAdapterName = this.adapterGroupName; + if(this.adapterName != null) { + currentAdapterName = currentAdapterName + "." + this.adapterName; + } + this.tempProp.setProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_GROUP_NAME, currentAdapterName); + + // Inboud Adapter mesageType + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + this.inAdapterMsgType = MessageType.ASC; + + if (inAdptGrpVO == null) { + if (logger.isWarn()) { + String tasAdapterName = ""; + if (this.callProp != null) + tasAdapterName = this.callProp.getProperty(Processor.TAS_ADAPTER_GROUP_NAME); + logger.warn(guidLogPrefix + "Source Adapter is null, TAS Inbound = " + tasAdapterName); + } + this.inAdapterMsgType = MessageType.ASC; + } else { + this.inAdapterMsgType = inAdptGrpVO.getMessageType(); + } + } + + public void setSendMsg() throws Exception { + // 표준메시지 방식일 경우 KESA메시지에 업무메시지를 설정하여 전달한다. + // [S, N, C] 값을 가짐 + if (logger.isDebug()) + logger.debug(guidLogPrefix + "IF_TYPE[" + this.adptrMsgPtrnCd + "]"); + + // 200 로그를 위한 변환된 메시지부를 설정 + this.reqEaiMsg.getStandardMessage().setBizData(tgtTranObject, this.outboundCharset); + + if (this.tgtTranObject instanceof byte[]) { + this.reqObject = (byte[]) this.tgtTranObject; + } else if (this.tgtTranObject instanceof String) { + this.reqObject = ((String)this.tgtTranObject).getBytes(this.outboundCharset); + } + + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + AdapterVO adptVO = null; + if (adapterName == null) { + String[] adptrs = adptGrpVO.getAdapterNames(); + if (adptrs != null && adptrs.length > 0) { + adptVO = adptGrpVO.getAdapterVO(adptrs[0]); + } + } else { + adptVO = adptGrpVO.getAdapterVO(adapterName); + this.tempProp.setProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_NAME, adptVO.getName()); + } + + if (adptVO == null) { + throw new Exception("adapter not found"); + } + + this.tempProp.setProperty(com.eactive.eai.adapter.Keys.OUT_ADAPTER_GROUP_NAME, this.adapterGroupName); + + // 표준전문일 경우 헤더부 거래타임아웃시간(TX_TMOT_TKTM) 셋팅 어댑터 기준 + AdapterPropManager adaptrPropManager = AdapterPropManager.getInstance(); + Properties prop = adaptrPropManager.getProperties(adptVO.getPropGroupName()); + String txTmotTktm = prop.getProperty("timeout", "50"); + setTimeout(this.reqEaiMsg, StringUtil.stringFormat(txTmotTktm, true, '0', 3)); + + + this.reqObject = makeStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, this.outboundCharset); + if(this.reqObject instanceof String) { + this.reqObject = ((String) this.reqObject).getBytes(this.outboundCharset); + } + } + else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + this.reqObject = makeSubStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, this.outboundCharset); + if(this.reqObject instanceof String) { + this.reqObject = ((String) this.reqObject).getBytes(this.outboundCharset); + } + } + + + if (logger.isDebug()) { + if (this.reqObject != null) { + logger.debug(guidLogPrefix + " Socket Request Message : " + + MessageUtil.toAdapterTypeString(this.reqObject, this.inboundCharset)); + } else { + logger.debug(guidLogPrefix + " Socket Request Message : IS NULL"); + } + } + } + + public void getTopicProperty() throws Exception { + PropManager propManager = PropManager.getInstance(); + + this.topicConFactory = propManager.getProperty(RouteKeys.GROUP_NAME, + RouteKeys.ROUTING_TOPIC_CONNECTION_FACTORY); + this.topicName = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC); + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tracekey = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + + if (ElinkConfig.isUseCacheTopic()) { + this.future = new Future(); + try { + ResponseMap.getInstance().put(this.tracekey, future); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the Cache Response Future. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } else { + jmsRespAction = new com.eactive.eai.common.worker.JMSListenerAction(this.topicConFactory, this.topicName, + this.timeout); + jmsRespAction.doInit(this.tracekey); + this.future = new Future(); + try { + jmsRespAction.doStart(future.getSlot()); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the JMSListenerAction. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + } + + public void performSend() throws Exception { + try { + // 변화후에 있기 때문에 tgtTranObject 이용해야 된다. + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + "headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + "전송 Type : [" + HeaderActionKeys.MESSAGE_SEND + "]"); + logger.debug(guidLogPrefix + "Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + + if (this.tgtTranObject instanceof byte[]) { + this.orgData = new byte[((byte[]) this.tgtTranObject).length]; + System.arraycopy(this.tgtTranObject, 0, this.orgData, 0, ((byte[]) this.tgtTranObject).length); + + this.tgtTranObject = action.excute(this.orgData, (byte[]) this.tgtTranObject, + HeaderActionKeys.MESSAGE_SEND, headerContolType); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "this.tgtTranObject " + + MessageUtil.toAdapterTypeString((byte[]) this.tgtTranObject, this.inboundCharset)); + } + + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + "byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); + } + + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP050"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void performRecv() throws Exception { + try { + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + "headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + "전송 Type : [" + HeaderActionKeys.MESSAGE_RECV + "]"); + logger.debug(guidLogPrefix + "Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + + if (this.resObject instanceof byte[]) { + this.resObject = action.excute(this.orgData, (byte[]) this.resObject, HeaderActionKeys.MESSAGE_RECV, + headerContolType); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "this.resObject" + + MessageUtil.toAdapterTypeString((byte[]) this.resObject, this.outboundCharset)); + } + + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + "byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.resObject); + } + + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP050"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void storeMessage() throws Exception { + // ---------------------------------------------- + // 비동기-비동기 거래 &&수동이 표준이 아닌 경우 + // 원거래복원 여부가 '1' 일 경우 복원 정보를 저장 + // ---------------------------------------------- + String recoverYn = getRecoverYn(reqEaiMsg); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Message 복원 Flag [" + recoverYn + "]"); + } + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) + && !com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd) + && STDMessageKeys.RECOVER_YN_YES.equals(recoverYn)) { + + try { + String keyMgtMsgCtnt = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Message 복원 실행 KEY[" + keyMgtMsgCtnt + "]"); + } + String extBizCd = this.reqEaiMsg.getExtBizCd(); + STDMessageMapper.storeMessageHeader(keyMgtMsgCtnt, this.reqEaiMsg.getStandardMessage(), extBizCd, this.inAdapterMsgType); + } catch (Exception e) { + if (logger.isError()) { + logger.error(guidLogPrefix + "Message 저장 중 에러 발생", e); + } + + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP011"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + } + + public void getBizMessage() throws Exception { + + } + + public void waitCheckForSync() throws Exception { + // Sync - Sync 거래중 Wait 메시지가 올경우 대비 + // Async -Sync 는 Flow Control에서 처리 함 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd) && resObject != null) { + if (EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + try { + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(this.adptrMsgType); + reader.parse(standardMessage, resObject); + //표준 전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(outboundCharset); + }catch(Exception e) { + logger.error("standardMessage parsing error " + e.getMessage(),e); + return ; + } + boolean isWait = standardManager.getMessageCoordinator().coordinateIsWaitCheckForSync(standardMessage); + if (isWait) { + getTopicProperty(); + try { + setTopicResult(); + }catch (Exception e) { + executeTimeout(); + } + } + } + } + } + + @Override + public void transControlHeaderTrnsformSinglesRes() throws Exception { + + } +} diff --git a/src/main/java/com/eactive/eai/outbound/WebTProcess.java b/src/main/java/com/eactive/eai/outbound/WebTProcess.java new file mode 100644 index 0000000..6198878 --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/WebTProcess.java @@ -0,0 +1,771 @@ +package com.eactive.eai.outbound; + +import java.util.Properties; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.http.client.HttpClientAdapterServiceKey; +import com.eactive.eai.common.EAIKeys; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.header.HeaderAction; +import com.eactive.eai.common.header.HeaderActionFactory; +import com.eactive.eai.common.header.HeaderActionKeys; +import com.eactive.eai.common.logger.Keys; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageKeys; +import com.eactive.eai.common.message.MessageType; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.routing.RouteKeys; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.stdmessage.STDMessageMapper; +import com.eactive.eai.common.util.MessageUtil; +import com.eactive.eai.common.util.StringUtil; +import com.eactive.eai.common.util.TranLogUtil; +import com.eactive.eai.common.worker.Future; +import com.eactive.eai.common.worker.ResponseMap; +import com.eactive.eai.control.LogSender; +import com.eactive.eai.control.Transform; +import com.eactive.eai.control.WebTSender; +import com.eactive.eai.env.ElinkConfig; +import com.eactive.eai.inbound.processor.Processor; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.StandardMessageUtil; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.util.SimHeaderUtil; +import com.ext.eai.common.stdmessage.STDMessageKeys; + +import tmax.webt.WebtIOException; +import tmax.webt.WebtServiceException; +import tmax.webt.WebtServiceFailException; + +public class WebTProcess extends DefaultProcess { + static final long serialVersionUID = 1L; + protected static String prefix = "RECEAIOWP"; + + public void outboundCtrlCallServiceAsync() throws Exception { + // async에서는 인터페이스 값을 설정하지 않고 Adapter의 타임아웃을 쓰기위해서 설정하지 않음 + try { + this.resObject = WebTSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, tempProp); + } catch (WebtIOException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (WebtServiceFailException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "003"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (WebtServiceException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "004"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Throwable t) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "001"; + String rspErrorMsg = ExceptionUtil.make(t, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + + public void outboundCtrlCallService() throws Exception { + // 인터페이스에 셋팅된 타임아웃설정 + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tempProp.put(INTERFACE_TIME_OUT, "" + this.timeout); + try { + this.resObject = WebTSender.callService(this.adapterGroupName, this.outboundProp, this.reqObject, tempProp); + // 응답코드에 대한 처리 + this.resEaiMsg = setResponseForOutbound(this.resEaiMsg); + } catch (WebtIOException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (WebtServiceFailException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "003"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (WebtServiceException e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "004"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "001"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } catch (Throwable t) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = prefix + "001"; + String rspErrorMsg = ExceptionUtil.make(t, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(rspErrorMsg); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + + public void logSenderCtrlSendRes() throws Exception { + try { + LogSender.send(this.logPssSno, this.resEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.resEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + public void logSenderCtrlSendReq() throws Exception { + try { + LogSender.send(this.logPssSno, this.reqEaiMsg, this.prop); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP021"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isWarn()) + logger.warn(rspErrorMsg); + } + } + + public void transControlTransformSingleRes() throws Exception { + try { + this.srcTranObject = this.resObject; + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, false, this.diURI, this.srcTranObject); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " 300 변환오류", e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP030"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + + public void transControlTransformSingleReq() throws Exception { + try { + this.srcTranObject = StandardMessageUtil.getBizData(this.reqEaiMsg); + this.diURI = this.reqEaiMsg.getCurrentSvcMsg().getCnvMsgID(); + this.tgtTranObject = Transform.transformSingle(this.guidLogPrefix, true, this.diURI, this.srcTranObject); + } catch (Exception e) { + if (logger.isError()) + logger.error(guidLogPrefix + " 200 변환오류", e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP020"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void printCallError(Exception e1) throws Exception { + this.resObject = new byte[0]; + AdapterManager manager = AdapterManager.getInstance(); + AdapterVO vo = manager.getAdapterVO(this.adapterGroupName, this.adapterName); + if (vo != null) { + if (!StringUtils.isEmpty(vo.getTestCallClass())) { + vo.setStatus(false); + } + } + } + + public void setRcvLogInfo() throws Exception { + this.logPssSno = TranLogUtil.getResLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); // 300 + + this.prop = new Properties(); + if (this.isSuccess) { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.FALSE); + } else { + prop.setProperty(Keys.ERROR_MESSAGE, Keys.TRUE); + } + + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + " 내부표준 추출"); + try { + resEaiMsg = setRcvLogInfo(resEaiMsg, this.adptrMsgType, this.resObject, this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizDataBytes(); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP002"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + if (logger.isDebug()) + logger.debug(guidLogPrefix + "SUB표준 업무데이터 추출"); + try { + this.resEaiMsg = convertToStandardMessage(resEaiMsg, adptrMsgType, this.resObject, + this.outboundCharset); + this.resObject = resEaiMsg.getStandardMessage().getBizDataBytes(); + } catch (Exception e) { + e.printStackTrace(); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP031"; // 잘못된 내부표준메시지 수신[{1}] + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + } + } + } else { + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() + && com.eactive.eai.adapter.Keys.TESTMASTER_TAS.equals(adptGrpVO.getTestMasterYn())) {// 비표준 시뮬레이터 + this.resObject = SimHeaderUtil.getSimData(this.resObject); + } + } + } + + public void setTopicResult() throws Exception { + try { + this.jmsRespObject = future.value(this.timeout); + if (this.jmsRespObject == null) { + if (logger.isError()) + logger.error(guidLogPrefix + "SYNC-ASYNC - HTTP setTopicResult jmsRespObject is null. timeout=" + + this.timeout); + throw new Exception("RECEAIOHP010"); + } + resEaiMsg = setResponseForOutbound(this.resEaiMsg); + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP010"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } finally { + if (jmsRespAction != null) { + this.jmsRespAction.doEnd(); + } + } + + if (this.jmsRespObject == null) { + this.resObject = new byte[0]; + } else if (this.jmsRespObject instanceof EAIMessage) { + EAIMessage topicEaiMsg = (EAIMessage) this.jmsRespObject; + this.resObject = topicEaiMsg.getStandardMessage().getBizDataBytes(); + } else if (this.jmsRespObject instanceof byte[]) { + this.resObject = (byte[]) this.jmsRespObject; + } else { + this.resObject = new byte[0]; + } + + } + + public void checkResultMessage() throws Exception { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " SYNC - HTTP RESPONSE MESSAGE : " + + MessageUtil.toAdapterTypeString(this.resObject, this.outboundCharset)); + } + + } + + public void checkSendResult() throws Exception { + if (MessageUtil.checkRspErrCd(this.resEaiMsg.getRspErrCd())) { + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " ASYNC - HTTP RESPONSE MESSAGE : " + + MessageUtil.toAdapterTypeString(this.resObject, this.outboundCharset)); + } + } + } + + public void init() throws Exception { + this.prop = null; + this.adapterName = null; + this.resEaiMsg = this.reqEaiMsg; + this.tempProp = new Properties(); + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType())) { + PropManager manager = PropManager.getInstance(); + Properties prop = manager.getProperties(RouteKeys.SIM); + + if (reqEaiMsg.getCurrentSvcMsg().isSyncItfTp()) { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_SYNC, "_SIM_OU_HTT_SyC"); + } else { + this.adapterGroupName = prop.getProperty(RouteKeys.SIM_ADAPTER_ASYNC, "_SIM_OU_HTT_AsC"); + } + this.reqEaiMsg.getSvcMsg(0).setPsvSysItfTp(this.adapterGroupName); + } else { + this.adapterGroupName = reqEaiMsg.getCurrentSvcMsg().getPsvSysItfTp(); + } + + this.svcTsmtUsgTp = this.reqEaiMsg.getSvcTsmtUsgTp(); // Inbound 호출방식 + this.psvItfTp = this.reqEaiMsg.getCurrentSvcMsg().getPsvItfTp(); // 호출방식 + + // 복합거래의 보상거래여부를 확인 + this.svcPssTp = this.reqEaiMsg.getSvcPssTp(); + this.svcPssSeq = this.reqEaiMsg.getSvcPssSeq(); + + if (this.callProp != null) { + logger.debug(guidLogPrefix + " COMP_VALUE[" + this.callProp.getProperty(EAIKeys.CALL_COMP_KEY) + "]"); + if (EAIKeys.CALL_COMP_VALUE.equals(this.callProp.getProperty(EAIKeys.CALL_COMP_KEY))) { + this.isComp = true; + try { + this.svcPssSeq = Integer.parseInt(this.callProp.getProperty(EAIKeys.CALL_COMP_SVC_SEQ)); + logger.debug(guidLogPrefix + " CALL_COMP_SVC_SEQ[" + this.svcPssSeq + "]"); + } catch (Exception e) { + logger.warn(guidLogPrefix + " CALL_COMP_SVC_SEQ Get Error"); + } + } else { + this.isComp = false; + } + } else { + this.isComp = false; + } + + String returnType = getReturnType(reqEaiMsg); + + if (STDMessageKeys.SEND_RECV_CD_RECV.equals(returnType)) { + this.logPssSno = 400; + } else { + this.logPssSno = TranLogUtil.getReqLogSeq(this.svcPssTp, this.svcPssSeq, this.isComp); + } + + // Inbound Adapter mesageType + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO inAdptGrpVO = adapterManager.getAdapterGroupVO(this.reqEaiMsg.getSngSysItfTp()); + this.inAdapterMsgType = MessageType.ASC; + + if (inAdptGrpVO == null) { + if (logger.isWarn()) { + String tasAdapterName = ""; + if (this.callProp != null) + tasAdapterName = this.callProp.getProperty(Processor.TAS_ADAPTER_GROUP_NAME); + logger.warn(guidLogPrefix + "Source Adapter is null, TAS Inbound = " + tasAdapterName); + } + } else { + this.inAdapterMsgType = inAdptGrpVO.getMessageType(); + } + } + + public String getUrlSubString(String url, int length) { + try { + int start = 0; + if (url.startsWith("http://")) + start = 7; + if (url.length() > length + start) { + url = url.substring(start, length + start); + } else { + url = url.substring(start); + } + } catch (Exception ex) { + return ""; + } + return url; + } + + public void setSendMsg() throws Exception { + try { + AdapterGroupVO adptGrpVO = null; + try { + AdapterManager adapterManager = AdapterManager.getInstance(); + adptGrpVO = adapterManager.getAdapterGroupVO(this.adapterGroupName); + + if (adptGrpVO == null) { + throw new Exception("adapter group not found"); + } + + AdapterVO adptVO = adptGrpVO.nextAdapterVO(); + + if (adptVO == null) { + throw new Exception("adapter not found"); + } + this.adapterName = adptVO.getName(); + + AdapterPropManager manager = AdapterPropManager.getInstance(); + + /** + * tempProp로 수정중 + */ + this.outboundProp = (Properties) manager.getProperties(adptVO.getPropGroupName());// clone 안함으로 변경 + + this.tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_GROUP_NAME, this.adapterGroupName); + this.tempProp.setProperty(HttpClientAdapterServiceKey.ADAPTER_NAME, adptVO.getName()); + + // MFC_FAILOVER : FAILOVER = Y 일 경우 무조건 2센터로 라우팅하도록 한다. (2020-08-27) + PropManager pmanager = PropManager.getInstance(); + String mfcFailOver = pmanager.getProperty("MFC_FAILOVER", "FAILOVER"); + + if (mfcFailOver != null && "Y".equals(mfcFailOver.toUpperCase())) { + String url_2grp = this.outboundProp.getProperty(HttpClientAdapterServiceKey.URL_2GRP); + if (logger.isInfo()) + logger.info(guidLogPrefix + "MFC_FAILOVER URL_2GRP - " + url_2grp); + if (url_2grp != null && url_2grp.trim().length() > 0) { + this.tempProp.setProperty(HttpClientAdapterServiceKey.URL, url_2grp); + this.reqEaiMsg.getCurrentSvcMsg().setPsvSysSvcCd(getUrlSubString(url_2grp, 20)); + } + if (logger.isInfo()) + logger.info(guidLogPrefix + "MFC_FAILOVER URL - " + + this.tempProp.getProperty(HttpClientAdapterServiceKey.URL)); + } else { + // 센터구분코드(2) 일 경우, URL_2GRP 로 URL 정보를 치환한다. (2020-07-23) + // DR일 경우에 대한 처리는 동일하게 +// if(STDMessageKeys.CNTERDSTCD_DR.equals(extmessage.getTargetGroup()) ) { +// String url_2grp = this.outboundProp.getProperty(HttpClientAdapterServiceKey.URL_2GRP); +// if (logger.isInfo()) logger.info(guidLogPrefix + "CNTERDSTCD URL_2GRP - " + url_2grp ); +// if(url_2grp != null && url_2grp.trim().length() > 0) { +// this.tempProp.setProperty(HttpClientAdapterServiceKey.URL, url_2grp); +// this.reqEaiMsg.getCurrentSvcMsg().setPsvSysSvcCd( getUrlSubString(url_2grp, 20) ); +// } +// if (logger.isInfo()) logger.info(guidLogPrefix + "CNTERDSTCD URL - " + this.tempProp.getProperty(HttpClientAdapterServiceKey.URL) ); +// } + } + + String svcName = getServiceId(this.reqEaiMsg); + if (svcName == null) { + svcName = ""; + } else { + svcName = svcName.trim(); + } + this.tempProp.setProperty(HttpClientAdapterServiceKey.TRAN_CODE, svcName); + if (logger.isInfo()) + logger.info(guidLogPrefix + " HTTP NKESA svcName : " + svcName); + + // ENVR_INFO_DVSN_CD = L + // FRST_DMND_SYS_IP_VAL 로 라우팅하도록 함 + String operationEnv = getOperationEnv(this.reqEaiMsg); + if (com.eactive.eai.common.server.Keys.EAI_LOCAL.equals(operationEnv) + && EAIServerManager.getInstance().isMCI()) { + String firstServiceIp = getFirstRequestSysIp(this.reqEaiMsg); + this.tempProp.setProperty(HttpClientAdapterServiceKey.LOCAL_CALL, + HttpClientAdapterServiceKey.LOCAL_CALL_Y); + this.tempProp.setProperty(HttpClientAdapterServiceKey.LOCAL_IP, firstServiceIp); + if (logger.isInfo()) + logger.info(guidLogPrefix + " HTTP NKESA LOCAL_CALL IP : " + firstServiceIp); + } + + this.adptrMsgPtrnCd = adptGrpVO.getAdptrMsgPtrnCd(); + this.adptrMsgType = adptGrpVO.getMessageType(); + } catch (Exception e) { + throw new Exception("Target Adapter Fail (" + this.adapterGroupName + ") "); + } + + // 200 로그를 위한 변환된 메시지부를 설정 + this.reqEaiMsg.getStandardMessage().setBizData(tgtTranObject, this.outboundCharset); + + // 표준메시지 방식일 경우 KESA메시지에 업무메시지를 설정하여 전달한다. + // migration - boolean 값이 아니라 [S, N, C] 값을 가짐 + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd)) { + this.reqObject = makeStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, + this.outboundCharset); + } else if (com.eactive.eai.adapter.Keys.IF_SUBSTANDARD.equals(this.adptrMsgPtrnCd)) { + this.reqObject = makeSubStandardMessageData(this.reqEaiMsg, this.adptrMsgType, this.reqObject, + this.outboundCharset); + if (this.reqObject instanceof String) { + this.reqObject = ((String) this.reqObject).getBytes(this.outboundCharset); + } + } else { + EAIServerManager eaiServerManager = EAIServerManager.getInstance(); + if (eaiServerManager.isTASEnabledEAIServer() + && EAIMessageKeys.TRANTYPE_TAS.equals(reqEaiMsg.getTranType())) { + this.reqObject = SimHeaderUtil.addSimHeader(reqEaiMsg.getEAISvcCd(), getInstCode(reqEaiMsg), + reqObject); + } + + if (logger.isDebug()) + logger.debug(guidLogPrefix + " HTTP NONSTANDARD Request Message : " + + MessageUtil.toAdapterTypeString(this.reqObject, this.inboundCharset)); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP022"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void getTopicProperty() throws Exception { + PropManager propManager = PropManager.getInstance(); + + this.topicConFactory = propManager.getProperty(RouteKeys.GROUP_NAME, + RouteKeys.ROUTING_TOPIC_CONNECTION_FACTORY); + this.topicName = propManager.getProperty(RouteKeys.GROUP_NAME, RouteKeys.ROUTING_TOPIC); + int iTimeoutValue = getTimeoutCodeToValue(); + this.timeout = iTimeoutValue * 1000; + this.tracekey = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + + if (ElinkConfig.isUseCacheTopic()) { + this.future = new Future(); + try { + ResponseMap.getInstance().put(this.tracekey, future); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the Cache Response Future. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } else { + jmsRespAction = new com.eactive.eai.common.worker.JMSListenerAction(this.topicConFactory, this.topicName, + this.timeout); + jmsRespAction.doInit(this.tracekey); + this.future = new Future(); + try { + jmsRespAction.doStart(future.getSlot()); + } catch (Exception e) { + logger.error(guidLogPrefix + "Cannot start the JMSListenerAction. - " + e.getMessage(), e); + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP060"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + } + + public void performSend() throws Exception { + try { + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_SEND + "]"); + logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + + if (this.tgtTranObject instanceof byte[]) { + this.orgData = new byte[((byte[]) this.tgtTranObject).length]; + System.arraycopy(this.tgtTranObject, 0, this.orgData, 0, ((byte[]) this.tgtTranObject).length); + + this.tgtTranObject = action.excute(this.orgData, (byte[]) this.tgtTranObject, + HeaderActionKeys.MESSAGE_SEND, headerContolType); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " this.orgMessage" + + MessageUtil.toAdapterTypeString((byte[]) this.tgtTranObject, this.inboundCharset)); + } + + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); + } + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP040"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void performRecv() throws Exception { + try { + String headerActionName = this.reqEaiMsg.getCurrentSvcMsg().getHdrRefClsName(); + String headerContolType = StringUtil.getNullStr(this.reqEaiMsg.getCurrentSvcMsg().getHdrCtrlDstcd()); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 실행합니다."); + logger.debug(guidLogPrefix + " headerActionName : [" + headerActionName + "]"); + logger.debug(guidLogPrefix + " 전송 Type : [" + HeaderActionKeys.MESSAGE_RECV + "]"); + logger.debug(guidLogPrefix + " Header Control Type : [" + headerContolType + "]"); + } + + HeaderAction action = HeaderActionFactory.createAction(headerActionName); + String bizData = this.resEaiMsg.getStandardMessage().getBizData(); + + if (bizData != null && bizData.length() > 0) { + this.tgtTranObject = bizData; + } + + if (this.tgtTranObject instanceof byte[]) { + this.tgtTranObject = action.excute(this.orgData, (byte[]) this.tgtTranObject, + HeaderActionKeys.MESSAGE_RECV, headerContolType); + this.resEaiMsg.getStandardMessage().setBizData(tgtTranObject, this.inboundCharset); + + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " this.tgtTranObject" + + MessageUtil.toAdapterTypeString((byte[]) this.tgtTranObject, this.outboundCharset)); + } + } else { + if (logger.isWarn()) { + logger.warn(guidLogPrefix + " byte[] 만허용됩니다. 업무메시지타입을 확인하세요" + this.tgtTranObject); + } + } + if (logger.isDebug()) { + logger.debug(guidLogPrefix + " Header 로직을 종료합니다."); + } + } catch (Exception e) { + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOHP040"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new Exception(rspErrorMsg); + } + } + + public void getBizMessage() throws Exception { + + } + + public void storeMessage() throws Exception { + // ---------------------------------------------- + // 비동기-비동기 거래 && 수동이 표준이 아닌 경우 + // 원거래복원 여부가 '1' 일 경우에 + // ---------------------------------------------- + String recoverYn = getRecoverYn(reqEaiMsg); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Message 복원 Flag [" + recoverYn + "]"); + } + if (EAIMessageKeys.ASYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp()) + && !com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd) + && STDMessageKeys.RECOVER_YN_YES.equals(recoverYn)) { + + try { + String keyMgtMsgCtnt = this.reqEaiMsg.getCurrentSvcMsg().getKeyMgtMsgVl(); + if (logger.isDebug()) { + logger.debug(guidLogPrefix + "Message 복원 실행 KEY[" + keyMgtMsgCtnt + "]"); + } + String extBizCd = this.reqEaiMsg.getExtBizCd(); + STDMessageMapper.storeMessageHeader(keyMgtMsgCtnt, this.reqEaiMsg.getStandardMessage(), extBizCd, + this.inAdapterMsgType); + } catch (Exception e) { + if (logger.isError()) { + logger.error(guidLogPrefix + "Message 저장 중 에러 발생", e); + } + + String[] msgArgs = new String[1]; + msgArgs[0] = this.reqEaiMsg.getEAISvcCd(); + String rspErrorCode = "RECEAIOSP011"; + String rspErrorMsg = ExceptionUtil.make(e, rspErrorCode, msgArgs); + if (logger.isError()) + logger.error(guidLogPrefix + rspErrorMsg, e); + this.resEaiMsg.setRspErr(rspErrorCode,rspErrorMsg); + throw new RuntimeException(rspErrorCode); + } + } + } + + public void waitCheckForSync() throws Exception { + /** + * Sync - Sync 거래중 Wait 메시지가 올경우 대비 + * Async -Sync 는 Flow Control에서 처리 함 + */ + if (com.eactive.eai.adapter.Keys.IF_STANDARD.equals(this.adptrMsgPtrnCd) && resObject != null) { + if (EAIMessageKeys.SYNC_SVC.equals(this.reqEaiMsg.getSvcTsmtUsgTp())) { + StandardMessage standardMessage = null; + StandardMessageManager standardManager = StandardMessageManager.getInstance(); + StandardReader reader = null; + try { + standardMessage = standardManager.getStandardMessage(); + reader = standardManager.getReader(this.adptrMsgType); + reader.parse(standardMessage, resObject); + //표준 전문 파싱 후 어댑터의 charset을 설정한다. + standardMessage.setBizDataCharset(outboundCharset); + }catch(Exception e) { + logger.error("standardMessage parsing error " + e.getMessage(),e); + return ; + } + boolean isWait = standardManager.getMessageCoordinator().coordinateIsWaitCheckForSync(standardMessage); + if (isWait) { + getTopicProperty(); + try { + setTopicResult(); + }catch (Exception e) { + executeTimeout(); + } + } + } + } + } + + /** + * 출력 매체 부 매핑 작업 운영관리 > 환경정보 > 공통코드관리 > 프라퍼티 관리 STDMESSAGE > + * DATAHEADER_OTPT_TRANSFORM=true 일 때에만 변환 수행 + */ + @SuppressWarnings("unchecked") + @Override + public void transControlHeaderTrnsformSinglesRes() throws Exception { + + } +} diff --git a/src/main/java/com/eactive/eai/outbound/pool/BidSendThreadPoolExecutor.java b/src/main/java/com/eactive/eai/outbound/pool/BidSendThreadPoolExecutor.java new file mode 100644 index 0000000..45ed221 --- /dev/null +++ b/src/main/java/com/eactive/eai/outbound/pool/BidSendThreadPoolExecutor.java @@ -0,0 +1,35 @@ +package com.eactive.eai.outbound.pool; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class BidSendThreadPoolExecutor { +private static BidSendThreadPoolExecutor instance = new BidSendThreadPoolExecutor(); + + /** + * 기동 여부 + */ + private boolean started; + private static ExecutorService executor = Executors.newFixedThreadPool(10); + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * 3. 주의사항 + **/ + private BidSendThreadPoolExecutor() { + + } + + public static BidSendThreadPoolExecutor getInstance() { + return instance; + } + + public ExecutorService getExecutor(){ + return executor; + } + public static void destroy(){ + instance = null; + executor.shutdownNow(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/transformer/servlet/BizKeyServlet.java b/src/main/java/com/eactive/eai/transformer/servlet/BizKeyServlet.java new file mode 100644 index 0000000..5174e17 --- /dev/null +++ b/src/main/java/com/eactive/eai/transformer/servlet/BizKeyServlet.java @@ -0,0 +1,100 @@ +package com.eactive.eai.transformer.servlet; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.bizkey.BizKeyManager; +import com.eactive.eai.common.bizkey.BizKeyVO; +import com.eactive.eai.common.util.Logger; + +public class BizKeyServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String key = request.getContext(); + + if (key.lastIndexOf('/') == -1) { + key = ""; + } else { + key = key.substring(key.indexOf('/')+1); + } + + String result = ""; + try { + result = show(key); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + final static String SCRIPT = + " \n"; + + public String show(String key) { + StringBuffer sb = new StringBuffer(); + BizKeyManager manager = BizKeyManager.getInstance(); + String[] bizkeys = manager.getAllKeyNames(); + + sb.append(SCRIPT); + sb.append("bizkey | keyword = " + key); + sb.append("
"); + + int count = 0; + for(int i=0; i 1) { + sb.append("
"); + } + + try { + sb.append("
");
+					BizKeyVO bizkey = manager.getBizKey(bizkeys[i]);
+					sb.append(bizkey.getEaiSvcCd() + "\n");
+					sb.append("
"); + } catch(Exception e) { + sb.append("
");
+			    	sb.append("(reload) ");
+					sb.append(ExceptionStackTrace.dump(e));
+					sb.append("
"); + } + + if (count > 1) { + sb.append("
"); + sb.append("
"); + } + + /** + * 100개 까지만 뿌려준다. + */ + if (resultCount++ >= 100) + break; + } + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/transformer/servlet/FunctionServlet.java b/src/main/java/com/eactive/eai/transformer/servlet/FunctionServlet.java new file mode 100644 index 0000000..577b643 --- /dev/null +++ b/src/main/java/com/eactive/eai/transformer/servlet/FunctionServlet.java @@ -0,0 +1,72 @@ +package com.eactive.eai.transformer.servlet; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.function.FunctionManager; + +public class FunctionServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String key = request.getContext(); + if (key.lastIndexOf('/') == -1) { + key = ""; + } else { + key = key.substring(key.indexOf('/')+1); + } + + String result = ""; + try { + result = show(key); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + final static String SCRIPT = + " \n"; + + public String show(String key) { + StringBuffer sb = new StringBuffer(); + FunctionManager manager = FunctionManager.getInstance(); + String[] functionNames = manager.getAllFunctionNames(); + + if(functionNames == null) return ""; + if(key == null) key = ""; + + sb.append(SCRIPT); + sb.append("message | key = " + key + "
"); + for(int i=0; i"); + sb.append("
");
+				sb.append(manager.getFunctionDefinition(functionNames[i]));
+	    	   	sb.append("
"); + sb.append(""); + sb.append("
"); + } + } + return sb.toString(); + } +} diff --git a/src/main/java/com/eactive/eai/transformer/servlet/LayoutServlet.java b/src/main/java/com/eactive/eai/transformer/servlet/LayoutServlet.java new file mode 100644 index 0000000..3eea579 --- /dev/null +++ b/src/main/java/com/eactive/eai/transformer/servlet/LayoutServlet.java @@ -0,0 +1,119 @@ +package com.eactive.eai.transformer.servlet; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.layout.Layout; +import com.eactive.eai.transformer.layout.LayoutManager; + +public class LayoutServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String key = request.getContext(); + + boolean isReload = false; + if (key.endsWith("/reload")) { + isReload = true; + key = key.substring(0, key.lastIndexOf('/')); + } + + if (key.lastIndexOf('/') == -1) { + key = ""; + } else { + key = key.substring(key.indexOf('/')+1); + } + + String result = ""; + try { + if (isReload) { + result = reload(key); + } else { + result = show(key); + } + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + final static String SCRIPT = + " \n"; + + public String show(String key) { + StringBuffer sb = new StringBuffer(); + LayoutManager manager = LayoutManager.getManager(); + String[] messageNames = manager.getAllLayoutName(); + + sb.append(SCRIPT); + sb.append("message | key = " + key); + sb.append("
"); + + int count = 0; + for(int i=0; i 1) { + sb.append("
"); + } + Layout l = manager.getLayoutByName(messageNames[i]); + if(l != null) { + sb.append("
");
+			    	sb.append("(reload) ");
+					sb.append(l.getRootItem().toString());
+					sb.append("
"); + } + else { + sb.append("
");
+			    	sb.append("(reload) ");
+					sb.append("Layout not found!");
+					sb.append("
"); + } + + if (count > 1) { + sb.append("
"); + sb.append("
"); + } + + /** + * 10개 까지만 뿌려준다. + */ + if (resultCount++ >= 100) + break; + } + } + return sb.toString(); + } + + public String reload(String key) throws Exception { + if (LayoutManager.getManager().getLayoutByName(key) == null) + return "layout '" + key + "' does not exist"; + + LayoutManager.getManager().reload(key); + return "reload message '" + key + "' successfully"; + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/transformer/servlet/ServiceServlet.java b/src/main/java/com/eactive/eai/transformer/servlet/ServiceServlet.java new file mode 100644 index 0000000..98ad8a1 --- /dev/null +++ b/src/main/java/com/eactive/eai/transformer/servlet/ServiceServlet.java @@ -0,0 +1,103 @@ +package com.eactive.eai.transformer.servlet; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.message.EAIMessageManager; +import com.eactive.eai.common.util.Logger; + +import java.net.URLDecoder; + +public class ServiceServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String key = request.getContext(); + + if (key.lastIndexOf('/') == -1) { + key = ""; + } else { + key = key.substring(key.indexOf('/')+1); + } + + String result = ""; + try { + result = show(URLDecoder.decode(key,"UTF-8")); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + final static String SCRIPT = + " \n"; + + public String show(String key) { + StringBuffer sb = new StringBuffer(); + EAIMessageManager manager = EAIMessageManager.getInstance(); + String[] serviceCodes = manager.getAllEAISvcCd(); + + sb.append(SCRIPT); + sb.append("message | key = " + key); + sb.append("
"); + + int count = 0; + for(int i=0; i 1) { + sb.append("
"); + } + + try { + sb.append("
");
+					EAIMessage message = manager.getEAIMessage(serviceCodes[i]);
+					sb.append(message.getEAISvcCd() + " - " + message.getEAISvcDesc() + "\n");
+					sb.append("response error message : " + message.getRspErrMsg() + "\n");
+					sb.append("
"); + } catch(Exception e) { + sb.append("
");
+			    	sb.append("(reload) ");
+					sb.append(ExceptionStackTrace.dump(e));
+					sb.append("
"); + } + + if (count > 1) { + sb.append("
"); + sb.append("
"); + } + + /** + * 100개 까지만 뿌려준다. + */ + if (resultCount++ >= 100) + break; + } + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/transformer/servlet/TransformServlet.java b/src/main/java/com/eactive/eai/transformer/servlet/TransformServlet.java new file mode 100644 index 0000000..748aa50 --- /dev/null +++ b/src/main/java/com/eactive/eai/transformer/servlet/TransformServlet.java @@ -0,0 +1,119 @@ +package com.eactive.eai.transformer.servlet; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.transform.Transform; +import com.eactive.eai.transformer.transform.TransformManager; + +public class TransformServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String key = request.getContext(); + + boolean isReload = false; + if (key.endsWith("/reload")) { + isReload = true; + key = key.substring(0, key.lastIndexOf('/')); + } + + if (key.lastIndexOf('/') == -1) { + key = ""; + } else { + key = key.substring(key.indexOf('/')+1); + } + + String result = ""; + try { + if (isReload) { + result = reload(key); + } else { + result = show(key); + } + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + final static String SCRIPT = + " \n"; + + public String show(String key) { + StringBuffer sb = new StringBuffer(); + TransformManager manager = TransformManager.getManager(); + String[] transformNames = manager.getAllTransformName(); + + sb.append(SCRIPT); + sb.append("transform | key = " + key); + sb.append("
"); + + int count = 0; + for(int i=0; i 1) { + sb.append("
"); + } + + sb.append("
");
+		    	sb.append("(reload) ");
+		    	Transform t = manager.getTransform(transformNames[i]);
+		    	if(t == null) {
+		    		sb.append("NULL");
+		    	}
+		    	else {
+		    		sb.append(t.toString());
+		    	}
+		    	sb.append("
"); + + if (count > 1) { + sb.append("
"); + sb.append("
"); + } + + /** + * 100개 까지만 뿌려준다. + */ + if (resultCount++ >= 100) + break; + } + } + + return sb.toString(); + } + + public String reload(String key) throws Exception { + if (TransformManager.getManager().getTransform(key) == null) + return "transform '" + key + "' does not exist"; + + TransformManager.getManager().reload(key); + return "reload transform '" + key + "' successfully"; + } +} diff --git a/src/main/java/com/eactive/eai/transformer/servlet/TransformerServlet.java b/src/main/java/com/eactive/eai/transformer/servlet/TransformerServlet.java new file mode 100644 index 0000000..fe687d3 --- /dev/null +++ b/src/main/java/com/eactive/eai/transformer/servlet/TransformerServlet.java @@ -0,0 +1,124 @@ +package com.eactive.eai.transformer.servlet; + +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.transformer.engine.TransformEngine; +import com.eactive.eai.transformer.util.MemoryLogger; + +public class TransformerServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String command = request.getContext(); + if (command.lastIndexOf('/') == -1) { + command = ""; + } else { + command = command.substring(command.indexOf('/')+1); + } + + String result = ""; + if (command == null || "".equals(command) || "tx".equals(command)) { + try { + result = transaction(); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + } else if ("error".equals(command) || "err".equals(command)) { + try { + result = error(); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + } else if ("dump".equals(command)) { + try { + result = dump(); + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + } else { + response.setResponseCode(404); + return; + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + final static String SCRIPT = + " \n"; + + private String transaction() throws Exception { + StringBuffer sb = new StringBuffer(); + String[] transactions = MemoryLogger.getTransactions(); + sb.append(SCRIPT); + + sb.append("

Transformer - transactions

"); + for (int i=transactions.length-1; i>=0; i--) { + sb.append("
"); + sb.append("
");
+    	   	sb.append(unescape(transactions[i]));
+    	   	sb.append("
"); + sb.append("
"); + sb.append("
"); + } + return sb.toString(); + } + + private String error() throws Exception { + StringBuffer sb = new StringBuffer(); + String[] errors = MemoryLogger.getErrors(); + sb.append(SCRIPT); + + sb.append("

Transformer - errors (" + MemoryLogger.getErrorCount() + ")

"); + for (int i=errors.length-1; i>=0; i--) { + sb.append("
"); + sb.append("
");
+    		sb.append(unescape(errors[i]));
+    	   	sb.append("
"); + sb.append("
"); + sb.append("
"); + + } + return sb.toString(); + } + + + private String dump() throws Exception { + StringBuffer sb = new StringBuffer(); + sb.append("

Transformer - dump

"); + sb.append("
");
+		sb.append(TransformEngine.getInstance().toString());
+    	sb.append("
\n"); + return sb.toString(); + } + + + + private String unescape(String string) { + string = string.replace("", "(b)").replace("", "(/b)"); + string = string.replaceAll("", "(a$1)").replace("", "(/a)"); + string = string.replaceAll("", "(font color='$1')").replace("", "(/font)"); + string = string.replace(">", ">").replace("<", "<"); + string = string.replace("(b)", "").replace("(/b)", ""); + string = string.replaceAll("\\(a( href=\\'[a-zA-Z0-9_/]+\\')\\)", "").replace("(/a)", ""); + string = string.replaceAll("\\(font color='([a-zA-Z]+)'\\)", "").replace("(/font)", ""); + return string; + } +} diff --git a/src/main/java/com/eactive/eai/util/ByteCharSequence.java b/src/main/java/com/eactive/eai/util/ByteCharSequence.java new file mode 100644 index 0000000..da287a1 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/ByteCharSequence.java @@ -0,0 +1,57 @@ +package com.eactive.eai.util; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ByteCharSequence implements CharSequence{ + private final byte[] data; + private final int length; + private final int offset; + + public ByteCharSequence(byte[] data){ + this(data, 0, data.length); + } + public ByteCharSequence(byte[] data, int offset, int length){ + this.data = data; + this.offset = offset; + this.length = length; + } + + @Override + public int length() { + return this.length; + } + + @Override + public char charAt(int index) { + return (char)(data[offset + index] & 0xff); + } + + @Override + public CharSequence subSequence(int start, int end) { + return new ByteCharSequence(data, offset + start, end - start); + } + + public static void main(String[] args) throws Exception{ + ByteMessage b = new ByteMessage(); + b.append((byte)0xD4); + b.append((byte)0xD6); + b.append((byte)0xC3); + b.append((byte)0xF5); + b.append((byte)0xF0); + b.append((byte)0xF9); + b.append((byte)0xF4); + b.append((byte)0x40); + b.append((byte)0x40); + b.append("0000HDRISO12345678901234567890123456789012345678901234567".getBytes()); + + Matcher m = Pattern.compile("[0-9]{4}HDR").matcher(new ByteCharSequence(b.getBytes())); + int index =0; + if (m.find()){ + index = m.start(); + } + System.out.println("index = " + index); + } +} diff --git a/src/main/java/com/eactive/eai/util/CharsetDecoderUtil.java b/src/main/java/com/eactive/eai/util/CharsetDecoderUtil.java new file mode 100644 index 0000000..3c6d867 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/CharsetDecoderUtil.java @@ -0,0 +1,57 @@ +package com.eactive.eai.util; + +import java.nio.ByteBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetDecoder; + +public class CharsetDecoderUtil { + private Charset charset = null; + private CharsetDecoder decoder = null; + + public CharsetDecoderUtil(String encoding) { + this.charset = Charset.forName(encoding); + this.decoder = charset.newDecoder(); + } + + public static String toKor(String s) { + if (s != null) { + return changeCode(s, "iso_8859-1", "KSC5601"); + } else { + return null; + } + } + + public static String changeCode(String s, String s1, String s2) { + String convString = null; + if (s != null) { + try { + convString = new String(s.getBytes(s1), s2); + } catch (Exception exception) { + //Log.errorlog(exception.toString()); + return null; + } + } + return convString; + } + + public String decode(ByteBuffer buffer) { + String string = null; + // buffer가 null일 경우 return한다. + if (buffer == null) { + return ""; + } + try { + // buffer를 decode한다. + string = decoder.decode(buffer).toString(); + } catch (CharacterCodingException e) { + string = ""; + } + // decode한 값이 null일 경우 ""를 리턴 한다. + if (string == null) { + return ""; + } else { + return string; + } + } +} diff --git a/src/main/java/com/eactive/eai/util/CryptoUtil.java b/src/main/java/com/eactive/eai/util/CryptoUtil.java new file mode 100644 index 0000000..d7849f1 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/CryptoUtil.java @@ -0,0 +1,70 @@ +package com.eactive.eai.util; + +import java.util.Base64; + +import javax.crypto.Cipher; +import javax.crypto.spec.SecretKeySpec; + +//TOUSE +//kbank 어댑터에서 업무데이터의 암호화 필드에 대한 암복호화 +//OAuth2.0 의 ClientID를 통해 등록된 key를 조회하여 사용 +public class CryptoUtil { + public static final String defaultCharset = "utf-8"; + private CryptoUtil() { + + } + + public static String encryptAES(String key, String text) { + return encrypt(key, text, "AES"); + } + + public static String decryptAES(String key, String base64EncodedText) { + return decrypt(key, base64EncodedText, "AES"); + } + + public static String encrypt(String key, String text, String algoritm) throws IllegalArgumentException { + try { + SecretKeySpec secureKey = new SecretKeySpec(key.getBytes(), algoritm); + Cipher cipher = Cipher.getInstance(algoritm); + cipher.init(Cipher.ENCRYPT_MODE, secureKey); + byte[] encryptData = cipher.doFinal(text.getBytes(defaultCharset)); + return new String(Base64.getEncoder().encode(encryptData)); + } catch (Exception e) { + throw new IllegalArgumentException(e.toString()); + } + } + + public static String decrypt(String key, String text, String algoritm) throws IllegalArgumentException { + try { + SecretKeySpec secureKey = new SecretKeySpec(key.getBytes(), algoritm); + byte[] encryptedData = Base64.getDecoder().decode(text.getBytes(defaultCharset)); + Cipher cipher = Cipher.getInstance(algoritm); + cipher.init(Cipher.DECRYPT_MODE, secureKey); + byte[] plainText = cipher.doFinal(encryptedData); + return new String(plainText); + } catch (Exception e) { + throw new IllegalArgumentException(e.toString()); + } + } + + public static void main(String[] args) { + String key = "ONAuROzlqWB4VuBwO5C/FA=="; + String text = "Hello AES 한글"; + + System.out.println("Original Text: " + text); + + long startEncryptTime = System.nanoTime(); + String enc = encryptAES(key, text); + long endEncryptTime = System.nanoTime(); + long encryptDuration = endEncryptTime - startEncryptTime; + System.out.println("Encrypted Text: " + enc); + System.out.println("Encryption took: " + encryptDuration + " nanoseconds"); + + long startDecryptTime = System.nanoTime(); + String dec = decryptAES(key, enc); + long endDecryptTime = System.nanoTime(); + long decryptDuration = endDecryptTime - startDecryptTime; + System.out.println("Decrypted Text: " + dec); + System.out.println("Decryption took: " + decryptDuration + " nanoseconds"); + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/util/HealthCheckManager.java b/src/main/java/com/eactive/eai/util/HealthCheckManager.java new file mode 100644 index 0000000..17147f9 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/HealthCheckManager.java @@ -0,0 +1,120 @@ +package com.eactive.eai.util; + +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.util.Logger; + +import java.util.HashMap; +import java.util.Timer; + +// Server Ping Test Health Check +public class HealthCheckManager implements Lifecycle { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + private static HealthCheckManager manager = new HealthCheckManager(); + + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + private boolean started; + + private HashMap serverHealthMap; + + private HealthCheckRunner runner; + private Timer timer; + + public static HealthCheckManager getInstance() { + return manager; + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICHC001"); + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + this.serverHealthMap = new HashMap(); + EAIServerManager mgr = EAIServerManager.getInstance(); + this.serverHealthMap.put(mgr.getLocalServerName(), 0); + + long period = 1000 * 5; +// try { +// period = Long.parseLong(pmanager.getProperty(PROP_GROUP, PROP_PERIOD)); +// } catch(Exception e) {} + + this.runner = new HealthCheckRunner(); + this.runner.setHealthCheckManager(this); + + this.timer = new Timer("HeadthCheckerTimer"); + this.timer.schedule(this.runner, period, period); + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICHC002"); + logger.warn("Stopping"); + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + + this.timer.cancel(); + + this.timer = null; + this.runner = null; + + if(this.serverHealthMap != null) { + this.serverHealthMap.clear(); + this.serverHealthMap = null; + } + + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, null); + logger.warn("Stopped"); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public void addFailCount(String instId, int count) { + if(!started) return; + Integer failCount = this.serverHealthMap.get(instId); + + if (failCount == null) { + this.serverHealthMap.put(instId, count); + } else { + int newCount = 0; + if (count > 0) + newCount = failCount + count; + this.serverHealthMap.put(instId, newCount); + } + logger.info("HealthCheckManager] Server Health : " + instId + " - " + this.serverHealthMap.get(instId)); + } + + public boolean getServerStatus(String instId) { + if(!started) return false; + Integer failCount = this.serverHealthMap.get(instId); + if (failCount == null) { + return false; + } else { + if (failCount >= 2) + return false; + else + return true; + } + } +} diff --git a/src/main/java/com/eactive/eai/util/HealthCheckRunner.java b/src/main/java/com/eactive/eai/util/HealthCheckRunner.java new file mode 100644 index 0000000..fbba5e4 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/HealthCheckRunner.java @@ -0,0 +1,44 @@ +package com.eactive.eai.util; + +import java.util.TimerTask; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.util.Logger; + +// HealthCheckManager에 등록된 HealthCheck Beans를 일정 주기로 실행 +public class HealthCheckRunner extends TimerTask { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + private HealthCheckManager manager; + + public HealthCheckRunner() { + } + + public void setHealthCheckManager(HealthCheckManager manager) { + this.manager = manager; + } + + public void run() { + EAIServerManager mgr = EAIServerManager.getInstance(); + EAIServerVO server = mgr.getEAIServer(mgr.getLocalServerName()); + if (server == null) { + return; + } + String instId = server.getFailoverSvr(); + + if (StringUtils.isBlank(instId)) { + logger.warn("HealthCheckRunner] FailOver Server instance not set - " + mgr.getLocalServerName()); + return; + } + + boolean isAlive = ServerPingUtil.pingHost(instId); + + if (isAlive) { + this.manager.addFailCount(instId, 0); + } else { + this.manager.addFailCount(instId, 1); + } + } +} diff --git a/src/main/java/com/eactive/eai/util/HexaConverter.java b/src/main/java/com/eactive/eai/util/HexaConverter.java new file mode 100644 index 0000000..ea8989b --- /dev/null +++ b/src/main/java/com/eactive/eai/util/HexaConverter.java @@ -0,0 +1,35 @@ +package com.eactive.eai.util; + +public class HexaConverter { + public static final String bytesToHexa(byte[] abyte) { + StringBuilder s = new StringBuilder(); + if (abyte == null) + return s.toString(); + for (int i = 0; i < abyte.length; i++) { + s.append( Integer.toHexString((abyte[i] & 0xf0) >> 4) ) + .append( Integer.toHexString(abyte[i] & 0xf)); + } + return s.toString(); + } + + public static final byte[] hexaToBytes(String hexa) { + if((hexa.length() % 2) != 0) return null; + byte[] bytes = new byte[hexa.length() / 2]; + + String hexaBytes = null; + for(int i=0; i = 0) { + String matchRegexp = match.replace("\\*", "[0-9]+").trim(); + Matcher matcher = Pattern.compile(matchRegexp, Pattern.CASE_INSENSITIVE).matcher(requestIp); + if (matcher.matches()) { + return true; + } + } else if (match.indexOf('/') >= 0) { // CIDR 표기법 "192.168.0.0/24" + org.apache.commons.net.util.SubnetUtils utils = new org.apache.commons.net.util.SubnetUtils(match); + if (utils.getInfo().isInRange(requestIp)) { + return true; + } + } else { + if (match.equals(requestIp)) { + return true; + } + } + } + return false; + } + + public static void main(String[] args) throws Exception { + String matchdIps = "192.168.0.1,192.168.0.0/24,192.168.1.*"; + String requestIp = "192.168.1.2"; + if (IpUtil.isMatchIp(matchdIps, requestIp)) { + System.out.println(true); + } else { + System.out.println(false); + + } + } +} \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/util/JsonBeatiUtil.java b/src/main/java/com/eactive/eai/util/JsonBeatiUtil.java new file mode 100644 index 0000000..1066703 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/JsonBeatiUtil.java @@ -0,0 +1,141 @@ +package com.eactive.eai.util; + +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +public class JsonBeatiUtil { + public static String SimpleBeautiful(Object input) { + JSONObject json = null; + String data = ""; + if (input instanceof JSONObject) { + json = (JSONObject) input; + } else if (input instanceof String) { + json = (JSONObject) JSONValue.parse((String) input); + } else if (input instanceof byte[]) { + String s = new String((byte[]) input); + json = (JSONObject) JSONValue.parse(s); + } + data = json.toJSONString(); + int tabCount = 0; + StringBuilder inputBuilder = new StringBuilder(); + char[] inputChar = data.toCharArray(); + for (int i = 0; i < inputChar.length; i++) { + String charI = String.valueOf(inputChar[i]); + if (charI.equals("}") || charI.equals("]")) { + tabCount--; + if (!String.valueOf(inputChar[i - 1]).equals("[") && !String.valueOf(inputChar[i - 1]).equals("{")) { + inputBuilder.append(simpleNewLine(tabCount)); + } + } + inputBuilder.append(charI); + if (charI.equals("{") || charI.equals("[")) { + tabCount++; + if (String.valueOf(inputChar[i + 1]).equals("]") || String.valueOf(inputChar[i + 1]).equals("}")) { + continue; + } + inputBuilder.append(simpleNewLine(tabCount)); + } + if (charI.equals(",")) { + inputBuilder.append(simpleNewLine(tabCount)); + } + } + return inputBuilder.toString(); + } + + private static String simpleNewLine(int tabCount) { + StringBuilder builder = new StringBuilder(); + builder.append("\n"); + for (int j = 0; j < tabCount; j++) { + builder.append(" "); + } + return builder.toString(); + } + + public static void main(String[] args) throws Exception { + String data = ""; + data += "{ "; + data += " \"EAI_UJSON2DEPTHEXT_REQ1\":{ "; + data += " \"abc\":\"cba \", "; + data += " \"grid1\":[ "; + data += " { "; + data += " \"long1\":1, "; + data += " \"data2\":\" \", "; + data += " \"grid2\":[ "; + data += " { "; + data += " \"data3\":\"12345\", "; + data += " \"big4\":14.00000 "; + data += " }, "; + data += " { "; + data += " \"data3\":\"13 \", "; + data += " \"big4\":14.00001 "; + data += " } "; + data += " ] "; + data += " }, "; + data += " { "; + data += " \"long1\":10000, "; + data += " \"data2\":\" \", "; + data += " \"grid2\":[ "; + data += " { "; + data += " \"data3\":\"23 \", "; + data += " \"big4\":24.00000 "; + data += " } "; + data += " ] "; + data += " }, "; + data += " { "; + data += " \"long1\":1000000000, "; + data += " \"data2\":\" \", "; + data += " \"grid2\":[ "; + data += " { "; + data += " \"data3\":\"33 \", "; + data += " \"big4\":1 "; + data += " }, "; + data += " { "; + data += " \"data3\":\" \", "; + data += " \"big4\":1234567890.00034 "; + data += " }, "; + data += " { "; + data += " \"data3\":\"35 \", "; + data += " \"big4\":0.00036 "; + data += " } "; + data += " ] "; + data += " } "; + data += " ], "; + data += " \"abcd\":\"123\", "; + data += " \"grid3\":[ "; + data += " { "; + data += " \"long1\":1, "; + data += " \"data2\":\" \", "; + data += " \"grid4\":[ "; + data += " { "; + data += " \"data5\":\"00023\", "; + data += " \"big6\":24 "; + data += " } "; + data += " ] "; + data += " }, "; + data += " { "; + data += " \"long1\":1000000000, "; + data += " \"data2\":\" \", "; + data += " \"grid4\":[ "; + data += " { "; + data += " \"data5\":\"00033\", "; + data += " \"big6\":0.0 "; + data += " }, "; + data += " { "; + data += " \"data5\":\" \", "; + data += " \"big6\":123456789012345 "; + data += " }, "; + data += " { "; + data += " \"data5\":\"00035\", "; + data += " \"big6\":900000003600011 "; + data += " } "; + data += " ] "; + data += " } "; + data += " ] "; + data += " } "; + data += "} "; + data = "{\"EAI_UJSON2DEPTHEXT_REQ1\":{\"abc\":\"cba \",\"grid1\":[{\"long1\":1,\"data2\":\" \",\"grid2\":[{\"data3\":\"12345\",\"big4\":\"14.00000\"},{\"data3\":\"13 \",\"big4\":\"14.00001\"}]},{\"long1\":10000,\"data2\":\" \",\"grid2\":[{\"data3\":\"23 \",\"big4\":\"24.00000\"}]},{\"long1\":1000000000,\"data2\":\" \",\"grid2\":[{\"data3\":\"33 \",\"big4\":\"0.00000\"},{\"data3\":\" \",\"big4\":\"0.00034\"},{\"data3\":\"35 \",\"big4\":\"0.00036\"}]}],\"abcd\":\"123\",\"grid3\":[{\"long1\":1,\"data2\":\" \",\"grid4\":[{\"data5\":\"00023\",\"big6\":\"24\"}]},{\"long1\":1000000000,\"data2\":\" \",\"grid4\":[{\"data5\":\"00033\",\"big6\":\"0\"},{\"data5\":\" \",\"big6\":\"34\"},{\"data5\":\"00035\",\"big6\":\"900000003600011\"}]}]}}"; + + System.out.println(JsonBeatiUtil.SimpleBeautiful(data)); + } + +} diff --git a/src/main/java/com/eactive/eai/util/JsonPathUtil.java b/src/main/java/com/eactive/eai/util/JsonPathUtil.java new file mode 100644 index 0000000..0f3e9b9 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/JsonPathUtil.java @@ -0,0 +1,125 @@ +package com.eactive.eai.util; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +// TOUSE +// kbbank 어댑터에서 업무데이터의 암호화 필드에 대한 암복호화시 +// 해당 필드에 대한 get/set 을 수행 +public class JsonPathUtil { + private JsonPathUtil() { + + } + + private static final ObjectMapper objectMapper = new ObjectMapper(); + + // 특정 경로의 값을 설정하는 함수 + public static String setValueAtPath(String jsonString, String path, String newValue, boolean isPretty) { + try { + // JSON 문자열을 JsonNode 객체로 파싱 + JsonNode rootNode = objectMapper.readTree(jsonString); + + // 경로에 해당하는 부모 노드를 가져옴 + JsonNode parentNode = getParentNode(rootNode, getParentPath(path)); + + // 경로의 마지막 노드 이름 또는 배열 인덱스 추출 + String fieldNameOrIndex = getFieldName(path); + + // 배열 또는 객체에서 값을 설정 + if (parentNode.isArray()) { + ((ArrayNode) parentNode).set(Integer.parseInt(fieldNameOrIndex), objectMapper.convertValue(newValue, JsonNode.class)); + } else if (parentNode.isObject()) { + ((ObjectNode) parentNode).put(fieldNameOrIndex, newValue); + } + + // 수정된 JSON 문자열 반환 + if(isPretty) + return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode); + else + return objectMapper.writeValueAsString(rootNode); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + // 특정 경로의 값을 가져오는 함수 + public static String getValueAtPath(String jsonString, String path) { + try { + // JSON 문자열을 JsonNode 객체로 파싱 + JsonNode rootNode = objectMapper.readTree(jsonString); + + // 경로에 해당하는 노드의 값을 반환 + JsonNode resultNode = getNodeAtPath(rootNode, path); + return resultNode != null ? resultNode.asText() : null; + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + // 경로에서 부모 경로를 추출하는 유틸리티 함수 + private static String getParentPath(String path) { + int lastSlashIndex = path.lastIndexOf('/'); + return lastSlashIndex == 0 ? "/" : path.substring(0, lastSlashIndex); + } + + // 경로에서 필드 이름 또는 배열 인덱스를 추출하는 유틸리티 함수 + private static String getFieldName(String path) { + int lastSlashIndex = path.lastIndexOf('/'); + return path.substring(lastSlashIndex + 1); + } + + // 특정 경로에 해당하는 부모 노드를 가져오는 유틸리티 함수 + private static JsonNode getParentNode(JsonNode rootNode, String parentPath) { + return getNodeAtPath(rootNode, parentPath); + } + + // 특정 경로에 해당하는 노드를 가져오는 유틸리티 함수 + private static JsonNode getNodeAtPath(JsonNode rootNode, String path) { + String[] tokens = path.split("/"); + JsonNode currentNode = rootNode; + + for (String token : tokens) { + if (token.isEmpty()) continue; + + if (token.matches("\\d+")) { + // 배열 인덱스 처리 + currentNode = currentNode.get(Integer.parseInt(token)); + } else { + // 객체 필드 처리 + currentNode = currentNode.get(token); + } + + if (currentNode == null) { + return null; // 경로가 존재하지 않음 + } + } + return currentNode; + } + + public static void main(String[] args) { + String jsonString = "{ \"person\": { \"name\": \"John\", \"age\": 30, \"groups\": [ { \"id\": 1, \"name\": \"Group A\" }, { \"id\": 2, \"name\": \"Group B\" }, { \"id\": 3, \"name\": \"Group C\" } ] } }"; + + System.out.println("Source JSON: \n" + jsonString); + + // 경로를 사용하여 값 가져오기 (반복되는 그룹 포함) + String getPath = "/person/groups/1/name"; + String secondGroupName = getValueAtPath(jsonString, getPath); + System.out.println("getPath: " + getPath + " -> " + secondGroupName); + + // 경로를 사용하여 값 설정하기 (반복되는 그룹 포함) 및 Pretty 출력 + String putPath = "/person/groups/2/name"; + String updatedJsonString = setValueAtPath(jsonString, putPath, "Group Z", true); + System.out.println("putPath: " + putPath); + System.out.println("Updated JSON (Pretty): \n" + updatedJsonString); + + getPath = "/person/name"; + System.out.println("getPath: " + getPath + " -> " + getValueAtPath(jsonString, getPath)); + getPath = "/person/age"; + System.out.println("getPath: " + getPath + " -> " + getValueAtPath(jsonString, getPath)); + } +} diff --git a/src/main/java/com/eactive/eai/util/PropertiesUtil.java b/src/main/java/com/eactive/eai/util/PropertiesUtil.java new file mode 100644 index 0000000..43cbd1d --- /dev/null +++ b/src/main/java/com/eactive/eai/util/PropertiesUtil.java @@ -0,0 +1,19 @@ +package com.eactive.eai.util; + +import java.util.Properties; + +public class PropertiesUtil { + /** + * Copies a property from source to destination if the key exists in source. + * + * @param source The source properties. + * @param destination The destination properties. + * @param key The key to check and copy. + */ + public static void copyPropertyIfPresent(Properties source, Properties destination, Object key) { + Object value = source.get(key); + if (value != null) { + destination.put(key, value); + } + } +} diff --git a/src/main/java/com/eactive/eai/util/ServerPingUtil.java b/src/main/java/com/eactive/eai/util/ServerPingUtil.java new file mode 100644 index 0000000..b4b3fb4 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/ServerPingUtil.java @@ -0,0 +1,60 @@ +package com.eactive.eai.util; + +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.common.server.EAIServerVO; +import com.eactive.eai.common.util.Logger; + +import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Socket; + +public class ServerPingUtil { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static boolean pingHost(String host, int port, int timeout) { + try (Socket socket = new Socket()) { + socket.connect(new InetSocketAddress(host, port), timeout); + return true; + } catch (IOException e) { + logger.warn(String.format("ServerPingUtil] pingHost (host= %s, port=%d) Failed.", host, port)); + return false; // Either timeout or unreachable or failed DNS lookup. + } + } + + public static boolean pingHost(String instId) { + boolean isAlive = true; + EAIServerManager mgr = EAIServerManager.getInstance(); + EAIServerVO serverVo = mgr.getEAIServer(instId); + + // if not found, server is invalid + if (serverVo == null) { + logger.warn("ServerPingUtil] invalid eLink instId = " + instId); + return false; + } + + String address = serverVo.getAddress(); + int port = Integer.parseInt(serverVo.getPort()); + isAlive = pingHost(address, port, 3 * 1000); + return isAlive; + } + +// public static void main(String[] argv) throws Exception { +// String host = "localhost"; +// int port = 10310; +// int timeout = 3; +// +// boolean isAlive = pingHost(host, port, timeout); +// System.out.println(">> Server Ping Test "); +// System.out.println(String.format("ServerPingUtil] pingHost (host= %s, port=%d) => %s",host, port, isAlive)); +// +// HashMap map = new HashMap(); +// +// Integer count = map.get("test"); +// System.out.println(count); +// +// map.put("test", 10); +// count = map.get("test"); +// System.out.println(count); +// +// } +} diff --git a/src/main/java/com/eactive/eai/util/SimHeaderUtil.java b/src/main/java/com/eactive/eai/util/SimHeaderUtil.java new file mode 100644 index 0000000..555f6b0 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/SimHeaderUtil.java @@ -0,0 +1,59 @@ +package com.eactive.eai.util; + +import org.apache.commons.lang3.StringUtils; + +import com.eactive.eai.adapter.socket2.protocol.ByteMessage; +import com.eactive.eai.inbound.processor.ProcessVO; + +public class SimHeaderUtil { + public static int EAISVCCD_LEN = 30;// eaisvccd + public static int BZWKSVCKEY_LEN = 40;// 업무추출키 + public static int INSTITUTIONCODE_LEN = 10;// 기관코드 + public static int TEMP_LEN = 20;// 임시 + + // TODO : check encoding or remove this class logic + private static byte[] toByteArray(Object obj) { + byte[] data = null; + if (obj instanceof byte[]) { + data = (byte[]) obj; + } else if (obj instanceof String) { + data = ((String) obj).getBytes(); + } + return data; + } + + public static byte[] addSimHeader(String eaiSvcCd, String InstitutionCode, Object obj) { + byte[] data = toByteArray(obj); + + ByteMessage bm = new ByteMessage(); + bm.append(StringUtils.rightPad(eaiSvcCd, EAISVCCD_LEN)); + bm.append(StringUtils.rightPad("", BZWKSVCKEY_LEN)); + bm.append(StringUtils.rightPad(InstitutionCode, INSTITUTIONCODE_LEN)); + bm.append(StringUtils.rightPad("", TEMP_LEN)); + bm.append(data); + return bm.getBytes(); + } + + // 시뮬레이터에서 온 데이터중 SIM Header 를 vo에 셋팅 + public static ProcessVO getSimHeader(ProcessVO vo, byte[] obj) throws Exception { + byte[] data = toByteArray(obj); + ByteMessage bm = new ByteMessage(data); + String eaiSvcCdKey = new String(bm.getBytes(0, EAISVCCD_LEN)); + String simKey = new String(bm.getBytes(EAISVCCD_LEN, BZWKSVCKEY_LEN)); + String instcdKey = new String(bm.getBytes(EAISVCCD_LEN + BZWKSVCKEY_LEN, INSTITUTIONCODE_LEN)); + String tempKey = new String(bm.getBytes(EAISVCCD_LEN + BZWKSVCKEY_LEN + INSTITUTIONCODE_LEN, TEMP_LEN)); + + vo.setSelectedKey(simKey.trim()); + vo.setInAdapterOsidInstiNo(instcdKey.trim()); + vo.setEaiSvcCd(eaiSvcCdKey.trim()); + + return vo; + } + + // 시뮬레이터에서 온 데이터중 SIM Header제거 하고 데이터만 추출 + public static byte[] getSimData(Object obj) { + byte[] data = toByteArray(obj); + ByteMessage bm = new ByteMessage((byte[]) data); + return bm.getBytes(EAISVCCD_LEN + BZWKSVCKEY_LEN + INSTITUTIONCODE_LEN + TEMP_LEN); + } +} diff --git a/src/main/java/com/eactive/eai/util/TestModeChecker.java b/src/main/java/com/eactive/eai/util/TestModeChecker.java new file mode 100644 index 0000000..96bd8cb --- /dev/null +++ b/src/main/java/com/eactive/eai/util/TestModeChecker.java @@ -0,0 +1,14 @@ +package com.eactive.eai.util; + +import org.apache.commons.lang.StringUtils; + +public class TestModeChecker { + + private TestModeChecker() { + + } + + public static boolean isTestMode() { + return StringUtils.equals(System.getProperty("use.test.trust", "n"), "y"); + } +} diff --git a/src/main/java/com/eactive/eai/util/UrlUtil.java b/src/main/java/com/eactive/eai/util/UrlUtil.java new file mode 100644 index 0000000..b5829c7 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/UrlUtil.java @@ -0,0 +1,27 @@ +package com.eactive.eai.util; + +import java.net.MalformedURLException; +import java.net.URL; + +public class UrlUtil { + public static String replaceIpAddress(String httpUrl, String newIp, String newPort) { + try { + URL url = new URL(httpUrl); + String host = url.getHost(); + int port = url.getPort(); + String newUrl = ""; + if (port == -1) { + newUrl = httpUrl.replace(host, newIp + ":" + newPort); + } else { + newUrl = httpUrl.replace(host + ":" + port, newIp + ":" + newPort); + } + return newUrl; + } catch (MalformedURLException e) { + return httpUrl; + } + } +// public static void main(String[] args) throws Exception { +// System.out.println( +// replaceIpAddress("http://i-ada.postbank.go.kr:123/web/jmd/ONL/EAI/abcd", "192.168.0.1", "5555")); +// } +} diff --git a/src/main/java/com/eactive/eai/util/json/JsonPathsTransform.java b/src/main/java/com/eactive/eai/util/json/JsonPathsTransform.java new file mode 100644 index 0000000..dca2a3d --- /dev/null +++ b/src/main/java/com/eactive/eai/util/json/JsonPathsTransform.java @@ -0,0 +1,75 @@ +package com.eactive.eai.util.json; + +import java.util.Map; + +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.util.json.transformer.ValueTransformer; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; +import com.jayway.jsonpath.spi.json.JacksonJsonNodeJsonProvider; +import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider; + +public class JsonPathsTransform { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + private static final ObjectMapper objectMapper = new ObjectMapper(); + + public static String modifyValuesAtPaths(String jsonString, + Map> pathTransformerMap, boolean isPretty) { + String path = null; + +// DocumentContext documentContext = JsonPath.parse(jsonString); + + // 변경헤도 별차이가 없음. + Configuration conf = Configuration.builder() + .jsonProvider(new JacksonJsonNodeJsonProvider()) + .mappingProvider(new JacksonMappingProvider()) + .build(); + DocumentContext documentContext = JsonPath.using(conf).parse(jsonString); + + for (Map.Entry> entry : pathTransformerMap.entrySet()) { + try { + path = entry.getKey(); + ValueTransformer transformer = entry.getValue(); + + // 현재 값 추출 + T currentValue = (T) documentContext.read(path, String.class); + + // 변환기 통해 새 값 생성 + R newValue = transformer.transform(currentValue); + // 새로운 값으로 설정 + documentContext.set(path, newValue); + + if (logger.isDebug()) { + // FIXME : kbank - 로그내용 수정 + String encLog = transformer.getClass().getName() + " : " + + String.format("path=%s, orgText[%s] plain[%s] newText[%s]", path, currentValue, + transformer.getProperty("PLAIN_VALUE"), newValue); + System.out.println(encLog); + logger.debug(encLog); + } + } catch (Exception e) { + logger.error("SKIP ERROR jsonpath=" + path, e); + } + } + return printJson(documentContext.jsonString(), isPretty); + + } + + // JSON을 pretty하게 출력하는 메서드 + private static String printJson(String jsonString, boolean isPretty) { + try { + Object jsonObject = objectMapper.readValue(jsonString, Object.class); + if (isPretty) { + return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonObject); + } else { + return objectMapper.writeValueAsString(jsonObject); + } + } catch (JsonProcessingException e) { + return jsonString; + } + } + +} diff --git a/src/main/java/com/eactive/eai/util/json/JsonSimplePathsTransform.java b/src/main/java/com/eactive/eai/util/json/JsonSimplePathsTransform.java new file mode 100644 index 0000000..5e16ed9 --- /dev/null +++ b/src/main/java/com/eactive/eai/util/json/JsonSimplePathsTransform.java @@ -0,0 +1,108 @@ +package com.eactive.eai.util.json; + +import java.util.Map; + +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.util.json.transformer.ValueTransformer; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; +import com.fasterxml.jackson.databind.node.ObjectNode; + +public class JsonSimplePathsTransform { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + private static final ObjectMapper objectMapper = new ObjectMapper(); + + public static String modifyValuesAtPaths(String jsonString, + Map> pathTransformerMap, boolean isPretty) { + try { + JsonNode rootNode = objectMapper.readTree(jsonString); + + for (Map.Entry> entry : pathTransformerMap.entrySet()) { + String path = entry.getKey(); + ValueTransformer transformer = entry.getValue(); + + JsonNode currentNode = getNodeAtPath(rootNode, path); + if (currentNode != null && currentNode.isValueNode()) { + T currentValue = extractValue(currentNode); + R newValue = transformer.transform(currentValue); + + if(logger.isDebug()) { + // FIXME : kbank - 로그내용 수정 + String encLog = transformer.getClass().getName() +" : "+ String.format("path=%s, orgText[%s] plain[%s] newText[%s]", path, currentValue, transformer.getProperty("PLAIN_VALUE"), newValue); + System.out.println(encLog); + logger.debug(encLog); + } + setNodeValue(getParentNode(rootNode, getParentPath(path)), getFieldName(path), newValue); + } + } + if(isPretty) { + return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(rootNode); + } + else { + return objectMapper.writeValueAsString(rootNode); + } + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + private static T extractValue(JsonNode node) { + if (node.isTextual()) { + return (T) node.asText(); + } else if (node.isInt()) { + return (T) (Integer) node.asInt(); + } else if (node.isDouble()) { + return (T) (Double) node.asDouble(); + } else if (node.isBoolean()) { + return (T) (Boolean) node.asBoolean(); + } else { + return (T) node.asText(); + } + } + + private static void setNodeValue(JsonNode parentNode, String fieldNameOrIndex, R newValue) { + if (parentNode.isArray()) { + ((ArrayNode) parentNode).set(Integer.parseInt(fieldNameOrIndex), + objectMapper.convertValue(newValue, JsonNode.class)); + } else if (parentNode.isObject()) { + ((ObjectNode) parentNode).set(fieldNameOrIndex, objectMapper.convertValue(newValue, JsonNode.class)); + } + } + + private static String getParentPath(String path) { + int lastSlashIndex = path.lastIndexOf('/'); + return lastSlashIndex == 0 ? "/" : path.substring(0, lastSlashIndex); + } + + private static String getFieldName(String path) { + int lastSlashIndex = path.lastIndexOf('/'); + return path.substring(lastSlashIndex + 1); + } + + private static JsonNode getParentNode(JsonNode rootNode, String parentPath) { + return getNodeAtPath(rootNode, parentPath); + } + + private static JsonNode getNodeAtPath(JsonNode rootNode, String path) { + String[] tokens = path.split("/"); + JsonNode currentNode = rootNode; + + for (String token : tokens) { + if (token.isEmpty()) + continue; + + if (token.matches("\\d+")) { + currentNode = currentNode.get(Integer.parseInt(token)); + } else { + currentNode = currentNode.get(token); + } + + if (currentNode == null) { + return null; + } + } + return currentNode; + } +} diff --git a/src/main/java/com/eactive/eai/util/json/transformer/CustomValueTransformer.java b/src/main/java/com/eactive/eai/util/json/transformer/CustomValueTransformer.java new file mode 100644 index 0000000..f0e265a --- /dev/null +++ b/src/main/java/com/eactive/eai/util/json/transformer/CustomValueTransformer.java @@ -0,0 +1,28 @@ +package com.eactive.eai.util.json.transformer; + +import java.util.HashMap; +import java.util.Map; + +public class CustomValueTransformer implements ValueTransformer { + + private final Map properties = new HashMap<>(); + + @Override + public void setProperty(String propertyName, Object value) { + properties.put(propertyName, value); + } + @Override + public String getProperty(String propertyName) { + return (String) properties.get(propertyName); + } + + @Override + public String transform(String value) { + // 예: 변환할 때 "prefix"와 "suffix" 속성을 사용 + String prefix = (String) properties.getOrDefault("PREFIX", ""); + String suffix = (String) properties.getOrDefault("SUFFIX", ""); + properties.put("PLAIN_VALUE", value); + return prefix + value + suffix; + } + +} diff --git a/src/main/java/com/eactive/eai/util/json/transformer/ValueTransformer.java b/src/main/java/com/eactive/eai/util/json/transformer/ValueTransformer.java new file mode 100644 index 0000000..cbc3e9f --- /dev/null +++ b/src/main/java/com/eactive/eai/util/json/transformer/ValueTransformer.java @@ -0,0 +1,7 @@ +package com.eactive.eai.util.json.transformer; + +public interface ValueTransformer { + void setProperty(String propertyName, Object value); + String getProperty(String propertyName); + R transform(T value) throws Exception; +} diff --git a/src/main/java/com/eactive/kakao/rolling/CurrentCommitId.java b/src/main/java/com/eactive/kakao/rolling/CurrentCommitId.java new file mode 100644 index 0000000..a0fcaac --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/CurrentCommitId.java @@ -0,0 +1,45 @@ +package com.eactive.kakao.rolling; + +import java.time.LocalDateTime; + +import javax.persistence.CascadeType; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.OneToOne; +import javax.persistence.Table; + +import org.hibernate.annotations.Comment; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; + +import com.eactive.eai.data.entity.AbstractEntity; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) + +@Entity +@Table(name = "current_commit_id") +@org.hibernate.annotations.Table(appliesTo = "current_commit_id", comment = "현재 Commit id를 저장") +public class CurrentCommitId extends AbstractEntity { + + private static final long serialVersionUID = 1L; + + public static final Long CURRENT_COMMIT_ID_ID = 1l; + + @Id + private Long id; + + @OneToOne(cascade = CascadeType.PERSIST) + @Comment("현재 Commit id") + private RollingSuffix rollingSuffix; + + @CreatedDate + private LocalDateTime createdDate; + + @LastModifiedDate + private LocalDateTime lastModifiedDate; + +} diff --git a/src/main/java/com/eactive/kakao/rolling/CurrentCommitIdRepository.java b/src/main/java/com/eactive/kakao/rolling/CurrentCommitIdRepository.java new file mode 100644 index 0000000..98c0302 --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/CurrentCommitIdRepository.java @@ -0,0 +1,7 @@ +package com.eactive.kakao.rolling; + +import com.eactive.eai.data.jpa.BaseRepository; + +public interface CurrentCommitIdRepository extends BaseRepository { + +} diff --git a/src/main/java/com/eactive/kakao/rolling/CurrentCommitIdService.java b/src/main/java/com/eactive/kakao/rolling/CurrentCommitIdService.java new file mode 100644 index 0000000..8120eab --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/CurrentCommitIdService.java @@ -0,0 +1,32 @@ +package com.eactive.kakao.rolling; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.data.jpa.AbstractDataService; + +@Service +@Transactional +public class CurrentCommitIdService extends AbstractDataService { + + @Value("#{systemEnvironment['COMMIT_ID'] ?: systemProperties['COMMIT_ID']}") + private String systemCommitId; + + public CurrentCommitId currentCommitId() { + return repository.getReferenceById(CurrentCommitId.CURRENT_COMMIT_ID_ID); + } + + public String getCurrentSuffix() { + return currentCommitId().getRollingSuffix().getSuffix(); + } + + public String getCurrentCommitId() { + return currentCommitId().getRollingSuffix().getCommitId(); + } + + public String getSystemCommitId() { + return systemCommitId; + } + +} diff --git a/src/main/java/com/eactive/kakao/rolling/RollingSuffix.java b/src/main/java/com/eactive/kakao/rolling/RollingSuffix.java new file mode 100644 index 0000000..1f54ef9 --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/RollingSuffix.java @@ -0,0 +1,43 @@ +package com.eactive.kakao.rolling; + +import java.time.LocalDateTime; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.TableGenerator; + +import org.hibernate.annotations.Comment; +import org.springframework.data.annotation.CreatedDate; + +import com.eactive.eai.data.entity.AbstractEntity; + +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Data +@EqualsAndHashCode(onlyExplicitlyIncluded = true, callSuper = true) + +@Entity +@Table(name = "rolling_suffix") +@org.hibernate.annotations.Table(appliesTo = "rolling_suffix", comment = "현재 commit id의 suffix를 매핑") +public class RollingSuffix extends AbstractEntity { + + private static final long serialVersionUID = 1L; + + @Id + @TableGenerator(name = "RollingSuffix", table = "TSEAISQ01", initialValue = 1, allocationSize = 1) + @GeneratedValue(strategy = GenerationType.TABLE, generator = "RollingSuffix") + private Long id; + + private String commitId; + + @Comment("테이블 suffix") + private String suffix; + + @CreatedDate + private LocalDateTime createdDate; + +} diff --git a/src/main/java/com/eactive/kakao/rolling/RollingSuffixRepository.java b/src/main/java/com/eactive/kakao/rolling/RollingSuffixRepository.java new file mode 100644 index 0000000..d34b1ef --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/RollingSuffixRepository.java @@ -0,0 +1,13 @@ +package com.eactive.kakao.rolling; + +import java.util.Optional; + +import org.springframework.data.querydsl.QuerydslPredicateExecutor; + +import com.eactive.eai.data.jpa.BaseRepository; + +public interface RollingSuffixRepository + extends BaseRepository, QuerydslPredicateExecutor { + + Optional findTopByOrderByIdDesc(); +} diff --git a/src/main/java/com/eactive/kakao/rolling/RollingSuffixService.java b/src/main/java/com/eactive/kakao/rolling/RollingSuffixService.java new file mode 100644 index 0000000..06512a3 --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/RollingSuffixService.java @@ -0,0 +1,63 @@ +package com.eactive.kakao.rolling; + +import javax.persistence.EntityNotFoundException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.data.jpa.AbstractDataService; + +@Service +@Transactional +public class RollingSuffixService extends AbstractDataService { + + @Autowired + private CurrentCommitIdRepository currentCommitIdRepository; + + public String getCurrentSuffixByCommitId(String currentCommitId) { + return repository + .findOne(QRollingSuffix.rollingSuffix.commitId.eq(currentCommitId)) + .map(r -> r.getSuffix()) + .orElseThrow(() -> new EntityNotFoundException("commit id를 찾을 수 없습니다 : " + currentCommitId)); + } + + public void insertRollingSuffixAndUpdateCurrentCommitId(String newCommitId) { + RollingSuffix newRollingSuffix = createNewRollingSuffix(newCommitId); + RollingSuffix savedRollingSuffix = repository.save(newRollingSuffix); + updateCurrentCommitId(savedRollingSuffix); + } + + private RollingSuffix createNewRollingSuffix(String commitId) { + RollingSuffix lastRollingSuffix = repository.findTopByOrderByIdDesc().orElse(new RollingSuffix()); + String newSuffix = calculateNextSuffix(lastRollingSuffix.getSuffix()); + + RollingSuffix newRollingSuffix = new RollingSuffix(); + newRollingSuffix.setSuffix(newSuffix); + newRollingSuffix.setCommitId(commitId); + return newRollingSuffix; + } + + private void updateCurrentCommitId(RollingSuffix rollingSuffix) { + CurrentCommitId currentCommitId = currentCommitIdRepository.findById(CurrentCommitId.CURRENT_COMMIT_ID_ID) + .orElseThrow(() -> new RuntimeException("CurrentCommitId not found")); + currentCommitId.setRollingSuffix(rollingSuffix); + currentCommitIdRepository.save(currentCommitId); + } + + private String calculateNextSuffix(String lastSuffix) { + int suffixNumber = (lastSuffix == null || lastSuffix.isEmpty()) ? 0 : Integer.parseInt(lastSuffix.replace("_", "")); + return String.format("_%02d", (suffixNumber % 5) + 1); + } + + public String insertRollingSuffix(String newCommitId) { + RollingSuffix newRollingSuffix = createNewRollingSuffix(newCommitId); + return repository.save(newRollingSuffix).getSuffix(); + } + + public void changeCurrentCommitId(String commitId) { + RollingSuffix targetRollingSuffix = repository.findOne(QRollingSuffix.rollingSuffix.commitId.eq(commitId)) + .orElseThrow(() -> new EntityNotFoundException("RollingSuffix not found with commitId: " + commitId)); + updateCurrentCommitId(targetRollingSuffix); + } +} diff --git a/src/main/java/com/eactive/kakao/rolling/RollingTableInterceptor.java b/src/main/java/com/eactive/kakao/rolling/RollingTableInterceptor.java new file mode 100644 index 0000000..a418695 --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/RollingTableInterceptor.java @@ -0,0 +1,12 @@ +package com.eactive.kakao.rolling; + +import org.hibernate.Interceptor; + +public interface RollingTableInterceptor extends Interceptor { + + @Override + default String onPrepareStatement(String sql) { + return sql; + } + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/kakao/rolling/TableSuffixResolver.java b/src/main/java/com/eactive/kakao/rolling/TableSuffixResolver.java new file mode 100644 index 0000000..7893562 --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/TableSuffixResolver.java @@ -0,0 +1,8 @@ +package com.eactive.kakao.rolling; + +@FunctionalInterface +public interface TableSuffixResolver { + + public String getCurrentSuffix(); + +} diff --git a/src/main/java/com/eactive/kakao/rolling/impl/RollingTableInterceptorImpl.java b/src/main/java/com/eactive/kakao/rolling/impl/RollingTableInterceptorImpl.java new file mode 100644 index 0000000..3429c6c --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/impl/RollingTableInterceptorImpl.java @@ -0,0 +1,39 @@ +package com.eactive.kakao.rolling.impl; + +import org.apache.commons.lang3.StringUtils; +import org.hibernate.EmptyInterceptor; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; + +import com.eactive.kakao.rolling.RollingTableInterceptor; +import com.eactive.kakao.rolling.TableSuffixResolver; + +public class RollingTableInterceptorImpl extends EmptyInterceptor implements RollingTableInterceptor { + + private static final long serialVersionUID = 1L; + + protected static final String[] TARGET_TABLE_NAMES = new String[] { "tseaihe01", "tseaihe02", "tseaims02", + "tseaifr01", "tseaifr03", "tseaihs04", "tseaihs05", "tseaifr06", "tseaitr07", "tseaitr08", "tseaitr01", + "tseaitr02", "tseaitr03", "tseaihs14", "tseaihs15" }; + + @Lazy + @Autowired + private transient TableSuffixResolver tableSuffixResolver; + + @Override + public String onPrepareStatement(String sql) { + + if (!StringUtils.containsAny(sql, TARGET_TABLE_NAMES)) { + return sql; + } + + String currentSuffix = tableSuffixResolver.getCurrentSuffix(); + for (String tableName : TARGET_TABLE_NAMES) { + if (StringUtils.contains(sql, tableName)) { + sql = StringUtils.replace(sql, tableName, tableName + currentSuffix); + } + } + return sql; + } + +} diff --git a/src/main/java/com/eactive/kakao/rolling/impl/TableSuffixResolverImpl.java b/src/main/java/com/eactive/kakao/rolling/impl/TableSuffixResolverImpl.java new file mode 100644 index 0000000..72b51eb --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/impl/TableSuffixResolverImpl.java @@ -0,0 +1,32 @@ +package com.eactive.kakao.rolling.impl; + +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; + +import com.eactive.kakao.rolling.CurrentCommitIdService; +import com.eactive.kakao.rolling.RollingSuffixService; +import com.eactive.kakao.rolling.TableSuffixResolver; + +public class TableSuffixResolverImpl implements TableSuffixResolver { + + private String currentSuffix; + + @Autowired + private RollingSuffixService rollingSuffixService; + + @Autowired + private CurrentCommitIdService currentCommitIdService; + + @PostConstruct + public void init() { + String systemCommitId = currentCommitIdService.getSystemCommitId(); + currentSuffix = rollingSuffixService.getCurrentSuffixByCommitId(systemCommitId); + } + + @Override + public String getCurrentSuffix() { + return currentSuffix; + } + +} \ No newline at end of file diff --git a/src/main/java/com/eactive/kakao/rolling/servlet/RollingServlet.java b/src/main/java/com/eactive/kakao/rolling/servlet/RollingServlet.java new file mode 100644 index 0000000..47aa661 --- /dev/null +++ b/src/main/java/com/eactive/kakao/rolling/servlet/RollingServlet.java @@ -0,0 +1,58 @@ +package com.eactive.kakao.rolling.servlet; + +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; +import com.eactive.kakao.rolling.CurrentCommitIdService; +import com.eactive.kakao.rolling.TableSuffixResolver; + +public class RollingServlet extends HttpServlet { + static final SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String command = request.getContext(); + if (command.lastIndexOf('/') == -1) { + command = ""; + } else { + command = command.substring(command.indexOf('/')+1); + } + String result = ""; + + try { + if (command == null || "".equals(command) || "commitid".equals(command)) { + result = getCommitId(); + } else if ("suffix".equals(command)) { + result = getSuffix(); + } else { + response.setResponseCode(404); + return; + } + } catch(Throwable e) { + result = "{ \"error\" : \"" + e.getMessage() + "\"}"; + } + + response.setContentType("application/json;charset=utf-8"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + private String getCommitId() throws Exception { + CurrentCommitIdService service = ApplicationContextProvider.getContext().getBean(CurrentCommitIdService.class); + String commitId = service.getSystemCommitId(); + + StringBuffer sb = new StringBuffer(); + sb.append("{\"commitId\" : \"").append(commitId).append("\"}"); + return sb.toString(); + } + private String getSuffix() throws Exception { + TableSuffixResolver service = ApplicationContextProvider.getContext().getBean(TableSuffixResolver.class); + String suffix = service.getCurrentSuffix(); + StringBuffer sb = new StringBuffer(); + sb.append("{\"suffix\" : \"").append(suffix).append("\"}"); + return sb.toString(); + } +} diff --git a/src/main/java/com/ext/eai/agent/fds/ReloadFDSCommand.java b/src/main/java/com/ext/eai/agent/fds/ReloadFDSCommand.java new file mode 100644 index 0000000..246682c --- /dev/null +++ b/src/main/java/com/ext/eai/agent/fds/ReloadFDSCommand.java @@ -0,0 +1,73 @@ +//package com.ext.eai.agent.fds; +// +//import com.eactive.eai.agent.command.Command; +//import com.eactive.eai.agent.command.CommandException; +//import com.eactive.eai.common.util.Logger; +//import com.ext.eai.fds.FDSManager; +// +//public class ReloadFDSCommand extends Command +//{ +// /** +// * +// */ +// private static final long serialVersionUID = 1L; +// +// /** +// * 1. 기능 : ReloadFDSCommand 생성자 +// * 2. 처리 개요 : +// * 3. 주의사항 +// * +// * @param +// * @return +// * @exception +// **/ +// public ReloadFDSCommand() { +// super("ReloadFDSCommand"); +// } +// +// /** +// * 1. 기능 : FDSManager의 데이터를 DB로부터 Reload +// * 2. 처리 개요 : FDSManager의 reload메소드를 실행하여 DB로부터 Reload +// * 3. 주의사항 +// * +// * @param +// * @return +// * @exception CommandException +// **/ +// public Object execute() throws CommandException +// { +// Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); +// if (logger.isInfo()) logger.info(this.name + " is executed"); +// +// if( !(args instanceof String) ) { +// String rspErrorCode = "RECEAIMCM001"; +// String msg = makeException(rspErrorCode, null); +// if (logger.isError()) logger.error(msg); +// throw new CommandException(msg); +// } +// +// try{ +// FDSManager manager = FDSManager.getInstance(); +// String keyName = (String)args; +// if(keyName != null ){ +// if( "ALL".equals(keyName)){ +// manager.reload(); +// if(logger.isWarn()) +// logger.warn(this.name + "] 모든 정보가 Reload 되었습니다."); +// }else{ +// throw new Exception("not support args " + keyName ); +// } +// } +// +// if(logger.isWarn()) logger.warn(this.name + "] 모든 정보가 Reload 되었습니다."); +// }catch (Exception e){ +// String rspErrorCode = "RECEAIMCM002"; +// String msg = makeException(rspErrorCode, e); +// if (logger.isError()) logger.error(msg); +//// e.printStackTrace(); +// throw new CommandException(msg); +// } +// return "success"; +// } +// +//} diff --git a/src/main/java/com/ext/eai/agent/stdmessage/ReloadSTDMessageCommand.java b/src/main/java/com/ext/eai/agent/stdmessage/ReloadSTDMessageCommand.java new file mode 100644 index 0000000..130fbb0 --- /dev/null +++ b/src/main/java/com/ext/eai/agent/stdmessage/ReloadSTDMessageCommand.java @@ -0,0 +1,85 @@ +package com.ext.eai.agent.stdmessage; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.stdmessage.STDMessageManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadSTDMessageCommand extends Command +{ + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * 1. 기능 : ReloadSTDMessageCommand 생성자 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param + * @return + * @exception + **/ + public ReloadSTDMessageCommand() { + super("ReloadSTDMessageCommand"); + } + + /** + * 1. 기능 : STDMessageManager의 데이터를 DB로부터 Reload + * 2. 처리 개요 : STDMessageManager의 reload메소드를 실행하여 DB로부터 Reload + * 3. 주의사항 + * + * @param + * @return + * @exception CommandException + **/ + public Object execute() throws CommandException + { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) logger.info(this.name + " is executed"); + + if( !(args instanceof String) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) logger.error(msg); + throw new CommandException(msg); + } + + try{ + STDMessageManager manager = STDMessageManager.getInstance(); + + String keyName = (String)args; + + if(keyName != null ){ + if( "ALL".equals(keyName)){ + manager.reload(); + if(logger.isWarn()) + logger.warn(this.name + "] 모든 정보가 Reload 되었습니다."); + } + else { + manager.reload(keyName); + if(logger.isWarn()) + logger.warn(this.name + "] "+keyName+" 에 대한 정보가 Reload 되었습니다."); + } + } + }catch (Exception e){ + String rspErrorCode = "RECEAIMCM002"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) logger.error(msg); +// e.printStackTrace(); + throw new CommandException(msg); + } + return "success"; + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// Command command = new ReloadSTDMessageCommand(); +// command.setArgs("ALL"); +// AgentUtil.broadcast(command); +// } +} diff --git a/src/main/java/com/ext/eai/agent/stdmessage/ReloadSTDMessageListCommand.java b/src/main/java/com/ext/eai/agent/stdmessage/ReloadSTDMessageListCommand.java new file mode 100644 index 0000000..f3916d1 --- /dev/null +++ b/src/main/java/com/ext/eai/agent/stdmessage/ReloadSTDMessageListCommand.java @@ -0,0 +1,84 @@ +package com.ext.eai.agent.stdmessage; + +import java.util.Vector; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.stdmessage.STDMessageManager; +import com.eactive.eai.common.util.Logger; + +public class ReloadSTDMessageListCommand extends Command +{ + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * 1. 기능 : ReloadSTDMessageCommand 생성자 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param + * @return + * @exception + **/ + public ReloadSTDMessageListCommand() { + super("ReloadSTDMessageListCommand"); + } + + /** + * 1. 기능 : STDMessageManager의 데이터를 DB로부터 Reload + * 2. 처리 개요 : STDMessageManager의 reload메소드를 실행하여 DB로부터 Reload + * 3. 주의사항 + * + * @param + * @return + * @exception CommandException + **/ + public Object execute() throws CommandException + { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) logger.info(this.name + " is executed"); + + if( !(args instanceof Vector) ) { + String rspErrorCode = "RECEAIMCM001"; + String msg = makeException(rspErrorCode, null); + if (logger.isError()) logger.error(msg); + throw new CommandException(msg); + } + + try{ + STDMessageManager manager = STDMessageManager.getInstance(); + + Vector messageVt = (Vector)args; + String key = ""; + for(int i=0; i header = (Map)reqJson.get(FDSKeys.JSON.HEADER); +// Map systemHeader = (Map)header.get(FDSKeys.JSON.SYSTEM_HEADER); +// systemHeader.put(FDSKeys.JSON.FDS_MSG_TYPE_CODE, FDSKeys.FDS_MSG_TYPE_CODE.REQ ); +// if (logger.isDebug()){ +// logger.debug("fds send data = "+reqJson); +// } +// return reqJson; +// } +//} diff --git a/src/main/java/com/ext/eai/trace/TranManagerWrapper.java b/src/main/java/com/ext/eai/trace/TranManagerWrapper.java new file mode 100644 index 0000000..ff566a7 --- /dev/null +++ b/src/main/java/com/ext/eai/trace/TranManagerWrapper.java @@ -0,0 +1,72 @@ +package com.ext.eai.trace; + +import com.eactive.eai.common.message.EAIMessage; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; + +@Deprecated +public class TranManagerWrapper { + protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + public static String start1(EAIMessage eaiMsg){ + String traceGeneratorYn = PropManager.getInstance().getProperty("TRACE", "trace.generator.yn", "Y"); + if (!"Y".equals(traceGeneratorYn)){ + return null; + } + String json = getJSONString(eaiMsg); + logger.debug("TranManagerWrapper] start1 GUID["+eaiMsg.getMapper().getGuid(eaiMsg.getStandardMessage()) + + "."+eaiMsg.getMapper().getGuidSeq(eaiMsg.getStandardMessage()) + "]" + json); + return json; + } + public static String end1(EAIMessage eaiMsg){ + String traceGeneratorYn = PropManager.getInstance().getProperty("TRACE", "trace.generator.yn", "Y"); + if (!"Y".equals(traceGeneratorYn)){ + return null; + } + String json = getJSONString(eaiMsg); + logger.debug("TranManagerWrapper] end1 GUID["+eaiMsg.getMapper().getGuid(eaiMsg.getStandardMessage()) + + "."+eaiMsg.getMapper().getGuidSeq(eaiMsg.getStandardMessage()) + "]" + json); + return json; + } + public static String start2(EAIMessage eaiMsg){ + String traceGeneratorYn = PropManager.getInstance().getProperty("TRACE", "trace.generator.yn", "Y"); + if (!"Y".equals(traceGeneratorYn)){ + return null; + } + String json = getJSONString(eaiMsg); + logger.debug("TranManagerWrapper] start2 GUID["+eaiMsg.getMapper().getGuid(eaiMsg.getStandardMessage()) + + "."+eaiMsg.getMapper().getGuidSeq(eaiMsg.getStandardMessage()) + "]" + json); + return json; + } + public static String end2(EAIMessage eaiMsg){ + String traceGeneratorYn = PropManager.getInstance().getProperty("TRACE", "trace.generator.yn", "Y"); + if (!"Y".equals(traceGeneratorYn)){ + return null; + } + String json = getJSONString(eaiMsg); + logger.debug("TranManagerWrapper] end2 GUID["+eaiMsg.getMapper().getGuid(eaiMsg.getStandardMessage()) + + "."+eaiMsg.getMapper().getGuidSeq(eaiMsg.getStandardMessage()) + "]" + json); + return json; + } + private static String getJSONString(EAIMessage eaiMsg){ +// ExtMessage ext = eaiMsg.getExtMsg(); +// STDMessage std = (STDMessage)ext.getStdMessage(); +// Object message = ext.getBizData()[0]; +// String msg =""; +// if (message instanceof String){ +// msg =(String)message; +// }else if (message instanceof byte[]){ +// try { +// msg = new String((byte[])message,"utf-8"); +// } catch (UnsupportedEncodingException e) { +// e.printStackTrace(); +// } +// } +// return msg; + try { + return eaiMsg.getStandardMessage().getBizData(); + } catch (Exception e) { + logger.error(e); + return null; + } + } +} diff --git a/src/main/java/com/kbstar/eai/common/businessday/BusinessDayDAO.java b/src/main/java/com/kbstar/eai/common/businessday/BusinessDayDAO.java new file mode 100644 index 0000000..e75cdaa --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/businessday/BusinessDayDAO.java @@ -0,0 +1,101 @@ +package com.kbstar.eai.common.businessday; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import com.eactive.eai.common.dao.BaseDAO; +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.data.entity.onl.businessday.BusinessDay; +import com.eactive.eai.data.entity.onl.businessday.BusinessDayEvent; +import com.eactive.eai.data.entity.onl.businessday.BusinessDayEventLog; +import com.eactive.eai.data.entity.onl.businessday.BusinessDayEventLogId; +import com.kbstar.eai.common.businessday.loader.BusinessDayEventLoader; +import com.kbstar.eai.common.businessday.loader.BusinessDayEventLogLogger; +import com.kbstar.eai.common.businessday.loader.BusinessDayLoader; +import com.kbstar.eai.common.businessday.mapper.BusinessDayEventMapper; +import com.kbstar.eai.common.businessday.mapper.BusinessDayMapper; + +@Service +@Transactional +public class BusinessDayDAO extends BaseDAO { + private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private BusinessDayLoader businessDayLoader; + + @Autowired + private BusinessDayMapper businessDayMapper; + + @Autowired + private BusinessDayEventLoader businessDayEventLoader; + + @Autowired + private BusinessDayEventMapper businessDayEventMapper; + + @Autowired + private BusinessDayEventLogLogger businessDayEventLogLogger; + + // 일자전환 변경대상목록 정보 전체 조회 + public Map getAllMessages() throws DAOException { + try { + List businessDays = businessDayLoader.findAll(); + Map businessDayMap = new HashMap<>(); + + logger.info("[ @@ getAllMessages Configuration - starting >>>>>>>>>>>>>>>>> ]"); + for (BusinessDay businessDay : businessDays) { + BusinessDayVO vo = businessDayMapper.toVo(businessDay); + businessDayMap.put(vo.getEAISvcName(), vo); + logger.info("@ " + vo.toString()); + } + logger.info("[>>getAllMessages Configuration - ended ]"); + return businessDayMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICIM101")); + } + } + + public Map getEventSystemInfo() throws DAOException { + try { + List businessDayEvents = businessDayEventLoader.findAll(); + Map businessDayEventMap = new HashMap<>(); + + logger.info("[ @@ getAllMessages Configuration - starting >>>>>>>>>>>>>>>>> ]"); + for (BusinessDayEvent businessDayEvent : businessDayEvents) { + EventSystemInfoVO vo = businessDayEventMapper.toVo(businessDayEvent); + businessDayEventMap.put(vo.getEvntRecvSysName(), vo); + logger.info("@ " + vo.toString()); + } + logger.info("[>>getAllMessages Configuration - ended ]"); + return businessDayEventMap; + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICIM101")); + } + } + + public void addEventLog(String evntRecvSysName, String eAIEvntDstcd, String evntSendYMS, + String evntPrcssRsultDpstYMS, String prcssRsultYn) throws DAOException { + try { + BusinessDayEventLog entity = new BusinessDayEventLog(); + BusinessDayEventLogId id = new BusinessDayEventLogId(); + + id.setEaievntdstcd(eAIEvntDstcd); + id.setEvntrecvsysname(evntRecvSysName); + id.setEvntsendyms(evntSendYMS); + + entity.setId(id); + entity.setEvntprcssrsultdpstyms(evntPrcssRsultDpstYMS); + entity.setPrcssrsultyn(prcssRsultYn); + + businessDayEventLogLogger.save(entity); + } catch (Exception e) { + throw new DAOException(ExceptionUtil.getErrorCode(e, "RECEAICBM102")); + } + } +} diff --git a/src/main/java/com/kbstar/eai/common/businessday/BusinessDayManager.java b/src/main/java/com/kbstar/eai/common/businessday/BusinessDayManager.java new file mode 100644 index 0000000..44ef436 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/businessday/BusinessDayManager.java @@ -0,0 +1,114 @@ +package com.kbstar.eai.common.businessday; + +import java.util.Map; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.common.util.Logger; + +// 일자전환 변경대상목록 정보를 DB로 부터 로딩해 메모리에 관리 + +@Component +public class BusinessDayManager implements Lifecycle { + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + @Autowired + private BusinessDayDAO businessDayDAO; + + private Map messages; + private LifecycleSupport lifecycle = new LifecycleSupport(this); + private boolean started; + + public static BusinessDayManager getInstance() { + return ApplicationContextProvider.getContext().getBean(BusinessDayManager.class); + } + + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICIM201"); + + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + messages = null; + try { + init(); + } catch (Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e, "RECEAICIM202")); + } + + started = true; + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + messages = businessDayDAO.getAllMessages(); + } + + public synchronized void reload() throws Exception { + if (logger.isWarn()) { + logger.warn("BusinessDayManager] reload all Started ..."); + } + init(); + if (logger.isWarn()) { + logger.warn("BusinessDayManager] reload all finished ..."); + } + } + + public void stop() throws LifecycleException { + if (!started) + throw new LifecycleException("RECEAICIM203"); + + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + messages.clear(); + started = false; + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void addLifecycleListener(LifecycleListener listener) { + lifecycle.addLifecycleListener(listener); + } + + public LifecycleListener[] findLifecycleListeners() { + return lifecycle.findLifecycleListeners(); + } + + public void removeLifecycleListener(LifecycleListener listener) { + lifecycle.removeLifecycleListener(listener); + } + + public boolean isStarted() { + return this.started; + } + + public BusinessDayVO getMessageVO(String eAISvcName) { + if (eAISvcName == null) + return null; + return messages.get(eAISvcName); + } + + public void setMessage(String eAISvcName, BusinessDayVO vo) { + messages.put(eAISvcName, vo); + } + + public void setMessage(BusinessDayVO vo) { + messages.put(vo.getEAISvcName(), vo); + } + + public void removeMessage(String eAISvcName) { + messages.remove(eAISvcName); + } + + public Map getAllBusinessDays() { + return this.messages; + } + + public String[] getAllCodes() { + return messages.keySet().toArray(new String[0]); + } +} diff --git a/src/main/java/com/kbstar/eai/common/businessday/BusinessDayVO.java b/src/main/java/com/kbstar/eai/common/businessday/BusinessDayVO.java new file mode 100644 index 0000000..5e477c2 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/businessday/BusinessDayVO.java @@ -0,0 +1,54 @@ +package com.kbstar.eai.common.businessday; + +import java.io.Serializable; + +import com.eactive.eai.common.util.NullControl; + +/** +* 1. 기능 : 일자전환변경대상목록 Java Value Object 클래스. +* 2. 처리 개요 : 일자전환변경대상목록 정보에 대한 Java Value Object 클래스. +* 3. 주의사항 +* +* @author : 이동훈 +* @version : v 1.0.0 +* @see : BusinessDayDAO, BusinessDayManager +* @since : +* : +*/ +public class BusinessDayVO implements Serializable +{ + /** + * EAI서비스명 + */ + private String eAISvcName; + + /** + * 전문유효일자 + */ + private String telgmValdYmd; + + public String getEAISvcName() { + return eAISvcName; + } + + public void setEAISvcName(String svcName) { + eAISvcName = svcName; + } + + public String getTelgmValdYmd() { + return telgmValdYmd; + } + + public void setTelgmValdYmd(String telgmValdYmd) { + this.telgmValdYmd = telgmValdYmd; + } + + public BusinessDayVO(String eAISvcName) { + this.eAISvcName = eAISvcName; + } + + public BusinessDayVO() { + } + + +} diff --git a/src/main/java/com/kbstar/eai/common/businessday/EventSystemInfoVO.java b/src/main/java/com/kbstar/eai/common/businessday/EventSystemInfoVO.java new file mode 100644 index 0000000..399f652 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/businessday/EventSystemInfoVO.java @@ -0,0 +1,70 @@ +package com.kbstar.eai.common.businessday; + +import java.io.Serializable; + +import com.eactive.eai.common.util.NullControl; + +/** +* 1. 기능 : 일자전환변경대상목록 Java Value Object 클래스. +* 2. 처리 개요 : 일자전환변경대상목록 정보에 대한 Java Value Object 클래스. +* 3. 주의사항 +* +* @author : 이동훈 +* @version : v 1.0.0 +* @see : +* @since : +* : +*/ +public class EventSystemInfoVO implements Serializable +{ + /** + * 이벤트수신시스템명 + */ + private String evntRecvSysName; + + /** + * 어댑터업무그룹명 + */ + private String adptrBzwkGroupName; + + /** + * EAI이벤트처리구분코드 + */ + private String eAIEvntPrcssDstcd; + + + public EventSystemInfoVO() { + } + + + public String getAdptrBzwkGroupName() { + return adptrBzwkGroupName; + } + + + public void setAdptrBzwkGroupName(String adptrBzwkGroupName) { + this.adptrBzwkGroupName = adptrBzwkGroupName; + } + + + public String getEAIEvntPrcssDstcd() { + return eAIEvntPrcssDstcd; + } + + + public void setEAIEvntPrcssDstcd(String evntPrcssDstcd) { + eAIEvntPrcssDstcd = evntPrcssDstcd; + } + + + public String getEvntRecvSysName() { + return evntRecvSysName; + } + + + public void setEvntRecvSysName(String evntRecvSysName) { + this.evntRecvSysName = evntRecvSysName; + } + + +} diff --git a/src/main/java/com/kbstar/eai/common/businessday/mapper/BusinessDayEventMapper.java b/src/main/java/com/kbstar/eai/common/businessday/mapper/BusinessDayEventMapper.java new file mode 100644 index 0000000..e1b4111 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/businessday/mapper/BusinessDayEventMapper.java @@ -0,0 +1,19 @@ +package com.kbstar.eai.common.businessday.mapper; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.data.entity.onl.businessday.BusinessDayEvent; +import com.eactive.eai.data.mapper.GenericMapper; +import com.kbstar.eai.common.businessday.BusinessDayVO; +import com.kbstar.eai.common.businessday.EventSystemInfoVO; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface BusinessDayEventMapper extends GenericMapper { + @Mapping(source = "evntrecvsysname", target = "evntRecvSysName") + @Mapping(source = "adptrbzwkgroupname", target = "adptrBzwkGroupName") + @Mapping(source = "eaievntprcssdstcd", target = "EAIEvntPrcssDstcd") + @Override + EventSystemInfoVO toVo(BusinessDayEvent entity); +} diff --git a/src/main/java/com/kbstar/eai/common/businessday/mapper/BusinessDayMapper.java b/src/main/java/com/kbstar/eai/common/businessday/mapper/BusinessDayMapper.java new file mode 100644 index 0000000..492fb43 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/businessday/mapper/BusinessDayMapper.java @@ -0,0 +1,23 @@ +package com.kbstar.eai.common.businessday.mapper; + +import org.mapstruct.InheritInverseConfiguration; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.ReportingPolicy; + +import com.eactive.eai.common.routing.RoutingVO; +import com.eactive.eai.data.entity.onl.businessday.BusinessDay; +import com.eactive.eai.data.entity.onl.routing.Routing; +import com.eactive.eai.data.mapper.GenericMapper; +import com.kbstar.eai.common.businessday.BusinessDayVO; + +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface BusinessDayMapper extends GenericMapper { + @Mapping(source = "id", target = "EAISvcName") + @Mapping(source = "splizvaldymd", target = "telgmValdYmd") + @Override + BusinessDayVO toVo(BusinessDay entity); + + @InheritInverseConfiguration + BusinessDay toEntity(BusinessDayVO vo); +} diff --git a/src/main/java/com/kbstar/eai/common/header/A2EHexaHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/A2EHexaHeaderAction.java new file mode 100644 index 0000000..e54dd36 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/A2EHexaHeaderAction.java @@ -0,0 +1,46 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; +import com.eactive.eai.transformer.util.IConv; + +/** +* 1. 기능 : ASCII를 EBCDIC Single로 변환하는 Class +* 2. 처리 개요 : +* - 추가시에만 기능처리 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class A2EHexaHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 0; // + + public A2EHexaHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + + } + public byte[] addHeader(byte[] orgData , byte[] message ) { + byte[] full = null; + full = IConv.asciiHexaToEBCDICHexa(message); + return full; + } + +// public static void main(String args[]) throws Exception { +// String actionName = "com.kbstar.eai.common.header.A2EHexaHeaderAction"; +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/ARSHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/ARSHeaderAction.java new file mode 100644 index 0000000..868a1e7 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/ARSHeaderAction.java @@ -0,0 +1,158 @@ +package com.kbstar.eai.common.header; + +import java.util.Arrays; + +import com.eactive.eai.common.header.HeaderActionSupport; + + +/** +* 1. 기능 : ARS공동망 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class ARSHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 7; // 공동망 헤더Length + + public ARSHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + } + + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + + } + public byte[] addHeader(byte[] orgData , byte[] message ) { + byte[] full = null; + full = new byte[HEADER_LENGTH+message.length]; + byte [] header = new byte[HEADER_LENGTH]; + + + byte[] hdr = {'H', 'D', 'R'}; + System.arraycopy(hdr, 0, header, 4, 3); + + // + System.arraycopy(header, 0, full, 0, HEADER_LENGTH ); + System.arraycopy(message, 0, full, HEADER_LENGTH, message.length); + + + // 전체 전문길이 계산 + byte len[] = Integer.toString( message.length +3 ).getBytes(); + + + //길이값 '0'으로 셋팅 + Arrays.fill(full, 0, 4, (byte)'0'); + //길이값 value 셋팅 + System.arraycopy(len, 0, full, 4 - len.length, len.length); + + return full; + + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.ARSHeaderAction"; + + + /////전송 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + /////////////////////////////////////////// + + + /////전송 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte[((byte[])bizObj).length ]; +// System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte["0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes().length ]; +// System.arraycopy("0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes(), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////////////////////////////////// +// +// +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/BBGHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/BBGHeaderAction.java new file mode 100644 index 0000000..5087f63 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/BBGHeaderAction.java @@ -0,0 +1,63 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; + +/** +* 1. 기능 : ARS공동망 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class BBGHeaderAction extends HeaderActionSupport +{ + //BBGHeaderAction - 앞에서부터 15바이트 삭제만 + private static final int HEADER_LENGTH = 15; + + public BBGHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + } + + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + } + + // 2009.10.06 정길영과장 요청 : 앞에 space 추가 15자리 + public byte[] addHeader(byte[] orgData , byte[] message ) { + byte[] full = null; + full = new byte[HEADER_LENGTH+message.length]; + + byte [] header = new byte[HEADER_LENGTH]; + + for(int i=0;i 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + /////////////////////////////////////////// + + + /////전송 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte[((byte[])bizObj).length ]; +// System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte["0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes().length ]; +// System.arraycopy("0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes(), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); +// } + +} + diff --git a/src/main/java/com/kbstar/eai/common/header/CSSLOANHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/CSSLOANHeaderAction.java new file mode 100644 index 0000000..3fc66fe --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/CSSLOANHeaderAction.java @@ -0,0 +1,137 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderAction; +import com.eactive.eai.common.header.HeaderActionFactory; +import com.eactive.eai.common.header.HeaderActionKeys; +import com.eactive.eai.common.header.HeaderActionSupport; + +/** +* 1. 기능 : CSSLOAN(여신임대차 조회) 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class CSSLOANHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 0; + + public CSSLOANHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + + } + public byte[] addHeader(byte[] orgData , byte[] message ) { + + String header = "1S0004"; + + int headerLength = header.length(); + + int msgLength = message.length + headerLength; + byte[] retHeader = new byte[msgLength]; + + System.arraycopy(header.getBytes(), 0, retHeader, 0, headerLength); + System.arraycopy(message, 0, retHeader, headerLength, retHeader.length-headerLength); + return retHeader; + } + +// public static void main(String args[]) throws Exception { +// String actionName = "com.kbstar.eai.common.header.CSSLOANHeaderAction"; +// +// +// /////전송 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + /////////////////////////////////////////// + + + /////전송 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte[((byte[])bizObj).length ]; +// System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte["0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes().length ]; +// System.arraycopy("0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes(), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + /////////////////////////////////////////// +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/CYUHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/CYUHeaderAction.java new file mode 100644 index 0000000..ae211b1 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/CYUHeaderAction.java @@ -0,0 +1,110 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.StringUtil; + + +/** +* 1. 기능 : 연계기관 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class CYUHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 30; // 연계 - 기관간의 헤더Length +// private static int mCount = 0; + + public CYUHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message ) { + return addHeader(orgData,message); + } + public byte[] addHeaderAD(byte[] orgData , byte[] message ) { + return addHeader(orgData,message); + } + + public byte[] addHeader(byte[] orgData , byte[] message ) { + String tranOccurPath = "E"; // 거래발생 경로(1) + String serverName = "EAISVR1"; // 서버이름(7) + String sysMinHMSUnit = ""; // 거래시간(12) + String tranSysDstcd = "1"; // 거래처리시스템 구분(1) + String tranLogRecrdEonot = "2"; // 거래log Dump 기록유무(1) + String Blnk0 = " "; // Filler (8) + + int msgLength = message.length + HEADER_LENGTH; + + sysMinHMSUnit = StringUtil.stringFormat(DatetimeUtil.getFormattedDate("HHmmssSSS"), false, ' ', 12); + + StringBuffer sb = new StringBuffer(30); + sb.append(tranOccurPath); + sb.append(serverName); + sb.append(sysMinHMSUnit); + sb.append(tranSysDstcd); + sb.append(tranLogRecrdEonot); + sb.append(Blnk0); + + byte[] retHeader = new byte[msgLength]; + + System.arraycopy(sb.toString().getBytes(), 0, retHeader, 0, HEADER_LENGTH); + System.arraycopy(message, 0, retHeader, HEADER_LENGTH, retHeader.length-HEADER_LENGTH); + return retHeader; + } +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.CYUHeaderAction"; +// +// +// /////전송 AD +//// HeaderAction action = HeaderActionFactory.createAction(actionName); +//// +//// Object[] bizObjs =new Object[1]; +//// bizObjs[0] = "1234567890".getBytes(); +//// Object bizObj = null; +//// if(bizObjs != null && bizObjs.length > 0) { +//// bizObj = bizObjs[0]; +//// } +//// byte[] orgData = null; +//// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +//// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +//// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +//// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +//// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +//// System.out.println("header=>"+new String(header)); +// ///////////// +// +// /////수신 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "EEAISVR1135201896 12 1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/E2AHexaHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/E2AHexaHeaderAction.java new file mode 100644 index 0000000..2dc2c37 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/E2AHexaHeaderAction.java @@ -0,0 +1,51 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; +import com.eactive.eai.transformer.util.IConv; + +/** +* 1. 기능 : EBCDIC을 ASCII Single로 변환하는 Class +* 2. 처리 개요 : +* - 추가시에만 기능처리 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class E2AHexaHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 0; // + + public E2AHexaHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + + } + public byte[] addHeader(byte[] orgData , byte[] message ) { + byte[] full = null; + full = IConv.ebcdicHexaToASCIIHexa(message); + return full; + } + +// public static void main(String args[]) throws Exception { +// String actionName = "com.kbstar.eai.common.header.E2AHexaHeaderAction"; +// +// +// +// +// +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/HOSTKISHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/HOSTKISHeaderAction.java new file mode 100644 index 0000000..149b62c --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/HOSTKISHeaderAction.java @@ -0,0 +1,130 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; + +/** +* 1. 기능 : CSSLOAN(여신임대차 조회) 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class HOSTKISHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 0; + + public HOSTKISHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + + } + public byte[] addHeader(byte[] orgData , byte[] message ) { + + byte[] header = {(byte)0xC8,(byte)0xE2,(byte)0xD7}; // "HSP" + + int headerLength = header.length; + + int msgLength = message.length + headerLength; + byte[] retHeader = new byte[msgLength]; + + System.arraycopy(header, 0, retHeader, 0, headerLength); + System.arraycopy(message, 0, retHeader, headerLength, retHeader.length-headerLength); + return retHeader; + } + +// public static void main(String args[]) throws Exception { +// test(); +// } + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.HOSTKISHeaderAction"; +// +// /////전송 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); +/////수신 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); +/////전송 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte[((byte[])bizObj).length ]; +// System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + /////수신 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte["0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes().length ]; +// System.arraycopy("0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes(), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/InterBankA2EHexaHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/InterBankA2EHexaHeaderAction.java new file mode 100644 index 0000000..aee4600 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/InterBankA2EHexaHeaderAction.java @@ -0,0 +1,64 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; +import com.eactive.eai.transformer.util.IConv; + +/** +* 1. 기능 : ASCII를 EBCDIC Single로 변환하는 Class +* 2. 처리 개요 : +* - 추가시에만 기능처리 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class InterBankA2EHexaHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 0; // + + public InterBankA2EHexaHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + + } + public byte[] addHeader(byte[] orgData , byte[] message ) { + byte[] full = null; + + int hostMessageSize = 700; + + full = IConv.asciiHexaToEBCDICHexa(message); + //----------------------------------- + // 500 bytes 로 Host Space(0x40) Padding 하여 전달 + //----------------------------------- + if(orgData.length < hostMessageSize) { + byte[] ebcdic = new byte[hostMessageSize]; + + System.arraycopy(full , 0, ebcdic, 0, full.length); + + for(int i=full.length; i 0 && ll <= (full.length - lengthBytes.length) ) { + byte[] ascii = new byte[ll + lengthBytes.length]; + + System.arraycopy(full, 0, ascii, 0, ascii.length); + + return ascii; + } + else { + return full; + } + + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.InterBankE2AHexaHeaderAction"; +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/KBSHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/KBSHeaderAction.java new file mode 100644 index 0000000..507d7c8 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/KBSHeaderAction.java @@ -0,0 +1,171 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderAction; +import com.eactive.eai.common.header.HeaderActionFactory; +import com.eactive.eai.common.header.HeaderActionKeys; +import com.eactive.eai.common.header.HeaderActionSupport; + +/** +* 1. 기능 : KB신용정보업무의 HEADER 와 CAP 매핑을 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 HEADER->CAP, R 는 CAP -> HEADER +* - DA 의 경우는 S는 CAP -> HEADER, R 는 HEADER->CAP +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class KBSHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 62; // 기관간의 헤더Length + private static final int CAP_LENGTH = 80; // HOST CAP 헤더Length + + public KBSHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + } + + public byte[] addHeaderAD(byte[] orgData , byte[] message ) { + return headerToCap(message); + } + + public byte[] deleteHeaderAD(byte[] message, int headerLength) { + return capToHeader(message); + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message ) { + return capToHeader(message); + } + + + public byte[] deleteHeaderDA(byte[] message, int headerLength) { + return headerToCap(message); + } + + public byte[] headerToCap(byte[] message) { + int msg_size = message.length - HEADER_LENGTH + CAP_LENGTH; + + byte[] retHeader = new byte[msg_size]; + byte[] capHeader = new byte[CAP_LENGTH]; + //-------------------------------------------- + /* + host_msg.trx_code ':=' kb_msg.tran_code for 8 bytes; + host_msg.filler1 ':=' [%H40]; + host_msg.io_meche ':=' [%HE3]; + host_msg.brno ':=' [%HF2,%HF5,%HF2,%HF7]; + host_msg.brno_sub ':=' [%HF0,%HF0,%HF0]; + host_msg.term_no ':=' kb_msg.term_no for 3 bytes; + host_msg.term_code ':=' kb_msg.term_code for 2 bytes; + host_msg.serl_no ':=' kb_msg.serl_no for 4 bytes; + host_msg.gsbr ':=' msg_text[62] for 4 bytes; + host_msg.gsbr_sub ':=' [%HF0,%HF0,%HF0]; + host_msg.appl_code ':=' kb_msg.upmu_code for 2 bytes; + host_msg.input_code ':=' kb_msg.input_code for 4 bytes; + host_msg.operator ':=' kb_msg.op_no for 4 bytes; + host_msg.stats_flag ':=' kb_msg.flag_code for 4 bytes; + host_msg.resv_no ':=' [%HF0,%HF0]; + host_msg.pf_key ':=' kb_msg.pf_key for 1 bytes; + host_msg.user_head ':=' kb_msg.user_head for 30 bytes; + */ + + System.arraycopy(message, 0, capHeader, 0, 8); + + capHeader[ 8] = (byte)0x40; + + capHeader[ 9] = (byte)0xE3; + + capHeader[10] = (byte)0xF2; + capHeader[11] = (byte)0xF5; + capHeader[12] = (byte)0xF2; + capHeader[13] = (byte)0xF7; + + capHeader[14] = (byte)0xF0; + capHeader[15] = (byte)0xF0; + capHeader[16] = (byte)0xF0; + + System.arraycopy(message, 8, capHeader, 17, 3); + System.arraycopy(message, 11, capHeader, 20, 2); + System.arraycopy(message, 13, capHeader, 22, 4); + System.arraycopy(message, 62, capHeader, 26, 4); + + capHeader[30] = (byte)0xF0; + capHeader[31] = (byte)0xF0; + capHeader[32] = (byte)0xF0; + + System.arraycopy(message, 17, capHeader, 33, 2); + System.arraycopy(message, 19, capHeader, 35, 4); + System.arraycopy(message, 23, capHeader, 39, 4); + System.arraycopy(message, 27, capHeader, 43, 4); + capHeader[47] = (byte)0xF0; + capHeader[48] = (byte)0xF0; + System.arraycopy(message, 31, capHeader, 49, 1); + System.arraycopy(message, 32, capHeader, 50,30); + //-------------------------------------------- + System.arraycopy(capHeader, 0, retHeader, 0, CAP_LENGTH); + System.arraycopy(message, HEADER_LENGTH, retHeader, CAP_LENGTH, message.length - HEADER_LENGTH); + return retHeader; + } + + public byte[] capToHeader(byte[] message) { + int msg_size = message.length + HEADER_LENGTH - CAP_LENGTH; + + byte[] retHeader = new byte[msg_size]; + byte[] header = new byte[HEADER_LENGTH]; + //-------------------------------------------- + /* + kb_msg.tran_code ':=' host_msg.trx_code for 8 bytes; + kb_msg.term_no ':=' host_msg.term_no for 3 bytes; + kb_msg.term_code ':=' host_msg.term_code for 2 bytes; + kb_msg.serl_no ':=' host_msg.serl_no for 4 bytes; + kb_msg.upmu_code ':=' host_msg.appl_code for 2 bytes; + kb_msg.input_code ':=' host_msg.input_code for 4 bytes; + kb_msg.op_no ':=' host_msg.operator for 4 bytes; + kb_msg.flag_code ':=' host_msg.stats_flag for 4 bytes; + kb_msg.pf_key ':=' host_msg.pf_key for 1 bytes; + kb_msg.user_head ':=' host_msg.user_head for 30 bytes; + */ + + System.arraycopy(message, 0, header, 0, 8); + System.arraycopy(message, 17, header, 8, 3); + System.arraycopy(message, 20, header, 11, 2); + System.arraycopy(message, 22, header, 13, 4); + System.arraycopy(message, 33, header, 17, 2); + System.arraycopy(message, 35, header, 19, 4); + System.arraycopy(message, 39, header, 23, 4); + System.arraycopy(message, 43, header, 27, 4); + System.arraycopy(message, 49, header, 31, 1); + System.arraycopy(message, 50, header, 32, 30); + //-------------------------------------------- + System.arraycopy(header, 0, retHeader, 0, HEADER_LENGTH); + System.arraycopy(message, CAP_LENGTH, retHeader, HEADER_LENGTH, message.length - CAP_LENGTH); + return retHeader; + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.KBSHeaderAction"; +// +// +// /////전송 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/KSHINBOHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/KSHINBOHeaderAction.java new file mode 100644 index 0000000..0e342ea --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/KSHINBOHeaderAction.java @@ -0,0 +1,188 @@ +package com.kbstar.eai.common.header; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +import com.eactive.eai.common.header.HeaderActionSupport; +//import com.kbstar.b2bgw.base.Utillity; + +/** +* 1. 기능 : 연계기관 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class KSHINBOHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 100; // B2B 헤더Length + + public KSHINBOHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message ) { + byte[] header = new byte[HEADER_LENGTH]; + byte[] full = null; + full = new byte[HEADER_LENGTH + message.length]; + byte[] body = message; + + System.arraycopy(orgData, 0, header, 0, HEADER_LENGTH); + + //전문 총길이를 헤더에 8byte로 추가 +// byte[] msgSize = Utillity.fillZero(Integer.toString(full.length), 8).getBytes(); +// System.arraycopy(msgSize, 0, header, 0, 8); + byte[] RES_CODE = "0000".getBytes(); + System.arraycopy(RES_CODE, 0, header, 8, 4); + byte[] SYSTEM_ID = "BLS".getBytes(); + System.arraycopy(SYSTEM_ID, 0, header, 12, 3); + byte[] FLOW_ID = "01".getBytes(); + System.arraycopy(FLOW_ID, 0, header, 25, 2); + String tmpSERVICE_CODE = ""; + try + { + //DB 삭제(2008.12.3) + tmpSERVICE_CODE = "DD" + new String(body, 19, 4); + + }catch(Exception ex){ + tmpSERVICE_CODE = "DD????"; + } + byte[] SERVICE_CODE = tmpSERVICE_CODE.getBytes(); + System.arraycopy(SERVICE_CODE, 0, header, 27, 6); + byte[] IO = "2".getBytes(); + System.arraycopy(IO, 0, header, 33, 1); + byte[] FORMAT_ID = "01".getBytes(); + System.arraycopy(FORMAT_ID, 0, header, 34, 2); + byte[] USER_ID = "WAPUSER".getBytes(); + System.arraycopy(USER_ID, 0, header, 46, USER_ID.length); + byte[] CERT = "0".getBytes(); + System.arraycopy(CERT, 0, header, 54, 1); + + String tmpIP = ""; + + try{ + tmpIP = InetAddress.getByName("www.shinbo.co.kr").getHostAddress(); + } + catch(UnknownHostException exHost){ + //tmpIP = "shinbo"; + tmpIP = "210.96.165.5"; + } + + byte[] IP = tmpIP.getBytes(); + System.arraycopy(IP, 0, header, 55, IP.length); +/* + byte[] LANG = "1".getBytes(); + System.arraycopy(LANG, 0, header, 77, 1); +*/ +// String tmpTRAN_DATE = Utillity.getDateStamp(); +// byte[] TRAN_DATE = tmpTRAN_DATE.getBytes(); +// System.arraycopy(TRAN_DATE, 0, header, 78, TRAN_DATE.length); +/* + String tmpTRAN_SEQ = "SB"+Utillity.fillZero(Long.toString(new Object().hashCode()), 6); + byte[] TRAN_SEQ = tmpTRAN_SEQ.getBytes(); + System.arraycopy(TRAN_SEQ, 0, header, 86, TRAN_SEQ.length); +*/ + System.arraycopy(header, 0, full, 0, HEADER_LENGTH ); + System.arraycopy(message, 0, full, HEADER_LENGTH, body.length ); + + return full; + } + public byte[] addHeaderAD(byte[] orgData , byte[] message ) { + byte[] header = new byte[HEADER_LENGTH]; + byte[] full = null; + + int bodySize = message.length - 15; + //15 byte Skip - 받은 메시지 중에 15byte는 Skip하여 처리한다. + full = new byte[HEADER_LENGTH + bodySize]; + byte[] bodyMsg = new byte[bodySize]; + System.arraycopy(message, 15, bodyMsg, 0, bodySize); + byte[] body = bodyMsg; + //Header에 화이트 스페이스 초기화 + Arrays.fill(header, 0, HEADER_LENGTH, (byte)' '); + + //전문 총길이를 헤더에 8byte로 추가 +// byte[] msgSize = Utillity.fillZero(Integer.toString(full.length), 8).getBytes(); +// System.arraycopy(msgSize, 0, header, 0, 8); + byte[] RES_CODE = "0000".getBytes(); + System.arraycopy(RES_CODE, 0, header, 8, 4); + byte[] SYSTEM_ID = "BLS".getBytes(); + System.arraycopy(SYSTEM_ID, 0, header, 12, 3); + byte[] FLOW_ID = "01".getBytes(); + System.arraycopy(FLOW_ID, 0, header, 25, 2); + String tmpSERVICE_CODE = ""; + try + { + //DB 삭제(2008.12.3) + tmpSERVICE_CODE = "DD" + new String(body, 19, 4); + + }catch(Exception ex){ + tmpSERVICE_CODE = "DD????"; + } + byte[] SERVICE_CODE = tmpSERVICE_CODE.getBytes(); + System.arraycopy(SERVICE_CODE, 0, header, 27, 6); + byte[] IO = "1".getBytes(); + System.arraycopy(IO, 0, header, 33, 1); + byte[] FORMAT_ID = "01".getBytes(); + System.arraycopy(FORMAT_ID, 0, header, 34, 2); + byte[] USER_ID = "WAPUSER".getBytes(); + System.arraycopy(USER_ID, 0, header, 46, USER_ID.length); + byte[] CERT = "0".getBytes(); + System.arraycopy(CERT, 0, header, 54, 1); + + String tmpIP = ""; + + try{ + tmpIP = InetAddress.getByName("www.shinbo.co.kr").getHostAddress(); + } + catch(UnknownHostException exHost){ + tmpIP = "shinbo"; + } + + byte[] IP = tmpIP.getBytes(); + System.arraycopy(IP, 0, header, 55, IP.length); +/* + byte[] LANG = "1".getBytes(); + System.arraycopy(LANG, 0, header, 77, 1); +*/ +// String tmpTRAN_DATE = Utillity.getDateStamp(); +// byte[] TRAN_DATE = tmpTRAN_DATE.getBytes(); +// System.arraycopy(TRAN_DATE, 0, header, 78, TRAN_DATE.length); + //IB.최진원대리,이민욱대리요청(2008.11.27) SB --> GB +// String tmpTRAN_SEQ = "GB"+Utillity.fillZero(Long.toString(new Object().hashCode()), 6); +// byte[] TRAN_SEQ = tmpTRAN_SEQ.getBytes(); +// System.arraycopy(TRAN_SEQ, 0, header, 86, TRAN_SEQ.length); + + System.arraycopy(header, 0, full, 0, HEADER_LENGTH ); + System.arraycopy(bodyMsg, 0, full, HEADER_LENGTH, body.length ); +// System.out.println("full][" +new String(full)+ "]"); + return full; + } + + public byte[] deleteHeaderAD(byte[] message, int headerLength) { + int msgLength = message.length - headerLength; + //원 전문(요청전문-업무)에서 앞 15byte를 skip하고 호스트에 데이타를 전송하게 되면 + //응답 전문 또한 15byte를 추가하여 응답으로 전송하게 된다. + //이에 15byte를 추가하는 부분 + int TMP_HEADER_SIZE = 15; // 15byte 크기 확보 + if(msgLength > 0) { + byte[] retHeader = new byte[msgLength+TMP_HEADER_SIZE]; + byte[] tmpHeader = new byte[TMP_HEADER_SIZE]; + tmpHeader = " ".getBytes(); + System.arraycopy(tmpHeader, 0, retHeader, 0, TMP_HEADER_SIZE); + System.arraycopy(message, headerLength, retHeader, 15, msgLength); + return retHeader; + }else { + return message; + } + + } + +} + diff --git a/src/main/java/com/kbstar/eai/common/header/OTPHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/OTPHeaderAction.java new file mode 100644 index 0000000..1e9db29 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/OTPHeaderAction.java @@ -0,0 +1,92 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; + +/** +* 1. 기능 : OTP 서버의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class OTPHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 19; // OTP - > HOST 서버간의 헤더Length + private static final int OPT_HEADER_LENGTH = 10; // HOST -> OTP 서버간의 헤더Length + + public OTPHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message ) { + return addHeader(orgData,message); + } + public byte[] addHeaderAD(byte[] orgData , byte[] message ) { + return addHeader(orgData,message); + } + + public byte[] addHeader(byte[] orgData , byte[] message ) { + int msgLength = message.length + OPT_HEADER_LENGTH; + + String otpHeader = "OPT "; + + byte[] retHeader = new byte[msgLength]; + + System.arraycopy(otpHeader.getBytes(), 0, retHeader, 0, OPT_HEADER_LENGTH); + System.arraycopy(message, 0, retHeader, OPT_HEADER_LENGTH, retHeader.length-OPT_HEADER_LENGTH); + return retHeader; + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.OTPHeaderAction"; + /////전송 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + + ///////////// + + /////수신 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "EEAISVR1135201896 12 1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/POSCOA2EHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/POSCOA2EHeaderAction.java new file mode 100644 index 0000000..0fc8596 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/POSCOA2EHeaderAction.java @@ -0,0 +1,71 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; +import com.eactive.eai.common.util.CommonLib; +import com.eactive.eai.transformer.util.IConv; + +/** +* 1. 기능 : ASCII를 EBCDIC Single로 변환하는 Class +* 2. 처리 개요 : +* - 추가시에만 기능처리 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class POSCOA2EHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 0; // + + public POSCOA2EHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + + } + public byte[] addHeader(byte[] orgData , byte[] message ) { + + byte[] full = message; + + byte[] header = null; + if(message.length > 52) { + header = new byte[52]; + System.arraycopy(message, 0, header, 0, header.length); + header = IConv.asciiHexaToEBCDICHexa(header); + System.arraycopy(header, 0, full, 0, header.length); + return full; + } + else { + full = IConv.asciiHexaToEBCDICHexa(full); + return full; + } + } + +// public static void main(String args[]) throws Exception { +// String actionName = "com.kbstar.eai.common.header.POSCOA2EHeaderAction"; +//System.out.println(actionName); +// POSCOA2EHeaderAction action = new POSCOA2EHeaderAction(); +// byte[] msg = "111111111111111111111111111111111111111111111111112233333".getBytes(); +// byte[] res = action.addHeader(msg, msg); +// +// System.out.println(CommonLib.getDumpMessage(res)); +// +// byte[] msg2 = "11111111111111111111111111111111111111111111111111".getBytes(); +// byte[] res2 = action.addHeader(msg2, msg2); +// +// System.out.println(CommonLib.getDumpMessage(res2)); +// +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/POSCOE2AHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/POSCOE2AHeaderAction.java new file mode 100644 index 0000000..aaf8cbc --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/POSCOE2AHeaderAction.java @@ -0,0 +1,72 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; +import com.eactive.eai.transformer.util.IConv; + +/** +* 1. 기능 : ASCII를 EBCDIC Single로 변환하는 Class +* 2. 처리 개요 : +* - 추가시에만 기능처리 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class POSCOE2AHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 0; // + + public POSCOE2AHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData,message); + + + } + public byte[] addHeader(byte[] orgData , byte[] message ) { + byte[] full = message; + + byte[] header = null; + if(message.length > 52) { + header = new byte[52]; + System.arraycopy(message, 0, header, 0, header.length); + header = IConv.ebcdicHexaToASCIIHexa(header); + System.arraycopy(header, 0, full, 0, header.length); + return full; + } + else { + full = IConv.ebcdicHexaToASCIIHexa(full); + return full; + } + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.POSCOE2AHeaderAction"; +//System.out.println(actionName); +// POSCOE2AHeaderAction action = new POSCOE2AHeaderAction(); +// byte[] msg = "111111111111111111111111111111111111111111111111112233333".getBytes(); +// byte[] res = action.addHeader(msg, msg); +// +// System.out.println(CommonLib.getDumpMessage(res)); +// +// byte[] msg2 = "11111111111111111111111111111111111111111111111111".getBytes(); +// byte[] res2 = action.addHeader(msg2, msg2); +// +// System.out.println(CommonLib.getDumpMessage(res2)); +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/PPSHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/PPSHeaderAction.java new file mode 100644 index 0000000..81c99e4 --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/PPSHeaderAction.java @@ -0,0 +1,202 @@ +package com.kbstar.eai.common.header; + +import java.util.Arrays; + +import com.eactive.eai.common.header.HeaderActionSupport; +import com.eactive.eai.common.util.DatetimeUtil; + + +/** +* 1. 기능 : 조달청 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class PPSHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 100; // 조달청 헤더Length + private static int mCount = 0; + + public PPSHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + private static int getIncMCount() { + if (mCount >= 99999){ + mCount =0; + } + mCount++; + return mCount; + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message ) { + byte[] full = null; + byte[] reqMessage = null; + reqMessage = orgData; + + full = new byte[HEADER_LENGTH+message.length]; + byte [] header = new byte[HEADER_LENGTH]; + + + System.arraycopy(reqMessage, 0, header, 0, HEADER_LENGTH ); + + //header 응답코드 변경 + Arrays.fill(header, 38 , 42, (byte)'0'); //header = header.substring(0, 38) + "0000" + header.substring(42); + + // + System.arraycopy(header, 0, full, 0, HEADER_LENGTH ); + System.arraycopy(message, 0, full, HEADER_LENGTH, message.length); + + + // 전체 전문길이 계산 + byte len[] = Integer.toString( full.length ).getBytes(); + + + //길이값 '0'으로 셋팅 + Arrays.fill(full, 0, 4, (byte)'0'); + //길이값 value 셋팅 + System.arraycopy(len, 0, full, 4 - len.length, len.length); + return full; + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message ) { + byte[] full = null; + full = new byte[HEADER_LENGTH + message.length]; + byte[] body = message; + + + // 보안헤더 + byte[] sec = new byte[HEADER_LENGTH]; + Arrays.fill(sec, 0, HEADER_LENGTH, (byte)' '); + + //길이 셋팅 + byte[] length = Integer.toString(body.length + HEADER_LENGTH).getBytes(); + Arrays.fill(sec, 0, 4, (byte)'0'); + System.arraycopy(length, 0, sec, 4 - length.length, length.length); + + byte[] date = DatetimeUtil.getCurrentDateTime().getBytes(); + System.arraycopy(date, 0, sec, 4, 14); + + byte[] seq = Integer.toString( PPSHeaderAction.getIncMCount() ).getBytes(); + Arrays.fill(sec, 18, 30, (byte)'0'); + System.arraycopy(seq, 0, sec, 30 - seq.length, seq.length); + + byte[] m_type = {'0', '2', '0', '0'}; + System.arraycopy(m_type, 0, sec, 30, 4); + + byte[] t_code = {'X', '2', '0', '3'}; + System.arraycopy(t_code, 0, sec, 34, 4); + + byte[] c_code = {'1', '3', '7', '0', '1', '0', '0', '0'}; + System.arraycopy(c_code, 0, sec, 42, 8); + + byte[] i_code = {'0', '0', '0', '0', '2'}; + System.arraycopy(i_code, 0, sec, 50, 5); + + byte[] s_code = {'S', 'F', 'X', ' '}; + System.arraycopy(s_code, 0, sec, 55, 4); + + byte[] sr_type = {'1'}; + System.arraycopy(sr_type, 0, sec, 68, 1); + + + System.arraycopy(sec,0,full,0,HEADER_LENGTH); + System.arraycopy(body,0,full,HEADER_LENGTH,body.length); + + return full; + + + } +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.PPSHeaderAction"; + /////전송 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + /////////////////////////////////////////// + + + /////전송 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte[((byte[])bizObj).length ]; +// System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte["0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes().length ]; +// System.arraycopy("0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes(), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/SHINBOHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/SHINBOHeaderAction.java new file mode 100644 index 0000000..3b248db --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/SHINBOHeaderAction.java @@ -0,0 +1,178 @@ +package com.kbstar.eai.common.header; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.Arrays; + +import com.eactive.eai.common.header.HeaderActionSupport; +//import com.kbstar.b2bgw.base.Utillity; + +/** +* 1. 기능 : 연계기관 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class SHINBOHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 100; // B2B 헤더Length + + public SHINBOHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message ) { + byte[] header = new byte[HEADER_LENGTH]; + byte[] full = null; + full = new byte[HEADER_LENGTH + message.length]; + byte[] body = message; + + System.arraycopy(orgData, 0, header, 0, HEADER_LENGTH); + + //전문 총길이를 헤더에 8byte로 추가 +// byte[] msgSize = Utillity.fillZero(Integer.toString(full.length), 8).getBytes(); +// System.arraycopy(msgSize, 0, header, 0, 8); + byte[] RES_CODE = "0000".getBytes(); + System.arraycopy(RES_CODE, 0, header, 8, 4); + byte[] SYSTEM_ID = "BLS".getBytes(); + System.arraycopy(SYSTEM_ID, 0, header, 12, 3); + byte[] FLOW_ID = "01".getBytes(); + System.arraycopy(FLOW_ID, 0, header, 25, 2); + String tmpSERVICE_CODE = ""; + try + { + //DB 삭제(2008.12.3) + tmpSERVICE_CODE = "DD" + new String(body, 19, 4); + + }catch(Exception ex){ + tmpSERVICE_CODE = "DD????"; + } + byte[] SERVICE_CODE = tmpSERVICE_CODE.getBytes(); + System.arraycopy(SERVICE_CODE, 0, header, 27, 6); + byte[] IO = "2".getBytes(); + System.arraycopy(IO, 0, header, 33, 1); + byte[] FORMAT_ID = "01".getBytes(); + System.arraycopy(FORMAT_ID, 0, header, 34, 2); + byte[] USER_ID = "WAPUSER".getBytes(); + System.arraycopy(USER_ID, 0, header, 46, USER_ID.length); + byte[] CERT = "0".getBytes(); + System.arraycopy(CERT, 0, header, 54, 1); + + String tmpIP = ""; + + try{ + tmpIP = InetAddress.getByName("www.shinbo.co.kr").getHostAddress(); + } + catch(UnknownHostException exHost){ + //tmpIP = "shinbo"; + tmpIP = "210.96.165.5"; + } + + byte[] IP = tmpIP.getBytes(); + System.arraycopy(IP, 0, header, 55, IP.length); +/* + byte[] LANG = "1".getBytes(); + System.arraycopy(LANG, 0, header, 77, 1); +*/ +// String tmpTRAN_DATE = Utillity.getDateStamp(); +// byte[] TRAN_DATE = tmpTRAN_DATE.getBytes(); +// System.arraycopy(TRAN_DATE, 0, header, 78, TRAN_DATE.length); +/* + String tmpTRAN_SEQ = "SB"+Utillity.fillZero(Long.toString(new Object().hashCode()), 6); + byte[] TRAN_SEQ = tmpTRAN_SEQ.getBytes(); + System.arraycopy(TRAN_SEQ, 0, header, 86, TRAN_SEQ.length); +*/ + System.arraycopy(header, 0, full, 0, HEADER_LENGTH ); + System.arraycopy(message, 0, full, HEADER_LENGTH, body.length ); + + return full; + } + public byte[] addHeaderAD(byte[] orgData , byte[] message ) { + byte[] header = new byte[HEADER_LENGTH]; + byte[] full = null; + full = new byte[HEADER_LENGTH + message.length]; + byte[] body = message; + + //Header에 화이트 스페이스 초기화 + Arrays.fill(header, 0, HEADER_LENGTH, (byte)' '); + + //전문 총길이를 헤더에 8byte로 추가 +// byte[] msgSize = Utillity.fillZero(Integer.toString(full.length), 8).getBytes(); +// System.arraycopy(msgSize, 0, header, 0, 8); + byte[] RES_CODE = "0000".getBytes(); + System.arraycopy(RES_CODE, 0, header, 8, 4); + byte[] SYSTEM_ID = "BLS".getBytes(); + System.arraycopy(SYSTEM_ID, 0, header, 12, 3); + byte[] FLOW_ID = "01".getBytes(); + System.arraycopy(FLOW_ID, 0, header, 25, 2); + String tmpSERVICE_CODE = ""; + try + { + // DB 삭제(2008.12.3) + tmpSERVICE_CODE = "DD" + new String(body, 19, 4); + + }catch(Exception ex){ + tmpSERVICE_CODE = "DD????"; + } + byte[] SERVICE_CODE = tmpSERVICE_CODE.getBytes(); + System.arraycopy(SERVICE_CODE, 0, header, 27, 6); + byte[] IO = "1".getBytes(); + System.arraycopy(IO, 0, header, 33, 1); + byte[] FORMAT_ID = "01".getBytes(); + System.arraycopy(FORMAT_ID, 0, header, 34, 2); + byte[] USER_ID = "WAPUSER".getBytes(); + System.arraycopy(USER_ID, 0, header, 46, USER_ID.length); + byte[] CERT = "0".getBytes(); + System.arraycopy(CERT, 0, header, 54, 1); + + String tmpIP = ""; + + try{ + tmpIP = InetAddress.getByName("www.shinbo.co.kr").getHostAddress(); + } + catch(UnknownHostException exHost){ + tmpIP = "shinbo"; + } + + byte[] IP = tmpIP.getBytes(); + System.arraycopy(IP, 0, header, 55, IP.length); +/* + byte[] LANG = "1".getBytes(); + System.arraycopy(LANG, 0, header, 77, 1); +*/ +// String tmpTRAN_DATE = Utillity.getDateStamp(); +// byte[] TRAN_DATE = tmpTRAN_DATE.getBytes(); +// System.arraycopy(TRAN_DATE, 0, header, 78, TRAN_DATE.length); +// +// String tmpTRAN_SEQ = "SB"+Utillity.fillZero(Long.toString(new Object().hashCode()), 6); +// byte[] TRAN_SEQ = tmpTRAN_SEQ.getBytes(); +// System.arraycopy(TRAN_SEQ, 0, header, 86, TRAN_SEQ.length); + + System.arraycopy(header, 0, full, 0, HEADER_LENGTH ); + System.arraycopy(message, 0, full, HEADER_LENGTH, body.length ); +// System.out.println("full][" +new String(full)+ "]"); + return full; + } +/* + public static void main(String[] args){ + //addHeaderDA(byte[] orgData , byte[] message ) + //String tmpOrgData = "000002680000BLSCBB0DDA12101DDA121101WAPUSER WAPUSER 010.88.50.117 N04EF 2008051900000025 063377 00030760000 A121200805191840490000 3377734701 68100916347143010535770"; + //String tmpMessage = "063377+00035760000+A122200805192027440000+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++3377734701+++++++++++++++++++++++++++++6810091634714301053577019560450연인컴퓨터 장지광 청주 01TLA2000018151101일반자금대출 200010040000000340000002000101300000003400000020051012000000034000000 000000040000000000000034000000.00044040 06"; + String tmpMessage = "760000 0111104 A185200806131015000000 "; + byte[] orgData = null; + byte[] message = tmpMessage.getBytes(); + + SHINBOHeaderAction sha = new SHINBOHeaderAction(); + byte[] res = sha.addHeaderAD(orgData, message); + System.out.println("res]" +new String(res)); + } +*/ +} + diff --git a/src/main/java/com/kbstar/eai/common/header/THHCYUHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/THHCYUHeaderAction.java new file mode 100644 index 0000000..40b6f8b --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/THHCYUHeaderAction.java @@ -0,0 +1,160 @@ +package com.kbstar.eai.common.header; + +import java.util.Arrays; + +import com.eactive.eai.common.header.HeaderActionSupport; +import com.eactive.eai.common.server.Keys; +import com.eactive.eai.common.util.DatetimeUtil; +import com.eactive.eai.common.util.StringUtil; + + +/** +* 1. 기능 : 연계기관 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class THHCYUHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 30; // 연계 - 기관간의 헤더Length +// private static int mCount = 0; + + private static String tranSysDstcd; + static { + String serverName = System.getProperty(Keys.SERVER_KEY); + tranSysDstcd = "1"; + if(serverName != null && serverName.length() > 2) { + //juns 서버명 변경에 따른 인스턴스 룰 추출변경 + //ex)EAIDSG_i11 => EAIDS01_i01 + //tranSysDstcd = serverName.substring(serverName.length()-2, serverName.length()-1); + tranSysDstcd = serverName.substring(serverName.length()-5, serverName.length()-4); + } + } + public THHCYUHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] deleteHeaderAD(byte[] message, int headerLength) { + return deleteHeader(message,headerLength); + } + public byte[] deleteHeaderDA(byte[] message, int headerLength) { + return deleteHeader(message,headerLength); + } + + public byte[] deleteHeader(byte[] message, int headerLength) { + int msgLength = message.length - headerLength; + if(msgLength > 0) { + + byte[] full = null; + full = new byte[7 + message.length - HEADER_LENGTH]; + byte [] header = new byte[7]; + + + byte[] hdr = {'H', 'D', 'R'}; + System.arraycopy(hdr, 0, header, 4, 3); + + // + System.arraycopy(header, 0, full, 0, 7 ); + System.arraycopy(message, HEADER_LENGTH, full, 7, message.length-HEADER_LENGTH); + + + // 전체 전문길이 계산 + byte len[] = Integer.toString( message.length +3 ).getBytes(); + + + //길이값 '0'으로 셋팅 + Arrays.fill(full, 0, 4, (byte)'0'); + //길이값 value 셋팅 + System.arraycopy(len, 0, full, 4 - len.length, len.length); + + return full; + } + else { + return message; + } + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message ) { + return addHeader(orgData,message); + } + public byte[] addHeaderAD(byte[] orgData , byte[] message ) { + return addHeader(orgData,message); + } + + public byte[] addHeader(byte[] orgData , byte[] message ) { + String serviceCode = "EAIKFTTA"; // 턱시도서비스코드(8) + String sysMinHMSUnit = ""; // 거래시간(12) + //String tranSysDstcd = "1"; // 거래처리시스템 구분(1) + String tranLogRecrdEonot = "2"; // 거래log Dump 기록유무(1) + String Blnk0 = " "; // Filler (8) + + int msgLength = message.length + HEADER_LENGTH; + + sysMinHMSUnit = StringUtil.stringFormat(DatetimeUtil.getFormattedDate("MMDDHHmmssSSS"), false, ' ', 12); + + StringBuffer sb = new StringBuffer(30); + sb.append(serviceCode); + sb.append(sysMinHMSUnit); + sb.append(tranSysDstcd); + sb.append(tranLogRecrdEonot); + sb.append(Blnk0); + + byte[] retHeader = new byte[msgLength]; + + System.arraycopy(sb.toString().getBytes(), 0, retHeader, 0, HEADER_LENGTH); + System.arraycopy(message, 7, retHeader, HEADER_LENGTH, retHeader.length-HEADER_LENGTH-7); + return retHeader; + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.THHCYUHeaderAction"; +// +// +// /////전송 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "HDR00001234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); +// ///////////// +// +// /////수신 AD +// +// bizObjs[0] = "EAIKFTTA135201896 12 1234567890".getBytes(); +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/TrcodeHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/TrcodeHeaderAction.java new file mode 100644 index 0000000..de050da --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/TrcodeHeaderAction.java @@ -0,0 +1,129 @@ +package com.kbstar.eai.common.header; + +import com.eactive.eai.common.header.HeaderActionSupport; + +/** +* 1. 기능 : Transaction Code(9) Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class TrcodeHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 9; // transaction Code Length + + public TrcodeHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + return addHeader(orgData, message); + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return addHeader(orgData, message); + + + } + public byte[] addHeader(byte[] orgData , byte[] message ) { + // 추가로직은 없음 + // message 를 리턴하도록 수정 - 20081126 + // 정길영 과장 요청사항 + return message; + + + } + +// public static void main(String args[]) throws Exception { +// String actionName = "com.kbstar.eai.common.header.TrcodeHeaderAction"; +// +// + /////전송 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + /////////////////////////////////////////// + + + /////전송 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte[((byte[])bizObj).length ]; +// System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte["0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes().length ]; +// System.arraycopy("0110200805021112280000000000010200X203 1370100000002SFX 1 1234567890".getBytes(), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + /////////////////////////////////////////// +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/header/WebFirmHeaderAction.java b/src/main/java/com/kbstar/eai/common/header/WebFirmHeaderAction.java new file mode 100644 index 0000000..037a65e --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/header/WebFirmHeaderAction.java @@ -0,0 +1,144 @@ +package com.kbstar.eai.common.header; + +import java.util.Arrays; + +import com.eactive.eai.common.header.HeaderActionSupport; + + +/** +* 1. 기능 : WebFirmBanking 의 Header를 EAI에서 생성하거나 삭제해야하는 경우를 위한 Class +* 2. 처리 개요 : +* - 메시지종류에 따라 헤더를 생성하거나 삭제하는 API를 제공 +* 3. 주의사항 +* - AD 의 경우는 S는 ADD, R 는 DELETE +* - DA 의 경우는 S는 DELETE, R 는 ADD +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class WebFirmHeaderAction extends HeaderActionSupport +{ + private static final int HEADER_LENGTH = 7; // XecureConnect 헤더Length + + public WebFirmHeaderAction(){ + super.setHeaderLength(HEADER_LENGTH); + + } + + public byte[] addHeaderDA(byte[] orgData , byte[] message) { + byte[] full = null; + full = new byte[HEADER_LENGTH+message.length]; + + System.arraycopy(message, 0, full, 7, message.length); + + // 전체 전문길이 계산 + byte len[] = Integer.toString( message.length ).getBytes(); + + + //길이값 '0'으로 셋팅 + Arrays.fill(full, 0, 7, (byte)'0'); + //길이값 value 셋팅 + System.arraycopy(len, 0, full, 7 - len.length, len.length); + + return full; + + } + public byte[] addHeaderAD(byte[] orgData , byte[] message) { + return "".getBytes(); + + + } + + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String actionName = "com.kbstar.eai.common.header.WebFirmHeaderAction"; +// + /////전송 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 AD +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0013HDR1234567890".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// //orgData = new byte[((byte[])bizObj).length ]; +// //System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.ADD_DELETE_HEADER); +// +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.ADD_DELETE_HEADER); +// System.out.println("header=>"+new String(header)); + /////////////////////////////////////////// + + + /////전송 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "00000140000000004ABCD".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte[((byte[])bizObj).length ]; +// System.arraycopy(((byte[])bizObj), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_SEND); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_SEND, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); + ///////////// + + /////수신 DA +// HeaderAction action = HeaderActionFactory.createAction(actionName); +// +// Object[] bizObjs =new Object[1]; +// bizObjs[0] = "0000000004ABCD".getBytes(); +// Object bizObj = null; +// if(bizObjs != null && bizObjs.length > 0) { +// bizObj = bizObjs[0]; +// } +// byte[] orgData = null; +// orgData = new byte["00000140000000004ABCD".getBytes().length ]; +// System.arraycopy("00000140000000004ABCD".getBytes(), 0, orgData, 0,orgData.length); +// System.out.println("orgData=>"+new String(orgData==null?"".getBytes():orgData)); +// System.out.println("message=>"+new String(bizObj==null?"".getBytes():(byte[])bizObj)); +// System.out.println("sendRecv=>"+HeaderActionKeys.MESSAGE_RECV); +// System.out.println("commandType=>"+HeaderActionKeys.DELETE_ADD_HEADER); +// byte[] header = action.excute(orgData ,(byte[])bizObj, HeaderActionKeys.MESSAGE_RECV, HeaderActionKeys.DELETE_ADD_HEADER); +// System.out.println("header=>"+new String(header)); +// /////////////////////////////////////////// +// +// +// } +} + diff --git a/src/main/java/com/kbstar/eai/common/loader/EAILogFIleLoader.java b/src/main/java/com/kbstar/eai/common/loader/EAILogFIleLoader.java new file mode 100644 index 0000000..c0a2b9f --- /dev/null +++ b/src/main/java/com/kbstar/eai/common/loader/EAILogFIleLoader.java @@ -0,0 +1,810 @@ +package com.kbstar.eai.common.loader; + +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileReader; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.Instant; +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.time.temporal.TemporalField; +import java.time.temporal.WeekFields; +import java.util.ArrayList; +import java.util.Date; +import java.util.Locale; +import java.util.Properties; + +import com.eactive.eai.common.util.StringUtil; +//import com.penta.scpdb.ScpDbAgent; + +/** +* 1. 기능 : 거래로그 파일을 DB에 저장 +* 2. 처리 개요 : 거래로그 파일을 DB에 저장 +* 3. 주의사항 : 독립모듈로 사용하기 위해 개발 +* +* @author : +* @version : v 1.0.0 +* @see : +* @since : +*/ +public class EAILogFIleLoader { + + private String driver = ""; + private String url = ""; + private String ival = ""; + private String pval = ""; + private String tableOwner = "inst1"; + + private final String delimeter = "#[|]@"; + private final String EOL = "EOL$$;"; + private final String NEWLINE = "\n"; + private int COL_COUNT = 182; + + private int totalCount = 0; + private int insertCount = 0; + private int position = 0; + private int commitSize = 100; // commit size + + + private String logSQL = " INSERT INTO #{LOG_MASTER_TABLE} ( \n" + //EAI업무공통부 + + " EAIBZWKDSTCD, MSGDPSTYMS, EAISVCSERNO, LOGPRCSSSERNO, EAISEVRINSTNCNAME, \n" + + " EAISVCNAME, SVCHMSEONOT, SVCMOTIVUSEDSTCD, SVCPRCSSDSTICNAME, FLOWCTRLROUTNAME, \n" + + " INTGRADSTICNAME, GSTATSVCDSTICNAME, SVCPRCSSNO, SVCBFCLMNLOGYN, STNDMSGUSEYN, \n" + + " GSTATSYSADPTRBZWKGROUPNAME, PRSNTMSGIDNAME, RSPNSERRCDNAME, MSGPRCSSYMS, SEVRLOGLVELNO, \n" + + " SVCLOGLVELNO, ERREAISVCNAME, DMNDERRCHNGIDNAME, DMNDERRFLDNAME, RSPNSERRCHNGIDNAME, \n" + + " RSPNSERRFLDNAME, PSVINTFACDSTICNAME, PSVBZWKSYSNAME, PSVSYSIDNAME, PSVSYSSVCDSTICNAME, \n" + + " PSVSYSADPTRBZWKGROUPNAME, FLOVRYN, CHNGYN, CHNGMSGIDNAME, INPTMSGIDNAME, \n" + + " BASCRSPNSMSGCMPRCTNT, BASCRSPNSCHNGYN, BASCRSPNSCHNGMSGIDNAME, ERRRSPNSMSGCMPRCTNT, ERRRSPNSCHNGYN, \n" + + " ERRRSPNSCHNGMSGIDNAME, NEXTSVCPRCSSNO, OUTBNDROUTNAME, TOUTVAL, CMPENSVCPRCSSNAME, \n" + + " SUPPLBZWKDATAYN, KEYMGTMSGCTNT, TRACKASISKEY1CTNT, TRACKASISKEY2CTNT, TRACKASISKEY3CTNT, \n" + + " TRACKASISKEY4CTNT, EAIGROUPCODSTCD, PGUID, TRANTYPE, RSPNSCHNGMSGTYPE, \n" + + " EAIERRCD, EAIERRCTNT, SEVRGROUPNAME, COMPANYCODE, SPLIZLENGTH, ADPTRINSTICODE, \n" + //EAI업무개별부 + + " BZWKDATACTNT, \n" + + //전행통합로그 헤더부 + + " TRANSTARTYMS, LGINGSYSID, LGINGSYSINSTNCID, LGINGYMS, INTGRALOGGUID, \n" + + " INTGRALOGIOMSGSERNO, EAISNDRCVTELGMDSTCD, \n" + //전행통합로그 공통부 + + " INTGRALOGTELGMRECVTRANCD, INTGRALOGERRCD, EAILOGKNDDSTCD, EAIBZWKTELGMDSTCD, INTGRALOGCHNLDSTCD, \n" + + " INTGRALOGMDIADSTCD, EAIDTALSBZWKCD, INTGRALOGTRANBRNCD, LOGIDIVICGRYVSNNO, INTGRALOGITSMMONITAGETYN, \n" + + " INTGRALOGTRANSCRENNO, INTGRALOGUSEREMPID, EAISCOPPERCTNT, \n" + + //내부표준전문 헤더부 + + " CICSTRNCD, INTNLSTELGMLEN, TRANBASEYMD, GUIDNO, TELGMDMNDDSTCD, \n" + + " TELGMFMATDSTCD, TELGMVALDYMD, TELGMVSNNO, GNRZTOUTCRTCNMVL, SYSIDNAME, \n" + + " OGTRANRCHNLDSTCD,PRCSSTCICSTRNCD,TRANPGROUPCOCD,ISCSENDSYSID, SPAREAREA, \n" + + //내부표준전문 공통부(거래정보) + + " GROUPCOCD, TELGMRECVTRANCD, PRCSSRTDTRANCD, SCRENNO, OSIDINSTICD, \n" + + " TRANSERNO, INOPARTLDSTCD, CMPXTDMNDDSTCD, SYSOEVIRNDSTCD, ITSMMONITAGETYN, \n" + + " TRANPTRNDSTCD, RBNDTRANYN, TERMLWAITRQSTYN, OGTRANRSTRYN, OGTRANGUIDNO, \n" + + //내부표준전문 공통부(채널정보) + + " BNKCD, TRANBRNCD, FEEPRCSSBRNCD, RELAYCHNLDSTCD, CHNLDSTCD, \n" + + " CHNLDBZWKDSTCD, MDIADSTCD, LANGDSTCD, TRMNO, USEREMPID, \n" + + " TERMLOPRTRNO, TERMLSPVSRNO, N1STSPVSRBRNCD, N2NDSPVSRBRNCD, N2NDSPVSRTRMNO, \n" + + //내부표준전문 공통부(입력메시지정보) + + " INPTMSGPTRNDSTCD, INPTMSGCTNNYN, INPTMSGSERNO, INPTMSGWRITYMS, \n" + //내부표준전문 공통부(승인정보) + + " ATHORFNSHDSTCD, SPVSRATHORDSTCD, N1STSPVSREMPID, N2NDSPVSREMPID, SPVSRARESNNOITM, \n" + + " SPVSRATHORRESNCD, \n" + //내부표준전문 공통부(전행업무공통부) + + " CLSNGAFYN, LSDTTRANYN, IDTREK, BZOPRDDDSTCD, SODBBRNPTRNDSTCD, \n" + + " SODUSERPTRNDSTCD, INOTABILYN, NORTAUSERYN, TRANDSCNDMNDYN, CALLGPGMNAME, \n" + + " RECVLUNAME, CNCLDSTCD, CNCLPTRNDSTCD, TRANCCRESNDSTCD, TRANCCRESNCTNT, \n" + + " OGTRANYMS, CNCLRSTRINFOCTNT, DSCNTRANDSTCD, IDIVIDATAEDTYN, OPBRNCD, \n" + + " CNCUTISCOPADDR, \n" + //내부표준전문 공통부(출력메시지정보) + + " OUTPTDPTRNDSTCD, OUTPTMPTRNDSTCD, OUTPTMSGCTNNYN, OUTPTMSGSERNO, OUTPTMSGWRITYMS,\n" + + " BRNCLSNGYN, \n" + //내부표준전문 공통부(에러정보) + + " ERRCD, TREATCD, CNCUTDSCNRQSTYN, FWORKCISCOPADDR, INTFACSENDTRANCD, \n" + + " CNCLECLUDYN, TRSMTRQSTID, CNCLABILYN, OUTPTMDIAEDTNO, ATMCSHRETUNDSTCD, \n" + + " SENDEAISVCNAME, \n" + + " LUSNDRCVTYPDSTCD, DTECALLOWTRANYN, IPADDR, \n" + + + " CHCMNLEN, MSGCHNLDSTCD, CNTERDSTCD, \n" + + + " SPAREAREA2, TESTCASID, \n" + //내부표준전문 공통부(입력매체부정보) + + " INPTMDIAPARTLLEN \n" + //내부표준전문 채널공통부 + + " ,CHANNELCOMMON \n" + + " ) VALUES ( \n" + + //EAI업무공통부 + + " ?, ?, ?, ?, ?, \n" //index to 5 + + " ?, ?, ?, ?, ?, \n" //index to 10 + + " ?, ?, ?, ?, ?, \n" //index to 15 + + " ?, ?, ?, ?, ?, \n" //index to 20 + + " ?, ?, ?, ?, ?, \n" //index to 25 + + " ?, ?, ?, ?, ?, \n" //index to 30 + + " ?, ?, ?, ?, ?, \n" //index to 35 + + " ?, ?, ?, ?, ?, \n" //index to 40 + + " ?, ?, ?, ?, ?, \n" //index to 45 + + " ?, ?, ?, ?, ?, \n" //index to 50 + + " ?, ?, ?, ?, ?, \n" //index to 55 + + " ?, ?, ?, ?, ?, \n" //index to 60 + + " ?, \n" //index to 61 + //EAI업무개별부 + + " CAST(? AS VARCHAR(1000))||CAST(? AS VARCHAR(1000))||CAST(? AS VARCHAR(1000))||CAST(? AS VARCHAR(1000)), \n" // 61 + + //전행통합로그 헤더부 + + " ?, ?, ?, ?, ?, \n" //index to 66 + + " ?, ?, \n" //index to 68 + + //전행통합로그 공통부 + + " ?, ?, ?, ?, ?, \n" //index to 68 + + " ?, ?, ?, ?, ?, \n" //index to 73 + + " ?, ?, ?, \n" //index to 76 + + //내부표준전문 헤더부 + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + //내부표준전문 공통부(거래정보) + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + //내부표준전문 공통부(채널정보) + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + //내부표준전문 공통부(입력메시지정보) + + " ?, ?, ?, ?, \n" + + //내부표준전문 공통부(승인정보) + + " ?, ?, ?, ?, ?, \n" + + " ?, \n" + + //내부표준전문 공통부(전행업무공통부) + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + " ?, \n" + //내부표준전문 공통부(출력메시지정보) + + " ?, ?, ?, ?, ?, \n" + + " ?, \n" + //내부표준전문 공통부(에러정보) + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + " ?, ?, ?, \n" + + " ?, ?, ?, ?, ?, \n" + + " ?, \n" //채널공통부길이 추가 + //내부표준전문 공통부(입력매체부정보) + + " ?, \n" + // 채널공통부(200) + + " ? \n" + + " ) "; + + private String logSubSQL = + " INSERT INTO #{LOG_SLAVE_TABLE} ( \n" + + " EAIBZWKDSTCD, MSGDPSTYMS, EAISVCSERNO, BZWKDATASERNO, LOGPRCSSSERNO \n" + + " , BZWKDATACTNT \n" + + " ) VALUES ( ?, ?, ?, ?, ? , ? ) "; + + private void init(String configPath) throws Exception { + Properties p = new Properties(); + FileInputStream in = null; + try{ + in = new FileInputStream(configPath); + p.load(in); + } catch (Exception e){ + System.out.println("환경설정 파일이 없습니다. - 파일명 : " + configPath); + throw e; + } + finally{ + if(in != null) { + try { + in.close(); + } + catch(Exception e) { + System.out.println("close error"); + } + } + } + + driver = p.getProperty("jdbc.driver"); + url = p.getProperty("jdbc.url"); + ival = p.getProperty("jdbc.ivalue"); + tableOwner = p.getProperty("table.owner"); + + String iniFilePath = p.getProperty("ini.file.path"); +// String iniKey = p.getProperty("ini.key"); + String encpval = p.getProperty("jdbc.pvalue"); + + System.out.println("========================================================="); + System.out.println(" EAILogFileLoader Configuration - "+ new Date()); + System.out.println("========================================================="); +// System.out.println("driver = " + driver); +// System.out.println("url = " + url); +// System.out.println("ivalue = " + ival); +// System.out.println("pvalue = " + encpval); +// System.out.println("Table Owner = " + tableOwner); +// System.out.println("iniFilePath = " + iniFilePath); + System.out.println("========================================================="); + +// ScpDbAgent agt = new ScpDbAgent(); +// try { +// pval = agt.ScpDecB64(iniFilePath, "SEC", encpval); +// } +// catch(Exception e) { +// System.out.println("ScpDecB64 error-" +e.toString()); +// } +// + } + + private static ZonedDateTime get(long time){ + Instant instant = Instant.ofEpochMilli(time); + return ZonedDateTime.ofInstant(instant, ZoneId.systemDefault()); + } + + public static int getDayOfWeekNum(String timeStr) { + Date date = new Date(); + try { + date = new SimpleDateFormat("yyyyMMdd").parse(timeStr); // "yyyyMMddHHmmssSSS" + } catch (ParseException e) { + System.out.println("getDayOfWeekNum error - "+timeStr); +// e.printStackTrace(); + } + long time = date.getTime(); + ZonedDateTime zdt = get(time); + TemporalField filedISO = WeekFields.of(Locale.KOREA).dayOfWeek(); + return zdt.getDayOfWeek().get(filedISO); + } + + private int toInt(String s) { + try { + return Integer.parseInt(s); + } + catch(Exception ex) { + return 0; + } + } + + private void loadLog(String cDay, ArrayList list, boolean isForce) throws Exception { + int insertResult = 0; + Connection conn = null; + PreparedStatement preparedStatement = null; + String[] info = null; + try { + + System.out.println(">> Log Date : " + cDay + ", rows=" + list.size()); + + if( driver != null ) { + Class.forName(driver); + conn = DriverManager.getConnection(url, ival, pval); + conn.setAutoCommit(true); + + int dayOfWeek = getDayOfWeekNum(cDay); + String tableName = tableOwner+".TSEAILG1" + dayOfWeek; + String cLogSQL = logSQL.replace("#{LOG_MASTER_TABLE}", tableName); + +// System.out.println(cLogSQL); + preparedStatement = conn.prepareStatement(cLogSQL); + + String apndBwkDataYn = "N"; //추가업무데이터 여부 + + for (int i=0; i x) + preparedStatement.setString(index++, bwkDataSplit[x]); + else + preparedStatement.setString(index++, ""); + } + + // 전행통합로그헤더부(92bytes) + preparedStatement.setString(index++, info[info_index++]); //채널거래시작일시 + preparedStatement.setString(index++, info[info_index++]); //로깅시스템ID, 차세대표준화-기술요소 명명규칙참조(mainframe,서버:시스템id) + preparedStatement.setString(index++, info[info_index++]); //로깅시스템인스턴스ID, 차세대표준화-기술요소 명명규칙참조(WAS의 인스턴스) + preparedStatement.setString(index++, info[info_index++]); //로깅일시 + preparedStatement.setString(index++, info[info_index++]); //GUID번호 + + preparedStatement.setString(index++, info[info_index++]); //입력메시지일련번호 + preparedStatement.setString(index++, info[info_index++]); //송수신전문구분코드 + + // 전행통합로그공통부(131bytes) + preparedStatement.setString(index++, info[info_index++]); //전문수신거래코드 + preparedStatement.setString(index++, info[info_index++]); //에러코드 + preparedStatement.setString(index++, info[info_index++]); //로그종류구분코드 - 1.업무로그(정상로그) 2. 업무로그(에러로그), 3. 중계 로그 + preparedStatement.setString(index++, info[info_index++]); + preparedStatement.setString(index++, info[info_index++]); //채널구분코드 + + preparedStatement.setString(index++, info[info_index++]); //매체구분코드 + preparedStatement.setString(index++, info[info_index++]); //세부업무구분코드 + preparedStatement.setString(index++, info[info_index++]);//거래부점코드 + preparedStatement.setString(index++, info[info_index++]); + preparedStatement.setString(index++, info[info_index++]); //ITSM모니터링대상여부 + + preparedStatement.setString(index++, info[info_index++]); //화면번호 + preparedStatement.setString(index++, info[info_index++]); //사용자번호 + preparedStatement.setString(index++, info[info_index++]); //영역별내용 + + + // 내부표준전문 헤더부(73bytes) + preparedStatement.setString(index++, info[info_index++]);//CICS트랜젝션코드 + preparedStatement.setInt(index++, toInt(info[info_index++]) ); //내부표준전문길이 + preparedStatement.setString(index++, info[info_index++]); //거래기준년월일 + preparedStatement.setString(index++, info[info_index++]); //GUID번호 + preparedStatement.setString(index++, info[info_index++]); //전문요청구분코드 + + preparedStatement.setString(index++, info[info_index++]); //전문형식구분코드 + preparedStatement.setString(index++, info[info_index++]);//전문유효년월일 + preparedStatement.setString(index++, info[info_index++]);//전문버전번호(TelgmVsnno), add ver.20090128 + preparedStatement.setInt(index++, toInt(info[info_index++]) );//총괄타임아웃임계치수(GnrzToutCrtcNmvl), add ver.20090128 + preparedStatement.setString(index++, info[info_index++]); //SYSID명, add 20090824 + + preparedStatement.setString(index++, info[info_index++]); //중계채널구분코드, add 20090824 + preparedStatement.setString(index++, info[info_index++]); //처리대상CICS트랜젝션코드 , add 20101221 + preparedStatement.setString(index++, info[info_index++]); //거래처리그룹회사코드, add 20101221 + preparedStatement.setString(index++, info[info_index++]); //ISC전송SYSID, add 20200429 + preparedStatement.setString(index++, info[info_index++]); //예비 AREA, add 20101221 + + + // 내부표준전문 공통부(거래정보, 112bytes) + preparedStatement.setString(index++, info[info_index++]); //그룹회사코드 + preparedStatement.setString(index++, info[info_index++]); //전문수신거래코드 + preparedStatement.setString(index++, info[info_index++]); //처리결과전문수신거래코드 + preparedStatement.setString(index++, info[info_index++]);//화면번호 + preparedStatement.setString(index++, info[info_index++]); //대외기관코드 + + preparedStatement.setString(index++, info[info_index++]);//거래일련번호 + preparedStatement.setString(index++, info[info_index++]); //내외부구분코드 + preparedStatement.setString(index++, info[info_index++]); //복합거래요청구분코드 + preparedStatement.setString(index++, info[info_index++]); //시스템운영환경구분코드 + preparedStatement.setString(index++, info[info_index++]);//ITSM모니터링대상여부(ITSMMoniTagetYn), add ver.20090128 + + preparedStatement.setString(index++, info[info_index++]);//거래유형구분코드 + preparedStatement.setString(index++, info[info_index++]);//리바운드 거래여부 + preparedStatement.setString(index++, info[info_index++]); //단말대기요구 여부 + preparedStatement.setString(index++, info[info_index++]); //원거래복원여부 + preparedStatement.setString(index++, info[info_index++]); //원거래 GUID번호 + + //내부표준전문 공통부(채널정보, 47bytes) + preparedStatement.setString(index++, info[info_index++]);//은행코드 + preparedStatement.setString(index++, info[info_index++]); //거래부점코드 + preparedStatement.setString(index++, info[info_index++]);//수수료처리부점코드(FeePrcssBrncd), add ver.20090128 + preparedStatement.setString(index++, info[info_index++]);//중계채널구분코드 + preparedStatement.setString(index++, info[info_index++]); //채널구분코드 + + preparedStatement.setString(index++, info[info_index++]); //채널세부업무구분코드(ChnlDtalsBzwkDstcd), add ver.20090128 + preparedStatement.setString(index++, info[info_index++]); //매체구분코드 + preparedStatement.setString(index++, info[info_index++]); //언어구분코드 + preparedStatement.setString(index++, info[info_index++]); //단말번호 + preparedStatement.setString(index++, info[info_index++]); //사용자직원번호 + + preparedStatement.setString(index++, info[info_index++]);//단말조작자번호 + preparedStatement.setString(index++, info[info_index++]);//단말책임자번호 + preparedStatement.setString(index++, info[info_index++]);//1차책임자부점코드(1stSpvsrBrncd), add ver.20090128 + preparedStatement.setString(index++, info[info_index++]); //2차책임자부점코드 + preparedStatement.setString(index++, info[info_index++]);//2차책임자단말번호 + + //내부표준전문 공통부(입력메시지정보, 26bytes) + preparedStatement.setString(index++, info[info_index++]); //입력메시지유형구분코드 + preparedStatement.setString(index++, info[info_index++]); //입력메시지계속여부 + preparedStatement.setString(index++, info[info_index++]);//입력메시지일련번호 + preparedStatement.setString(index++, info[info_index++]); //입력메시지작성일시 + + //내부표준전문 공통부(승인정보, 98bytes) + preparedStatement.setString(index++, info[info_index++]); //승인완료구분코드 + preparedStatement.setString(index++, info[info_index++]);//책임자승인구분코드 + preparedStatement.setString(index++, info[info_index++]);//1차책임자직원번호 + preparedStatement.setString(index++, info[info_index++]);//2차책임자직원번호 + preparedStatement.setInt(index++, toInt(info[info_index++]));//책임자승인사유건수 + + preparedStatement.setString(index++, info[info_index++]); //책임자승인사유코드(10) - 80bytes + + //내부표준전문 공통부(전행업무공통부, 179bytes) + preparedStatement.setString(index++, info[info_index++]);//마감후여부 + preparedStatement.setString(index++, info[info_index++]); //전일자거래여부 + //index 140 + preparedStatement.setString(index++, info[info_index++]); //카드거래처리년월일 + + preparedStatement.setString(index++, info[info_index++]); //영업일구분코드(BzoprDdDstcd), add ver.20090128 + + preparedStatement.setString(index++, info[info_index++]); //SOD영업점유형구분코드 + + preparedStatement.setString(index++, info[info_index++]); //SOD사용자유형구분코드 + preparedStatement.setString(index++, info[info_index++]); //입출가능여부 + preparedStatement.setString(index++, info[info_index++]); //무자원대체가능사용자여부 + preparedStatement.setString(index++, info[info_index++]); //거래중단요청여부 + preparedStatement.setString(index++, info[info_index++]); //호출프로그램명 + + preparedStatement.setString(index++, info[info_index++]);//수신LU명 + preparedStatement.setString(index++, info[info_index++]); //취소구분코드 + //index 150 + preparedStatement.setString(index++, info[info_index++]); //취소유형구분코드 + preparedStatement.setString(index++, info[info_index++]); //거래취소정정사유구분코드 + + preparedStatement.setString(index++, info[info_index++]);//거래취소정정사유내용 + + preparedStatement.setString(index++, info[info_index++]); //원거래일시 + + preparedStatement.setString(index++, info[info_index++]); //취소복원정보내용(CnclRstrInfoCtnt), add ver.20090128 + + preparedStatement.setString(index++, info[info_index++]);//중단거래구분코드 + preparedStatement.setString(index++, info[info_index++]);//개별데이터편집여부 + preparedStatement.setString(index++, info[info_index++]); //개설부점코드 + + preparedStatement.setString(index++, info[info_index++]); //센터컷인터페이스영역주소(CncutIntfacScopAddr), add ver.20090128 + + //내부표준전문 공통부(출력메시지정보, 29bytes) + preparedStatement.setString(index++, info[info_index++]); //출력데이터유형구분코드 + //index 160 + preparedStatement.setString(index++, info[info_index++]); //출력메시지유형구분코드 + preparedStatement.setString(index++, info[info_index++]); //출력메시지계속여부 + + preparedStatement.setString(index++, info[info_index++]);//출력메시지일련번호 + preparedStatement.setString(index++, info[info_index++]); //출력메시지작성일시 + + preparedStatement.setString(index++, info[info_index++]); //부점마감여부 + + //내부표준전문 공통부(에러정보, 17bytes) + preparedStatement.setString(index++, info[info_index++]);//에러코드 + preparedStatement.setString(index++, info[info_index++]); //조치코드 + preparedStatement.setString(index++, info[info_index++]); //센터컷 중단요구 여부 + + preparedStatement.setString(index++, info[info_index++]); //프레임워크제어정보영역주소, add 20090824 + preparedStatement.setString(index++, info[info_index++]); //인터페이스송신거래코드, add 20090824 + //index 170 + + // TODO DB 필드매핑 20101221 + preparedStatement.setString(index++, info[info_index++]); //취소제외여부 + preparedStatement.setString(index++, info[info_index++]); //전송요구ID + preparedStatement.setString(index++, info[info_index++]); //취소가능여부 + preparedStatement.setString(index++, info[info_index++]); //출력매체편집번호 + preparedStatement.setString(index++, info[info_index++]); //자동화기기현금반환구분코드 + preparedStatement.setString(index++, info[info_index++]);//송신EAI서비스명 + + preparedStatement.setString(index++, info[info_index++]); //LU송수신타입구분 + preparedStatement.setString(index++, info[info_index++]); //일자전환허용거래여부 + preparedStatement.setString(index++, info[info_index++]); //IP주소 + + preparedStatement.setInt(index++, toInt(info[info_index++]) ); //채널공통부길이 + + preparedStatement.setString(index++, info[info_index++]); //메시지채널구분코드 + + preparedStatement.setString(index++, info[info_index++]); //예비 AREA + preparedStatement.setString(index++, info[info_index++]);//테스트사례ID + + //내부표준전문 공통부(입력매체부정보, 4bytes) + preparedStatement.setInt(index++, toInt(info[info_index++]) ); //입력매체부길이(InptMdiaCgryLen), add ver.20090128 + + preparedStatement.setString(index++, info[info_index++]); // 채널공통부 + + insertResult = preparedStatement.executeUpdate(); + insertCount += insertResult; + + if ("Y".equals(apndBwkDataYn)) { + addBwkDataSub(conn, info, addBwkData, dayOfWeek); // 업무데이터서브 + } +// conn.commit(); + } + catch(Exception ex) { + System.out.println("ERROR SKIP INSERT - row : "+ position +", Error : " + ex.toString()); +// ex.printStackTrace(); + if(!isForce) throw ex; + } + } // for (int i=0; i list = new ArrayList(); + int count = 0; + + BufferedReader br = new BufferedReader(new FileReader(filePath)); + String lineStr = null; + StringBuffer sb = new StringBuffer(); + String[] codes = null; + + boolean dayChanged = false; + String pDay = null; + String cDay = null; + + int multiLine = 0; + try { + while ((lineStr = br.readLine()) != null) { + if(EOL.equals(lineStr)) { + codes = split(sb.toString(), delimeter); + cDay = codes[1].substring(0, 8); + if(pDay != null) { + dayChanged = !pDay.equals(cDay); + } + if(dayChanged) { + loadLog(cDay, list, true); + count = 0; + list.clear(); + } + + pDay = cDay; + count++; + list.add(codes); + + if(count % commitSize == 0) { + loadLog(cDay, list, true); + count = 0; + list.clear(); + } + multiLine = 0; + sb.setLength(0); + continue; + } + multiLine++; + if(multiLine > 1) { + sb.append(NEWLINE); + } + sb.append(lineStr); + } + } + catch(Exception e) { + System.out.println(e.toString()); + } + finally { + try { + if(br != null) br.close(); + } + catch(Exception e) { + System.out.println(e.toString()); + } + } + if(count > 0) { + loadLog(cDay, list, true); + } + + System.out.println(String.format("## FILE=%s, INSERT ROW COUNTS : (%d/%d)", filePath, insertCount, totalCount)); + } + + private String[] split(String data, String deli) { + String[] s = data.split(deli); + return s; + } + + public void printArrayList(ArrayList list) { + for(int i=0; i java " + EAILogFIleLoader.class.getName() + " [Config File Path] [Log File Path]"; + } + + /** + * @param args + */ + public static void main(String[] args) { + EAILogFIleLoader loader = null; + + // Local Test : set false + boolean isReal = false; + + String configPath = "C:\\trlog\\EAILogFileLoader.properties"; // args[0]; + String filePath = "C:\\trlog\\tran.log"; //args[1]; + try { + if(isReal && args.length < 2) { + System.out.println(getUsage()); + System.exit(-1); + } + + if(isReal) { + configPath = args[0]; + filePath = args[1]; + } + + System.out.println("\n## START LOADING Infomation - " + configPath); + loader = new EAILogFIleLoader(); + loader.init(configPath); + loader.parse(filePath); + } catch (Exception e) { + System.out.println("ERROR MAIN"); + System.out.println(e.toString()); + System.exit(-2); + } + System.exit(0); + } + +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/ATSRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/ATSRouteAction.java new file mode 100644 index 0000000..419c728 --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/ATSRouteAction.java @@ -0,0 +1,24 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class ATSRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(CodeConversion.seToAsc(message), 40, 8); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [40,8]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/AppCodeRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/AppCodeRouteAction.java new file mode 100644 index 0000000..ad85bed --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/AppCodeRouteAction.java @@ -0,0 +1,27 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class AppCodeRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + byte[] appCode = new byte[3]; + + System.arraycopy(message, 0, appCode, 0, appCode.length); + keys[0] = new String( CodeConversion.seToAsc(appCode) ); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [0,3]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/CMBSRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/CMBSRouteAction.java new file mode 100644 index 0000000..97137dd --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/CMBSRouteAction.java @@ -0,0 +1,66 @@ +package com.kbstar.eai.flowcontrol.action; + +import java.io.ByteArrayInputStream; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Attr; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; + +public class CMBSRouteAction extends RouteActionSupport { + + // 2009.02.13 정길영과장 요청사항 + // CMBS용 라우팅 Action + // + // mode 값을 추출한다. + // + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; +// int keyIndex = 0; + + String xml = ""+new String(message)+""; + DocumentBuilder builder = null; + try { + builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes()); + Document doc = builder.parse(bis); + Element root = doc.getDocumentElement(); + + NodeList lst = root.getChildNodes(); + + Node n = null; + String nodeName = ""; + for(int i=0;i"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/GCMSRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/GCMSRouteAction.java new file mode 100644 index 0000000..3bb0b42 --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/GCMSRouteAction.java @@ -0,0 +1,23 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; + +public class GCMSRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(message, 0, 8); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [0,8]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/JKBULRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/JKBULRouteAction.java new file mode 100644 index 0000000..a4bb00a --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/JKBULRouteAction.java @@ -0,0 +1,23 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; + +public class JKBULRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(message, 0, 3) + strncpy(message, 66, 2); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [0,3]+[66,2]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/KEDRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/KEDRouteAction.java new file mode 100644 index 0000000..fe8adee --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/KEDRouteAction.java @@ -0,0 +1,20 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class KEDRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(CodeConversion.seToAsc(message), 9, 6); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/KUKAdapterRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/KUKAdapterRouteAction.java new file mode 100644 index 0000000..bf78049 --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/KUKAdapterRouteAction.java @@ -0,0 +1,27 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.util.IConv; + +public class KUKAdapterRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + // + String[] keys = new String[1]; + int keyIndex = 0; + try { + //keys[0] = strncpy(message, 0, 1) + strncpy(message, 53, 2); + byte[] resBytes = new byte[2]; + System.arraycopy(message, 1, resBytes, 0, resBytes.length ); + keys[0] = IConv.ebcdicToASCII(resBytes); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [1,2]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/OTPRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/OTPRouteAction.java new file mode 100644 index 0000000..ca16137 --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/OTPRouteAction.java @@ -0,0 +1,18 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionSupport; + +public class OTPRouteAction extends RouteActionSupport { + + // OTP 통지응답거래를 위한 RouteAction으로 고정값(OTP)를 리턴한다. + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + keys[0] = "OTP"; + return keys; + } + + public String getDescription() { + return "키추출방식 : FIXED:OTP"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/RCM1RouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/RCM1RouteAction.java new file mode 100644 index 0000000..3a85abe --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/RCM1RouteAction.java @@ -0,0 +1,24 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class RCM1RouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(CodeConversion.seToAsc(message), 150, 8); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [150,8]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/RCM5RouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/RCM5RouteAction.java new file mode 100644 index 0000000..91a7967 --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/RCM5RouteAction.java @@ -0,0 +1,24 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class RCM5RouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(CodeConversion.seToAsc(message), 9, 8); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [9,8]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/RCM8RouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/RCM8RouteAction.java new file mode 100644 index 0000000..d18d71c --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/RCM8RouteAction.java @@ -0,0 +1,24 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class RCM8RouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(CodeConversion.seToAsc(message), 159, 8); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [159,8]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/RCMDANRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/RCMDANRouteAction.java new file mode 100644 index 0000000..f200c1b --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/RCMDANRouteAction.java @@ -0,0 +1,24 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class RCMDANRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(CodeConversion.seToAsc(message), 52, 4); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [52,4]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/RCMKMBRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/RCMKMBRouteAction.java new file mode 100644 index 0000000..df46d1f --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/RCMKMBRouteAction.java @@ -0,0 +1,24 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class RCMKMBRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(CodeConversion.seToAsc(message), 4, 4); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [4,4]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/RCMSDSRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/RCMSDSRouteAction.java new file mode 100644 index 0000000..e9c1166 --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/RCMSDSRouteAction.java @@ -0,0 +1,24 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class RCMSDSRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(CodeConversion.seToAsc(message), 9, 4); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [9,4]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/SGWRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/SGWRouteAction.java new file mode 100644 index 0000000..562d23d --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/SGWRouteAction.java @@ -0,0 +1,25 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; + +public class SGWRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[2]; + int keyIndex = 0; + try { + keys[0] = strncpy(message, 105, 2); + keyIndex++; + keys[1] = strncpy(message, 21, 1) + strncpy(message, 104, 3); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [105,2], 전문 [104,3]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/SYBFMLRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/SYBFMLRouteAction.java new file mode 100644 index 0000000..82db15c --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/SYBFMLRouteAction.java @@ -0,0 +1,30 @@ +package com.kbstar.eai.flowcontrol.action; +//package com.eactive.eai.flowcontrol.action; +// +//import weblogic.wtc.jatmi.FldTbl; +//import weblogic.wtc.jatmi.TypedFML32; +// +//public class SYBFMLRouteAction extends RouteActionSupport { +// +// public String[] getRouteKeys(TypedFML32 fml) throws Exception { +// //------------------------------- +// // 2009.03.24 정길영과장 요청 +// //------------------------------- +// // FML32의 STRING1 의 값을 추출 +// // 앞의 6자리만 잘라서 사용 : +// +// +// String[] keys = new String[1]; +// int keyIndex = 0; +// try { +// Class cl = Class.forName("com.eactive.eai.adapter.wtc.CrmFmlTable"); +// FldTbl fldTable = (FldTbl)cl.newInstance(); +// String str = (String)fml.Fget(fldTable.name_to_Fldid("STRING1"), 0); +// +// keys[0] = strncpy(str.getBytes(), 0, 6); +// } catch(Exception e) { +// throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); +// } +// return keys; +// } +//} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/SYBRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/SYBRouteAction.java new file mode 100644 index 0000000..69ece08 --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/SYBRouteAction.java @@ -0,0 +1,23 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; + +public class SYBRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + // 앞의 6자리만 잘라서 사용 : 2009.03.18 정길영과장 요청 + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(message, 0, 6); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [0,6]"; + } +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/YGSHRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/YGSHRouteAction.java new file mode 100644 index 0000000..7995d66 --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/YGSHRouteAction.java @@ -0,0 +1,71 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class YGSHRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + + String[] keys = new String[1]; + int keyIndex = 0; + try { + keys[0] = strncpy(CodeConversion.seToAsc(message), 177, 8); + + // 2009.09.07 정길영과장 요청 - ASIS, TOBE // 2010.01.15 권세환대리 요청으로 주석처리 + // if("50500323".equals(keys[0])) { // 동양증권 자동결재 + // byte[] keyBytes = new byte[4]; + // System.arraycopy(message, 158, keyBytes, 0, keyBytes.length); + // String keyStr = new String(CodeConversion.seToAsc(keyBytes)); + // + // if("9613".equals(keyStr)) { + // keys[0] = keys[0] + "9"; + // } + // } + // else + if("50500325".equals(keys[0])) { // 미래에셋증권 자동결재 + byte[] keyBytes = new byte[4]; + System.arraycopy(message, 158, keyBytes, 0, keyBytes.length); + String keyStr = new String(CodeConversion.seToAsc(keyBytes)); + + if("9613".equals(keyStr) || + "9617".equals(keyStr)) { + // keys[0] = keys[0] + "9"; + keys[0] = keys[0].substring(0,3) + "A" + keys[0].substring(4, keys[0].length()); + } + } +// else if("50500312".equals(keys[0])) { // HMC증권 자동결재 +// byte[] keyBytes = new byte[4]; +// System.arraycopy(message, 158, keyBytes, 0, keyBytes.length); +// String keyStr = new String(CodeConversion.seToAsc(keyBytes)); + +// if("9613".equals(keyStr)) { +// keys[0] = keys[0] + "9"; +// } +// } + + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [117,8] -> 미래에셋증권자동결재 확인(4번째자리 값을 A로 치환)"; + } + +// public static void main(String args[]) throws Exception { +// test(); +//} + +// private static void test() throws Exception { +// String msg = "12345678"; +// msg = msg.substring(0,3) + "A" + msg.substring(4, msg.length()); +// System.out.println(msg); +// +// YGSHRouteAction action = new YGSHRouteAction(); +// System.out.println(action.getDescription()); +// } + +} diff --git a/src/main/java/com/kbstar/eai/flowcontrol/action/YGSRouteAction.java b/src/main/java/com/kbstar/eai/flowcontrol/action/YGSRouteAction.java new file mode 100644 index 0000000..cfa60b3 --- /dev/null +++ b/src/main/java/com/kbstar/eai/flowcontrol/action/YGSRouteAction.java @@ -0,0 +1,30 @@ +package com.kbstar.eai.flowcontrol.action; + +import com.eactive.eai.flowcontrol.action.RouteActionException; +import com.eactive.eai.flowcontrol.action.RouteActionSupport; +import com.eactive.eai.transformer.function.util.CodeConversion; + +public class YGSRouteAction extends RouteActionSupport { + + public String[] getRouteKeys(byte[] message) throws Exception { + // 2009.07.13 정길영과장 요청 + // - 출발지는 호스트, 목적지는 기관 + // - Offset : 177, 자릿수 : 8자리 (Ex :50500337) + + String[] keys = new String[1]; + int keyIndex = 0; + + byte[] keyBytes = new byte[8]; + try { + System.arraycopy(message, 177, keyBytes, 0, 8); + keys[0] = new String(CodeConversion.seToAsc(keyBytes)); + } catch(Exception e) { + throw new RouteActionException(this.getClass().getName() +" Error Extract Key("+keyIndex+"): " +e.getMessage()); + } + return keys; + } + + public String getDescription() { + return "키추출방식 : 전문 [117,8]"; + } +} diff --git a/src/main/java/com/kbstar/eai/inbound/action/CDSFirstAccountRequestAction.java b/src/main/java/com/kbstar/eai/inbound/action/CDSFirstAccountRequestAction.java new file mode 100644 index 0000000..cd0fcb6 --- /dev/null +++ b/src/main/java/com/kbstar/eai/inbound/action/CDSFirstAccountRequestAction.java @@ -0,0 +1,151 @@ +package com.kbstar.eai.inbound.action; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.agent.firstaccount.ShareMemory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageKeyExtractor; +import com.eactive.eai.inbound.action.ActionException; +import com.eactive.eai.inbound.action.RequestActionSupport; + +/** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 KESA를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - 어뎁터의 업무그룹코드를 키값앞에 추가한다. + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : + * @since : + */ +public class CDSFirstAccountRequestAction extends RequestActionSupport +{ + /** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 KESA를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @return String 비표준메시지의 메시지키값 + * @exception + **/ + public String[] perform(Object message) throws ActionException + { + byte[] tmp = null; + String[] key = null; + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + String eaiBizCode = null; + if(adptGrpVO != null) { + eaiBizCode = adptGrpVO.getEaiBizCode(); + } + else { + eaiBizCode = getEaiBizCodeFromAdapterName(adapterGroupName); + } + + if(message instanceof byte[]) { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + tmp = (byte[])message; + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + //집중계좌번호 호출 로직 + ShareMemory sm = ShareMemory.getInstance(); + String accNum = sm.getAccoutName(); + + for(int i=0; i> "+ new String(tmp)); + + try { + // 연계확인 로직 후 연계가 아닌 경우 등록한 룰을 통해 메시지키를 추출한다. + /* + tcp_length[4], // 0 + tcp_hdr[3], // 4 + system_id[2], // 7 + bank_code[3], // 9 + jeonmun_code[4], // 12 + gubun_code[3], // 16 + send_rcv_flag, // 19 + rsp_code[3], // 20 + acquire_bank_code[3], // 23 취급은행코드 + acquire_jumpo_code[4], // 26 취급지점코드 + acquire_gwanri_no[6], // 30 취급관리번호 + acquire_jeonmun_time[12], // 36 취급전문시간 + kft_gwanri_no[9], // 48 중계관리번호 + kft_jeonmun_time[12], // 57 중계전문시간 + issue_bank_code[3], // 69 개설은행코드 + issue_jumpo_code[4], // 72 개설지점코드 + issue_gwanri_no[6], // 76 개설관리번호 + issue_jeonmun_time[12], // 82 개설전문시간 + reserve[MAX_TRAN_LEN-92]; // 94 + + if ((strncmp(text.system_id, "03", 2) == 0) && + ((strncmp(text.jeonmun_code, "0200500", 7) == 0) || + (strncmp(text.jeonmun_code, "9210500", 7) == 0))) + { + memset(yun_gae, (char)NULL, sizeof(yun_gae)); + memcpy(yun_gae, text.reserve+12, 14); + status = Yun_Gae_Chk(yun_gae); + if (status == 0) // 연계계좌 + */ + String system_id = new String(tmp, 7, 2); + String jeonmun_code = new String(tmp, 12, 7); + + if("03".equals(system_id) && + ( "0200500".equals(jeonmun_code) || "9210500".equals(jeonmun_code)) ) { + int status = Yun_Gae_Chk(tmp); + + if (status == 0) { + key = new String[1]; + key[0] = jeonmun_code + "CYU"; + } + else { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } + } + else { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } + } catch(Exception e) { + if (logger.isError()) logger.info(adapterName+"] EBEAdapterRequestAction "+ e.getMessage()); + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + + } else { + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + if (logger.isError()) logger.info(adapterName+"] EBEAdapterRequestAction "+ e.getMessage()); + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + } + + for(int i=0; i 13 + + if( (bytesncmp(message, yun_gae_offset + 9 , " ")) || + (bytesncmp(message, yun_gae_offset + 10 , " ")) || + (bytesncmp(message, yun_gae_offset + 11 , " "))) { + return -1; + } + + if( bytesncmp(message, yun_gae_offset + 12, " ")) { + if ((bytesncmp(message, yun_gae_offset + 3, "07")) || + (bytesncmp(message, yun_gae_offset + 3, "08")) || + (bytesncmp(message, yun_gae_offset + 3, "26"))) { + return 0; // 연계 + } + } + else if ( ( bytesncmp(message, yun_gae_offset + 12, " ") ) == false) { + if (bytesncmp(message, yun_gae_offset + 4, "90")) { + return 0; // 연계 + } + } + return -1; + } + + public boolean bytesncmp(byte[] src, int startPos, String value) { + + if(value == null || value.length() < 1) { + return false; + } + + byte[] valueBytes = value.getBytes(); + int valueBytesLength = valueBytes.length; + + if(src == null || src.length <(startPos + valueBytesLength)) { + return false; + } + + byte[] cmpareBytes = new byte[valueBytesLength]; + + System.arraycopy(src, startPos, cmpareBytes, 0, cmpareBytes.length ); + if(value.equals(new String(cmpareBytes))) { + return true; + } + + return false; + } + + public String getDescription() { + return "키추출방식 : 연계계좌 확인 - 어댑터업무코드[3]+전문번호[7] +CYU , 아닐 경우 어댑터업무코드[3]+추출키값"; + } +} diff --git a/src/main/java/com/kbstar/eai/inbound/action/EBEFirstAccountRequestAction.java b/src/main/java/com/kbstar/eai/inbound/action/EBEFirstAccountRequestAction.java new file mode 100644 index 0000000..056da7e --- /dev/null +++ b/src/main/java/com/kbstar/eai/inbound/action/EBEFirstAccountRequestAction.java @@ -0,0 +1,147 @@ +package com.kbstar.eai.inbound.action; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.agent.firstaccount.ShareMemory; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.MessageKeyExtractor; +import com.eactive.eai.inbound.action.ActionException; +import com.eactive.eai.inbound.action.RequestActionSupport; + +/** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 KESA를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - 어뎁터의 업무그룹코드를 키값앞에 추가한다. + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @author : + * @version : v 1.0.0 + * @see : + * @since : + */ +public class EBEFirstAccountRequestAction extends RequestActionSupport +{ + /** + * 1. 기능 : Inbound Adapter를 통해 전달받은 비표준메시지에서 KESA를 생성하기 위한 키값을 추출 + * 2. 처리 개요 : + * - MessageKeyExtractor를 통해 Adapter별 추출 Rule에 따라 메시지를 구분할 수 있는 키값을 추출한다. + * 3. 주의사항 + * + * @param message Object 타입의 요청메시지 + * @return String 비표준메시지의 메시지키값 + * @exception + **/ + public String[] perform(Object message) throws ActionException + { + byte[] tmp = null; + String[] key = null; + + AdapterManager adapterManager = AdapterManager.getInstance(); + AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName); + String eaiBizCode = null; + if(adptGrpVO != null) { + eaiBizCode = adptGrpVO.getEaiBizCode(); + } + else { + eaiBizCode = getEaiBizCodeFromAdapterName(adapterGroupName); + } + + if(message instanceof byte[]) { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + tmp = (byte[])message; + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + //집중계좌번호 호출 로직 + ShareMemory sm = ShareMemory.getInstance(); + String accNum = sm.getAccoutName(); + + for(int i=0; i> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + for(int i=0; i> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + + + for(int i=0; i> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + //집중계좌번호 호출 로직 + ShareMemory sm = ShareMemory.getInstance(); + String accNum = sm.getAccoutName(); + + for(int i=0; i> "+ new String(tmp)); + } else { + try { + key = MessageKeyExtractor.getMessageKeyValue(this.adapterGroupName, message); + } catch(Exception e) { + throw new ActionException(ExceptionUtil.getErrorCode(e, "RECEAIIRA001")); + } + if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ message); + } + + + + for(int i=0; i> "+ e.getMessage(), e); + throw new ActionException(e.getMessage()); + } + + } else { + logger.error(adapterName+"] received Message Object >> "+ message.getClass().getName()); + throw new ActionException(); + } + + return messageId; + } + + public int getFeedback(Object message) throws ActionException + { + int feedback = -1; + + if (message instanceof Message) { + Message msg = (Message) message; + try { + feedback = msg.getIntProperty("JMS_IBM_Feedback"); + } catch(Exception e) { + logger.error(adapterName + "] Can not get feedback message >> " + e.getMessage()); + //throw new ActionException(e.getMessage()); + } + } + + return feedback; + } + + public String getDescription() { + return "키추출방식 : MQ JMSMessageID"; + } +} diff --git a/src/main/java/com/kbstar/eai/inbound/action/TuxedoCrmRequestAction.java b/src/main/java/com/kbstar/eai/inbound/action/TuxedoCrmRequestAction.java new file mode 100644 index 0000000..0b0a61a --- /dev/null +++ b/src/main/java/com/kbstar/eai/inbound/action/TuxedoCrmRequestAction.java @@ -0,0 +1,33 @@ +package com.kbstar.eai.inbound.action; +//package com.eactive.eai.inbound.action; +// +//import com.eactive.eai.adapter.wtc.CrmFmlTable; +//import com.eactive.eai.common.util.Logger; +//import weblogic.wtc.jatmi.Ferror; +//import weblogic.wtc.jatmi.TypedFML32; +// +//public class TuxedoCrmRequestAction extends RequestActionSupport +//{ +// +// public String[] perform(Object message) throws ActionException +// { +// TypedFML32 inFml = null; +// String[] svcName = null; +// if(message instanceof TypedFML32) { +// if (logger.isInfo()) logger.info(adapterName+"] received data >> "+ inFml.toString()); +// try { +// inFml = (TypedFML32)message; +// svcName[0] = (String)inFml.Fget(CrmFmlTable.SVCNAME ,0); +// } catch(Ferror fe) { +// if (logger.isInfo()) logger.info(adapterName+"] perform Exception Occur >> "+ fe.getMessage()); +// throw new ActionException(fe.getMessage()); +// } +// +// } else { +// if (logger.isInfo()) logger.info(adapterName+"] received Message Object >> "+ message.getClass().getName()); +// } +// +// +// return svcName; +// } +//} diff --git a/src/main/java/com/openbanking/eai/agent/token/ReloadAccessTokenCommand.java b/src/main/java/com/openbanking/eai/agent/token/ReloadAccessTokenCommand.java new file mode 100644 index 0000000..d1ca2ac --- /dev/null +++ b/src/main/java/com/openbanking/eai/agent/token/ReloadAccessTokenCommand.java @@ -0,0 +1,118 @@ +package com.openbanking.eai.agent.token; + +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.agent.command.CommandException; +import com.eactive.eai.common.util.Logger; +import com.openbanking.eai.common.token.AccessTokenManager; +import com.openbanking.eai.common.token.AccessTokenVO; + +import java.util.HashMap; + +public class ReloadAccessTokenCommand extends Command +{ + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * 1. 기능 : ReloadAccessTokenCommand 생성자 + * 2. 처리 개요 : + * 3. 주의사항 + * + * @param + * @return + * @exception + **/ + public ReloadAccessTokenCommand() { + super("ReloadAccessTokenCommand"); + } + + /** + * 1. 기능 : AccessTokenManager의 데이터를 동기화 + * 2. 처리 개요 : AccessTokenManager의 데이터를 동기화 + * 3. 주의사항 + * + * @param + * @return + * @exception CommandException + **/ + public Object execute() throws CommandException + { + Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + if (logger.isInfo()) logger.info(this.name + " is executed"); + +// if ( !(args instanceof HashMap) ) { +// String rspErrorCode = "EAIINIT001"; +// String msg = makeException(rspErrorCode, null); +// if (logger.isError()) logger.error(msg); +// throw new CommandException(msg); +// } + + try { +// if (args == null) { +// if (logger.isError()) +// logger.error("Refresh 토큰 정보가 없습니다."); +// } + + AccessTokenManager manager = AccessTokenManager.getInstance(); + String adapterGroupNameList = manager.getTargetAdapterGroup(); + String[] adapterGroupNames = adapterGroupNameList.split("[,]"); + + HashMap tokens = manager.getAllAccessTokenVO(); + + // 토큰맵에서 어댑터그룹명이 없으면 삭제로 간주 + if (tokens != null) { + for (String key : tokens.keySet()) { + boolean isDelete = true; + + if (adapterGroupNames != null && adapterGroupNames.length > 0) { + for (String adapterGroupName : adapterGroupNames) { + if (key.equals(adapterGroupName)) { + isDelete = false; + break; + } + } + } + + if (isDelete) { + manager.stopToken(key); + } + } + } + + if (adapterGroupNames != null && adapterGroupNames.length > 0) { + for (String adapterGroupName : adapterGroupNames) { + // 어댑터그룹명이 토큰맵에 없는 경우 + if (!tokens.containsKey(adapterGroupName)) { + // 추가로 간주 토큰 발급 시작 + manager.startToken(adapterGroupName); + // 어댑터그룹명이 토큰맵에 있는 경우 + } else { +// AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName); +// +// // 어댑터가 사용중이 아니면 중지 +// if (!gvo.isUsedFlag()) { +// manager.stopToken(adapterGroupName); +// } + } + } + } + + tokens = manager.getAllAccessTokenVO(); + + if (logger.isInfo()) + logger.info(this.name + "] tokens : " + tokens); + + if(logger.isInfo()) + logger.info(this.name + "] 토큰 정보가 Refresh 되었습니다."); + } catch (Exception e) { + String rspErrorCode = "EAIINIT003"; + String msg = makeException(rspErrorCode, e); + if (logger.isError()) logger.error(msg, e); + throw new CommandException(msg); + } + return "success"; + } + +} diff --git a/src/main/java/com/openbanking/eai/common/token/AccessTokenManager.java b/src/main/java/com/openbanking/eai/common/token/AccessTokenManager.java new file mode 100644 index 0000000..61524cd --- /dev/null +++ b/src/main/java/com/openbanking/eai/common/token/AccessTokenManager.java @@ -0,0 +1,568 @@ +package com.openbanking.eai.common.token; + +import com.eactive.eai.adapter.AdapterGroupVO; +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.agent.AgentUtil; +import com.eactive.eai.agent.command.Command; +import com.eactive.eai.common.exception.ExceptionUtil; +import com.eactive.eai.common.lifecycle.Lifecycle; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.lifecycle.LifecycleListener; +import com.eactive.eai.common.lifecycle.LifecycleSupport; +import com.eactive.eai.common.property.PropGroupVO; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; +import com.openbanking.eai.agent.token.ReloadAccessTokenCommand; +import com.openbanking.eai.common.token.client.HttpClientAccessTokenService; +import com.openbanking.eai.common.token.client.HttpClientAccessTokenServiceFactory; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.util.Date; +import java.util.HashMap; +import java.util.Properties; + +/** +* 1. 기능 : Access 토큰 정보를 DB로 부터 로딩하고 만료시 재발급 정보를 메모리에 관리하는 Manager 클래스 +* 2. 처리 개요 : DB 프로퍼티 정보에 저장된 Access 토큰 정보를 메모리에 로딩하거나 재발급 관리한다. +* * - +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class AccessTokenManager implements Lifecycle +{ + /** + * Default Logger + */ + static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + /** + * AccessTokenManager Single Instance + */ + private static AccessTokenManager instance = new AccessTokenManager();; + + /** + * LifecyleSupport object + */ + private LifecycleSupport lifecycle = new LifecycleSupport(this); + + /** + * 기동 여부 + */ + private boolean started; + + /** + * 토큰 정보를 저장하는 collection + */ + private HashMap tokens; + + /** + * 토큰 발급 Thread를 관리하는 collection + */ + private HashMap threads; + + + /** + * 1. 기능 : Default Constructor + * 2. 처리 개요 : + * - + * 3. 주의사항 + * + **/ + private AccessTokenManager() { + tokens = new HashMap(); + threads = new HashMap(); + } + + /** + * 1. 기능 : AccessTokenManager Singleton Object를 반환하는 getter method + * 2. 처리 개요 : AccessTokenManager Singleton Object를 반환한다. + * - + * 3. 주의사항 + * + * @param + * @return + * @exception + **/ + public static AccessTokenManager getInstance() { + return instance; + } + + /** + * 1. 기능 : AccessTokenManager의 초기화 여부를 반환하는 getter 메서드 + * 2. 처리 개요 : AccessTokenManager의 초기화 여부를 반환한다. + * 3. 주의사항 + * + * @return 초기화 여부 + **/ + public boolean isStarted() { + return this.started; + } + + // ================================================================================= + // 이 부분은 Lifecycle용으로 제공되는 메소드이다. + /** + * 1. 기능 : Lifecycle의 start 메서드로 AccessTokenManager를 초기화하는 메서드 + * 2. 처리 개요 : PropertyDAO를 이용해 추출 Rule 정보 모두를 가져와 초기화한다. <--- + * - + * 3. 주의사항 + * + * @param + * @return + * @exception + **/ + public void start() throws LifecycleException { + if (started) + throw new LifecycleException("RECEAICPM201"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTING_EVENT, this); + + try { + // accessToken 초기화 + tokens.clear(); + + init(); + } catch(Exception e) { + throw new LifecycleException(ExceptionUtil.getErrorCode(e,"RECEAICPM201")); + } + + started = true; + if (logger.isWarn()){ + logger.warn("AccessTokenManager] It is started."); + } + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STARTED_EVENT, this); + } + + private void init() throws Exception { + + String adapterGroupNameList = getTargetAdapterGroup(); + String[] adapterGroupNames = adapterGroupNameList.split("[,]"); + + if (adapterGroupNames.length > 0) { + // 어댑터그룹별 토큰 관리 + for (String adapterGroupName : adapterGroupNames) { + startToken(adapterGroupName); + } + } + } + + /** + * 1. 기능 : Lifecycle의 stop 메서드로 AccessTokenManager를 종료하는 메서드 + * 2. 처리 개요 : 멤버에 캐싱한 Access 토큰 정보를 clear한다. + * - + * 3. 주의사항 + * + * @param + * @return + * @exception + **/ + public void stop() throws LifecycleException { + // Validate and update our current component state + if (!started) + throw new LifecycleException("RECEAICPM203"); + + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPING_EVENT, this); + + // 기동중인 Thread가 존재하면 전체를 중지 시킨다. + if (threads.size() > 0) { + threads.forEach((n, t) -> + { + try { + if (t.isAlive()) { + t.stop(); + + logger.warn("AccessTokenManager] STOP (" + n + ") stopped."); + } + } catch (Exception ignore) { + ; + } + + }); + } + + this.tokens = null; + + started = false; + if (logger.isWarn()){ + logger.warn("AccessTokenManager] It is stopped."); + } + // Notify our interested LifecycleListeners + lifecycle.fireLifecycleEvent(STOPPED_EVENT, this); + } + + public void startToken(String adapterGroupName) { + + // 이미 기동중인 Thread가 존재하면 Skip한다. + if (threads.containsKey(adapterGroupName)) { + logger.warn("AccessTokenManager] SKIP (" + adapterGroupName + ") thread aleady started"); + return; + } + + Runnable runnable = new Runnable() { + long sleepTime = 60; + long startTime = System.currentTimeMillis(); + + public void run() { + while(true) { + long interval = 24 * 60 * 60; + AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName); + // 어댑터가 사용중이 아니면 Skip한다. + if (gvo != null && gvo.isUsedFlag()) { + try { + PropGroupVO vo = PropManager.getInstance().getPropGroupVO(AccessTokenVO.PROP_GROUP); + String tokenInfo = vo.getProperty(adapterGroupName); + + // 토큰 정보가 없을 경우 중지한다. + if (StringUtils.isBlank(tokenInfo)) { + logger.error("AccessTokenManager] INFO (" + adapterGroupName + ") is NULL"); + break; + } + + JSONObject tokenInfoObject = (JSONObject) JSONValue.parse(tokenInfo); + // 초단위 입력. 값이 없을 경우 1일(24 * 60 * 60초) + try { + interval = tokenInfoObject.containsKey("interval") ? Long.parseLong((String) tokenInfoObject.get("interval")) : 24 * 60 * 60; + } catch(Exception e) { + logger.warn("AccessTokenManager] SLEEP (" + adapterGroupName + ") default interval"); + } + + long intervalTime = startTime + (interval * 1000L); + + // interval이 0보다 작은 경우 Thread를 중지한다. + if (interval < 0) { + logger.error("AccessTokenManager] STOP (" + adapterGroupName + ")"); + break; + } + + // 해당 어댑터그룹명의 토큰이 존재할 경우 + if (!tokens.isEmpty() && tokens.containsKey(adapterGroupName)) { + if (System.currentTimeMillis() > intervalTime) { + long tempTime = System.currentTimeMillis(); + AccessTokenVO accessToken = tokens.get(adapterGroupName); + + // 다음 스케줄 시간 전까지 만료가 될경우 재 발급 + if (accessToken.getExpiration() != null && accessToken.getExpiration().before(new Date(intervalTime))) { + refresh(adapterGroupName, true); + + logger.warn("AccessTokenManager] REFRESH (" + adapterGroupName + ") AccessToken : " + instance.getAccessTokenVO(adapterGroupName)); + } else { + logger.info("AccessTokenManager] SKIP (" + adapterGroupName + ") AccessToken : " + instance.getAccessTokenVO(adapterGroupName)); + } + + startTime = tempTime; + } + // 해당 어댑터그룹명의 토큰이 존재하지 않을 경우 + } else { + long tempTime = System.currentTimeMillis(); + + refresh(adapterGroupName); + + startTime = tempTime; + + logger.warn("AccessTokenManager] NEW (" + adapterGroupName + ") AccessToken : " + instance.getAccessTokenVO(adapterGroupName)); + } + } catch(Throwable t) { + logger.error("AccessTokenManager] FAIL (" + adapterGroupName + ") start failed", t); + } + } else { + logger.info("AccessTokenManager] SKIP (" + adapterGroupName + ") adapter not used"); + } + + try { + logger.info("AccessTokenManager] SLEEP (" + adapterGroupName + ") " + sleepTime + " sec."); + + Thread.sleep(sleepTime * 1000L); + } catch(InterruptedException e) { + logger.error("AccessTokenManager] SLEEP (" + adapterGroupName + ") failed", e); + } + } + } + }; + + Thread thread = new Thread(runnable); + thread.setName(adapterGroupName + "-AccessTokenRefresh"); + thread.setPriority(Thread.MAX_PRIORITY); + thread.start(); + + // Thread 관리를 위함 + threads.put(adapterGroupName, thread); + } + + public void stopToken(String adapterGroupName) { + + // 기동중인 Thread가 존재하지 않으면 Skip한다. + if (!threads.containsKey(adapterGroupName)) { + return; + } + + Thread t = threads.get(adapterGroupName); + + if (t.isAlive()) { + t.stop(); + + if (logger.isDebugEnabled()){ + logger.warn("AccessTokenManager] STOP (" + adapterGroupName + ") stopped."); + } + + threads.remove(adapterGroupName); + tokens.remove(adapterGroupName); + } + } + + public String getStatus(String adapterGroupName) { + + if (!threads.containsKey(adapterGroupName)) { + return "STOPED"; + } else { + return "STARTED"; + +// Thread t = threads.get(adapterGroupName); +// +// if (t.isAlive()) { +// return "STARTED"; +// } else { +// return "SLEEP"; +// } + } + } + + /** + * 1. 기능 : LifecycleListener를 등록하는 메서드 + * 2. 처리 개요 : LifecycleListener를 등록한다. + * 3. 주의사항 + * + * @param listener LifecycleEvent를 수신한 LifecycleListener + **/ + public void addLifecycleListener(LifecycleListener listener) + { + lifecycle.addLifecycleListener(listener); + } + + /** + * 1. 기능 : 등록된 LifecycleListener 리스트를 반환하는 메서드 + * 2. 처리 개요 : 등록된 LifecycleListener 리스트를 반환하다. + * 3. 주의사항 + * + * @return 등록된 LifecycleListener 리스트 + **/ + public LifecycleListener[] findLifecycleListeners() + { + return lifecycle.findLifecycleListeners(); + } + + /** + * 1. 기능 : 등록된 LifecycleListener를 삭제하는 메서드 + * 2. 처리 개요 : 파라미터의 LifecycleListener를 삭제한다. + * 3. 주의사항 + * + * @param listener 삭제할 LifecycleListener + **/ + public void removeLifecycleListener(LifecycleListener listener) + { + lifecycle.removeLifecycleListener(listener); + } + + public String getTargetAdapterGroup() throws Exception { + + PropGroupVO vo = PropManager.getInstance().getPropGroupVO(AccessTokenVO.PROP_GROUP); + return vo.getProperty(AccessTokenVO.TARGET_ADAPTER_GROUP); + } + + + public void refresh() throws Exception { + if(logger.isWarn()) { + logger.warn("AccessTokenManager] refresh all Started ..."); + } + String adapterGroupNameList = getTargetAdapterGroup(); + String[] adapterGroupNames = adapterGroupNameList.split("[,]"); + + if (adapterGroupNames.length > 0) { + // 어댑터별 토큰 관리 + for (String adapterGroupName : adapterGroupNames) { + refresh(adapterGroupName); + } + } + + if(logger.isWarn()) { + logger.warn("AccessTokenManager] refresh all finished ..."); + } + } + + public void refresh(String adapterGroupName) throws Exception { + refresh(adapterGroupName, false); + } + + public synchronized void refresh(String adapterGroupName, boolean isRefresh) throws Exception { + boolean isExpired = true; + + if (tokens.containsKey(adapterGroupName)) { + AccessTokenVO accessToken = tokens.get(adapterGroupName); + isExpired = accessToken.isExpired(); + } + + // 만료됐거나 토큰 존재하지 않을때 + if (isExpired || isRefresh) { + // 기존 토큰이 있을 경우 제거 + tokens.remove(adapterGroupName); + + AdapterGroupVO gvo = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName); + + if (gvo != null && gvo.getAdapters().hasNext()) { + // 어댑터의 첫 프로퍼티 정보를 참조 + AdapterVO avo = (AdapterVO)gvo.getAdapters().next(); + + Properties properties = AdapterPropManager.getInstance().getProperties(avo.getPropGroupName()); + + String type = properties.getProperty("ADAPTER_TOKEN_ISSUING_CLIENT_TYPE"); + + // 토큰 발급 서비스가 다를 경우 HttpClientTokenService 인터페이스를 구현한 서비스를 추가 + HttpClientAccessTokenService service = HttpClientAccessTokenServiceFactory.createFactory(type); + if(service != null) { + AccessTokenVO accessToken = (AccessTokenVO) service.execute(adapterGroupName, properties); + this.tokens.put(adapterGroupName, accessToken); + } + } + } + } + + /** + * 1. 기능 : 모든 Access 토큰을 찾아 반환하는 메서드 + * 2. 처리 개요 : 모든 Access 토큰을 찾아 HashMap 객체로반환한다. + * 3. 주의사항 + * + * @return Access 토큰 정보 VO 객체 Collection + **/ + public HashMap getAllAccessTokenVO() { + return tokens; + } + + /** + * 1. 기능 : Access 토큰 정보를 반환하는 메서드 + * 2. 처리 개요 : Access 토큰 정보를 반환한다. + * - + * 3. 주의사항 + * + * @return Access 토큰 정보 + **/ + public AccessTokenVO getAccessTokenVO(String adapterGroupName) { + AccessTokenVO accessToken = null; + + try { + accessToken = tokens.get(adapterGroupName); + } catch(Exception e) { + if (logger.isError()) logger.error("토큰을 찾을 수 없습니다. ["+adapterGroupName+"] ", e); + } + + return accessToken; + } + + /** + * 1. 기능 : Access 토큰 값를 반환하는 메서드 + * 2. 처리 개요 : Access 토큰 값를 반환한다. + * - + * 3. 주의사항 + * + * @return accessToken 값 + **/ + public String getAccessToken(String adapterGroupName) { + String accessToken = null; + + try { + accessToken = tokens.get(adapterGroupName).getAccessToken(); + } catch(Exception e) { + if (logger.isError()) logger.error("토큰을 찾을 수 없습니다. ["+adapterGroupName+"] ", e); + } + + return accessToken; + } + + /** + * 1. 기능 : Access 토큰 정보를 등록하는 메서드 + * 2. 처리 개요 : Access 토큰 정보를 등록한다. + * - + * 3. 주의사항 + * + * @param vo AccessTokenVO + **/ + public void setAllAccessTokenVO(HashMap tokens) { + this.tokens = tokens; + } + + /** + * 1. 기능 : Access 토큰 정보를 등록하는 메서드 + * 2. 처리 개요 : Access 토큰 정보를 등록한다. + * - + * 3. 주의사항 + * + * @param vo AccessTokenVO + **/ + public void setAccessTokenVO(String adapterGroupName, AccessTokenVO accessToken) { + tokens.put(adapterGroupName, accessToken); + } + + /** + * 1. 기능 : Access 토큰를 삭제하는 메서드 + * 2. 처리 개요 : Access 토큰를 삭제한다. + * - + * 3. 주의사항 + * + **/ + public void removeAccessTokenVO(String adapterGroupName) { + tokens.remove(adapterGroupName); + } + + /** + * 1. 기능 : Access 토큰를 재발급하는 메서드 + * 2. 처리 개요 : Access 토큰를 재발급한다. + * - + * 3. 주의사항 + * + **/ + public synchronized AccessTokenVO retryAccessTokenVO(String adapterGroupName, Properties properties, String oldToken) throws Exception { + + AccessTokenVO accessToken = getAccessTokenVO(adapterGroupName); + + // 동시 요청이 발생할 경우 synchronized 처리를 했기때문에 토큰을 다시 한번 체크한다. + if (accessToken == null || accessToken.isExpired() + || StringUtils.equals(accessToken.getAccessToken(), oldToken)) { + String type = properties.getProperty("ADAPTER_TOKEN_ISSUING_CLIENT_TYPE"); + + HttpClientAccessTokenService service = HttpClientAccessTokenServiceFactory.createFactory(type); + if(service != null) { + accessToken = (AccessTokenVO) service.execute(adapterGroupName, properties); + } + tokens.put(adapterGroupName, accessToken); + } + + return accessToken; + } + + /** + * 1. 기능 : Access 토큰를 동기화하는 메서드 + * 2. 처리 개요 : Access 토큰를 동기화한다. + * - + * 3. 주의사항 + * @throws Exception + * + **/ + public synchronized void notifyAllAccessTokenVO() throws Exception { + try { + Command command = new ReloadAccessTokenCommand(); + command.setArgs(tokens); + AgentUtil.broadcast(command); + } catch (Exception e) { + throw new Exception("토큰 동기화에 실패했습니다. " +e.getMessage()); + } + } +} diff --git a/src/main/java/com/openbanking/eai/common/token/AccessTokenVO.java b/src/main/java/com/openbanking/eai/common/token/AccessTokenVO.java new file mode 100644 index 0000000..e40108c --- /dev/null +++ b/src/main/java/com/openbanking/eai/common/token/AccessTokenVO.java @@ -0,0 +1,24 @@ +package com.openbanking.eai.common.token; + +import java.util.Date; + +public interface AccessTokenVO +{ + public static final String BEARER_TYPE = "Bearer"; + + public static final String PROP_GROUP = "OAuthInfo"; + public static final String HEADER_CONTENT_TYPE = "header.content.type"; + public static final String TARGET_ADAPTER_GROUP = "target.adapter.group"; + +// public static final String OAUTH_ACCESS_TOKEN_URI = "oauth.token.uri"; +// public static final String OAUTH_CLIENT_ID = "oauth.client.id"; +// public static final String OAUTH_CLIENT_SECRET = "oauth.client.secret"; +// public static final String OAUTH_SCOPE = "oauth.scope"; +// public static final String OAUTH_GRANT_TYPE = "oauth.grant.type"; + + public abstract String getAccessToken(); + + public abstract Date getExpiration(); + + public abstract boolean isExpired(); +} diff --git a/src/main/java/com/openbanking/eai/common/token/OAuth2AccessTokenVO.java b/src/main/java/com/openbanking/eai/common/token/OAuth2AccessTokenVO.java new file mode 100644 index 0000000..78d4fb5 --- /dev/null +++ b/src/main/java/com/openbanking/eai/common/token/OAuth2AccessTokenVO.java @@ -0,0 +1,99 @@ +package com.openbanking.eai.common.token; + +import org.apache.commons.lang3.builder.ReflectionToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +import java.io.Serializable; +import java.util.Date; + +/** +* 1. 기능 : OAuth2 토큰 정보를 표현하는 Java Value Object 클래스. +* 2. 처리 개요 : OAuth2 토큰 정보를 정의한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : 관련 기능을 참조 +* @since : +* : +*/ +public class OAuth2AccessTokenVO implements AccessTokenVO, Serializable +{ + private String accessToken; + private String tokenType; + private Date expiration; + private String scope; + private String clientUseCode; + + public OAuth2AccessTokenVO() { + + } + + public OAuth2AccessTokenVO(OAuth2AccessTokenVO oAuth2AccessTokenVO) { + this.accessToken = oAuth2AccessTokenVO.getAccessToken(); + this.tokenType = oAuth2AccessTokenVO.getTokenType(); + this.expiration = oAuth2AccessTokenVO.getExpiration(); + this.scope = oAuth2AccessTokenVO.getScope(); + this.clientUseCode = oAuth2AccessTokenVO.getClientUseCode(); + } + + public String getAccessToken() { + return accessToken; + } + + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } + + public String getAuthorization() { + return String.format("%s %s", BEARER_TYPE, accessToken); + } + + public String getTokenType() { + return tokenType; + } + + public void setTokenType(String tokenType) { + this.tokenType = tokenType; + } + + public long getExpiresIn() { + return expiration == null ? 0 : Long.valueOf((expiration.getTime() - System.currentTimeMillis()) / 1000L); + } + + public void setExpiresIn(long expiresIn) { + setExpiration(new Date(System.currentTimeMillis() + (expiresIn * 1000L))); + } + + public Date getExpiration() { + return expiration; + } + + public void setExpiration(Date expiration) { + this.expiration = expiration; + } + + public boolean isExpired() { + return expiration != null && expiration.before(new Date()); + } + + public String getScope() { + return scope; + } + + public void setScope(String scope) { + this.scope = scope; + } + + public String getClientUseCode() { + return clientUseCode; + } + + public void setClientUseCode(String clientUseCode) { + this.clientUseCode = clientUseCode; + } + + public String toString() { + return ReflectionToStringBuilder.toString(this, ToStringStyle.DEFAULT_STYLE); + } +} diff --git a/src/main/java/com/openbanking/eai/common/token/client/HttpClientAccessTokenService.java b/src/main/java/com/openbanking/eai/common/token/client/HttpClientAccessTokenService.java new file mode 100644 index 0000000..edc6dc1 --- /dev/null +++ b/src/main/java/com/openbanking/eai/common/token/client/HttpClientAccessTokenService.java @@ -0,0 +1,33 @@ + +package com.openbanking.eai.common.token.client; + +import java.util.Properties; + + +/** +* 1. 기능 : HTTP 웹 컴포넌트를 GET/POST 방식으로 호출할 수 있는 기능을 제공한다. +* 2. 처리 개요 : +* * - 2009.11.24 retry 로직 제거 : 요청 +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +* @since : + +*/ +public interface HttpClientAccessTokenService { + + /** + * 1. 기능 : 토큰발급 처리에 사용한다. + * 2. 처리 개요 : + * - 속성 정보를 설정 하고 토큰 발급 URL 호출 한다. + * 3. 주의사항 + * + * @param prop Http Adapter 속성 정보 + * @return 반환 된 AccessTokenVO + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + public Object execute(String name, Properties prop) throws Exception ; + +} diff --git a/src/main/java/com/openbanking/eai/common/token/client/HttpClientAccessTokenServiceFactory.java b/src/main/java/com/openbanking/eai/common/token/client/HttpClientAccessTokenServiceFactory.java new file mode 100644 index 0000000..16b71dc --- /dev/null +++ b/src/main/java/com/openbanking/eai/common/token/client/HttpClientAccessTokenServiceFactory.java @@ -0,0 +1,43 @@ +package com.openbanking.eai.common.token.client; + +import java.util.concurrent.ConcurrentHashMap; + +import com.eactive.eai.common.util.Logger; + +public class HttpClientAccessTokenServiceFactory { + static Logger logger = Logger.getLogger(Logger.LOGGER_ADAPTER); + static private ConcurrentHashMap h = new ConcurrentHashMap(); + + /** + * + */ + public HttpClientAccessTokenServiceFactory() { + super(); + } + + /** + * 공통코드 HTTP_CLIENT_TOKEN_ISSUANCE_CLASS 에 정의된 구현체를 생성 한다. + * + * @param className + * @return + */ + @SuppressWarnings("rawtypes") + public static HttpClientAccessTokenService createFactory(String className) { + if (h.containsKey(className)) { + return (HttpClientAccessTokenService) h.get(className); + } + + HttpClientAccessTokenService service = null; + try { + Class cl = Class.forName(className); + service = (HttpClientAccessTokenService) cl.newInstance(); + if (service != null) { + h.put(className, service); + } + } catch (Exception e) { + logger.error("Cannot create a HttpClientAccessTokenService. - {}", className); + } + + return service; + } +} diff --git a/src/main/java/com/openbanking/eai/common/token/client/impl/HttpClientAccessTokenServiceForCODEF.java b/src/main/java/com/openbanking/eai/common/token/client/impl/HttpClientAccessTokenServiceForCODEF.java new file mode 100644 index 0000000..b87c461 --- /dev/null +++ b/src/main/java/com/openbanking/eai/common/token/client/impl/HttpClientAccessTokenServiceForCODEF.java @@ -0,0 +1,184 @@ + +package com.openbanking.eai.common.token.client.impl; + +import com.eactive.eai.adapter.http.secure.CustomHttpsSocketFactory; +import com.eactive.eai.adapter.http.secure.EasySSLProtocolSocketFactory; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ScpDbAgentUtil; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; +import com.openbanking.eai.common.token.client.HttpClientAccessTokenService; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpVersion; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.protocol.Protocol; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.util.Base64; +import java.util.Date; +import java.util.Properties; + + +/** +* 1. 기능 : CODEF API 시스템을 통해 토큰 발급 수행 +* 2. 처리 개요 : +* * - 2020.09.04 - 속성 정보를 설정 하고 토큰 발급 URL 호출 한다. +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : HttpClientAccessTokenServiceFactory +* @since : + +*/ +public class HttpClientAccessTokenServiceForCODEF implements HttpClientAccessTokenService { + public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static final String OAUTH_ACCESS_TOKEN_URI = "url"; + public static final String OAUTH_CLIENT_ID = "client_id"; + public static final String OAUTH_CLIENT_SECRET = "client_secret"; + public static final String OAUTH_SCOPE = "scope"; + public static final String OAUTH_GRANT_TYPE = "grant_type"; + + public static final String TOKEN_ERROR_CHECK_KEY = "token_error_check_key"; + public static final String TOKEN_ERROR_CHECK_VALUES = "token_error_check_values"; + + public AccessTokenVO execute(String name, Properties prop) throws Exception { + String url = prop.getProperty("URL"); + String encode = prop.getProperty("ENCODE"); + String timeoutTemp = prop.getProperty("HTTP_TIME_OUT", "0"); + String connectionTimeoutTemp = prop.getProperty("CONNECTION_TIMEOUT", "0"); + + int timeout = Integer.parseInt(timeoutTemp); + int connectionTimeout = Integer.parseInt(connectionTimeoutTemp); + long currentTime = System.currentTimeMillis(); + + PropManager propManager = PropManager.getInstance(); + String tokenInfo = propManager.getProperty(AccessTokenVO.PROP_GROUP, name); + + if (StringUtils.isBlank(tokenInfo)) { + throw new Exception("TokenInfo is NULL"); + } + + /** + * 프로퍼티 OAuthInfo에 프로퍼티 명이 TokenManager에서 관리하는 Key(어댑터그룹명)로 등록 + * interval, url, client_id, client_secret(암호화), scope, grant_type + * + * ex) _TST_OU_RST_SyC => + * { + * "interval": "86400", + * "url": "oauth/2.0/token", + * "client_id": "l7xx3b02c23ae8d64d2fb12a7266895f8687", + * "client_secret": "4e88d1d2edb44eadb35a1f6da9823a64", + * "scope": "read", + * "grant_type": "client_credentials" + * } + */ + JSONObject tokenInfoObject = (JSONObject) JSONValue.parse(tokenInfo); + + String oauthAccessTokenUrl = tokenInfoObject.containsKey(OAUTH_ACCESS_TOKEN_URI) ? (String)tokenInfoObject.get(OAUTH_ACCESS_TOKEN_URI) : ""; + String oauthClientId = tokenInfoObject.containsKey(OAUTH_CLIENT_ID ) ? (String)tokenInfoObject.get(OAUTH_CLIENT_ID ) : ""; + String oauthClientSecret = tokenInfoObject.containsKey(OAUTH_CLIENT_SECRET ) ? (String)tokenInfoObject.get(OAUTH_CLIENT_SECRET ) : ""; + String oauthScope = tokenInfoObject.containsKey(OAUTH_SCOPE ) ? (String)tokenInfoObject.get(OAUTH_SCOPE ) : ""; + String oauthGrantType = tokenInfoObject.containsKey(OAUTH_GRANT_TYPE ) ? (String)tokenInfoObject.get(OAUTH_GRANT_TYPE ) : ""; + + //2020-03-12 Scp 모듈 Util로 변경 + // client_secret를 복호화한다 + try { + oauthClientSecret = ScpDbAgentUtil.ScpDecB64(PropManager.getInstance().getProperties(ScpDbAgentUtil.EXT_MODULE), oauthClientSecret, "EUC-KR"); + } catch (Exception e) { + logger.error("addInboundErrorInfo] scpdb_agent encryption Error - " + e.getMessage()); + } + + String uri = ""; + if (StringUtils.contains(oauthAccessTokenUrl, "http://") + || StringUtils.contains(oauthAccessTokenUrl, "https://")) { + uri = oauthAccessTokenUrl; + } else { + uri = url + "/" + oauthAccessTokenUrl; + } + + String contentType = propManager.getProperty(AccessTokenVO.PROP_GROUP, AccessTokenVO.HEADER_CONTENT_TYPE); + + HttpClient mclient = new HttpClient(); + PostMethod httpMethod = new PostMethod(uri); + + if(timeout > -1) { + httpMethod.getParams().setSoTimeout(timeout); + } + + if ( connectionTimeout != 0) { + httpMethod.getParams().setParameter("http.connection.timeout", connectionTimeout); + } + httpMethod.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_0); + + if(uri != null && uri.startsWith("https")){ + Protocol.registerProtocol("https", new Protocol("https", + new CustomHttpsSocketFactory(new EasySSLProtocolSocketFactory()), 443)); + } + + try { + httpMethod.setParameter(OAUTH_GRANT_TYPE , oauthGrantType ); + httpMethod.setParameter(OAUTH_SCOPE , oauthScope ); //// + + String basicAuth = oauthClientId + ":" + oauthClientSecret; + basicAuth = "Basic " + Base64.getEncoder().encodeToString(basicAuth.getBytes()); + httpMethod.setRequestHeader("Authorization", basicAuth); + httpMethod.setRequestHeader("Content-Type", contentType + "; charset=" + encode); + + logger.debug("HttpClientAccessTokenServiceForCODEF] oauthClientId = ["+ oauthClientId +"]"); + logger.debug("HttpClientAccessTokenServiceForCODEF] oauthClientSecret = ["+ oauthClientSecret +"]"); + logger.debug("HttpClientAccessTokenServiceForCODEF] oauthScope = ["+ oauthScope +"]"); + logger.debug("HttpClientAccessTokenServiceForCODEF] oauthGrantType = ["+ oauthGrantType +"]"); + logger.debug("HttpClientAccessTokenServiceForCODEF] contentType = ["+ contentType +"]"); + logger.debug("HttpClientAccessTokenServiceForCODEF] encode = ["+ encode +"]"); + logger.debug("HttpClientAccessTokenServiceForCODEF] Authorization = ["+ basicAuth +"]"); + + int status = mclient.executeMethod(httpMethod); + + if (status !=200) { + throw new Exception ("oauth token receive status fail value= " + status); + } + + byte[] responseBody = httpMethod.getResponseBody(); + String responseString = new String(responseBody, encode); + + OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); + + if (StringUtils.isNotBlank(responseString)) { + logger.debug("HttpClientAccessTokenServiceForCODEF] oauthToken RECV = ["+ responseString +"]"); + + JSONObject responseJSON = (JSONObject) JSONValue.parse(responseString); + + if (responseJSON.containsKey("access_token") + && responseJSON.containsKey("token_type") + && responseJSON.containsKey("expires_in") + && responseJSON.containsKey("scope")) { + accessToken.setAccessToken((String) responseJSON.get("access_token")); + accessToken.setTokenType ((String) responseJSON.get("token_type" )); + accessToken.setExpiration (new Date(currentTime + ((long) responseJSON.get("expires_in") * 1000L))); + accessToken.setScope ((String) responseJSON.get("scope" )); + } + + if (responseJSON.containsKey("client_use_code")) { + accessToken.setClientUseCode((String) responseJSON.get("client_use_code")); + } + + logger.debug("HttpClientAccessTokenServiceForCODEF] oauthToken ="+ accessToken.toString()); + } else { + throw new Exception ("oauth token return null"); + } + + return accessToken; + // 오류 처리 상세화 필요 + } catch (Exception e) { + logger.error("HttpClientAccessTokenServiceForCODEF] oauth token fail : " + e.toString() ,e); + throw e; + } finally { + httpMethod.releaseConnection(); + } + } +} diff --git a/src/main/java/com/openbanking/eai/common/token/client/impl/HttpClientAccessTokenServiceForKFTC.java b/src/main/java/com/openbanking/eai/common/token/client/impl/HttpClientAccessTokenServiceForKFTC.java new file mode 100644 index 0000000..ac3074f --- /dev/null +++ b/src/main/java/com/openbanking/eai/common/token/client/impl/HttpClientAccessTokenServiceForKFTC.java @@ -0,0 +1,177 @@ + +package com.openbanking.eai.common.token.client.impl; + +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; +import com.eactive.eai.common.util.ScpDbAgentUtil; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; +import com.openbanking.eai.common.token.client.HttpClientAccessTokenService; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpVersion; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.lang3.StringUtils; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.math.BigDecimal; +import java.util.Date; +import java.util.Properties; + + +/** +* 1. 기능 : HTTP 웹 컴포넌트를 POST 방식으로 호출할 수 있는 기능을 제공한다. +* 2. 처리 개요 : +* * - 2009.11.24 retry 로직 제거 : 요청 +* 3. 주의사항 +* +* @author : +* @version : v 1.0.0 +* @see : WLIAdapterFactory.java, WLIAdapter.java, WLIDefaultAdapter.java +* @since : + +*/ +public class HttpClientAccessTokenServiceForKFTC implements HttpClientAccessTokenService { + + public static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); + + public static final String OAUTH_ACCESS_TOKEN_URI = "url"; + public static final String OAUTH_CLIENT_ID = "client_id"; + public static final String OAUTH_CLIENT_SECRET = "client_secret"; + public static final String OAUTH_SCOPE = "scope"; + public static final String OAUTH_GRANT_TYPE = "grant_type"; + + /** + * 1. 기능 : 결제원 오픈뱅킹 토큰 발급에 사용 + * 2. 처리 개요 : + * - 속성 정보를 설정 하고 토큰 발급 URL 호출 한다. + * 3. 주의사항 + * + * @param prop Http Adapter 속성 정보 + * @return 반환 된 AccessTokenVO + * @exception Exception 수동 시스템 간 통신 중 발생 + **/ + public AccessTokenVO execute(String name, Properties prop) throws Exception { + + String url = prop.getProperty("URL"); + String encode = prop.getProperty("ENCODE"); + String timeoutTemp = prop.getProperty("HTTP_TIME_OUT", "0"); + String connectionTimeoutTemp = prop.getProperty("CONNECTION_TIMEOUT", "0"); + +// // OAuth 정보 관리 대상을 어댑터의 프로퍼티로 변경 +// String oauthAccessTokenUrl = prop.getProperty(AccessTokenVO.OAUTH_ACCESS_TOKEN_URL); +// String oauthClientId = prop.getProperty(AccessTokenVO.OAUTH_CLIENT_ID); +// String oauthClientSecret = prop.getProperty(AccessTokenVO.OAUTH_CLIENT_SECRET); +// String oauthScope = prop.getProperty(AccessTokenVO.OAUTH_SCOPE); +// String oauthGrantType = prop.getProperty(AccessTokenVO.OAUTH_GRANT_TYPE); + + int timeout = Integer.parseInt(timeoutTemp); + int connectionTimeout = Integer.parseInt(connectionTimeoutTemp); + long currentTime = System.currentTimeMillis(); + + PropManager propManager = PropManager.getInstance(); + String tokenInfo = propManager.getProperty(AccessTokenVO.PROP_GROUP, name); + + if (StringUtils.isBlank(tokenInfo)) { + throw new Exception("TokenInfo is NULL"); + } + + /** + * 프로퍼티 OAuthInfo에 프로퍼티 명이 TokenManager에서 관리하는 Key(어댑터그룹명)로 등록 + * interval, url, client_id, client_secret(암호화), scope, grant_type + * + * ex) _TST_OU_RST_SyC => {"interval":"86400","url":"oauth/2.0/token","client_id":"l7xx18ddb941fc0d4a6a910f5e132186aa88","client_secret":"18a91f9579994ce8ac10f1aab39ce205","scope":"sa","grant_type":"client_credentials"} + */ + JSONObject tokenInfoObject = (JSONObject) JSONValue.parse(tokenInfo); + + String oauthAccessTokenUrl = tokenInfoObject.containsKey(OAUTH_ACCESS_TOKEN_URI) ? (String)tokenInfoObject.get(OAUTH_ACCESS_TOKEN_URI) : ""; + String oauthClientId = tokenInfoObject.containsKey(OAUTH_CLIENT_ID ) ? (String)tokenInfoObject.get(OAUTH_CLIENT_ID ) : ""; + String oauthClientSecret = tokenInfoObject.containsKey(OAUTH_CLIENT_SECRET ) ? (String)tokenInfoObject.get(OAUTH_CLIENT_SECRET ) : ""; + String oauthScope = tokenInfoObject.containsKey(OAUTH_SCOPE ) ? (String)tokenInfoObject.get(OAUTH_SCOPE ) : ""; + String oauthGrantType = tokenInfoObject.containsKey(OAUTH_GRANT_TYPE ) ? (String)tokenInfoObject.get(OAUTH_GRANT_TYPE ) : ""; + + //2020-03-12 Scp 모듈 Util로 변경 + // client_secret를 복호화한다 + try { + oauthClientSecret = ScpDbAgentUtil.ScpDecB64(PropManager.getInstance().getProperties(ScpDbAgentUtil.EXT_MODULE), oauthClientSecret, "EUC-KR"); + } catch (Exception e) { + logger.error("addInboundErrorInfo] scpdb_agent encryption Error - " + e.getMessage()); + } + + String uri = url + "/" + oauthAccessTokenUrl; + String contentType = propManager.getProperty(AccessTokenVO.PROP_GROUP, AccessTokenVO.HEADER_CONTENT_TYPE); + + HttpClient mclient = new HttpClient(); + PostMethod httpMethod = new PostMethod(uri); + + if(timeout > -1) { + httpMethod.getParams().setSoTimeout(timeout); + } + + if ( connectionTimeout != 0) { + httpMethod.getParams().setParameter("http.connection.timeout", connectionTimeout); + } + httpMethod.getParams().setParameter("http.protocol.version", HttpVersion.HTTP_1_0); + + try { + httpMethod.setParameter(OAUTH_CLIENT_ID , oauthClientId ); + httpMethod.setParameter(OAUTH_CLIENT_SECRET, oauthClientSecret); + httpMethod.setParameter(OAUTH_SCOPE , oauthScope ); + httpMethod.setParameter(OAUTH_GRANT_TYPE , oauthGrantType ); + + httpMethod.setRequestHeader("Content-Type", contentType + "; charset=" + encode); + + logger.debug("HttpClientAccessTokenServiceKFTC] oauthClientId = ["+ oauthClientId +"]"); + logger.debug("HttpClientAccessTokenServiceKFTC] oauthClientSecret = ["+ oauthClientSecret +"]"); + logger.debug("HttpClientAccessTokenServiceKFTC] oauthScope = ["+ oauthScope +"]"); + logger.debug("HttpClientAccessTokenServiceKFTC] oauthGrantType = ["+ oauthGrantType +"]"); + logger.debug("HttpClientAccessTokenServiceKFTC] contentType = ["+ contentType +"]"); + logger.debug("HttpClientAccessTokenServiceKFTC] encode = ["+ encode +"]"); + + int status = mclient.executeMethod(httpMethod); + + if (status !=200) { + throw new Exception ("oauth token receive status fail value= " + status); + } + + byte[] responseBody = httpMethod.getResponseBody(); + String responseString = new String(responseBody, encode); + + OAuth2AccessTokenVO accessToken = new OAuth2AccessTokenVO(); + + if (StringUtils.isNotBlank(responseString)) { + logger.debug("HttpClientAccessTokenServiceKFTC] oauthToken RECV = ["+ responseString +"]"); + + JSONObject responseJSON = (JSONObject) JSONValue.parse(responseString); + + if (responseJSON.containsKey("access_token") + && responseJSON.containsKey("token_type") + && responseJSON.containsKey("expires_in") + && responseJSON.containsKey("scope")) { + accessToken.setAccessToken((String) responseJSON.get("access_token")); + accessToken.setTokenType ((String) responseJSON.get("token_type" )); + + accessToken.setExpiration (new Date(currentTime + ((BigDecimal)responseJSON.get("expires_in")).longValue()* 1000L)); +// accessToken.setExpiration (new Date(currentTime + ((long) responseJSON.get("expires_in") * 1000L))); + accessToken.setScope ((String) responseJSON.get("scope" )); + } + + if (responseJSON.containsKey("client_use_code")) { + accessToken.setClientUseCode((String) responseJSON.get("client_use_code")); + } + + logger.debug("HttpClientAccessTokenServiceKFTC] oauthToken ="+ accessToken.toString()); + } else { + throw new Exception ("oauth token return null"); + } + + return accessToken; + // 오류 처리 상세화 필요 + } catch (Exception e) { + logger.error("HttpClientAccessTokenServiceKFTC] oauth token fail : " + e.toString() ,e); + throw e; + } finally { + httpMethod.releaseConnection(); + } + } +} diff --git a/src/main/java/com/openbanking/eai/common/token/servlet/AccessTokenServlet.java b/src/main/java/com/openbanking/eai/common/token/servlet/AccessTokenServlet.java new file mode 100644 index 0000000..4ee1d80 --- /dev/null +++ b/src/main/java/com/openbanking/eai/common/token/servlet/AccessTokenServlet.java @@ -0,0 +1,231 @@ +package com.openbanking.eai.common.token.servlet; + +import com.eactive.eai.adapter.AdapterManager; +import com.eactive.eai.adapter.AdapterPropManager; +import com.eactive.eai.adapter.AdapterVO; +import com.eactive.eai.adapter.socket2.common.ExceptionStackTrace; +import com.eactive.eai.adapter.socket2.config.SocketAdapterManager; +import com.eactive.eai.adapter.socket2.config.SocketLoggerManager; +import com.eactive.eai.adapter.socket2.protocol.http.HttpServlet; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpRequest; +import com.eactive.eai.adapter.socket2.protocol.http.codec.HttpResponse; +import com.eactive.eai.adapter.socket2.protocol.http.servlet.ThreadDumpUtil; +import com.eactive.eai.common.property.PropGroupVO; +import com.eactive.eai.common.property.PropManager; +import com.eactive.eai.common.util.Logger; +import com.openbanking.eai.common.token.AccessTokenManager; +import com.openbanking.eai.common.token.AccessTokenVO; +import com.openbanking.eai.common.token.OAuth2AccessTokenVO; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; + +import java.util.Properties; + +public class AccessTokenServlet extends HttpServlet { + final static SocketAdapterManager manager = SocketAdapterManager.getInstance(); + static Logger logger = SocketLoggerManager.getInstance().getLogger("FileLogger{NET}_HTTP"); + + protected void doService(HttpRequest request, HttpResponse response) throws Exception { + String command = request.getContext(); + if (command.lastIndexOf('/') == -1) { + command = ""; + } else { + command = command.substring(command.indexOf('/')+1); + } + + String result = ""; + + try { + String adapterGroupName = request.getParameter("adapter"); + + if (command == null || "".equals(command) || "show".equals(command)) { + result = show(adapterGroupName); + } else if (command.startsWith("refresh")) { + logger.fatal("AccessToken | " + adapterGroupName + " | refresh - " + request.getSession()); + result = refresh(adapterGroupName); + } else if (command.startsWith("start")) { + logger.fatal("AccessToken | " + adapterGroupName + " | start - " + request.getSession()); + result = start(adapterGroupName); + } else if (command.startsWith("stop")) { + logger.fatal("AccessToken | " + adapterGroupName + " | stop - " + request.getSession()); + result = stop(adapterGroupName); + } else { + response.setResponseCode(404); + return; + } + + } catch(Throwable e) { + result = "
" + ExceptionStackTrace.dump(e) + "
"; + } + + response.setContentType("text/html"); + response.setResponseCode(HttpResponse.HTTP_STATUS_SUCCESS); + response.appendBody(result); + } + + final static String SCRIPT = + " \n"; + + private String show(String adapterGroupName) throws Exception { + StringBuffer sb = new StringBuffer(); + sb.append(SCRIPT); + + AccessTokenManager manager = AccessTokenManager.getInstance(); + +// HashMap tokens = manager.getAllAccessTokenVO(); +// for (String key : tokens.keySet()) { + + String adapterGroupNameList = manager.getTargetAdapterGroup(); + String[] adapterGroupNames = adapterGroupNameList.split("[,]"); + + ThreadGroup it = Thread.currentThread().getThreadGroup(); + Thread[] threads = new Thread[it.activeCount()] ; + it.enumerate(threads); + + for (String key : adapterGroupNames) { + if (adapterGroupName != null && !"".equals(adapterGroupName) && adapterGroupName.indexOf(key) < 0) { + continue; + } + + sb.append("¨Ó " + key + ""); + + String status = manager.getStatus(key); + + if ("STARTED".equals(status)) { + sb.append(" (" + status + ")"); + } else { + sb.append(" (" + status + ")"); + } + + sb.append("
"); + sb.append(" (refresh"); + sb.append("|start"); + sb.append("|stop)"); + sb.append("
"); + + sb.append("\n"); + + OAuth2AccessTokenVO token = (OAuth2AccessTokenVO) manager.getAccessTokenVO(key); + + if (token != null) { + sb.append(String.format("%4s %-20s : %s\n", "", "access_token", token.getAccessToken())); + sb.append(String.format("%4s %-20s : %s\n", "", "expiration", token.getExpiration())); + sb.append(String.format("%4s %-20s : %s\n", "", "is_expired", token.isExpired())); + sb.append(String.format("%4s %-20s : %s\n", "", "scope", token.getScope())); + sb.append(String.format("%4s %-20s : %s\n", "", "token_type", token.getTokenType())); + sb.append(String.format("%4s %-20s : %s\n", "", "client_use_code", token.getClientUseCode())); + } + + PropGroupVO vo = PropManager.getInstance().getPropGroupVO(AccessTokenVO.PROP_GROUP); + String tokenInfo = vo.getProperty(key); + + if (tokenInfo != null) { + sb.append("\n"); + + JSONObject tokenInfoObject = (JSONObject) JSONValue.parse(tokenInfo); + + int interval = Integer.parseInt(tokenInfoObject.get("interval") != null ? (String) tokenInfoObject.get("interval") : "0"); + String hms = "sec"; + + if (interval / 60 / 60 > 1) { + interval = interval / 60 / 60; + hms = "hour"; + } else if (interval / 60 > 1) { + interval = interval / 60; + hms = "min"; + } + + boolean adapter = false; + String url = (String) tokenInfoObject.get("url"); + + try { + AdapterVO avo = (AdapterVO) AdapterManager.getInstance().getAdapterGroupVO(key).getAdapters().next(); + Properties properties = AdapterPropManager.getInstance().getProperties(avo.getPropGroupName()); + url = properties.getProperty("URL") + "/" + url; + + adapter = true; + } catch (Exception ignore) { + adapter = false;; + } + + sb.append(String.format("%4s %-20s : %s\n", "", "adapter", adapter)); + sb.append(String.format("%4s %-20s : %s %s\n", "", "interval", interval, hms)); + sb.append(String.format("%4s %-20s : %s\n", "", "url", url)); + sb.append(String.format("%4s %-20s : %s\n", "", "grant_type", (String) tokenInfoObject.get("grant_type"))); + } + + /** + * threads info + */ + sb.append("\n threads"); + sb.append("\n"); + sb.append(""); + for (int i=0; i"); + sb.append(ThreadDumpUtil.getStackTrace(threads[i])); + sb.append(""); + } + } catch(Exception e) { + logger.error("Error", e) ; + } + } + sb.append("
"); + sb.append("
"); + sb.append("\n"); + sb.append("\n"); + +// String filter = key + "-AccessToken"; +// sb.append(""); +// sb.append(ThreadDumpUtil.dump(filter)); +// sb.append(""); + } + + sb.append("button"); + + return "
" + sb.toString() + "
"; + } + + private String refresh(String adapterGroupName) throws Exception { + + AccessTokenManager manager = AccessTokenManager.getInstance(); + +// String token = manager.getAccessToken(adapterGroupName); +// if (token == null) +// return "
token not exist
"; + + manager.refresh(adapterGroupName, true); + + return adapterGroupName + " | successfully refreshed"; + } + + private String start(String adapterGroupName) throws Exception { + + AccessTokenManager manager = AccessTokenManager.getInstance(); + manager.startToken(adapterGroupName); + + return adapterGroupName + " | successfully started"; + } + + private String stop(String adapterGroupName) throws Exception { + + AccessTokenManager manager = AccessTokenManager.getInstance(); + manager.stopToken(adapterGroupName); + + return adapterGroupName + " | successfully stoped"; + } +} \ No newline at end of file diff --git a/src/test/java/com/eactive/eai/authserver/dao/ClientDAOTest.java b/src/test/java/com/eactive/eai/authserver/dao/ClientDAOTest.java new file mode 100644 index 0000000..1f4388c --- /dev/null +++ b/src/test/java/com/eactive/eai/authserver/dao/ClientDAOTest.java @@ -0,0 +1,54 @@ +package com.eactive.eai.authserver.dao; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.authserver" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { "com.eactive.eai.authserver" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.authserver" }) +@Sql({ "/com/eactive/eai/authserver/init_tseaiau01.sql" }) +class ClientDAOTest { + + @Autowired + ClientDAO clientDAO; + + @Test + void testLoadClientDetails() throws DAOException { + // given + + // when + clientDAO.loadClientDetails(); + + // then + assertNotNull(clientDAO.loadClientDetails()); + assertTrue(clientDAO.loadClientDetails().size() > 0); + } + + @Test + void testGetClientByI() throws DAOException { + // given + String clientId = "R4v8qDMVOmLJ1X4yKQslrKmhVOu2TNb2"; + // when + clientDAO.getClientById(clientId); + + // then + assertNotNull(clientDAO.getClientById(clientId)); + assertTrue(clientDAO.getClientById(clientId).getClientId().length() > 0); + } + +} diff --git a/src/test/java/com/eactive/eai/authserver/dao/ScopeDAOTest.java b/src/test/java/com/eactive/eai/authserver/dao/ScopeDAOTest.java new file mode 100644 index 0000000..997ca81 --- /dev/null +++ b/src/test/java/com/eactive/eai/authserver/dao/ScopeDAOTest.java @@ -0,0 +1,78 @@ +package com.eactive.eai.authserver.dao; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.authserver" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.authserver" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.authserver" }) +@Sql({ "/com/eactive/eai/authserver/init_tseaiau04.sql" }) +class ScopeDAOTest { + + @Autowired + ScopeDAO scopeDAO; + + @Test + void testLoadApiScopeRelations() throws DAOException { + // given + + // when + scopeDAO.loadApiScopeRelations(); + + // then + assertNotNull(scopeDAO.loadApiScopeRelations()); + assertTrue(scopeDAO.loadApiScopeRelations().size() > 0); + } + + @Test + void testGetApiScopeRelationsByApiId() throws DAOException { + // given + String apiId = "test.Bzwksvckeyname"; + // when + scopeDAO.getApiScopeRelationsByApiId(apiId); + + // then + assertNotNull(scopeDAO.getApiScopeRelationsByApiId(apiId)); + assertTrue(scopeDAO.getApiScopeRelationsByApiId(apiId).size() > 0); + } + + @Test + void testGetApiScopeRelationsByScopeId() throws DAOException { + // given + String scopeId = "invest.account"; + // when + scopeDAO.getApiScopeRelationsByScopeId(scopeId); + + // then + assertNotNull(scopeDAO.getApiScopeRelationsByScopeId(scopeId)); + assertTrue(scopeDAO.getApiScopeRelationsByScopeId(scopeId).size() > 0); + } + + @Test + void testHasApiScopeRelation() throws DAOException { + // given + String apiId = "test.Bzwksvckeyname"; + String scopeId = "test.Scopeid"; + // when + scopeDAO.hasApiScopeRelation(apiId, scopeId); + + // then + assertTrue(scopeDAO.hasApiScopeRelation(apiId, scopeId)); + } +} diff --git a/src/test/java/com/eactive/eai/authserver/dao/UserDAOTest.java b/src/test/java/com/eactive/eai/authserver/dao/UserDAOTest.java new file mode 100644 index 0000000..78778e1 --- /dev/null +++ b/src/test/java/com/eactive/eai/authserver/dao/UserDAOTest.java @@ -0,0 +1,41 @@ + +package com.eactive.eai.authserver.dao; + +import static org.junit.Assert.assertNotNull; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.authserver" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { "com.eactive.eai.authserver" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.authserver" }) +@Sql({ "/com/eactive/eai/authserver/init_tseaiau02.sql" }) +class UserDAOTest { + + @Autowired + UserDAO userDAO; + + @Test + void testStart() throws DAOException { + // given + String userId = "testId"; + + // when + userDAO.getUserByUserId(userId); + + // then + assertNotNull(userDAO.getUserByUserId(userId)); + } +} diff --git a/src/test/java/com/eactive/eai/authserver/service/OAuth2ManagerTest.java b/src/test/java/com/eactive/eai/authserver/service/OAuth2ManagerTest.java new file mode 100644 index 0000000..5d8a552 --- /dev/null +++ b/src/test/java/com/eactive/eai/authserver/service/OAuth2ManagerTest.java @@ -0,0 +1,43 @@ +package com.eactive.eai.authserver.service; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.authserver" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { "com.eactive.eai.authserver" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.authserver" }) +@Sql({ "/com/eactive/eai/authserver/init_tseaiau01.sql", "/com/eactive/eai/authserver/init_tseaiau04.sql" }) +class OAuth2ManagerTest { + + @Autowired + OAuth2Manager oAuth2Manager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + oAuth2Manager.start(); + + // then + assertNotNull(oAuth2Manager.getApiScopeMap()); + assertTrue(oAuth2Manager.getApiScopeMap().size() > 0); + assertNotNull(oAuth2Manager.getClientDeatilsStore()); + assertTrue(oAuth2Manager.getClientDeatilsStore().size() > 0); + } +} diff --git a/src/test/java/com/eactive/eai/authserver/service/UserDetailsServiceImplTest.java b/src/test/java/com/eactive/eai/authserver/service/UserDetailsServiceImplTest.java new file mode 100644 index 0000000..882f63a --- /dev/null +++ b/src/test/java/com/eactive/eai/authserver/service/UserDetailsServiceImplTest.java @@ -0,0 +1,40 @@ +package com.eactive.eai.authserver.service; + +import static org.junit.Assert.assertNotNull; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.authserver" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { "com.eactive.eai.authserver" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.authserver" }) +@Sql({ "/com/eactive/eai/authserver/init_tseaiau02.sql" }) +class UserDetailsServiceImplTest { + + @Autowired + UserDetailsServiceImpl userDetailsServiceImpl; + + @Test + void testStart() throws DAOException { + // given + String userId = "testId"; + // when + userDetailsServiceImpl.loadUserByUsername(userId); + + // then + assertNotNull(userDetailsServiceImpl.loadUserByUsername(userId)); + } + +} diff --git a/src/test/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapDAOTest.java b/src/test/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapDAOTest.java new file mode 100644 index 0000000..fcddb8e --- /dev/null +++ b/src/test/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapDAOTest.java @@ -0,0 +1,61 @@ +package com.eactive.eai.common.b2badaptermapping; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class, EAIServerManager.class }) +@ComponentScan({ "com.eactive.eai.common.b2badaptermapping" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.b2badaptermapping" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.b2badaptermapping" }) +@Sql({ "/com/eactive/eai/common/b2badaptermapping/init_tseaifr07.sql" }) +class B2BAdapterMapDAOTest { + + @SpyBean + B2BAdapterMapDAO b2bAdapterMapDAO; + + @MockBean + private EAIServerManager eaiServerManager; + + @Test + void getAllB2BAdapterMapsTest() throws Exception { + // given + String eaiInstCd = "fepOnlSvr12"; + + // when + b2bAdapterMapDAO.getAllB2BAdapterMaps(eaiInstCd); + + // then + assertNotNull(b2bAdapterMapDAO.getAllB2BAdapterMaps(eaiInstCd)); + assertTrue(b2bAdapterMapDAO.getAllB2BAdapterMaps(eaiInstCd).size() > 0); + } + + @Test + void getB2BAdapterMapTest() throws Exception { + // given + String eaiInstCd = "fepOnlSvr22"; + String eaiSvcCd = "ATS0210012270R2"; + + // when + b2bAdapterMapDAO.getB2BAdapterMap(eaiInstCd, eaiSvcCd); + + // then + assertNotNull(b2bAdapterMapDAO.getB2BAdapterMap(eaiInstCd, eaiSvcCd)); + assertTrue(b2bAdapterMapDAO.getB2BAdapterMap(eaiInstCd, eaiSvcCd).size() > 0); + } +} diff --git a/src/test/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapManagerTest.java b/src/test/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapManagerTest.java new file mode 100644 index 0000000..bb803a9 --- /dev/null +++ b/src/test/java/com/eactive/eai/common/b2badaptermapping/B2BAdapterMapManagerTest.java @@ -0,0 +1,50 @@ +package com.eactive.eai.common.b2badaptermapping; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.BDDMockito.given; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class, EAIServerManager.class }) +@ComponentScan({ "com.eactive.eai.common.b2badaptermapping" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.b2badaptermapping" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.b2badaptermapping" }) +@Sql({ "/com/eactive/eai/common/b2badaptermapping/init_tseaifr07.sql" }) +class B2BAdapterMapManagerTest { + + @SpyBean + B2BAdapterMapManager b2bAdapterMapManager; + + @MockBean + private EAIServerManager eaiServerManager; + + @Test + void testStart() throws Exception { + // given + given(eaiServerManager.getLocalServerName()).willReturn("fepOnlSvr12"); + + // when + b2bAdapterMapManager.start(); + + // then + assertNotNull(b2bAdapterMapManager.getAllKeyNames()); + assertTrue(b2bAdapterMapManager.getAllKeyNames().length > 0); + + } + +} diff --git a/src/test/java/com/eactive/eai/common/b2bextractor/B2BExtractManagerTest.java b/src/test/java/com/eactive/eai/common/b2bextractor/B2BExtractManagerTest.java new file mode 100644 index 0000000..b45bfe8 --- /dev/null +++ b/src/test/java/com/eactive/eai/common/b2bextractor/B2BExtractManagerTest.java @@ -0,0 +1,43 @@ +package com.eactive.eai.common.b2bextractor; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.mock.mockito.SpyBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.b2bextractor" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.b2bextractor" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.b2bextractor" }) +@Sql({ "/com/eactive/eai/common/b2bextractor/init_tseaifr06.sql" }) +class B2BExtractManagerTest { + + @SpyBean + B2BExtractManager b2bExtractManager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + b2bExtractManager.start(); + + // then + assertNotNull(b2bExtractManager.getAllKeyNames()); + assertTrue(b2bExtractManager.getAllKeyNames().length > 0); + } + +} diff --git a/src/test/java/com/eactive/eai/common/b2bservice/B2BServiceManagerTest.java b/src/test/java/com/eactive/eai/common/b2bservice/B2BServiceManagerTest.java new file mode 100644 index 0000000..25ec629 --- /dev/null +++ b/src/test/java/com/eactive/eai/common/b2bservice/B2BServiceManagerTest.java @@ -0,0 +1,44 @@ +package com.eactive.eai.common.b2bservice; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.b2bservice" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.b2bservice" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.b2bservice" }) +@Sql({ "/com/eactive/eai/common/b2bservice/init_tseaihe03.sql" }) +class B2BServiceManagerTest { + + @Autowired + B2BServiceManager b2bServiceManager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + b2bServiceManager.start(); + + // then + assertNotNull(b2bServiceManager.getAllKeys()); + assertTrue(b2bServiceManager.getAllKeys().length > 0); + + } + +} diff --git a/src/test/java/com/eactive/eai/common/bizkey/BizKeyDAOTest.java b/src/test/java/com/eactive/eai/common/bizkey/BizKeyDAOTest.java new file mode 100644 index 0000000..eb58c8c --- /dev/null +++ b/src/test/java/com/eactive/eai/common/bizkey/BizKeyDAOTest.java @@ -0,0 +1,55 @@ +package com.eactive.eai.common.bizkey; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.bizkey" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.bizkey" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.bizkey" }) +@Sql({ "/com/eactive/eai/common/bizkey/init_tseaifr03.sql" }) +class BizKeyDAOTest { + @Autowired + BizKeyDAO bizKeyDAO; + + @Test + void getAllBizKeysTest() throws Exception { + // given + + // when + bizKeyDAO.getAllBizKeys(); + + // then + assertNotNull(bizKeyDAO.getAllBizKeys()); + assertTrue(bizKeyDAO.getAllBizKeys().size() > 0); + } + + @Test + void getBizKeyTest() throws Exception { + // given + String eaiSvcCd = "AC1B805Q01S2"; + String exrClsNm = "TR"; + + // when + bizKeyDAO.getBizKey(eaiSvcCd, exrClsNm); + + // then + assertNotNull(bizKeyDAO.getBizKey(eaiSvcCd, exrClsNm)); + assertTrue(bizKeyDAO.getBizKey(eaiSvcCd, exrClsNm).size() > 0); + assertTrue(bizKeyDAO.getBizKey(eaiSvcCd, exrClsNm).toString().length() > 0); + } +} diff --git a/src/test/java/com/eactive/eai/common/bizkey/BizKeyManagerTest.java b/src/test/java/com/eactive/eai/common/bizkey/BizKeyManagerTest.java new file mode 100644 index 0000000..2133497 --- /dev/null +++ b/src/test/java/com/eactive/eai/common/bizkey/BizKeyManagerTest.java @@ -0,0 +1,43 @@ +package com.eactive.eai.common.bizkey; + +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.bizkey" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.bizkey" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.bizkey" }) +@Sql({ "/com/eactive/eai/common/bizkey/init_tseaifr03.sql" }) +class BizKeyManagerTest { + @Autowired + BizKeyManager bizKeyManager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + bizKeyManager.start(); + + // then + assertNotNull(bizKeyManager.getAllKeyNames()); + assertTrue(bizKeyManager.getAllKeyNames().length > 0); + + } + +} diff --git a/src/test/java/com/eactive/eai/common/c2rservice/C2RServiceDAOTest.java b/src/test/java/com/eactive/eai/common/c2rservice/C2RServiceDAOTest.java new file mode 100644 index 0000000..b4bc60b --- /dev/null +++ b/src/test/java/com/eactive/eai/common/c2rservice/C2RServiceDAOTest.java @@ -0,0 +1,55 @@ +package com.eactive.eai.common.c2rservice; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.c2rservice" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.c2rservice" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.c2rservice" }) +@Sql({ "/com/eactive/eai/common/c2rservice/init_tseaihe04.sql" }) +class C2RServiceDAOTest { + + @Autowired + C2RServiceDAO c2rServiceDAO; + + @Test + void getAllC2RServices() throws DAOException { + // given + + // when + c2rServiceDAO.getAllC2RServices(); + + // then + assertNotNull(c2rServiceDAO.getAllC2RServices()); + assertTrue(c2rServiceDAO.getAllC2RServices().size() > 0); + } + +// @Test +// void testStart() throws DAOException { +// // given +// String c2rExtnlInstiCd = "50500226"; +// +// // when +// c2rServiceDAO.getC2RService(c2rExtnlInstiCd); +// +// // then +//// assertNotNull(c2rServiceDAO.getC2RService(c2rExtnlInstiCd)); +// assertTrue(c2rServiceDAO.getC2RService(c2rExtnlInstiCd).size() > 0); +// } +} diff --git a/src/test/java/com/eactive/eai/common/c2rservice/C2RServiceManagerTest.java b/src/test/java/com/eactive/eai/common/c2rservice/C2RServiceManagerTest.java new file mode 100644 index 0000000..c09c4a3 --- /dev/null +++ b/src/test/java/com/eactive/eai/common/c2rservice/C2RServiceManagerTest.java @@ -0,0 +1,44 @@ +package com.eactive.eai.common.c2rservice; + +import static org.junit.Assert.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.c2rservice" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.c2rservice" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.c2rservice" }) +@Sql({ "/com/eactive/eai/common/c2rservice/init_tseaihe04.sql" }) +class C2RServiceManagerTest { + + @Autowired + C2RServiceManager c2rServiceManager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + c2rServiceManager.start(); + + // then + assertNotNull(c2rServiceManager.getAllKeys()); + assertTrue(c2rServiceManager.getAllKeys().length > 0); + + } + +} diff --git a/src/test/java/com/eactive/eai/common/inflow/InflowControlManagerTest.java b/src/test/java/com/eactive/eai/common/inflow/InflowControlManagerTest.java new file mode 100644 index 0000000..60fae8b --- /dev/null +++ b/src/test/java/com/eactive/eai/common/inflow/InflowControlManagerTest.java @@ -0,0 +1,41 @@ +package com.eactive.eai.common.inflow; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.inflow" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.inflow" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.inflow" }) +@Sql({ "/com/eactive/eai/common/inflow/init_tseaifr09.sql", "/com/eactive/eai/common/inflow/init_tseaifr11.sql" }) +class InflowControlManagerTest { + + @Autowired + InflowControlManager inflowControlManager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + inflowControlManager.start(); + + // then + assertTrue(inflowControlManager.isStarted()); + } + +} diff --git a/src/test/java/com/eactive/eai/common/message/EAIMessageDAOTest.java b/src/test/java/com/eactive/eai/common/message/EAIMessageDAOTest.java new file mode 100644 index 0000000..5563501 --- /dev/null +++ b/src/test/java/com/eactive/eai/common/message/EAIMessageDAOTest.java @@ -0,0 +1,57 @@ +package com.eactive.eai.common.message; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.message" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.message" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.message" }) +@Sql({ "/com/eactive/eai/common/message/init_tseaihe01.sql", "/com/eactive/eai/common/message/init_tseaihe02.sql", + "/com/eactive/eai/common/message/init_tseaifr01.sql", "/com/eactive/eai/common/message/init_tseaims02.sql" }) +class EAIMessageDAOTest { + @Autowired + EAIMessageDAO eaiMessageDAO; + + @Test + void getAllEAIMessages() throws DAOException { + // given + + // when + eaiMessageDAO.getAllEAIMessages(); + + // then + assertNotNull(eaiMessageDAO.getAllEAIMessages()); + assertTrue(eaiMessageDAO.getAllEAIMessages().size() > 0); + + } + + @Test + void getEAIMessagesByCode() throws DAOException { + // given + String code = "EDDMIAS00000028S1"; + // when + eaiMessageDAO.getEAIMessagesByCode(code); + + // then + assertNotNull(eaiMessageDAO.getEAIMessagesByCode(code)); + assertTrue(eaiMessageDAO.getEAIMessagesByCode(code).getEAISvcCd().length() > 0); + + } + +} diff --git a/src/test/java/com/eactive/eai/common/message/EAIMessageManagerTest.java b/src/test/java/com/eactive/eai/common/message/EAIMessageManagerTest.java new file mode 100644 index 0000000..1b72320 --- /dev/null +++ b/src/test/java/com/eactive/eai/common/message/EAIMessageManagerTest.java @@ -0,0 +1,44 @@ +package com.eactive.eai.common.message; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.message" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.message" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.message" }) +@Sql({ "/com/eactive/eai/common/message/init_tseaihe01.sql", "/com/eactive/eai/common/message/init_tseaihe02.sql", + "/com/eactive/eai/common/message/init_tseaims02.sql", "/com/eactive/eai/common/message/init_tseaifr01.sql" }) +class EAIMessageManagerTest { + @Autowired + EAIMessageManager eaiMessageManager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + eaiMessageManager.start(); + + // then + assertNotNull(eaiMessageManager.getAllEAISvcCd()); + assertTrue(eaiMessageManager.getAllEAISvcCd().length > 0); + + } + +} diff --git a/src/test/java/com/eactive/eai/common/messagekey/MessageKeyManagerTest.java b/src/test/java/com/eactive/eai/common/messagekey/MessageKeyManagerTest.java new file mode 100644 index 0000000..b9700ec --- /dev/null +++ b/src/test/java/com/eactive/eai/common/messagekey/MessageKeyManagerTest.java @@ -0,0 +1,54 @@ +package com.eactive.eai.common.messagekey; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.messagekey" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.messagekey" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.messagekey" }) +@Sql({ "/com/eactive/eai/common/messagekey/init_tseaifr04.sql" }) +class MessageKeyManagerTest { + + @Autowired + MessageKeyManager messageKeyManager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + messageKeyManager.start(); + + // then + assertTrue(messageKeyManager.getAllKeyNames().length > 0); + + MessageKeyVO vo = messageKeyManager.getMessageKey("_EAI_IN_NET_SyS" + "I"); + System.out.println(vo); + assertTrue(vo.getMessageKeyGroup(0).getMessageKeyFldLength() == 2); + + try { + vo = messageKeyManager.getMessageKey("_EAI_IN_NET_SyS", "I"); + } catch (DAOException e) { + e.printStackTrace(); + } + System.out.println(vo); + + } + +} diff --git a/src/test/java/com/eactive/eai/common/pushinfo/PushInfoDAOTest.java b/src/test/java/com/eactive/eai/common/pushinfo/PushInfoDAOTest.java new file mode 100644 index 0000000..5b91bab --- /dev/null +++ b/src/test/java/com/eactive/eai/common/pushinfo/PushInfoDAOTest.java @@ -0,0 +1,55 @@ +package com.eactive.eai.common.pushinfo; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.pushinfo.PushInfoDetailVO.Result; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.pushinfo" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.pushinfo" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.pushinfo" }) +class PushInfoDAOTest { + @Autowired + PushInfoDAO pushInfoDAO; + + @Test + void test() throws DAOException { + // given + String guid = "guid001"; + int count = 2; + PushInfoVO vo = new PushInfoVO(); + vo.setGuid(guid); + vo.setPushTargetCount(count); + vo.setPushTarget("0001,0002"); + // when + pushInfoDAO.insertPushInfo(vo); + + List list = new ArrayList<>(); + for (int i = 0; i < count; i++) { + PushInfoDetailVO detail = new PushInfoDetailVO(); + detail.setGuid("GUID" + i); + detail.setPushResult(Result.success); + list.add(detail); + } + pushInfoDAO.batchInsertPushInfoDetail(list); + // then + assertTrue(pushInfoDAO.getPushInfoDetailCount() == 2); + } + +} diff --git a/src/test/java/com/eactive/eai/common/routing/RoutingManagerTest.java b/src/test/java/com/eactive/eai/common/routing/RoutingManagerTest.java new file mode 100644 index 0000000..7fab8cc --- /dev/null +++ b/src/test/java/com/eactive/eai/common/routing/RoutingManagerTest.java @@ -0,0 +1,41 @@ +package com.eactive.eai.common.routing; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.routing" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.routing" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.routing" }) +@Sql({ "/com/eactive/eai/common/routing/init_tseaifr02.sql" }) +class RoutingManagerTest { + + @Autowired + RoutingManager routingManager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + routingManager.start(); + + // then + assertTrue(routingManager.getAllRoutingNames().length > 0); + } + +} diff --git a/src/test/java/com/eactive/eai/common/sessioninfo/SessionInfoDAOTest.java b/src/test/java/com/eactive/eai/common/sessioninfo/SessionInfoDAOTest.java new file mode 100644 index 0000000..2bf76d1 --- /dev/null +++ b/src/test/java/com/eactive/eai/common/sessioninfo/SessionInfoDAOTest.java @@ -0,0 +1,41 @@ +package com.eactive.eai.common.sessioninfo; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; + +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.common.sessioninfo" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.common.sessioninfo" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.sessioninfo" }) +public class SessionInfoDAOTest { + @Autowired + SessionInfoDAO sessioninfoDAO; + +// @Test +// @Transactional(propagation = Propagation.NOT_SUPPORTED) +// void testStart() throws DAOException { +// // given +// String userId = "test001"; +// String sessionId = "session-001"; +// SessionInfoVO vo = new SessionInfoVO(userId); +// vo.setSessionId(sessionId); +// // when +// sessioninfoDAO.upsertSessionInfo(vo); +// +// vo.setSessionId("session-002"); +// sessioninfoDAO.upsertSessionInfo(vo); +// // then +// SessionInfoVO readVo = sessioninfoDAO.getSessionInfo(userId); +// System.out.println("readVo ===>" + readVo.toString()); +// assertFalse(sessionId.equals(readVo.getSessionId())); +// } +} diff --git a/src/test/java/com/eactive/eai/data/CommonJPATestConfiguration.java b/src/test/java/com/eactive/eai/data/CommonJPATestConfiguration.java new file mode 100644 index 0000000..9464e13 --- /dev/null +++ b/src/test/java/com/eactive/eai/data/CommonJPATestConfiguration.java @@ -0,0 +1,23 @@ +package com.eactive.eai.data; + +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; + +import com.eactive.eai.common.util.ApplicationContextProvider; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@Configuration +@ComponentScan({ "com.eactive.eai.property" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { "com.eactive.eai.property" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.property" }) +public class CommonJPATestConfiguration { + + @Bean + ApplicationContextProvider applicationContextProvider() { + return new ApplicationContextProvider(); + } + +} \ No newline at end of file diff --git a/src/test/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverDAOTest.java b/src/test/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverDAOTest.java new file mode 100644 index 0000000..6b2046b --- /dev/null +++ b/src/test/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverDAOTest.java @@ -0,0 +1,56 @@ +package com.eactive.eai.flowcontrol.jms; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.flowcontrol.jms" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.flowcontrol.jms" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.flowcontrol.jms" }) +@Sql({ "/com/eactive/eai/flowcontrol/jms/init_tseaiqm02.sql" }) +class FCQueueReceiverDAOTest { + + @Autowired + FCQueueReceiverDAO fcQueueReceiverDAO; + +// @Test +// void getAllReceivers() throws DAOException { +// // given +// +// // when +// fcQueueReceiverDAO.getAllReceivers(); +// +// // then +// assertNotNull(fcQueueReceiverDAO.getAllReceivers()); +// assertTrue(fcQueueReceiverDAO.getAllReceivers().size() > 0); +// } + + @Test + void getReceiver() throws DAOException { + // given + String queRcverName = "FlowRouterQueue_0101"; + + // when + fcQueueReceiverDAO.getReceiver(queRcverName); + + // then + assertNotNull(fcQueueReceiverDAO.getReceiver(queRcverName)); + assertTrue(fcQueueReceiverDAO.getReceiver(queRcverName).getQueueName().length() > 0); + } + +} diff --git a/src/test/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverManagerTest.java b/src/test/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverManagerTest.java new file mode 100644 index 0000000..00e6f56 --- /dev/null +++ b/src/test/java/com/eactive/eai/flowcontrol/jms/FCQueueReceiverManagerTest.java @@ -0,0 +1,48 @@ +package com.eactive.eai.flowcontrol.jms; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.BDDMockito.given; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl;; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.flowcontrol.jms" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.flowcontrol.jms" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.flowcontrol.jms" }) +@Sql({ "/com/eactive/eai/flowcontrol/jms/init_tseaiqm02.sql" }) +class FCQueueReceiverManagerTest { + @Autowired + FCQueueReceiverManager fcQueueReceiverManager; + + @MockBean + EAIServerManager eaiServerManager; + + @Test + void getAllReceivers() throws LifecycleException { + // given + given(eaiServerManager.getLocalServerName()).willReturn("fepSvr11"); + // when + fcQueueReceiverManager.start(); + + // then + assertNotNull(fcQueueReceiverManager.getAllFCQueueReceiverVos()); + assertTrue(fcQueueReceiverManager.getAllFCQueueReceiverVos().size() > 0); + } + +} diff --git a/src/test/java/com/eactive/eai/flowcontrol/jms/QueueMonitorDAOTest.java b/src/test/java/com/eactive/eai/flowcontrol/jms/QueueMonitorDAOTest.java new file mode 100644 index 0000000..9744068 --- /dev/null +++ b/src/test/java/com/eactive/eai/flowcontrol/jms/QueueMonitorDAOTest.java @@ -0,0 +1,51 @@ +package com.eactive.eai.flowcontrol.jms; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.BDDMockito.given; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.dao.DAOException; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class, EAIServerManager.class }) +@ComponentScan({ "com.eactive.eai.flowcontrol.jms" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.flowcontrol.jms" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.flowcontrol.jms" }) +@Sql({ "/com/eactive/eai/flowcontrol/jms/init_tseaiqm01.sql" }) +class QueueMonitorDAOTest { + + @Autowired + QueueMonitorDAO queueMonitorDAO; + + @MockBean + EAIServerManager eaiServerManager; + + @Test + void getAllC2RServices() throws DAOException { + // given + given(eaiServerManager.getLocalServerName()).willReturn("fepSvr11"); + + // when + queueMonitorDAO.getAllQueue(); + + // then + assertNotNull(queueMonitorDAO.getAllQueue()); + assertTrue(queueMonitorDAO.getAllQueue().size() > 0); + + } + +} diff --git a/src/test/java/com/eactive/eai/flowcontrol/jms/QueueMonitorManagerTest.java b/src/test/java/com/eactive/eai/flowcontrol/jms/QueueMonitorManagerTest.java new file mode 100644 index 0000000..eaaab08 --- /dev/null +++ b/src/test/java/com/eactive/eai/flowcontrol/jms/QueueMonitorManagerTest.java @@ -0,0 +1,51 @@ +package com.eactive.eai.flowcontrol.jms; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.mockito.BDDMockito.given; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.boot.test.mock.mockito.MockBean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.common.server.EAIServerManager; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl;; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class, EAIServerManager.class }) +@ComponentScan({ "com.eactive.eai.flowcontrol.jms" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.flowcontrol.jms" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.flowcontrol.jms" }) +@Sql({ "/com/eactive/eai/flowcontrol/jms/init_tseaiqm01.sql" }) +class QueueMonitorManagerTest { + + @Autowired + QueueMonitorManager queueMonitorManager; + + @MockBean + EAIServerManager eaiServerManager; + + @Test + void getAllC2RServices() throws LifecycleException { + // given + given(eaiServerManager.getLocalServerName()).willReturn("fepSvr11"); + + // when + queueMonitorManager.start(); + + // then + assertNotNull(queueMonitorManager.getAllQueueMonitorVos()); + assertTrue(queueMonitorManager.getAllQueueMonitorVos().size() > 0); + + } + +} diff --git a/src/test/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoTest.java b/src/test/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoTest.java new file mode 100644 index 0000000..93c244b --- /dev/null +++ b/src/test/java/com/eactive/eai/httpouttlsinfo/HttpOutTlsInfoTest.java @@ -0,0 +1,42 @@ +package com.eactive.eai.httpouttlsinfo; + +import com.eactive.eai.common.lifecycle.LifecycleException; +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.httpouttlsinfo" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.httpouttlsinfo" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.httpouttlsinfo" }) +@Sql({ "/com/eactive/eai/httpouttlsinfo/init_http_tls_client_info.sql" }) +class HttpOutTlsInfoManagerTest { + + @Autowired + HttpOutTlsInfoManager httpOutTlsInfoManager; + + @Test + void testStart() throws LifecycleException { + // given + + // when + httpOutTlsInfoManager.start(); + + // then + assertNotNull(httpOutTlsInfoManager.getAllClientIds()); + assertTrue(httpOutTlsInfoManager.getAllClientIds().length > 0); + } + +} diff --git a/src/test/java/com/eactive/eai/message/layout/DatabaseReaderTest.java b/src/test/java/com/eactive/eai/message/layout/DatabaseReaderTest.java new file mode 100644 index 0000000..f4d7f80 --- /dev/null +++ b/src/test/java/com/eactive/eai/message/layout/DatabaseReaderTest.java @@ -0,0 +1,42 @@ +package com.eactive.eai.message.layout; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.List; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.jdbc.Sql; + +import com.eactive.eai.data.CommonJPATestConfiguration; +import com.eactive.eai.data.jpa.BaseRepositoryImpl; +import com.eactive.eai.message.StandardItem; + +@DataJpaTest +@ContextConfiguration(classes = { CommonJPATestConfiguration.class }) +@ComponentScan({ "com.eactive.eai.message.layout", "com.eactive.eai.common.stdmessage" }) +@EnableJpaRepositories(repositoryBaseClass = BaseRepositoryImpl.class, basePackages = { + "com.eactive.eai.message.layout", "com.eactive.eai.common.stdmessage" }) +@EntityScan({ "com.eactive.eai.data.entity.onl.stdmessage" }) +@Sql({ "/com/eactive/eai/message/layout/DatabaseReaderTest.sql" }) +class DatabaseReaderTest { + + @Autowired + DatabaseReader databaseReader; + + String layoutName = "HANA_POC_SAMPLE"; + + @Test + void testParse() throws Exception { + + List list = databaseReader.parse(layoutName); + + assertThat(list).isNotEmpty(); + } + +} diff --git a/src/test/java/com/eactive/eai/message/test/InterfaceTest.java b/src/test/java/com/eactive/eai/message/test/InterfaceTest.java new file mode 100644 index 0000000..44f20d2 --- /dev/null +++ b/src/test/java/com/eactive/eai/message/test/InterfaceTest.java @@ -0,0 +1,80 @@ +package com.eactive.eai.message.test; + + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.service.InterfaceMapper; +import com.eactive.eai.message.service.InterfaceMessage; + +public class InterfaceTest { + static Logger logger = LoggerFactory.getLogger(InterfaceTest.class); + + public InterfaceTest() { + } + + public static void main(String[] args) throws Exception { +// System.setProperty(StandardMessageManager.STANDARD_MESSAGE_CONFIG, "./resources/standard-message-config-test.properties"); + System.setProperty(StandardMessageManager.STANDARD_MESSAGE_CONFIG, "./resources/standard-message-config.properties"); + testInterfaceWithManager(); + } + + public static void testInterfaceWithManager() { + StandardMessageManager manager = StandardMessageManager.getInstance(); + try { + manager.init(); + } + catch(Exception ex) { + ex.printStackTrace(); + return; + } + + StandardMessage standardMessage = manager.getStandardMessage(); + InterfaceMapper mapper = manager.getMapper(); + + String serviceCode = mapper.getEaiSvcCode(standardMessage); + + // get Interface message with serviceCode + InterfaceMessage interfaceMessage = new InterfaceMessage(); + + interfaceMessage.setStandardMessage(standardMessage); + interfaceMessage.setMapper(mapper); + + logger.debug(">> Init."); + logger.debug("getServiceId = {}",interfaceMessage.getMapper().getServiceId(interfaceMessage.getStandardMessage())); + logger.debug("getGuid = {}",interfaceMessage.getMapper().getGuid(interfaceMessage.getStandardMessage())); + logger.debug("getReturnType = {}",interfaceMessage.getMapper().getSendRecvDivision(interfaceMessage.getStandardMessage())); + logger.debug("getReturnType = {}",interfaceMessage.getMapper().getSendRecvDivision(interfaceMessage.getStandardMessage())); + + logger.debug("getEaiSvcCode = {}", interfaceMessage.getMapper().getEaiSvcCode(standardMessage)); + logger.debug("standardMessage = {}",interfaceMessage.getStandardMessage().toPrettyJson()); + + String changed = "ELKCHANGED"; + logger.debug("\n>> Change : setServiceId = {}", changed); + interfaceMessage.getMapper().setServiceId(interfaceMessage.getStandardMessage(), changed); + interfaceMessage.getMapper().setErrorCode(interfaceMessage.getStandardMessage(), "ERR01"); + interfaceMessage.getMapper().setErrorMsg(interfaceMessage.getStandardMessage(), "내부처리 중 에러"); + interfaceMessage.getMapper().setResponseType(interfaceMessage.getStandardMessage(), "E"); + + logger.debug("getServiceId = {}",mapper.getServiceId(interfaceMessage.getStandardMessage())); + logger.debug("getEaiSvcCode = {}", interfaceMessage.getMapper().getEaiSvcCode(standardMessage)); + + try { + interfaceMessage.getStandardMessage().setBizData("{\"response\":\"response message is here!\"}", "utf-8"); + } catch (Exception e) { + logger.error("bizdata set error", e); + } + logger.debug("toPrettyJson = {}",interfaceMessage.getStandardMessage().toPrettyJson()); + + try { + interfaceMessage.getStandardMessage().setBizData("response message is here!", "utf-8"); + } catch (Exception e) { + logger.error("bizdata set error", e); + } + logger.debug("toXML = {}",interfaceMessage.getStandardMessage().toPrettyXML()); + + } + +} diff --git a/src/test/java/com/eactive/eai/message/test/SrandardMessageTest.java b/src/test/java/com/eactive/eai/message/test/SrandardMessageTest.java new file mode 100644 index 0000000..0f694c4 --- /dev/null +++ b/src/test/java/com/eactive/eai/message/test/SrandardMessageTest.java @@ -0,0 +1,439 @@ +package com.eactive.eai.message.test; + +import java.util.ArrayList; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.eactive.eai.message.StandardItem; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.StandardMessageUtil; +import com.eactive.eai.message.StandardType; +import com.eactive.eai.message.manager.StandardMessageManager; +import com.eactive.eai.message.parser.StandardReader; +import com.eactive.eai.message.parser.XmlReader; + +public class SrandardMessageTest { + static Logger logger = LoggerFactory.getLogger(SrandardMessageTest.class); + static String strString = + "000199GIDNO00000000004444 ELINKSVC01ELINK TEST Service SSESSIONID001 NO SCREEN0000001000000000100000000020000000003 USER000001 EACTEACT001ELINK01CHEA20220928000000000 S TESTSET-BIZDATA"; + + static String jsonString = + "{" + + " \"msg_len\":199," + + " \"global_id\":\"GIDNO00000000002222\"," + + " \"service_id\":\"ELINKSVC01\"," + + " \"service_cmt\":\"ELINK TEST Service\"," + + " \"service_tn\":\"S\"," + + " \"Session_id\":\"SESSIONID001\"," + + " \"encrypt_yn\":\"NO\"," + + " \"http_url\":\"\"," + + " \"screen_id\":\"SCREEN0000001\"," + + " \"scr_no\":\"000000000100000000020000000003\"," + + " \"scr_dsc\":\"\"," + + " \"usr_id\":\"USER000001\"," + + " \"ip_addr\":\"\"," + + " \"ip_mac\":\"\"," + + " \"com_code\":\"EACT\"," + + " \"head_code\":\"EACT001\"," + + " \"dept_cd\":\"ELINK01\"," + + " \"conn_tp\":\"CH\"," + + " \"Inter_chn\":\"EA\"," + + " \"recv_tm\":\"20220928000000000\"," + + " \"send_tm\":\"\"," + + " \"return_gubun\":\"S\"," + + " \"return_value\":\"\"," + + " \"msg_id\":\"\"," + + " \"msg_nm\":\"\"," + + " \"filler\":\"\"," + + " \"bizData\":{" + + " \"bizfield1\":\"BIZ1\"," + + " \"bizfield2\":\"BIZ2\"," + + " \"bizfield3\":\"BIZ3\"" + + " }" + + "}"; + + static String xmlString = + "" + + "" + + " 199" + + " GIDNO00000000003333" + + " ELINKSVC01" + + " ELINK TEST Service" + + " S" + + " SESSIONID001" + + " NO" + + " " + + " SCREEN0000001" + + " 000000000100000000020000000003" + + " " + + " USER000001" + + " " + + " " + + " EACT" + + " EACT001" + + " ELINK01" + + " CH" + + " EA" + + " 20220928000000000" + + " " + + " S" + + " " + + " " + + " " + + " " + + " BIZ1BIZ2BIZ3" + + ""; + + public SrandardMessageTest() { + + } + + public static StandardMessage generateMessage() { +// return StandardMessageUtil.generateMessageFromCCsvFile(); + StandardMessageManager manager = StandardMessageManager.getInstance(); + try { + manager.init(); + } + catch(Exception ex) { + ex.printStackTrace(); + return null; + } + return manager.getStandardMessage(); + } + + + public static StandardMessage generateMessageFromItemList() { + // Test generator from List definition (with default values) + logger.debug("\n>> ----------------------------------------------------------------------------------"); + logger.debug(">> Test generator from List definition ( with default values)"); + ArrayList list = new ArrayList(); + StandardItem group = null; + StandardItem item = null; + group = new StandardItem("Header", 1, StandardType.GROUP, 1, 0, 0, null); + list.add(group); + item = new StandardItem("StndCicsTrncd", 2, StandardType.FIELD, 1, 10, 0, ""); + list.add(item); + item = new StandardItem("StndIntnlStndTelgmLen", 2, StandardType.FIELD, 1, 10, 1, "0"); + list.add(item); + item = new StandardItem("StndTranBaseYmd", 2, StandardType.FIELD, 1, 10, 0, ""); + list.add(item); + + StandardItem group1 = new StandardItem("Common", 1, StandardType.GROUP, 0, 0, null); + list.add(group1); + group = new StandardItem("TranInfo", 2, StandardType.GROUP, 0, 0, null); + list.add(group); + item = new StandardItem("StndCicsTrncd", 3, StandardType.FIELD, 3, 0, "KB0"); + list.add(item); + item = new StandardItem("StndTelgmRecvTranCd", 3, StandardType.FIELD, 10, 0, ""); + list.add(item); + item = new StandardItem("StndPrcssRtdTranCd", 3, StandardType.FIELD, 10, 0, ""); + list.add(item); + + group = new StandardItem("Array", 1, StandardType.GRID, 3, 0, null); + list.add(group); + item = new StandardItem("Item1", 2, StandardType.FIELD, 10, 0, "JI6H"); + list.add(item); + item = new StandardItem("Group", 2, StandardType.GRID, 1, 0, null); + list.add(item); + item = new StandardItem("gitem1", 3, StandardType.FIELD, 10, 1, "726"); + list.add(item); + item = new StandardItem("gitem2", 3, StandardType.FIELD, 10, 0, "20220905"); + list.add(item); + + item = new StandardItem("bizData", 1, StandardType.BIZDATA, 0, 0, null); + list.add(item); + + StandardMessage message = null;; + try { + message = StandardMessageUtil.generate(list); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + // TODO + // 1. CSV -> List -> gen + // 2. XML -> List -> gen + // 3. JSON -> List -> gen + logger.debug("@toCSVString\n" + message.toCSVString()); + logger.debug("@toString\n" + message.toString()); + logger.debug("@toJson\n" + message.toJson()); + + // Test initialize getter + logger.debug("\n>> ----------------------------------------------------------------------------------"); + logger.debug(">> Test initialize getter"); + String findItem = "StndCicsTrncd"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + + findItem = "Header.StndCicsTrncd"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + + findItem = "Common.TranInfo.StndCicsTrncd"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + + logger.debug("\n>> ----------------------------------------------------------------------------------"); + logger.debug(">> Test file item with path & set value"); + StandardItem it = message.findItem(findItem); + if(it !=null) { + it.setValue("changed!"); + } + logger.debug(findItem + " => " +message.findItemValue(findItem)); + + findItem = "Common.TranInfo.StndCicsTrncd1"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + + findItem = "Array[0].Group.gitem2"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + + findItem = "Array[0]"; + logger.debug(findItem + " => " +message.findItem(findItem)); + + return message; + } + + public static void testJsonReader() throws Exception { + StandardMessage message = null;; + message = generateMessage(); + if(message == null) { + return; + } + + logger.debug(">> Test Json Parsing"); + + logger.debug("jsonString = " +jsonString); + + // Test Json parsing +// StandardReader jsonReader = new JsonReader(); + + // Test Dynamic Loading + StandardReader reader = null; + String readerName = "com.eactive.eai.message.parser.JsonReader"; + Class cl = null; + try { + cl = Class.forName(readerName); + reader = (StandardReader)cl.newInstance(); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + return; + } + reader.parse(message, jsonString); + + String charset = "utf-8"; + message.setBizDataCharset(charset); + logger.debug(">> message=\n" + message); + logger.debug(">> message.toJson()=\n" + message.toJson()); + logger.debug(">> message.toJson(false)=\n" + message.toJson(false)); + logger.debug(">> message.toPrettyJson()=\n" + message.toPrettyJson()); + logger.debug(">> message.toPrettyJson(false)=\n" + message.toPrettyJson(false)); + logger.debug(">> message.toXML()=\n" + message.toXML()); + logger.debug(">> message.toPrettyXML()=\n" + message.toPrettyXML()); + logger.debug(">> message.toFixedString()=\n[" + message.toFixedString(charset)+"]"); + logger.debug(">> message.toByteArray()=\n[" + new String(message.toByteArray(charset)) + "]"); + logger.debug(">> message.toLogList()=\n" + message.toLogList()); + // Test getter after parsing + logger.debug("\n>> ----------------------------------------------------------------------------------"); + String findItem = null; + logger.debug(">> Test getter after parsing"); + findItem = "global_id"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + findItem = "Session_id"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + findItem = "screen_id"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + findItem = "recv_tm"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + } + + public static void testXmlReader() throws Exception { + StandardMessage message = null;; + message = generateMessage(); + if(message == null) { + return; + } + + logger.debug(">> Test Json Parsing"); + + logger.debug("xmlString = " + xmlString); + + // Test XML parsing + StandardReader reader = new XmlReader(); + reader.parse(message, xmlString); + + logger.debug(">> message=\n" + message); + logger.debug(">> message.toJson()=\n" + message.toJson()); + logger.debug(">> message.toXML()=\n" + message.toXML()); + // Test getter after parsing + logger.debug("\n>> ----------------------------------------------------------------------------------"); + String findItem = null; + logger.debug(">> Test getter after parsing"); + findItem = "global_id"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + findItem = "Session_id"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + findItem = "screen_id"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + findItem = "recv_tm"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + } + + + public static void testDynamicReader(String messageType, String messageString) throws Exception { + StandardMessage message = null; + message = generateMessage(); + if(message == null) { + return; + } + + logger.debug(">> Test Parsing"); + + logger.debug("messageString = " +messageString); + + // Test Json parsing + // Test Dynamic Loading + StandardReader reader = null; + + StandardMessageManager manager = StandardMessageManager.getInstance(); + + reader = manager.getReader(messageType); + + reader.parse(message, messageString); + + String charset = "utf-8"; + + logger.debug(">> message=\n" + message); + logger.debug(">> message.toByteArray()=\n" + new String(message.toByteArray(charset))); + logger.debug(">> message.toJson()=\n" + message.toJson()); + logger.debug(">> message.toPrettyJson()=\n" + message.toPrettyJson()); + logger.debug(">> message.toXML()=\n" + message.toXML()); + logger.debug(">> message.toPrettyXML()=\n" + message.toPrettyXML()); + + logger.debug(">> message.setBizData() to TESTSET-DATA"); + message.setBizData("TESTSET-DATA", "utf-8"); + logger.debug(">> message.toByteArray()=\n[" + new String(message.toByteArray(charset)) +"]"); + // Test getter after parsing + logger.debug("\n>> ----------------------------------------------------------------------------------"); + String findItem = null; + logger.debug(">> Test getter after parsing"); + findItem = "global_id"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + findItem = "Session_id"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + findItem = "screen_id"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + findItem = "recv_tm"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + } + + public static void testSimple() { + int level = 0; + StandardMessage message = new StandardMessage(); + StandardItem group = null; + StandardItem item = null; + level++; + group = new StandardItem("Header", level, 2, 0, 0, null); + level++; + item = new StandardItem("StndCicsTrncd", level, 1, 10, 0, "JI6H"); + group.addItem(item); + item = new StandardItem("StndIntnlStndTelgmLen", level, 1, 10, 1, "726"); + group.addItem(item); + item = new StandardItem("StndTranBaseYmd", level, 1, 10, 0, "20220905"); + group.addItem(item); + message.addItem(group); + + level--; + StandardItem group1 = new StandardItem("Common", level, 2, 0, 0, null); + level++; + group = new StandardItem("TranInfo", level, 2, 0, 0, null); + level++; + item = new StandardItem("StndCicsTrncd", level, 1, 10, 0, "KB0"); + group.addItem(item); + item = new StandardItem("StndTelgmRecvTranCd", level, 1, 10, 0, "EDU0100101"); + group.addItem(item); + item = new StandardItem("StndPrcssRtdTranCd", level, 1, 10, 0, "JI6HWSE02002"); + group.addItem(item); + group1.addItem(group); + message.addItem(group1); + + logger.debug(">> toString"); + logger.debug(message.toString()); + logger.debug(">> toCSVString"); + logger.debug(message.toCSVString()); + logger.debug(">> toJson"); + logger.debug(message.toJson()); + + String findItem = "StndCicsTrncd"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + + findItem = "Header.StndCicsTrncd"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + + findItem = "Common.TranInfo.StndCicsTrncd"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + + findItem = "Common.TranInfo.StndCicsTrncd1"; + logger.debug(findItem + " => " +message.findItemValue(findItem)); + } + + public static void splitTest(String path, String pathSeparator) { + String[] paths = null; + logger.debug("path=" + path); + logger.debug("pathSeparator=" + pathSeparator); + + paths = path.split("[" + pathSeparator +"]"); + int index =0; + for(String p: paths) { + System.out.printf("path[%d]=(%s)\n", index++, p); + } + } + + public static void testFlatReader( int caseNumber) { + String testString = null; + + if( caseNumber == 1) { + testString ="000199GIDNO00000000004444 ELINKSVC01ELINK TEST Service SSESSIONID001 NO SCREEN0000001000000000100000000020000000003 USER000001 EACTEACT001ELINK01CHEA20220928000000000 S @@"; + try { + testDynamicReader("FLAT", testString); + } + catch(Exception ex) { + logger.debug("success test : " + ex.toString()); + } + } + + // underflow + if( caseNumber == 2) { + testString ="000199GIDNO00000000004444 ELINKSVC01ELINK TEST Service SSESSIONID001 NO SCREEN0000001000000000100000000020000000003 USER000001 EACTEACT001ELINK01CHEA20220928000000000 S @@"; + try { + testDynamicReader("FLAT", testString); + } + catch(Exception ex) { + logger.debug("underflow test : " + ex.toString()); + } + } + // with bizData + if( caseNumber == 3) { + testString ="001005GIDNO00000000004444 ELINKSVC01ELINK TEST Service SSESSIONID001 NO SCREEN0000001000000000100000000020000000003 USER000001 EACTEACT001ELINK01CHEA20220928000000000 S ADDED@@"; + try { + testDynamicReader("FLAT", testString); + } + catch(Exception ex) { + logger.debug("overflow test : " + ex.toString()); + } + } + } + + public static void main(String[] args) throws Exception { +// testSimple(); + +// testJsonReader(); +// testXmlReader(); + testFlatReader(1); +// testFlatReader(2); +// testFlatReader(3); + +// testDynamicReader("JSON", jsonString); +// testDynamicReader("XML", xmlString); +// generateMessageFromItemList(); + } + +} diff --git a/src/test/java/com/eactive/eai/message/test/TestInterfaceMapper.java b/src/test/java/com/eactive/eai/message/test/TestInterfaceMapper.java new file mode 100644 index 0000000..1effac6 --- /dev/null +++ b/src/test/java/com/eactive/eai/message/test/TestInterfaceMapper.java @@ -0,0 +1,21 @@ +package com.eactive.eai.message.test; + +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.service.DefaultInterfaceMapper; + +public class TestInterfaceMapper extends DefaultInterfaceMapper { + public TestInterfaceMapper() { + + } + //------------------------------------------------------------ + // 재정의가 필요한 항목에 대한 로직 추가 + //------------------------------------------------------------ + @Override + public String getEaiSvcCode(StandardMessage standardMessage) { + String eaiSvcCode = null; + String cicsTranCd = getServiceId(standardMessage); + // TODO : site에 맞게 조합해야 함. + eaiSvcCode = cicsTranCd +"S01"; + return eaiSvcCode; + } +} diff --git a/src/test/java/com/eactive/eai/message/test/VersionMappingTest.java b/src/test/java/com/eactive/eai/message/test/VersionMappingTest.java new file mode 100644 index 0000000..8a04e92 --- /dev/null +++ b/src/test/java/com/eactive/eai/message/test/VersionMappingTest.java @@ -0,0 +1,88 @@ +package com.eactive.eai.message.test; + + +import java.util.ArrayList; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.eactive.eai.message.StandardDataType; +import com.eactive.eai.message.StandardItem; +import com.eactive.eai.message.StandardMessage; +import com.eactive.eai.message.StandardMessageUtil; +import com.eactive.eai.message.StandardType; +import com.eactive.eai.message.mapper.DefaultMessageMapper; +import com.eactive.eai.message.mapper.MessageMapper; + +public class VersionMappingTest { + static Logger logger = LoggerFactory.getLogger(VersionMappingTest.class); + + public VersionMappingTest() { + + } + + public static StandardMessage generateMessageFromItemList() { + // Test generator from List definition (with default values) + logger.debug("\n>> ----------------------------------------------------------------------------------"); + logger.debug(">> Test generator from List definition ( with default values)"); + ArrayList list = new ArrayList(); + StandardItem group = null; + StandardItem item = null; + group = new StandardItem("Header", 1, StandardType.GROUP, 1, 0, 0, null); + list.add(group); + item = new StandardItem("StndCicsTrncd", 2, StandardType.FIELD, 1, 10, StandardDataType.STRING, ""); + list.add(item); + item = new StandardItem("StndIntnlStndTelgmLen", 2, StandardType.FIELD, 1, 10, StandardDataType.LL_NUMBER, "0"); + list.add(item); + item = new StandardItem("StndTranBaseYmd", 2, StandardType.FIELD, 1, 10, StandardDataType.STRING, ""); + list.add(item); + + StandardItem group1 = new StandardItem("Common", 1, StandardType.GROUP, 0, 0, null); + list.add(group1); + group = new StandardItem("TranInfo", 2, StandardType.GROUP, 0, 0, null); + list.add(group); + item = new StandardItem("StndCicsTrncd", 3, StandardType.FIELD, 3, StandardDataType.STRING, "KB0"); + list.add(item); + item = new StandardItem("StndTelgmRecvTranCd", 3, StandardType.FIELD, 10, StandardDataType.STRING, ""); + list.add(item); + item = new StandardItem("StndPrcssRtdTranCd", 3, StandardType.FIELD, 10, StandardDataType.STRING, ""); + list.add(item); + + group = new StandardItem("Array", 1, StandardType.GRID, 3, 0, null); + list.add(group); + item = new StandardItem("Item1", 2, StandardType.FIELD, 10, StandardDataType.STRING, "JI6H"); + list.add(item); + item = new StandardItem("Group", 2, StandardType.GRID, 1, StandardDataType.STRING, null); + list.add(item); + item = new StandardItem("gitem1", 3, StandardType.FIELD, 10, StandardDataType.STRING, "726"); + list.add(item); + item = new StandardItem("gitem2", 3, StandardType.FIELD, 10, StandardDataType.STRING, "20220905"); + list.add(item); + + item = new StandardItem("bizData", 1, StandardType.BIZDATA, 0, StandardDataType.STRING, null); + list.add(item); + + StandardMessage message = null;; + try { + message = StandardMessageUtil.generate(list); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + + logger.debug("@toJson\n" + message.toJson()); + + MessageMapper mapper = new DefaultMessageMapper(); + String targetPath = "Header.StndCicsTrncd"; + String sourcePath = "Common.TranInfo.StndCicsTrncd"; + mapper.map(message, sourcePath, message, targetPath); + logger.debug("@toJson\n" + message.toJson()); + + return message; + } + + public static void main(String[] args) throws Exception { + generateMessageFromItemList(); + } + +} diff --git a/src/test/java/com/eactive/eai/util/jsonJson/PathsTransformTest.java b/src/test/java/com/eactive/eai/util/jsonJson/PathsTransformTest.java new file mode 100644 index 0000000..f1eebd4 --- /dev/null +++ b/src/test/java/com/eactive/eai/util/jsonJson/PathsTransformTest.java @@ -0,0 +1,57 @@ +package com.eactive.eai.util.jsonJson; + +import java.util.HashMap; +import java.util.Map; + +import com.eactive.eai.util.json.JsonPathsTransform; +import com.eactive.eai.util.json.transformer.CustomValueTransformer; +import com.eactive.eai.util.json.transformer.ValueTransformer; + +public class PathsTransformTest { + public static void main(String[] args) { + String jsonString = "{ \"person\": { \"name\": \"John\", \"age\": 30, \"groups\": [ { \"id\": 1, \"name\": \"Group A\" }, { \"id\": 2, \"name\": \"Group B\" }, { \"id\": 3, \"name\": \"Group C\" } ] } }"; + + System.out.println("Origin JSON): \n" + jsonString); + + // CustomValueTransformer 사용 예제 + CustomValueTransformer nameTransformer = new CustomValueTransformer(); + nameTransformer.setProperty("PREFIX", "Mr. "); + nameTransformer.setProperty("SUFFIX", " Esq."); + + CustomValueTransformer groupTransformer = new CustomValueTransformer(); + groupTransformer.setProperty("PREFIX", "Team: "); + groupTransformer.setProperty("SUFFIX", " Ltd."); + + // 타입에따라 각각 처리하도록 해야 한다. + Map> pathTransformerMap = new HashMap<>(); + pathTransformerMap.put("$.person.name", nameTransformer); // 경로: person.name + pathTransformerMap.put("$.person.groups[0].name", groupTransformer); // 경로: groups[0].name + pathTransformerMap.put("$.person.groups[1].name", groupTransformer); // 경로: groups[1].name + pathTransformerMap.put("$.person.groups[2].name", groupTransformer); // 경로: groups[2].name + + String modifiedJsonString = JsonPathsTransform.modifyValuesAtPaths(jsonString, pathTransformerMap, true); + System.out.println("Modified JSON (Pretty): \n" + modifiedJsonString); + + Map> intTransformerMap = new HashMap<>(); + intTransformerMap.put("$.person.age", new ValueTransformer() { + @Override + public Integer transform(Integer age) { + return age + 10; + } + + @Override + public void setProperty(String propertyName, Object value) { + // TODO Auto-generated method stub + } + @Override + public String getProperty(String propertyName) { + return null; + } + + }); + + modifiedJsonString = JsonPathsTransform.modifyValuesAtPaths(jsonString, intTransformerMap, true); + System.out.println("Modified JSON (Pretty): \n" + modifiedJsonString); + + } +} diff --git a/src/test/java/com/eactive/eai/util/jsonJson/SimplePathsTransformTest.java b/src/test/java/com/eactive/eai/util/jsonJson/SimplePathsTransformTest.java new file mode 100644 index 0000000..a2b9e1f --- /dev/null +++ b/src/test/java/com/eactive/eai/util/jsonJson/SimplePathsTransformTest.java @@ -0,0 +1,58 @@ +package com.eactive.eai.util.jsonJson; + +import java.util.HashMap; +import java.util.Map; + +import com.eactive.eai.util.json.JsonPathsTransform; +import com.eactive.eai.util.json.JsonSimplePathsTransform; +import com.eactive.eai.util.json.transformer.CustomValueTransformer; +import com.eactive.eai.util.json.transformer.ValueTransformer; + +public class SimplePathsTransformTest { + public static void main(String[] args) { + String jsonString = "{ \"person\": { \"name\": \"John\", \"age\": 30, \"groups\": [ { \"id\": 1, \"name\": \"Group A\" }, { \"id\": 2, \"name\": \"Group B\" }, { \"id\": 3, \"name\": \"Group C\" } ] } }"; + + System.out.println("Origin JSON): \n" + jsonString); + + // CustomValueTransformer 사용 예제 + CustomValueTransformer nameTransformer = new CustomValueTransformer(); + nameTransformer.setProperty("PREFIX", "Mr. "); + nameTransformer.setProperty("SUFFIX", " Esq."); + + CustomValueTransformer groupTransformer = new CustomValueTransformer(); + groupTransformer.setProperty("PREFIX", "Team: "); + groupTransformer.setProperty("SUFFIX", " Ltd."); + + // 타입에따라 각각 처리하도록 해야 한다. + Map> pathTransformerMap = new HashMap<>(); + pathTransformerMap.put("/person/name", nameTransformer); + pathTransformerMap.put("/person/groups/0/name", groupTransformer); + pathTransformerMap.put("/person/groups/1/name", groupTransformer); + pathTransformerMap.put("/person/groups/2/name", groupTransformer); + + String modifiedJsonString = JsonSimplePathsTransform.modifyValuesAtPaths(jsonString, pathTransformerMap, true); + System.out.println("Modified JSON (Pretty): \n" + modifiedJsonString); + + Map> intTransformerMap = new HashMap<>(); + intTransformerMap.put("/person/age", new ValueTransformer() { + @Override + public Integer transform(Integer age) { + return age + 10; + } + + @Override + public void setProperty(String propertyName, Object value) { + // TODO Auto-generated method stub + } + @Override + public String getProperty(String propertyName) { + return null; + } + + }); + + modifiedJsonString = JsonSimplePathsTransform.modifyValuesAtPaths(jsonString, intTransformerMap, true); + System.out.println("Modified JSON (Pretty): \n" + modifiedJsonString); + + } +} diff --git a/src/test/java/com/eactive/kakao/rolling/impl/SchemaGenerator.java b/src/test/java/com/eactive/kakao/rolling/impl/SchemaGenerator.java new file mode 100644 index 0000000..78f1981 --- /dev/null +++ b/src/test/java/com/eactive/kakao/rolling/impl/SchemaGenerator.java @@ -0,0 +1,36 @@ +package com.eactive.kakao.rolling.impl; + +import java.util.EnumSet; + +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistry; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.tool.hbm2ddl.SchemaExport; +import org.hibernate.tool.schema.TargetType; + +import com.eactive.kakao.rolling.CurrentCommitId; +import com.eactive.kakao.rolling.RollingSuffix; + +public class SchemaGenerator { + + public static void main(String[] args) { + StandardServiceRegistry registry = new StandardServiceRegistryBuilder() +// .applySetting("hibernate.dialect", "org.hibernate.dialect.Oracle10gDialect") + .applySetting("hibernate.dialect", "org.hibernate.dialect.PostgreSQL10Dialect") + .build(); + + MetadataSources metadata = new MetadataSources(registry); + + // 엔티티 클래스 추가 + metadata.addAnnotatedClass(RollingSuffix.class); + // rolling_suffix + metadata.addAnnotatedClass(CurrentCommitId.class); + + SchemaExport export = new SchemaExport(); + export.setFormat(true); + export.setOutputFile("build/create.sql"); + export.createOnly(EnumSet.of(TargetType.SCRIPT), metadata.buildMetadata()); + + StandardServiceRegistryBuilder.destroy(registry); + } +} diff --git a/src/test/resources/com/eactive/eai/authserver/init_tseaiau01.sql b/src/test/resources/com/eactive/eai/authserver/init_tseaiau01.sql new file mode 100644 index 0000000..6c1bde2 --- /dev/null +++ b/src/test/resources/com/eactive/eai/authserver/init_tseaiau01.sql @@ -0,0 +1,5 @@ +INSERT INTO tseaiau01 (clientname,clientid,clientsecret, scope, granttypes,redirecturi,authorities,resourceids,accesstokenvalidityseconds,refreshtokenvalidityseconds,autoapprove,allowedips,modifiedby,modifiedon,securitykey) VALUES + ('eactive','AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8','KwBYJT1m1v3SUvzN2HPHhy2Ad9Q2GADbgWkYZZg9Ybbc8R1uEuBJNQ9oVl13b1qiXwYvDWTaX0EanxY4SMjNfnBBsZzfNoMwwDPTb3IjQy5k3CRxTAYzcSnmzlC4FSsG','hanapoc','client_credentials','','','','600','600','','','admin','20220809180307',NULL), + ('TEST_CLIENT','R4v8qDMVOmLJ1X4yKQslrKmhVOu2TNb2','vVkLWgO0mdQDpbhBAOfddX5WrPXRn0bMDs23lquTRxHNCEjdBtzE67FZSx0KJmuBDlNfnr8tsMC3lgOXYwM79RqP791dKHAeF3iVuc87snHt7JlnS8fdZGIpmQQQSK2f','invest.account,invest.irp,invest.list','client_credentials','','','',36000,72000,'','','apiadm','20210707165244',''), + ('종합포털','GV8INN0FbEdEyToaAIlKdH2X7h9nlv5P0Akx0GW3A','NGPfApj4KBhJ6bcUEcjOBTJix0g4aNRpHZgKYK0Akx0GW3AM9byPcuC3bxiesGtANyATGdfIVuGML92mplMnIEbJxXf9UD5CDMjBhK0s70PmzYj0rx6CnAJmVIkEELsP','[invest.list, invest.irp, invest.account]','[client_credentials]','[]','[]','[]',36000,72000,'[]','','apiadm','20211020130408',''), + ('종합포털2','GV8INN0FbEdEyToaAIlKdH2X7h9nlv5P','NGPfApj4KBhJ6bcUEcjOBTJix0g4aNRpHZgKYK0Akx0GW3AM9byPcuC3bxiesGtANyATGdfIVuGML92mplMnIEbJxXf9UD5CDMjBhK0s70PmzYj0rx6CnAJmVIkEELsP','invest.list,invest.account,invest.irp','client_credentials','','','',36000,72000,'','','apiadm','20210702132403',''); diff --git a/src/test/resources/com/eactive/eai/authserver/init_tseaiau02.sql b/src/test/resources/com/eactive/eai/authserver/init_tseaiau02.sql new file mode 100644 index 0000000..ec2fe78 --- /dev/null +++ b/src/test/resources/com/eactive/eai/authserver/init_tseaiau02.sql @@ -0,0 +1,3 @@ +INSERT INTO tseaiau02 (userid, password, name, email, mobile, usertype, status, organizationid, authorities, modifiedby, modifiedon) VALUES + ('AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8', '', 'eactive', '', '', '', '', '', '', '', ''), + ('testId', 'testPass', 'testName', '', '', '', '', '', '', '', ''); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/authserver/init_tseaiau04.sql b/src/test/resources/com/eactive/eai/authserver/init_tseaiau04.sql new file mode 100644 index 0000000..717c4e6 --- /dev/null +++ b/src/test/resources/com/eactive/eai/authserver/init_tseaiau04.sql @@ -0,0 +1,3 @@ +INSERT INTO tseaiau04 (bzwksvckeyname, scopeid) VALUES + ('mgmts/orgs', 'invest.account'), + ('test.Bzwksvckeyname', 'test.Scopeid'); diff --git a/src/test/resources/com/eactive/eai/common/b2badaptermapping/init_tseaifr07.sql b/src/test/resources/com/eactive/eai/common/b2badaptermapping/init_tseaifr07.sql new file mode 100644 index 0000000..838b830 --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/b2badaptermapping/init_tseaifr07.sql @@ -0,0 +1,9 @@ +INSERT INTO tseaifr07 (eaisevrinstncname, eaisvcname, extnlinstiidnfiname, dmnddtalsbzwkdsticname, psvsysadptrbzwkgroupname, adptrbzwkname) VALUES + ('fepOnlSvr12','ATS0210012270R2','ATSCHC','ISO','_ATS_IO_NET_AsC{CHC_ISO}','DEFAULT'), + ('fepOnlSvr12','ATS0210012270R2','ATSFAB','ISO','_ATS_IO_NET_AsC{FAB_ISO}','DEFAULT'), + ('fepOnlSvr12','ATS0210012270R2','ATSNHS','ISO','_ATS_IO_NET_AsC{NHS_ISO}','DEFAULT'), + ('fepOnlSvr12','ATS0210012270R2','ATSNIC','ISO','_ATS_IO_NET_AsC{NIC_ISO}','DEFAULT'), + ('fepOnlSvr22','ATS0210012270R2','ATSCHC','ISO','_ATS_IO_NET_AsC{CHC_ISO}','DEFAULT'), + ('fepOnlSvr22','ATS0210012270R2','ATSFAB','ISO','_ATS_IO_NET_AsC{FAB_ISO}','DEFAULT'), + ('fepOnlSvr22','ATS0210012270R2','ATSNHS','ISO','_ATS_IO_NET_AsC{NHS_ISO}','DEFAULT'), + ('fepOnlSvr22','ATS0210012270R2','ATSNIC','ISO','_ATS_IO_NET_AsC{NIC_ISO}','DEFAULT'); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/b2bextractor/init_tseaifr06.sql b/src/test/resources/com/eactive/eai/common/b2bextractor/init_tseaifr06.sql new file mode 100644 index 0000000..09ef4bb --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/b2bextractor/init_tseaifr06.sql @@ -0,0 +1,3 @@ +INSERT INTO tseaifr06 (eaisvcname,svcprcssno,svcroutclsname,adptrroutclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms) VALUES + ('FDASFEP00000635R1',1,'com.eactive.eai.flowcontrol.action.','com.eactive.eai.flowcontrol.action.',' ',' ',' '), + ('TSTSFEP00000635R1',1,'com.eactive.eai.flowcontrol.action.','com.eactive.eai.flowcontrol.action.',' ',' ',' '); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/b2bservice/init_tseaihe03.sql b/src/test/resources/com/eactive/eai/common/b2bservice/init_tseaihe03.sql new file mode 100644 index 0000000..50ec446 --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/b2bservice/init_tseaihe03.sql @@ -0,0 +1,1072 @@ +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('000021',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('000412',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('10011470',1,'ASYN','EGX','B2B_Svr1',' ','_EGX_OU_NET_AsC{10011470}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ','양천구금고','1'), + ('10026000',1,'ASYN','EGX','B2B_Svr1',' ','_EGX_OU_NET_AsC{10026000}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ',' ','1'), + ('10026170',1,'ASYN','EGX','B2B_Svr1',' ','_EGX_OU_NET_AsC{10026000}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ','부산시동구','1'), + ('10029000',1,'ASYN','EGX','B2B_Svr1',' ','_EGX_OU_NET_AsC{10029000}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ',' ','1'), + ('10041310',1,'ASYN','EGX','B2B_Svr1',' ','_EGX_OU_NET_AsC{10041310}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ','구리시금고','1'), + ('1007032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{GEPS}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('10099999',1,'ASYN','EGX','B2B_Svr1',' ','_EGX_OU_NET_AsC{TOTAL}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ',' ','1'), + ('1013032',1,'ASYN','DAN','B2B_Svr1',' ','RCM8_OU_NET_AsS{nps}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('1015032',1,'ASYN','KMB','B2B_Svr1',' ','RCMS_OU_NET_AsS{kcomwel}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1016001',1,'ASYN','CDS','KFTCDOM',' ','_CDS_OU_NET_AsC{KFTC_29}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','3',' ',' ',' ','1'), + ('1033032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsS{DAEHANLIFE}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1037032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{lgdacom}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1041032',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AyS{DONGBUFIRE_1011}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1041219',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AyS{DONGBUFIRE_1106}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1045032',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AsS{DONGYANGSEC}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1059032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsS{MERITZFIRE}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1078032',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsC{SDS}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1079032',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AsS{SAMSUNGLIFE}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('1081032',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsS{SAMSUNGSEC}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1082032',1,'ASYN','SDS','B2B_Svr1',' ','RCM1_OU_NET_AsS{SSCARD}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1082219',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsS{SSCARD_FM2}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1082220',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsS{SSCARD_FM1}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1083032',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AsS{SSfire}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1097032',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsC{settle}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1100032',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AsS{SMARTCARD}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1111032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsS{SHCARD_1123}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1112032',1,'ASYN','KMB','B2B_Svr1',' ','RCMS_OU_NET_AsC{SHCARD_CHK}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','신한카드','1'), + ('1128232',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsS{WEBCASH_SDS}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('1129232',1,'ASYN','SDS','B2B_Svr1',' ','RCM1_OU_NET_AsS{SSCARD_CHK}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1144218',1,'ASYN','HJJ','B2B_Svr1',' ','_KVN_OU_NET_AsS{KSVAN_SP}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1157176',1,'ASYN','KSJ','B2B_Svr1',' ','_KSJ_OU_NET_AsC{KSNET_JB}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1170032',1,'ASYN','POS','B2B_Svr1',' ','RCMS_CISCO_IO{POSDATA}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1173232',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AsS{HANASKCARD_CHK}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','하나SK카드','1'), + ('1181176',1,'ASYN','HBJ','B2B_Svr1',' ','_HBJ_OU_NET_AsC{KOVAN}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1181218',1,'ASYN','HJJ','B2B_Svr1',' ','_KVN_OU_NET_AsS{KOVAN_SP}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1184176',1,'ASYN','HJJ','B2B_Svr1',' ','_HJJ_OU_NET_AsS{NICE_JB}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1184218',1,'ASYN','HJJ','B2B_Svr1',' ','_KVN_OU_NET_AsS{NICE_SP}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1186176',1,'ASYN','HPJ','B2B_Svr1',' ','_HPJ_OU_NET_AsC{KIS_JB}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('1186218',1,'ASYN','HJJ','B2B_Svr1',' ','_KVN_OU_NET_AsS{KIS_SP}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1189057',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsC{KICC}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','한국정보통신','1'), + ('1189176',1,'ASYN','HTJ','B2B_Svr1',' ','_HTJ_OU_NET_AsC{KICC_JB}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1189218',1,'ASYN','HJJ','B2B_Svr1',' ','_KVN_OU_NET_AsS{KICC_SP}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1211032',1,'ASYN','KMB','B2B_Svr1',' ','RCMS_OU_NET_AsS{HUNGKUKLIFE}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1221032',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsS{ecBank}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1234032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{KIBNET}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1238032',1,'ASYN','KSN','B2B_Svr1',' ','RCMS_OU_NET_AsS{KSNET_KSN}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1238219',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsS{KSNET_SDS}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1238220',1,'ASYN','KSN','B2B_Svr1',' ','RCM5_OU_NET_AsS{KSNET}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('1238332',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsS{KSNET_SDS2}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1243032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsS{SHCARD_1129}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1243219',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{SHCARD_1368}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1243220',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{SHCARD_1369}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1245032',1,'ASYN','LGC','B2B_Svr1',' ','RCMS_OU_NET_AsC{LGCNS}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1247032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsS{LIG}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1257032',1,'ASYN','DAN','B2B_Svr1',' ','RCM8_OU_NET_AsC{SKCnC}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1258032',1,'ASYN','DAN','B2B_Svr1',' ','RCM8_OU_NET_AsC{SKCnC}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1310032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{SAHAK}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('1319232',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsC{KEFCI}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('1408032',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsC{MMAA}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2025057',1,'ASYN','KMB','B2B_Svr1',' ','RCMS_OU_NET_AsC{KYOBOSEC}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2083032',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AsS{LOTTECARD}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2083232',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AsS{LOTTECARD_CHK}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2089232',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AsC{WOORICARD_CHK}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','우리카드(체크)','1'), + ('2233032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{KAMKO}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','한국자산관리공사','1'), + ('2264032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsS{HDCARD}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2271032',1,'ASYN','KMB','B2B_Svr1',' ','RCM1_OU_NET_AsS{HDCARD_CHK}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2319032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{BCCARD}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2321032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsS{webcash_ivan}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('2324032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{HYOSUNGFMS}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2343278',1,'SYNC','KFI','B2B_Svr1',' ','_KFI_OU_HTT_SyC{IWORKS_CHINA}','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ',' ','1'), + ('2344278',1,'SYNC','RBF','B2B_Svr1',' ','_RBF_OU_NET_SyC{NS_SEOUL}','0','1',' ',' ','1',' ',' ','1',' ',0,'SOCKETOUT',10,' ','0','02',' ','1',' ',' ',' ','1'), + ('2345278',1,'SYNC','RBF','B2B_Svr1',' ','_RBF_OU_NET_SyC{NS_SEOUL}','0','1',' ',' ','1',' ',' ','1',' ',0,'SOCKETOUT',10,' ','0','02',' ','1',' ',' ',' ','1'), + ('2346278',1,'SYNC','KFI','B2B_Svr1',' ','_KFI_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ','서울ROC','1'), + ('2347278',1,'SYNC','KFI','B2B_Svr1',' ','_KFI_OU_HTT_SyC{NEWYORK}','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ','뉴욕ROC','1'), + ('2348278',1,'SYNC','KFI','B2B_Svr1',' ','_KFI_OU_HTT_SyC{OAKLAND}','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ','오클랜드ROC','1'), + ('2349278',1,'SYNC','KFI','B2B_Svr1',' ','_KFI_OU_HTT_SyC{CHINA}','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ','중국ROC','1'), + ('2351032',1,'ASYN','KMB','B2B_Svr1',' ','RCMS_OU_NET_AsC{DBINS}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2355032',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsC{MOGEF}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','여성가족부','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('2357278',1,'SYNC','KFI','B2B_Svr1',' ','_KFI_OU_HTT_SyC{DR}','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ','해외영업점DR','1'), + ('2361057',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{seoulmetro}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','서울교통공사','1'), + ('2361232',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsC{douzone}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','더즌','1'), + ('2363032',1,'ASYN','DAN','B2B_Svr1',' ','RCMS_OU_NET_AsC{WEBCASH_COUP}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('2363298',1,'ASYN','SDS','B2B_Svr1',' ','RCMS_OU_NET_AsC{WEBCASH_COUP2}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50500026',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500026}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500100',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500108',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500108}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500111',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500112',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500113',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500117',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500118',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500119',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500121',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500133',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500138',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500139',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500142',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500143',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500144',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500148',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500181',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500203',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500203}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500204',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500204}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500207',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500207}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500221',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500222',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500223',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500225',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500226',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500227',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500237',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500239',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500240',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500241',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500242',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500243',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500245',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500246',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500247',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500248',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500301',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500301}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500302',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500302}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500303',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500303}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500304',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500304}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500305',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500305}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500306',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500306}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500307',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500307}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500308',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500308}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500311',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsS{50500311}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500312',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500312}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500314',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500314}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500316',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500316}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500320',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500320}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500323',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500323}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500326',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500326}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500327',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_CISCO_IO{50500327}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500328',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500328}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500329',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500329}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500330',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500330}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500331',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsS{50500331}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500332',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500332}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500334',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500334}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500335',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500335}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500337',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500337}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500355',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500355}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500356',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500356}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500357',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsS{50500357}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500358',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsS{50500358}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500363',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500369',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500370',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500373',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500374',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500376',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500380',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500381',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500382',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500383',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500384',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500385',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500386',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500387',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500388',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500389',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500391',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500391}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500392',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500396',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500231}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500424',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500424}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500438',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsS{50500438}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500440',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500440}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500441',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500461',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500462',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500463',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500466',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500467',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500468',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500469',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500470',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500471',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500473',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500476',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500477',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500478',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500479',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500483',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500484',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500485',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500487',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500488',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500489',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500490',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500491',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500492',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500493',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500541}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500494',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500495',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500496',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500497',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500499',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500542',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500541}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500543',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500541}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500551',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500553',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500556',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500560',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500563',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500564',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500565',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500566',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500571',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500573',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500577',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500587',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500702',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500707',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500710',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500716',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500717',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500720',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500721',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500727',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500728',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500729',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500732',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500733',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500738',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500747',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500748',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500752',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500763',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500764',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500766',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500768',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500769',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500770',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500771',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500773',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500774',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500778',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500811',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500812',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500813',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500815',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500816',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500818',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500819',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500820',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500822',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500824',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500825',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500828',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500831',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500840',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500840}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500843',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500541}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500845',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500840}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500846',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500840}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500847',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500840}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500848',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500863',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500865',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500869',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_CISCO_IO{50500869}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500881',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500893',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500893}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500902',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500905',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500905}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500911',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500911}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500912',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500911}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500913',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500914',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500840}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500915',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500915}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500916',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500917',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500918',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500921',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500921}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500922',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500923',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500940',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500940}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500942',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500943',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500943}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500944',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500944}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500947',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500947}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500949',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500949}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500950',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500950}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500951',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500951}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500952',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500952}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500953',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500953}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500956',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500956}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500961',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500962',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500963',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500964',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500966',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500967',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500968',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500969',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500985',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500986',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500992',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500997',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500998',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501101',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501105',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501108',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501109',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501111',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501112',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501113',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50501114',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501115',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501116',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501117',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501118',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501119',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501120',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501124',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501125',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501128',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50501130',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501138',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501139',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501142',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501143',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501144',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501147',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501151',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501152',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501153',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','신한생명보험','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50501155',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501156',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501156}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501903',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501903}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501907',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501907}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501910',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501910}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501911',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501911}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501912',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501912}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501914',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501914}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501917',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501917}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501918',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500203}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50501924',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501928',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501929',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501930',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501932',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500108}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501933',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501934',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500391}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501935',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501937',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501941',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50501942',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501943',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501944',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501945',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501946',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501947',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501959',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501966',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501966}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501967',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501968',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50501969',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501970',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501971',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501973',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501973}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501974',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501980',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501981',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501982',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501936}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501983',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500391}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501984',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50501989',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501990',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501903}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501993',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501993}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501995',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501998',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50501999',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502000',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502002',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502003',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502007',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502008',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502009',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502010',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502013',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502014',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502015',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502016',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502017',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502018',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502019',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502020',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502021',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502022',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502023',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502024',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502025',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500440}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502028',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502028}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502029',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502032',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502033',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502035',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502038',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502039',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502045',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502046',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502049',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502051',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502052',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502054',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502056',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502087}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ','부산시상수도','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502058',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502059',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502060',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502061',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502063',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502064',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502066',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502067',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502068',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502069',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502070',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','롯데카드','1'), + ('50502071',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500840}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)아워홈','1'), + ('50502072',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502073',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502074',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502075',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502076',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502076}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502078',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502079',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502081',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502084',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502087',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502087}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502088',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502089',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502091',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500440}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)프레시원','1'), + ('50502092',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500440}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)프레시원강남','1'), + ('50502093',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500440}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502094',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500440}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502095',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500440}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)프레시원인천','1'), + ('50502097',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500440}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)프레시원부산','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502098',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502099',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국광물자원공사','1'), + ('50502100',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502101',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502102',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502103',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','롯데카드','1'), + ('50502104',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502105',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502109',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502110',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502111',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502112',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502115',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502116',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502118',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502119',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','호반건설','1'), + ('50502122',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','동양미래대학교','1'), + ('50502123',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502124',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','유한대학교','1'), + ('50502125',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)리치빔','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502126',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502127',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','구리시청(주정차과태료)','1'), + ('50502128',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502129',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502130',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502131',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','아모레퍼시픽','1'), + ('50502132',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502133',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한밭대학교','1'), + ('50502134',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광운대학교','1'), + ('50502136',1,'ASYN','EGX','B2B_Svr1',' ','_EGX_OU_NET_AsC{10026000}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502137',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502138',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국건설기술연구원','1'), + ('50502139',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500541}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','현대성우쏠라이트','1'), + ('50502140',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502140}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','롯데카드(카드론)','1'), + ('50502141',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502142',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsC{50502142}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','서울보증보험','1'), + ('50502143',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502144',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502144}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502145',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502145}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502147',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502148',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502149',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502150',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국야쿠르트','1'), + ('50502151',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502152',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502152}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','국세청','1'), + ('50502154',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','호반건설산업','1'), + ('50502155',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502156',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502158',1,'ASYN','EIJ','B2B_Svr1',' ','_EIJ_OU_NET_AsC{MMAA}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502159',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502160',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','의정부시청','1'), + ('50502165',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502166',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','코카콜라','1'), + ('50502167',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502169',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502170',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502173',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502174',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502175',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502176',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502177',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502178',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502179',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502180',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502181',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502183',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502185',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502187',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502188',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502189',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502190',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502191',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502192',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502193',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502194',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502195',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502196',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502197',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502198',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502199',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502209',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502210',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502212',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502213',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502214',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502215',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500921}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502216',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502217',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502219',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502222',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502223',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502224',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502225',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502226',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502227',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502229',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502229}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502232',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502234',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','엘티대한제3호뉴스테이','1'), + ('50502802',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502804',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502805',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502229}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502806',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502807',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502808',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502808}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502809',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502810',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502811',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502812',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502814',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502087}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502815',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502816',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502818',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502819',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502821',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501903}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502823',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502824',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502825',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502826',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502833',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502834',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502835',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502836',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502838',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500108}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502839',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','대한소방공제회','1'), + ('50502840',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500940}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국자산관리(공사채권)','1'), + ('50502841',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','안양시청(세외수입)','1'), + ('50502842',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','안양시청(세외수입_만안구)','1'), + ('50502843',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','안양시청(세외수입_동안구)','1'), + ('50502844',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','디에스솔루션즈','1'), + ('50502845',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','시흥시청','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502846',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','구리시청(세외수입)','1'), + ('50502847',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','용인시청(세외수입)','1'), + ('50502848',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502849',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502850',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502851',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500956}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국자산관리공사(개발회계)','1'), + ('50502852',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502853',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502854',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502855',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)예미지뉴스테이(예미지)','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502857',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','연구개발특구진흥재단','1'), + ('50502858',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','엘티대한제2호(타워피엠씨)','1'), + ('50600898',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600893}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50502859',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','수원시상수원사업소','1'), + ('50502860',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','코리아에셋매니지먼트','1'), + ('50502861',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','엘티대한제3호뉴스테이(임대료)','1'), + ('50502862',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','남양주시청(세외특별)','1'), + ('50502863',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','남양주시청(세외일반)','1'), + ('50502864',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','케이리얼티제1호뉴스테이','1'), + ('50502865',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','티에스주택','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502866',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)동부익스프레스','1'), + ('50502867',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502867}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502868',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500108}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','나이스페이먼츠(동행복권)','1'), + ('50502870',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','파주시청(세외수입)','1'), + ('50502871',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502087}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','2',' ',' ','부산시금고','1'), + ('50502872',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502235}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','노원구','1'), + ('50502873',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502235}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광진구','1'), + ('50502874',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','국제대학교','1'), + ('50502875',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광주시청','1'), + ('50502876',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)교원크리에이티브','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502877',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','에이치디씨현대산업개발(주)','1'), + ('50502878',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광주광역시남구청(지방세)','1'), + ('50502879',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광주광역시남구청(세외수입)','1'), + ('50502880',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광주광역시남구청(주정차)','1'), + ('50502881',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광주광역시남구청(환경개선)','1'), + ('50502882',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광주광역시남구청(교통유발)','1'), + ('50502883',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','엑소후레쉬물류','1'), + ('50502884',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','대한제5호뉴스테이','1'), + ('50502885',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)이월드쥬얼리사업부가산','1'), + ('50502887',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사부산울산지역','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502888',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사강원지역','1'), + ('50502889',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사용인지사','1'), + ('50502890',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','엘티대한제3호뉴스테이(타워피엠씨)','1'), + ('50502891',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','티에스자산개발(주)','1'), + ('50502892',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','롯데건설(주)','1'), + ('50502893',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','성원애드피아몰','1'), + ('50502894',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','풀무원건강생활(주)','1'), + ('50502895',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502235}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광주남구청','1'), + ('50502896',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','성남시청(세외수입)','1'), + ('50502897',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','안양시 상하수도사업소','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502898',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)에쓰프레시','1'), + ('50502899',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','대우조선해양(주)서울사무소','1'), + ('50502900',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502900}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','douzone','1'), + ('50502901',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','수원시청(세외수입)','1'), + ('50502902',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','수원시청(주정차과태료용)','1'), + ('50502903',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','하나자산신탁4','1'), + ('50502904',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502900}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','에스엠하이플러스','1'), + ('50502906',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','청강문화산업대학교(신입생)','1'), + ('50502907',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','청강문화산업대학교','1'), + ('50502908',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502909',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','의정부시(세외수입)','1'), + ('50502910',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502229}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광주광역시청(세외수입)','1'), + ('50502911',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','티에스리빙(주)','1'), + ('50502912',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502912}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','여성가족부','1'), + ('50502913',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','올림푸스한국(주)','1'), + ('50502914',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502915',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','현대건설(주)','1'), + ('50502916',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)케이티셋','1'), + ('50502917',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502917}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','서울교통공사','1'), + ('50502918',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','피에스앤마케팅','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502919',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502152}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','경찰청(경범죄)','1'), + ('50502920',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','파주시환경수도사업단','1'), + ('50502921',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','가톨릭평화방송','1'), + ('50502922',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','하나자산신탁5','1'), + ('50502923',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','광양시청','1'), + ('50502924',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','서한카이트제11호','1'), + ('50502925',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','씨제이올리브영','1'), + ('50502926',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','계원예술대학교','1'), + ('50502927',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한남대학교','1'), + ('50502928',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','티에스건설(주)','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502929',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','우미토건','1'), + ('50502930',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502931',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502932',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502933',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502934',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502935',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502936',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502937',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502938',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502939',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502940',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502941',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502942',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502943',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502944',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502945',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502946',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502947',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502948',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502949',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502950',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502951',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502952',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502953',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502954',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502955',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502956',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502957',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502958',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502959',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502960',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502961',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502962',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502963',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502964',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502965',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502966',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502967',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502968',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502969',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502970',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국전기안전공사','1'), + ('50502971',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502972',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','아주대학교','1'), + ('50502973',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','군산대학교','1'), + ('50502974',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','(주)무궁화신탁','1'), + ('50502975',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502900}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','인천김포고속도로','1'), + ('50502977',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50502900}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502978',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','천안시청(서북구)','1'), + ('50502979',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','천안시청(동남구)','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502980',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','중봉건설','1'), + ('50502981',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','중흥에스클래스','1'), + ('50502982',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','해피투게더하우스제3호','1'), + ('50502984',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','해태아이스크림(주)','1'), + ('50502985',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50502900}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','더즌(재판매)','1'), + ('50502986',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','구리시청(세외일반)','1'), + ('50502987',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50502989',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국장학재단(기부금)','1'), + ('50502990',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','오설록','1'), + ('50502993',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50502994',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','대한제10호뉴스테이','1'), + ('50502995',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','인피니소프트(재판매)','1'), + ('50502996',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','엘티케이비문래제4호뉴스테이','1'), + ('50502997',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','아시아신탁2','1'), + ('50502998',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','하나자산신탁6','1'), + ('50502999',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503001',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503002',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503003',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503004',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50501903}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','근로복지공단(재난기부금)','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50503005',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503007',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503008',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503009',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503010',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503011',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503012',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503013',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503014',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503015',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50503016',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503017',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503018',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503019',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503020',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503021',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503022',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503023',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503024',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503025',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50503026',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503027',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503028',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503029',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503030',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503031',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsC{50501114}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503032',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50503033',1,'ASYN','YGS',' ',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('505A0325',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500325A}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50600857',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_CISCO_IO{50600857}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50600858',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_CISCO_IO{50600858}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600866',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600867}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','롯데PS넷(세븐일레븐)','1'), + ('50600867',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600867}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600868',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600867}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600869',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_CISCO_IO{50600869}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600890',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600890}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600891',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600890}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600893',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600893}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600894',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600894}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600896',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600894}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50600899',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600894}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600901',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600890}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','효성티앤에스(GSR)','1'), + ('50600902',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600890}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600903',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600893}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600904',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600894}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600905',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_CISCO_IO{50600905}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600906',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600893}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50600907',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600890}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50699857',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_CISCO_IO{50699857}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50699890',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600890}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50699894',1,'ASYN','ATS','B2B_Svr1',' ','_ATS_OU_NET_AsS{50600894}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('50800001',1,'ASYN','EFL','B2B_Svr1',' ','_EFL_IO_NET_AsS{50800001}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','대우증권','1'), + ('50800002',1,'ASYN','EFL','B2B_Svr1',' ','_EFL_IO_NET_AsS{50800002}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50800003',1,'ASYN','EFL','B2B_Svr1',' ','_EFL_OU_NET_AsS{50800003}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50800004',1,'ASYN','EFL','B2B_Svr1',' ','_EFL_OU_NET_AsS{50800863}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50800005',1,'ASYN','EFL','B2B_Svr1',' ','_EFL_OU_NET_AsS{50800005}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50800006',1,'ASYN','EFL','B2B_Svr1',' ','_EFL_OU_NET_AsC{50801111}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','한국무역보험공사(외화)','1'), + ('50800007',1,'ASYN','EFL','B2B_Svr1',' ','_EFL_OU_NET_AsS{50800007}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50800008',1,'ASYN','EFL','B2B_Svr1',' ','_EFL_OU_NET_AsS{50800008}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ','키움증권','1'), + ('50800009',1,'ASYN','EFL',' ',' ','_EFL_OU_NET_AsS{50800863}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('60500207',1,'ASYN','EJC','B2B_Svr1',' ','_EJC_OU_NET_AsS{SSFUTURES}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('60500306',1,'ASYN','EJC','B2B_Svr1',' ','_EJC_OU_NET_AsC{DONGBUSEC}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('60500312',1,'ASYN','EJC','B2B_Svr1',' ','_EJC_OU_NET_AsS{HMSEC}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('60500314',1,'ASYN','EJC','B2B_Svr1',' ','_EJC_OU_NET_AsS{MERITZSEC}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('60501919',1,'ASYN','EJC','B2B_Svr1',' ','_EJC_OU_NET_AsS{KBSEC}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('60501982',1,'ASYN','EJC','B2B_Svr1',' ','_EJC_OU_NET_AsS{EGFUTURES}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('60502162',1,'ASYN','EJC','B2B_Svr1',' ','_EJC_OU_NET_AsS{KRFUTURES}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('A1403065',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{A1403065}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('A1404065',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{A1404065}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('BCOASYN',1,'ASYN','BCO','B2B_Svr1',' ','_BCO_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('BCOSYNC',1,'SYNC','BCO','B2B_Svr1',' ','_BCO_OU_HTT_SyC{NS}','0','1',' ',' ','1',' ',' ','1','TRANSFORM_EAI_UJNTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('BFAASYN',1,'ASYN','BFA','B2B_Svr1',' ','_BFA_OU_HTT_AsC{NS}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('BFASYNC',1,'SYNC','BFA','B2B_Svr1',' ','_BFA_OU_HTT_SyC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_UJNTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('BFDASYN',1,'ASYN','BFD','B2B_Svr1',' ','_BFD_OU_HTT_AsC{NS}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('BFDSYNC',1,'SYNC','BFD','B2B_Svr1',' ','_BFD_OU_HTT_SyC{NS}','0','1',' ',' ','1',' ',' ','1','TRANSFORM_EAI_UJNTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('BFFASYN',1,'ASYN','BFF','B2B_Svr1',' ','_BFF_OU_HTT_AsC{NS}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('BFFSYNC',1,'SYNC','BFF','B2B_Svr1',' ','_BFF_OU_HTT_SyC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_UJNTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('BNJASYN',1,'ASYN','BNJ','B2B_Svr1',' ','_BNJ_OU_HTT_AsC{NS}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('BNJSYNC',1,'SYNC','BNJ','B2B_Svr1',' ','_BNJ_OU_HTT_SyC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_UJNTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('CTKASYN',1,'ASYN','KJI','B2B_Svr1',' ','_CTK_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('CTKSYNC',1,'SYNC','KJI','B2B_Svr1',' ','_CTK_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('GI1ASYN',1,'ASYN','PCB','B2B_Svr1',' ','_PCB_OU_HTT_AsC{NS_2}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('GI1SYNC',1,'SYNC','PCB','B2B_Svr1',' ','_PCB_OU_HTT_SyC{NS}','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('GI2ASYN',1,'ASYN','PCB','B2B_Svr1',' ','_PCB_OU_HTT_AsC{NS_3}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('GI2SYNC',1,'SYNC','PCB','B2B_Svr1',' ','_PCB_OU_HTT_SyC{NS_2}','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('GI3ASYN',1,'ASYN','PCB','B2B_Svr1',' ','_PCB_OU_HTT_AsC{NS_4}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('GI3SYNC',1,'SYNC','PCB','B2B_Svr1',' ','_PCB_OU_HTT_SyC{NS_3}','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('GI4ASYN',1,'ASYN','PCB','B2B_Svr1',' ','_PCB_OU_HTT_AsC{NS}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('GI4SYNC',1,'SYNC','PCB','B2B_Svr1',' ','_PCB_OU_HTT_SyC{NS_4}','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('HDDASYN',1,'ASYN','KJI','B2B_Svr1',' ','_HDD_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('HDDSYNC',1,'SYNC','KJI','B2B_Svr1',' ','_HDD_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KAAASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KAA_OU_HTT_AsC{NS}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KAASYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KAA_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KAFASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KAF_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KAFSYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KAF_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KB0001',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0003',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0003}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0004',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0005',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0006',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0006}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0009',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0014',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0015',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0016',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0017',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0020',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0021',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0023',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0024',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0025',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0026',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0027',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0028',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0028}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0029',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0029}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0030',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0031',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0028}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0032',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0038',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0039',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0040',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0042',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0043',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0044',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0045',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0046',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0049',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0050',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0029}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0051',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0053',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0060',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0060}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0062',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0063',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0064',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0029}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0065',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0066',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0067',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0068',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0071',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0073',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0074',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0075',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0076',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0076}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','대우증권','1'), + ('KB0078',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0079',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0090',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0098',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0106',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0029}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','잠금상선','1'), + ('KB0107',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','삼성물산','1'), + ('KB0108',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','CJ넷마블','1'), + ('KB0109',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','현대 글로비스','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0111',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','삼성전기','1'), + ('KB0112',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','코오롱인더스트리','1'), + ('KB0117',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','코오롱베니트','1'), + ('KB0118',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','코리아이플랫폼','1'), + ('KB0119',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','동아에스티','1'), + ('KB0121',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','한국거래소','1'), + ('KB0126',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0029}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0127',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0029}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0132',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','아모레퍼시픽','1'), + ('KB0133',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0028}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0134',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','씨제이프레시웨이','1'), + ('KB0136',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','(주)실리콘파일','1'), + ('KB0139',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','광물자원공사','1'), + ('KB0140',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0028}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0144',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0145',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0147',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0029}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','시노코페트로케미컬(주)','1'), + ('KB0148',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','씨제이이앤엠','1'), + ('KB0150',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0151',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0155',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0029}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','한화토탈','1'), + ('KB0163',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0163}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','교보증권','1'), + ('KB0168',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0169',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0173',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0174',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0175',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_IO_NET_AsS{KB0175}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0184',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0185',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0186',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0191',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0196',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0197',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0200',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0200}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0201',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0202',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0202}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0204',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0205',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0214',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0215',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0216',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','하나파워시스템','1'), + ('KB0218',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0219',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0220',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0221',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0222',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0222}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','대신증권','1'), + ('KB0223',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0229',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0235',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','(주)센트랄','1'), + ('KB0236',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','현대트랜시스','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0243',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','코오롱생명과학(주)','1'), + ('KB0251',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','대림피앤피','1'), + ('KB0252',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','태평양물산','1'), + ('KB0253',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','와이즈퍼시픽','1'), + ('KB0254',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','두산인프라코어','1'), + ('KB0255',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0029}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','(주)엘지화학','1'), + ('KB0256',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','나디아퍼시픽주식회사','1'), + ('KB0257',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0038}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','현대건설(주)','1'), + ('KB0263',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0001}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','비바리퍼블리카','1'), + ('KB0264',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','(주)휴맥스','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KB0267',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsS{KB0267}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KB0270',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0009}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ','씨제이올리브영주식회사','1'), + ('KB0278',1,'ASYN','KTN','B2B_Svr1',' ','_KTN_OU_NET_AsC{KB0004}','0','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','02',' ','2',' ',' ',' ','1'), + ('KECASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KEC_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KECSYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KEC_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KEDASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KED_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ',' ','1'), + ('KEDSYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KED_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ',' ','1'), + ('KEEASYN',1,'ASYN','KEE','B2B_Svr1',' ','CMBS_OU_HTT_AsC{InHouse2_IN}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KEESYNC',1,'SYNC','KEE','B2B_Svr1',' ','CMBS_OU_HTT_SyC{InHouse2_IN}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KFLASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KFL_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KFLSYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KFL_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',10,' ','0','02',' ','1',' ',' ',' ','1'), + ('KGBASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KGB_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KGBSYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KGB_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KGIASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KGI_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KGISYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KGI_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KGNASYN',1,'ASYN','KGN','B2B_Svr1',' ','_KGN_OU_HTT_AsC','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KGNSYNC',1,'SYNC','KGN','B2B_Svr1',' ','_KGN_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KIEIERA1',1,'ASYN','KIE','B2B_Svr1',' ','_KIE_OU_NET_AsS{KTNET}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','1',' ',' ','KTNET','1'), + ('KIEIERA2',1,'ASYN','KIE','B2B_Svr1',' ','_KIE_OU_NET_AsS{FINOTEK}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','1',' ',' ','피노텍','1'), + ('KIEIERS1',1,'SYNC','KIE','B2B_Svr1',' ','_KIE_OU_NET_SyS{KTNET}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','1',' ',' ','KTNET','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KIEIERS2',1,'SYNC','KIE','B2B_Svr1',' ','_KIE_OU_NET_SyS{FINOTEK}','1','1',' ',' ','1',' ',' ','0',' ',0,'SOCKETOUT',60,' ','0','01',' ','1',' ',' ','피노텍','1'), + ('KIKASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KIK_OU_HTT_AsC{NS}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KIKSYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KIK_OU_HTTP_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KJ1ASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KJI_OU_HTT_AsC{NS_UJN}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KJ1SYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KJI_OU_HTT_SyC{NS_UJN}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_UJNTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KJIASYN',1,'ASYN','KJI','B2B_Svr1',' ','_KJI_OU_HTT_AsC','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KJISYNC',1,'SYNC','KJI','B2B_Svr1',' ','_KJI_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KJOASYN',1,'ASYN','KJI','B2B_Svr1',' ','MIS0_OU_HTT_AsC{MIS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KJOSYNC',1,'SYNC','KJI','B2B_Svr1',' ','MIS0_OU_HTT_SyC{MIS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KMAASYN',1,'ASYN','KMA','B2B_Svr1',' ','_KMA_OU_HTT_AsC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('KMASYNC',1,'SYNC','KMA','B2B_Svr1',' ','_KMA_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KMBASYN',1,'ASYN','KMB','B2B_Svr1',' ','_KMB_OU_HTT_AsC','0','1',' ',' ','0',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KMBSYNC',1,'SYNC','KMB','B2B_Svr1',' ','_KMB_OU_HTT_SyC','0','1',' ',' ','0',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KMDASYN',1,'ASYN','KMD','B2B_Svr1',' ','_KMD_OU_HTT_AsC','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('KMDSYNC',1,'SYNC','KMD','B2B_Svr1',' ','_KMD_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('MAQASYN',1,'ASYN','KJI','B2B_Svr1',' ','MIS3_OU_HTT_AsC{MIS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('MAQSYNC',1,'SYNC','KJI','B2B_Svr1',' ','MIS3_OU_HTT_SyC{MIS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('MBAASYN',1,'ASYN','KJI','B2B_Svr1',' ','_MBA_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('MBASYNC',1,'SYNC','KJI','B2B_Svr1',' ','_MBA_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('MBIASYN',1,'ASYN','KJI','B2B_Svr1',' ','_MBI_OU_HTT_AsC{NS}','0','1',' ',' ','0',' ',' ','0',' ',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'); +INSERT INTO tseaihe03 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('MBISYNC',1,'SYNC','KJI','B2B_Svr1',' ','_MBI_OU_HTT_SyC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('PDMASYN',1,'ASYN','KJI','B2B_Svr1',' ','_PDM_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('WFPASYN',1,'ASYN','KJI','B2B_Svr1',' ','_WFP_OU_HTT_AsC{NS}','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'), + ('WFPSYNC',1,'SYNC','KJI','B2B_Svr1',' ','_WFP_OU_HTT_SyC','0','1',' ',' ','1',' ',' ','1',' TRANSFORM_EAI_XMLTOEBC_ERR',0,'HTTPCRM',0,' ','0','02',' ','1',' ',' ',' ','1'); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/bizkey/init_tseaifr03.sql b/src/test/resources/com/eactive/eai/common/bizkey/init_tseaifr03.sql new file mode 100644 index 0000000..3121e09 --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/bizkey/init_tseaifr03.sql @@ -0,0 +1,5 @@ +INSERT INTO tseaifr03 (eaisvcname,etractdstcd,fldprcssno,msgdstcd,bzwkfldname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms) VALUES + ('AC1B805Q01R1','TR',1,'ASC','TST_OTST00020020_RES.NIC30_9_10','F',' ','2022050518101266 '), + ('AC1B805Q01S2','TR',1,' ','TST_IDAS00020696_REQ.NIC30_9_10','F',' ','2022070516385093 '), + ('AC1B805Q09R1','TR',1,'ASC','TST_OTST00020006_RES.NIC30_9_10',' ',' ',' '), + ('AC1B805Q09S2','TR',1,'ASC','TST_IDAS00020686_REQ.NIC30_9_10',' ',' ',' '); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/c2rservice/init_tseaihe04.sql b/src/test/resources/com/eactive/eai/common/c2rservice/init_tseaihe04.sql new file mode 100644 index 0000000..ab7d1b0 --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/c2rservice/init_tseaihe04.sql @@ -0,0 +1,57 @@ +INSERT INTO tseaihe04 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500143',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500144',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500148',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500181',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500881}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500203',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500203}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500204',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500204}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500207',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500207}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500221',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500222',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500223',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe04 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500225',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500226',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500227',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500237',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500239',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500240',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500241',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500242',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500243',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500245',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe04 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500246',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500247',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50502232}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500248',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500471}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500301',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500301}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500302',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500302}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500303',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500303}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500304',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500304}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500305',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500305}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500306',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500306}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500307',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500307}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe04 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500308',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500308}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500311',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsS{50500311}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500312',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500312}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500314',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500314}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500316',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500316}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500320',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500320}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500323',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500323}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500326',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500326}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500327',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_CISCO_IO{50500327}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500328',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500328}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe04 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500329',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500329}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500330',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500330}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500331',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsS{50500331}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500332',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500332}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500334',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500334}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500335',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500335}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500337',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500337}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500355',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsC{50500355}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500356',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_OU_NET_AsS{50500356}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'), + ('50500357',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsS{50500357}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); +INSERT INTO tseaihe04 (extnlinstiidnfiname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,adptrbzwkgroupdesc,useyn) VALUES + ('50500358',1,'ASYN','YGS','B2B_Svr1',' ','_YGS_IO_NET_AsS{50500358}','1','1',' ',' ','0',' ',' ','0',' ',0,'SOCKETOUT',0,' ','0','01',' ','2',' ',' ',' ','1'); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/inflow/init_tseaifr09.sql b/src/test/resources/com/eactive/eai/common/inflow/init_tseaifr09.sql new file mode 100644 index 0000000..ac25a7f --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/inflow/init_tseaifr09.sql @@ -0,0 +1,6 @@ +INSERT INTO tseaifr09 (type,name,threshold,useyn,thresholdpersecond,thresholdtimeunit) VALUES + ('01','_AA0_IN_NET_AsS',10,'1',0,NULL), + ('01','_AB0_IN_NET_AsS',3,'1',0,NULL), + ('01','_TST_IN_NET_AsS',1,'1',0,NULL), + ('02','FASSFEP00000004S2',10,'1',0,NULL), + ('02','FDASFEP00000009S2',2,'1',0,NULL); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/inflow/init_tseaifr11.sql b/src/test/resources/com/eactive/eai/common/inflow/init_tseaifr11.sql new file mode 100644 index 0000000..4549ce0 --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/inflow/init_tseaifr11.sql @@ -0,0 +1,24 @@ +INSERT INTO tseaifr11 (eaibzwkdstcd,msgdpstyms,eaisvcserno,eaisevrinstncname,eaisvcname,adptrbzwkgroupname,threshold,thresholdpersecond,thresholdtimeunit) VALUES + ('XYZ','20220207164038502','1104b23e73-ef92-464d-9719-f9716a8a1b18 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','1110619664-4601-4da4-8b82-311e7645c23f ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','1110758729-005b-4da7-855f-445ba24643c8 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','113ceb048f-87a5-4a2a-b411-c678f57b032d ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','114a2c7de4-8d02-4e0c-8114-4fb22dc8dbcb ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','1185a617d8-6d63-4432-ad16-a753739c8554 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','11931aef2b-f8ef-4085-8b5b-9e23b5acad52 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','119b508b78-2012-4aed-bd47-084ded1fd6bc ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','11a6015a50-a474-4dc7-b279-4d0257bb0604 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','11a912f79a-ce85-4edd-b326-b6caa2a6ef95 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','11d0708457-55e4-4c98-ae89-ccfeaff08b76 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038502','11f64d1bda-838a-473d-a16a-5fab25d12f5a ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038503','110ade11be-81a8-4d47-8c39-b551a05d5af0 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038503','114a1ec2eb-dcbb-45ff-981f-4c61e6a0141a ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038503','11514832cd-fe6e-4b86-a910-4c21e9af9246 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038503','117b242de9-953e-42c7-b5dc-e83a5cf43f28 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038503','11a2e2f15b-57b4-49d6-8188-4c19eb59a9e0 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038503','11e76c8b2c-3e9f-4053-b7a7-ecb1d67867f1 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038843','1102378fde-4918-414a-907a-c4efe35b7ec4 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038854','114d621f7d-bf6c-45ab-af9e-dc04bc12fe40 ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038854','115eec32bd-3216-45dd-af1c-a794be905dac ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038855','11e7ad837d-8500-445a-a42c-a8a795b7059b ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL), + ('XYZ','20220207164038858','114027f76e-04ec-43ee-9988-dffe39247a3d ','fepSvr11','FFEPDAS00000328S1','_TST_IN_NET_AsS',1,0,NULL); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/message/init_tseaifr01.sql b/src/test/resources/com/eactive/eai/common/message/init_tseaifr01.sql new file mode 100644 index 0000000..7cc2712 --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/message/init_tseaifr01.sql @@ -0,0 +1,107 @@ +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('ECISIIS00000002S1',1, 1, 0, '', '', ''), + ('ECISSIS00000002S1',1, 2, 0, '', '', ''), + ('EDASCIS00000001S1',1, 3, 0, '', '', ''), + ('EDASCIS00000002S1',1, 4, 0, '', '', ''), + ('EDASCIS00000003S1',1, 5, 0, '', '', ''), + ('EDASCIS00000009S1',1, 6, 0, '', '', ''), + ('EDASCIS00000014S1',1, 7, 0, '', '', ''), + ('EDASCIS00000015S1',1, 8, 0, '', '', ''), + ('EDASCIS00000016S1',1, 9, 0, '', '', ''), + ('EDASCIS00000017S1',1, 10, 0, '', '', ''); +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('EDASCIS00000018S1',1, 11, 0, '', '', ''), + ('EDASCIS00000019S1',1, 12, 0, '', '', ''), + ('EDASCIS00000020S1',1, 13, 0, '', '', ''), + ('EDASCIS00020013S1',1, 14, 0, '', '', ''), + ('EDASCIS00020014S1',1, 15, 0, '', '', ''), + ('EDASCIS00020015S1',1, 16, 0, '', '', ''), + ('EDASCIS00020017S1',1, 17, 0, '', '', ''), + ('EDASCIS00020018S1',1, 18, 0, '', '', ''), + ('EDASDAS00000013S1',1, 19, 0, '', '', ''), + ('EDASIDS00000002S1',1, 20, 0, '', '', ''); +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('EDASIDS00000003S1',1, 21, 0, '', '', ''), + ('EDASIIS00000002S1',1, 22, 0, '', '', ''), + ('EDASSAB00000002S1',1, 23, 0, '', '', ''), + ('EDASSAB00000003S1',1, 24, 0, '', '', ''), + ('EDASSAB00000004S1',1, 25, 0, '', '', ''), + ('EDASSAB00000005S1',1, 26, 0, '', '', ''), + ('EDASSAB00000006S1',1, 27, 0, '', '', ''), + ('EDASSAB00000007S1',1, 28, 0, '', '', ''), + ('EDASSAB00000008S1',1, 29, 0, '', '', ''), + ('EDASSAB00000009S1',1, 30, 0, '', '', ''); +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('EDASSAB00000010S1',1, 31, 0, '', '', ''), + ('EDASSAB00000011S1',1, 32, 0, '', '', ''), + ('EDASSAB00000030S1',1, 33, 0, '', '', ''), + ('EDASSAB00000031S1',1, 34, 0, '', '', ''), + ('EDASSAB00000032S1',1, 35, 0, '', '', ''), + ('EDASSAB00000071S1',1, 36, 0, '', '', ''), + ('EDASSAB00000072S1',1, 37, 0, '', '', ''), + ('EDASSDS00000002S1',1, 38, 0, '', '', ''), + ('EDASSIS00000002S1',1, 39, 0, '', '', ''), + ('EDDMDAS00000002S1',1, 40, 0, '', '', ''); +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('EDDMDAS00000003S1',1, 41, 0, '', '', ''), + ('EDDMDAS00000004S1',1, 42, 0, '', '', ''), + ('EDDMDAS00000005S1',1, 43, 0, '', '', ''), + ('EDDMDAS00000006S1',1, 44, 0, '', '', ''), + ('EDDMDAS00000007S1',1, 45, 0, '', '', ''), + ('EDDMDAS00000008S1',1, 46, 0, '', '', ''), + ('EDDMIAS00000002S1',1, 47, 0, '', '', ''), + ('EDDMIAS00000003S1',1, 48, 0, '', '', ''), + ('EDDMIAS00000004S1',1, 49, 0, '', '', ''), + ('EDDMIAS00000005S1',1, 50, 0, '', '', ''); +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('EDDMIAS00000006S1',1, 51, 0, '', '', ''), + ('EDDMIAS00000007S1',1, 52, 0, '', '', ''), + ('EDDMIAS00000008S1',1, 53, 0, '', '', ''), + ('EDDMIAS00000009S1',1, 54, 0, '', '', ''), + ('EDDMIAS00000010S1',1, 55, 0, '', '', ''), + ('EDDMIAS00000011S1',1, 56, 0, '', '', ''), + ('EDDMIAS00000012S1',1, 57, 0, '', '', ''), + ('EDDMIAS00000013S1',1, 58, 0, '', '', ''), + ('EDDMIAS00000014S1',1, 59, 0, '', '', ''), + ('EDDMIAS00000015S1',1, 60, 0, '', '', ''); +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('EDDMIAS00000016S1',1, 61, 0, '', '', ''), + ('EDDMIAS00000017S1',1, 62, 0, '', '', ''), + ('EDDMIAS00000018S1',1, 63, 0, '', '', ''), + ('EDDMIAS00000019S1',1, 64, 0, '', '', ''), + ('EDDMIAS00000020S1',1, 65, 0, '', '', ''), + ('EDDMIAS00000021S1',1, 66, 0, '', '', ''), + ('EDDMIAS00000022S1',1, 67, 0, '', '', ''), + ('EDDMIAS00000023S1',1, 68, 0, '', '', ''), + ('EDDMIAS00000024S1',1, 69, 0, '', '', ''), + ('EDDMIAS00000025S1',1, 70, 0, '', '', ''); +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('EDDMIAS00000026S1',1, 71, 0, '', '', ''), + ('EDDMIAS00000027S1',1, 72, 0, '', '', ''), + ('EDDMIAS00000028S1',1, 73, 0, '', '', ''), + ('EDDMIAS00000029S1',1, 74, 0, '', '', ''), + ('EDDMIAS00000030S1',1, 75, 0, '', '', ''), + ('EDDMIAS00000031S1',1, 76, 0, '', '', ''), + ('EDDMIAS00000032S1',1, 77, 0, '', '', ''), + ('EDDMIAS00000033S1',1, 78, 0, '', '', ''), + ('EIDSIIS00000002S1',1, 79, 0, '', '', ''), + ('EIDSSIS00000002S1',1, 80, 0, '', '', ''); +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('EIISIDS00000002S1',1, 81, 0, '', '', ''), + ('EIISSDS00000002S1',1, 82, 0, '', '', ''), + ('EMHSDAS00000001S1',1, 83, 0, '', '', ''), + ('EMHSMHS00000001S1',1, 84, 0, '', '', ''), + ('ESDSIIS00000002S1',1, 85, 0, '', '', ''), + ('ESDSSIS00000002S1',1, 86, 0, '', '', ''), + ('ESISIDS00000002S1',1, 87, 0, '', '', ''), + ('ESISSDS00000002S1',1, 88, 0, '', '', ''), + ('TST00000009S1',1, 89, 0, '', '', ''), + ('TST0071302S1',1, 90, 0, '', '', ''); +INSERT INTO tseaifr01 (eaisvcname, svcprcssno, ruleserno, rsultprcssno, rulefldgroupname, rulefldname, cmprctnt) VALUES + ('TST0071802S1',1, 91, 0, '', '', ''), + ('TST0071901S1',1, 92, 0, '', '', ''), + ('TST0200100S1',1, 93, 0, '', '', ''), + ('신규S1',1, 94, 0, '', '', ''), + ('EDASSAB00000030S1',2, 95, 0, '', '', ''), + ('BASICTEST001S1',1, 96, 0, '', '', ''), + ('BASICTEST002S1',1, 97, 0, '', '', ''); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/message/init_tseaihe01.sql b/src/test/resources/com/eactive/eai/common/message/init_tseaihe01.sql new file mode 100644 index 0000000..240401b --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/message/init_tseaihe01.sql @@ -0,0 +1,106 @@ +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('ECISIIS00000002S1','CEA','0','SYNC','SINGLE','BASEFC','ONLINE','1','_CIS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (채널통합서비스 -> 인터넷보험)','E',' ','2021120315305511 ',' ','R','1','00002','CECEC00001',NULL,NULL,'SI210169',NULL), + ('ECISSIS00000002S1','CEA','0','SYNC','SINGLE','BASEFC','ONLINE','1','_CIS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (채널통합서비스 -> 스마트보험)','E',' ','2021120315394977 ',' ','R','1','00002','CEEEE00001',NULL,NULL,'SI210169',NULL), + ('EDASCIS00000001S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','포탈 등록여부 조회','E',' ','2021112316443689 ',' ','R','1','00012','ATKCM00402',NULL,NULL,'SI210174',NULL), + ('EDASCIS00000002S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','포탈 등록가입 연동','E',' ','2021112316450524 ',' ','R','1','00007','ATKCM00402',NULL,NULL,'SI210174',NULL), + ('EDASCIS00000003S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','스마트폰가입 동의','E',' ','2021102510083365 ',' ','R','1','00004','ATKCM01502',NULL,NULL,'SI210174',NULL), + ('EDASCIS00000009S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','계좌소유고객번호변경','E',' ','2021110813373613 ',' ','R','1','00005','ATKCS00803',NULL,NULL,'SI210176',NULL), + ('EDASCIS00000014S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','인증서신청정보조회','E',' ','2021101918102574 ',' ','R','1','00006','ATKCS10501',NULL,NULL,'SI210176',NULL), + ('EDASCIS00000015S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','인증서신청발급인가','E',' ','2021101920135847 ',' ','R','1','00006','ATKCS10501',NULL,NULL,'SI210176',NULL), + ('EDASCIS00000016S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','인증서신청재발급인가','E',' ','2021101920281510 ',' ','R','1','00004','ATKCS10501',NULL,NULL,'SI210176',NULL), + ('EDASCIS00000017S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','인증서발급인가결과조회','E',' ','2021102810253051 ',' ','R','1','00005','ATKCS11001',NULL,NULL,'SI210176',NULL); +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('EDASCIS00000018S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','비대면활성화등록_이체','E',' ','2021111920030719 ',' ','R','1','00006','ATKDP08202',NULL,NULL,'SI210449',NULL), + ('EDASCIS00000019S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','전자금융 이용PC사전등록해지','E',' ','2021092809175758 ',' ','R','1','00002','ATKCS02004',NULL,NULL,'SI210176',NULL), + ('EDASCIS00000020S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','바이오정보인증등록목록조회','E',' ','2021110911123185 ',' ','R','1','00006','ATKCS03501',NULL,NULL,'SI210176',NULL), + ('EDASCIS00020013S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','마트청약ACS완전판매모니터링역씽크처리','E',' ','2021102120173693 ',' ','R','1','00002','ATKIN00102',NULL,NULL,'SI210175',NULL), + ('EDASCIS00020014S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','보험금청구LMS발송정보조회','E',' ','2021110410555946 ',' ','R','1','00002','ATKIN00801',NULL,NULL,'SI210175',NULL), + ('EDASCIS00020015S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','비대면전자금융약정관리(당행OTP)','E',' ','2021110420553473 ',' ','R','1','00002','ATKSM02501',NULL,NULL,'SI210175',NULL), + ('EDASCIS00020017S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','포털ID조회','E',' ','2021111917244358 ',' ','R','1','00002','ATKIN00701',NULL,NULL,'SI210175',NULL), + ('EDASCIS00020018S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[채널통합] EAI 테스트','E',' ','2021112216313385 ',' ','R','1','00006','CEAEA00001',NULL,NULL,'SI210176',NULL), + ('EDASDAS00000013S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','포털ID조회','E',' ','2021111716331911 ',' ','R','1','00002','ATKIN00701',NULL,NULL,'SI210175',NULL), + ('EDASIDS00000002S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[고객채널] EAI 테스트','E',' ','2021111517090667 ',' ','R','1','00002','CEBEB00001',NULL,NULL,'SI210176',NULL); +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('EDASIDS00000003S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[고객채널] EAI 테스트','E',' ','2021111517274196 ',' ','R','1','00002','CEBEB00001',NULL,NULL,'SI210211',NULL), + ('EDASIIS00000002S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[고객채널(보험)] EAI 테스트','E',' ','2021111616483482 ',' ','R','1','00002','CECEC00001',NULL,NULL,'SI210176',NULL), + ('EDASSAB00000002S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','서비스개시 지시 0800/100101','E',' ','2021112314394182 ',' ','R','1','00003',NULL,NULL,NULL,'SI210666',NULL), + ('EDASSAB00000003S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','서비스종료 요청 0800/100102','E',' ','2021112314395767 ',' ','R','1','00002',NULL,NULL,NULL,'SI210666',NULL), + ('EDASSAB00000004S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','인증 요청 0200/200201','E',' ','2021112314393466 ',' ','R','1','00002',NULL,NULL,NULL,'SI210666',NULL), + ('EDASSAB00000005S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','개설기관비식별확인키조회 요청 0200/200302','E',' ','2021112314392414 ',' ','R','1','00002',NULL,NULL,NULL,'SI210666',NULL), + ('EDASSAB00000006S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','계좌번호조회 요청 0200/200305','E',' ','2021112314390998 ',' ','R','1','00002',NULL,NULL,NULL,'SI210666',NULL), + ('EDASSAB00000007S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','인증바이오정보조회 요청 0200/200202','E',' ','2021112314385657 ',' ','R','1','00002',NULL,NULL,NULL,'SI210666',NULL), + ('EDASSAB00000008S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','공개키조회 요청 0200/200303','E',' ','2021112314384912 ',' ','R','1','00002',NULL,NULL,NULL,'SI210666',NULL), + ('EDASSAB00000009S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','잠김상태조회해제 수신 0300/400101','E',' ','2021112314384157 ',' ','R','1','00002',NULL,NULL,NULL,'SI210666',NULL); +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('EDASSAB00000010S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','삭제 수신 대내 0300/400102','E',' ','2021120214154997 ',' ','R','1','00003',NULL,NULL,NULL,'SI210666',NULL), + ('EDASSAB00000011S1','CEH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','전자서명검증 - 지시','E',' ','2021112314375741 ',' ','R','1','00002',NULL,NULL,NULL,'SI210666',NULL), + ('EDASSAB00000030S1','ATA','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[EAI]바이오인증(금융서버방식)지점명조회( 400301','E',' ','2021112616492972 ',' ','R','1','00002','ATACN73004',NULL,NULL,'SI210085',NULL), + ('EDASSAB00000031S1','ATA','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[EAI]바이오(금융서버)개인키저장처리(400201)','E',' ','2021112617003542 ',' ','R','1','00002','ATACN73002',NULL,NULL,'SI210085',NULL), + ('EDASSAB00000032S1','ATA','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[EAI]바이오인증서버연계_송신','E',' ','2021112617334281 ',' ','R','1','00003','ATACN80001',NULL,NULL,'SI210085',NULL), + ('EDASSAB00000071S1','CEC','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[EAI]바이오인증서연계_송신','E',' ','2021120113240682 ',' ','R','1','00002','ATACN80001',NULL,NULL,'SI210211',NULL), + ('EDASSAB00000072S1','CED','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[EAI]바이오인증서연계_송신','E',' ','2021120113262681 ',' ','R','1','00002','ATACN80001',NULL,NULL,'SI210211',NULL), + ('EDASSDS00000002S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[고객채널(스마트예금)] EAI 테스트','E',' ','2021111713253495 ',' ','R','1','00002','CEDED00001',NULL,NULL,'SI210176',NULL), + ('EDASSIS00000002S1','ATK','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DAS_IN_HTT_SyS',2,3,'','','','','','[고객채널(스마트보험)] EAI 테스트','E',' ','2021111713435115 ',' ','R','1','00002','CEEEE00001',NULL,NULL,'SI210176',NULL), + ('EDDMDAS00000002S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','고객정보조회','E',' ','2021101909293716 ',' ','R','1','00002','ATHCA35301',NULL,NULL,'SI210095',NULL); +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('EDDMDAS00000003S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','압류코드조회','E',' ','2021110214415091 ',' ','R','1','00002','ATFSR42001',NULL,NULL,'SI210095',NULL), + ('EDDMDAS00000004S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','압류기관코드조회','E',' ','2021110813415911 ',' ','R','1','00001','ATFSM43001',NULL,NULL,'SI210095',NULL), + ('EDDMDAS00000005S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','법원이미지압류가압류사고등록','E',' ','2021112314145485 ',' ','R','1','00001','ATFSR01012',NULL,NULL,'SI210095',NULL), + ('EDDMDAS00000006S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','자기앞수표정보화내역저장','E',' ','2021120315422467 ',' ','R','1','00003','ADACB10312',NULL,NULL,'SI210095',NULL), + ('EDDMDAS00000007S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','고액자기앞수표이미지확인등록','E',' ','2021120116331697 ',' ','R','1','00005','ADACB00532',NULL,NULL,'SI210095',NULL), + ('EDDMDAS00000008S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','푸시알림전송등록','E',' ','2021120315325450 ',' ','R','1','00001','ATDCS06002',NULL,NULL,'SI210095',NULL), + ('EDDMIAS00000002S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','지급 신규 청구접수정보 조회','E',' ','2021092713561567 ',' ','R','1','00003',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000003S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','지급 AI OCR 정보 등록','E',' ','2021092713564563 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000004S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','지급 신규 스캔 문서정보 등록','E',' ','2021092713570760 ',' ','R','1','00001',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000005S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','변경 청구 스캔이미지일련번호 조회','E',' ','2021100716374322 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL); +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('EDDMIAS00000006S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','변경 청구 스캔 문서정보 등록','E',' ','2021100716375687 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000007S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','변경 개인신용정보제공동의.동의철회 스캔이미지일련번호 조회','E',' ','2021100716380371 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000008S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','변경 개인신용정보제공동의.동의철회 스캔 문서정보 등록','E',' ','2021100716381090 ',' ','R','1','00003',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000009S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','상담 보험신용정보조회활용동의서 스캔이미지일련번호 조회','E',' ','2021102015533396 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000010S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','상담 보험신용정보조회활용동의서 스캔 문서정보 등록','E',' ','2021102015531861 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000011S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','모집 불완전판매율공개동의.철회 스캔 가능여부 검증','E',' ','2021102017273777 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000012S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','모집 불완전판매율공개동의.철회 스캔문서정보 등록','E',' ','2021102018034266 ',' ','R','1','00003',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000013S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 적부 스캔 증서번호 확인','E',' ','2021101215371025 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000014S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 개인 스캔 문서정보 등록','E',' ','2021101215384238 ',' ','R','1','00001',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000015S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 OCR 정보 등록','E',' ','2021101215401159 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL); +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('EDDMIAS00000016S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 단체 정보 조회','E',' ','2021101215413799 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000017S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 단체 스캔 문서정보 등록','E',' ','2021101215432775 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000018S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 개인 계약사항 조회','E',' ','2021101215445075 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000019S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 고객면담OCR 정보 등록','E',' ','2021101215455927 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000020S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 개인 보완 내역 조회','E',' ','2021101215471817 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000021S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 단체 보완 내역 조회','E',' ','2021101215485439 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000022S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 진단 보완 내역 조회','E',' ','2021101215500667 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000023S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','지급 보완 내역 조회','E',' ','2021101215512617 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000024S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','지급 보완.조사심사서류 스캔 문서정보 등록','E',' ','2021101215524117 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000025S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','지급 조사심사서류 스캔 청구정보 조회','E',' ','2021101215535741 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL); +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('EDDMIAS00000026S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 통합 스캔 증서번호 확인','E',' ','2021101215550581 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000027S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 통합 스캔 문서정보 등록','E',' ','2021101215560730 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000028S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','특별조건부재심사 신청내역 조회','E',' ','2021101215571968 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000029S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','특별조건부재심사 스캔 문서정보 등록','E',' ','2021101215583189 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000030S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','사기방지 스캔이미지일련번호 조회','E',' ','2021101216005335 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000031S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','사기방지 스캔 문서정보 등록','E',' ','2021101216020993 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000032S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 사전심사 스캔이미지일련번호 조회','E',' ','2021101216032488 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EDDMIAS00000033S1','ATG','0','SYNC','SINGLE','BASEFC','ONLINE','1','_DDM_IN_HTT_SyS',2,3,'','','','','','청약 사전심사 스캔 문서정보 등록','E',' ','2021101216044852 ',' ','R','1','00002',NULL,NULL,NULL,'SI210093',NULL), + ('EIDSIIS00000002S1','CEB','0','SYNC','SINGLE','BASEFC','ONLINE','1','_IDS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (인터넷예금 -> 인터넷보험)','E',' ','2021120311261164 ',' ','R','1','00002','CECEC00001',NULL,NULL,'SI210169',NULL), + ('EIDSSIS00000002S1','CEB','0','SYNC','SINGLE','BASEFC','ONLINE','1','_IDS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (인터넷예금 -> 스마트보험)','E',' ','2021120314255715 ',' ','R','1','00003','CEEEE00001',NULL,NULL,'SI210169',NULL); +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('EIISIDS00000002S1','CEC','0','SYNC','SINGLE','BASEFC','ONLINE','1','_IIS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (인터넷보험 -> 인터넷예금)','E',' ','2021120315514638 ',' ','R','1','00002','CEBEB00001',NULL,NULL,'SI210169',NULL), + ('EIISSDS00000002S1','CEC','0','SYNC','SINGLE','BASEFC','ONLINE','1','_IIS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (인터넷보험 -> 스마트예금)','E',' ','2021120316031466 ',' ','R','1','00002','CEDED00001',NULL,NULL,'SI210169',NULL), + ('EMHSDAS00000001S1','XYZ','0','SYNC','SINGLE','BASEFC','ONLINE','1','_MHS_IN_HTT_SyS',2,3,'','','','','','연계거래 - 샘플)EAI-동기 응답거래(타겟 시스템)','E',' ','2021082310545183 ',' ','R','1','00005','XYZAA08011',NULL,NULL,'SI210210',NULL), + ('EMHSMHS00000001S1','ATH','0','SYNC','SINGLE','BASEFC','ONLINE','1','_MHS_IN_HTT_SyS',2,3,'','','','','','고객정보처리정지','E',' ','2021071916542775 ',' ','R','1','00007',NULL,NULL,NULL,'SI210375',NULL), + ('ESDSIIS00000002S1','CED','0','SYNC','SINGLE','BASEFC','ONLINE','1','_SDS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (스마트예금 -> 인터넷보험)','E',' ','2021120315041254 ',' ','R','1','00002','CECEC00001',NULL,NULL,'SI210169',NULL), + ('ESDSSIS00000002S1','CED','0','SYNC','SINGLE','BASEFC','ONLINE','1','_SDS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (스마트예금 -> 스마트보험)','E',' ','2021120315202690 ',' ','R','1','00002','CEEEE00001',NULL,NULL,'SI210169',NULL), + ('ESISIDS00000002S1','CEE','0','SYNC','SINGLE','BASEFC','ONLINE','1','_SIS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (스마트보험 -> 인터넷예금)','E',' ','2021120316501756 ',' ','R','1','00002','CEBEB00001',NULL,NULL,'SI210169',NULL), + ('ESISSDS00000002S1','CEE','0','SYNC','SINGLE','BASEFC','ONLINE','1','_SIS_IN_HTT_SyS',2,3,'','','','','','EAI 테스트 (스마트보험 -> 스마트예금)','E',' ','2021120316565473 ',' ','R','1','00002','CEDED00001',NULL,NULL,'SI210169',NULL), + ('TST00000009S1','TST','0','SYNC','SINGLE','BASEFC','ONLINE','1','_TST_IN_NET_SyS',2,3,'','','','','','[하나은행] 테스트','E',' ','2022071814511260 ',' ','R','1','00006','','','','admin',NULL), + ('TST0071302S1','TST','0','SYNC','SINGLE','BASEFC','ONLINE','1','_TST_IN_HTT_SyS',2,3,'','','','','','[테스트] 동기 Flat to Json(비표준-비표준)','E',' ','20220722113025000',' ','R','1','00006','','TST0071301','','admin',NULL); +INSERT INTO tseaihe01 (eaisvcname,eaibzwkdstcd,svchmseonot,svcmotivusedstcd,svcprcesdsticname,flowctrlroutname,intgradsticname,svcbfclmnlogyn,gstatsysadptrbzwkgroupname,sevrloglvelno,svcloglvelno,erreaisvcname,dmnderrchngidname,dmnderrfldname,rspnserrchngidname,rspnserrfldname,eaisvcdesc,eaisevrdstcd,modfimgtstusdstcd,eailastamndyms,eaigroupcocd,trantype,useyn,verinfo,txid,refkey,extbizcd,author,internalexternaldvcd) VALUES + ('TST0071802S1','TST','0','ASYN','SINGLE','BASEFC','ONLINE','1','_TST_IN_HTT_AsS',2,3,'','','','','','[테스트] 비동기 Flat to Json(비표준-비표준)-요청','E',' ','2022072119092019 ',' ','R','1','00005','','TST0071801','','admin',NULL), + ('TST0071901S1','TST','0','SYNC','SINGLE','BASEFC','ONLINE','1','_TST_IN_HTT_SyS',2,3,'','','','','','등록 시연-01','E',' ','2022072216441322 ',' ','R','1','00002','','TST0071901','','admin',NULL), + ('TST0200100S1','TST','0','SYNC','SINGLE','BASEFC','ONLINE','1','_TST_IN_NET_SyS',2,3,'','','','','','동기 FLAT JSON 테스트 dhlee','E',' ','2022071110444628 ',' ','R','1','00000',NULL,NULL,NULL,NULL,NULL), + ('신규S1','TST','0','SYNC','SINGLE','BASEFC','ONLINE','1','',2,3,'','','','','','동기 FLAT JSON 테스트 dhlee','E',' ','2022070816114887 ',' ','R','1','00000',NULL,NULL,NULL,NULL,NULL), + ('BASICTEST002S1','TST','0','SYNC','SINGLE','BASEFC','ONLINE','1','_TST_IN_NET_SyS',0,3,'','','','','','BASIC_TEST_002','E',NULL,'20230706143649 ',NULL,'R','1','00005','','BASICTST02','','admin',NULL), + ('BASICTEST001S1','TST','0','SYNC','SINGLE','BASEFC','ONLINE','1','_TST_IN_HTT_SyS',1,3,'','','','','','BASIC_TEST_001','E',' ','20230706142525 ',NULL,'R','1','00005','','BASICTST01','','admin',NULL); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/message/init_tseaihe02.sql b/src/test/resources/com/eactive/eai/common/message/init_tseaihe02.sql new file mode 100644 index 0000000..7400da7 --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/message/init_tseaihe02.sql @@ -0,0 +1,107 @@ +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('ECISIIS00000002S1',1,'SYNC','ECI','EAIDOM',' ','_IIS_OU_HTT_SyC','0','1','TRANSFORM_CEA_ECISIIS00000002S1_REQ',' ','1','TRANSFORM_CEA_ECISIIS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('ECISSIS00000002S1',1,'SYNC','ECI','EAIDOM',' ','_SIS_OU_HTT_SyC','0','1','TRANSFORM_CEA_ECISSIS00000002S1_REQ',' ','1','TRANSFORM_CEA_ECISSIS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('EDASCIS00000001S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000001S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000001S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00000002S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000002S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00000003S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000003S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000003S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00000009S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000009S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000009S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00000014S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000014S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000014S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00000015S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000015S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000015S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00000016S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000016S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000016S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00000017S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000017S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000017S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'); +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('EDASCIS00000018S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000018S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000018S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00000019S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000019S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000019S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00000020S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00000020S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00000020S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00020013S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00020013S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00020013S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00020014S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00020014S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00020014S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00020015S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00020015S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00020015S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00020017S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00020017S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00020017S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASCIS00020018S1',1,'SYNC','EDA','EAIDOM',' ','_CIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASCIS00020018S1_REQ',' ','1','TRANSFORM_ATK_EDASCIS00020018S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASDAS00000013S1',1,'SYNC','EDA','EAIDOM',' ','_DAS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASDAS00000013S1_REQ',' ','1','TRANSFORM_ATK_EDASDAS00000013S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASIDS00000002S1',1,'SYNC','EDA','EAIDOM',' ','_IDS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASIDS00000002S1_REQ',' ','1','TRANSFORM_ATK_EDASIDS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'); +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('EDASIDS00000003S1',1,'SYNC','EDA','EAIDOM',' ','_IDS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASIDS00000003S1_REQ',' ','1','TRANSFORM_ATK_EDASIDS00000003S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASIIS00000002S1',1,'SYNC','EDA','EAIDOM',' ','_IIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASIIS00000002S1_REQ',' ','1','TRANSFORM_ATK_EDASIIS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000002S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000002S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000003S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000003S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000003S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000004S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000004S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000004S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000005S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000005S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000005S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000006S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000006S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000006S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000007S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000007S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000007S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000008S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000008S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000008S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000009S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000009S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000009S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'); +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('EDASSAB00000010S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000010S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000010S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('EDASSAB00000011S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_CEH_EDASSAB00000011S1_REQ',' ','1','TRANSFORM_CEH_EDASSAB00000011S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000030S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_ATA_EDASSAB00000030S1_REQ',' ','1','TRANSFORM_ATA_EDASSAB00000030S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000031S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_ATA_EDASSAB00000031S1_REQ',' ','1','TRANSFORM_ATA_EDASSAB00000031S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000032S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_ATA_EDASSAB00000032S1_REQ',' ','1','TRANSFORM_ATA_EDASSAB00000032S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000071S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_ATA_EDASSAB00000071S1_REQ',' ','1','TRANSFORM_ATA_EDASSAB00000071S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSAB00000072S1',1,'SYNC','EDA','EAIDOM',' ','_SAB_OU_HTT_SyC','0','1','TRANSFORM_ATA_EDASSAB00000072S1_REQ',' ','1','TRANSFORM_ATA_EDASSAB00000072S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSDS00000002S1',1,'SYNC','EDA','EAIDOM',' ','_SDS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASSDS00000002S1_REQ',' ','1','TRANSFORM_ATK_EDASSDS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDASSIS00000002S1',1,'SYNC','EDA','EAIDOM',' ','_SIS_OU_HTT_SyC','0','1','TRANSFORM_ATK_EDASSIS00000002S1_REQ',' ','1','TRANSFORM_ATK_EDASSIS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMDAS00000002S1',1,'SYNC','EDD','EAIDOM',' ','_DAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'); +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('EDDMDAS00000003S1',1,'SYNC','EDD','EAIDOM',' ','_DAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMDAS00000004S1',1,'SYNC','EDD','EAIDOM',' ','_DAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMDAS00000005S1',1,'SYNC','EDD','EAIDOM',' ','_DAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMDAS00000006S1',1,'SYNC','EDD','EAIDOM',' ','_DAS_OU_HTT_SyC','0','1','TRANSFORM_ATG_EDDMDAS00000006S1_REQ',' ','1','TRANSFORM_ATG_EDDMDAS00000006S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('EDDMDAS00000007S1',1,'SYNC','EDD','EAIDOM',' ','_DAS_OU_HTT_SyC','0','1','TRANSFORM_ATG_EDDMDAS00000007S1_REQ',' ','1','TRANSFORM_ATG_EDDMDAS00000007S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMDAS00000008S1',1,'SYNC','EDD','EAIDOM',' ','_DAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('EDDMIAS00000002S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000003S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000004S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000005S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'); +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('EDDMIAS00000006S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000007S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000008S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000009S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000010S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000011S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000012S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000013S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000014S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000015S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'); +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('EDDMIAS00000016S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000017S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000018S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000019S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000020S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000021S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000022S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000023S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000024S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000025S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'); +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('EDDMIAS00000026S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000027S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000028S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000029S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000030S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000031S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000032S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EDDMIAS00000033S1',1,'SYNC','EDD','EAIDOM',' ','_IAS_OU_HTT_SyC','0','0',' ',' ','0',' ',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EIDSIIS00000002S1',1,'SYNC','EID','EAIDOM',' ','_IIS_OU_HTT_SyC','0','1','TRANSFORM_CEB_EIDSIIS00000002S1_REQ',' ','1','TRANSFORM_CEB_EIDSIIS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('EIDSSIS00000002S1',1,'SYNC','EID','EAIDOM',' ','_SIS_OU_HTT_SyC','0','1','TRANSFORM_CEB_EIDSSIS00000002S1_REQ',' ','1','TRANSFORM_CEB_EIDSSIS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'); +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('EIISIDS00000002S1',1,'SYNC','EII','EAIDOM',' ','_IDS_OU_HTT_SyC','0','1','TRANSFORM_CEC_EIISIDS00000002S1_REQ',' ','1','TRANSFORM_CEC_EIISIDS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('EIISSDS00000002S1',1,'SYNC','EII','EAIDOM',' ','_SDS_OU_HTT_SyC','0','1','TRANSFORM_CEC_EIISSDS00000002S1_REQ',' ','1','TRANSFORM_CEC_EIISSDS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('EMHSDAS00000001S1',1,'SYNC','EMH','EAIDOM',' ','_DAS_OU_HTT_SyC','0','1','TRANSFORM_XYZ_EMHSDAS00000001S1_REQ',' ','1','TRANSFORM_XYZ_EMHSDAS00000001S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ',' ','S'), + ('EMHSMHS00000001S1',1,'SYNC','EMH','EAIDOM',' ','_MHS_OU_HTT_SyC','0','1','TRANSFORM_ATH_EMHSMHS00000001S1_REQ',' ','1','TRANSFORM_ATH_EMHSMHS00000001S1_RES',' ','0',' ',1,'HTTPOUT',30,' ','0','01',' ',' ',NULL), + ('ESDSIIS00000002S1',1,'SYNC','ESD','EAIDOM',' ','_IIS_OU_HTT_SyC','0','1','TRANSFORM_CED_ESDSIIS00000002S1_REQ',' ','1','TRANSFORM_CED_ESDSIIS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('ESDSSIS00000002S1',1,'SYNC','ESD','EAIDOM',' ','_SIS_OU_HTT_SyC','0','1','TRANSFORM_CED_ESDSSIS00000002S1_REQ',' ','1','TRANSFORM_CED_ESDSSIS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('ESISIDS00000002S1',1,'SYNC','ESI','EAIDOM',' ','_IDS_OU_HTT_SyC','0','1','TRANSFORM_CEE_ESISIDS00000002S1_REQ',' ','1','TRANSFORM_CEE_ESISIDS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('ESISSDS00000002S1',1,'SYNC','ESI','EAIDOM',' ','_SDS_OU_HTT_SyC','0','1','TRANSFORM_CEE_ESISSDS00000002S1_REQ',' ','1','TRANSFORM_CEE_ESISSDS00000002S1_RES',' ','0',' ',1,'HTTPOUT',60,' ','0','01',' ','','S'), + ('TST00000009S1',1,'SYNC','TST','EAIDOM',' ','_TST_OU_NET_SyC','0','1','TRANSFORM_TST_ETSTTST00000009S1_REQ',' ','1','TRANSFORM_TST_ETSTTST00000009S1_RES',' ','0',' ',1,'SOCKETOUT',60,' ','0','01',' ','','M'), + ('TST0071302S1',1,'SYNC','TST','EAIDOM',' ','_TST_OU_RST_SyC','0','1','TRANSFORM_TST_ETSTTST00000010S1_REQ',' ','1','TRANSFORM_TST_ETSTTST00000010S1_RES',' ','0',' ',1,'RESTOUT',30,' ','0','01',' ','{"type":"simpleRequest","extraPath":"syncAcho","method":"post"}',''); +INSERT INTO tseaihe02 (eaisvcname,svcprcssno,psvintfacdsticname,psvsysbzwkdstcd,psvsysidname,psvsyssvcdsticname,psvsysadptrbzwkgroupname,flovryn,chngeonot,chngmsgidname,bascrspnsmsgcmprctnt,bascrspnschngeonot,bascrspnschngmsgidname,errrspnsmsgcmprctnt,errrspnschngeonot,errrspnschngmsgidname,nextsvcprcssno,outbndroutname,toutval,cmpensvcprcssdsticname,suppldelyn,hdrctrldstcd,hdrrefclsname,restoption,timeoutcode) VALUES + ('TST0071802S1',1,'ASYN','TST','EAIDOM',' ','_TST_OU_RST_AsC','0','1','TRANSFORM_TST_ETSTTST00000011S1_REQ',' ','0',' ',' ','0',' ',1,'RESTOUT',30,' ','0','01',' ','{"type":"simpleRequest","extraPath":"asyncDummy","method":"post"}',''), + ('TST0071901S1',1,'SYNC','TST','EAIDOM',' ','_TST_OU_RST_SyC','0','1','TRANSFORM_TST_ETSTTST00000013S1_REQ',' ','1','TRANSFORM_TST_ETSTTST00000013S1_RES',' ','0',' ',1,'RESTOUT',120,' ','0','01',' ','{"type":"simpleRequest","extraPath":"syncAcho","method":"post"}',''), + ('TST0200100S1',1,'SYNC','TST','EAIDOM',' ','_TST_OU_RST_SyC{HB}','0','1','TRANSFORM_TST_ETSTTST00000008S1_REQ',' ','1','TRANSFORM_TST_ETSTTST00000008S1_RES',' ','0',' ',1,'RESTOUT',60,' ','0','01',' ','',NULL), + ('신규S1',1,'SYNC','신규S','EAIDOM',' ','','0','1','TRANSFORM_TST_ETSTTST00000008S1_REQ',' ','1','TRANSFORM_TST_ETSTTST00000008S1_RES',' ','0',' ',1,'',60,' ','0','01',' ','',NULL), + ('EDASSAB00000030S1',2,'SYNC','EDA0',NULL,'','_SAB_OU_HTT_SyC','0','0','','','0','','','0','',1,'HTTPOUT',0,'','0','01','','',NULL), + ('BASICTEST001S1',1,'SYNC',NULL,'EAIDOM',' ','_TST_OU_NET_SyC','0','0','',' ','0','',' ','0',' ',1,'SOCKETOUT',120,' ','0','01',' ','{"type":"simpleRequest","extraPath":"syncAcho","method":"post"}',''), + ('BASICTEST002S1',1,'SYNC','ADA',NULL,'','_TST_OU_NET_SyC','0','1','TRANSFORM_TST_BASICTEST002_REQ','','1','TRANSFORM_TST_BASICTEST002_RES','','0','',0,'SOCKETOUT',0,'','0','01','','',NULL); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/common/message/init_tseaims02.sql b/src/test/resources/com/eactive/eai/common/message/init_tseaims02.sql new file mode 100644 index 0000000..1987718 --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/message/init_tseaims02.sql @@ -0,0 +1,107 @@ +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname) VALUES + ('ECISIIS00000002S1',1, 1, ''), + ('ECISSIS00000002S1',1, 1, ''), + ('EDASCIS00000001S1',1, 1, ''), + ('EDASCIS00000002S1',1, 1, ''), + ('EDASCIS00000003S1',1, 1, ''), + ('EDASCIS00000009S1',1, 1, ''), + ('EDASCIS00000014S1',1, 1, ''), + ('EDASCIS00000015S1',1, 1, ''), + ('EDASCIS00000016S1',1, 1, ''), + ('EDASCIS00000017S1',1, 1, ''); +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname)VALUES + ('EDASCIS00000018S1',1, 1, ''), + ('EDASCIS00000019S1',1, 1, ''), + ('EDASCIS00000020S1',1, 1, ''), + ('EDASCIS00020013S1',1, 1, ''), + ('EDASCIS00020014S1',1, 1, ''), + ('EDASCIS00020015S1',1, 1, ''), + ('EDASCIS00020017S1',1, 1, ''), + ('EDASCIS00020018S1',1, 1, ''), + ('EDASDAS00000013S1',1, 1, ''), + ('EDASIDS00000002S1',1, 1, ''); +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname) VALUES + ('EDASIDS00000003S1',1, 1, ''), + ('EDASIIS00000002S1',1, 1, ''), + ('EDASSAB00000002S1',1, 1, ''), + ('EDASSAB00000003S1',1, 1, ''), + ('EDASSAB00000004S1',1, 1, ''), + ('EDASSAB00000005S1',1, 1, ''), + ('EDASSAB00000006S1',1, 1, ''), + ('EDASSAB00000007S1',1, 1, ''), + ('EDASSAB00000008S1',1, 1, ''), + ('EDASSAB00000009S1',1, 1, ''); +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname) VALUES + ('EDASSAB00000010S1',1, 1, ''), + ('EDASSAB00000011S1',1, 1, ''), + ('EDASSAB00000030S1',1, 1, ''), + ('EDASSAB00000031S1',1, 1, ''), + ('EDASSAB00000032S1',1, 1, ''), + ('EDASSAB00000071S1',1, 1, ''), + ('EDASSAB00000072S1',1, 1, ''), + ('EDASSDS00000002S1',1, 1, ''), + ('EDASSIS00000002S1',1, 1, ''), + ('EDDMDAS00000002S1',1, 1, ''); +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname) VALUES + ('EDDMDAS00000003S1',1, 1, ''), + ('EDDMDAS00000004S1',1, 1, ''), + ('EDDMDAS00000005S1',1, 1, ''), + ('EDDMDAS00000006S1',1, 1, ''), + ('EDDMDAS00000007S1',1, 1, ''), + ('EDDMDAS00000008S1',1, 1, ''), + ('EDDMIAS00000002S1',1, 1, ''), + ('EDDMIAS00000003S1',1, 1, ''), + ('EDDMIAS00000004S1',1, 1, ''), + ('EDDMIAS00000005S1',1, 1, ''); +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname) VALUES + ('EDDMIAS00000006S1',1, 1, ''), + ('EDDMIAS00000007S1',1, 1, ''), + ('EDDMIAS00000008S1',1, 1, ''), + ('EDDMIAS00000009S1',1, 1, ''), + ('EDDMIAS00000010S1',1, 1, ''), + ('EDDMIAS00000011S1',1, 1, ''), + ('EDDMIAS00000012S1',1, 1, ''), + ('EDDMIAS00000013S1',1, 1, ''), + ('EDDMIAS00000014S1',1, 1, ''), + ('EDDMIAS00000015S1',1, 1, ''); +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname) VALUES + ('EDDMIAS00000016S1',1, 1, ''), + ('EDDMIAS00000017S1',1, 1, ''), + ('EDDMIAS00000018S1',1, 1, ''), + ('EDDMIAS00000019S1',1, 1, ''), + ('EDDMIAS00000020S1',1, 1, ''), + ('EDDMIAS00000021S1',1, 1, ''), + ('EDDMIAS00000022S1',1, 1, ''), + ('EDDMIAS00000023S1',1, 1, ''), + ('EDDMIAS00000024S1',1, 1, ''), + ('EDDMIAS00000025S1',1, 1, ''); +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname) VALUES + ('EDDMIAS00000026S1',1, 1, ''), + ('EDDMIAS00000027S1',1, 1, ''), + ('EDDMIAS00000028S1',1, 1, ''), + ('EDDMIAS00000029S1',1, 1, ''), + ('EDDMIAS00000030S1',1, 1, ''), + ('EDDMIAS00000031S1',1, 1, ''), + ('EDDMIAS00000032S1',1, 1, ''), + ('EDDMIAS00000033S1',1, 1, ''), + ('EIDSIIS00000002S1',1, 1, ''), + ('EIDSSIS00000002S1',1, 1, ''); +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname) VALUES + ('EIISIDS00000002S1',1, 1, ''), + ('EIISSDS00000002S1',1, 1, ''), + ('EMHSDAS00000001S1',1, 1, ''), + ('EMHSMHS00000001S1',1, 1, ''), + ('ESDSIIS00000002S1',1, 1, ''), + ('ESDSSIS00000002S1',1, 1, ''), + ('ESISIDS00000002S1',1, 1, ''), + ('ESISSDS00000002S1',1, 1, ''), + ('TST00000009S1',1, 1, ''), + ('TST0071302S1',1, 1, ''); +INSERT INTO tseaims02 (eaisvcname, svcprcssno, refmsgidno, refmsgidname) VALUES + ('TST0071802S1',1, 1, ''), + ('TST0071901S1',1, 1, ''), + ('TST0200100S1',1, 1, ''), + ('신규S1',1, 1, ''), + ('EDASSAB00000030S1',2, 1, ''), + ('BASICTEST001S1',1, 1, ''), + ('BASICTEST002S1',1, 1, ''); diff --git a/src/test/resources/com/eactive/eai/common/messagekey/init_tseaifr04.sql b/src/test/resources/com/eactive/eai/common/messagekey/init_tseaifr04.sql new file mode 100644 index 0000000..07e047c --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/messagekey/init_tseaifr04.sql @@ -0,0 +1,5 @@ +INSERT INTO tseaifr04 (adptrbzwkgroupname, msgdstcd, iodstcd, groupinorno, fldprcssno, bzwkfldname, clsname, msgfldstartsituval, msgfldlen, nomalprcssctnt) VALUES('_EAI_IN_NET_SyS', 'ASC', 'I', 1, 1, '전문종별1', '', 8, 10, ''); +INSERT INTO tseaifr04 (adptrbzwkgroupname, msgdstcd, iodstcd, groupinorno, fldprcssno, bzwkfldname, clsname, msgfldstartsituval, msgfldlen, nomalprcssctnt) VALUES('_EAI_IN_NET_SyS', 'ASC', 'I', 1, 2, '전문종별2', '', 20, 10, ''); +--INSERT INTO tseaifr04 (adptrbzwkgroupname, msgdstcd, iodstcd, groupinorno, fldprcssno, bzwkfldname, clsname, msgfldstartsituval, msgfldlen, nomalprcssctnt) VALUES('_TST_IN_HTT_AsS', 'ASC', 'I', 1, 1, '전문종별', '', 8, 10, ''); +--INSERT INTO tseaifr04 (adptrbzwkgroupname, msgdstcd, iodstcd, groupinorno, fldprcssno, bzwkfldname, clsname, msgfldstartsituval, msgfldlen, nomalprcssctnt) VALUES('_TST_IN_HTT_SyS', 'ASC', 'I', 1, 1, '전문종별', '', 8, 10, ''); +INSERT INTO tseaifr04 (adptrbzwkgroupname, msgdstcd, iodstcd, groupinorno, fldprcssno, bzwkfldname, clsname, msgfldstartsituval, msgfldlen, nomalprcssctnt) VALUES('_TST_IN_NET_SyS', 'ASC', 'I', 1, 1, '전문종별', '', 8, 10, ''); diff --git a/src/test/resources/com/eactive/eai/common/routing/init_tseaifr02.sql b/src/test/resources/com/eactive/eai/common/routing/init_tseaifr02.sql new file mode 100644 index 0000000..a6139d5 --- /dev/null +++ b/src/test/resources/com/eactive/eai/common/routing/init_tseaifr02.sql @@ -0,0 +1,69 @@ +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'com.elink.eai.common.FlowRouterHostQueue', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC001', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue001', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC002', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue002', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC003', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue003', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC004', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue004', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC005', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue005', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC006', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue006', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC007', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue007', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC008', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue008', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC009', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue009', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC010', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue010', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC011', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue011', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC012', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue012', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC013', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue013', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC014', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue014', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC015', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue015', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC016', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue016', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC017', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue017', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC018', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue018', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC019', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue019', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC020', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue020', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC021', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue021', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC022', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue022', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC023', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue023', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC024', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue024', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC025', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue025', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC026', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue026', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC027', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue027', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC028', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue028', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC029', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue029', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('B2BFC030', 'com.eactive.eai.flowcontroller.B2BFCProcess', ' ', 'UserQueue030', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'com.elink.eai.common.FlowRouterHostQueue', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC001', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue001', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC002', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue002', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC003', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue003', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC004', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue004', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC005', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue005', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC006', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue006', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC007', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue007', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC008', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue008', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC009', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue009', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC010', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue010', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC011', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue011', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC012', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue012', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC013', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue013', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC014', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue014', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC015', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue015', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC016', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue016', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC017', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue017', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC018', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue018', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC019', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue019', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC020', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue020', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC021', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue021', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC022', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue022', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC023', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue023', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC024', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue024', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC025', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue025', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC026', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue026', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC027', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue027', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC028', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue028', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC029', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue029', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('BASEFC030', 'com.eactive.eai.flowcontroller.BaseFCProcess', ' ', 'UserQueue030', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('C2RFC', 'com.eactive.eai.flowcontroller.C2RFCProcess', ' ', 'com.elink.eai.common.FlowRouterHostQueue', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('HTTPOUT', 'com.eactive.eai.outbound.HTTPProcess', 'HTT', ' ', 'O'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('LOOPBACK', 'com.eactive.eai.outbound.LoopBackProcess', ' ', ' ', 'O'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('MSG-LOG', 'com.eactive.eai.outbound.MessageLoggingProcess', ' ', ' ', 'O'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('PUBFC', 'com.eactive.eai.flowcontroller.PubFCProcess', ' ', 'com.elink.eai.common.FlowRouterHostQueue', 'F'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('RESTOUT', 'com.eactive.eai.outbound.RESTProcess', 'RST', ' ', 'O'); +INSERT INTO tseaifr02 (routname, motivrouturiname, adptrcd, nonmotivrouturiname, layerdstcd) VALUES('SOCKETOUT', 'com.eactive.eai.outbound.SocketProcess', 'NET', ' ', 'O'); diff --git a/src/test/resources/com/eactive/eai/flowcontrol/jms/init_tseaiqm01.sql b/src/test/resources/com/eactive/eai/flowcontrol/jms/init_tseaiqm01.sql new file mode 100644 index 0000000..a867b79 --- /dev/null +++ b/src/test/resources/com/eactive/eai/flowcontrol/jms/init_tseaiqm01.sql @@ -0,0 +1,27 @@ +INSERT INTO tseaiqm01 (nonsyncztranquename,eaisevrinstncname,eaiquebzwkctnt,queuseyn,queusagdstcd,eaibzwkdstcd,eaiquebzwkdtalsctnt,eaiquecrtcnmvlval) VALUES + ('FlowRouterHostQueue','fepSvr11','FlowRouterHostQueue','1','1','IIB','FlowRouterHostQueue',0), + ('FlowRouterHostQueue','fepSvr12','FlowRouterHostQueue','1','1','IIB','FlowRouterHostQueue',0), + ('FlowRouterQueue','fepSvr11','FlowRouterQueue','1','1','IIB','FlowRouterQueue',0), + ('FlowRouterQueue','fepSvr12','FlowRouterQueue','1','1','IIB','FlowRouterQueue',0), + ('UserQueue001','fepSvr11','UserQueue001','1','1','IIB','UserQueue001',0), + ('UserQueue001','fepSvr12','UserQueue001','1','1','IIB','UserQueue001',0), + ('UserQueue002','fepSvr11','UserQueue002','1','1','IIB','UserQueue002',0), + ('UserQueue002','fepSvr12','UserQueue002','1','1','IIB','UserQueue002',0), + ('UserQueue003','fepSvr11','UserQueue003','1','1','IIB','UserQueue003',0), + ('UserQueue003','fepSvr12','UserQueue003','1','1','IIB','UserQueue003',0); +INSERT INTO tseaiqm01 (nonsyncztranquename,eaisevrinstncname,eaiquebzwkctnt,queuseyn,queusagdstcd,eaibzwkdstcd,eaiquebzwkdtalsctnt,eaiquecrtcnmvlval) VALUES + ('UserQueue004','fepSvr11','UserQueue004','1','1','IIB','UserQueue004',0), + ('UserQueue004','fepSvr12','UserQueue004','1','1','IIB','UserQueue004',0), + ('UserQueue005','fepSvr11','UserQueue005','1','1','IIB','UserQueue005',0), + ('UserQueue005','fepSvr12','UserQueue005','1','1','IIB','UserQueue005',0), + ('UserQueue006','fepSvr11','UserQueue006','1','1','IIB','UserQueue006',0), + ('UserQueue006','fepSvr12','UserQueue006','1','1','IIB','UserQueue006',0), + ('UserQueue007','fepSvr11','UserQueue007','1','1','IIB','UserQueue007',0), + ('UserQueue007','fepSvr12','UserQueue007','1','1','IIB','UserQueue007',0), + ('UserQueue008','fepSvr11','UserQueue008','1','1','IIB','UserQueue008',0), + ('UserQueue008','fepSvr12','UserQueue008','1','1','IIB','UserQueue008',0); +INSERT INTO tseaiqm01 (nonsyncztranquename,eaisevrinstncname,eaiquebzwkctnt,queuseyn,queusagdstcd,eaibzwkdstcd,eaiquebzwkdtalsctnt,eaiquecrtcnmvlval) VALUES + ('UserQueue009','fepSvr11','UserQueue009','1','1','IIB','UserQueue009',0), + ('UserQueue009','fepSvr12','UserQueue009','1','1','IIB','UserQueue009',0), + ('UserQueue010','fepSvr11','UserQueue010','1','1','IIB','UserQueue010',0), + ('UserQueue010','fepSvr12','UserQueue010','1','1','IIB','UserQueue010',0); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/flowcontrol/jms/init_tseaiqm02.sql b/src/test/resources/com/eactive/eai/flowcontrol/jms/init_tseaiqm02.sql new file mode 100644 index 0000000..59007aa --- /dev/null +++ b/src/test/resources/com/eactive/eai/flowcontrol/jms/init_tseaiqm02.sql @@ -0,0 +1,27 @@ +INSERT INTO tseaiqm02 (quercvername,nonsyncztranquename,nonsyncztranobstclquename,quemsgselctctnt,senddlayttmval,sendretralnotms,quercvercnt,quercverdtalsctnt,bascquercveryn,eaisevrinstncname) VALUES + ('FlowRouterHostQueue_0101','FlowRouterHostQueue',' ',' ',0,1,5,' ','1','fepSvr11'), + ('FlowRouterHostQueue_0102','FlowRouterHostQueue',' ',' ',0,1,5,' ','1','fepSvr12'), + ('FlowRouterQueue_0101','FlowRouterQueue',' ',' ',0,1,5,' ','1','fepSvr11'), + ('FlowRouterQueue_0102','FlowRouterQueue',' ',' ',0,1,5,' ','1','fepSvr12'), + ('UserQueue001_0101','UserQueue001',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue001_0102','UserQueue001',' ',' ',0,1,10,' ','0','fepSvr12'), + ('UserQueue002_0101','UserQueue002',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue002_0102','UserQueue002',' ',' ',0,1,10,' ','0','fepSvr12'), + ('UserQueue003_0101','UserQueue003',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue003_0102','UserQueue003',' ',' ',0,1,10,' ','0','fepSvr12'); +INSERT INTO tseaiqm02 (quercvername,nonsyncztranquename,nonsyncztranobstclquename,quemsgselctctnt,senddlayttmval,sendretralnotms,quercvercnt,quercverdtalsctnt,bascquercveryn,eaisevrinstncname) VALUES + ('UserQueue004_0101','UserQueue004',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue004_0102','UserQueue004',' ',' ',0,1,10,' ','0','fepSvr12'), + ('UserQueue005_0101','UserQueue005',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue005_0102','UserQueue005',' ',' ',0,1,10,' ','0','fepSvr12'), + ('UserQueue006_0101','UserQueue006',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue006_0102','UserQueue006',' ',' ',0,1,10,' ','0','fepSvr12'), + ('UserQueue007_0101','UserQueue007',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue007_0102','UserQueue007',' ',' ',0,1,10,' ','0','fepSvr12'), + ('UserQueue008_0101','UserQueue008',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue008_0102','UserQueue008',' ',' ',0,1,10,' ','0','fepSvr12'); +INSERT INTO tseaiqm02 (quercvername,nonsyncztranquename,nonsyncztranobstclquename,quemsgselctctnt,senddlayttmval,sendretralnotms,quercvercnt,quercverdtalsctnt,bascquercveryn,eaisevrinstncname) VALUES + ('UserQueue009_0101','UserQueue009',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue009_0102','UserQueue009',' ',' ',0,1,10,' ','0','fepSvr12'), + ('UserQueue010_0101','UserQueue010',' ',' ',0,1,10,' ','0','fepSvr11'), + ('UserQueue010_0102','UserQueue010',' ',' ',0,1,10,' ','0','fepSvr12'); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/httpouttlsinfo/init_http_tls_client_info.sql b/src/test/resources/com/eactive/eai/httpouttlsinfo/init_http_tls_client_info.sql new file mode 100644 index 0000000..e8b8c7d --- /dev/null +++ b/src/test/resources/com/eactive/eai/httpouttlsinfo/init_http_tls_client_info.sql @@ -0,0 +1,9 @@ +INSERT INTO http_tls_client_info (clientid,store_type,keystore_filename,keystore_info,keystore_pwd,truststore_filename,truststore_info,truststore_pwd,created_at,updated_at) VALUES + ('AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8','JKS','AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8_keystore.jks','C:\tls_info\keystore\AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8_keystore.jks','keystorePwd1','AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8_truststore.jks','C:\tls_info\truststore\AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8_truststore.jks','truststorePwd1','2024-09-13 01:24:42','2024-09-13 01:24:42'), + ('clientA','P12','clientA_keystore.p12','C:\tls_info\keystore\clientA_keystore.p12','keystorePwd2','clientA_truststore.p12','C:\tls_info\truststore\clientA_truststore.p12','truststorePwd2','2024-09-13 01:24:42','2024-09-13 01:24:42'), + ('clientB','JKS','clientB_keystore.jks','C:\tls_info\keystore\clientB_keystore.jks','keystorePwd3','clientB_truststore.jks','C:\tls_info\truststore\clientB_truststore.jks','truststorePwd3','2024-09-13 01:24:42','2024-09-13 01:24:42'), + ('CSY5EJ1QFVFhsuuEI3iqGfmO80liAizl','JKS','CSY5EJ1QFVFhsuuEI3iqGfmO80liAizl_keystore.jks','C:\tls_info\keystore\CSY5EJ1QFVFhsuuEI3iqGfmO80liAizl_keystore.jks','Xj9CA9yZmOHhdrOPf6QAe2ONDcnXtswE','CSY5EJ1QFVFhsuuEI3iqGfmO80liAizl_truststore.jks','C:\tls_info\truststore\CSY5EJ1QFVFhsuuEI3iqGfmO80liAizl_truststore.jks','pbdBVEDdYxCjm5FjgmLSoJZZwivKhqII','2024-08-22 13:36:22','2024-08-22 13:36:22'), + ('jztFpn4QAwQhXJ8U5rTD9Dr95jU76QmC','P12','jztFpn4QAwQhXJ8U5rTD9Dr95jU76QmC_keystore.p12','C:\tls_info\keystore\jztFpn4QAwQhXJ8U5rTD9Dr95jU76QmC_keystore.p12','mf0gO5UO27SManbqvRgCWbOkEKLa0x1R','jztFpn4QAwQhXJ8U5rTD9Dr95jU76QmC_truststore.p12','C:\tls_info\truststore\jztFpn4QAwQhXJ8U5rTD9Dr95jU76QmC_truststore.p12','TfTFfTuI5PPw0C1FxjESeISuA9aRrz3e','2024-08-12 10:38:54','2024-08-12 10:38:54'), + ('R8dOKXwSlcu24jodJK0QPRd0H1Qxbyz6','P12','R8dOKXwSlcu24jodJK0QPRd0H1Qxbyz6_keystore.p12','C:\tls_info\keystore\R8dOKXwSlcu24jodJK0QPRd0H1Qxbyz6_keystore.p12','guYeyEtHEH3s5aZ55B456CNbbJNIgOOa','R8dOKXwSlcu24jodJK0QPRd0H1Qxbyz6_truststore.p12','C:\tls_info\truststore\R8dOKXwSlcu24jodJK0QPRd0H1Qxbyz6_truststore.p12','83ALFp6ZCBp6aRFMp3zC5iVNsysq9Upq','2024-08-23 10:13:08','2024-08-23 10:13:08'), + ('ylHlInda57ImS22aXS5OjNTtKLZCcDLQ','JKS','ylHlInda57ImS22aXS5OjNTtKLZCcDLQ_keystore.jks','C:\tls_info\keystore\ylHlInda57ImS22aXS5OjNTtKLZCcDLQ_keystore.jks','xRtA9hJsyr9RYcCcbYhrOQAwdL073LvP','ylHlInda57ImS22aXS5OjNTtKLZCcDLQ_truststore.jks','C:\tls_info\truststore\ylHlInda57ImS22aXS5OjNTtKLZCcDLQ_truststore.jks','t7t1RIuKW5Rs3EOqN4AMUq2AaVhwNaqm','2024-08-19 15:34:36','2024-08-19 15:34:36'), + ('zspi1ZtjZmyAfrV892fzpsx9yL0oj7h7','JKS','zspi1ZtjZmyAfrV892fzpsx9yL0oj7h7_keystore.jks','C:\tls_info\keystore\zspi1ZtjZmyAfrV892fzpsx9yL0oj7h7_keystore.jks','F3ZZYmsOc2pMpCgj3zUSwCserZdMm5CO','zspi1ZtjZmyAfrV892fzpsx9yL0oj7h7_truststore.jks','C:\tls_info\truststore\zspi1ZtjZmyAfrV892fzpsx9yL0oj7h7_truststore.jks','P2Nm6quu26vYrFpJKNliV0XLzloIxSs3','2024-07-01 09:58:29','2024-07-01 09:58:29'); \ No newline at end of file diff --git a/src/test/resources/com/eactive/eai/message/layout/DatabaseReaderTest.sql b/src/test/resources/com/eactive/eai/message/layout/DatabaseReaderTest.sql new file mode 100644 index 0000000..2a6374c --- /dev/null +++ b/src/test/resources/com/eactive/eai/message/layout/DatabaseReaderTest.sql @@ -0,0 +1,86 @@ +INSERT INTO std_msg_lout +(layout_name, layout_desc, writer_name, create_datetime, update_datetime) +VALUES('HANA_POC_SAMPLE', '하나은행 POC 기준샘플', 'admin', '2022-11-30 12:56:49.000', '2023-08-09 17:17:55.951'); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 1, 'msg_len', 'msg_len', ' ', 1, ' ', 2, '199', 1, 1, 6, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 2, 'global_id', 'global_id', ' ', 1, ' ', 2, 'GIDNO00000000001111', 1, 1, 29, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 3, 'service_id', 'service_id', ' ', 1, ' ', 2, 'ELINKSVC01', 1, 1, 10, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 4, 'service_cmt', 'service_cmt', ' ', 1, ' ', 2, 'ELINK TEST Service', 1, 1, 100, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 5, 'service_tn', 'service_tn', ' ', 1, ' ', 2, 'S', 1, 1, 1, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 6, 'Session_id', 'Session_id', ' ', 1, ' ', 2, 'SESSIONID001', 1, 1, 100, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 7, 'encrypt_yn', 'encrypt_yn', ' ', 1, ' ', 2, 'NO', 1, 1, 2, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 8, 'http_url', 'http_url', ' ', 1, ' ', 2, NULL, 1, 1, 100, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 9, 'screen_id', 'screen_id', ' ', 1, ' ', 2, 'SCREEN0000001', 1, 1, 13, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 10, 'scr_no', 'scr_no', ' ', 1, ' ', 2, '0000000000', 1, 1, 30, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 11, 'scr_dsc', 'scr_dsc', ' ', 1, ' ', 2, NULL, 1, 1, 100, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 12, 'usr_id', 'usr_id', ' ', 1, ' ', 2, 'USER000001', 1, 1, 10, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 13, 'ip_addr', 'ip_addr', ' ', 1, ' ', 2, NULL, 1, 1, 47, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 14, 'ip_mac', 'ip_mac', ' ', 1, ' ', 2, NULL, 1, 1, 12, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 15, 'com_code', 'com_code', ' ', 1, ' ', 2, 'EACT', 1, 1, 4, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 16, 'head_code', 'head_code', ' ', 1, ' ', 2, 'EACT001', 1, 1, 7, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 17, 'dept_cd', 'dept_cd', ' ', 1, ' ', 2, 'ELINK01', 1, 1, 7, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 18, 'conn_tp', 'conn_tp', ' ', 1, ' ', 2, 'CH', 1, 1, 2, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 19, 'Inter_chn', 'Inter_chn', ' ', 1, ' ', 2, 'EA', 1, 1, 2, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 20, 'recv_tm', 'recv_tm', ' ', 1, ' ', 2, NULL, 1, 1, 17, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 21, 'send_tm', 'send_tm', ' ', 1, ' ', 2, '20221219152000000', 1, 1, 17, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 22, 'return_gubun', 'return_gubun', ' ', 1, ' ', 2, '1', 1, 1, 1, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 23, 'return_value', 'return_value', ' ', 1, ' ', 2, NULL, 1, 1, 1, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 24, 'msg_id', 'msg_id', ' ', 1, ' ', 2, NULL, 1, 1, 7, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 25, 'msg_nm', 'msg_nm', ' ', 1, ' ', 2, NULL, 1, 1, 250, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 26, 'filler', 'filler', ' ', 1, ' ', 2, NULL, 1, 1, 125, 1); +INSERT INTO std_msg_lout_item +(layout_name, item_no, item_name, item_desc, ref_field_path, item_level, ref_value, item_type, default_value, array_size, field_type, data_length, data_type) +VALUES('HANA_POC_SAMPLE', 27, 'bizData', 'bizData', ' ', 1, ' ', 9, NULL, 0, 1, 0, 1); + +