diff --git a/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java b/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java new file mode 100644 index 0000000..36adc9d --- /dev/null +++ b/src/main/java/com/eactive/eai/common/context/ElinkTransactionContext.java @@ -0,0 +1,99 @@ +package com.eactive.eai.common.context; + +import java.util.HashMap; +import java.util.Map; + +/** + * 트랜잭션 범위 컨텍스트 관리 + * - ThreadLocal 기반으로 현재 스레드의 트랜잭션 컨텍스트 관리 + * - Lazy initialization: 최초 put 시 자동 생성 + * - 비동기 전달: getAll()로 복사본 획득, restore()로 복원 + * + *
+ * [동기 거래]
+ * ApiAdapterController → ... → JEP 함수에서 set/get → ... → finally { clear() }
+ *
+ * [비동기 거래]
+ * 송신측: FlowRouter → eaiMessage.setTransactionContextTransfer(getAll()) → JMS Queue
+ * 수신측: Consumer → ElinkESBProcessProxy → restore(transfer) → JEP 함수 → clear()
+ * 
+ */ +public class ElinkTransactionContext { + + private static final ThreadLocal> THREAD_LOCAL = new ThreadLocal<>(); + + // Context Map Keys + private static final String KEY_SEED_SALT = "SEED_SALT"; + private static final String KEY_ENCRYPTION_KEY = "ENCRYPTION_KEY"; + + // ==================== 컨텍스트 관리 ==================== + + /** + * 컨텍스트 정리 (필수) + * - 동기: ApiAdapterController finally 블록에서 호출 + * - 비동기: ElinkESBProcessProxy finally 블록에서 호출 + */ + public static void clear() { + THREAD_LOCAL.remove(); + } + + /** + * 비동기 전달용 컨텍스트 복사본 반환 + * - FlowRouter에서 JMS 송신 전 호출 + * - 컨텍스트가 없으면 null 반환 + */ + public static Map getAll() { + Map ctx = THREAD_LOCAL.get(); + return ctx != null ? new HashMap<>(ctx) : null; + } + + /** + * 비동기 수신 시 컨텍스트 복원 + * - ElinkESBProcessProxy에서 비동기 거래 처리 시작 시 호출 + */ + public static void restore(Map transferContext) { + if (transferContext != null && !transferContext.isEmpty()) { + THREAD_LOCAL.set(new HashMap<>(transferContext)); + } + } + + // ==================== 내부 헬퍼 ==================== + + private static Map getOrCreate() { + Map ctx = THREAD_LOCAL.get(); + if (ctx == null) { + ctx = new HashMap<>(); + THREAD_LOCAL.set(ctx); + } + return ctx; + } + + private static void put(String key, Object value) { + if (value != null) { + getOrCreate().put(key, value); + } + } + + private static String get(String key) { + Map ctx = THREAD_LOCAL.get(); + return ctx != null ? (String) ctx.get(key) : null; + } + + // ==================== 명시적 변수 접근자 ==================== + + public static void setSeedSalt(String seedSalt) { + put(KEY_SEED_SALT, seedSalt); + } + + public static String getSeedSalt() { + return get(KEY_SEED_SALT); + } + + public static void setEncryptionKey(String encryptionKey) { + put(KEY_ENCRYPTION_KEY, encryptionKey); + } + + public static String getEncryptionKey() { + return get(KEY_ENCRYPTION_KEY); + } +}