diff --git a/build.gradle b/build.gradle index 7f90ea0..de5348c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,9 +1,10 @@ plugins { - id 'java-library' + id 'java-library' id 'eclipse' - id 'eclipse-wtp' + id 'eclipse-wtp' id 'idea' id 'war' + id 'com.diffplug.eclipse.apt' version '3.41.1' } group 'com.eactive' @@ -31,11 +32,11 @@ allprojects { project.webAppDirName = 'WebContent' java { - toolchain { - languageVersion = JavaLanguageVersion.of(8) - } + toolchain { + languageVersion = JavaLanguageVersion.of(8) + } } - + sourceSets { main { java { @@ -45,56 +46,56 @@ sourceSets { } compileJava { - options.encoding = 'UTF-8' - options.compilerArgs = ['-parameters'] - options.generatedSourceOutputDirectory = project.file(generatedJavaDir) + options.encoding = 'UTF-8' + options.compilerArgs = ['-parameters'] + options.generatedSourceOutputDirectory = project.file(generatedJavaDir) + + aptOptions { + processorArgs = [ 'querydsl.generatedAnnotationClass' : 'com.querydsl.core.annotations.Generated' ] + } } 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' - exclude '**/context-*.xml' - archiveFileName = "eapim-admin.war" - duplicatesStrategy = DuplicatesStrategy.WARN + 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' + exclude '**/context-*.xml' + archiveFileName = "eapim-admin.war" + duplicatesStrategy = DuplicatesStrategy.WARN } tasks.withType(JavaCompile) { - options.encoding = 'UTF-8' - options.compilerArgs += ['-parameters', "-Xlint:unchecked", "-Xlint:deprecation"] + 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" - + + 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-djb") + implementation project(':elink-online-emsclient') + implementation project(':elink-portal-common') + //implementation project(':kjb-safedb') + //implementation project(":eapim-admin-djb") /* Custom Libs (damo-manager.jar 는 Tomcat lib 가 런타임 제공 → compileOnly, WAR 미포함) */ implementation fileTree(dir: 'libs', include: ['*.jar'], exclude: ['damo-manager.jar']) compileOnly files('libs/damo-manager.jar') - //implementation "org.dom4j:dom4j:2.1.3" + //implementation "org.dom4j:dom4j:2.1.3" //implementation "com.rabbitmq:amqp-client:3.6.6" implementation "commons-primitives:commons-primitives:1.0" @@ -116,10 +117,10 @@ dependencies { // 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 '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" @@ -186,32 +187,32 @@ dependencies { 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 files("libs/eai-bap-client.jar") + implementation group: 'commons-net', name: 'commons-net', version: '3.5' - compileOnly 'javax.xml.bind:jaxb-api:2.3.1' + // JDK 8 의 rt.jar 에는 org.w3c.dom.ElementTraversal 이 없어 xercesImpl 가 NCDFE 를 일으킴. + // xml-apis 1.4.01 에 그 클래스가 포함됨. 직접 의존성으로 묶어 WAR 에 패키징되도록 함. + implementation 'xml-apis:xml-apis:1.4.01' - //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 group: 'commons-net', name: 'commons-net', version: '3.5' - - // JDK 8 의 rt.jar 에는 org.w3c.dom.ElementTraversal 이 없어 xercesImpl 가 NCDFE 를 일으킴. - // xml-apis 1.4.01 에 그 클래스가 포함됨. 직접 의존성으로 묶어 WAR 에 패키징되도록 함. - implementation 'xml-apis:xml-apis:1.4.01' - - 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' + 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 { @@ -219,9 +220,9 @@ test { } configurations.all { - exclude group: 'log4j', module: 'log4j' - exclude group: 'org.apache.activemq' - exclude group: 'org.codehaus.jackson' + 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' @@ -245,25 +246,29 @@ task settingEclipseEncoding { } task initDirs() { - file(generatedJavaDir).mkdirs() + file(generatedJavaDir).mkdirs() } eclipse { - wtp { - component { - contextPath = 'monitoring' - } - } - synchronizationTasks settingEclipseEncoding, initDirs - jdt { - - } - project { - if (!natures.contains('org.eclipse.buildship.core.gradleprojectnature')) { - natures.add('org.eclipse.buildship.core.gradleprojectnature') - buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder' - } - } + wtp { + component { + contextPath = 'monitoring' + } + } + synchronizationTasks settingEclipseEncoding, initDirs + jdt { + apt { + // generated 된 패스 경로를 .setting/org.eclipse.jdt.apt.core.prefs 의 org.eclipse.jdt.apt.genSrcDir에 적용한다. + // project > properties > Java Compiler > Annoation Processing 화면에서 확인 가능하다. + genSrcDir = file(generatedJavaDir) + } + } + project { + if (!natures.contains('org.eclipse.buildship.core.gradleprojectnature')) { + natures.add('org.eclipse.buildship.core.gradleprojectnature') + buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder' + } + } } tasks.withType(JavaCompile) { diff --git a/settings.gradle b/settings.gradle index 3656dda..9753534 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,7 +7,7 @@ include 'elink-online-common' include 'elink-online-emsclient' include 'elink-portal-common' //include 'kjb-safedb' -include 'eapim-admin-djb' +//include 'eapim-admin-djb' project (':elink-online-core-jpa').projectDir = new File(settingsDir, "../eapim-online/elink-online-core-jpa") project (':elink-online-core').projectDir = new File(settingsDir, "../eapim-online/elink-online-core") @@ -16,4 +16,4 @@ project (':elink-online-common').projectDir = new File(settingsDir, "../eapim-on project (':elink-online-emsclient').projectDir = new File(settingsDir, "../eapim-online/elink-online-emsclient") project (':elink-portal-common').projectDir = new File(settingsDir, "../elink-portal-common") //project (':kjb-safedb').projectDir = new File(settingsDir, "../kjb-safedb") -project (':eapim-admin-djb').projectDir = new File(settingsDir, "../eapim-admin-djb") \ No newline at end of file +//project (':eapim-admin-djb').projectDir = new File(settingsDir, "../eapim-admin-djb") \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/rms/common/context/MonitoringContextImpl.java b/src/main/java/com/eactive/eai/rms/common/context/MonitoringContextImpl.java index a4a6e68..cb67ded 100644 --- a/src/main/java/com/eactive/eai/rms/common/context/MonitoringContextImpl.java +++ b/src/main/java/com/eactive/eai/rms/common/context/MonitoringContextImpl.java @@ -21,8 +21,8 @@ import com.eactive.eai.rms.common.util.ContainerUtil; import com.eactive.eai.rms.data.entity.man.monitoringProperty.MonitoringPropertyId; import com.eactive.eai.rms.data.entity.man.monitoringProperty.service.MonitoringPropertyGroupService; import com.eactive.eai.rms.data.entity.man.monitoringProperty.service.MonitoringPropertyService; -import com.eactive.ext.kjb.common.KjbPropertyHolder; -import com.eactive.ext.kjb.util.KjbPropertyInjector; +import com.eactive.eai.rms.ext.djb.common.DjbPropertyHolder; +import com.eactive.eai.rms.ext.djb.common.DjbPropertyInjector; @Service("monitoringContext") @Transactional(transactionManager = "transactionManagerForEMS") @@ -45,7 +45,7 @@ class MonitoringContextImpl implements MonitoringContext { public void refresh() { init(); - KjbPropertyHolder.reload(); + DjbPropertyHolder.reload(); } public void refresh(String propName) { @@ -85,9 +85,9 @@ class MonitoringContextImpl implements MonitoringContext { setPortMapper(monitoringContextDAO.getPortMap()); - // KjbPropertyHolder 초기화 - KjbPropertyInjector injector = new KjbPropertyInjector(monitoringPropertyService, "Monitoring"); - KjbPropertyHolder.initialize(injector::inject); + // DjbPropertyHolder 초기화 + DjbPropertyInjector injector = new DjbPropertyInjector(monitoringPropertyService, "Monitoring"); + DjbPropertyHolder.initialize(injector::inject); logger.info("SSO AgentId : " + System.getProperty(EAI_AGENTID)); diff --git a/src/main/java/com/eactive/eai/rms/common/login/MainController.java b/src/main/java/com/eactive/eai/rms/common/login/MainController.java index 78f7a2d..e96c05a 100644 --- a/src/main/java/com/eactive/eai/rms/common/login/MainController.java +++ b/src/main/java/com/eactive/eai/rms/common/login/MainController.java @@ -32,7 +32,6 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.servlet.View; import com.eactive.eai.common.seed.Seed; -import com.eactive.eai.rms.ext.kjb.smsauth.SmsAuthService; import com.eactive.ext.djb.DamoManager; import com.eactive.eai.data.converter.LocalDateTimeFormatters; import com.eactive.eai.rms.common.context.MonitoringContext; @@ -51,6 +50,7 @@ import com.eactive.eai.rms.data.entity.man.user.UserLoginHistoryService; import com.eactive.eai.rms.data.entity.man.user.UserRole; import com.eactive.eai.rms.data.entity.man.user.UserRoleService; import com.eactive.eai.rms.data.entity.man.user.UserServiceTypeService; +import com.eactive.eai.rms.ext.djb.smsauth.SmsAuthService; @Controller public class MainController implements InterceptorSkipController { diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbProperty.java b/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbProperty.java new file mode 100644 index 0000000..b6cbd00 --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbProperty.java @@ -0,0 +1,121 @@ +package com.eactive.eai.rms.ext.djb.common; + +import lombok.Data; +import org.hibernate.validator.constraints.NotEmpty; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.Pattern; + +@Data +public class DjbProperty { + + // SMS 2차 인증 + + @DjbPropertyValue( + key = "djb.sms_auth.enabled", + defaultValue = "true", + description = "SMS 2차 인증 사용 여부. true 시 휴대폰번호 없는 사용자는 ID/PW 로그인 불가") + private boolean smsAuthEnabled = false; + + @DjbPropertyValue( + key = "djb.sms_auth.mode", + defaultValue = "real", + description = "인증번호 생성 모드: real(랜덤), hhmm00(현재시각+00), fixed(고정값)") + @Pattern(regexp = "^(real|hhmm00|fixed)$", message = "djb.sms_auth.mode는 real, hhmm00, fixed 중 하나여야 합니다.") + private String smsAuthMode = "real"; + + @DjbPropertyValue( + key = "djb.sms_auth.fixed_value", + defaultValue = "654321", + description = "mode가 fixed일 때 사용할 고정 인증번호 (6자리 숫자)") + @Pattern(regexp = "^\\d{6}$", message = "djb.sms_auth.fixed_value는 6자리 숫자여야 합니다.") + private String smsAuthFixedValue = "654321"; + + + @DjbPropertyValue( + key = "djb.api.allow_ip_list", + description = "API 접근 허용 IP 목록 (콤마(,)로 구분된 IP들, 예: 192.168.0.1, 192.168.1.*,127.*.*.*", + defaultValue = "10.15.106.*, 10.14.8.*, 10.15.8.*, 192.168.240.*, 127.0.0.1, 192.168.132.*, 192.168.131.*" + ) + private String apiAllowIpList = "10.15.106.*, 10.14.8.*, 10.15.8.*, 192.168.240.*, 127.0.0.1, 192.168.132.*, 192.168.131.*"; + + @DjbPropertyValue( + key = "djb.api_gw_metric.page_size", + description = "API GW Metric 조회시 페이지 크기 설정 (Integer, 0 = 무한, 기본값 10000)", + defaultValue = "10000" + ) + private Integer apiGwMetricPageSize = 10000; + + + + public String toJsonString(boolean isPretty) { + return isPretty + ? new GsonBuilder().setPrettyPrinting().create().toJson(this) + : new Gson().toJson(this); + } + + + // 기본 프로퍼티 목록을 콘솔로 출력 (가이드용) + public static void main(String[] args) { + System.out.println("| Key | Default Value | Description |"); + System.out.println("|-----|---------------|-------------|"); + + for (java.lang.reflect.Field field : DjbProperty.class.getDeclaredFields()) { + DjbPropertyValue annotation = field.getAnnotation(DjbPropertyValue.class); + if (annotation != null) { + String key = annotation.key(); + String defaultValue = annotation.defaultValue(); + String description = annotation.description(); + System.out.printf("| %s | %s | %s |%n", key, defaultValue, description); + } + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbPropertyHolder.java b/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbPropertyHolder.java new file mode 100644 index 0000000..d5f1ead --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbPropertyHolder.java @@ -0,0 +1,92 @@ +package com.eactive.eai.rms.ext.djb.common; + +import lombok.extern.slf4j.Slf4j; + +import java.util.function.Function; + +/** + * DjbProperty 싱글톤 홀더. + * + *

모든 곳에서 {@code DjbPropertyHolder.get()}으로 현재 DjbProperty에 접근합니다. + * eapim-admin에서 초기화 시 {@code initialize()}를 호출하고, + * MonitoringContext.refresh() 시 {@code reload()}를 호출하여 값을 갱신합니다.

+ * + *

사용 예시:

+ *
+ * // 값 접근
+ * String url = DjbPropertyHolder.get().getUmsHostUrl();
+ *
+ * // 초기화 (eapim-admin에서)
+ * DjbPropertyInjector injector = new DjbPropertyInjector(service, "Monitoring");
+ * DjbPropertyHolder.initialize(injector::inject);
+ *
+ * // reload (MonitoringContext.refresh() 시)
+ * DjbPropertyHolder.reload();
+ *
+ * // 테스트용
+ * DjbPropertyHolder.setForTest(mockProperty);
+ * 
+ */ +@Slf4j +public class DjbPropertyHolder { + + private static volatile DjbProperty instance = new DjbProperty(); + private static volatile Function injector; + + private DjbPropertyHolder() { + // 유틸리티 클래스 + } + + /** + * 현재 DjbProperty 인스턴스를 반환합니다. + */ + public static DjbProperty get() { + return instance; + } + + /** + * 초기화 함수를 등록하고 최초 로딩을 수행합니다. + * eapim-admin 부팅 시 MonitoringContextImpl.init()에서 호출됩니다. + * + * @param injectorFn DjbProperty를 DB에서 로딩하는 함수 (DjbPropertyInjector::inject) + */ + public static void initialize(Function injectorFn) { + injector = injectorFn; + reload(); + log.info("DjbPropertyHolder 초기화 완료"); + } + + /** + * DB에서 프로퍼티를 다시 로딩합니다. + * MonitoringContext.refresh() 호출 시 함께 호출됩니다. + */ + public static void reload() { + if (injector != null) { + try { + instance = injector.apply(new DjbProperty()); + log.info("DjbProperty reload 완료"); + } catch (Exception e) { + log.error("DjbProperty reload 실패: {}", e.getMessage(), e); + } + } else { + log.debug("DjbPropertyHolder: injector가 설정되지 않음 (테스트 환경일 수 있음)"); + } + } + + /** + * 테스트용 - 직접 인스턴스를 설정합니다. + */ + public static void setForTest(DjbProperty testProperty) { + instance = testProperty; + log.debug("DjbProperty 테스트 인스턴스 설정"); + } + + /** + * 테스트용 - 기본값으로 초기화합니다. + */ + public static void resetForTest() { + instance = new DjbProperty(); + injector = null; + log.debug("DjbPropertyHolder 테스트 초기화"); + } +} diff --git a/src/main/java/com/eactive/ext/kjb/util/KjbPropertyInjector.java b/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbPropertyInjector.java similarity index 76% rename from src/main/java/com/eactive/ext/kjb/util/KjbPropertyInjector.java rename to src/main/java/com/eactive/eai/rms/ext/djb/common/DjbPropertyInjector.java index 8d2dfb5..3d61fb5 100644 --- a/src/main/java/com/eactive/ext/kjb/util/KjbPropertyInjector.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbPropertyInjector.java @@ -1,10 +1,8 @@ -package com.eactive.ext.kjb.util; +package com.eactive.eai.rms.ext.djb.common; import com.eactive.eai.rms.data.entity.man.monitoringProperty.MonitoringProperty; import com.eactive.eai.rms.data.entity.man.monitoringProperty.MonitoringPropertyId; import com.eactive.eai.rms.data.entity.man.monitoringProperty.service.MonitoringPropertyService; -import com.eactive.ext.kjb.common.KjbProperty; -import com.eactive.ext.kjb.common.KjbPropertyValue; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; @@ -12,52 +10,49 @@ import java.lang.reflect.Field; import java.util.Optional; @Slf4j -public class KjbPropertyInjector { +public class DjbPropertyInjector { private final MonitoringPropertyService monitoringPropertyService; private final String groupId; - public KjbPropertyInjector(MonitoringPropertyService monitoringPropertyService, String groupId) { + public DjbPropertyInjector(MonitoringPropertyService monitoringPropertyService, String groupId) { this.monitoringPropertyService = monitoringPropertyService; this.groupId = groupId; } /** - * KjbProperty의 URL 값들이 설정되어 있는지 확인 - * @param property 검사할 KjbProperty 객체 + * DjbProperty의 URL 값들이 설정되어 있는지 확인 + * @param property 검사할 DjbProperty 객체 * @return URL 값들이 모두 설정되어 있으면 true */ - public boolean isUrlConfigured(KjbProperty property) { + public boolean isUrlConfigured(DjbProperty property) { if (property == null) return false; - // 주요 URL 값들 중 하나라도 설정되어 있으면 true - return StringUtils.isNotEmpty(property.getEaiBatchUrl()) - || StringUtils.isNotEmpty(property.getUmsHostUrl()) - || StringUtils.isNotEmpty(property.getObpUrl()); + return StringUtils.isNotEmpty(property.getApiAllowIpList()); } /** * URL 값이 비어있을 경우 DB에서 재로딩 시도 - * @param property 기존 KjbProperty 객체 - * @return 재로딩된 KjbProperty 객체 (재로딩 실패 시 기존 객체 반환) + * @param property 기존 DjbProperty 객체 + * @return 재로딩된 DjbProperty 객체 (재로딩 실패 시 기존 객체 반환) */ - public KjbProperty reloadIfUrlEmpty(KjbProperty property) { + public DjbProperty reloadIfUrlEmpty(DjbProperty property) { if (property == null) { - return inject(new KjbProperty()); + return inject(new DjbProperty()); } if (!isUrlConfigured(property)) { - log.info("KjbProperty URL 값이 비어있어 DB에서 재로딩 시도"); + log.info("DjbProperty URL 값이 비어있어 DB에서 재로딩 시도"); try { - KjbProperty reloaded = inject(new KjbProperty()); + DjbProperty reloaded = inject(new DjbProperty()); if (isUrlConfigured(reloaded)) { - log.info("KjbProperty 재로딩 성공"); + log.info("DjbProperty 재로딩 성공"); return reloaded; } else { - log.warn("KjbProperty 재로딩 후에도 URL 값이 비어있음"); + log.warn("DjbProperty 재로딩 후에도 URL 값이 비어있음"); } } catch (Exception e) { - log.error("KjbProperty 재로딩 실패: {}", e.getMessage(), e); + log.error("DjbProperty 재로딩 실패: {}", e.getMessage(), e); } } @@ -68,7 +63,7 @@ public class KjbPropertyInjector { Class clazz = property.getClass(); for (Field field : clazz.getDeclaredFields()) { - KjbPropertyValue anno = field.getAnnotation(KjbPropertyValue.class); + DjbPropertyValue anno = field.getAnnotation(DjbPropertyValue.class); if (anno != null) { String key = anno.key(); diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbPropertyValue.java b/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbPropertyValue.java new file mode 100644 index 0000000..a1e6393 --- /dev/null +++ b/src/main/java/com/eactive/eai/rms/ext/djb/common/DjbPropertyValue.java @@ -0,0 +1,14 @@ +package com.eactive.eai.rms.ext.djb.common; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface DjbPropertyValue { + String key(); + String defaultValue() default ""; + String description() default ""; +} diff --git a/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthController.java b/src/main/java/com/eactive/eai/rms/ext/djb/smsauth/SmsAuthController.java similarity index 99% rename from src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthController.java rename to src/main/java/com/eactive/eai/rms/ext/djb/smsauth/SmsAuthController.java index 73aa5ba..cf49ca4 100644 --- a/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthController.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/smsauth/SmsAuthController.java @@ -1,4 +1,4 @@ -package com.eactive.eai.rms.ext.kjb.smsauth; +package com.eactive.eai.rms.ext.djb.smsauth; import com.eactive.apim.portal.user.entity.UserInfo; import com.eactive.eai.rms.common.interceptor.InterceptorSkipController; diff --git a/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthDto.java b/src/main/java/com/eactive/eai/rms/ext/djb/smsauth/SmsAuthDto.java similarity index 95% rename from src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthDto.java rename to src/main/java/com/eactive/eai/rms/ext/djb/smsauth/SmsAuthDto.java index 3944255..ac89b23 100644 --- a/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthDto.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/smsauth/SmsAuthDto.java @@ -1,4 +1,4 @@ -package com.eactive.eai.rms.ext.kjb.smsauth; +package com.eactive.eai.rms.ext.djb.smsauth; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthService.java b/src/main/java/com/eactive/eai/rms/ext/djb/smsauth/SmsAuthService.java similarity index 94% rename from src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthService.java rename to src/main/java/com/eactive/eai/rms/ext/djb/smsauth/SmsAuthService.java index 187784e..73ef754 100644 --- a/src/main/java/com/eactive/eai/rms/ext/kjb/smsauth/SmsAuthService.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/smsauth/SmsAuthService.java @@ -1,4 +1,4 @@ -package com.eactive.eai.rms.ext.kjb.smsauth; +package com.eactive.eai.rms.ext.djb.smsauth; import java.security.SecureRandom; import java.time.LocalDateTime; @@ -13,11 +13,9 @@ import org.springframework.stereotype.Service; import com.eactive.apim.portal.template.entity.MessageCode; import com.eactive.apim.portal.user.entity.UserInfo; import com.eactive.eai.rms.common.login.LoginVo; +import com.eactive.eai.rms.ext.djb.common.DjbProperty; +import com.eactive.eai.rms.ext.djb.common.DjbPropertyHolder; import com.eactive.eai.rms.ext.djb.ums.UmsManager; -import com.eactive.ext.kjb.common.KjbProperty; -import com.eactive.ext.kjb.common.KjbPropertyHolder; -import com.eactive.ext.kjb.common.KjbUmsException; -import com.eactive.ext.kjb.ums.KjbUmsService; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -46,13 +44,11 @@ public class SmsAuthService { private final UmsManager ums; - private static KjbProperty getProperty() { - return KjbPropertyHolder.get(); + private static DjbProperty getProperty() { + return DjbPropertyHolder.get(); } - private KjbUmsService getUmsService() { - return KjbUmsService.getInstance(); - } + /** * SMS 인증이 필요한지 확인 @@ -86,7 +82,7 @@ public class SmsAuthService { * 인증번호 생성 */ public String generateAuthCode() { - KjbProperty prop = getProperty(); + DjbProperty prop = getProperty(); String mode = prop.getSmsAuthMode(); if (MODE_FIXED.equalsIgnoreCase(mode)) { @@ -113,7 +109,7 @@ public class SmsAuthService { HashMap params = new HashMap(); params.put("authNumber", authCode); params.put("userName", userInfo.getUsername()); -log.debug("\n\n\nDDDDDDDDD" + userInfo.toString()); + ums.send(userInfo, MessageCode.ADMIN_VERIFICATION_MOBILEPHONE, params); return true; } catch (Exception e) { diff --git a/src/main/java/com/eactive/eai/rms/ext/djb/ums/service/UmsService.java b/src/main/java/com/eactive/eai/rms/ext/djb/ums/service/UmsService.java index df534fa..8d1062c 100644 --- a/src/main/java/com/eactive/eai/rms/ext/djb/ums/service/UmsService.java +++ b/src/main/java/com/eactive/eai/rms/ext/djb/ums/service/UmsService.java @@ -248,15 +248,15 @@ public class UmsService { // 이메일 데이터 EmailDataVO dataVO = new EmailDataVO(); - dataVO.setUms_evnt_id(""); // UMS이벤트ID(필수) + dataVO.setUms_evnt_id(""); // TODO: UMS이벤트ID(필수) dataVO.setSnd_dman_dt(jsonData[0]); dataVO.setSnd_dman_id(""); dataVO.setSnd_dman_sno("1"); dataVO.setEmail_titl(messageRequest.getSubject()); // 메일제목 - dataVO.setCstno(""); // 고객번호(필수) - dataVO.setSendr_emaddr(""); // 발신자 이메일 - dataVO.setSendr_nm(""); // 발신자 이름 - dataVO.setSndbk_emaddr(""); // 리턴 이메일 + dataVO.setCstno(""); // TODO: 고객번호(필수) + dataVO.setSendr_emaddr(""); // TODO: 발신자 이메일 + dataVO.setSendr_nm(""); // TODO: 발신자 이름 + dataVO.setSndbk_emaddr(""); // TODO: 리턴 이메일 dataVO.setRecvr_emaddr(messageRequest.getEmail()); // 수신자 이메일(필수) dataVO.setRecvr_nm(messageRequest.getUsername()); // 수신자명(필수) dataVO.setTmplt_mpng_info(messageRequest.getMessage()); // 탬플릿매핑정보 @@ -266,8 +266,8 @@ public class UmsService { dataVO.setBzwk_cd(BZWK_DVCD); // 업무구분코드 dataVO.setSub_bzwk_cd(SUB_BZWK_CD); // 업무세부코드 dataVO.setSys_dvcd(SYS_DVCD); - dataVO.setTx_dt(jsonData[0]); //거래일자 - dataVO.setTx_tktm(jsonData[1].substring(0,6)); //거래시간 + dataVO.setTx_dt(jsonData[0]); // 거래일자 + dataVO.setTx_tktm(jsonData[1].substring(0,6)); // 거래시간 List dataList = new ArrayList(); dataList.add(dataVO); diff --git a/src/main/java/com/eactive/eai/rms/ext/kjb/sso/SsoController.java b/src/main/java/com/eactive/eai/rms/ext/kjb/sso/SsoController.java index 5789cb3..a042729 100644 --- a/src/main/java/com/eactive/eai/rms/ext/kjb/sso/SsoController.java +++ b/src/main/java/com/eactive/eai/rms/ext/kjb/sso/SsoController.java @@ -14,9 +14,9 @@ import com.eactive.eai.rms.data.entity.man.user.UserRoleId; import com.eactive.eai.rms.data.entity.man.user.UserRoleService; import com.eactive.eai.rms.data.entity.man.user.UserServiceTypeService; import com.eactive.eai.rms.onl.apim.masking.MaskingUtils; -import com.eactive.ext.kjb.common.KjbProperty; -import com.eactive.ext.kjb.common.KjbPropertyHolder; -import com.eactive.ext.kjb.sso.KjbSsoModule; +//import com.eactive.ext.kjb.common.KjbProperty; +//import com.eactive.ext.kjb.common.KjbPropertyHolder; +//import com.eactive.ext.kjb.sso.KjbSsoModule; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Controller; @@ -52,108 +52,108 @@ public class SsoController implements InterceptorSkipController { this.mainController = mainController; } - private KjbSsoModule getSsoModule() { - return KjbSsoModule.getInstance(); - } +// private KjbSsoModule getSsoModule() { +// return KjbSsoModule.getInstance(); +// } +// +// private KjbProperty getProperty() { +// return KjbPropertyHolder.get(); +// } - private KjbProperty getProperty() { - return KjbPropertyHolder.get(); - } - - @RequestMapping(value = "/sso/login.do") - public String login(HttpServletRequest req, HttpServletResponse res, - @RequestParam(name = "UURL", required = false) String uurl) throws Exception { - HttpSession session = req.getSession(); - String ssoId = getSsoModule().getSsoId(req); - - log.debug("ssoId : {}", ssoId); - log.debug("uurl : {}", uurl); - - // 디버깅용 쿠키 목록 출력 - if (log.isDebugEnabled()) { - Cookie[] cookies = req.getCookies(); - if (cookies == null || cookies.length == 0) { - log.debug("No cookies"); - } else { - for (Cookie c : cookies) { - log.debug("Cookie[{}] : Domain={}, Path={}", - c.getName(), c.getDomain(), c.getPath()); - } - } - } - - if (StringUtils.isEmpty(uurl)) { - uurl = getSsoModule().getAscpUrl(); - log.debug("UURL is empty, set to ASCP URL"); - log.debug("uurl : {}", uurl); - } - - if (ssoId == null) { - getSsoModule().goLoginPage(res, uurl); - return null; - } else { - // EAM 세션 검증 - String retCode = getSsoModule().getEamSessionCheck(req, res); - log.debug("retCode : {}", retCode); - - log.debug("Property - sso.ignore_validation = {}", getProperty().isSsoIgnoreValidation()); - if (!getProperty().isSsoIgnoreValidation() && !"0".equalsIgnoreCase(retCode)) { - // SSO 검증 실패 시 에러 메시지 설정 및 로그인 페이지로 이동 - log.warn("SSO 검증 실패 - retCode: {}, ssoId: {}", retCode, ssoId); - session.setAttribute("resultMsg", "SSO 로그인을 실패 하였습니다. (오류코드: " + retCode + ") 다른 로그인 방식을 시도 하세요"); - return "redirect:/loginForm.do"; - } - - if (StringUtils.isEmpty(ssoId)) { - session.setAttribute("resultMsg", "SSO 인증 정보를 획득하지 못했습니다."); - return "redirect:/loginForm.do"; - } - - if (getProperty().isSsoSyncInfo()) { - // 기본 정보 - Properties info = getSsoModule().getUserInfos(ssoId); - // 확장 정보 - Properties extendedInfo = getSsoModule().getUserExFields(ssoId); - - // 필수 필드 검증 - try { - validateRequiredFields(info, extendedInfo); - } catch (IllegalStateException e) { - log.warn("SSO 필수 필드 검증 실패: {}", e.getMessage()); - session.setAttribute("resultMsg", e.getMessage()); - return "redirect:/loginForm.do"; - } - - // 사용자 정보 로깅 (개인정보 마스킹 처리) - String userId = info.getProperty("USERID"); - String name = info.getProperty("NAME"); - String email = info.getProperty("EMAIL"); - String cellPhoneNo = extendedInfo != null ? extendedInfo.getProperty("CELLPHONENO") : null; - - log.info("SSO 로그인 시도 - userId: {}", userId); - log.debug("SSO 사용자 정보 - userId: {}, name: {}, phone: {}, email: {}", - userId, - MaskingUtils.maskName(name), - MaskingUtils.maskPhoneNumber(cellPhoneNo), - MaskingUtils.maskEmailId(email)); - - // 사용자 생성 또는 업데이트 - UserInfo userInfo = findOrCreateUser(info, extendedInfo); - - // 로그인 세션 설정 (MainController 위임) - log.info("SSO 로그인 성공 - userId: {}", userId); - return mainController.setupSsoLoginSession(req, userInfo); - } else { - // 동기화 비활성화 모드: 기존 사용자는 업데이트 없이, 신규 사용자는 최소 정보로 생성 - log.info("SSO 동기화 비활성화 모드로 로그인 처리 - ssoId: {}", ssoId); - - UserInfo userInfo = findOrCreateUserWithoutSync(ssoId); - - log.info("SSO 로그인 성공 (동기화 비활성화 모드) - userId: {}", ssoId); - return mainController.setupSsoLoginSession(req, userInfo); - } - } - } +// @RequestMapping(value = "/sso/login.do") +// public String login(HttpServletRequest req, HttpServletResponse res, +// @RequestParam(name = "UURL", required = false) String uurl) throws Exception { +// HttpSession session = req.getSession(); +// String ssoId = getSsoModule().getSsoId(req); +// +// log.debug("ssoId : {}", ssoId); +// log.debug("uurl : {}", uurl); +// +// // 디버깅용 쿠키 목록 출력 +// if (log.isDebugEnabled()) { +// Cookie[] cookies = req.getCookies(); +// if (cookies == null || cookies.length == 0) { +// log.debug("No cookies"); +// } else { +// for (Cookie c : cookies) { +// log.debug("Cookie[{}] : Domain={}, Path={}", +// c.getName(), c.getDomain(), c.getPath()); +// } +// } +// } +// +// if (StringUtils.isEmpty(uurl)) { +// uurl = getSsoModule().getAscpUrl(); +// log.debug("UURL is empty, set to ASCP URL"); +// log.debug("uurl : {}", uurl); +// } +// +// if (ssoId == null) { +// getSsoModule().goLoginPage(res, uurl); +// return null; +// } else { +// // EAM 세션 검증 +// String retCode = getSsoModule().getEamSessionCheck(req, res); +// log.debug("retCode : {}", retCode); +// +// log.debug("Property - sso.ignore_validation = {}", getProperty().isSsoIgnoreValidation()); +// if (!getProperty().isSsoIgnoreValidation() && !"0".equalsIgnoreCase(retCode)) { +// // SSO 검증 실패 시 에러 메시지 설정 및 로그인 페이지로 이동 +// log.warn("SSO 검증 실패 - retCode: {}, ssoId: {}", retCode, ssoId); +// session.setAttribute("resultMsg", "SSO 로그인을 실패 하였습니다. (오류코드: " + retCode + ") 다른 로그인 방식을 시도 하세요"); +// return "redirect:/loginForm.do"; +// } +// +// if (StringUtils.isEmpty(ssoId)) { +// session.setAttribute("resultMsg", "SSO 인증 정보를 획득하지 못했습니다."); +// return "redirect:/loginForm.do"; +// } +// +// if (getProperty().isSsoSyncInfo()) { +// // 기본 정보 +// Properties info = getSsoModule().getUserInfos(ssoId); +// // 확장 정보 +// Properties extendedInfo = getSsoModule().getUserExFields(ssoId); +// +// // 필수 필드 검증 +// try { +// validateRequiredFields(info, extendedInfo); +// } catch (IllegalStateException e) { +// log.warn("SSO 필수 필드 검증 실패: {}", e.getMessage()); +// session.setAttribute("resultMsg", e.getMessage()); +// return "redirect:/loginForm.do"; +// } +// +// // 사용자 정보 로깅 (개인정보 마스킹 처리) +// String userId = info.getProperty("USERID"); +// String name = info.getProperty("NAME"); +// String email = info.getProperty("EMAIL"); +// String cellPhoneNo = extendedInfo != null ? extendedInfo.getProperty("CELLPHONENO") : null; +// +// log.info("SSO 로그인 시도 - userId: {}", userId); +// log.debug("SSO 사용자 정보 - userId: {}, name: {}, phone: {}, email: {}", +// userId, +// MaskingUtils.maskName(name), +// MaskingUtils.maskPhoneNumber(cellPhoneNo), +// MaskingUtils.maskEmailId(email)); +// +// // 사용자 생성 또는 업데이트 +// UserInfo userInfo = findOrCreateUser(info, extendedInfo); +// +// // 로그인 세션 설정 (MainController 위임) +// log.info("SSO 로그인 성공 - userId: {}", userId); +// return mainController.setupSsoLoginSession(req, userInfo); +// } else { +// // 동기화 비활성화 모드: 기존 사용자는 업데이트 없이, 신규 사용자는 최소 정보로 생성 +// log.info("SSO 동기화 비활성화 모드로 로그인 처리 - ssoId: {}", ssoId); +// +// UserInfo userInfo = findOrCreateUserWithoutSync(ssoId); +// +// log.info("SSO 로그인 성공 (동기화 비활성화 모드) - userId: {}", ssoId); +// return mainController.setupSsoLoginSession(req, userInfo); +// } +// } +// } /** * 필수 필드 검증 diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricManService.java b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricManService.java index a815b2c..b007940 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricManService.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/obp/ObpGwMetricManService.java @@ -1,5 +1,23 @@ package com.eactive.eai.rms.onl.apim.obp; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.time.temporal.ChronoUnit; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + import com.eactive.apim.portal.apprequest.entity.AppRequest; import com.eactive.apim.portal.apprequest.repository.AppRequestRepository; import com.eactive.apim.portal.obp.entity.ObpGwMetric; @@ -10,18 +28,7 @@ import com.eactive.eai.rms.common.util.CommonUtil; import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricJpaDAO; import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricService; import com.eactive.eai.rms.data.entity.onl.apim.obp.ObpGwMetricVO; -import com.eactive.ext.kjb.common.KjbPropertyHolder; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.dao.DataIntegrityViolationException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.time.temporal.ChronoUnit; -import java.util.*; -import java.util.stream.Collectors; +import com.eactive.eai.rms.ext.djb.common.DjbPropertyHolder; /** * ObpGwMetric Man Service - 비즈니스 로직 @@ -328,7 +335,7 @@ public class ObpGwMetricManService extends BaseService { DataSourceTypeManager.getDataSourceType(DataSourceTypeManager.MONITORING)); // KjbProperty에서 pageSize 읽기 - Integer pageSize = KjbPropertyHolder.get().getApiGwMetricPageSize(); + Integer pageSize = DjbPropertyHolder.get().getApiGwMetricPageSize(); if (pageSize == null) { pageSize = 10000; // 기본값 (null 안전 처리) } diff --git a/src/main/java/com/eactive/eai/rms/onl/apim/service/IpAuthenticationService.java b/src/main/java/com/eactive/eai/rms/onl/apim/service/IpAuthenticationService.java index 753c7eb..b433aa1 100644 --- a/src/main/java/com/eactive/eai/rms/onl/apim/service/IpAuthenticationService.java +++ b/src/main/java/com/eactive/eai/rms/onl/apim/service/IpAuthenticationService.java @@ -1,11 +1,13 @@ package com.eactive.eai.rms.onl.apim.service; -import com.eactive.eai.util.IpUtil; -import com.eactive.ext.kjb.common.KjbPropertyHolder; -import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.stereotype.Service; +import com.eactive.eai.rms.ext.djb.common.DjbPropertyHolder; +import com.eactive.eai.util.IpUtil; + +import lombok.extern.slf4j.Slf4j; + /** * IP 화이트리스트 인증 서비스 * @@ -113,7 +115,7 @@ public class IpAuthenticationService { */ private String loadWhitelistFromDb() { try { - String whitelist = KjbPropertyHolder.get().getApiAllowIpList(); + String whitelist = DjbPropertyHolder.get().getApiAllowIpList(); if (StringUtils.isBlank(whitelist)) { log.warn("IP whitelist property is empty"); return "";