EMSADM DDL identity to sequence 대응 완료
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
eLink EMS (eLink Management System) is a web-based management service for eLink that provides configuration, monitoring, and statistics features. This is a Spring-based Java web application deployed on Tomcat or WebLogic.
|
||||
|
||||
### Key Features
|
||||
- User and permission management
|
||||
- Transaction log viewing (online/batch/bulk)
|
||||
- Statistics and dashboard monitoring
|
||||
- Interface, layout, adapter, and routing management
|
||||
- Integration with external systems (UMS, EAI batch)
|
||||
|
||||
## Build and Development Commands
|
||||
|
||||
### Build Commands
|
||||
```bash
|
||||
# Standard build
|
||||
gradle build
|
||||
|
||||
# Build for Weblogic deployment (excludes tests)
|
||||
gradle build -x test -Pprofile=weblogic
|
||||
|
||||
# Build WAR file
|
||||
gradle war
|
||||
|
||||
# Clean build
|
||||
gradle clean build
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
```bash
|
||||
# Run all tests
|
||||
gradle test
|
||||
|
||||
# Run specific test (use JUnit platform)
|
||||
gradle test --tests "com.eactive.eai.rms.*"
|
||||
```
|
||||
|
||||
### Development Setup
|
||||
The application is configured via environment-specific properties files in `WebContent/WEB-INF/properties/`:
|
||||
- `env.D.properties` - Development
|
||||
- `env.T.properties` - Test/Staging
|
||||
- `env.P.properties` - Production
|
||||
|
||||
**Local Development (Tomcat)**
|
||||
Set the following JVM options:
|
||||
```
|
||||
-Deai.datasource.type=DEV
|
||||
-Dinst.Name=emsSvr99
|
||||
-Deai.tableowner=EMSADM
|
||||
-Deai.systemmode=D
|
||||
-Dfile.encoding=utf-8
|
||||
-Dlogin.mode=db
|
||||
-DLOGBACK_LOG_LEVEL=DEBUG
|
||||
-Dlogback.configurationFile=classpath:logback-dev.xml
|
||||
-Dhibernate.dialect=org.hibernate.dialect.Oracle12cDialect
|
||||
-Dkjb_safedb.mode=fake
|
||||
```
|
||||
|
||||
**Profile Configuration**
|
||||
- `-Pprofile=weblogic`: Uses `weblogic-web.xml` instead of `web.xml` (resolves DefaultServlet issues)
|
||||
|
||||
## Architecture and Code Structure
|
||||
|
||||
### Multi-Module Project
|
||||
This project references several external eLink modules defined in `settings.gradle`:
|
||||
- `elink-online-core` - Core interfaces and classes
|
||||
- `elink-online-transformer` - Message transformation logic
|
||||
- `elink-online-adapter` - Communication adapters
|
||||
- `elink-online-common` - Common utilities
|
||||
- `elink-online-emsclient` - EMS communication client
|
||||
- `elink-portal-common` - Portal shared components
|
||||
- `kjb-safedb` - KJB bank-specific database encryption
|
||||
- `eapim-admin-kjb` - KJB bank-specific customizations
|
||||
|
||||
These modules are located in sibling directories (`../eapim-online/`, `../elink-portal-common/`, etc.)
|
||||
|
||||
### Package Structure
|
||||
```
|
||||
com.eactive.eai
|
||||
├── agent/command - Command pattern implementations
|
||||
├── common - Common utilities, iBatis, JSON serialization
|
||||
├── custom - Customer-specific customizations
|
||||
├── rms - Main application code
|
||||
│ ├── bap - Batch processing (BAP)
|
||||
│ │ ├── adaptor - Batch adapters
|
||||
│ │ ├── manage - Batch management (messages, servers, properties)
|
||||
│ │ └── tansaction - Batch transaction tracking
|
||||
│ ├── bat - Additional batch functionality
|
||||
│ ├── common - RMS common (filters, startup, services)
|
||||
│ ├── data - Data entities, repositories
|
||||
│ ├── env - Environment configuration
|
||||
│ ├── kakao - Kakao integration
|
||||
│ ├── onl - Online transaction management
|
||||
│ │ ├── apim - API management (portal org, users, approvals)
|
||||
│ │ ├── manage - Resource management
|
||||
│ │ └── transaction - Transaction handling
|
||||
│ └── service - Business services
|
||||
└── ext.kjb - Kwangju Bank (KJB) extensions
|
||||
```
|
||||
|
||||
### Technology Stack
|
||||
- **Framework**: Spring 5.3.27 (MVC, Data JPA)
|
||||
- **Persistence**:
|
||||
- Hibernate 5.6.15 (JPA/ORM)
|
||||
- iBatis 2.3.4 (legacy SQL mapping)
|
||||
- QueryDSL 5.0.0 (type-safe queries)
|
||||
- **Database**: Oracle 12c (primary), with support for MariaDB/PostgreSQL
|
||||
- **Logging**: Logback 1.2.10 (with SLF4J)
|
||||
- **Build**: Gradle 8.x with Java 8
|
||||
- **View**: JSP with JSTL
|
||||
- **Other**: Quartz scheduler, EhCache, Jackson, Lombok, MapStruct
|
||||
|
||||
### Spring Configuration
|
||||
- Root context: `WebContent/WEB-INF/applicationContext.xml`
|
||||
- Servlet context: `WebContent/WEB-INF/springapp-servlet.xml`
|
||||
- Environment-specific configs loaded based on `${eai.systemmode}` system property
|
||||
- Component scanning enabled with annotation-based configuration
|
||||
|
||||
### Data Access Patterns
|
||||
The application uses **dual persistence**:
|
||||
1. **JPA/Hibernate** - For newer entity-based code in `com.eactive.eai.rms.data.entity`
|
||||
2. **iBatis** - For legacy SQL mappings in `src/main/resources/com/eactive/eai/**/*.xml`
|
||||
|
||||
Repositories use Spring Data JPA conventions, Services use `@Service`, Controllers use `@RestController`/`@Controller`.
|
||||
|
||||
### Key Initialization
|
||||
- `AppInitializer` - Main application startup bean that sets system properties
|
||||
- `CustomizingAppInitializer` - Customer-specific initialization
|
||||
- System properties: `inst.Name`, `eai.tableowner`, `eai.systemmode`, `theme.color`
|
||||
|
||||
## KJB (Kwangju Bank) Specific Configuration
|
||||
|
||||
### Property Management
|
||||
KJB-specific properties are stored in database table `TSEAIRM24` with group name `'Monitoring'`. Key properties handled by `com.eactive.ext.kjb.common.KjbProperty`:
|
||||
|
||||
**Email Notification (via EAI Batch)**
|
||||
- `kjb.eai_batch.url` - EAI batch server URL for email sending
|
||||
- Dev: http://172.31.32.111:10230/BATAppWeb/EaiBatCall
|
||||
- QA: http://172.31.33.111:10430/BATAppWeb/EaiBatCall
|
||||
- Prod: http://172.21.1.40:10860/BATAppWeb/EaiBatCall
|
||||
- `kjb.ums.eai_batch.send_dir` - Email file send directory (default: `/Data/eapim/portal/sendmail/snd`)
|
||||
- `kjb.ums.eai_batch.backup_dir` - Email backup directory (default: `/Data/eapim/portal/sendmail/bak`)
|
||||
- `kjb.ums.eai_batch.interface_id` - Interface ID for customer email (e.g., `UAGFF00001UIE`)
|
||||
|
||||
**UMS (SMS/LMS/KakaoTalk) Integration**
|
||||
- `kjb.ums.host_url` - UMS API endpoint
|
||||
- `kjb.ums.api_key` - UMS API authentication key
|
||||
- `kjb.ums.connection_timeout` - Connection timeout in seconds
|
||||
- `kjb.ums.response_timeout` - Response timeout in seconds
|
||||
|
||||
### Security
|
||||
- Custom password encoder: `KjbSafedbPasswordEncoder` for SafeDB integration
|
||||
- Set `-Dkjb_safedb.mode=fake` for local development without SafeDB
|
||||
|
||||
## Database Vendor Support
|
||||
|
||||
The application supports multiple databases via vendor-specific SQL mapping files:
|
||||
- Oracle: `*-oracle.xml`
|
||||
- MariaDB: `*-mariadb.xml`
|
||||
- PostgreSQL: `*-postgresql.xml`
|
||||
|
||||
Database vendor is configured in properties files via `db.vendor` and `hibernate.dialect`.
|
||||
|
||||
## WAR Deployment
|
||||
|
||||
The WAR file is built as `eapim-admin.war` with context path `/monitoring`.
|
||||
|
||||
**Weblogic Deployment**: Use `-Pprofile=weblogic` to include `weblogic-web.xml` configuration.
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **Encoding**: System uses UTF-8. CharacterEncodingFilter applies UTF-8 to all requests except `*.excel` patterns.
|
||||
- **XSS Protection**: CrossScriptingFilter applied to all requests via `com.eactive.eai.rms.common.filter.CrossScriptingFilter`
|
||||
- **Real-time Updates**: All management changes are reflected immediately in both DB and memory
|
||||
- **Instance Name**: Each deployment must have unique `inst.Name` for clustering
|
||||
- **Table Owner**: Oracle schema owner specified via `eai.tableowner` property
|
||||
@@ -3,6 +3,8 @@ package com.eactive.eai.custom;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
import com.eactive.eai.rms.data.PortalSchemaProviderHolder;
|
||||
import com.eactive.eai.rms.env.EmsConfig;
|
||||
import com.eactive.eai.transformer.message.ISO8583MessageFactory;
|
||||
|
||||
/**
|
||||
@@ -36,5 +38,8 @@ public class CustomizingAppInitializer implements InitializingBean {
|
||||
logger.info(String.format("ISO8583MessageFactory registered - %s = %s", MESSAGE_TYPE_SVL, ISO8583_SVL_CLASS_NAME));
|
||||
logger.info(String.format("ISO8583MessageFactory registered - %s = %s", LAYOUT_TYPE_H2H, ISO8583_H2H_CLASS_NAME));
|
||||
logger.info(String.format("ISO8583MessageFactory registered - %s = %s", LAYOUT_TYPE_SVL, ISO8583_SVL_CLASS_NAME));
|
||||
|
||||
// PortalSchemaProviderHolder 초기화 (eai.tableowner 주입)
|
||||
PortalSchemaProviderHolder.setProvider(() -> System.getProperty(EmsConfig.TABLE_OWNER));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
|
||||
import com.eactive.eai.rms.common.datasource.DataSourceType;
|
||||
import com.eactive.eai.rms.common.datasource.DataSourceTypeManager;
|
||||
import com.eactive.eai.rms.data.PortalSchemaProviderHolder;
|
||||
import com.eactive.eai.rms.env.EmsConfig;
|
||||
|
||||
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
|
||||
|
||||
@@ -23,6 +25,12 @@ public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor
|
||||
public void postProcessBeanFactory(ConfigurableListableBeanFactory factory)
|
||||
throws BeansException {
|
||||
|
||||
// PortalSchemaProviderHolder 초기화 (Hibernate EntityManagerFactory 생성 전에 필요)
|
||||
PortalSchemaProviderHolder.setProvider(() -> System.getProperty(EmsConfig.TABLE_OWNER));
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("PortalSchemaProviderHolder initialized with tableOwner: " + System.getProperty(EmsConfig.TABLE_OWNER));
|
||||
}
|
||||
|
||||
List<DataSourceType> dataSourceTypes = new ArrayList<DataSourceType>();
|
||||
|
||||
Map maps = factory.getBeansOfType(DataSourceType.class);
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
package com.eactive.eai.rms.common.startup;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
@@ -21,7 +18,7 @@ public class AppInitializer implements InitializingBean, DisposableBean {
|
||||
|
||||
private String tableOwner;
|
||||
|
||||
private String systemMode = "D"; //EAI System Mode : [P/T/D/S]
|
||||
private String systemMode = "D"; // EAI System Mode : [P/T/D/S]
|
||||
|
||||
private String themeColor = "black";
|
||||
|
||||
@@ -29,97 +26,99 @@ public class AppInitializer implements InitializingBean, DisposableBean {
|
||||
|
||||
private String eaiDatasourceType = "DEV"; // 데이터 소스 타입 :[DEV:개발/STG:스테이징/PRD:운영] ...NSG:내부서버
|
||||
|
||||
public void setInstName(String instName) {
|
||||
this.instName = instName;
|
||||
}
|
||||
public void setInstName(String instName) {
|
||||
this.instName = instName;
|
||||
}
|
||||
|
||||
public void setTableOwner(String tableOwner) {
|
||||
this.tableOwner = tableOwner;
|
||||
}
|
||||
public void setTableOwner(String tableOwner) {
|
||||
this.tableOwner = tableOwner;
|
||||
}
|
||||
|
||||
public void setSystemMode(String systemMode) {
|
||||
this.systemMode = systemMode;
|
||||
}
|
||||
public void setSystemMode(String systemMode) {
|
||||
this.systemMode = systemMode;
|
||||
}
|
||||
|
||||
public void setThemeColor(String themeColor) {
|
||||
this.themeColor = themeColor;
|
||||
}
|
||||
public void setThemeColor(String themeColor) {
|
||||
this.themeColor = themeColor;
|
||||
}
|
||||
|
||||
public void setDrMode(String drMode) {
|
||||
this.drMode = drMode;
|
||||
}
|
||||
public void setEaiDatasourceType(String eaiDatasourceType) {
|
||||
this.eaiDatasourceType = eaiDatasourceType;
|
||||
}
|
||||
public void setDrMode(String drMode) {
|
||||
this.drMode = drMode;
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
if (debug) {
|
||||
logger.debug("applicationInitialized");
|
||||
}
|
||||
//MS949로 default encoding 고정
|
||||
// System.setProperty("file.encoding","MS949");
|
||||
// Field charset = null;
|
||||
// try {
|
||||
// charset = Charset.class.getDeclaredField("defaultCharset");
|
||||
// charset.setAccessible(true);
|
||||
// charset.set(null, null);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
public void setEaiDatasourceType(String eaiDatasourceType) {
|
||||
this.eaiDatasourceType = eaiDatasourceType;
|
||||
}
|
||||
|
||||
// set default value
|
||||
String serverName = System.getProperty(EmsConfig.INST_NAME);
|
||||
if(serverName == null) {
|
||||
System.setProperty(EmsConfig.INST_NAME, instName);
|
||||
}
|
||||
private void init() {
|
||||
if (debug) {
|
||||
logger.debug("applicationInitialized");
|
||||
}
|
||||
// MS949로 default encoding 고정
|
||||
// System.setProperty("file.encoding","MS949");
|
||||
// Field charset = null;
|
||||
// try {
|
||||
// charset = Charset.class.getDeclaredField("defaultCharset");
|
||||
// charset.setAccessible(true);
|
||||
// charset.set(null, null);
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
String tOwner = System.getProperty(EmsConfig.TABLE_OWNER);
|
||||
if(tOwner == null) {
|
||||
System.setProperty(EmsConfig.TABLE_OWNER, tableOwner);
|
||||
}
|
||||
// set default value
|
||||
String serverName = System.getProperty(EmsConfig.INST_NAME);
|
||||
if (serverName == null) {
|
||||
System.setProperty(EmsConfig.INST_NAME, instName);
|
||||
}
|
||||
|
||||
// 서버 구분 설정(개발:D, 테스트:T, 온라인:P)
|
||||
CommonConstants.SERVER_TYPE = systemMode;
|
||||
String tOwner = System.getProperty(EmsConfig.TABLE_OWNER);
|
||||
if (tOwner == null) {
|
||||
System.setProperty(EmsConfig.TABLE_OWNER, tableOwner);
|
||||
}
|
||||
|
||||
//모니터링 테마 적용
|
||||
String tColor = System.getProperty(EmsConfig.THEME_COLOR);
|
||||
if(tColor == null || "".equals(tColor)) {
|
||||
System.setProperty(EmsConfig.THEME_COLOR, themeColor);
|
||||
}
|
||||
// 서버 구분 설정(개발:D, 테스트:T, 온라인:P)
|
||||
CommonConstants.SERVER_TYPE = systemMode;
|
||||
|
||||
if (debug) {
|
||||
logger.debug(EmsConfig.DR_MODE + " = " + drMode);
|
||||
}
|
||||
//env 프라퍼티 파일만 있음 dr 여부 셋팅
|
||||
System.setProperty(EmsConfig.DR_MODE, drMode);
|
||||
// 모니터링 테마 적용
|
||||
String tColor = System.getProperty(EmsConfig.THEME_COLOR);
|
||||
if (tColor == null || "".equals(tColor)) {
|
||||
System.setProperty(EmsConfig.THEME_COLOR, themeColor);
|
||||
}
|
||||
|
||||
//데이터 소스타입(DEV:개발 / STG:스테이징 / PRD:운영 ... )
|
||||
String eDatasourceType = System.getProperty(EmsConfig.DATASOURCE_TYPE);
|
||||
if(eDatasourceType == null || "".equals(eDatasourceType)) {
|
||||
System.setProperty(EmsConfig.DATASOURCE_TYPE, eaiDatasourceType);
|
||||
}
|
||||
if (debug) {
|
||||
logger.debug(EmsConfig.DR_MODE + " = " + drMode);
|
||||
}
|
||||
// env 프라퍼티 파일만 있음 dr 여부 셋팅
|
||||
System.setProperty(EmsConfig.DR_MODE, drMode);
|
||||
|
||||
if (debug) {
|
||||
logger.debug(EmsConfig.DATASOURCE_TYPE + " =" + eaiDatasourceType); //env 프라퍼티
|
||||
}
|
||||
// 데이터 소스타입(DEV:개발 / STG:스테이징 / PRD:운영 ... )
|
||||
String eDatasourceType = System.getProperty(EmsConfig.DATASOURCE_TYPE);
|
||||
if (eDatasourceType == null || "".equals(eDatasourceType)) {
|
||||
System.setProperty(EmsConfig.DATASOURCE_TYPE, eaiDatasourceType);
|
||||
}
|
||||
|
||||
if(debug) {
|
||||
logger.debug("SERVER_TYPE ="+CommonConstants.SERVER_TYPE);
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
logger.debug(EmsConfig.DATASOURCE_TYPE + " =" + eaiDatasourceType); // env 프라퍼티
|
||||
}
|
||||
|
||||
public void destroy()
|
||||
{
|
||||
AdapterStatusSendThreadPool.destroy();
|
||||
if(debug) {
|
||||
logger.debug("############ e-link WebApplication stopping... preStop ############");
|
||||
}
|
||||
}
|
||||
if (debug) {
|
||||
logger.debug("SERVER_TYPE =" + CommonConstants.SERVER_TYPE);
|
||||
}
|
||||
|
||||
if (debug) {
|
||||
logger.debug("PortalSchemaProviderHolder initialized with tableOwner: " + tableOwner);
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() {
|
||||
AdapterStatusSendThreadPool.destroy();
|
||||
if (debug) {
|
||||
logger.debug("############ e-link WebApplication stopping... preStop ############");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
init();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
import org.springframework.data.annotation.CreatedBy;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
|
||||
@@ -30,7 +31,20 @@ public class UserAthrRoleChgHistory extends AbstractEntity<String> implements Se
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
// @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@GenericGenerator(
|
||||
name = "TB_APIMS_USER_ATHR_ROLE_CHG_H_GEN",
|
||||
strategy = "com.eactive.eai.rms.data.jpa.SchemaPrefixedSequenceGenerator",
|
||||
parameters = {
|
||||
@org.hibernate.annotations.Parameter(name = "sequence_name", value = "TB_APIMS_USER_ATHR_ROLE_CHG_H_SEQ"),
|
||||
@org.hibernate.annotations.Parameter(name = "initial_value", value = "1"),
|
||||
@org.hibernate.annotations.Parameter(name = "increment_size", value = "1")
|
||||
}
|
||||
)
|
||||
@GeneratedValue(
|
||||
strategy = GenerationType.SEQUENCE,
|
||||
generator = "TB_APIMS_USER_ATHR_ROLE_CHG_H_GEN"
|
||||
)
|
||||
@Column(name = "CHG_LOG_ID", unique = true, nullable = false)
|
||||
@Comment("사용자 정보 변경 로그 식별 ID")
|
||||
private int chgLogId;
|
||||
|
||||
@@ -11,6 +11,7 @@ import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
import org.hibernate.annotations.Comment;
|
||||
import org.hibernate.annotations.GenericGenerator;
|
||||
import org.springframework.data.annotation.CreatedDate;
|
||||
|
||||
import com.eactive.eai.data.entity.AbstractEntity;
|
||||
@@ -30,7 +31,20 @@ public class UserLoginHistory extends AbstractEntity<String> implements Serializ
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
// @GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@GenericGenerator(
|
||||
name = "TB_APIMS_LOIN_L_GEN",
|
||||
strategy = "com.eactive.eai.rms.data.jpa.SchemaPrefixedSequenceGenerator",
|
||||
parameters = {
|
||||
@org.hibernate.annotations.Parameter(name = "sequence_name", value = "TB_APIMS_LOIN_L_GEN_SEQ"),
|
||||
@org.hibernate.annotations.Parameter(name = "initial_value", value = "1"),
|
||||
@org.hibernate.annotations.Parameter(name = "increment_size", value = "1")
|
||||
}
|
||||
)
|
||||
@GeneratedValue(
|
||||
strategy = GenerationType.SEQUENCE,
|
||||
generator = "TB_APIMS_LOIN_L_GEN"
|
||||
)
|
||||
@Column(name="LOIN_LOG_ID", unique = true, nullable = false)
|
||||
@Comment("로그인 로그 식별자")
|
||||
private int loginLogId;
|
||||
|
||||
@@ -37,5 +37,4 @@ public class CustomRevisionEntity {
|
||||
@Column(name = "USERID")
|
||||
@Comment("변경자ID")
|
||||
private String userId;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user