Merge branch 'jenkins_with_weblogic' of ssh://git@192.168.240.178:18081/eapim/eapim-online.git into jenkins_with_weblogic
This commit is contained in:
+1
-1
@@ -12,4 +12,4 @@
|
|||||||
url = ssh://git@192.168.240.178:18081/eapim/elink-online-emsclient.git
|
url = ssh://git@192.168.240.178:18081/eapim/elink-online-emsclient.git
|
||||||
[submodule "elink-online-core-jpa"]
|
[submodule "elink-online-core-jpa"]
|
||||||
path = elink-online-core-jpa
|
path = elink-online-core-jpa
|
||||||
url = ssh://git@192.168.240.178:18081/eapim/elink-online-core-jpa.git
|
url = ssh://git@192.168.240.178:18081/eapim/elink-online-core-jpa.git
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<Context>
|
|
||||||
|
|
||||||
<!-- maxTotal: Maximum number of database connections in pool. Make sure you
|
|
||||||
configure your mysqld max_connections large enough to handle
|
|
||||||
all of your db connections. Set to -1 for no limit.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- maxIdle: Maximum number of idle database connections to retain in pool.
|
|
||||||
Set to -1 for no limit. See also the DBCP documentation on this
|
|
||||||
and the minEvictableIdleTimeMillis configuration parameter.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- maxWaitMillis: Maximum time to wait for a database connection to become available
|
|
||||||
in ms, in this example 10 seconds. An Exception is thrown if
|
|
||||||
this timeout is exceeded. Set to -1 to wait indefinitely.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- username and password: MySQL username and password for database connections -->
|
|
||||||
|
|
||||||
<!-- driverClassName: Class name for the old mm.mysql JDBC driver is
|
|
||||||
org.gjt.mm.mysql.Driver - we recommend using Connector/J though.
|
|
||||||
Class name for the official MySQL Connector/J driver is com.mysql.jdbc.Driver.
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- url: The JDBC connection url for connecting to your MySQL database.
|
|
||||||
-->
|
|
||||||
<!--
|
|
||||||
<Resource name="NDAPIGW_APP_NXA" auth="Container" type="javax.sql.DataSource"
|
|
||||||
maxTotal="10" initialSize="10" maxIdle="10" maxActive="10" maxWaitMillis="10000"
|
|
||||||
poolPreparedStatements="true" validationQuery="SELECT 1" validationInterval="600000"
|
|
||||||
username="apigw" password="apigw" driverClassName="com.mysql.jdbc.Driver"
|
|
||||||
url="jdbc:mysql://192.168.8.30:13306/apigw"/>
|
|
||||||
-->
|
|
||||||
<!-- APIGW myPC MySql 5.7 -->
|
|
||||||
|
|
||||||
<Resource name="jndi/dsAPIGW" auth="Container" type="javax.sql.DataSource"
|
|
||||||
maxTotal="10" initialSize="10" maxIdle="10" maxActive="10" maxWaitMillis="10000"
|
|
||||||
poolPreparedStatements="true" validationQuery="SELECT 1" validationInterval="600000"
|
|
||||||
username="apigw" password="apigw" driverClassName="com.mysql.cj.jdbc.Driver"
|
|
||||||
url="jdbc:mysql://localhost:3306/apigw"/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- APIGW -->
|
|
||||||
<!--
|
|
||||||
<Resource name="jndi/dsAPIGW" auth="Container" type="javax.sql.DataSource"
|
|
||||||
maxTotal="10" maxIdle="10" maxWaitMillis="10000"
|
|
||||||
username="apigw" password="apigw1234" driverClassName="oracle.jdbc.OracleDriver"
|
|
||||||
url="jdbc:oracle:thin:@//localhost:1521/XE"/>
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!-- APIGW 유차장 ORACLE-->
|
|
||||||
|
|
||||||
<Resource name="jdbc/dsOBP_AGW" auth="Container" type="javax.sql.DataSource"
|
|
||||||
maxTotal="10" maxIdle="10" maxWaitMillis="10000"
|
|
||||||
username="AGWAPP" password="AGWAPP123!" driverClassName="oracle.jdbc.OracleDriver"
|
|
||||||
url="jdbc:oracle:thin:@//192.168.240.177:1599/DAPM"/>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Context>
|
|
||||||
@@ -63,7 +63,7 @@
|
|||||||
<prop key="hibernate.hbm2ddl.auto">validate</prop>
|
<prop key="hibernate.hbm2ddl.auto">validate</prop>
|
||||||
<prop key="hibernate.format_sql">true</prop>
|
<prop key="hibernate.format_sql">true</prop>
|
||||||
<prop key="hibernate.show_sql">false</prop>
|
<prop key="hibernate.show_sql">false</prop>
|
||||||
<prop key="hibernate.dialect">${hibernate.dialect:org.hibernate.dialect.PostgreSQL10Dialect}</prop>
|
<prop key="hibernate.dialect">${hibernate.dialect:org.hibernate.dialect.Oracle12cDialect}</prop>
|
||||||
<prop key="hibernate.jdbc.batch_size">100</prop>
|
<prop key="hibernate.jdbc.batch_size">100</prop>
|
||||||
<prop key="hibernate.jdbc.fetch_size">100</prop>
|
<prop key="hibernate.jdbc.fetch_size">100</prop>
|
||||||
<prop key="hibernate.cache.use_second_level_cache">false</prop>
|
<prop key="hibernate.cache.use_second_level_cache">false</prop>
|
||||||
|
|||||||
@@ -21,6 +21,8 @@
|
|||||||
base-package="com.eactive.eai.authserver" />
|
base-package="com.eactive.eai.authserver" />
|
||||||
<context:component-scan
|
<context:component-scan
|
||||||
base-package="com.eactive.eai.adapter" />
|
base-package="com.eactive.eai.adapter" />
|
||||||
|
<context:component-scan
|
||||||
|
base-package="com.eactive.eai.manage" />
|
||||||
<context:annotation-config />
|
<context:annotation-config />
|
||||||
<mvc:annotation-driven />
|
<mvc:annotation-driven />
|
||||||
<mvc:default-servlet-handler />
|
<mvc:default-servlet-handler />
|
||||||
|
|||||||
+61
-23
@@ -2,7 +2,7 @@
|
|||||||
<web-app id="servlet-3_0" version="3.0"
|
<web-app id="servlet-3_0" version="3.0"
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||||
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
|
||||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
|
||||||
|
|
||||||
<description/>
|
<description/>
|
||||||
@@ -36,20 +36,23 @@
|
|||||||
</context-param>
|
</context-param>
|
||||||
|
|
||||||
<!-- Weblogic 14.1.2 서블릿 설정 -->
|
<!-- Weblogic 14.1.2 서블릿 설정 -->
|
||||||
<!--
|
<!-- <servlet> -->
|
||||||
<servlet>
|
<!-- <servlet-name>default</servlet-name> -->
|
||||||
<servlet-name>default</servlet-name>
|
<!-- <servlet-class>weblogic.servlet.FileServlet</servlet-class> -->
|
||||||
<servlet-class>weblogic.servlet.FileServlet</servlet-class>
|
<!-- </servlet> -->
|
||||||
</servlet>
|
<!-- <servlet-mapping> -->
|
||||||
<servlet-mapping>
|
<!-- <servlet-name>default</servlet-name> -->
|
||||||
<servlet-name>default</servlet-name>
|
<!-- <url-pattern>/static/*</url-pattern> -->
|
||||||
<url-pattern>/static/*</url-pattern>
|
<!-- </servlet-mapping> -->
|
||||||
</servlet-mapping>
|
|
||||||
-->
|
|
||||||
<!-- oAuth 2.0 인증서버 설정 -->
|
<!-- oAuth 2.0 인증서버 설정 -->
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>authserver</servlet-name>
|
<servlet-name>authserver</servlet-name>
|
||||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>throwExceptionIfNoHandlerFound</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</init-param>
|
||||||
<load-on-startup>1</load-on-startup>
|
<load-on-startup>1</load-on-startup>
|
||||||
</servlet>
|
</servlet>
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
@@ -71,18 +74,17 @@
|
|||||||
</filter-mapping>
|
</filter-mapping>
|
||||||
|
|
||||||
<!-- Dynamic REST API 어댑터 설정 -->
|
<!-- Dynamic REST API 어댑터 설정 -->
|
||||||
<!-- <servlet>
|
<!-- <servlet>-->
|
||||||
<description/>
|
<!-- <description/>-->
|
||||||
<servlet-name>RestApiDynamicInAdapter</servlet-name>
|
<!-- <servlet-name>RestApiDynamicInAdapter</servlet-name>-->
|
||||||
<servlet-class>com.eactive.eai.adapter.http.dynamic.RestApiAdapterMain</servlet-class>
|
<!-- <servlet-class>com.eactive.eai.adapter.http.dynamic.RestApiAdapterMain</servlet-class>-->
|
||||||
<load-on-startup>2</load-on-startup>
|
<!-- <load-on-startup>2</load-on-startup>-->
|
||||||
</servlet>
|
<!-- </servlet>-->
|
||||||
<servlet-mapping>
|
<!-- <servlet-mapping>-->
|
||||||
<servlet-name>RestApiDynamicInAdapter</servlet-name>
|
<!-- <servlet-name>RestApiDynamicInAdapter</servlet-name>-->
|
||||||
<url-pattern>/API/*</url-pattern>
|
<!-- <url-pattern>/API/*</url-pattern>-->
|
||||||
<url-pattern>/api/*</url-pattern>
|
<!-- <url-pattern>/api/*</url-pattern>-->
|
||||||
</servlet-mapping> -->
|
<!-- </servlet-mapping>-->
|
||||||
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<listener>
|
<listener>
|
||||||
@@ -162,9 +164,45 @@
|
|||||||
<welcome-file-list>
|
<welcome-file-list>
|
||||||
<welcome-file>index.jsp</welcome-file>
|
<welcome-file>index.jsp</welcome-file>
|
||||||
</welcome-file-list>
|
</welcome-file-list>
|
||||||
|
<error-page>
|
||||||
|
<error-code>400</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>401</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>402</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>403</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>404</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>405</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
<error-page>
|
<error-page>
|
||||||
<error-code>500</error-code>
|
<error-code>500</error-code>
|
||||||
<location>/error.jsp</location>
|
<location>/error.jsp</location>
|
||||||
</error-page>
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>501</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>502</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>503</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
|
||||||
</web-app>
|
</web-app>
|
||||||
@@ -49,6 +49,10 @@
|
|||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>authserver</servlet-name>
|
<servlet-name>authserver</servlet-name>
|
||||||
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
|
||||||
|
<init-param>
|
||||||
|
<param-name>throwExceptionIfNoHandlerFound</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</init-param>
|
||||||
<load-on-startup>1</load-on-startup>
|
<load-on-startup>1</load-on-startup>
|
||||||
</servlet>
|
</servlet>
|
||||||
<servlet-mapping>
|
<servlet-mapping>
|
||||||
@@ -160,9 +164,45 @@
|
|||||||
<welcome-file-list>
|
<welcome-file-list>
|
||||||
<welcome-file>index.jsp</welcome-file>
|
<welcome-file>index.jsp</welcome-file>
|
||||||
</welcome-file-list>
|
</welcome-file-list>
|
||||||
|
<error-page>
|
||||||
|
<error-code>400</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>401</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>402</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>403</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>404</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>405</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
<error-page>
|
<error-page>
|
||||||
<error-code>500</error-code>
|
<error-code>500</error-code>
|
||||||
<location>/error.jsp</location>
|
<location>/error.jsp</location>
|
||||||
</error-page>
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>501</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>502</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
<error-page>
|
||||||
|
<error-code>503</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
|
||||||
</web-app>
|
</web-app>
|
||||||
@@ -1,5 +1,26 @@
|
|||||||
|
<%@page import="com.eactive.eai.common.util.MessageUtil"%>
|
||||||
<%@ page import="java.io.*, java.util.*"%>
|
<%@ page import="java.io.*, java.util.*"%>
|
||||||
<%@ page language="java" contentType="text/html;charset=utf-8" isErrorPage="true"%>
|
<%@ page language="java" contentType="text/html;charset=utf-8" isErrorPage="true"%>
|
||||||
|
<%
|
||||||
|
Integer statusCode = (Integer) request.getAttribute("_authServerStatusCode");
|
||||||
|
if (statusCode != null) {
|
||||||
|
response.setStatus(statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
String code;
|
||||||
|
if (statusCode != null && statusCode == 401) {
|
||||||
|
code = MessageUtil.ERROR_CODE_AUTH_FAIL;
|
||||||
|
} else if (statusCode != null && statusCode == 404) {
|
||||||
|
code = MessageUtil.ERROR_CODE_SERVICE_NOT_FOUND;
|
||||||
|
} else {
|
||||||
|
code = MessageUtil.ERROR_CODE_AP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
String message = (String)request.getAttribute("errorMessage");
|
||||||
|
String jsonErrorMessage = MessageUtil.makeJsonErrorMessage(code, message);
|
||||||
|
out.println(jsonErrorMessage);
|
||||||
|
%>
|
||||||
|
<%--
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<title>Error</title>
|
<title>Error</title>
|
||||||
@@ -16,3 +37,4 @@
|
|||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
<% response.setStatus(200); %>
|
<% response.setStatus(200); %>
|
||||||
|
--%>
|
||||||
@@ -51,6 +51,7 @@ war {
|
|||||||
|
|
||||||
if (profile == "weblogic") {
|
if (profile == "weblogic") {
|
||||||
webXml = file("WebContent/WEB-INF/weblogic-web.xml")
|
webXml = file("WebContent/WEB-INF/weblogic-web.xml")
|
||||||
|
exclude 'WEB-INF/web.xml'
|
||||||
}
|
}
|
||||||
archiveFileName = "eapim-online.war"
|
archiveFileName = "eapim-online.war"
|
||||||
duplicatesStrategy = DuplicatesStrategy.WARN
|
duplicatesStrategy = DuplicatesStrategy.WARN
|
||||||
|
|||||||
+1
-1
Submodule elink-online-common updated: aacc1a389e...5274ce811d
@@ -1,5 +1,15 @@
|
|||||||
### 비표준 -> 표준 테스트
|
### 비표준 -> 표준 테스트
|
||||||
POST http://localhost:7080/api/test/case012
|
POST http://localhost:10210/api/test/case012
|
||||||
|
Content-Type: application/json
|
||||||
|
Accept: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"field1": "aaaa",
|
||||||
|
"field2": "bbbb"
|
||||||
|
}
|
||||||
|
|
||||||
|
### 비표준 -> 비표준 테스트
|
||||||
|
POST http://localhost:10210/api/test/case001
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
Accept: application/json
|
Accept: application/json
|
||||||
|
|
||||||
@@ -7,5 +17,4 @@ Accept: application/json
|
|||||||
"serviceId": "TST10001",
|
"serviceId": "TST10001",
|
||||||
"aaa": "aaaa",
|
"aaa": "aaaa",
|
||||||
"bbb": "bbbb"
|
"bbb": "bbbb"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,10 +1,5 @@
|
|||||||
### 기본 테스트
|
### 기본 테스트
|
||||||
POST http://localhost:7080/api/test/case001
|
POST http://localhost:10210/HTT/TstInHttSysStd
|
||||||
Content-Type: application/json
|
Content-Type: text/plain; charset=ms949
|
||||||
Accept: application/json
|
|
||||||
|
|
||||||
{
|
000010163034ITRT97774O20251203100415P00421003SR1010.15.11.86 ITREAI0201M2192614300070MCI 034LAC01613021 TESTCASE001 A1OBPOOY034ITRT97774O20251203100415P0042100103403330003330333TITR01T97774LAC016130SC002307110953LAC016130SC00.scn KORN00 0000000000NN 20251203N202660016 N N NN NN 00000000000000000000000000000000000000000000000000000000000004N2025120310041542202512031004155520251203100415415N 003 IO00000015{"key":"value"}@@
|
||||||
"serviceId": "TST10001",
|
|
||||||
"aaa": "aaaa",
|
|
||||||
"bbb": "bbbb"
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
-- ============================================
|
||||||
|
-- 유량제어 그룹 테이블 DDL
|
||||||
|
-- ============================================
|
||||||
|
|
||||||
|
-- ============================================
|
||||||
|
-- Oracle
|
||||||
|
-- ============================================
|
||||||
|
|
||||||
|
-- 유량제어 그룹 테이블
|
||||||
|
CREATE TABLE inflow_control_group (
|
||||||
|
group_id VARCHAR2(36) NOT NULL, -- UUID
|
||||||
|
group_name VARCHAR2(100),
|
||||||
|
threshold NUMBER(10),
|
||||||
|
threshold_per_second NUMBER(10),
|
||||||
|
threshold_time_unit VARCHAR2(12),
|
||||||
|
use_yn VARCHAR2(1) DEFAULT '1',
|
||||||
|
modified_by VARCHAR2(50),
|
||||||
|
modified_at TIMESTAMP,
|
||||||
|
CONSTRAINT pk_inflow_control_group PRIMARY KEY (group_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TABLE inflow_control_group IS '유량제어 그룹';
|
||||||
|
COMMENT ON COLUMN inflow_control_group.group_id IS '그룹 ID (UUID)';
|
||||||
|
COMMENT ON COLUMN inflow_control_group.group_name IS '그룹명';
|
||||||
|
COMMENT ON COLUMN inflow_control_group.threshold IS '임계치';
|
||||||
|
COMMENT ON COLUMN inflow_control_group.threshold_per_second IS '초당 임계치';
|
||||||
|
COMMENT ON COLUMN inflow_control_group.threshold_time_unit IS '임계치 TimeUnit (SEC, MIN, HOU, DAY, MON)';
|
||||||
|
COMMENT ON COLUMN inflow_control_group.use_yn IS '사용여부 (1:사용, 0:미사용)';
|
||||||
|
COMMENT ON COLUMN inflow_control_group.modified_by IS '수정자';
|
||||||
|
COMMENT ON COLUMN inflow_control_group.modified_at IS '수정일시';
|
||||||
|
|
||||||
|
-- 그룹-인터페이스 매핑 테이블
|
||||||
|
CREATE TABLE inflow_control_group_mapping (
|
||||||
|
interface_id VARCHAR2(100) NOT NULL,
|
||||||
|
group_id VARCHAR2(36) NOT NULL,
|
||||||
|
use_yn VARCHAR2(1) DEFAULT '1',
|
||||||
|
modified_by VARCHAR2(50),
|
||||||
|
modified_at TIMESTAMP,
|
||||||
|
CONSTRAINT pk_inflow_ctrl_grp_mapping PRIMARY KEY (interface_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
COMMENT ON TABLE inflow_control_group_mapping IS '유량제어 그룹 매핑';
|
||||||
|
COMMENT ON COLUMN inflow_control_group_mapping.interface_id IS '인터페이스 ID';
|
||||||
|
COMMENT ON COLUMN inflow_control_group_mapping.group_id IS '그룹 ID';
|
||||||
|
COMMENT ON COLUMN inflow_control_group_mapping.use_yn IS '사용여부 (1:사용, 0:미사용)';
|
||||||
|
COMMENT ON COLUMN inflow_control_group_mapping.modified_by IS '수정자';
|
||||||
|
COMMENT ON COLUMN inflow_control_group_mapping.modified_at IS '수정일시';
|
||||||
|
|
||||||
|
-- 인덱스
|
||||||
|
CREATE INDEX idx_inflow_ctrl_grp_map_grp ON inflow_control_group_mapping (group_id);
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
## 메뉴 추가 정보
|
||||||
|
|
||||||
|
* 경로 : 환경정보 > 유량제어
|
||||||
|
* 메뉴 명 : 그룹 별 유량제어
|
||||||
|
* URL: /monitoring/onl/admin/inflow/inflowGroupControlMan.view
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
Header 헤더부 1 3 1 1 0 1
|
||||||
|
Sys_Info 시스템식별 2 3 1 1 0 1
|
||||||
|
STND_MESG_LEN 표준전문길이 3 2 1 1 8 12
|
||||||
|
ENCD_CMPI_DVCD 암호화압축구분코드 3 2 1 1 1 1 0
|
||||||
|
GUID GUID 3 2 1 1 36 1
|
||||||
|
MESG_DMAN_DVCD 전문요청구분코드 3 2 1 1 1 1 S
|
||||||
|
MESG_VER_NO 전문버전번호 3 2 1 1 3 1 R10
|
||||||
|
Src_System 전송시스템 2 3 1 1 0 1
|
||||||
|
FRST_TRNM_IPAD 최초전송IP주소 3 2 1 1 39 1
|
||||||
|
FRST_TRNM_SYS_CD 최초전송시스템코드 3 2 1 1 3 1 API
|
||||||
|
TRNM_SYS_CD 전송시스템코드 3 2 1 1 3 1
|
||||||
|
TRNM_NODE_NO 전송노드번호 3 2 1 1 4 1
|
||||||
|
MCI_SESN_ID MCI세션ID 3 2 1 1 8 1
|
||||||
|
GNRZ_TMOT_TKTM 총괄타임아웃시간 3 2 1 1 3 1 070
|
||||||
|
TX_TMOT_TKTM 거래타임아웃시간 3 2 1 1 3 1 060
|
||||||
|
KJB_Add KJB추가 2 3 1 1 0 1
|
||||||
|
OTSD_DMAN_SYS_CD 대외요청시스템코드 3 2 1 1 3 1 OBP
|
||||||
|
EAI_NODE_NO EAI노드번호 3 2 1 1 2 1
|
||||||
|
FEP_NODE_NO FEP노드번호 3 2 1 1 2 1
|
||||||
|
FEP_SESN_ID FEP세션ID 3 2 1 1 6 1
|
||||||
|
Spare_Zone 예비영역 2 3 1 1 0 1
|
||||||
|
HEDR_SPR_CTNT 헤더예비영역 3 2 1 1 25 1
|
||||||
|
Common 공통부 1 3 1 1 0 1
|
||||||
|
Service_info 거래서비스정보 2 3 1 1 0 1
|
||||||
|
GROUP_CMP_CD 그룹회사코드 3 2 1 1 3 1 034
|
||||||
|
SRVC_ID 서비스ID 3 2 1 1 11 1
|
||||||
|
PROCS_RSLT_RCMS_SRVC_ID 처리결과수신서비스ID 3 2 1 1 11 1
|
||||||
|
IF_ID 인터페이스ID 3 2 1 1 20 1
|
||||||
|
TX_SYNZ_DVCD 거래동기화구분코드 3 2 1 1 1 1
|
||||||
|
HMAB_DVCD 내외구분코드 3 2 1 1 1 1 2
|
||||||
|
OTSD_CHNL_INST_CD 대외채널기관코드 3 2 1 1 3 1
|
||||||
|
SYS_OPRT_ENV_DVCD 시스템운영환경구분코드 3 2 1 1 1 1
|
||||||
|
TX_TYP_DVCD 거래유형구분코드 3 2 1 1 1 1 O
|
||||||
|
ORTR_RESTR_YN 원거래복원여부 3 2 1 1 1 1
|
||||||
|
ORTR_GUID 원거래GUID 3 2 1 1 36 1
|
||||||
|
Channel_Info 채널정보 2 3 1 1 0 1
|
||||||
|
BANK_CD 은행코드 3 2 1 1 3 1
|
||||||
|
TX_BRCD 거래부점코드 3 2 1 1 4 1
|
||||||
|
DSPC_RCV_BRN_DVCD 파출수납부점구분코드 3 2 1 1 2 1
|
||||||
|
RLTR_BRCD 실거래부점코드 3 2 1 1 4 1
|
||||||
|
TRMN_INSL_BRCD 단말설치부점코드 3 2 1 1 4 1
|
||||||
|
CHNL_TYCD 채널유형코드 3 2 1 1 1 1
|
||||||
|
CHNL_DTLS_CLCD 채널세부분류코드 3 2 1 1 3 1
|
||||||
|
TMNL_KIND_DVCD 단말기종류구분코드 3 2 1 1 2 1
|
||||||
|
TRMN_NO 단말번호 3 2 1 1 6 1
|
||||||
|
SCN_NO 화면번호 3 2 1 1 13 1
|
||||||
|
SCN_FILE_VER 화면파일버전 3 2 1 1 10 2
|
||||||
|
SCN_FILE_NM 화면파일명 3 2 1 1 30 1
|
||||||
|
LANG_DVCD 언어구분코드 3 2 1 1 3 1 KOR
|
||||||
|
CHNL_COM_SCTN_EXIS_YN 채널공통부문존재여부 3 2 1 1 1 1 N
|
||||||
|
Confirm_Info 승인정보 2 3 1 1 0 1
|
||||||
|
PRCG_APRV_PROCS_STCD 책임자승인처리상태코드 3 2 1 1 1 1
|
||||||
|
PRCG_APRV_TYCD 책임자승인유형코드 3 2 1 1 1 1
|
||||||
|
APRV_PRCG_EMPNO 승인책임자직원번호 3 2 1 1 7 1
|
||||||
|
NURN_RSBT_EMPNO 차상위책임직원번호 3 2 1 1 7 1
|
||||||
|
PRCG_APRV_SEQNO 책임자승인일련번호 3 2 1 1 10 2
|
||||||
|
NURN_AGNCY_APRV_YN 차상위대행승인여부 3 2 1 1 1 1
|
||||||
|
DSGT_PRCG_CHNG_YN 지정책임자변경여부 3 2 1 1 1 1
|
||||||
|
CHNG_DSGT_PRCG_EMPNO 변경지정책임자직원번호 3 2 1 1 7 1
|
||||||
|
PRCG_APRV_DMAN_RSN 책임자승인요청사유 3 2 1 1 40 1
|
||||||
|
PRCG_APRV_RSN 책임자승인사유 3 2 1 1 40 1
|
||||||
|
BizProc_Info 업무처리정보 2 3 1 1 0 1
|
||||||
|
BZOP_DT 영업일자 3 2 1 1 8 1
|
||||||
|
ANTT_YN 계정처리여부 3 2 1 1 1 1
|
||||||
|
MESG_IQRY_DVCD 전문조회구분코드 3 2 1 1 1 1
|
||||||
|
ATMC_CLSN_DVCD 자동화기기마감구분코드 3 2 1 1 1 1
|
||||||
|
TLRNO 텔러번호 3 2 1 1 7 1
|
||||||
|
ASST_TLRNO 보조텔러번호 3 2 1 1 7 1
|
||||||
|
PSWD_VALDTN_YN 비밀번호검증여부 3 2 1 1 1 1
|
||||||
|
TX_TELR_PSWD 거래텔러비밀번호 3 2 1 1 44 1
|
||||||
|
CSIF_IDNT_DVCD 고객정보식별구분코드 3 2 1 1 3 1
|
||||||
|
CSIF_ID 고객정보ID 3 2 1 1 30 1
|
||||||
|
CSIF_CUST_NM 고객정보고객명 3 2 1 1 30 1
|
||||||
|
CSIF_MASK_REVOC_YN 고객정보마스크해제여부 3 2 1 1 1 1
|
||||||
|
CUST_PTLET_MASK_YN 고객포틀릿마스크여부 3 2 1 1 1 1
|
||||||
|
IDC_IMG_NO 신분증이미지번호 3 2 1 1 32 1
|
||||||
|
SMTWKP_TX_YN 스마트워크플레이스거래여부 3 2 1 1 1 1
|
||||||
|
SECU_ACCO_REG_YN 보안계좌등록여부 3 2 1 1 1 1
|
||||||
|
ABC_TX_DTLS_DVCD ABC거래세부구분코드 3 2 1 1 2 1
|
||||||
|
CLNT_TELR_CSHN_RFLC_YN 클라이언트텔러시재반영여부 3 2 1 1 1 1
|
||||||
|
SLIP_DIV_YN 전표구분여부 3 2 1 1 1 1
|
||||||
|
SLIP_NO 전표번호 3 2 1 1 9 1
|
||||||
|
TELR_SLIP_SEQNO 텔러전표일련번호 3 2 1 1 10 2
|
||||||
|
TELR_CASH_AMT 텔러현금금액 3 2 1 1 17 2
|
||||||
|
TELR_CBPC_AMT 텔러타점권금액 3 2 1 1 17 2
|
||||||
|
TELR_TRFAMT 텔러대체금액 3 2 1 1 17 2
|
||||||
|
LOGIN_DVCD 로그인구분코드 3 2 1 1 1 1
|
||||||
|
TX_DT_EXTNS_YN 거래일자연장여부 3 2 1 1 1 1 N
|
||||||
|
TX_DT 거래일자 3 2 1 1 8 1
|
||||||
|
TX_TIME 거래시각 3 2 1 1 8 1
|
||||||
|
SYS_DT 시스템일자 3 2 1 1 8 1
|
||||||
|
SYS_TIME 시스템시각 3 2 1 1 8 1
|
||||||
|
MESG_DMAN_DT 전문요청일자 3 2 1 1 8 1
|
||||||
|
MESG_DMAN_TKTM 전문요청시간 3 2 1 1 9 1
|
||||||
|
MESG_CNTY_YN 전문연속여부 3 2 1 1 1 1
|
||||||
|
MESG_RSPN_DT 전문응답일자 3 2 1 1 8 1
|
||||||
|
MESG_RSPN_TKTM 전문응답시간 3 2 1 1 9 1
|
||||||
|
PROCS_RSLT_DVCD 처리결과구분코드 3 2 1 1 2 1
|
||||||
|
OUTPUT_MESG_TYCD 출력전문유형코드 3 2 1 1 1 1
|
||||||
|
LRQN_OUTPUT_DSCT_TRGT_YN 대량출력중단대상여부 3 2 1 1 1 1
|
||||||
|
MESG_CNTY_SEQNO 전문연속일련번호 3 2 1 1 3 1
|
||||||
|
Error_Info 에러정보 2 3 1 1 0 1
|
||||||
|
ERR_CD 오류코드 3 2 1 1 6 1
|
||||||
|
ERR_SYS_CD 오류시스템코드 3 2 1 1 3 1
|
||||||
|
KJB_Add KJB추가 2 3 1 1 0 1
|
||||||
|
ORTR_SCN_ID 원거래화면ID 3 2 1 1 13 1
|
||||||
|
CORP_DPRM_NO 기업부서번호 3 2 1 1 5 1
|
||||||
|
CSIF_IQRY_RSCD 고객정보조회사유코드 3 2 1 1 2 1
|
||||||
|
Com_Spare_Zone 예비영역 2 3 1 1 0 1
|
||||||
|
COM_SPR_CTNT 공통예비내용 3 2 1 1 212 1
|
||||||
|
Channel_Common 채널공통부 1 3 0 1 0 1 Common.Channel_Info.CHNL_COM_SCTN_EXIS_YN Y
|
||||||
|
Data_Header 데이터헤더 2 3 0 1 0 1
|
||||||
|
DATA_HEDR_KNCD 데이터헤더종류코드 3 2 1 1 2 1
|
||||||
|
DATA_HEDR_LEN 데이터헤더길이 3 2 1 1 8 1
|
||||||
|
Data_For_Each 개별데이터부 2 3 0 1 0 1
|
||||||
|
PSWD_ERR_DVCD 비밀번호오류구분코드 3 2 1 1 2 1
|
||||||
|
ELFN_CUST_TYCD 전자금융고객유형코드 3 2 1 1 2 1
|
||||||
|
USER_ID_S14 사용자ID_S14 3 2 1 1 14 1
|
||||||
|
MST_ID_S14 마스터ID_S14 3 2 1 1 14 1
|
||||||
|
SVR_TX_NO 서버거래번호 3 2 1 1 10 1
|
||||||
|
HOST_TX_NO_S10 호스트거래번호_S10 3 2 1 1 10 1
|
||||||
|
NEXT_PAGE_EXIS_YN1 다음페이지존재여부1 3 2 1 1 1 1
|
||||||
|
SCCR_ISS_CD 보안카드발급코드 3 2 1 1 2 1
|
||||||
|
SQ1_SCCR_SSBP_NO_SER 1차보안카드첨자번호순서 3 2 1 1 2 1
|
||||||
|
SQ2_SCCR_SSBP_NO_SER 2차보안카드첨자번호순서 3 2 1 1 2 1
|
||||||
|
SECU_MEDIA_SEQNO_S4 보안매체일련번호_S4 3 2 1 1 4 1
|
||||||
|
SECU_MEDIA_DTL_DVCD_N3 보안매체상세구분코드_N3 3 2 1 1 3 1
|
||||||
|
PAGE_NO 페이지번호 3 2 1 1 5 1
|
||||||
|
PAGE_SIZE 페이지사이즈 3 2 1 1 5 1
|
||||||
|
TTCN_N5 총건수_N5 3 2 1 1 5 1
|
||||||
|
IQRY_CCNT_N5 조회건수_N5 3 2 1 1 5 1
|
||||||
|
PRIQR_TX_NO 선조회거래번호 3 2 1 1 10 1
|
||||||
|
SQ1_CUST_CNFR_INFO_CTNT_S39 1차고객확인정보내용_S39 3 2 1 1 39 1
|
||||||
|
SQ2_CUST_CNFR_INFO_CTNT_S39 2차고객확인정보내용_S39 3 2 1 1 39 1
|
||||||
|
MAC_S17 MAC주소_S17 3 2 1 1 17 1
|
||||||
|
HDD_SEQ_NO_S24 HDD일련번호_S24 3 2 1 1 24 1
|
||||||
|
CMCM_CD 통신사코드 3 2 1 1 1 1
|
||||||
|
TLNO_S14 전화번호_S14 3 2 1 1 14 1
|
||||||
|
OTP_EXPR_GDNC_DVCD_S1 OTP만기안내구분코드_S1 3 2 1 1 1 1
|
||||||
|
KFTC_ENCD_MST_KEY_VER_S2 금융결제원암호화마스터키버전_S2 3 2 1 1 2 1
|
||||||
|
KFTC_ENCD_RAND1_S32 금융결제원암호화난수1_S32 3 2 1 1 32 1
|
||||||
|
KFTC_ENCD_RAND2_S32 금융결제원암호화난수2_S32 3 2 1 1 32 1
|
||||||
|
ADDT_ATHN_YN_S1 추가인증여부_S1 3 2 1 1 1 1
|
||||||
|
ADDT_ATHN_METH_DVCD_S2 추가인증수단구분코드_S2 3 2 1 1 2 1
|
||||||
|
ADDT_ATHN_ATHN_VAL_S40 추가인증인증값_S40 3 2 1 1 40 1
|
||||||
|
DUP_TX_YN_S1 중복거래여부_S1 3 2 1 1 1 1
|
||||||
|
ABR_IP_BLC_YN_S1 해외IP차단여부_S1 3 2 1 1 1 1
|
||||||
|
VIRT_ACCO_DVCD_S1 가상계좌조회구분_S1 3 2 1 1 1 1
|
||||||
|
BZWK_DVCD1_S1 업무구분코드1_S1 3 2 1 1 1 1
|
||||||
|
BZWK_DVCD2_S1 업무구분코드2_S1 3 2 1 1 1 1
|
||||||
|
BZWK_DVCD3_S1 업무구분코드3_S1 3 2 1 1 1 1
|
||||||
|
BZWK_DVCD4_S1 업무구분코드4_S1 3 2 1 1 1 1
|
||||||
|
BZWK_DVCD5_S1 업무구분코드5_S1 3 2 1 1 1 1
|
||||||
|
TX_SER_SEQNO_N3 거래순서일련번호_N3 3 2 1 1 3 1
|
||||||
|
SECU_MEDIA_SEQNO_DMAN_VAL_S4 보안매체일련번호요청값_S4 3 2 1 1 4 1
|
||||||
|
MEDIA_D1_UZ_POSB_AMT_N12 매체1일사용가능금액_N12 3 2 1 1 12 1
|
||||||
|
CPHR_KEY_SECU_CO_CD_S1 암호키보안업체코드_S1 3 2 1 1 1 1
|
||||||
|
HDD_VOLU_ID_S35 HDDVOLUMEID_S35 3 2 1 1 35 1
|
||||||
|
SPR_FILD_S197 예비필드_S197 3 2 1 1 197 1
|
||||||
|
Message 메시지부 1 3 0 1 0 1 Header.Sys_Info.MESG_DMAN_DVCD R
|
||||||
|
Msg_Header 메시지헤더 2 3 0 1 0 1
|
||||||
|
MSG_HEDR_KNCD 메시지헤더종류코드 3 2 1 1 2 1 NM
|
||||||
|
MSG_HEDR_LEN 메시지헤더길이 3 2 1 1 8 2
|
||||||
|
Msg_Body 메시지 2 3 0 1 0 1
|
||||||
|
OUTPUT_ATRB_CD 출력속성코드 3 2 1 1 1 1 0
|
||||||
|
OUTPUT_MSG_CD 출력메시지코드 3 2 1 1 10 1
|
||||||
|
OUTPUT_MSG_CTNT 출력메시지내용 3 2 1 1 200 1
|
||||||
|
OUTPUT_MSG_DESC 출력메시지설명 3 2 1 1 300 1
|
||||||
|
ERR_MNGM_CTNT 오류조치내용 3 2 1 1 200 1
|
||||||
|
ERR_CHGR_NM 오류담당자명 3 2 1 1 10 1
|
||||||
|
ERR_CHGR_CNPL_NO 오류담당연락처번호 3 2 1 1 20 1
|
||||||
|
OUTPUT_MSG_NCNT 출력메시지개수 3 2 1 1 4 2 0000
|
||||||
|
Output_Msg_Grid 출력메시지 3 4 0 1 0 1 Message.Msg_Body.OUTPUT_MSG_NCNT
|
||||||
|
OUTPUT_MSG_CD 출력메시지코드 4 2 0 1 10 1
|
||||||
|
OUTPUT_MSG_CTNT 출력메시지내용 4 2 0 1 200 1
|
||||||
|
OUTPUT_MSG_DESC 출력메시지설명 4 2 0 1 300 1
|
||||||
|
ERR_MNGM_CTNT 오류조치내용 4 2 0 1 200 1
|
||||||
|
ERR_LOCT_CTNT 오류위치내용 4 2 0 1 200 1
|
||||||
|
ERR_OCCU_ITEM_NM 오류발생항목명 4 2 0 1 20 1
|
||||||
|
Manager_Confirm 책임자승인부 1 3 0 1 0 1 Manager_Confirm.Data_Header.DATA_HEDR_KNCD AD
|
||||||
|
Data_Header 데이터헤더 2 3 0 1 0 1
|
||||||
|
DATA_HEDR_KNCD 데이터헤더종류코드 3 2 1 1 2 1
|
||||||
|
DATA_HEDR_LEN 데이터헤더길이 3 2 1 1 8 2
|
||||||
|
Data_Header_Etc 데이터헤더부가정보 2 3 0 1 0 1
|
||||||
|
OUTPUT_SRVC_ID 출력서비스ID 3 2 1 1 13 1
|
||||||
|
OUTPUT_SCN_ID 출력화면ID 3 2 1 1 13 1
|
||||||
|
OUTPUT_SCN_DRVTN_MSG_CTNT 출력화면유도메시지내용 3 2 1 1 50 1
|
||||||
|
DCG_DVCD 배출구분코드 3 2 1 1 1 1
|
||||||
|
Data_For_Each 개별데이터부 2 3 0 1 0 1
|
||||||
|
ACNO 계좌번호 3 2 1 1 16 1
|
||||||
|
TRMN_CUST_FLNM 단말고객성명 3 2 1 1 20 1
|
||||||
|
TX_AMT 거래금액 3 2 1 1 17 2
|
||||||
|
APRV_RSCD_CCNT 승인사유코드건수 3 2 1 1 5 2
|
||||||
|
APRV_RSCD 승인사유코드 3 2 1 1 5 1
|
||||||
|
PRCG_APRV_DESC 책임자승인설명 3 2 1 1 50 1
|
||||||
|
PRCG_APRV_TYCD 책임자승인유형코드 3 2 1 1 1 1
|
||||||
|
PRCG_APRV_LIST_CCNT 책임자승인목록건수 3 2 1 1 5 2
|
||||||
|
TX_DVCD 거래구분코드 3 2 1 1 2 1
|
||||||
|
PRCG_EMPNO 책임자직원번호 3 2 1 1 6 1
|
||||||
|
KOR_FLNM 한글성명 3 2 1 1 40 1
|
||||||
|
BLNG_BRCD 소속부점코드 3 2 1 1 4 1
|
||||||
|
BRN_KOR_NM 부점한글명 3 2 1 1 100 1
|
||||||
|
LOGIN_IPAD 로그인IP주소 3 2 1 1 30 1
|
||||||
|
JOBCLS_CD 직급코드 3 2 1 1 2 1
|
||||||
|
LOGIN_STCD 로그인상태코드 3 2 1 1 2 1
|
||||||
|
ABSC_YN 부재여부 3 2 1 1 1 1
|
||||||
|
AGNCY_APRV_TLRNO 대행승인텔러번호 3 2 1 1 7 1
|
||||||
|
BRMNR_YN 지점장여부 3 2 1 1 1 1
|
||||||
|
AUDT_UNCN_PRCG_YN 감사통할책임자여부 3 2 1 1 1 1
|
||||||
|
Data_Part 데이터부 1 3 1 1 0 1
|
||||||
|
Data_Header 데이터헤더 2 3 1 1 0 1
|
||||||
|
DATA_HEDR_KNCD 데이터헤더종류코드 3 2 1 1 2 1 IO
|
||||||
|
DATA_HEDR_LEN 데이터헤더길이 3 2 1 1 8 2
|
||||||
|
Data_Header_Etc 데이터헤더부가정보 2 3 0 1 0 1 Data_Part.Data_Header.DATA_HEDR_KNCD OD
|
||||||
|
OUTPUT_SRVC_ID 출력서비스ID 3 2 1 1 13 1
|
||||||
|
OUTPUT_SCN_ID 출력화면ID 3 2 1 1 13 1
|
||||||
|
OUTPUT_SCN_DRVTN_MSG_CTNT 출력화면유도메시지내용 3 2 1 1 50 1
|
||||||
|
DCG_DVCD 배출구분코드 3 2 1 1 1 1
|
||||||
|
BizData 업무데이터 2 9 1 1 0 1
|
||||||
|
END_BIT_CTNT 종료비트내용 1 2 1 1 2 11 @@
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
}
|
||||||
|
|
||||||
|
group = 'com.eactive.eai'
|
||||||
|
version = '1.0.0'
|
||||||
|
|
||||||
|
java {
|
||||||
|
sourceCompatibility = '17'
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType(JavaCompile) {
|
||||||
|
options.encoding = 'UTF-8'
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2'
|
||||||
|
implementation 'org.apache.httpcomponents.client5:httpclient5:5.2.1'
|
||||||
|
|
||||||
|
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.named('test') {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
||||||
BIN
Binary file not shown.
@@ -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
|
||||||
Vendored
+234
@@ -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" "$@"
|
||||||
Vendored
+89
@@ -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
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
rootProject.name = 'kjb-errors'
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
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.HttpClients;
|
||||||
|
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.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class BearerTokenErrorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase001_잘못된GrantType() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/auth/oauth/v2/token");
|
||||||
|
|
||||||
|
List<NameValuePair> params = new ArrayList<>();
|
||||||
|
params.add(new BasicNameValuePair("grant_type", "password"));
|
||||||
|
params.add(new BasicNameValuePair("client_id", "AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8"));
|
||||||
|
params.add(new BasicNameValuePair("client_secret", "KwBYJT1m1v3SUvzN2HPHhy2Ad9Q2GADbgWkYZZg9Ybbc8R1uEuBJNQ9oVl13b1qiXwYvDWTaX0EanxY4SMjNfnBBsZzfNoMwwDPTb3IjQy5k3CRxTAYzcSnmzlC4FSsG"));
|
||||||
|
params.add(new BasicNameValuePair("scope", "api"));
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setEntity(new UrlEncodedFormEntity(params));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(401, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// MessageUtil.makeJsonErrorMessage 기본 포맷 검증
|
||||||
|
ErrorResponseValidator.validateErrorFormat(responseBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase002_존재하지않는ClientId() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/auth/oauth/v2/token");
|
||||||
|
|
||||||
|
List<NameValuePair> params = new ArrayList<>();
|
||||||
|
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||||
|
params.add(new BasicNameValuePair("client_id", "INVALID_CLIENT_ID"));
|
||||||
|
params.add(new BasicNameValuePair("client_secret", "invalid_secret"));
|
||||||
|
params.add(new BasicNameValuePair("scope", "api"));
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setEntity(new UrlEncodedFormEntity(params));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(401, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// MessageUtil.makeJsonErrorMessage 기본 포맷 검증
|
||||||
|
ErrorResponseValidator.validateErrorFormat(responseBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase003_잘못된ClientSecret() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/auth/oauth/v2/token");
|
||||||
|
|
||||||
|
List<NameValuePair> params = new ArrayList<>();
|
||||||
|
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||||
|
params.add(new BasicNameValuePair("client_id", "AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8"));
|
||||||
|
params.add(new BasicNameValuePair("client_secret", "WRONG_SECRET"));
|
||||||
|
params.add(new BasicNameValuePair("scope", "api"));
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setEntity(new UrlEncodedFormEntity(params));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(401, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// MessageUtil.makeJsonErrorMessage 기본 포맷 검증
|
||||||
|
ErrorResponseValidator.validateErrorFormat(responseBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase004_Scope없음() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/auth/oauth/v2/token");
|
||||||
|
|
||||||
|
List<NameValuePair> params = new ArrayList<>();
|
||||||
|
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||||
|
params.add(new BasicNameValuePair("client_id", "AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8"));
|
||||||
|
params.add(new BasicNameValuePair("client_secret", "KwBYJT1m1v3SUvzN2HPHhy2Ad9Q2GADbgWkYZZg9Ybbc8R1uEuBJNQ9oVl13b1qiXwYvDWTaX0EanxY4SMjNfnBBsZzfNoMwwDPTb3IjQy5k3CRxTAYzcSnmzlC4FSsG"));
|
||||||
|
params.add(new BasicNameValuePair("scope", ""));
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setEntity(new UrlEncodedFormEntity(params));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(401, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// MessageUtil.makeJsonErrorMessage 기본 포맷 검증
|
||||||
|
ErrorResponseValidator.validateErrorFormat(responseBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase005_허용되지않은Scope() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/auth/oauth/v2/token");
|
||||||
|
|
||||||
|
List<NameValuePair> params = new ArrayList<>();
|
||||||
|
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||||
|
params.add(new BasicNameValuePair("client_id", "AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8"));
|
||||||
|
params.add(new BasicNameValuePair("client_secret", "KwBYJT1m1v3SUvzN2HPHhy2Ad9Q2GADbgWkYZZg9Ybbc8R1uEuBJNQ9oVl13b1qiXwYvDWTaX0EanxY4SMjNfnBBsZzfNoMwwDPTb3IjQy5k3CRxTAYzcSnmzlC4FSsG"));
|
||||||
|
params.add(new BasicNameValuePair("scope", "invalid_scope"));
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setEntity(new UrlEncodedFormEntity(params));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(401, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// MessageUtil.makeJsonErrorMessage 기본 포맷 검증
|
||||||
|
ErrorResponseValidator.validateErrorFormat(responseBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||||
|
import org.apache.hc.core5.http.ContentType;
|
||||||
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class BearerTokenFilterErrorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase001_잘못된Bearer토큰_401에러() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/api/auth/case009?transactionId=1234567890");
|
||||||
|
String invalidToken = "INVALID_TOKEN_12345";
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setHeader("Authorization", "Bearer " + invalidToken);
|
||||||
|
httpPost.setHeader("Content-Type", "application/json");
|
||||||
|
httpPost.setEntity(new StringEntity("{}", ContentType.APPLICATION_JSON));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(401, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// MessageUtil.makeJsonErrorMessage 기본 포맷 검증
|
||||||
|
ErrorResponseValidator.validateErrorFormat(responseBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
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.HttpClients;
|
||||||
|
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.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class BearerTokenSuccessTest {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase001_BearerToken발급성공() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/auth/oauth/v2/token");
|
||||||
|
|
||||||
|
List<NameValuePair> params = new ArrayList<>();
|
||||||
|
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||||
|
params.add(new BasicNameValuePair("client_id", "AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8"));
|
||||||
|
params.add(new BasicNameValuePair("client_secret", "KwBYJT1m1v3SUvzN2HPHhy2Ad9Q2GADbgWkYZZg9Ybbc8R1uEuBJNQ9oVl13b1qiXwYvDWTaX0EanxY4SMjNfnBBsZzfNoMwwDPTb3IjQy5k3CRxTAYzcSnmzlC4FSsG"));
|
||||||
|
params.add(new BasicNameValuePair("scope", "api"));
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setEntity(new UrlEncodedFormEntity(params));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(200, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 응답 검증
|
||||||
|
JsonNode jsonNode = objectMapper.readTree(responseBody);
|
||||||
|
assertNotNull(jsonNode, "JSON 응답이 null입니다");
|
||||||
|
|
||||||
|
// Bearer Token 응답 필드 확인
|
||||||
|
assertNotNull(jsonNode.get("access_token"), "access_token 필드가 없습니다");
|
||||||
|
assertNotNull(jsonNode.get("token_type"), "token_type 필드가 없습니다");
|
||||||
|
assertNotNull(jsonNode.get("expires_in"), "expires_in 필드가 없습니다");
|
||||||
|
assertNotNull(jsonNode.get("scope"), "scope 필드가 없습니다");
|
||||||
|
|
||||||
|
assertEquals("Bearer", jsonNode.get("token_type").asText());
|
||||||
|
|
||||||
|
String prettyJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
|
||||||
|
System.out.println("Bearer Token Response:");
|
||||||
|
System.out.println(prettyJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+218
@@ -0,0 +1,218 @@
|
|||||||
|
# EAPIM 에러 응답 포맷 통일 작업 히스토리
|
||||||
|
|
||||||
|
## 작업 배경
|
||||||
|
|
||||||
|
### 목표
|
||||||
|
모든 HTTP 에러 응답을 다음과 같은 표준 JSON 포맷으로 통일:
|
||||||
|
```json
|
||||||
|
{"error":{"code":"에러코드","message":"에러메시지"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 변경 내역
|
||||||
|
|
||||||
|
### 1. MessageUtil 에러 포맷 정의
|
||||||
|
**파일**: `elink-online-common/src/main/java/com/eactive/eai/common/util/MessageUtil.java`
|
||||||
|
|
||||||
|
- 표준 에러 응답 포맷 정의
|
||||||
|
```java
|
||||||
|
public static final String ERROR_MESSAGE_DEFAULT_FORMAT = "{\"error\":{\"code\":\"%s\",\"message\":\"%s\"}}";
|
||||||
|
```
|
||||||
|
|
||||||
|
- 에러 코드 상수 추가
|
||||||
|
```java
|
||||||
|
public static final String ERROR_CODE_AP_ERROR = "E.GW.AP_ERROR";
|
||||||
|
public static final String ERROR_CODE_AUTH_FAIL = "E.GW.AUTH_FAIL";
|
||||||
|
public static final String ERROR_CODE_SERVICE_NOT_FOUND = "E.GW.SERVICE_NOT_FOUND";
|
||||||
|
```
|
||||||
|
|
||||||
|
- 에러 메시지 생성 메서드
|
||||||
|
```java
|
||||||
|
public static String makeJsonErrorMessage(String code, String msg)
|
||||||
|
public static String makeJsonErrorMessage(String code, String msg, String errorFormat)
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. 전역 ExceptionHandler 추가
|
||||||
|
**파일**: `src/main/java/com/eactive/eai/authserver/config/WebMvcConfig.java` (신규 생성)
|
||||||
|
|
||||||
|
Spring MVC 전역 예외 처리를 위한 `@ControllerAdvice` 클래스 추가
|
||||||
|
|
||||||
|
**처리하는 예외**:
|
||||||
|
- `HttpMessageNotReadableException` - HTTP 메시지 파싱 실패
|
||||||
|
- `MethodArgumentNotValidException` - 유효성 검증 실패
|
||||||
|
- `MissingServletRequestParameterException` - 필수 파라미터 누락
|
||||||
|
- `BindException` - 바인딩 에러
|
||||||
|
- `NoHandlerFoundException` - 404 Not Found (핸들러 없음)
|
||||||
|
- `AuthenticationException` - 401 Unauthorized (인증 실패)
|
||||||
|
- `AccessDeniedException` - 403 Forbidden (권한 없음)
|
||||||
|
- `Exception` - 500 Internal Server Error (기타 예외)
|
||||||
|
|
||||||
|
**동작 방식**:
|
||||||
|
1. 예외 발생 시 적절한 HTTP 상태 코드 설정
|
||||||
|
2. request에 `_authServerStatusCode`, `errorMessage` 속성 설정
|
||||||
|
3. `/error.jsp`로 forward하여 표준 JSON 응답 생성
|
||||||
|
|
||||||
|
### 3. error.jsp 수정
|
||||||
|
**파일**: `WebContent/error.jsp`
|
||||||
|
|
||||||
|
**변경 사항**:
|
||||||
|
- 기존 HTML 에러 페이지를 JSON 응답으로 변경
|
||||||
|
- `MessageUtil.makeJsonErrorMessage()` 호출하여 표준 포맷 응답 생성
|
||||||
|
- HTTP 상태 코드에 따른 에러 코드 매핑:
|
||||||
|
- 401 → `ERROR_CODE_AUTH_FAIL`
|
||||||
|
- 404 → `ERROR_CODE_SERVICE_NOT_FOUND`
|
||||||
|
- 기타 → `ERROR_CODE_AP_ERROR`
|
||||||
|
|
||||||
|
```jsp
|
||||||
|
Integer statusCode = (Integer) request.getAttribute("_authServerStatusCode");
|
||||||
|
if (statusCode != null) {
|
||||||
|
response.setStatus(statusCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
String code;
|
||||||
|
if (statusCode != null && statusCode == 401) {
|
||||||
|
code = MessageUtil.ERROR_CODE_AUTH_FAIL;
|
||||||
|
} else if (statusCode != null && statusCode == 404) {
|
||||||
|
code = MessageUtil.ERROR_CODE_SERVICE_NOT_FOUND;
|
||||||
|
} else {
|
||||||
|
code = MessageUtil.ERROR_CODE_AP_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
String message = (String)request.getAttribute("errorMessage");
|
||||||
|
String jsonErrorMessage = MessageUtil.makeJsonErrorMessage(code, message);
|
||||||
|
out.println(jsonErrorMessage);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. WebSecurityConfig 에러 처리 추가
|
||||||
|
**파일**: `src/main/java/com/eactive/eai/authserver/config/WebSecurityConfig.java`
|
||||||
|
|
||||||
|
**변경 사항**:
|
||||||
|
- Spring Security 레벨의 인증/권한 에러 처리 추가
|
||||||
|
- `authenticationEntryPoint`: 401 Unauthorized → error.jsp 포워딩
|
||||||
|
- `accessDeniedHandler`: 403 Forbidden → error.jsp 포워딩
|
||||||
|
- `/error.jsp` 접근 허용 설정 추가
|
||||||
|
|
||||||
|
### 5. web.xml 설정 추가
|
||||||
|
**파일**: `WebContent/WEB-INF/web.xml`
|
||||||
|
|
||||||
|
**변경 사항**:
|
||||||
|
- DispatcherServlet에 `throwExceptionIfNoHandlerFound=true` 설정 추가
|
||||||
|
```xml
|
||||||
|
<init-param>
|
||||||
|
<param-name>throwExceptionIfNoHandlerFound</param-name>
|
||||||
|
<param-value>true</param-value>
|
||||||
|
</init-param>
|
||||||
|
```
|
||||||
|
→ 핸들러 없을 시 `NoHandlerFoundException` 발생하도록 설정
|
||||||
|
|
||||||
|
- error-page 매핑 (400, 401, 403, 404, 500 등)
|
||||||
|
```xml
|
||||||
|
<error-page>
|
||||||
|
<error-code>404</error-code>
|
||||||
|
<location>/error.jsp</location>
|
||||||
|
</error-page>
|
||||||
|
```
|
||||||
|
→ Servlet 레벨에서 발생한 에러도 error.jsp로 라우팅
|
||||||
|
|
||||||
|
### 6. KjbMGOAuth2Controller 에러 처리 적용
|
||||||
|
**파일**: `src/main/java/com/eactive/eai/authserver/custom/KjbMGOAuth2Controller.java`
|
||||||
|
|
||||||
|
**변경 사항**:
|
||||||
|
- `JwtAuthException`, 일반 예외 처리 시 `MessageUtil.makeJsonErrorMessage()` 사용
|
||||||
|
- HTTP 400/401 에러를 표준 포맷으로 반환
|
||||||
|
|
||||||
|
### 7. BearerTokenContoller 에러 처리 적용
|
||||||
|
**파일**: `src/main/java/com/eactive/eai/authserver/custom/BearerTokenContoller.java`
|
||||||
|
|
||||||
|
**변경 사항**:
|
||||||
|
- `MessageUtil` import 추가
|
||||||
|
- 기존 OAuth2 RFC 6749 에러 포맷을 MessageUtil 표준 포맷으로 변경
|
||||||
|
- `JwtAuthException`: HTTP 401 + `ERROR_CODE_AUTH_FAIL`
|
||||||
|
- 일반 예외: HTTP 500 + `ERROR_CODE_AP_ERROR`
|
||||||
|
|
||||||
|
### 8. BearerTokenFilter 에러 처리 적용
|
||||||
|
**파일**: `src/main/java/com/eactive/eai/authserver/custom/BearerTokenFilter.java`
|
||||||
|
|
||||||
|
**변경 사항**:
|
||||||
|
- `MessageUtil` import 추가
|
||||||
|
- 필터에서 발생하는 에러 응답을 MessageUtil 표준 포맷으로 변경
|
||||||
|
- `JwtAuthException`: HTTP 401 + `ERROR_CODE_AUTH_FAIL`
|
||||||
|
- 일반 예외: HTTP 500 + `ERROR_CODE_AP_ERROR`
|
||||||
|
- JSONObject 직접 생성 방식 제거
|
||||||
|
|
||||||
|
### 9. ApiAdapterController 에러 처리 적용
|
||||||
|
**파일**: `src/main/java/com/eactive/eai/adapter/controller/ApiAdapterController.java`
|
||||||
|
|
||||||
|
**변경 사항**:
|
||||||
|
- Adapter URI를 찾을 수 없는 경우: `ERROR_CODE_SERVICE_NOT_FOUND`
|
||||||
|
- Adapter를 찾을 수 없는 경우: `ERROR_CODE_AP_ERROR`
|
||||||
|
|
||||||
|
## 적용 범위
|
||||||
|
|
||||||
|
### 처리되는 에러 시나리오
|
||||||
|
|
||||||
|
1. **OAuth2 토큰 발급 실패** (`/mapi/oauth2/token`)
|
||||||
|
- 필수 파라미터 누락, 잘못된 grant_type, 인증 실패 등
|
||||||
|
- HTTP 400/401 + 표준 JSON 에러 응답
|
||||||
|
|
||||||
|
2. **CA Bearer 토큰 발급 실패** (`/auth/oauth/v2/token`)
|
||||||
|
- 잘못된 grant_type, 존재하지 않는 client_id, 잘못된 client_secret, scope 오류 등
|
||||||
|
- HTTP 401/500 + 표준 JSON 에러 응답
|
||||||
|
|
||||||
|
3. **Bearer 토큰 인증 실패** (`/api/auth/*`)
|
||||||
|
- 토큰 만료, 잘못된 토큰 등
|
||||||
|
- HTTP 401 + 표준 JSON 에러 응답
|
||||||
|
|
||||||
|
4. **404 Not Found**
|
||||||
|
- 존재하지 않는 API 엔드포인트 호출
|
||||||
|
- HTTP 404 + 표준 JSON 에러 응답
|
||||||
|
|
||||||
|
5. **400 Bad Request**
|
||||||
|
- 잘못된 JSON 포맷, 필수 파라미터 누락 등
|
||||||
|
- HTTP 400 + 표준 JSON 에러 응답
|
||||||
|
|
||||||
|
6. **403 Forbidden**
|
||||||
|
- 권한 없는 리소스 접근
|
||||||
|
- HTTP 403 + 표준 JSON 에러 응답
|
||||||
|
|
||||||
|
7. **500 Internal Server Error**
|
||||||
|
- 서버 내부 오류
|
||||||
|
- HTTP 500 + 표준 JSON 에러 응답
|
||||||
|
|
||||||
|
## 테스트
|
||||||
|
|
||||||
|
테스트 코드는 별도 모듈(`kjb-errors`)에 작성됨.
|
||||||
|
|
||||||
|
**테스트 문서**: `kjb-errors/src/test/java/com/eactive/eai/kjb/errors/EAPIM_ExceptionHandler_Test.md`
|
||||||
|
|
||||||
|
**주요 테스트**:
|
||||||
|
- `OAuth2TokenSuccessTest` - OAuth2 토큰 발급 성공
|
||||||
|
- `OAuth2BearerAuthTest` - Bearer 토큰 인증 성공
|
||||||
|
- `OAuth2BearerAuth404ErrorTest` - Bearer 토큰 인증 후 404 에러
|
||||||
|
- `ExceptionHandler400ErrorTest` - 400 에러 응답 검증
|
||||||
|
- `ExceptionHandler404ErrorTest` - 404 에러 응답 검증
|
||||||
|
- `ExceptionHandlerSuccessTest` - 일반 API 정상 응답
|
||||||
|
- `BearerTokenSuccessTest` - CA Bearer 토큰 발급 성공
|
||||||
|
- `BearerTokenErrorTest` - CA Bearer 토큰 발급 에러 (5가지 케이스)
|
||||||
|
- `BearerTokenFilterErrorTest` - Bearer 토큰 필터 인증 실패
|
||||||
|
|
||||||
|
**검증 항목**:
|
||||||
|
- HTTP 상태 코드 정확성
|
||||||
|
- 응답 포맷이 `{"error":{"code":"...","message":"..."}}` 형식인지 확인
|
||||||
|
- 에러 코드가 적절히 매핑되는지 확인
|
||||||
|
|
||||||
|
## 에러 코드 매핑
|
||||||
|
|
||||||
|
| HTTP Status | Error Code | 설명 |
|
||||||
|
|-------------|-----------|------|
|
||||||
|
| 400 | E.GW.AP_ERROR | Bad Request (잘못된 요청) |
|
||||||
|
| 401 | E.GW.AUTH_FAIL | Unauthorized (인증 실패) |
|
||||||
|
| 403 | E.GW.AP_ERROR | Forbidden (권한 없음) |
|
||||||
|
| 404 | E.GW.SERVICE_NOT_FOUND | Not Found (서비스 없음) |
|
||||||
|
| 500 | E.GW.AP_ERROR | Internal Server Error (서버 오류) |
|
||||||
|
|
||||||
|
## 참고 사항
|
||||||
|
|
||||||
|
### 주의사항
|
||||||
|
- `MessageUtil.makeJsonErrorMessage()`는 메시지 내의 특수문자를 JSON escape 처리함
|
||||||
|
- error.jsp는 JSON 응답만 출력하므로 브라우저에서 HTML로 보이지 않음
|
||||||
|
- 상태 코드는 실제 HTTP 응답 상태 코드와 일치해야 함
|
||||||
@@ -0,0 +1,99 @@
|
|||||||
|
# EAPIM ExceptionHandler 테스트
|
||||||
|
|
||||||
|
## 개요
|
||||||
|
에러 응답이 `MessageUtil.makeJsonErrorMessage()` 포맷으로 통일되는지 검증
|
||||||
|
|
||||||
|
**에러 응답 포맷**:
|
||||||
|
```json
|
||||||
|
{"error":{"code":"에러코드","message":"에러메시지"}}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 테스트 케이스
|
||||||
|
|
||||||
|
### OAuth2 토큰 발급 성공 (OAuth2TokenSuccessTest)
|
||||||
|
- **URL**: `http://127.0.0.1:30110/oauth/token`
|
||||||
|
- **Content-Type**: `application/x-www-form-urlencoded`
|
||||||
|
- **파라미터**: grant_type, client_id, client_secret, scope
|
||||||
|
- **테스트 대상**: AuthorizationServerConfig 표준 OAuth2 토큰 발급
|
||||||
|
- **검증**: HTTP 200, access_token, token_type, expires_in
|
||||||
|
|
||||||
|
### Bearer 토큰 인증 성공 (OAuth2BearerAuthTest)
|
||||||
|
- **Step 1**: 토큰 발급 (`/oauth/token`)
|
||||||
|
- **Step 2**: Bearer 토큰으로 API 호출 (POST)
|
||||||
|
- **URL**: `http://127.0.0.1:30110/api/auth/case009?transactionId=1234567890`
|
||||||
|
- **Authorization**: `Bearer {access_token}`
|
||||||
|
- **요청**: `{}`
|
||||||
|
- **테스트 대상**: Bearer 토큰 인증 API
|
||||||
|
- **검증**: HTTP 200, 정상 응답
|
||||||
|
|
||||||
|
### Bearer 토큰 인증 404 에러 (OAuth2BearerAuth404ErrorTest)
|
||||||
|
- **Step 1**: 토큰 발급 (`/oauth/token`)
|
||||||
|
- **Step 2**: 존재하지 않는 API 호출 (POST)
|
||||||
|
- **URL**: `http://127.0.0.1:30110/api/auth/caseXXX`
|
||||||
|
- **Authorization**: `Bearer {access_token}`
|
||||||
|
- **요청**: `{}`
|
||||||
|
- **테스트 대상**: WebMvcConfig @ExceptionHandler(NoHandlerFoundException)
|
||||||
|
- **검증**: HTTP 404, MessageUtil 포맷
|
||||||
|
|
||||||
|
### 400 에러 (ExceptionHandler400ErrorTest)
|
||||||
|
- **URL**: `http://127.0.0.1:30110/mapi/oauth2/token`
|
||||||
|
- **요청**: `{}`
|
||||||
|
- **테스트 대상**: KjbMGOAuth2Controller JwtAuthException 처리
|
||||||
|
- **검증**: HTTP 400, MessageUtil 포맷
|
||||||
|
|
||||||
|
### 404 에러 (ExceptionHandler404ErrorTest)
|
||||||
|
- **URL**: `http://127.0.0.1:30110/oauth/token/v2`
|
||||||
|
- **요청**: `{}`
|
||||||
|
- **테스트 대상**: WebMvcConfig @ExceptionHandler(NoHandlerFoundException)
|
||||||
|
- **검증**: HTTP 404, MessageUtil 포맷
|
||||||
|
|
||||||
|
### 일반 API 정상 응답 (ExceptionHandlerSuccessTest)
|
||||||
|
- **URL**: `http://localhost:30110/api/test/case001`
|
||||||
|
- **요청**: `{"serviceId": "TST10001", "aaa": "aaaa", "bbb": "bbbb"}`
|
||||||
|
- **테스트 대상**: 일반 컨트롤러 정상 응답
|
||||||
|
- **검증**: HTTP 200, transactionId, status="approved"
|
||||||
|
|
||||||
|
### Bearer 토큰 발급 성공 (BearerTokenSuccessTest)
|
||||||
|
- **URL**: `http://127.0.0.1:30110/auth/oauth/v2/token`
|
||||||
|
- **Content-Type**: `application/x-www-form-urlencoded`
|
||||||
|
- **파라미터**: grant_type, client_id, client_secret, scope
|
||||||
|
- **테스트 대상**: BearerTokenContoller CA Bearer Token 발급
|
||||||
|
- **검증**: HTTP 200, access_token, token_type="Bearer", expires_in, scope
|
||||||
|
|
||||||
|
### Bearer 토큰 발급 에러 (BearerTokenErrorTest)
|
||||||
|
#### testCase001_잘못된GrantType
|
||||||
|
- **URL**: `http://127.0.0.1:30110/auth/oauth/v2/token`
|
||||||
|
- **grant_type**: `password` (잘못된 값)
|
||||||
|
- **테스트 대상**: BearerTokenContoller JwtAuthException 처리
|
||||||
|
- **검증**: HTTP 401, MessageUtil 포맷
|
||||||
|
|
||||||
|
#### testCase002_존재하지않는ClientId
|
||||||
|
- **URL**: `http://127.0.0.1:30110/auth/oauth/v2/token`
|
||||||
|
- **client_id**: `INVALID_CLIENT_ID`
|
||||||
|
- **테스트 대상**: BearerTokenContoller JwtAuthException 처리
|
||||||
|
- **검증**: HTTP 401, MessageUtil 포맷
|
||||||
|
|
||||||
|
#### testCase003_잘못된ClientSecret
|
||||||
|
- **URL**: `http://127.0.0.1:30110/auth/oauth/v2/token`
|
||||||
|
- **client_secret**: `WRONG_SECRET`
|
||||||
|
- **테스트 대상**: BearerTokenContoller JwtAuthException 처리
|
||||||
|
- **검증**: HTTP 401, MessageUtil 포맷
|
||||||
|
|
||||||
|
#### testCase004_Scope없음
|
||||||
|
- **URL**: `http://127.0.0.1:30110/auth/oauth/v2/token`
|
||||||
|
- **scope**: `` (빈 값)
|
||||||
|
- **테스트 대상**: BearerTokenContoller JwtAuthException 처리
|
||||||
|
- **검증**: HTTP 401, MessageUtil 포맷
|
||||||
|
|
||||||
|
#### testCase005_허용되지않은Scope
|
||||||
|
- **URL**: `http://127.0.0.1:30110/auth/oauth/v2/token`
|
||||||
|
- **scope**: `invalid_scope`
|
||||||
|
- **테스트 대상**: BearerTokenContoller JwtAuthException 처리
|
||||||
|
- **검증**: HTTP 401, MessageUtil 포맷
|
||||||
|
|
||||||
|
### Bearer 토큰 필터 에러 (BearerTokenFilterErrorTest)
|
||||||
|
- **URL**: `http://127.0.0.1:30110/api/auth/case009?transactionId=1234567890`
|
||||||
|
- **Authorization**: `Bearer INVALID_TOKEN_12345`
|
||||||
|
- **요청**: `{}`
|
||||||
|
- **테스트 대상**: BearerTokenFilter JwtAuthException 처리
|
||||||
|
- **검증**: HTTP 401, MessageUtil 포맷
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageUtil.makeJsonErrorMessage 기본 포맷 검증 유틸리티
|
||||||
|
* 기본 포맷: { "error" : {"code":"%s","message":"%s"} }
|
||||||
|
*/
|
||||||
|
public class ErrorResponseValidator {
|
||||||
|
|
||||||
|
private static final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MessageUtil.makeJsonErrorMessage 포맷 검증
|
||||||
|
* @param responseBody JSON 응답 문자열
|
||||||
|
* @throws Exception JSON 파싱 실패 시
|
||||||
|
*/
|
||||||
|
public static void validateErrorFormat(String responseBody) throws Exception {
|
||||||
|
JsonNode jsonNode = objectMapper.readTree(responseBody);
|
||||||
|
assertNotNull(jsonNode, "JSON 응답이 null입니다");
|
||||||
|
|
||||||
|
assertTrue(jsonNode.has("error"), "error 필드가 존재해야 합니다");
|
||||||
|
|
||||||
|
JsonNode errorNode = jsonNode.get("error");
|
||||||
|
assertNotNull(errorNode, "error 객체가 null입니다");
|
||||||
|
|
||||||
|
assertTrue(errorNode.has("code"), "error.code 필드가 존재해야 합니다");
|
||||||
|
assertTrue(errorNode.has("message"), "error.message 필드가 존재해야 합니다");
|
||||||
|
|
||||||
|
assertNotNull(errorNode.get("code").asText(), "error.code 값이 null입니다");
|
||||||
|
assertNotNull(errorNode.get("message").asText(), "error.message 값이 null입니다");
|
||||||
|
|
||||||
|
// 검증 성공 시 Pretty Print
|
||||||
|
String prettyJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
|
||||||
|
System.out.println("Validated Error Format:");
|
||||||
|
System.out.println(prettyJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||||
|
import org.apache.hc.core5.http.ContentType;
|
||||||
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class ExceptionHandler400ErrorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase001_400에러() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/mapi/oauth2/token");
|
||||||
|
|
||||||
|
String requestBody = """
|
||||||
|
{}
|
||||||
|
""";
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setHeader("Content-Type", "application/json");
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(400, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// MessageUtil.makeJsonErrorMessage 기본 포맷 검증
|
||||||
|
ErrorResponseValidator.validateErrorFormat(responseBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||||
|
import org.apache.hc.core5.http.ContentType;
|
||||||
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class ExceptionHandler404ErrorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase001_404에러() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/oauth/token/v2");
|
||||||
|
|
||||||
|
String requestBody = """
|
||||||
|
{}
|
||||||
|
""";
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setHeader("Content-Type", "application/json");
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(404, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// MessageUtil.makeJsonErrorMessage 기본 포맷 검증
|
||||||
|
ErrorResponseValidator.validateErrorFormat(responseBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
|
import org.apache.hc.client5.http.impl.classic.HttpClients;
|
||||||
|
import org.apache.hc.core5.http.ContentType;
|
||||||
|
import org.apache.hc.core5.http.HttpEntity;
|
||||||
|
import org.apache.hc.core5.http.io.entity.EntityUtils;
|
||||||
|
import org.apache.hc.core5.http.io.entity.StringEntity;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
class ExceptionHandlerSuccessTest {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase001_정상호출() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/api/test/case001");
|
||||||
|
|
||||||
|
String requestBody = """
|
||||||
|
{
|
||||||
|
"serviceId": "TST10001",
|
||||||
|
"aaa": "aaaa",
|
||||||
|
"bbb": "bbbb"
|
||||||
|
}
|
||||||
|
""";
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setHeader("Content-Type", "application/json");
|
||||||
|
httpPost.setHeader("Accept", "application/json");
|
||||||
|
httpPost.setEntity(new StringEntity(requestBody, ContentType.APPLICATION_JSON));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
assertEquals(200, response.getCode());
|
||||||
|
return EntityUtils.toString(response.getEntity());
|
||||||
|
});
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertNotNull(responseBody);
|
||||||
|
|
||||||
|
JsonNode jsonNode = objectMapper.readTree(responseBody);
|
||||||
|
assertNotNull(jsonNode);
|
||||||
|
|
||||||
|
// validate
|
||||||
|
assertNotNull(jsonNode.get("transactionId"));
|
||||||
|
assertEquals("approved", jsonNode.get("status").asText());
|
||||||
|
String prettyJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
|
||||||
|
System.out.println(prettyJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
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.HttpClients;
|
||||||
|
import org.apache.hc.core5.http.ContentType;
|
||||||
|
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.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class OAuth2BearerAuth404ErrorTest {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase001_Bearer인증_존재하지않는API_404에러() throws Exception {
|
||||||
|
// Step 1: 토큰 발급
|
||||||
|
String tokenUrl = TestConfig.getBaseUrl("/oauth2/token");
|
||||||
|
String accessToken;
|
||||||
|
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost tokenPost = new HttpPost(tokenUrl);
|
||||||
|
|
||||||
|
List<NameValuePair> params = new ArrayList<>();
|
||||||
|
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||||
|
params.add(new BasicNameValuePair("client_id", "AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8"));
|
||||||
|
params.add(new BasicNameValuePair("client_secret", "KwBYJT1m1v3SUvzN2HPHhy2Ad9Q2GADbgWkYZZg9Ybbc8R1uEuBJNQ9oVl13b1qiXwYvDWTaX0EanxY4SMjNfnBBsZzfNoMwwDPTb3IjQy5k3CRxTAYzcSnmzlC4FSsG"));
|
||||||
|
params.add(new BasicNameValuePair("scope", "api"));
|
||||||
|
|
||||||
|
tokenPost.setEntity(new UrlEncodedFormEntity(params));
|
||||||
|
|
||||||
|
String tokenResponse = httpClient.execute(tokenPost, response -> {
|
||||||
|
assertEquals(200, response.getCode(), "토큰 발급 실패");
|
||||||
|
return EntityUtils.toString(response.getEntity());
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonNode tokenJson = objectMapper.readTree(tokenResponse);
|
||||||
|
accessToken = tokenJson.get("access_token").asText();
|
||||||
|
assertNotNull(accessToken, "access_token이 null입니다");
|
||||||
|
|
||||||
|
System.out.println("Access Token: " + accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: 존재하지 않는 API 호출 (404 에러 예상)
|
||||||
|
String apiUrl = TestConfig.getBaseUrl("/api/auth/caseXXX");
|
||||||
|
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(apiUrl);
|
||||||
|
httpPost.setHeader("Authorization", "Bearer " + accessToken);
|
||||||
|
httpPost.setHeader("Content-Type", "application/json");
|
||||||
|
httpPost.setEntity(new StringEntity("{}", ContentType.APPLICATION_JSON));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(404, response.getCode(), "404 에러가 발생해야 합니다");
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// MessageUtil.makeJsonErrorMessage 기본 포맷 검증
|
||||||
|
ErrorResponseValidator.validateErrorFormat(responseBody);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
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.HttpClients;
|
||||||
|
import org.apache.hc.core5.http.ContentType;
|
||||||
|
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.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class OAuth2BearerAuthTest {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase001_Bearer인증_성공() throws Exception {
|
||||||
|
// Step 1: 토큰 발급
|
||||||
|
String tokenUrl = TestConfig.getBaseUrl("/oauth2/token");
|
||||||
|
String accessToken;
|
||||||
|
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost tokenPost = new HttpPost(tokenUrl);
|
||||||
|
|
||||||
|
List<NameValuePair> params = new ArrayList<>();
|
||||||
|
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||||
|
params.add(new BasicNameValuePair("client_id", "AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8"));
|
||||||
|
params.add(new BasicNameValuePair("client_secret", "KwBYJT1m1v3SUvzN2HPHhy2Ad9Q2GADbgWkYZZg9Ybbc8R1uEuBJNQ9oVl13b1qiXwYvDWTaX0EanxY4SMjNfnBBsZzfNoMwwDPTb3IjQy5k3CRxTAYzcSnmzlC4FSsG"));
|
||||||
|
params.add(new BasicNameValuePair("scope", "api"));
|
||||||
|
|
||||||
|
tokenPost.setEntity(new UrlEncodedFormEntity(params));
|
||||||
|
|
||||||
|
String tokenResponse = httpClient.execute(tokenPost, response -> {
|
||||||
|
assertEquals(200, response.getCode(), "토큰 발급 실패");
|
||||||
|
return EntityUtils.toString(response.getEntity());
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonNode tokenJson = objectMapper.readTree(tokenResponse);
|
||||||
|
accessToken = tokenJson.get("access_token").asText();
|
||||||
|
assertNotNull(accessToken, "access_token이 null입니다");
|
||||||
|
|
||||||
|
System.out.println("Access Token: " + accessToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 2: Bearer 토큰으로 인증 API 호출
|
||||||
|
String apiUrl = TestConfig.getBaseUrl("/api/auth/case009?transactionId=1234567890");
|
||||||
|
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(apiUrl);
|
||||||
|
httpPost.setHeader("Authorization", "Bearer " + accessToken);
|
||||||
|
httpPost.setHeader("Content-Type", "application/json");
|
||||||
|
httpPost.setEntity(new StringEntity("{}", ContentType.APPLICATION_JSON));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(200, response.getCode(), "Bearer 인증 실패");
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 응답 검증
|
||||||
|
JsonNode jsonNode = objectMapper.readTree(responseBody);
|
||||||
|
assertNotNull(jsonNode, "JSON 응답이 null입니다");
|
||||||
|
|
||||||
|
String prettyJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
|
||||||
|
System.out.println("API Response:");
|
||||||
|
System.out.println(prettyJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||||
|
|
||||||
|
import org.apache.hc.client5.http.classic.methods.HttpPost;
|
||||||
|
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.HttpClients;
|
||||||
|
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.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
class OAuth2TokenSuccessTest {
|
||||||
|
|
||||||
|
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testCase001_토큰발급성공() throws Exception {
|
||||||
|
// given
|
||||||
|
String url = TestConfig.getBaseUrl("/oauth2/token");
|
||||||
|
|
||||||
|
List<NameValuePair> params = new ArrayList<>();
|
||||||
|
params.add(new BasicNameValuePair("grant_type", "client_credentials"));
|
||||||
|
params.add(new BasicNameValuePair("client_id", "AyeWx0OpYLJbHpZ21DDSxYfQPmD5Ckn8"));
|
||||||
|
params.add(new BasicNameValuePair("client_secret", "KwBYJT1m1v3SUvzN2HPHhy2Ad9Q2GADbgWkYZZg9Ybbc8R1uEuBJNQ9oVl13b1qiXwYvDWTaX0EanxY4SMjNfnBBsZzfNoMwwDPTb3IjQy5k3CRxTAYzcSnmzlC4FSsG"));
|
||||||
|
params.add(new BasicNameValuePair("scope", "api"));
|
||||||
|
|
||||||
|
// when
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost httpPost = new HttpPost(url);
|
||||||
|
httpPost.setEntity(new UrlEncodedFormEntity(params));
|
||||||
|
|
||||||
|
String responseBody = httpClient.execute(httpPost, response -> {
|
||||||
|
String body = EntityUtils.toString(response.getEntity());
|
||||||
|
System.out.println("Response Body: " + body);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assertEquals(200, response.getCode());
|
||||||
|
return body;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 응답 검증
|
||||||
|
JsonNode jsonNode = objectMapper.readTree(responseBody);
|
||||||
|
assertNotNull(jsonNode, "JSON 응답이 null입니다");
|
||||||
|
|
||||||
|
// OAuth2 토큰 응답 필드 확인
|
||||||
|
assertNotNull(jsonNode.get("access_token"), "access_token 필드가 없습니다");
|
||||||
|
assertNotNull(jsonNode.get("token_type"), "token_type 필드가 없습니다");
|
||||||
|
assertNotNull(jsonNode.get("expires_in"), "expires_in 필드가 없습니다");
|
||||||
|
|
||||||
|
String prettyJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonNode);
|
||||||
|
System.out.println("Token Response:");
|
||||||
|
System.out.println(prettyJson);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
package com.eactive.eai.kjb.errors;
|
||||||
|
|
||||||
|
public class TestConfig {
|
||||||
|
|
||||||
|
private static final String DEFAULT_HOST = "127.0.0.1";
|
||||||
|
private static final String DEFAULT_PORT = "30110";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 테스트 서버 호스트 반환
|
||||||
|
* 시스템 프로퍼티 test.host가 있으면 사용, 없으면 127.0.0.1
|
||||||
|
* @return 호스트 주소
|
||||||
|
*/
|
||||||
|
public static String getHost() {
|
||||||
|
return System.getProperty("test.host", DEFAULT_HOST);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 테스트 서버 포트 반환
|
||||||
|
* 시스템 프로퍼티 test.port가 있으면 사용, 없으면 30110
|
||||||
|
* @return 포트 번호
|
||||||
|
*/
|
||||||
|
public static String getPort() {
|
||||||
|
return System.getProperty("test.port", DEFAULT_PORT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 테스트 베이스 URL 생성
|
||||||
|
* @param path API 경로 (예: "/oauth/token")
|
||||||
|
* @return 전체 URL
|
||||||
|
*/
|
||||||
|
public static String getBaseUrl(String path) {
|
||||||
|
return String.format("http://%s:%s%s", getHost(), getPort(), path);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -50,10 +50,10 @@ public class ApiAdapterController implements HttpAdapterServiceKey {
|
|||||||
ApiAdapterService service;
|
ApiAdapterService service;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KBANK 요구사항으로 /api/v1/oauth/token 과 같은 형태로 토큰 발급거래를 수행해야해서 예외처리함
|
* KJBANK 요구사항으로 /mapi/oauth2/token 과 같은 형태로 토큰 발급거래를 수행해야해서 예외처리함
|
||||||
* @See com.eactive.eai.authserver.config.AuthorizationServerConfig.configure(AuthorizationServerEndpointsConfigurer endpoints)
|
* @See com.eactive.eai.authserver.config.AuthorizationServerConfig.configure(AuthorizationServerEndpointsConfigurer endpoints)
|
||||||
*/
|
*/
|
||||||
@RequestMapping(value = {"/api/*", "/mapi/*", "/api/*/{path:^(?!.*oauth).*$}/**", "/mapi/*/{path:^(?!.*oauth).*$}/**"})
|
@RequestMapping(value = {"/api/*", "/mapi/*", "/api/*/{path:^(?!.*oauth).*$}/**", "/mapi/{path:^(?!.*oauth2).*$}/**"})
|
||||||
// @RequestMapping(value = {"/api/**"})
|
// @RequestMapping(value = {"/api/**"})
|
||||||
public ResponseEntity<String> callApi(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception {
|
public ResponseEntity<String> callApi(HttpServletRequest servletRequest, HttpServletResponse servletResponse) throws Exception {
|
||||||
// /ONLWeb/api/v1/public/getUserInfo.svc
|
// /ONLWeb/api/v1/public/getUserInfo.svc
|
||||||
@@ -87,8 +87,10 @@ public class ApiAdapterController implements HttpAdapterServiceKey {
|
|||||||
|
|
||||||
if (adptUri == null) {
|
if (adptUri == null) {
|
||||||
logError(servletRequest);
|
logError(servletRequest);
|
||||||
// throw new Exception("can not find Adapter Uri");
|
String errorMsg = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_SERVICE_NOT_FOUND, "can not find Adapter Uri");
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("can not find Adapter Uri");
|
return ResponseEntity.status(HttpStatus.NOT_FOUND)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.body(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Received time , jwhong
|
//Received time , jwhong
|
||||||
@@ -100,8 +102,10 @@ public class ApiAdapterController implements HttpAdapterServiceKey {
|
|||||||
AdapterGroupVO adapterGroupVO = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName);
|
AdapterGroupVO adapterGroupVO = AdapterManager.getInstance().getAdapterGroupVO(adapterGroupName);
|
||||||
AdapterVO adapterVO = AdapterManager.getInstance().getAdapterVO(adapterGroupName, adapterName);
|
AdapterVO adapterVO = AdapterManager.getInstance().getAdapterVO(adapterGroupName, adapterName);
|
||||||
if (adapterVO == null) {
|
if (adapterVO == null) {
|
||||||
// throw new Exception("Adapter not found error");
|
String errorMsg = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AP_ERROR, "Adapter not found error");
|
||||||
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Adapter not found error");
|
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.body(errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties httpProp = AdapterPropManager.getInstance().getProperties(adapterVO.getPropGroupName());
|
Properties httpProp = AdapterPropManager.getInstance().getProperties(adapterVO.getPropGroupName());
|
||||||
@@ -152,17 +156,19 @@ public class ApiAdapterController implements HttpAdapterServiceKey {
|
|||||||
}
|
}
|
||||||
} catch (HttpStatusException e) {
|
} catch (HttpStatusException e) {
|
||||||
logger.warn("ApiAdapterController] " + adapterGroupName + "-" + adapterName + ">>" + e.getMessage());
|
logger.warn("ApiAdapterController] " + adapterGroupName + "-" + adapterName + ">>" + e.getMessage());
|
||||||
String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, e.getCode(),
|
String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, MessageUtil.ERROR_CODE_AP_ERROR,
|
||||||
e.getMessage(), errorResponseFormat);
|
e.getMessage(), errorResponseFormat);
|
||||||
responseEntity = ResponseEntity.status(e.getStatus()).contentType(mediaType).body(errorMsg);
|
responseEntity = ResponseEntity.status(e.getStatus()).contentType(mediaType).body(errorMsg);
|
||||||
} catch (JwtAuthException e) {
|
} catch (JwtAuthException e) {
|
||||||
logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e);
|
logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e);
|
||||||
String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, e.getCode(),
|
String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, MessageUtil.ERROR_CODE_AUTH_FAIL,
|
||||||
e.getMessage(), errorResponseFormat);
|
e.getMessage(), errorResponseFormat);
|
||||||
responseEntity = ResponseEntity.status(HttpStatus.UNAUTHORIZED).contentType(mediaType).body(errorMsg);
|
responseEntity = ResponseEntity.status(HttpStatus.UNAUTHORIZED).contentType(mediaType).body(errorMsg);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e);
|
logger.error(adapterGroupName + "-" + adapterName + ">>" + e.getMessage(), e);
|
||||||
responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(mediaType).body(e);
|
String errorMsg = MessageUtil.makeErrorMessageByMessageType(adptMsgType, encode, MessageUtil.ERROR_CODE_AP_ERROR,
|
||||||
|
e.getMessage(), errorResponseFormat);
|
||||||
|
responseEntity = ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).contentType(mediaType).body(errorMsg);
|
||||||
} finally {
|
} finally {
|
||||||
/**
|
/**
|
||||||
* 로깅 인터셉터에 데이터를 전달하기 위한 처리
|
* 로깅 인터셉터에 데이터를 전달하기 위한 처리
|
||||||
|
|||||||
@@ -151,6 +151,7 @@ public class ApiAdapterService extends HttpAdapterServiceSupport {
|
|||||||
|
|
||||||
if (isParameterType) {
|
if (isParameterType) {
|
||||||
paramValue = request.getQueryString();
|
paramValue = request.getQueryString();
|
||||||
|
transactionProp.put(INBOUND_QUERY_STRING, StringUtils.defaultString(paramValue)); // Filter에서 QueryString 검증을 위해 저장
|
||||||
if (paramValue == null)
|
if (paramValue == null)
|
||||||
paramValue = "";
|
paramValue = "";
|
||||||
if (traceLevel >= 3) {
|
if (traceLevel >= 3) {
|
||||||
@@ -309,14 +310,34 @@ public class ApiAdapterService extends HttpAdapterServiceSupport {
|
|||||||
result = mapper.writeValueAsString(rootNode);
|
result = mapper.writeValueAsString(rootNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// KJBank는 요청에 대한 응답 (Sync응답, Aync 에 대한 Ack응답) 에 대하여 암호화 하지 않는다. 무조건 안한다. 따라서 아래부분은 구현은 했지만 사용하지 않는다.
|
||||||
|
//result = doPostEncryption(result, transactionProp); // jwhong Encrypt
|
||||||
|
// ASYNC 인 경우 광주은행은 RETURN 해 주는 값들이 수정되어야 한다. JWHONG
|
||||||
|
/*
|
||||||
|
if ("ASYN".equals(syncAsyncType) && MessageType.JSON.equals(adptMsgType) && StringUtils.isNotBlank(headerGroupName)) {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
ObjectNode rootNode = (ObjectNode) mapper.readTree(result);
|
||||||
|
JsonNode headerGroup = rootNode.get(headerGroupName);
|
||||||
|
if(headerGroup != null) {
|
||||||
|
for(Iterator<String> it = headerGroup.fieldNames(); it.hasNext();) {
|
||||||
|
String name = it.next();
|
||||||
|
String value = headerGroup.get(name).asText();
|
||||||
|
response.addHeader(name, value);
|
||||||
|
}
|
||||||
|
rootNode.remove(headerGroupName);
|
||||||
|
result = mapper.writeValueAsString(rootNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
// KJBank는 요청에 대한 응답 (Sync응답, Aync 에 대한 Ack응답) 에 대하여 암호화 하지 않는다. 무조건 안한다. 따라서 아래부분은 구현은 했지만 사용하지 않는다.
|
// KJBank는 요청에 대한 응답 (Sync응답, Aync 에 대한 Ack응답) 에 대하여 암호화 하지 않는다. 무조건 안한다. 따라서 아래부분은 구현은 했지만 사용하지 않는다.
|
||||||
//result = doPostEncryption(result, transactionProp); // jwhong Encrypt
|
//result = doPostEncryption(result, transactionProp); // jwhong Encrypt
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// jwhong decrypt
|
// jwhong decrypt
|
||||||
|
|
||||||
private String doPreDecryption(String eaiBody, Properties transactionProp, HttpServletRequest request) {
|
private String doPreDecryption(String eaiBody, Properties transactionProp, HttpServletRequest request) {
|
||||||
String decryptAlgorithm = transactionProp.getProperty(ENCRYPT_ALGORITHM, "");
|
String decryptAlgorithm = transactionProp.getProperty(ENCRYPT_ALGORITHM, "");
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
|
|||||||
tokenType = vo.getProperty(PROP_TOKEN_TYPE, "JWT");
|
tokenType = vo.getProperty(PROP_TOKEN_TYPE, "JWT");
|
||||||
}
|
}
|
||||||
|
|
||||||
// endpoints.pathMapping("/oauth/token", "/auth/oauth/v2/token") ;
|
endpoints.pathMapping("/oauth/token", "/oauth2/token") ;
|
||||||
endpoints.authenticationManager(authenticationManager);
|
endpoints.authenticationManager(authenticationManager);
|
||||||
endpoints.userDetailsService(userDetailsService);
|
endpoints.userDetailsService(userDetailsService);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
package com.eactive.eai.authserver.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||||
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
|
import org.springframework.security.core.AuthenticationException;
|
||||||
|
import org.springframework.validation.BindException;
|
||||||
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
|
import org.springframework.web.bind.MissingServletRequestParameterException;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
@ControllerAdvice
|
||||||
|
public class WebMvcConfig {
|
||||||
|
|
||||||
|
@ExceptionHandler({
|
||||||
|
HttpMessageNotReadableException.class,
|
||||||
|
MethodArgumentNotValidException.class,
|
||||||
|
MissingServletRequestParameterException.class,
|
||||||
|
BindException.class
|
||||||
|
})
|
||||||
|
public String handleBadRequest(HttpServletRequest request, HttpServletResponse response, Exception ex) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
|
request.setAttribute("_authServerStatusCode", HttpServletResponse.SC_BAD_REQUEST);
|
||||||
|
request.setAttribute("errorMessage", "400 Bad Request");
|
||||||
|
return "forward:/error.jsp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(NoHandlerFoundException.class)
|
||||||
|
public String handleNotFound(HttpServletRequest request, HttpServletResponse response, Exception ex) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
request.setAttribute("_authServerStatusCode", HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
request.setAttribute("errorMessage", "404 Not Found");
|
||||||
|
return "forward:/error.jsp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(AuthenticationException.class)
|
||||||
|
public String handleUnauthorized(HttpServletRequest request, HttpServletResponse response, Exception ex) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
request.setAttribute("_authServerStatusCode", HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
request.setAttribute("errorMessage", "401 Unauthorized");
|
||||||
|
return "forward:/error.jsp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(AccessDeniedException.class)
|
||||||
|
public String handleAccessDenied(HttpServletRequest request, HttpServletResponse response, Exception ex) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
request.setAttribute("_authServerStatusCode", HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
request.setAttribute("errorMessage", "403 Forbidden");
|
||||||
|
return "forward:/error.jsp";
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(Exception.class)
|
||||||
|
public String handleException(HttpServletRequest request, HttpServletResponse response, Exception ex) {
|
||||||
|
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
|
request.setAttribute("_authServerStatusCode", HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
|
request.setAttribute("errorMessage", ex.getMessage());
|
||||||
|
return "forward:/error.jsp";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,6 +14,8 @@ import org.springframework.security.core.userdetails.UserDetailsService;
|
|||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@EnableWebSecurity
|
@EnableWebSecurity
|
||||||
@Order(1)
|
@Order(1)
|
||||||
@@ -29,8 +31,23 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
|
|||||||
.headers().frameOptions().disable()
|
.headers().frameOptions().disable()
|
||||||
.and()
|
.and()
|
||||||
.authorizeRequests()
|
.authorizeRequests()
|
||||||
|
.antMatchers("/error.jsp").permitAll()
|
||||||
.antMatchers("/**").permitAll()
|
.antMatchers("/**").permitAll()
|
||||||
.and()
|
.and()
|
||||||
|
.exceptionHandling()
|
||||||
|
.authenticationEntryPoint((request, response, authException) -> {
|
||||||
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
request.setAttribute("_authServerStatusCode", HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
request.setAttribute("errorMessage", "401 Unauthorized");
|
||||||
|
request.getRequestDispatcher("/error.jsp").forward(request, response);
|
||||||
|
})
|
||||||
|
.accessDeniedHandler((request, response, accessDeniedException) -> {
|
||||||
|
response.setStatus(HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
request.setAttribute("_authServerStatusCode", HttpServletResponse.SC_FORBIDDEN);
|
||||||
|
request.setAttribute("errorMessage", "403 Forbidden");
|
||||||
|
request.getRequestDispatcher("/error.jsp").forward(request, response);
|
||||||
|
})
|
||||||
|
.and()
|
||||||
.formLogin();
|
.formLogin();
|
||||||
// .and()
|
// .and()
|
||||||
// .httpBasic();
|
// .httpBasic();
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.RestController;
|
|||||||
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
|
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
|
||||||
import com.eactive.eai.authserver.service.OAuth2Manager;
|
import com.eactive.eai.authserver.service.OAuth2Manager;
|
||||||
import com.eactive.eai.common.util.Logger;
|
import com.eactive.eai.common.util.Logger;
|
||||||
|
import com.eactive.eai.common.util.MessageUtil;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/auth/oauth/v2")
|
@RequestMapping("/auth/oauth/v2")
|
||||||
@@ -75,20 +76,12 @@ public class BearerTokenContoller {
|
|||||||
return ResponseEntity.ok(resObject);
|
return ResponseEntity.ok(resObject);
|
||||||
} catch (JwtAuthException e) {
|
} catch (JwtAuthException e) {
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
|
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, e.getMessage());
|
||||||
JSONObject errorJson = new JSONObject();
|
return ResponseEntity.status(401).body(errorJson);
|
||||||
errorJson.put("error", e.getCode());
|
|
||||||
errorJson.put("error_description", e.getMessage());
|
|
||||||
resObject.putAll(errorJson);
|
|
||||||
return ResponseEntity.status(401).body(resObject);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(e);
|
logger.error(e);
|
||||||
|
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AP_ERROR, e.getMessage());
|
||||||
JSONObject errorJson = new JSONObject();
|
return ResponseEntity.status(500).body(errorJson);
|
||||||
errorJson.put("error", "invalid_request");
|
|
||||||
errorJson.put("error_description", e.getMessage());
|
|
||||||
resObject.putAll(errorJson);
|
|
||||||
return ResponseEntity.status(500).body(resObject);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.springframework.web.filter.OncePerRequestFilter;
|
|||||||
|
|
||||||
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
|
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
|
||||||
import com.eactive.eai.common.util.Logger;
|
import com.eactive.eai.common.util.Logger;
|
||||||
|
import com.eactive.eai.common.util.MessageUtil;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class BearerTokenFilter extends OncePerRequestFilter{
|
public class BearerTokenFilter extends OncePerRequestFilter{
|
||||||
@@ -35,8 +36,6 @@ public class BearerTokenFilter extends OncePerRequestFilter{
|
|||||||
protected void doFilterInternal(HttpServletRequest request,
|
protected void doFilterInternal(HttpServletRequest request,
|
||||||
HttpServletResponse response,
|
HttpServletResponse response,
|
||||||
FilterChain filterChain) throws IOException, ServletException {
|
FilterChain filterChain) throws IOException, ServletException {
|
||||||
JSONObject resObject = new JSONObject();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
String auth = request.getHeader("Authorization");
|
String auth = request.getHeader("Authorization");
|
||||||
|
|
||||||
@@ -62,23 +61,16 @@ public class BearerTokenFilter extends OncePerRequestFilter{
|
|||||||
filterChain.doFilter(request, response);
|
filterChain.doFilter(request, response);
|
||||||
} catch (JwtAuthException jae) {
|
} catch (JwtAuthException jae) {
|
||||||
logger.debug(jae.getMessage());
|
logger.debug(jae.getMessage());
|
||||||
|
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, jae.getMessage());
|
||||||
JSONObject errorJson = new JSONObject();
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
errorJson.put("error", jae.getCode());
|
|
||||||
errorJson.put("error_description", jae.getMessage());
|
|
||||||
resObject.putAll(errorJson);
|
|
||||||
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 설정
|
|
||||||
response.setContentType("application/json;charset=UTF-8");
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
response.getWriter().write(resObject.toJSONString());
|
response.getWriter().write(errorJson);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(e.getMessage());
|
logger.error(e.getMessage());
|
||||||
JSONObject errorJson = new JSONObject();
|
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AP_ERROR, e.getMessage());
|
||||||
errorJson.put("error", "invalid_request");
|
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
errorJson.put("error_description", e.getMessage());
|
|
||||||
resObject.putAll(errorJson);
|
|
||||||
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); // 500 설정
|
|
||||||
response.setContentType("application/json;charset=UTF-8");
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
response.getWriter().write(resObject.toJSONString());
|
response.getWriter().write(errorJson);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
package com.eactive.eai.authserver.custom;
|
package com.eactive.eai.authserver.custom;
|
||||||
|
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.security.KeyFactory;
|
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.security.PublicKey;
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.security.Signature;
|
import java.security.Signature;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.Base64;
|
import java.util.Base64;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -39,7 +36,6 @@ import org.springframework.web.bind.annotation.ResponseBody;
|
|||||||
|
|
||||||
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
|
import com.eactive.eai.adapter.http.dynamic.filter.JwtAuthException;
|
||||||
import com.eactive.eai.authserver.config.IssueLimitOAuth2Exception;
|
import com.eactive.eai.authserver.config.IssueLimitOAuth2Exception;
|
||||||
import com.eactive.eai.authserver.config.AuthorizationServerConfig;
|
|
||||||
import com.eactive.eai.authserver.config.RequestContextData;
|
import com.eactive.eai.authserver.config.RequestContextData;
|
||||||
import com.eactive.eai.authserver.dao.TokenIssuanceLogDAO;
|
import com.eactive.eai.authserver.dao.TokenIssuanceLogDAO;
|
||||||
import com.eactive.eai.authserver.service.OAuth2Manager;
|
import com.eactive.eai.authserver.service.OAuth2Manager;
|
||||||
@@ -48,8 +44,10 @@ import com.eactive.eai.authserver.vo.ClientVO;
|
|||||||
import com.eactive.eai.common.dao.DAOException;
|
import com.eactive.eai.common.dao.DAOException;
|
||||||
import com.eactive.eai.common.logger.EAIDBLogControl;
|
import com.eactive.eai.common.logger.EAIDBLogControl;
|
||||||
import com.eactive.eai.common.util.Logger;
|
import com.eactive.eai.common.util.Logger;
|
||||||
|
import com.eactive.eai.common.util.MessageUtil;
|
||||||
import com.eactive.eai.common.util.UUID;
|
import com.eactive.eai.common.util.UUID;
|
||||||
import com.eactive.eai.data.entity.onl.authserver.TokenIssuanceLog;
|
import com.eactive.eai.data.entity.onl.authserver.TokenIssuanceLog;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
public class KjbMGOAuth2Controller {
|
public class KjbMGOAuth2Controller {
|
||||||
@@ -61,9 +59,9 @@ public class KjbMGOAuth2Controller {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TokenIssuanceLogDAO tokenIssuanceLogDAO;
|
private TokenIssuanceLogDAO tokenIssuanceLogDAO;
|
||||||
|
|
||||||
@RequestMapping(value = "/mapi/oauth2/token2", method = RequestMethod.POST, produces = "application/json; charset=\"UTF-8\"")
|
@RequestMapping(value = "/mapi/oauth2/token", method = RequestMethod.POST, produces = "application/json; charset=\"UTF-8\"")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public KjbMGOAuth2AccessTokenResponse token(@RequestBody KjbMGOAuth2AccessTokenRequest tokenRequest,
|
public ResponseEntity<String> token(@RequestBody KjbMGOAuth2AccessTokenRequest tokenRequest,
|
||||||
HttpServletRequest request, HttpServletResponse response) {
|
HttpServletRequest request, HttpServletResponse response) {
|
||||||
if (logger.isDebug()) {
|
if (logger.isDebug()) {
|
||||||
logger.debug(tokenRequest.toString());
|
logger.debug(tokenRequest.toString());
|
||||||
@@ -96,7 +94,7 @@ public class KjbMGOAuth2Controller {
|
|||||||
ClientDetails clientDetails = OAuth2Manager.getInstance().getClientDeatilsStore().get(clientId);
|
ClientDetails clientDetails = OAuth2Manager.getInstance().getClientDeatilsStore().get(clientId);
|
||||||
verifyClient(clientDetails, clientId, scopeSet);
|
verifyClient(clientDetails, clientId, scopeSet);
|
||||||
|
|
||||||
String traceId = UUID.randomUUID().toString().replace("-", "");
|
String traceId = UUID.randomUUID().toString().replace("-", "");
|
||||||
response.setHeader(HEADER_TRACEID, traceId);
|
response.setHeader(HEADER_TRACEID, traceId);
|
||||||
|
|
||||||
HashMap<String, String> authorizationParameters = new HashMap<String, String>();
|
HashMap<String, String> authorizationParameters = new HashMap<String, String>();
|
||||||
@@ -123,19 +121,22 @@ public class KjbMGOAuth2Controller {
|
|||||||
responseToken.setExpiresOn(System.currentTimeMillis() + (token.getExpiresIn() * 1000));
|
responseToken.setExpiresOn(System.currentTimeMillis() + (token.getExpiresIn() * 1000));
|
||||||
responseToken.setScope(tokenRequest.getScope());
|
responseToken.setScope(tokenRequest.getScope());
|
||||||
responseToken.setResource(tokenRequest.getResource());
|
responseToken.setResource(tokenRequest.getResource());
|
||||||
|
|
||||||
|
// 성공 시 JSON 문자열로 변환하여 반환
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
String successJson = mapper.writeValueAsString(responseToken);
|
||||||
|
return ResponseEntity.ok(successJson);
|
||||||
|
|
||||||
} catch (JwtAuthException e) {
|
} catch (JwtAuthException e) {
|
||||||
response.setStatus(NumberUtils.toInt(StringUtils.left(e.getCode(), 3), HttpStatus.UNAUTHORIZED.value()));
|
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, e.getMessage());
|
||||||
responseToken.setResponseCode(e.getCode());
|
int statusCode = NumberUtils.toInt(StringUtils.left(e.getCode(), 3), HttpStatus.UNAUTHORIZED.value());
|
||||||
responseToken.setResponseMessage(e.getMessage());
|
return ResponseEntity.status(statusCode).body(errorJson);
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error(e.getMessage());
|
logger.error(e.getMessage());
|
||||||
response.setStatus(HttpStatus.UNAUTHORIZED.value());
|
String errorJson = MessageUtil.makeJsonErrorMessage(MessageUtil.ERROR_CODE_AUTH_FAIL, "Unauthorized. [Unknown]");
|
||||||
responseToken.setResponseCode(
|
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(errorJson);
|
||||||
String.format("%d%s%s", HttpStatus.UNAUTHORIZED.value(), SERVICE_CODE_ACCESS_TOKEN, "00"));
|
|
||||||
responseToken.setResponseMessage("Unauthorized. [Unknown]");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return responseToken;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyClient(ClientDetails clientDetails, String clientId, Set<String> scopeSet)
|
private void verifyClient(ClientDetails clientDetails, String clientId, Set<String> scopeSet)
|
||||||
|
|||||||
@@ -1,425 +0,0 @@
|
|||||||
package com.eactive.eai.custom.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 java.util.Properties;
|
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import com.eactive.eai.common.dao.DAOFactory;
|
|
||||||
import com.eactive.eai.common.exception.ExceptionUtil;
|
|
||||||
import com.eactive.eai.common.inflow.CustomBucket;
|
|
||||||
import com.eactive.eai.common.inflow.InflowControlDAO;
|
|
||||||
import com.eactive.eai.common.inflow.InflowControlManager;
|
|
||||||
import com.eactive.eai.common.inflow.InflowTargetVO;
|
|
||||||
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.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;
|
|
||||||
|
|
||||||
public class InflowControlManagerSBI implements Lifecycle, com.eactive.eai.common.inflow.Bucket
|
|
||||||
{
|
|
||||||
static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
|
|
||||||
|
|
||||||
private static InflowControlManagerSBI manager;
|
|
||||||
|
|
||||||
private HashMap<String,CustomBucket> adapterBucketList;
|
|
||||||
private HashMap<String,CustomBucket> interfaceBucketList;
|
|
||||||
private boolean started;
|
|
||||||
private LifecycleSupport lifecycle = new LifecycleSupport(this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. 기능 : Default Constructor
|
|
||||||
* 2. 처리 개요 : C2RServiceVO Rule 정보를 저장하기 위한 HashMap을 초기화한다.
|
|
||||||
* 3. 주의사항
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
private InflowControlManagerSBI() {
|
|
||||||
adapterBucketList = new HashMap<String, CustomBucket>();
|
|
||||||
interfaceBucketList = new HashMap<String, CustomBucket>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. 기능 : InflowControlManagerSBI Singleton Object를 반환하는 getter method
|
|
||||||
* 2. 처리 개요 : C2RServiceManager Singleton Object를 반환한다.
|
|
||||||
* 3. 주의사항
|
|
||||||
*
|
|
||||||
* @return InflowControlManagerSBI Singleton object
|
|
||||||
**/
|
|
||||||
public static InflowControlManagerSBI getInstance() {
|
|
||||||
if(manager == null) {
|
|
||||||
synchronized(InflowControlManagerSBI.class) {
|
|
||||||
if(manager == null) {
|
|
||||||
manager = new InflowControlManagerSBI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static com.eactive.eai.common.inflow.Bucket getBucket() {
|
|
||||||
if(manager == null) {
|
|
||||||
synchronized(InflowControlManagerSBI.class) {
|
|
||||||
if(manager == null) {
|
|
||||||
manager = new InflowControlManagerSBI();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 유량제어 대상인 거래인지 체크한다.(사이트에 맞게 구성)
|
|
||||||
* @param eaiServerManager
|
|
||||||
* @param eaiMessage
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
public static Boolean isTargetOfInflowControl(EAIServerManager eaiServerManager, EAIMessage eaiMessage) {
|
|
||||||
// 1. 모든 요청거래
|
|
||||||
InterfaceMapper mapper = eaiMessage.getMapper();
|
|
||||||
String returnType = mapper.getSendRecvDivision(eaiMessage.getStandardMessage()); // S|R
|
|
||||||
|
|
||||||
if (STDMessageKeys.SEND_RECV_CD_SEND.equals(returnType)) {
|
|
||||||
return new Boolean(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Boolean(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() throws LifecycleException {
|
|
||||||
if (started)
|
|
||||||
throw new LifecycleException("RECEAICMM201");
|
|
||||||
|
|
||||||
// Notify our interested LifecycleListeners
|
|
||||||
lifecycle.fireLifecycleEvent(STARTING_EVENT, this);
|
|
||||||
|
|
||||||
// C2RServiceVO Table Initializing ....
|
|
||||||
|
|
||||||
try {
|
|
||||||
init();
|
|
||||||
} catch(Exception e) {
|
|
||||||
//throw new LifecycleException("RECEAICMM202");
|
|
||||||
throw new LifecycleException(ExceptionUtil.getErrorCode(e,"RECEAICMM202"));
|
|
||||||
}
|
|
||||||
|
|
||||||
started = true;
|
|
||||||
// Notify our interested LifecycleListeners
|
|
||||||
lifecycle.fireLifecycleEvent(STARTED_EVENT, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void init() throws Exception {
|
|
||||||
initAdapter();
|
|
||||||
initInterface();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initAdapter() throws Exception {
|
|
||||||
// Initializing ....
|
|
||||||
adapterBucketList = new HashMap<String, CustomBucket>();
|
|
||||||
InflowControlDAO dao = null;
|
|
||||||
dao = (InflowControlDAO) DAOFactory.newInstance().create(InflowControlDAO.class);
|
|
||||||
List<InflowTargetVO> inflowAdapterVoList = dao.getInflowAdapterList();
|
|
||||||
|
|
||||||
for (InflowTargetVO inflowVo : inflowAdapterVoList) {
|
|
||||||
if (InflowControlManagerSBI.isInflowTarget(inflowVo)) {
|
|
||||||
CustomBucket bucket = makeBucketUsingInflowVO(inflowVo);
|
|
||||||
if (bucket != null) {
|
|
||||||
adapterBucketList.put(inflowVo.getName(), bucket);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initInterface() throws Exception {
|
|
||||||
// Initializing ....
|
|
||||||
interfaceBucketList = new HashMap<String, CustomBucket>();
|
|
||||||
InflowControlDAO dao = null;
|
|
||||||
dao = (InflowControlDAO) DAOFactory.newInstance().create(InflowControlDAO.class);
|
|
||||||
List<InflowTargetVO> inflowInterfaceVoList = dao.getInflowInterfaceList();
|
|
||||||
|
|
||||||
for (InflowTargetVO inflowVo : inflowInterfaceVoList) {
|
|
||||||
if (InflowControlManagerSBI.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("InflowControlManagerSBI] reload all Started ...");
|
|
||||||
}
|
|
||||||
initAdapter();
|
|
||||||
if(logger.isWarn()) {
|
|
||||||
logger.warn("InflowControlManagerSBI] reload all finished ...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public synchronized void reloadInterface() throws Exception {
|
|
||||||
if(logger.isWarn()) {
|
|
||||||
logger.warn("InflowControlManagerSBI] reload all Started ...");
|
|
||||||
}
|
|
||||||
initInterface();
|
|
||||||
if(logger.isWarn()) {
|
|
||||||
logger.warn("InflowControlManagerSBI] reload all finished ...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public synchronized void reloadAdapter(String adapter) throws Exception {
|
|
||||||
if (logger.isWarn()) {
|
|
||||||
logger.warn("InflowControlManagerSBI] reload Started ...");
|
|
||||||
}
|
|
||||||
InflowControlDAO dao = null;
|
|
||||||
dao = (InflowControlDAO) DAOFactory.newInstance().create(InflowControlDAO.class);
|
|
||||||
Map<String, InflowTargetVO> map = dao.getInflowTargetByAdater(adapter);
|
|
||||||
if (map != null) {
|
|
||||||
Iterator it = map.keySet().iterator();
|
|
||||||
String key = "";
|
|
||||||
for (int i = 0; it.hasNext(); i++) {
|
|
||||||
key = (String) it.next();
|
|
||||||
|
|
||||||
InflowTargetVO inflowTarget = map.get(key);
|
|
||||||
if (InflowControlManagerSBI.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("InflowControlManagerSBI] reload finished ...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public synchronized void reloadInterface(String inter) throws Exception {
|
|
||||||
if (logger.isWarn()) {
|
|
||||||
logger.warn("InflowControlManagerSBI] reload Started ...");
|
|
||||||
}
|
|
||||||
InflowControlDAO dao = null;
|
|
||||||
dao = (InflowControlDAO) DAOFactory.newInstance().create(InflowControlDAO.class);
|
|
||||||
Map<String, InflowTargetVO> map = dao.getInflowTargetByInterface(inter);
|
|
||||||
if (map != null) {
|
|
||||||
Iterator it = map.keySet().iterator();
|
|
||||||
String key = "";
|
|
||||||
for (int i = 0; it.hasNext(); i++) {
|
|
||||||
key = (String) it.next();
|
|
||||||
|
|
||||||
InflowTargetVO inflowTarget = map.get(key);
|
|
||||||
if (InflowControlManagerSBI.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("InflowControlManagerSBI] reload finished ...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. 기능 : Lifecycle의 stop 메서드로 C2RServiceManager를 종료하는 메서드
|
|
||||||
* 2. 처리 개요 : 멤버에 캐싱한 C2RServiceVO Rule 정보를 clear한다.
|
|
||||||
* 3. 주의사항
|
|
||||||
*
|
|
||||||
* @exception LifecycleException 이미 종료된 경우 발생(RECEAICMM203)
|
|
||||||
**/
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 1. 기능 : LifecycleListener를 등록하는 메서드
|
|
||||||
* 2. 처리 개요 : LifecycleListener를 등록한다.
|
|
||||||
* 3. 주의사항
|
|
||||||
*
|
|
||||||
* @param listener LifecycleEvent를 수신한 LifecycleListener
|
|
||||||
**/
|
|
||||||
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] = (String)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] = (String)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 (InflowControlManagerSBI.isInflowTarget(inflowTarget)) {
|
|
||||||
LocalBucketBuilder builder = Bucket4j.builder();
|
|
||||||
if (inflowTarget.getThresholdPerSecond() > 0) { // TPS
|
|
||||||
builder.addLimit(Bandwidth.simple(inflowTarget.getThresholdPerSecond(), Duration.ofSeconds(1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inflowTarget.getThreshold() > 0 && StringUtils.isNotBlank(inflowTarget.getThresholdTimeUnit())) {
|
|
||||||
builder.addLimit(Bandwidth.simple(inflowTarget.getThreshold(),
|
|
||||||
InflowControlManagerSBI.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) {
|
|
||||||
CustomBucket b = adapterBucketList.get(adapter);
|
|
||||||
if (b == null) return null;
|
|
||||||
return b.getInflowTargetVo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public InflowTargetVO getInterfaceInflow(String inter) {
|
|
||||||
CustomBucket b = interfaceBucketList.get(inter);
|
|
||||||
if (b == null) return null;
|
|
||||||
return b.getInflowTargetVo();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isInflowTarget(InflowTargetVO inflowTarget) {
|
|
||||||
if (inflowTarget == null || !inflowTarget.isActivate()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inflowTarget.getThresholdPerSecond() > 0) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inflowTarget.getThreshold() > 0 && StringUtils.equalsAnyIgnoreCase(inflowTarget.getThresholdTimeUnit(),
|
|
||||||
InflowControlManager.QUOTA_TIMEUNIT_DAY, InflowControlManager.QUOTA_TIMEUNIT_SECOND,
|
|
||||||
InflowControlManager.QUOTA_TIMEUNIT_MINUTE, InflowControlManager.QUOTA_TIMEUNIT_HOUR,
|
|
||||||
InflowControlManager.QUOTA_TIMEUNIT_DAY, InflowControlManager.QUOTA_TIMEUNIT_MONTH)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Duration getPeriod(String timeUnit) {
|
|
||||||
if (StringUtils.equalsIgnoreCase(timeUnit, InflowControlManager.QUOTA_TIMEUNIT_SECOND)) {
|
|
||||||
return Duration.ofSeconds(1);
|
|
||||||
} else if (StringUtils.equalsIgnoreCase(timeUnit, InflowControlManager.QUOTA_TIMEUNIT_MINUTE)) {
|
|
||||||
return Duration.ofMinutes(1);
|
|
||||||
} else if (StringUtils.equalsIgnoreCase(timeUnit, InflowControlManager.QUOTA_TIMEUNIT_HOUR)) {
|
|
||||||
return Duration.ofHours(1);
|
|
||||||
} else if (StringUtils.equalsIgnoreCase(timeUnit, InflowControlManager.QUOTA_TIMEUNIT_DAY)) {
|
|
||||||
return Duration.ofDays(1);
|
|
||||||
} else if (StringUtils.equalsIgnoreCase(timeUnit, InflowControlManager.QUOTA_TIMEUNIT_MONTH)) {
|
|
||||||
Calendar calendar = Calendar.getInstance();
|
|
||||||
return Duration.ofDays(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -3,6 +3,7 @@ package com.eactive.eai.custom.message;
|
|||||||
import java.time.ZonedDateTime;
|
import java.time.ZonedDateTime;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
import com.eactive.eai.common.util.DatetimeUtil;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
import com.eactive.eai.common.server.Keys;
|
import com.eactive.eai.common.server.Keys;
|
||||||
@@ -19,8 +20,6 @@ import com.eactive.eai.common.util.UUID;
|
|||||||
*/
|
*/
|
||||||
public final class GUIDGeneratorKJB {
|
public final class GUIDGeneratorKJB {
|
||||||
|
|
||||||
private static final DateTimeFormatter SDF_YYYYMMDDHHMMSS = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 그룹사코드(3) + 호스트명(8) + 서버구분번호(2) + 일자(8) + 전문생성시간(6) + 일련번호(6) + 시스템경로번호(3, '001')
|
* 그룹사코드(3) + 호스트명(8) + 서버구분번호(2) + 일자(8) + 전문생성시간(6) + 일련번호(6) + 시스템경로번호(3, '001')
|
||||||
*/
|
*/
|
||||||
@@ -34,18 +33,34 @@ public final class GUIDGeneratorKJB {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized static String getGUID(String groupCmpCd) {
|
public synchronized static String getGUID(String groupCmpCd) {
|
||||||
if (StringUtils.isEmpty(groupCmpCd)) groupCmpCd = "034"; //광주은행 그룹회사코드 "034"
|
String guid = groupCmpCd + UNIQUE_NUM;
|
||||||
|
guid = guid + DatetimeUtil.getCurrentDateTime();
|
||||||
String nowDateTime = SDF_YYYYMMDDHHMMSS.format(ZonedDateTime.now());
|
|
||||||
String strSeq = StringUtils.leftPad(String.valueOf(seq), 6, '0') ;
|
|
||||||
String guid = groupCmpCd + UNIQUE_NUM + nowDateTime + strSeq + "001";
|
|
||||||
|
|
||||||
seq++;
|
if(seq < 10) {
|
||||||
if (seq > 999999) {
|
guid = guid + "00000" + seq;
|
||||||
|
}
|
||||||
|
else if(seq < 100) {
|
||||||
|
guid = guid + "0000" + seq;
|
||||||
|
}
|
||||||
|
else if(seq < 1000) {
|
||||||
|
guid = guid + "000" + seq;
|
||||||
|
}
|
||||||
|
else if(seq < 10000) {
|
||||||
|
guid = guid + "00" + seq;
|
||||||
|
}
|
||||||
|
else if(seq < 100000) {
|
||||||
|
guid = guid + "0" + seq;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
guid = guid + seq;
|
||||||
|
}
|
||||||
|
|
||||||
|
seq ++;
|
||||||
|
if(seq > 999999) {
|
||||||
seq = 1;
|
seq = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return guid;
|
return guid + "001";
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String UNIQUE_NUM;
|
private static String UNIQUE_NUM;
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public class InterfaceMapperKJB extends DefaultInterfaceMapper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getOrgGuid(StandardMessage standardMessage) {
|
public String getOrgGuid(StandardMessage standardMessage) {
|
||||||
String orgGuid = getItemValue(standardMessage, getPath(GUID_ORG));
|
String orgGuid = getItemValue(standardMessage, getPath(GUID));
|
||||||
if (orgGuid.length() == 36) {
|
if (orgGuid.length() == 36) {
|
||||||
orgGuid = orgGuid.substring(0, 33);
|
orgGuid = orgGuid.substring(0, 33);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,185 @@
|
|||||||
|
package com.eactive.eai.custom.message;
|
||||||
|
|
||||||
|
import com.eactive.eai.adapter.AdapterGroupVO;
|
||||||
|
import com.eactive.eai.adapter.AdapterManager;
|
||||||
|
import com.eactive.eai.common.dao.Keys;
|
||||||
|
import com.eactive.eai.common.server.EAIServerManager;
|
||||||
|
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.inbound.processor.ProcessVO;
|
||||||
|
import com.eactive.eai.inbound.processor.Processor;
|
||||||
|
import com.eactive.eai.message.StandardItem;
|
||||||
|
import com.eactive.eai.message.StandardMessage;
|
||||||
|
import com.eactive.eai.message.manager.StandardMessageManager;
|
||||||
|
import com.eactive.eai.message.service.DefaultStandardMessageCoordinator;
|
||||||
|
import com.eactive.eai.message.service.InterfaceMapper;
|
||||||
|
import com.ext.eai.common.stdmessage.STDMessageKeys;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
public class StandardMessageCoordinatorKJB extends DefaultStandardMessageCoordinator {
|
||||||
|
private static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT);
|
||||||
|
|
||||||
|
public static final String DEFAULT_LENGTH = "00000745";
|
||||||
|
private static final String MESSAGE_PART = "Message";
|
||||||
|
private static final String MESSAGE_PART_HEADER_PART = "Message.Msg_Header";
|
||||||
|
private static final String MESSAGE_PART_MSG_HEDR_KNCD = "Message.Msg_Header.MSG_HEDR_KNCD";
|
||||||
|
private static final String MESSAGE_PART_MSG_HEDR_LEN = "Message.Msg_Header.MSG_HEDR_LEN";
|
||||||
|
private static final String MESSAGE_PART_BODY_PART = "Message.Msg_Body";
|
||||||
|
private static final String MESSAGE_PART_OUTPUT_MSG_CD = "Message.Msg_Body.OUTPUT_MSG_CD";
|
||||||
|
private static final String MESSAGE_PART_OUTPUT_MSG_CTNT = "Message.Msg_Body.OUTPUT_MSG_CTNT";
|
||||||
|
private static final String COMMON_PART_GROUP_CMD_CD = "Common.Service_info.GROUP_CMP_CD";
|
||||||
|
private static final String COMMON_PART_OTSD_CHNL_INST_CD = "Common.Service_info.OTSD_CHNL_INST_CD";
|
||||||
|
private static final String DATA_HEADER_DATA_HEDR_LEN = "Data_Part.Data_Header.DATA_HEDR_LEN";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void coordinateAfterParsing(StandardMessage standardMessage, Object paramObject, Properties prop) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void coordinateBeforeStandardMessageSend(StandardMessage standardMessage, String msgType, String charset) {
|
||||||
|
makeupDataHeaderLength(standardMessage, charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void coordinateBeforeResponse(StandardMessage standardMessage, ProcessVO processVO, Properties prop, String charset) {
|
||||||
|
makeupDataHeaderLength(standardMessage, charset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void coordinateAfterCreateMessageByRule(StandardMessage standardMessage, Object paramObject, Properties prop) {
|
||||||
|
// guid 설정
|
||||||
|
StandardMessageManager standardManager = StandardMessageManager.getInstance();
|
||||||
|
InterfaceMapper mapper = standardManager.getMapper();
|
||||||
|
|
||||||
|
//GUID 설정
|
||||||
|
String groupCmdCd = standardMessage.findItemValue(COMMON_PART_GROUP_CMD_CD);
|
||||||
|
|
||||||
|
String guid = GUIDGeneratorKJB.getGUID(groupCmdCd);
|
||||||
|
|
||||||
|
mapper.setGuid(standardMessage, guid);
|
||||||
|
|
||||||
|
StandardItem dataHeaderEtc = standardMessage.findItem("Data_Part.Data_Header_Etc");
|
||||||
|
dataHeaderEtc.setHidden(true);
|
||||||
|
|
||||||
|
//기관코드, 텔러번호 설정
|
||||||
|
//Adapter에 셋팅된 기관코드를 셋팅한다.
|
||||||
|
String adapterGroupName = prop.getProperty(Processor.ADAPTER_GROUP_NAME);
|
||||||
|
AdapterManager adapterManager = AdapterManager.getInstance();
|
||||||
|
AdapterGroupVO adptGrpVO = adapterManager.getAdapterGroupVO(adapterGroupName);
|
||||||
|
|
||||||
|
// Adapter의 기관코드를 얻어온다.
|
||||||
|
//TODO: 기관코드의 경우 현재 EAPIM 시스템에 컬럼은 있으나 설정을 사용하지 않고있으므로 불필요 할 경우 사용하지 않는다, 필요 할 경우 추가한다.
|
||||||
|
String inAdapterOsidInstiNo = adptGrpVO.getOsidInstiNo();
|
||||||
|
if(inAdapterOsidInstiNo != null && inAdapterOsidInstiNo.trim().length() > 0) {
|
||||||
|
standardMessage.setData(COMMON_PART_OTSD_CHNL_INST_CD, inAdapterOsidInstiNo);
|
||||||
|
if (logger.isDebug()) {
|
||||||
|
logger.debug("FIELD SET " + COMMON_PART_OTSD_CHNL_INST_CD + " << "+inAdapterOsidInstiNo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//2012-12-17 나영채 차장 타발요청에만 셋팅해달라고 요청
|
||||||
|
//전문요청일자
|
||||||
|
standardMessage.setData("Common.BizProc_Info.MESG_DMAN_DT", DatetimeUtil.getCurrentDate());
|
||||||
|
//전문요청시간
|
||||||
|
standardMessage.setData("Common.BizProc_Info.MESG_DMAN_TKTM", DatetimeUtil.getTime8());
|
||||||
|
|
||||||
|
|
||||||
|
//2012-07-24 임의 로 영업일자에 system시간 설정
|
||||||
|
standardMessage.setData("Common.BizProc_Info.BZOP_DT", DatetimeUtil.getCurrentDate());
|
||||||
|
|
||||||
|
EAIServerManager eaiServerManager = EAIServerManager.getInstance();
|
||||||
|
//비표준일경우 시스템 운영환경 구분코드를 셋팅한다.
|
||||||
|
standardMessage.setData("Common.Service_info.SYS_OPRT_ENV_DVCD", getSysOprtEnvDvcd(eaiServerManager));
|
||||||
|
|
||||||
|
//헤더부 최초전송IP주소 FRST_TRNM_IPAD
|
||||||
|
try {
|
||||||
|
standardMessage.setData("Header.Src_System.FRST_TRNM_IPAD", java.net.InetAddress.getLocalHost().getHostAddress());
|
||||||
|
} catch (UnknownHostException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean coordinateSetStandardMessageError(StandardMessage standardMessage, InterfaceMapper mapper,
|
||||||
|
String errCode, String errMsg) {
|
||||||
|
|
||||||
|
mapper.setResponseType(standardMessage, STDMessageKeys.RESPONSE_TYPE_CODE_E);
|
||||||
|
mapper.setSendRecvDivision(standardMessage, STDMessageKeys.SEND_RECV_CD_RECV);
|
||||||
|
|
||||||
|
StandardItem messagePart = standardMessage.findItem(MESSAGE_PART);
|
||||||
|
messagePart.setHidden(false);
|
||||||
|
messagePart.setSize(1);
|
||||||
|
|
||||||
|
StandardItem messageHeaderPart = standardMessage.findItem(MESSAGE_PART_HEADER_PART);
|
||||||
|
messageHeaderPart.setSize(1);
|
||||||
|
StandardItem messageBodyPart = standardMessage.findItem(MESSAGE_PART_BODY_PART);
|
||||||
|
messageBodyPart.setSize(1);
|
||||||
|
|
||||||
|
errCode = StringUtils.defaultString(errCode);
|
||||||
|
String siteErrCode = MessageUtil.getTobeCode(errCode);
|
||||||
|
String siteErrMessage;
|
||||||
|
switch(errCode) {
|
||||||
|
case("RECEAIIRP070"):
|
||||||
|
siteErrMessage = "거래 통제 되었습니다.";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
siteErrMessage = MessageUtil.getTobeMessage(errCode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
mapper.setErrorCode(standardMessage, siteErrCode);
|
||||||
|
|
||||||
|
standardMessage.setData(MESSAGE_PART_MSG_HEDR_KNCD, "EM");
|
||||||
|
standardMessage.setData(MESSAGE_PART_MSG_HEDR_LEN, DEFAULT_LENGTH);
|
||||||
|
standardMessage.setData(MESSAGE_PART_OUTPUT_MSG_CD, siteErrCode);
|
||||||
|
//Message.Msg_Body.OUTPUT_MSG_CTNT
|
||||||
|
mapper.setErrorMsg(standardMessage, siteErrMessage);
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void coordinateAfterRecvNonStdSyncResponse(StandardMessage responseMessage) {
|
||||||
|
StandardItem messagePart = responseMessage.findItem(MESSAGE_PART);
|
||||||
|
messagePart.setHidden(false);
|
||||||
|
messagePart.setSize(1);
|
||||||
|
|
||||||
|
StandardItem messageHeaderPart = responseMessage.findItem(MESSAGE_PART_HEADER_PART);
|
||||||
|
messageHeaderPart.setSize(1);
|
||||||
|
StandardItem messageBodyPart = responseMessage.findItem(MESSAGE_PART_BODY_PART);
|
||||||
|
messageBodyPart.setSize(1);
|
||||||
|
|
||||||
|
responseMessage.setData(MESSAGE_PART_MSG_HEDR_KNCD, "NM");
|
||||||
|
responseMessage.setData(MESSAGE_PART_MSG_HEDR_LEN, DEFAULT_LENGTH);
|
||||||
|
responseMessage.setData(MESSAGE_PART_OUTPUT_MSG_CD, "100000 ");
|
||||||
|
responseMessage.setData(MESSAGE_PART_OUTPUT_MSG_CTNT, "정상처리 되었습니다.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSysOprtEnvDvcd(EAIServerManager eaiServerManager) {
|
||||||
|
String result = "";
|
||||||
|
if (eaiServerManager.isPEAIServer()){ //운영
|
||||||
|
result = STDMessageKeys.SYS_OPRT_ENV_DVCD_ONLINE;
|
||||||
|
}else if (eaiServerManager.isDEAIServer()){ //개발
|
||||||
|
result = STDMessageKeys.SYS_OPRT_ENV_DVCD_DEV;
|
||||||
|
}else if (eaiServerManager.isSEAIServer()){ //테스트/검증
|
||||||
|
result = STDMessageKeys.SYS_OPRT_ENV_DVCD_TESTSTAGE;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void makeupDataHeaderLength(StandardMessage standardMessage, String charset) {
|
||||||
|
String dataBytesLengthStr = null;
|
||||||
|
try {
|
||||||
|
dataBytesLengthStr = String.valueOf(standardMessage.getBizDataBytes(charset).length);
|
||||||
|
String dataHeaderLength = StringUtils.leftPad(dataBytesLengthStr, 8, '0');
|
||||||
|
standardMessage.setData(DATA_HEADER_DATA_HEDR_LEN, dataHeaderLength);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
package com.eactive.eai.manage.inflow;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GroupBucketStatusDTO {
|
||||||
|
private String groupId;
|
||||||
|
private String groupName;
|
||||||
|
private boolean activate;
|
||||||
|
private List<BucketInfo> buckets;
|
||||||
|
|
||||||
|
public static class BucketInfo {
|
||||||
|
private String type; // "perSecond" | "threshold"
|
||||||
|
private long capacity; // 최대 토큰 수
|
||||||
|
private long availableTokens; // 현재 사용 가능한 토큰 수
|
||||||
|
private String timeUnit; // threshold인 경우 시간 단위
|
||||||
|
private double usagePercent; // 사용률 (100 - availableTokens/capacity * 100)
|
||||||
|
|
||||||
|
public BucketInfo() {}
|
||||||
|
|
||||||
|
public BucketInfo(String type, long capacity, long availableTokens, String timeUnit) {
|
||||||
|
this.type = type;
|
||||||
|
this.capacity = capacity;
|
||||||
|
this.availableTokens = availableTokens;
|
||||||
|
this.timeUnit = timeUnit;
|
||||||
|
this.usagePercent = capacity > 0 ?
|
||||||
|
Math.round((1.0 - (double) availableTokens / capacity) * 10000) / 100.0 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getCapacity() {
|
||||||
|
return capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCapacity(long capacity) {
|
||||||
|
this.capacity = capacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getAvailableTokens() {
|
||||||
|
return availableTokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAvailableTokens(long availableTokens) {
|
||||||
|
this.availableTokens = availableTokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimeUnit() {
|
||||||
|
return timeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTimeUnit(String timeUnit) {
|
||||||
|
this.timeUnit = timeUnit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getUsagePercent() {
|
||||||
|
return usagePercent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUsagePercent(double usagePercent) {
|
||||||
|
this.usagePercent = usagePercent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGroupId() {
|
||||||
|
return groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupId(String groupId) {
|
||||||
|
this.groupId = groupId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGroupName() {
|
||||||
|
return groupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setGroupName(String groupName) {
|
||||||
|
this.groupName = groupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isActivate() {
|
||||||
|
return activate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setActivate(boolean activate) {
|
||||||
|
this.activate = activate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BucketInfo> getBuckets() {
|
||||||
|
return buckets;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBuckets(List<BucketInfo> buckets) {
|
||||||
|
this.buckets = buckets;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package com.eactive.eai.manage.inflow;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/manage/inflow/group")
|
||||||
|
public class InflowGroupBucketController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InflowGroupBucketService bucketService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 특정 그룹의 버킷 상태 조회
|
||||||
|
* GET /manage/inflow/group/{groupId}/bucket-status
|
||||||
|
*/
|
||||||
|
@GetMapping("/{groupId}/bucket-status")
|
||||||
|
public ResponseEntity<?> getGroupBucketStatus(@PathVariable String groupId) {
|
||||||
|
GroupBucketStatusDTO status = bucketService.getGroupBucketStatus(groupId);
|
||||||
|
|
||||||
|
if (status == null) {
|
||||||
|
Map<String, Object> error = new HashMap<>();
|
||||||
|
error.put("success", false);
|
||||||
|
error.put("message", "그룹을 찾을 수 없습니다: " + groupId);
|
||||||
|
return ResponseEntity.ok(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("data", status);
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 모든 그룹의 버킷 상태 조회
|
||||||
|
* GET /manage/inflow/group/bucket-status
|
||||||
|
*/
|
||||||
|
@GetMapping("/bucket-status")
|
||||||
|
public ResponseEntity<?> getAllGroupBucketStatus() {
|
||||||
|
List<GroupBucketStatusDTO> statusList = bucketService.getAllGroupBucketStatus();
|
||||||
|
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
result.put("success", true);
|
||||||
|
result.put("data", statusList);
|
||||||
|
result.put("count", statusList.size());
|
||||||
|
return ResponseEntity.ok(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package com.eactive.eai.manage.inflow;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.eactive.eai.common.inflow.CustomGroupBucket;
|
||||||
|
import com.eactive.eai.common.inflow.InflowControlManager;
|
||||||
|
import com.eactive.eai.common.inflow.InflowGroupVO;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class InflowGroupBucketService {
|
||||||
|
|
||||||
|
public GroupBucketStatusDTO getGroupBucketStatus(String groupId) {
|
||||||
|
InflowControlManager manager = InflowControlManager.getInstance();
|
||||||
|
|
||||||
|
InflowGroupVO groupVo = manager.getGroupInflowThreshold(groupId);
|
||||||
|
if (groupVo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupBucketStatusDTO dto = new GroupBucketStatusDTO();
|
||||||
|
dto.setGroupId(groupId);
|
||||||
|
dto.setGroupName(groupVo.getGroupName());
|
||||||
|
dto.setActivate(groupVo.isActivate());
|
||||||
|
|
||||||
|
List<GroupBucketStatusDTO.BucketInfo> buckets = new ArrayList<>();
|
||||||
|
|
||||||
|
// CustomGroupBucket에서 직접 토큰 조회
|
||||||
|
CustomGroupBucket customGroupBucket = getCustomGroupBucket(groupId);
|
||||||
|
|
||||||
|
// perSecond bucket
|
||||||
|
if (groupVo.getThresholdPerSecond() > 0) {
|
||||||
|
long capacity = groupVo.getThresholdPerSecond();
|
||||||
|
long available = capacity;
|
||||||
|
if (customGroupBucket != null) {
|
||||||
|
long tokens = customGroupBucket.getPerSecondAvailableTokens();
|
||||||
|
if (tokens >= 0) {
|
||||||
|
available = Math.min(tokens, capacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buckets.add(new GroupBucketStatusDTO.BucketInfo(
|
||||||
|
"perSecond",
|
||||||
|
capacity,
|
||||||
|
available,
|
||||||
|
"SEC"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// threshold bucket
|
||||||
|
if (groupVo.getThreshold() > 0) {
|
||||||
|
long capacity = groupVo.getThreshold();
|
||||||
|
long available = capacity;
|
||||||
|
if (customGroupBucket != null) {
|
||||||
|
long tokens = customGroupBucket.getThresholdAvailableTokens();
|
||||||
|
if (tokens >= 0) {
|
||||||
|
available = Math.min(tokens, capacity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buckets.add(new GroupBucketStatusDTO.BucketInfo(
|
||||||
|
"threshold",
|
||||||
|
capacity,
|
||||||
|
available,
|
||||||
|
groupVo.getThresholdTimeUnit()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
dto.setBuckets(buckets);
|
||||||
|
return dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 그룹 버킷 조회 (리플렉션 사용)
|
||||||
|
*/
|
||||||
|
public CustomGroupBucket getCustomGroupBucket(String groupId) {
|
||||||
|
try {
|
||||||
|
InflowControlManager manager = InflowControlManager.getInstance();
|
||||||
|
Field field = InflowControlManager.class.getDeclaredField("groupBucketList");
|
||||||
|
field.setAccessible(true);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, CustomGroupBucket> groupBucketList =
|
||||||
|
(Map<String, CustomGroupBucket>) field.get(manager);
|
||||||
|
return groupBucketList.get(groupId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<GroupBucketStatusDTO> getAllGroupBucketStatus() {
|
||||||
|
InflowControlManager manager = InflowControlManager.getInstance();
|
||||||
|
String[] groupIds = manager.getGroupAllKeys();
|
||||||
|
|
||||||
|
List<GroupBucketStatusDTO> result = new ArrayList<>();
|
||||||
|
for (String groupId : groupIds) {
|
||||||
|
GroupBucketStatusDTO dto = getGroupBucketStatus(groupId);
|
||||||
|
if (dto != null) {
|
||||||
|
result.add(dto);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# 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; // 0: String, 1: Number,10: ZZ String, 11: LL Number
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# name ,level ,type ,size ,fieldType ,length ,dataType ,,refPath, refValue,value
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
# name ,level ,type ,size ,fieldType ,length ,dataType ,refPath, refValue, value
|
||||||
|
Header,1,3,1,1,0,1,,,
|
||||||
|
Sys_Info,2,3,1,1,0,1,,,
|
||||||
|
STND_MESG_LEN,3,2,1,1,8,12,,,
|
||||||
|
ENCD_CMPI_DVCD,3,2,1,1,1,1,,,0
|
||||||
|
GUID,3,2,1,1,36,1,,,
|
||||||
|
MESG_DMAN_DVCD,3,2,1,1,1,1,,,S
|
||||||
|
MESG_VER_NO,3,2,1,1,3,1,,,R10
|
||||||
|
Src_System,2,3,1,1,0,1,,,
|
||||||
|
FRST_TRNM_IPAD,3,2,1,1,39,1,,,
|
||||||
|
FRST_TRNM_SYS_CD,3,2,1,1,3,1,,,API
|
||||||
|
TRNM_SYS_CD,3,2,1,1,3,1,,,
|
||||||
|
TRNM_NODE_NO,3,2,1,1,4,1,,,
|
||||||
|
MCI_SESN_ID,3,2,1,1,8,1,,,
|
||||||
|
GNRZ_TMOT_TKTM,3,2,1,1,3,1,,,070
|
||||||
|
TX_TMOT_TKTM,3,2,1,1,3,1,,,060
|
||||||
|
KJB_Add,2,3,1,1,0,1,,,
|
||||||
|
OTSD_DMAN_SYS_CD,3,2,1,1,3,1,,,OBP
|
||||||
|
EAI_NODE_NO,3,2,1,1,2,1,,,
|
||||||
|
FEP_NODE_NO,3,2,1,1,2,1,,,
|
||||||
|
FEP_SESN_ID,3,2,1,1,6,1,,,
|
||||||
|
Spare_Zone,2,3,1,1,0,1,,,
|
||||||
|
HEDR_SPR_CTNT,3,2,1,1,25,1,,,
|
||||||
|
Common,1,3,1,1,0,1,,,
|
||||||
|
Service_info,2,3,1,1,0,1,,,
|
||||||
|
GROUP_CMP_CD,3,2,1,1,3,1,,,034
|
||||||
|
SRVC_ID,3,2,1,1,11,1,,,
|
||||||
|
PROCS_RSLT_RCMS_SRVC_ID,3,2,1,1,11,1,,,
|
||||||
|
IF_ID,3,2,1,1,20,1,,,
|
||||||
|
TX_SYNZ_DVCD,3,2,1,1,1,1,,,
|
||||||
|
HMAB_DVCD,3,2,1,1,1,1,,,2
|
||||||
|
OTSD_CHNL_INST_CD,3,2,1,1,3,1,,,
|
||||||
|
SYS_OPRT_ENV_DVCD,3,2,1,1,1,1,,,
|
||||||
|
TX_TYP_DVCD,3,2,1,1,1,1,,,O
|
||||||
|
ORTR_RESTR_YN,3,2,1,1,1,1,,,
|
||||||
|
ORTR_GUID,3,2,1,1,36,1,,,
|
||||||
|
Channel_Info,2,3,1,1,0,1,,,
|
||||||
|
BANK_CD,3,2,1,1,3,1,,,
|
||||||
|
TX_BRCD,3,2,1,1,4,1,,,
|
||||||
|
DSPC_RCV_BRN_DVCD,3,2,1,1,2,1,,,
|
||||||
|
RLTR_BRCD,3,2,1,1,4,1,,,
|
||||||
|
TRMN_INSL_BRCD,3,2,1,1,4,1,,,
|
||||||
|
CHNL_TYCD,3,2,1,1,1,1,,,
|
||||||
|
CHNL_DTLS_CLCD,3,2,1,1,3,1,,,
|
||||||
|
TMNL_KIND_DVCD,3,2,1,1,2,1,,,
|
||||||
|
TRMN_NO,3,2,1,1,6,1,,,
|
||||||
|
SCN_NO,3,2,1,1,13,1,,,
|
||||||
|
SCN_FILE_VER,3,2,1,1,10,2,,,
|
||||||
|
SCN_FILE_NM,3,2,1,1,30,1,,,
|
||||||
|
LANG_DVCD,3,2,1,1,3,1,,,KOR
|
||||||
|
CHNL_COM_SCTN_EXIS_YN,3,2,1,1,1,1,,,N
|
||||||
|
Confirm_Info,2,3,1,1,0,1,,,
|
||||||
|
PRCG_APRV_PROCS_STCD,3,2,1,1,1,1,,,
|
||||||
|
PRCG_APRV_TYCD,3,2,1,1,1,1,,,
|
||||||
|
APRV_PRCG_EMPNO,3,2,1,1,7,1,,,
|
||||||
|
NURN_RSBT_EMPNO,3,2,1,1,7,1,,,
|
||||||
|
PRCG_APRV_SEQNO,3,2,1,1,10,2,,,
|
||||||
|
NURN_AGNCY_APRV_YN,3,2,1,1,1,1,,,
|
||||||
|
DSGT_PRCG_CHNG_YN,3,2,1,1,1,1,,,
|
||||||
|
CHNG_DSGT_PRCG_EMPNO,3,2,1,1,7,1,,,
|
||||||
|
PRCG_APRV_DMAN_RSN,3,2,1,1,40,1,,,
|
||||||
|
PRCG_APRV_RSN,3,2,1,1,40,1,,,
|
||||||
|
BizProc_Info,2,3,1,1,0,1,,,
|
||||||
|
BZOP_DT,3,2,1,1,8,1,,,
|
||||||
|
ANTT_YN,3,2,1,1,1,1,,,
|
||||||
|
MESG_IQRY_DVCD,3,2,1,1,1,1,,,
|
||||||
|
ATMC_CLSN_DVCD,3,2,1,1,1,1,,,
|
||||||
|
TLRNO,3,2,1,1,7,1,,,
|
||||||
|
ASST_TLRNO,3,2,1,1,7,1,,,
|
||||||
|
PSWD_VALDTN_YN,3,2,1,1,1,1,,,
|
||||||
|
TX_TELR_PSWD,3,2,1,1,44,1,,,
|
||||||
|
CSIF_IDNT_DVCD,3,2,1,1,3,1,,,
|
||||||
|
CSIF_ID,3,2,1,1,30,1,,,
|
||||||
|
CSIF_CUST_NM,3,2,1,1,30,1,,,
|
||||||
|
CSIF_MASK_REVOC_YN,3,2,1,1,1,1,,,
|
||||||
|
CUST_PTLET_MASK_YN,3,2,1,1,1,1,,,
|
||||||
|
IDC_IMG_NO,3,2,1,1,32,1,,,
|
||||||
|
SMTWKP_TX_YN,3,2,1,1,1,1,,,
|
||||||
|
SECU_ACCO_REG_YN,3,2,1,1,1,1,,,
|
||||||
|
ABC_TX_DTLS_DVCD,3,2,1,1,2,1,,,
|
||||||
|
CLNT_TELR_CSHN_RFLC_YN,3,2,1,1,1,1,,,
|
||||||
|
SLIP_DIV_YN,3,2,1,1,1,1,,,
|
||||||
|
SLIP_NO,3,2,1,1,9,1,,,
|
||||||
|
TELR_SLIP_SEQNO,3,2,1,1,10,2,,,
|
||||||
|
TELR_CASH_AMT,3,2,1,1,17,2,,,
|
||||||
|
TELR_CBPC_AMT,3,2,1,1,17,2,,,
|
||||||
|
TELR_TRFAMT,3,2,1,1,17,2,,,
|
||||||
|
LOGIN_DVCD,3,2,1,1,1,1,,,
|
||||||
|
TX_DT_EXTNS_YN ,3,2,1,1,1,1,,,
|
||||||
|
TX_DT,3,2,1,1,8,1,,,
|
||||||
|
TX_TIME,3,2,1,1,8,1,,,
|
||||||
|
SYS_DT,3,2,1,1,8,1,,,
|
||||||
|
SYS_TIME,3,2,1,1,8,1,,,
|
||||||
|
MESG_DMAN_DT,3,2,1,1,8,1,,,
|
||||||
|
MESG_DMAN_TKTM,3,2,1,1,9,1,,,
|
||||||
|
MESG_CNTY_YN,3,2,1,1,1,1,,,
|
||||||
|
MESG_RSPN_DT,3,2,1,1,8,1,,,
|
||||||
|
MESG_RSPN_TKTM,3,2,1,1,9,1,,,
|
||||||
|
PROCS_RSLT_DVCD,3,2,1,1,2,1,,,
|
||||||
|
OUTPUT_MESG_TYCD,3,2,1,1,1,1,,,
|
||||||
|
LRQN_OUTPUT_DSCT_TRGT_YN,3,2,1,1,1,1,,,
|
||||||
|
MESG_CNTY_SEQNO,3,2,1,1,3,1,,,
|
||||||
|
Error_Info,2,3,1,1,0,1,,,
|
||||||
|
ERR_CD,3,2,1,1,6,1,,,
|
||||||
|
ERR_SYS_CD,3,2,1,1,3,1,,,
|
||||||
|
KJB_Add,2,3,1,1,0,1,,,
|
||||||
|
ORTR_SCN_ID,3,2,1,1,13,1,,,
|
||||||
|
CORP_DPRM_NO,3,2,1,1,5,1,,,
|
||||||
|
CSIF_IQRY_RSCD,3,2,1,1,2,1,,,
|
||||||
|
Com_Spare_Zone,2,3,1,1,0,1,,,
|
||||||
|
COM_SPR_CTNT,3,2,1,1,212,1,,,
|
||||||
|
Channel_Common,1,3,0,1,0,1,Std_Header.Common.Channel_Info.CHNL_COM_SCTN_EXIS_YN,Y,
|
||||||
|
Data_Header,2,3,0,1,0,1,,,
|
||||||
|
DATA_HEDR_KNCD,3,2,1,1,2,1,,,
|
||||||
|
DATA_HEDR_LEN,3,2,1,1,8,1,,,
|
||||||
|
Data_For_Each,2,3,0,1,0,1,,,
|
||||||
|
PSWD_ERR_DVCD,3,2,1,1,2,1,,,
|
||||||
|
ELFN_CUST_TYCD,3,2,1,1,2,1,,,
|
||||||
|
USER_ID_S14,3,2,1,1,14,1,,,
|
||||||
|
MST_ID_S14,3,2,1,1,14,1,,,
|
||||||
|
SVR_TX_NO,3,2,1,1,10,1,,,
|
||||||
|
HOST_TX_NO_S10,3,2,1,1,10,1,,,
|
||||||
|
NEXT_PAGE_EXIS_YN1,3,2,1,1,1,1,,,
|
||||||
|
SCCR_ISS_CD,3,2,1,1,2,1,,,
|
||||||
|
SQ1_SCCR_SSBP_NO_SER,3,2,1,1,2,1,,,
|
||||||
|
SQ2_SCCR_SSBP_NO_SER,3,2,1,1,2,1,,,
|
||||||
|
SECU_MEDIA_SEQNO_S4,3,2,1,1,4,1,,,
|
||||||
|
SECU_MEDIA_DTL_DVCD_N3,3,2,1,1,3,1,,,
|
||||||
|
PAGE_NO,3,2,1,1,5,1,,,
|
||||||
|
PAGE_SIZE,3,2,1,1,5,1,,,
|
||||||
|
TTCN_N5,3,2,1,1,5,1,,,
|
||||||
|
IQRY_CCNT_N5,3,2,1,1,5,1,,,
|
||||||
|
PRIQR_TX_NO,3,2,1,1,10,1,,,
|
||||||
|
SQ1_CUST_CNFR_INFO_CTNT_S39,3,2,1,1,39,1,,,
|
||||||
|
SQ2_CUST_CNFR_INFO_CTNT_S39,3,2,1,1,39,1,,,
|
||||||
|
MAC_S17,3,2,1,1,17,1,,,
|
||||||
|
HDD_SEQ_NO_S24,3,2,1,1,24,1,,,
|
||||||
|
CMCM_CD,3,2,1,1,1,1,,,
|
||||||
|
TLNO_S14,3,2,1,1,14,1,,,
|
||||||
|
OTP_EXPR_GDNC_DVCD_S1,3,2,1,1,1,1,,,
|
||||||
|
KFTC_ENCD_MST_KEY_VER_S2,3,2,1,1,2,1,,,
|
||||||
|
KFTC_ENCD_RAND1_S32,3,2,1,1,32,1,,,
|
||||||
|
KFTC_ENCD_RAND2_S32,3,2,1,1,32,1,,,
|
||||||
|
ADDT_ATHN_YN_S1,3,2,1,1,1,1,,,
|
||||||
|
ADDT_ATHN_METH_DVCD_S2,3,2,1,1,2,1,,,
|
||||||
|
ADDT_ATHN_ATHN_VAL_S40,3,2,1,1,40,1,,,
|
||||||
|
DUP_TX_YN_S1,3,2,1,1,1,1,,,
|
||||||
|
ABR_IP_BLC_YN_S1,3,2,1,1,1,1,,,
|
||||||
|
VIRT_ACCO_DVCD_S1,3,2,1,1,1,1,,,
|
||||||
|
BZWK_DVCD1_S1,3,2,1,1,1,1,,,
|
||||||
|
BZWK_DVCD2_S1,3,2,1,1,1,1,,,
|
||||||
|
BZWK_DVCD3_S1,3,2,1,1,1,1,,,
|
||||||
|
BZWK_DVCD4_S1,3,2,1,1,1,1,,,
|
||||||
|
BZWK_DVCD5_S1,3,2,1,1,1,1,,,
|
||||||
|
TX_SER_SEQNO_N3,3,2,1,1,3,1,,,
|
||||||
|
SECU_MEDIA_SEQNO_DMAN_VAL_S4,3,2,1,1,4,1,,,
|
||||||
|
MEDIA_D1_UZ_POSB_AMT_N12,3,2,1,1,12,1,,,
|
||||||
|
CPHR_KEY_SECU_CO_CD_S1,3,2,1,1,1,1,,,
|
||||||
|
HDD_VOLU_ID_S35,3,2,1,1,35,1,,,
|
||||||
|
SPR_FILD_S197,3,2,1,1,197,1,,,
|
||||||
|
Message,1,3,0,1,0,1,Std_Header.Header.Sys_Info.MESG_DMAN_DVCD,R,
|
||||||
|
Msg_Header,2,3,0,1,0,1,,,
|
||||||
|
MSG_HEDR_KNCD,3,2,1,1,2,1,,,NM
|
||||||
|
MSG_HEDR_LEN,3,2,1,1,8,2,,,
|
||||||
|
Msg_Body,2,3,0,1,0,1,,,
|
||||||
|
OUTPUT_ATRB_CD,3,2,1,1,1,1,,,0
|
||||||
|
OUTPUT_MSG_CD,3,2,1,1,10,1,,,
|
||||||
|
OUTPUT_MSG_CTNT,3,2,1,1,200,1,,,
|
||||||
|
OUTPUT_MSG_DESC,3,2,1,1,300,1,,,
|
||||||
|
ERR_MNGM_CTNT,3,2,1,1,200,1,,,
|
||||||
|
ERR_CHGR_NM,3,2,1,1,10,1,,,
|
||||||
|
ERR_CHGR_CNPL_NO,3,2,1,1,20,1,,,
|
||||||
|
OUTPUT_MSG_NCNT,3,2,1,1,4,2,,,0000
|
||||||
|
Output_Msg_Grid,3,4,0,1,0,1,Message.Msg_Body.OUTPUT_MSG_NCNT,,
|
||||||
|
OUTPUT_MSG_CD,4,2,0,1,10,1,,,
|
||||||
|
OUTPUT_MSG_CTNT,4,2,0,1,200,1,,,
|
||||||
|
OUTPUT_MSG_DESC,4,2,0,1,300,1,,,
|
||||||
|
ERR_MNGM_CTNT,4,2,0,1,200,1,,,
|
||||||
|
ERR_LOCT_CTNT,4,2,0,1,200,1,,,
|
||||||
|
ERR_OCCU_ITEM_NM,4,2,0,1,20,1,,,
|
||||||
|
Manager_Confirm,1,3,0,1,0,1,Std_Header.Header.Sys_Info.MESG_DMAN_DVCD,R,
|
||||||
|
Data_Header,2,3,0,1,0,1,,,
|
||||||
|
DATA_HEDR_KNCD,3,2,1,1,2,1,,,
|
||||||
|
DATA_HEDR_LEN,3,2,1,1,8,2,,,
|
||||||
|
Data_Header_Etc,2,3,0,1,0,1,,,
|
||||||
|
OUTPUT_SRVC_ID,3,2,1,1,13,1,,,
|
||||||
|
OUTPUT_SCN_ID,3,2,1,1,13,1,,,
|
||||||
|
OUTPUT_SCN_DRVTN_MSG_CTNT,3,2,1,1,50,1,,,
|
||||||
|
DCG_DVCD,3,2,1,1,1,1,,,
|
||||||
|
Data_For_Each,2,3,0,1,0,1,,,
|
||||||
|
ACNO,3,2,1,1,16,1,,,
|
||||||
|
TRMN_CUST_FLNM,3,2,1,1,20,1,,,
|
||||||
|
TX_AMT,3,2,1,1,17,2,,,
|
||||||
|
APRV_RSCD_CCNT,3,2,1,1,5,2,,,
|
||||||
|
APRV_RSCD,3,2,1,1,5,1,,,
|
||||||
|
PRCG_APRV_DESC,3,2,1,1,50,1,,,
|
||||||
|
PRCG_APRV_TYCD,3,2,1,1,1,1,,,
|
||||||
|
PRCG_APRV_LIST_CCNT,3,2,1,1,5,2,,,
|
||||||
|
TX_DVCD,3,2,1,1,2,1,,,
|
||||||
|
PRCG_EMPNO,3,2,1,1,6,1,,,
|
||||||
|
KOR_FLNM,3,2,1,1,40,1,,,
|
||||||
|
BLNG_BRCD,3,2,1,1,4,1,,,
|
||||||
|
BRN_KOR_NM ,3,2,1,1,100,1,,,
|
||||||
|
LOGIN_IPAD,3,2,1,1,30,1,,,
|
||||||
|
JOBCLS_CD,3,2,1,1,2,1,,,
|
||||||
|
LOGIN_STCD,3,2,1,1,2,1,,,
|
||||||
|
ABSC_YN,3,2,1,1,1,1,,,
|
||||||
|
AGNCY_APRV_TLRNO,3,2,1,1,7,1,,,
|
||||||
|
BRMNR_YN,3,2,1,1,1,1,,,
|
||||||
|
AUDT_UNCN_PRCG_YN,3,2,1,1,1,1,,,
|
||||||
|
Data_Part,1,3,0,1,0,1,,,
|
||||||
|
Data_Header,2,3,0,1,0,1,,,
|
||||||
|
DATA_HEDR_KNCD,3,2,1,1,2,1,,,IO
|
||||||
|
DATA_HEDR_LEN,3,2,1,1,8,2,,,
|
||||||
|
Data_Header_Etc,2,3,0,1,0,1,Std_Header.Header.Sys_Info.MESG_DMAN_DVCD,R,
|
||||||
|
OUTPUT_SRVC_ID,3,2,1,1,13,1,,,
|
||||||
|
OUTPUT_SCN_ID,3,2,1,1,13,1,,,
|
||||||
|
OUTPUT_SCN_DRVTN_MSG_CTNT,3,2,1,1,50,1,,,
|
||||||
|
DCG_DVCD,3,2,1,1,1,1,,,
|
||||||
|
Data_For_Each,2,3,0,1,0,1,,,
|
||||||
|
BizData,3,9,1,1,0,1,,,
|
||||||
|
END_BIT_CTNT,1,2,1,1,2,11,,,@@
|
||||||
|
@@ -1,18 +1,18 @@
|
|||||||
# layout : StandardMessage layout definition
|
# layout : StandardMessage layout definition
|
||||||
#layout.file.type=CSV
|
#layout.file.type=CSV
|
||||||
layout.file.type=DB
|
layout.file.type=DB
|
||||||
#layout.file.path=standard-layout-sbi.csv
|
#layout.file.path=standard-layout-kjb.csv
|
||||||
#layout.file.path=standard-layout-elk.csv
|
#layout.file.path=standard-layout-elk.csv
|
||||||
#layout.filter.FLAT=com.eactive.eai.custom.message.FlatMessageFilterSBI
|
#layout.filter.FLAT=com.eactive.eai.custom.message.FlatMessageFilterSBI
|
||||||
layout.filter.FLAT=com.eactive.eai.message.filter.FlatMessageFilter
|
layout.filter.FLAT=com.eactive.eai.message.filter.FlatMessageFilter
|
||||||
# mapper : StandardMessage's fields getter/setter interface
|
# mapper : StandardMessage's fields getter/setter interface
|
||||||
#mapper.class=com.eactive.eai.custom.message.InterfaceMapperSBI
|
#mapper.class=com.eactive.eai.custom.message.InterfaceMapperSBI
|
||||||
mapper.class=com.eactive.eai.custom.message.InterfaceMapperKBANK
|
mapper.class=com.eactive.eai.custom.message.InterfaceMapperKJB
|
||||||
#mapper.definition=standard-message-mapping-config-sbi.properties
|
#mapper.definition=standard-message-mapping-config-sbi.properties
|
||||||
#mapper.definition=standard-message-mapping-config-elk.properties
|
#mapper.definition=standard-message-mapping-config-elk.properties
|
||||||
mapper.definition=standard-message-mapping-config.properties
|
mapper.definition=standard-message-mapping-config-kjb.properties
|
||||||
# StandardMessage Coordinator implementation
|
# StandardMessage Coordinator implementation
|
||||||
message.coordinator.class=com.eactive.eai.custom.message.StandardMessageCoordinatorKBANK
|
message.coordinator.class=com.eactive.eai.custom.message.StandardMessageCoordinatorKJB
|
||||||
# RequestProcessor implementation
|
# RequestProcessor implementation
|
||||||
#requestProcessor.class=com.eactive.eai.inbound.processor.RequestProcessor
|
#requestProcessor.class=com.eactive.eai.inbound.processor.RequestProcessor
|
||||||
# reader : parsing input data to StandardMessage
|
# reader : parsing input data to StandardMessage
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#C2R\uC5D0\uC11C\uB9CC \uC0AC\uC6A9
|
||||||
|
REQ_SYS_CODE=
|
||||||
|
#\uCC44\uB110\uC720\uD615\uCF54\uB4DC
|
||||||
|
CHANNEL_TYPE_CD=
|
||||||
|
#\uCC44\uB110\uC138\uBD80\uBD84\uB958\uCF54\uB4DC
|
||||||
|
CHANNEL_DETAIL_CD=
|
||||||
|
#\uC804\uC1A1\uC2DC\uAC04-400\uC751\uB2F5\uC2DC\uC5D0 \uC14B\uD305
|
||||||
|
SEND_TIME=
|
||||||
|
#GUID - K
|
||||||
|
GUID=Header.Sys_Info.GUID
|
||||||
|
#\uC2DC\uC2A4\uD15C\uD0C0\uC785-MCI/EAI/FEP-\uC0AC\uC6A9
|
||||||
|
SYSTEM_TYPE=Header.Src_System.FRST_TRNM_SYS_CD
|
||||||
|
#\uC218\uC2E0\uC2DC\uAC01
|
||||||
|
RECV_TIME=Common.BizProc_Info.MESG_DMAN_TKTM
|
||||||
|
# \uBBF8\uC0AC\uC6A9
|
||||||
|
RETURN_VALUE=
|
||||||
|
#\uC6D0\uAC70\uB798GUID - K
|
||||||
|
GUID_ORG=
|
||||||
|
#GUID\uC758 \uC9C4\uD589\uC77C\uB828\uBC88\uD638 - K
|
||||||
|
GUID_SEQ=
|
||||||
|
#\uACC4\uC815\uACC4\uC11C\uBE44\uC2A4ID - K
|
||||||
|
SERVICE_ID=Common.Service_info.SRVC_ID
|
||||||
|
#\uACC4\uC815\uACC4\uC751\uB2F5\uC11C\uBE44\uC2A4ID
|
||||||
|
RETURN_SERVICE_ID=
|
||||||
|
#\uC778\uD130\uD398\uC774\uC2A4ID - K
|
||||||
|
INTERFACE_ID=Common.Service_info.IF_ID
|
||||||
|
#\uC138\uC158ID-MCI/EAI/FEP\uBCC4\uB85C map
|
||||||
|
SESSION_ID=Header.Src_System.MCI_SESN_ID
|
||||||
|
#\uC694\uCCAD\uC751\uB2F5\uAD6C\uBD84\uCF54\uB4DC(S|R)
|
||||||
|
SEND_RECV_DIVISION=Header.Sys_Info.MESG_DMAN_DVCD
|
||||||
|
#\uB0B4\uC678\uAD6C\uBD84\uCF54\uB4DC(1|2)
|
||||||
|
IN_EX_DIVISION=Common.Service_info.HMAB_DVCD
|
||||||
|
#\uC6B4\uC601\uD658\uACBD\uAD6C\uBD84\uCF54\uB4DC
|
||||||
|
OPERATION_ENV=Common.Service_info.SYS_OPRT_ENV_DVCD
|
||||||
|
#\uCD5C\uCD08\uC694\uCCADIP
|
||||||
|
FIRST_REQ_IP=Header.Src_System.FRST_TRNM_IPAD
|
||||||
|
#\uBCF5\uC6D0\uC5EC\uBD80(0|1)
|
||||||
|
RECOVER_YN=Common.Service_info.ORTR_RESTR_YN
|
||||||
|
#\uC778\uC2A4\uD134\uC2A4ID
|
||||||
|
INST_CODE=
|
||||||
|
#\uD0C0\uC784\uC544\uC6C3
|
||||||
|
TIMEOUT=
|
||||||
|
#\uC5D0\uB7EC\uCF54\uB4DC
|
||||||
|
ERROR_CODE=Common.Error_Info.ERR_CD
|
||||||
|
#\uC5D0\uB7EC\uBA54\uC2DC\uC9C0
|
||||||
|
ERROR_MSG=Message.Msg_Body.OUTPUT_MSG_CTNT
|
||||||
|
#\uC0AC\uC6A9\uC790ID
|
||||||
|
USER_ID=
|
||||||
|
#\uC751\uB2F5\uD0C0\uC785-\uC815\uC0C1\uC5EC\uBD80(0=\uC815\uC0C1|1=\uC5D0\uB7EC)
|
||||||
|
RESPONSE_TYPE=Common.BizProc_Info.PROCS_RSLT_DVCD
|
||||||
|
#\uAC70\uB798\uB3D9\uAE30\uD654\uAD6C\uBD84\uCF54\uB4DC(S|A)
|
||||||
|
SYNC_ASYNC_TYPE=Common.Service_info.TX_SYNZ_DVCD
|
||||||
Reference in New Issue
Block a user