APIS api 추가
This commit is contained in:
@@ -91,11 +91,13 @@ kjb-gradle.sh tasks --all
|
||||
|
||||
1. **IDE 설정 파일 생성 (최초 1회)**
|
||||
```bash
|
||||
# IntelliJ IDEA 사용 시
|
||||
kjb-gradle.sh idea
|
||||
|
||||
# Eclipse 사용 시
|
||||
# Eclipse 사용 시 (기본)
|
||||
kjb-gradle.sh eclipse
|
||||
|
||||
# IntelliJ IDEA 사용 시 (build.gradle.intellij 파일 사용 필요)
|
||||
# 1. build.gradle을 build.gradle.eclipse로 백업
|
||||
# 2. build.gradle.intellij를 build.gradle로 복사
|
||||
# 3. kjb-gradle.sh idea 실행
|
||||
```
|
||||
|
||||
2. **QueryDSL 등 소스 코드 생성**
|
||||
@@ -109,7 +111,8 @@ kjb-gradle.sh tasks --all
|
||||
```
|
||||
|
||||
4. **IDE에서 프로젝트 열기**
|
||||
- `kjb-gradle.sh idea` 또는 `kjb-gradle.sh eclipse` 실행 후, IDE에서 프로젝트를 엽니다.
|
||||
- Eclipse: `kjb-gradle.sh eclipse` 실행 후, IDE에서 프로젝트를 엽니다.
|
||||
- IntelliJ: IntelliJ 전용 `build.gradle.intellij`를 `build.gradle`로 교체 후 사용합니다.
|
||||
|
||||
5. **실행 구성(Run Configuration) 설정**
|
||||
- 사용하는 WAS(Tomcat 등)에 `eapim-admin` 프로젝트를 배포하도록 설정합니다.
|
||||
@@ -156,26 +159,24 @@ eapim-admin (root project)
|
||||
- **Lombok**: 애노테이션 프로세싱을 통한 Getters/setters/builders
|
||||
- **MapStruct**: DTO와 엔티티 간의 객체 매퍼
|
||||
|
||||
#### 이중 Q-Class 생성 (Gradle + Eclipse)
|
||||
#### Q-Class 생성 위치
|
||||
|
||||
이 프로젝트는 **Gradle과 Eclipse 애노테이션 프로세서 모두를 사용**하므로, Q-classes가 **두 위치에 생성**됩니다:
|
||||
|
||||
1. **`build/generated/java/`** - `kjb-gradle.sh compileJava` 또는 `kjb-gradle.sh build` 실행 시 Gradle이 생성
|
||||
2. **`WebContent/generated/`** - Eclipse IDE에서 빌드 시 Eclipse APT가 생성
|
||||
|
||||
**이는 예상된 동작이며 의도적입니다.** 두 디렉토리 모두 `.gitignore`에 포함되어 있으며 커밋해서는 안 됩니다.
|
||||
Q-classes는 `build/generated/java/` 디렉토리에 생성됩니다.
|
||||
- `kjb-gradle.sh compileJava` 또는 `kjb-gradle.sh build` 실행 시 Gradle이 자동으로 생성
|
||||
- 이 디렉토리는 `.gitignore`에 포함되어 있으며 커밋해서는 안 됩니다
|
||||
|
||||
#### 생성된 코드 작업하기
|
||||
|
||||
- **Gradle 빌드**: `build/generated/java/`의 Q-classes가 자동으로 classpath에 포함됩니다
|
||||
- **Eclipse IDE**: `WebContent/generated/`의 Q-classes가 자동으로 classpath에 포함됩니다
|
||||
- **업데이트 pull 후**: `kjb-gradle.sh compileJava`를 실행하거나 Eclipse 프로젝트를 새로고침하여 Q-classes를 재생성합니다
|
||||
- **Q-classes IDE 오류 시**: `kjb-gradle.sh clean compileJava` 또는 Eclipse → Project → Clean으로 재생성합니다
|
||||
- **업데이트 pull 후**: `kjb-gradle.sh compileJava`를 실행하여 Q-classes를 재생성합니다
|
||||
- **Q-classes IDE 오류 시**: `kjb-gradle.sh clean compileJava`로 재생성합니다
|
||||
|
||||
중복이 문제를 일으키지 않는 이유:
|
||||
- 두 도구 모두 동일한 JPA 엔티티에서 동일한 Q-classes를 생성합니다
|
||||
- 두 출력 디렉토리 모두 gitignore됩니다
|
||||
- 각 도구는 자체 생성 클래스를 사용합니다 (classpath 충돌 없음)
|
||||
#### IDE별 빌드 설정 파일
|
||||
|
||||
- **`build.gradle`**: Eclipse 전용 (기본, Eclipse APT 플러그인 포함)
|
||||
- **`build.gradle.intellij`**: IntelliJ IDEA 전용
|
||||
|
||||
IntelliJ를 사용하려면 `build.gradle.intellij`를 `build.gradle`로 교체해야 합니다.
|
||||
|
||||
## 로컬 개발 환경 설정
|
||||
|
||||
@@ -315,6 +316,50 @@ com.eactive.eai
|
||||
|
||||
리포지토리는 Spring Data JPA 규칙을 사용하며, 서비스는 `@Service`, 컨트롤러는 `@RestController`/`@Controller`를 사용합니다.
|
||||
|
||||
### Multi-tenancy (동적 스키마 전환)
|
||||
|
||||
애플리케이션은 Hibernate Multi-tenancy를 사용하여 **런타임에 스키마를 동적으로 전환**합니다.
|
||||
|
||||
**핵심 컴포넌트:**
|
||||
- `DataSourceContextHolder` - ThreadLocal로 현재 데이터소스 타입 관리
|
||||
- `DataSourceTypeManager` - 데이터소스 타입 상수 정의 (MONITORING, APIGW, EAI, BAT 등)
|
||||
- `TenantIdentifierResolver` - `DataSourceContextHolder`에서 tenant 식별자 반환
|
||||
- `ConfigurableMultiTenantConnectionProvider` - tenant에 따라 `connection.setSchema()` 호출
|
||||
- `DataSourceTypeInterceptor` - 요청 파라미터 `serviceType`에서 데이터소스 자동 설정
|
||||
|
||||
**동작 흐름:**
|
||||
1. `DataSourceTypeInterceptor.preHandle()` → `request.getParameter("serviceType")` 읽음
|
||||
2. `DataSourceContextHolder.setDataSourceType(dataSourceType)` 설정
|
||||
3. JPA 쿼리 실행 시 `TenantIdentifierResolver` → `DataSourceContextHolder`에서 tenant 반환
|
||||
4. `ConfigurableMultiTenantConnectionProvider` → `connection.setSchema(schema)` 호출
|
||||
|
||||
**사용 방법:**
|
||||
|
||||
1. **URL 파라미터 방식** (인터셉터가 자동 처리):
|
||||
```
|
||||
/api/endpoint?serviceType=APIGW
|
||||
```
|
||||
|
||||
2. **Controller에서 명시적 설정** (특정 데이터소스 강제):
|
||||
```java
|
||||
@Controller
|
||||
public class MyController {
|
||||
@RequestMapping("/my/api.json")
|
||||
public String myApi() {
|
||||
// 서비스 호출 전에 데이터소스 설정
|
||||
DataSourceContextHolder.setDataSourceType(
|
||||
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
|
||||
|
||||
return myService.getData();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**주의사항:**
|
||||
- `@PersistenceContext`만 사용 (기본 `entityManagerFactory` 사용, Multi-tenancy 적용됨)
|
||||
- `@PersistenceContext(unitName = "entityManagerFactoryForEMS")`는 **Multi-tenancy 미적용** (MONITORING 스키마 고정)
|
||||
- Controller에서 `DataSourceContextHolder` 설정 후 Service 메서드를 호출해야 트랜잭션 시작 시점에 올바른 스키마가 적용됨
|
||||
|
||||
### 주요 초기화
|
||||
- `AppInitializer` - 시스템 프로퍼티를 설정하는 메인 애플리케이션 시작 빈
|
||||
- `CustomizingAppInitializer` - 고객사별 초기화
|
||||
@@ -328,19 +373,7 @@ com.eactive.eai
|
||||
|
||||
## IDE 설정
|
||||
|
||||
### Eclipse
|
||||
|
||||
```bash
|
||||
kjb-gradle.sh eclipse
|
||||
```
|
||||
|
||||
다음을 생성합니다:
|
||||
- `.project` 및 `.classpath` 파일
|
||||
- Eclipse WTP 설정 (context path: `/monitoring`)
|
||||
- UTF-8 인코딩 설정
|
||||
- QueryDSL/Lombok을 위한 애노테이션 프로세서 설정
|
||||
|
||||
### IntelliJ IDEA
|
||||
### IntelliJ IDEA (권장)
|
||||
|
||||
```bash
|
||||
kjb-gradle.sh idea
|
||||
@@ -348,6 +381,30 @@ kjb-gradle.sh idea
|
||||
|
||||
또는 IntelliJ에서 직접 "Import Gradle Project"를 사용합니다.
|
||||
|
||||
기본 `build.gradle`은 IntelliJ 전용으로 설정되어 있습니다.
|
||||
|
||||
### Eclipse
|
||||
|
||||
Eclipse를 사용하려면 Eclipse APT 플러그인이 포함된 별도의 빌드 설정 파일을 사용해야 합니다:
|
||||
|
||||
```bash
|
||||
# 1. 기존 build.gradle 백업 (필요시)
|
||||
cp build.gradle build.gradle.intellij
|
||||
|
||||
# 2. Eclipse 전용 설정으로 교체
|
||||
cp build.gradle.eclipse build.gradle
|
||||
|
||||
# 3. Eclipse 프로젝트 생성
|
||||
kjb-gradle.sh eclipse
|
||||
```
|
||||
|
||||
Eclipse 전용 설정(`build.gradle.eclipse`)은 다음을 포함합니다:
|
||||
- `com.diffplug.eclipse.apt` 플러그인 (Eclipse APT 지원)
|
||||
- `.project` 및 `.classpath` 파일 생성
|
||||
- Eclipse WTP 설정 (context path: `/monitoring`)
|
||||
- UTF-8 인코딩 설정
|
||||
- QueryDSL/Lombok을 위한 애노테이션 프로세서 설정
|
||||
|
||||
## 테스트
|
||||
|
||||
테스트에 사용되는 것들:
|
||||
|
||||
@@ -0,0 +1,244 @@
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'idea'
|
||||
id 'war'
|
||||
id 'project-report'
|
||||
id 'checkstyle'
|
||||
}
|
||||
|
||||
group 'com.eactive'
|
||||
version '4.5.7'
|
||||
|
||||
def springVersion = "5.3.27"
|
||||
def quartzVersion = "2.2.1"
|
||||
def queryDslVersion = "5.0.0"
|
||||
def hibernateVersion = "5.6.15.Final"
|
||||
|
||||
/*def nexusUrl = "https://nexus.eactive.synology.me:8090"*/
|
||||
//def useOnJboss = false
|
||||
|
||||
def generatedJavaDir = "$buildDir/generated/java"
|
||||
|
||||
/*repositories {
|
||||
maven {
|
||||
url "${nexusUrl}/repository/maven-public/"
|
||||
allowInsecureProtocol = true
|
||||
}
|
||||
}*/
|
||||
|
||||
project.webAppDirName = 'WebContent'
|
||||
|
||||
java {
|
||||
toolchain {
|
||||
languageVersion = JavaLanguageVersion.of(8)
|
||||
}
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = '8.45.1'
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
java {
|
||||
srcDirs generatedJavaDir
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compileJava {
|
||||
options.encoding = 'UTF-8'
|
||||
options.compilerArgs = [
|
||||
'-parameters',
|
||||
'-Aquerydsl.generatedAnnotationClass=com.querydsl.core.annotations.Generated'
|
||||
]
|
||||
options.generatedSourceOutputDirectory = project.file(generatedJavaDir)
|
||||
}
|
||||
|
||||
war {
|
||||
def profile = project.findProperty("profile") ?: "tomcat"
|
||||
|
||||
if (profile == "weblogic") {
|
||||
webXml = file("WebContent/WEB-INF/weblogic-web.xml")
|
||||
exclude 'WEB-INF/web.xml'
|
||||
}
|
||||
|
||||
|
||||
// rootSpec.exclude '**/persistence.xml'
|
||||
exclude '**/context.xml'
|
||||
archiveFileName = "eapim-admin.war"
|
||||
duplicatesStrategy = DuplicatesStrategy.WARN
|
||||
}
|
||||
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
options.compilerArgs += ['-parameters', "-Xlint:unchecked", "-Xlint:deprecation"]
|
||||
}
|
||||
|
||||
|
||||
dependencies {
|
||||
|
||||
annotationProcessor "org.projectlombok:lombok:1.18.28", "org.projectlombok:lombok-mapstruct-binding:0.2.0", "org.mapstruct:mapstruct-processor:1.5.5.Final"
|
||||
annotationProcessor "com.querydsl:querydsl-apt:${queryDslVersion}:jpa", "jakarta.persistence:jakarta.persistence-api:2.2.3", "jakarta.annotation:jakarta.annotation-api:1.3.5"
|
||||
|
||||
implementation project(':elink-online-core')
|
||||
implementation project(':elink-online-transformer')
|
||||
implementation project(':elink-online-common')
|
||||
implementation project(':elink-online-emsclient')
|
||||
implementation project(':elink-portal-common')
|
||||
implementation project(':kjb-safedb')
|
||||
implementation project(":eapim-admin-kjb")
|
||||
|
||||
/* Custom Libs */
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
|
||||
//implementation "org.dom4j:dom4j:2.1.3"
|
||||
//implementation "com.rabbitmq:amqp-client:3.6.6"
|
||||
|
||||
implementation "commons-primitives:commons-primitives:1.0"
|
||||
implementation 'org.apache.commons:commons-lang3:3.12.0'
|
||||
implementation "commons-lang:commons-lang:2.6"
|
||||
implementation "commons-httpclient:commons-httpclient:3.1"
|
||||
implementation "commons-cli:commons-cli:1.1"
|
||||
implementation "commons-pool:commons-pool:1.6"
|
||||
implementation group: 'commons-io', name: 'commons-io', version: '2.6'
|
||||
implementation 'net.sf.j8583:j8583:1.18.0'
|
||||
implementation "commons-beanutils:commons-beanutils:1.6.1"
|
||||
implementation 'org.apache.commons:commons-compress:1.26.0'
|
||||
// implementation "log4j:log4j:1.2.17"
|
||||
|
||||
implementation "net.sf.ehcache:ehcache:2.10.5"
|
||||
implementation "org.apache.poi:poi:3.2-FINAL"
|
||||
|
||||
implementation 'org.codehaus.groovy:groovy:3.0.18'
|
||||
|
||||
// https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api
|
||||
compileOnly group: 'javax.servlet', name: 'javax.servlet-api', version: '4.0.1'
|
||||
|
||||
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.13.1'
|
||||
//implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-xml', version: '2.13.1'
|
||||
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.13.1'
|
||||
|
||||
implementation "javax.jms:javax.jms-api:2.0"
|
||||
implementation "org.snmp4j:snmp4j:1.10.1"
|
||||
implementation "com.googlecode.json-simple:json-simple:1.1.1"
|
||||
|
||||
implementation "io.netty:netty-all:4.1.0.Final"
|
||||
|
||||
compileOnly "org.apache.mina:mina-filter-ssl:1.1.6"
|
||||
compileOnly "org.apache.mina:mina-core:1.1.6"
|
||||
|
||||
// https://mvnrepository.com/artifact/org.modelmapper/modelmapper
|
||||
implementation 'org.modelmapper:modelmapper:2.4.5'
|
||||
|
||||
////implementation "xalan:xalan:2.6.0"
|
||||
implementation "com.sun.xml.messaging.saaj:saaj-impl:1.3.28"
|
||||
|
||||
implementation "org.apache.ibatis:ibatis-sqlmap:2.3.4.726"
|
||||
implementation "org.jdom:jdom:1.1"
|
||||
implementation "com.google.code.gson:gson:2.3.1"
|
||||
implementation "javax.annotation:javax.annotation-api:1.2"
|
||||
implementation "net.sf.json-lib:json-lib-ext-spring:1.0.2"
|
||||
implementation "taglibs:standard:1.1.2"
|
||||
implementation "javax.servlet:jstl:1.1.2"
|
||||
implementation group: 'com.jcraft', name: 'jsch', version: '0.1.51'
|
||||
|
||||
implementation "org.quartz-scheduler:quartz:${quartzVersion}"
|
||||
|
||||
// https://mvnrepository.com/artifact/org.apache.poi/poi
|
||||
implementation group: 'org.apache.poi', name: 'poi', version: '3.17'
|
||||
// https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml
|
||||
implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '3.17'
|
||||
|
||||
implementation group: 'org.aspectj', name: 'aspectjrt', version: '1.9.7'
|
||||
implementation group: 'org.aspectj', name: 'aspectjtools', version: '1.9.7'
|
||||
|
||||
implementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.13'
|
||||
implementation group: 'org.apache.httpcomponents', name: 'httpcore', version: '4.4.15'
|
||||
implementation group: 'org.apache.httpcomponents', name: 'httpmime', version: '4.5.13'
|
||||
|
||||
//implementation "com.eactive:ojdbc8:1.0"
|
||||
//implementation "com.eactive:INISAFECore:v2.2.28"
|
||||
//implementation "com.eactive:backport-util-concurrent:1.0"
|
||||
|
||||
implementation "org.springframework:spring-web:${springVersion}"
|
||||
implementation "org.springframework:spring-aop:${springVersion}"
|
||||
implementation "org.springframework:spring-aspects:${springVersion}"
|
||||
implementation "org.springframework:spring-orm:${springVersion}"
|
||||
//implementation "com.eactive:spring-orm-ibatis-4.1.4:1.0"
|
||||
implementation "org.springframework:spring-webmvc:${springVersion}"
|
||||
implementation "org.springframework:spring-context:${springVersion}"
|
||||
implementation "org.springframework:spring-context-support:${springVersion}"
|
||||
implementation "org.springframework:spring-jdbc:${springVersion}"
|
||||
implementation 'org.springframework.data:spring-data-jpa:2.5.2'
|
||||
|
||||
implementation 'org.hibernate:hibernate-entitymanager:5.4.33.Final'
|
||||
implementation 'org.hibernate:hibernate-validator:5.4.3.Final'
|
||||
implementation 'org.hibernate:hibernate-ehcache:5.4.3.Final'
|
||||
|
||||
implementation 'org.slf4j:jul-to-slf4j:1.7.35'
|
||||
implementation 'org.slf4j:jcl-over-slf4j:1.7.35'
|
||||
implementation 'org.slf4j:log4j-over-slf4j:1.7.35'
|
||||
implementation 'org.slf4j:slf4j-api:1.7.35'
|
||||
|
||||
implementation 'ch.qos.logback:logback-classic:1.2.10'
|
||||
implementation 'ch.qos.logback:logback-access:1.2.10'
|
||||
implementation 'ch.qos.logback:logback-core:1.2.10'
|
||||
|
||||
implementation files("libs/eai-bap-client.jar")
|
||||
|
||||
compileOnly 'javax.xml.bind:jaxb-api:2.3.1'
|
||||
|
||||
//implementation 'org.postgresql:postgresql:42.2.23'
|
||||
|
||||
implementation 'backport-util-concurrent:backport-util-concurrent:3.0'
|
||||
|
||||
implementation ('software.amazon.awssdk:s3:2.20.142') {
|
||||
exclude group: 'org.slf4j', module: 'slf4j-api'
|
||||
exclude group: 'org.slf4j', module: 'logback-classic'
|
||||
}
|
||||
implementation 'software.amazon.awssdk:sso:2.20.142'
|
||||
implementation 'software.amazon.awssdk:sts:2.20.142'
|
||||
|
||||
implementation ('io.kubernetes:client-java:18.0.1') {
|
||||
exclude group: 'org.slf4j', module: 'slf4j-api'
|
||||
exclude group: 'org.slf4j', module: 'logback-classic'
|
||||
}
|
||||
|
||||
implementation group: 'commons-net', name: 'commons-net', version: '3.5'
|
||||
|
||||
testRuntimeOnly 'com.h2database:h2:2.1.214'
|
||||
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1'
|
||||
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test:2.6.15'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
configurations.all {
|
||||
exclude group: 'log4j', module: 'log4j'
|
||||
exclude group: 'org.apache.activemq'
|
||||
exclude group: 'org.codehaus.jackson'
|
||||
resolutionStrategy {
|
||||
// 10 minute cache of dynamic version navigation
|
||||
cacheDynamicVersionsFor 10, 'minutes'
|
||||
// Do not cache changing modules
|
||||
cacheChangingModulesFor 0, 'seconds'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
task initDirs() {
|
||||
file(generatedJavaDir).mkdirs()
|
||||
}
|
||||
|
||||
|
||||
tasks.withType(Checkstyle) {
|
||||
reports {
|
||||
xml.required = false
|
||||
html.required = true
|
||||
}
|
||||
}
|
||||
@@ -5,3 +5,8 @@ GET {{emsUrl}}/kjb/gw-metrics/after-timeslice/2025-12-02_01:00:00.json
|
||||
|
||||
### Pretty Print
|
||||
GET {{emsUrl}}/kjb/gw-metrics/after-timeslice/2025-12-02_01:00:00.json?pretty=true
|
||||
|
||||
|
||||
### API 목록
|
||||
GET {{emsUrl}}/kjb/apis.json
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.eactive.eai.rms.onl.apim.obp;
|
||||
|
||||
import com.eactive.eai.rms.common.datasource.DataSourceContextHolder;
|
||||
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
|
||||
import com.eactive.eai.rms.onl.apim.common.BaseRestController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* OBP API 목록 조회 REST Controller
|
||||
*
|
||||
* <p>TSEAIHE01과 TSEAIHS04를 조인하여 API 정보를 JSON으로 제공</p>
|
||||
*
|
||||
* @see BaseRestController 세션 체크 우회 및 JSON 유틸리티 제공
|
||||
*/
|
||||
@Controller
|
||||
public class ObpApiController extends BaseRestController {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ObpApiController.class);
|
||||
|
||||
private final ObpApiService obpApiService;
|
||||
|
||||
public ObpApiController(ObpApiService obpApiService) {
|
||||
this.obpApiService = obpApiService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 전체 API 목록 조회
|
||||
*
|
||||
* @param pretty true면 JSON 들여쓰기 적용
|
||||
* @return JSON Array
|
||||
*/
|
||||
@RequestMapping(
|
||||
value = "/kjb/apis.json",
|
||||
produces = JSON_CONTENT_TYPE
|
||||
)
|
||||
@ResponseBody
|
||||
public String getApis(
|
||||
@RequestParam(value = "pretty", required = false) Boolean pretty) {
|
||||
log.debug("OBP API 목록 조회 요청: pretty={}", pretty);
|
||||
long startTime = System.currentTimeMillis();
|
||||
|
||||
// APIGW 데이터소스 강제 설정
|
||||
DataSourceContextHolder.setDataSourceType(
|
||||
DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.APIGW));
|
||||
|
||||
try {
|
||||
List<ObpApiDTO> apis = obpApiService.findAllApis();
|
||||
|
||||
String json = toJson(apis, pretty);
|
||||
|
||||
long elapsed = System.currentTimeMillis() - startTime;
|
||||
log.info("OBP API 목록 조회 완료: count={}, size={}, elapsed={}ms",
|
||||
apis.size(), getFormattedJsonSize(json), elapsed);
|
||||
|
||||
return json;
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error("OBP API 목록 조회 실패", e);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package com.eactive.eai.rms.onl.apim.obp;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* OBP API 목록 조회 DTO
|
||||
*
|
||||
* <p>TSEAIHE01과 TSEAIHS04 테이블을 조인하여 API 정보를 제공</p>
|
||||
*/
|
||||
@Getter
|
||||
@Builder
|
||||
public class ObpApiDTO {
|
||||
|
||||
/**
|
||||
* API ID (TSEAIHE01.EAISVCNAME)
|
||||
*/
|
||||
private final String id;
|
||||
|
||||
/**
|
||||
* API 이름 (TSEAIHE01.EAISVCDESC)
|
||||
*/
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* 활성화 여부 (TSEAIHE01.USEYN = '1' -> true)
|
||||
*/
|
||||
private final boolean enabled;
|
||||
|
||||
/**
|
||||
* API URL (TSEAIHS04.APIFULLPATH에서 '|' 이후 부분)
|
||||
*/
|
||||
private final String url;
|
||||
|
||||
/**
|
||||
* HTTP Method (TSEAIHS04.APIFULLPATH에서 '|' 이전 부분)
|
||||
*/
|
||||
private final String method;
|
||||
|
||||
/**
|
||||
* 인증 타입 (TSEAIHE01.AUTHTYPE)
|
||||
*/
|
||||
private final String authType;
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package com.eactive.eai.rms.onl.apim.obp;
|
||||
|
||||
import com.eactive.eai.data.entity.onl.message.QEAIMessageEntity;
|
||||
import com.eactive.eai.data.entity.onl.stdmessage.QStandardMessageInfo;
|
||||
import com.querydsl.core.Tuple;
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.PersistenceContext;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* OBP API 목록 조회 Service
|
||||
*
|
||||
* <p>APIGW 데이터소스의 TSEAIHE01, TSEAIHS04 테이블에서 API 정보 조회</p>
|
||||
*/
|
||||
@Service
|
||||
public class ObpApiService {
|
||||
|
||||
@PersistenceContext
|
||||
private EntityManager entityManager;
|
||||
|
||||
private JPAQueryFactory getQueryFactory() {
|
||||
return new JPAQueryFactory(entityManager);
|
||||
}
|
||||
|
||||
/**
|
||||
* 전체 API 목록 조회
|
||||
*
|
||||
* @return API 목록
|
||||
*/
|
||||
public List<ObpApiDTO> findAllApis() {
|
||||
QEAIMessageEntity he01 = QEAIMessageEntity.eAIMessageEntity;
|
||||
QStandardMessageInfo hs04 = QStandardMessageInfo.standardMessageInfo;
|
||||
|
||||
List<Tuple> results = getQueryFactory()
|
||||
.select(
|
||||
he01.eaisvcname,
|
||||
he01.eaisvcdesc,
|
||||
he01.useyn,
|
||||
he01.authtype,
|
||||
hs04.apifullpath
|
||||
)
|
||||
.from(he01)
|
||||
.leftJoin(hs04).on(he01.eaisvcname.eq(hs04.eaisvcname))
|
||||
.orderBy(he01.eaisvcname.asc())
|
||||
.fetch();
|
||||
|
||||
return results.stream()
|
||||
.map(this::toDto)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tuple을 DTO로 변환
|
||||
*/
|
||||
private ObpApiDTO toDto(Tuple tuple) {
|
||||
QEAIMessageEntity he01 = QEAIMessageEntity.eAIMessageEntity;
|
||||
QStandardMessageInfo hs04 = QStandardMessageInfo.standardMessageInfo;
|
||||
|
||||
String eaisvcname = tuple.get(he01.eaisvcname);
|
||||
String eaisvcdesc = tuple.get(he01.eaisvcdesc);
|
||||
String useyn = tuple.get(he01.useyn);
|
||||
String authtype = tuple.get(he01.authtype);
|
||||
String apifullpath = tuple.get(hs04.apifullpath);
|
||||
|
||||
// APIFULLPATH 파싱: "POST|/mapi/kjbank/..." -> method="POST", url="/mapi/kjbank/..."
|
||||
String method = null;
|
||||
String url = null;
|
||||
if (StringUtils.isNotBlank(apifullpath) && apifullpath.contains("|")) {
|
||||
int pipeIndex = apifullpath.indexOf('|');
|
||||
method = apifullpath.substring(0, pipeIndex);
|
||||
url = apifullpath.substring(pipeIndex + 1);
|
||||
}
|
||||
|
||||
// USEYN이 "1"이면 enabled = true
|
||||
boolean enabled = "1".equals(useyn);
|
||||
|
||||
return ObpApiDTO.builder()
|
||||
.id(eaisvcname)
|
||||
.name(eaisvcdesc)
|
||||
.enabled(enabled)
|
||||
.url(url)
|
||||
.method(method)
|
||||
.authType(authtype)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user