) value);
+ }
+ jsonData.put(key, value);
+ }
+ return jsonData;
+ }
+
+
+
+}
diff --git a/auth/src/main/java/com/urpsys/baseauth/common/DataSourceUtil.java b/auth/src/main/java/com/urpsys/baseauth/common/DataSourceUtil.java
deleted file mode 100644
index d850aa45..00000000
--- a/auth/src/main/java/com/urpsys/baseauth/common/DataSourceUtil.java
+++ /dev/null
@@ -1,111 +0,0 @@
-package com.urpsys.baseauth.common;
-
-import javax.sql.DataSource;
-
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.mybatis.spring.SqlSessionFactoryBean;
-import org.springframework.core.env.Environment;
-import org.springframework.core.io.Resource;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-
-import com.urpsys.baseauth.common.crypto.Aes256Cipher;
-import com.urpsys.baseauth.common.exception.CustomException;
-import com.zaxxer.hikari.HikariConfig;
-import com.zaxxer.hikari.HikariDataSource;
-
-/**
- * Datasource 생성하는 유틸리티
- *
- * @author 나혁제
- * @since 2023.02.28
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2023.02.28 나혁제 최초작성
- *
- *
- */
-
-public class DataSourceUtil
-{
- /**
- * 데이터 소스 만드는 메소드
- * @param dataSourceName
- * @param env
- * @param cipher
- * @return
- */
- public static DataSource createDataSource(String dataSourceName, Environment env, Aes256Cipher cipher)
- {
- HikariConfig config = new HikariConfig();
-
- config.setDriverClassName (env.getProperty(dataSourceName + ".driverClassName" ));
- config.setJdbcUrl (env.getProperty(dataSourceName + ".jdbcUrl" ));
-
- config.setUsername (cipher.decrypt(env.getProperty(dataSourceName + ".username")));
- config.setPassword (cipher.decrypt(env.getProperty(dataSourceName + ".password")));
-
- config.setAutoCommit(false);
-
- config.setMaximumPoolSize (Integer.parseInt(env.getProperty(dataSourceName + ".maximumPoolSize" )));
- config.setMinimumIdle (Integer.parseInt(env.getProperty(dataSourceName + ".minimumIdle" )));
- config.setConnectionTimeout (Long.parseLong (env.getProperty(dataSourceName + ".connectionTimeout" )));
- config.setIdleTimeout (Long.parseLong (env.getProperty(dataSourceName + ".idleTimeout" )));
-
- config.addDataSourceProperty("cachePrepStmts" , "true");
- config.addDataSourceProperty("prepStmtCacheSize" , "250");
- config.addDataSourceProperty("prepStmtCacheSqlLimit" , "2048");
-
- return new HikariDataSource(config);
- }
-
- /**
- * SqlSessionFactory 만드는 메소드
- * @param dataSource
- * @param configLocation
- * @param mapperLocation
- * @return
- * @throws CustomException
- */
- public static SqlSessionFactory createSqlSessionFactory(DataSource dataSource, Resource configLocation,
- Resource[] mapperLocation) throws CustomException
- {
- SqlSessionFactory sqlSessionFactory;
-
- try {
- SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
- sessionFactoryBean.setDataSource(dataSource);
- sessionFactoryBean.setConfigLocation(configLocation);
- sessionFactoryBean.setMapperLocations(mapperLocation);
-
- sqlSessionFactory = sessionFactoryBean.getObject();
- }
- catch (Exception ex)
- {
- throw new CustomException(ex.getMessage());
- }
-
- return sqlSessionFactory;
- }
-
- /**
- * 트랜잭션 처리 메소드
- * @param dataSource
- * @return
- */
- public static DataSourceTransactionManager createTxManager(DataSource dataSource)
- {
- DataSourceTransactionManager txManager = new DataSourceTransactionManager(dataSource);
- txManager.setGlobalRollbackOnParticipationFailure(false);
-
- return txManager;
- }
-
- //end method
-}
diff --git a/auth/src/main/java/com/urpsys/baseauth/common/crypto/Aes256Cipher.java b/auth/src/main/java/com/urpsys/baseauth/common/crypto/Aes256Cipher.java
deleted file mode 100644
index 6407a4c8..00000000
--- a/auth/src/main/java/com/urpsys/baseauth/common/crypto/Aes256Cipher.java
+++ /dev/null
@@ -1,142 +0,0 @@
-package com.urpsys.baseauth.common.crypto;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.InvalidKeyException;
-import java.util.Properties;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.binary.Hex;
-import org.springframework.core.io.ClassPathResource;
-
-import com.urpsys.baseauth.common.CommonUtil;
-
-/**
- * aes 256 암호화 클래스
- *
- * @author 나혁제
- * @since 2023.02.28
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2023.02.28 나혁제 최초작성
- *
- *
- */
-
-public class Aes256Cipher
-{
- private SecretKey keySpec; // keySpec
- private IvParameterSpec ivSpec; // ivSpec
-
- /**
- * Aes256Cipher 생성자
- *
- * @param keyFile 키 파일 위치를 입력 받음
- * @throws IOException 파일 io 시 발생하는 익셉션
- * @throws InvalidKeyException key가 잘못되었을 경우 발생하는 익셉션
- * @throws DecoderException 암호화된 문자열을 decoding할 때 발생하는 익셉션
- */
- public Aes256Cipher() throws IOException, InvalidKeyException, DecoderException {
-
- String activeProfile = (CommonUtil.nvl(System.getProperty("spring.profiles.active")));
-
- InputStream fis = null;
- String secretKey = null;
-
- try
- {
- fis = new ClassPathResource("secrets/UrpSystem.keystore").getInputStream();
-
- Properties props = new Properties();
- props.load(fis);
- secretKey = props.getProperty("aes256.key");
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- }
- finally
- {
- fis.close();
- }
-
- byte[] secretKeyBytes = Hex.decodeHex(secretKey);
-
- if (secretKeyBytes.length != 32) {
- throw new InvalidKeyException("Invalid key (key length is not valid) ");
- }
-
- byte[] ivBytes = new byte[16];
-
- System.arraycopy(secretKeyBytes, 0, ivBytes, 0, 16);
-
- keySpec = new SecretKeySpec(secretKeyBytes, "AES");
- ivSpec = new IvParameterSpec(ivBytes);
- }
-
- /**
- * encryption 하는 메소드
- *
- * @param plainStr 평문을 입력 받음
- * @return 암호화된 문자열
- */
- public String encrypt(String plainStr) {
- if (plainStr == null) {
- return null;
- }
-
- String encryptedStr = null;
-
- try {
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
- byte[] encrypted = cipher.doFinal(plainStr.getBytes("UTF-8"));
- encryptedStr = new String(Base64.encodeBase64(encrypted));
- } catch (Exception ex) {
- ex.printStackTrace();
- }
-
- return encryptedStr;
- }
-
- /**
- * 암호화된 문자열을 복호화하는 메소드
- *
- * @param encryptedStr 암호화된 문자열
- * @return 암호화가 해제된 문자열
- */
- public String decrypt(String encryptedStr) {
- if (encryptedStr == null)
- {
- return null;
- }
-
- String decryptedStr = null;
-
- try {
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
-
- cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
- byte[] byteStr = Base64.decodeBase64(encryptedStr.getBytes("UTF-8"));
- decryptedStr = new String(cipher.doFinal(byteStr), "UTF-8");
- } catch (Exception ex) {
- ex.printStackTrace();
- }
-
- return decryptedStr;
- }
-}
diff --git a/auth/src/main/java/com/urpsys/baseauth/common/exception/CustomException.java b/auth/src/main/java/com/urpsys/baseauth/common/exception/CustomException.java
deleted file mode 100644
index bcf20646..00000000
--- a/auth/src/main/java/com/urpsys/baseauth/common/exception/CustomException.java
+++ /dev/null
@@ -1,114 +0,0 @@
-package com.urpsys.baseauth.common.exception;
-
-import java.sql.SQLSyntaxErrorException;
-
-import lombok.Getter;
-
-/**
- * Custom exception 클래스
- *
- * @author 나혁제
- * @since 2023.02.28
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2023.02.28 나혁제 최초작성
- *
- *
- */
-
-public class CustomException extends Exception
-{
- private static final long serialVersionUID = 3559302713942492181L;
-
- @Getter
- private String errorCode;
-
- @Getter
- private String errorMsg;
-
- /**
- * 생성자(throwable를 받아서 exception 종류에 따라 에러 코드 정의하는 클래스)
- * 에러코드 처리 부분은 향후 db에서 에러코드 읽어와서 매핑하는 것으로
- * 변경 가능성 있음
- * @param throwable
- */
- public CustomException(Throwable throwable) {
- Throwable rootThrowable = getRootCause(throwable);
-
- // TODO 에러 코드는 상세 정의해서 define 해야 함
- if(rootThrowable instanceof SQLSyntaxErrorException) {
- this.errorCode = "100";
- this.errorMsg = "SQL 오류";
- } else if(rootThrowable instanceof ArithmeticException) {
- this.errorCode = "200";
- this.errorMsg = "연산 오류";
- } else {
- this.errorCode = "900";
- this.errorMsg = "Unknown Error";
- }
- }
-
- /**
- * 생성자(에러메시지만 받을 경우 에러코드를 0을 default로 세팅)
- * @param errorMsg
- */
- public CustomException(String errorMsg) {
- super(errorMsg);
- this.errorCode = "0";
- this.errorMsg = errorMsg;
- }
-
- /**
- * 생성자(errorcode, errmsg를 받아 세팅, 소스코드에서 편하게 사용하기 위해
- * 에러코드를 int 값으로 받으면 string으로 변환하여 저장)
- * @param errorCode
- * @param errorMsg
- */
- public CustomException(int errorCode, String errorMsg) {
- super(errorMsg);
- this.errorCode = String.valueOf(errorCode);
- this.errorMsg = errorMsg;
- }
-
- /**
- * 생성자(에러코드, 에러메시지를 받아 세팅)
- * @param errorCode
- * @param errorMsg
- */
- public CustomException(String errorCode, String errorMsg) {
- super(errorMsg);
- this.errorCode = errorCode;
- this.errorMsg = errorMsg;
- }
-
- /**
- * stack에서 에러코드 중 root cause를 찾아내는 메소드
- * @param throwable
- * @return
- */
- private Throwable getRootCause(Throwable throwable) {
- Throwable cause = throwable.getCause();
-
- if (cause == null) {
- return throwable;
- }
-
- while (true) {
-
- if(cause.getCause() == null) {
- break;
- } else {
- cause = cause.getCause();
- }
- }
-
- return cause;
- }
-}
diff --git a/auth/src/main/java/com/urpsys/baseauth/config/EncryptConfig.java b/auth/src/main/java/com/urpsys/baseauth/config/EncryptConfig.java
index f2d7bf12..f427cbab 100644
--- a/auth/src/main/java/com/urpsys/baseauth/config/EncryptConfig.java
+++ b/auth/src/main/java/com/urpsys/baseauth/config/EncryptConfig.java
@@ -1,38 +1,38 @@
-package com.urpsys.baseauth.config;
-
-import java.io.IOException;
-import java.security.InvalidKeyException;
-import org.apache.commons.codec.DecoderException;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-
-import com.urpsys.baseauth.common.crypto.Aes256Cipher;
-
-/**
- * 암호화 유틸리티를 등록하는 클래스
- *
- * @author 나혁제
- * @since 2023.02.28
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2023.02.28 나혁제 최초작성
- *
- *
- */
-
-@Configuration
-public class EncryptConfig
-{
- @Bean(name="aes256Cipher")
- public Aes256Cipher aes256Cipher() throws InvalidKeyException, IOException, DecoderException
- {
- return new Aes256Cipher();
- }
-}
+package com.urpsys.baseauth.config;
+
+import java.io.IOException;
+import java.security.InvalidKeyException;
+import org.apache.commons.codec.DecoderException;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import com.urpsys.common.crypto.Aes256Cipher;
+
+/**
+ * 암호화 유틸리티를 등록하는 클래스
+ *
+ * @author 나혁제
+ * @since 2023.02.28
+ * @version 1.0.0
+ * @see
+ *
+ *
+ *
+ * << 개정이력(Modification information) >>
+ *
+ * 수정일 수정자 수정내용
+ * ----------- --------- ------------------------
+ * 2023.02.28 나혁제 최초작성
+ *
+ *
+ */
+
+@Configuration
+public class EncryptConfig
+{
+ @Bean(name="aes256Cipher")
+ public Aes256Cipher aes256Cipher() throws InvalidKeyException, IOException, DecoderException
+ {
+ return new Aes256Cipher();
+ }
+}
diff --git a/auth/src/main/java/com/urpsys/baseauth/config/Oauth2AuthorizationConfig.java b/auth/src/main/java/com/urpsys/baseauth/config/Oauth2AuthorizationConfig.java
index 14817c0b..67e21444 100644
--- a/auth/src/main/java/com/urpsys/baseauth/config/Oauth2AuthorizationConfig.java
+++ b/auth/src/main/java/com/urpsys/baseauth/config/Oauth2AuthorizationConfig.java
@@ -1,206 +1,206 @@
-package com.urpsys.baseauth.config;
-
-import java.util.Arrays;
-
-import javax.sql.DataSource;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
-import org.springframework.core.io.ClassPathResource;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.crypto.password.PasswordEncoder;
-import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
-import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
-import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
-import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
-import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
-import org.springframework.security.oauth2.provider.approval.ApprovalStore;
-import org.springframework.security.oauth2.provider.approval.JdbcApprovalStore;
-import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
-import org.springframework.security.oauth2.provider.token.TokenStore;
-import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
-import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
-import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
-
-import com.urpsys.baseauth.common.crypto.Aes256Cipher;
-import com.urpsys.baseauth.service.UserDetailService;
-import com.zaxxer.hikari.HikariConfig;
-import com.zaxxer.hikari.HikariDataSource;
-
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 인증서버 기본세팅
- *
- * @author 나혁제
- * @since 2023.02.28
- * @version 1.0.0
- * @see
- * @comment :
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2023.02.28 나혁제 최초작성
- *
- *
- */
-
-@Slf4j
-@EnableAuthorizationServer
-@Configuration
-public class Oauth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter
-{
- @Autowired
- private UserDetailService userDetailService;
-
- @Autowired
- private AuthenticationManager authenticationManager;
-
- /* DB 접속정보 */
- @Autowired
- private DataSource dataSource;
-
- /* 환경정보 */
- @Autowired
- private Environment env;
-
- /* aes256 암호화 유틸리티 */
- @Autowired
- private Aes256Cipher aes256Cipher;
-
- @Autowired
- private PasswordEncoder passwordEncoder;
-
- /**
- * 인증허용범위 설정 (5번 설정등록)
- *
- * @param 인증 범위 객체
- * @return 인증 범위 상세객체
- */
- @Override
- public void configure(AuthorizationServerSecurityConfigurer security) throws Exception
- {
- log.info(">>>>>>>>>> 5. Oauth2AuthorizationConfig | AuthorizationServerSecurityConfigurer | configure | 허용범위설정 <<<<<<<<<<");
-
- security.tokenKeyAccess("permitAll()")
- .checkTokenAccess("isAuthenticated()")
- .allowFormAuthenticationForClients()
- ;
-
- log.info("<<<<<<<<<< 5. Oauth2AuthorizationConfig | AuthorizationServerSecurityConfigurer | configure | 허용범위설정 >>>>>>>>>>");
-
- }
-
- /**
- * 접근 client 설정 (4번 설정등록)
- *
- * @param 클라이언트 접근정보 객체
- * @return 클라이언트 접근정보 상세 객체
- */
- @Override
- public void configure(ClientDetailsServiceConfigurer clients) throws Exception
- {
- log.info(">>>>>>>>>> 4. Oauth2AuthorizationConfig | ClientDetailsServiceConfigurer | configure | 접근 클라이언트 설정 <<<<<<<<<<");
-
- clients.inMemory()
- .withClient("clientId")
- .secret(passwordEncoder.encode("secretKey"))
- .authorizedGrantTypes("authorization_code","password", "refresh_token", "client_credentials") // 가능한 토큰 발행 타입
- .scopes("read", "write") // 가능한 접근 범위
- .accessTokenValiditySeconds (60*60*24) // access 토큰 유효 시간 : 24시간
- .refreshTokenValiditySeconds(60*60*24) // refresh 토큰 유효 시간 : 24시간
- .redirectUris("http://localhost:9010/callback") // 가능한 redirect uri
- .autoApprove(true); // 권한 동의는 자동으로 yes (false 로 할시 권한 동의 여부를 묻는다.)
-
- log.info("<<<<<<<<<< 4. Oauth2AuthorizationConfig | ClientDetailsServiceConfigurer | configure | 접근 클라이언트 설정 >>>>>>>>>>");
- }
-
- /**
- * 인증, 토큰유형, 토큰발행처리등 토큰발행정보설정 (3번 설정등록)
- *
- * @param 인증,토큰정보 객체
- * @return 인증,토큰정보 상세객체
- */
- @Override
- public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
- {
- log.info(">>>>>>>>>> 3. Oauth2AuthorizationConfig | AuthorizationServerEndpointsConfigurer | configure | 인증, 토큰 설정 <<<<<<<<<<");
-
- TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
- tokenEnhancerChain.setTokenEnhancers(Arrays.asList(new CustomTokenEnhancer(), jwtAccessTokenConverter())); // 토큰 enhancer 객체 생성
-
- endpoints.authenticationManager(authenticationManager) // grant_type password를 사용하기 위함
- // (manager 지정 안할시 password type 으로 토큰 발행시 Unsupported grant type: password 오류 발생)
- .userDetailsService(userDetailService) // refrash token 발행시 유저 정보 검사 하는데 사용하는 서비스 설정
- .tokenEnhancer(tokenEnhancerChain) // enhancer 설정
- .accessTokenConverter(jwtAccessTokenConverter())
- .approvalStore(approvalStore())
- ;
-
- log.info("<<<<<<<<<< 3. Oauth2AuthorizationConfig | AuthorizationServerEndpointsConfigurer | configure | 인증, 토큰 설정 >>>>>>>>>>");
- }
-
-
- // 토큰 DB 저장
- public HikariDataSource datasource2()
- {
- HikariConfig config = new HikariConfig();
-
- String dataSourceName = "primarydb";
-
- config.setDriverClassName (env.getProperty(dataSourceName + ".driverClassName" ));
- config.setJdbcUrl (env.getProperty(dataSourceName + ".jdbcUrl" ));
-
- config.setUsername (aes256Cipher.decrypt(env.getProperty(dataSourceName + ".username")));
- config.setPassword (aes256Cipher.decrypt(env.getProperty(dataSourceName + ".password")));
-
- return new HikariDataSource(config);
- }
-
- // 토큰 DB 저장
- @Bean
- public TokenStore tokenStore()
- {
- DataSource ds2 = datasource2();
- return new JdbcTokenStore(ds2);
- }
-
- // 권한 동의 DB 저장
- @Bean
- public ApprovalStore approvalStore()
- {
- DataSource ds2 = datasource2();
- return new JdbcApprovalStore(ds2);
- }
-
-
- /**
- * 자바토큰 발행 및 암호와 처리
- *
- * @param 인증,토큰정보 객체
- * @return 인증,토큰정보 상세객체
- */
- @Bean
- public JwtAccessTokenConverter jwtAccessTokenConverter()
- {
- // RSA 암호화 : 비 대칭키 암호화 : 공개키로 암호화 하면 개인키로 복호화
- KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("jwtkey.jks"), "corin1234".toCharArray());
- JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
- converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwtkey"));
-
- return converter;
- }
-
-
-
-
-
-
-
-}
+package com.urpsys.baseauth.config;
+
+import java.util.Arrays;
+
+import javax.sql.DataSource;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.core.io.ClassPathResource;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
+import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
+import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
+import org.springframework.security.oauth2.provider.approval.ApprovalStore;
+import org.springframework.security.oauth2.provider.approval.JdbcApprovalStore;
+import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
+import org.springframework.security.oauth2.provider.token.TokenStore;
+import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;
+import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
+import org.springframework.security.oauth2.provider.token.store.KeyStoreKeyFactory;
+
+import com.urpsys.common.crypto.Aes256Cipher;
+import com.urpsys.baseauth.service.UserDetailService;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 인증서버 기본세팅
+ *
+ * @author 나혁제
+ * @since 2023.02.28
+ * @version 1.0.0
+ * @see
+ * @comment :
+ *
+ *
+ *
+ * << 개정이력(Modification information) >>
+ *
+ * 수정일 수정자 수정내용
+ * ----------- --------- ------------------------
+ * 2023.02.28 나혁제 최초작성
+ *
+ *
+ */
+
+@Slf4j
+@EnableAuthorizationServer
+@Configuration
+public class Oauth2AuthorizationConfig extends AuthorizationServerConfigurerAdapter
+{
+ @Autowired
+ private UserDetailService userDetailService;
+
+ @Autowired
+ private AuthenticationManager authenticationManager;
+
+ /* DB 접속정보 */
+ @Autowired
+ private DataSource dataSource;
+
+ /* 환경정보 */
+ @Autowired
+ private Environment env;
+
+ /* aes256 암호화 유틸리티 */
+ @Autowired
+ private Aes256Cipher aes256Cipher;
+
+ @Autowired
+ private PasswordEncoder passwordEncoder;
+
+ /**
+ * 인증허용범위 설정 (5번 설정등록)
+ *
+ * @param 인증 범위 객체
+ * @return 인증 범위 상세객체
+ */
+ @Override
+ public void configure(AuthorizationServerSecurityConfigurer security) throws Exception
+ {
+ log.info(">>>>>>>>>> 5. Oauth2AuthorizationConfig | AuthorizationServerSecurityConfigurer | configure | 허용범위설정 <<<<<<<<<<");
+
+ security.tokenKeyAccess("permitAll()")
+ .checkTokenAccess("isAuthenticated()")
+ .allowFormAuthenticationForClients()
+ ;
+
+ log.info("<<<<<<<<<< 5. Oauth2AuthorizationConfig | AuthorizationServerSecurityConfigurer | configure | 허용범위설정 >>>>>>>>>>");
+
+ }
+
+ /**
+ * 접근 client 설정 (4번 설정등록)
+ *
+ * @param 클라이언트 접근정보 객체
+ * @return 클라이언트 접근정보 상세 객체
+ */
+ @Override
+ public void configure(ClientDetailsServiceConfigurer clients) throws Exception
+ {
+ log.info(">>>>>>>>>> 4. Oauth2AuthorizationConfig | ClientDetailsServiceConfigurer | configure | 접근 클라이언트 설정 <<<<<<<<<<");
+
+ clients.inMemory()
+ .withClient("clientId")
+ .secret(passwordEncoder.encode("secretKey"))
+ .authorizedGrantTypes("authorization_code","password", "refresh_token", "client_credentials") // 가능한 토큰 발행 타입
+ .scopes("read", "write") // 가능한 접근 범위
+ .accessTokenValiditySeconds (60*60*24) // access 토큰 유효 시간 : 24시간
+ .refreshTokenValiditySeconds(60*60*24) // refresh 토큰 유효 시간 : 24시간
+ .redirectUris("http://localhost:9010/callback") // 가능한 redirect uri
+ .autoApprove(true); // 권한 동의는 자동으로 yes (false 로 할시 권한 동의 여부를 묻는다.)
+
+ log.info("<<<<<<<<<< 4. Oauth2AuthorizationConfig | ClientDetailsServiceConfigurer | configure | 접근 클라이언트 설정 >>>>>>>>>>");
+ }
+
+ /**
+ * 인증, 토큰유형, 토큰발행처리등 토큰발행정보설정 (3번 설정등록)
+ *
+ * @param 인증,토큰정보 객체
+ * @return 인증,토큰정보 상세객체
+ */
+ @Override
+ public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception
+ {
+ log.info(">>>>>>>>>> 3. Oauth2AuthorizationConfig | AuthorizationServerEndpointsConfigurer | configure | 인증, 토큰 설정 <<<<<<<<<<");
+
+ TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
+ tokenEnhancerChain.setTokenEnhancers(Arrays.asList(new CustomTokenEnhancer(), jwtAccessTokenConverter())); // 토큰 enhancer 객체 생성
+
+ endpoints.authenticationManager(authenticationManager) // grant_type password를 사용하기 위함
+ // (manager 지정 안할시 password type 으로 토큰 발행시 Unsupported grant type: password 오류 발생)
+ .userDetailsService(userDetailService) // refrash token 발행시 유저 정보 검사 하는데 사용하는 서비스 설정
+ .tokenEnhancer(tokenEnhancerChain) // enhancer 설정
+ .accessTokenConverter(jwtAccessTokenConverter())
+ .approvalStore(approvalStore())
+ ;
+
+ log.info("<<<<<<<<<< 3. Oauth2AuthorizationConfig | AuthorizationServerEndpointsConfigurer | configure | 인증, 토큰 설정 >>>>>>>>>>");
+ }
+
+
+ // 토큰 DB 저장
+ public HikariDataSource datasource2()
+ {
+ HikariConfig config = new HikariConfig();
+
+ String dataSourceName = "primarydb";
+
+ config.setDriverClassName (env.getProperty(dataSourceName + ".driverClassName" ));
+ config.setJdbcUrl (env.getProperty(dataSourceName + ".jdbcUrl" ));
+
+ config.setUsername (aes256Cipher.decrypt(env.getProperty(dataSourceName + ".username")));
+ config.setPassword (aes256Cipher.decrypt(env.getProperty(dataSourceName + ".password")));
+
+ return new HikariDataSource(config);
+ }
+
+ // 토큰 DB 저장
+ @Bean
+ public TokenStore tokenStore()
+ {
+ DataSource ds2 = datasource2();
+ return new JdbcTokenStore(ds2);
+ }
+
+ // 권한 동의 DB 저장
+ @Bean
+ public ApprovalStore approvalStore()
+ {
+ DataSource ds2 = datasource2();
+ return new JdbcApprovalStore(ds2);
+ }
+
+
+ /**
+ * 자바토큰 발행 및 암호와 처리
+ *
+ * @param 인증,토큰정보 객체
+ * @return 인증,토큰정보 상세객체
+ */
+ @Bean
+ public JwtAccessTokenConverter jwtAccessTokenConverter()
+ {
+ // RSA 암호화 : 비 대칭키 암호화 : 공개키로 암호화 하면 개인키로 복호화
+ KeyStoreKeyFactory keyStoreKeyFactory = new KeyStoreKeyFactory(new ClassPathResource("jwtkey.jks"), "corin1234".toCharArray());
+ JwtAccessTokenConverter converter = new JwtAccessTokenConverter();
+ converter.setKeyPair(keyStoreKeyFactory.getKeyPair("jwtkey"));
+
+ return converter;
+ }
+
+
+
+
+
+
+
+}
diff --git a/auth/src/main/java/com/urpsys/baseauth/config/PrimaryDbConfig.java b/auth/src/main/java/com/urpsys/baseauth/config/PrimaryDbConfig.java
index c5d858c8..36778cf9 100644
--- a/auth/src/main/java/com/urpsys/baseauth/config/PrimaryDbConfig.java
+++ b/auth/src/main/java/com/urpsys/baseauth/config/PrimaryDbConfig.java
@@ -1,113 +1,113 @@
-package com.urpsys.baseauth.config;
-
-import java.io.IOException;
-import java.sql.Connection;
-
-import javax.sql.DataSource;
-import org.apache.ibatis.session.ExecutorType;
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.mybatis.spring.SqlSessionTemplate;
-import org.mybatis.spring.annotation.MapperScan;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.core.env.Environment;
-import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;
-import org.springframework.transaction.PlatformTransactionManager;
-import org.springframework.transaction.annotation.EnableTransactionManagement;
-
-import com.urpsys.baseauth.common.DataSourceUtil;
-import com.urpsys.baseauth.common.crypto.Aes256Cipher;
-import com.urpsys.baseauth.common.exception.CustomException;
-
-/**
- * primary db config 클래스
- *
- * @author 나혁제
- * @since 2023.02.28
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2023.02.28 나혁제 최초작성
- *
- *
- */
-
-@Configuration
-@EnableTransactionManagement
-@MapperScan(value="com.urpsys.baseauth.dao", sqlSessionFactoryRef="primarySqlSessionFactory")
-public class PrimaryDbConfig
-{
- /* spring environment class */
- @Autowired
- private Environment env;
-
- /* aes256 암호화 유틸리티 */
- @Autowired
- private Aes256Cipher aes256Cipher;
-
-
- /**
- * 데이터소스 등록하는 메소드
- * @return
- */
- @Bean(name="primaryDataSource")
- public DataSource primaryDataSource()
- {
- return new LazyConnectionDataSourceProxy(DataSourceUtil.createDataSource("primarydb", env, aes256Cipher));
- }
-
- /**
- * sqlsessionfactory 등록하는 메소드
- *
- * @param dataSource
- * @param context
- * @return
- * @throws SchedulerException
- * @throws IOException
- */
- @Bean(name="primarySqlSessionFactory")
- public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource, ApplicationContext context)
- throws CustomException, IOException
- {
- SqlSessionFactory sqlSessionFactory = DataSourceUtil.createSqlSessionFactory( dataSource
- , context.getResource ("classpath:mapper/primarydb/config/MybatisConfig.xml")
- , context.getResources("classpath:mapper/primarydb/sqlmap/**/*Mapper*.xml")
- );
-
- sqlSessionFactory.getConfiguration().setDefaultExecutorType(ExecutorType.SIMPLE);
-
- return sqlSessionFactory;
- }
-
- /**
- * sqlsessiontemplate 등록하는 메소드
- * @param primarySqlSessionFactory
- * @return
- */
- @Bean("primarySqlSessionTemplate")
- public SqlSessionTemplate mainSqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory primarySqlSessionFactory)
- {
- return new SqlSessionTemplate(primarySqlSessionFactory);
- }
-
- /**
- * 트랜잭션 매니저 등록하는 메소드
- * @param dataSource
- * @return
- */
- @Bean(name="primaryTxManager")
- public PlatformTransactionManager primaryTxManager(@Qualifier("primaryDataSource") DataSource dataSource)
- {
- return DataSourceUtil.createTxManager(dataSource);
- }
-}
-
+package com.urpsys.baseauth.config;
+
+import java.io.IOException;
+import java.sql.Connection;
+
+import javax.sql.DataSource;
+import org.apache.ibatis.session.ExecutorType;
+import org.apache.ibatis.session.SqlSessionFactory;
+import org.mybatis.spring.SqlSessionTemplate;
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.env.Environment;
+import org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy;
+import org.springframework.transaction.PlatformTransactionManager;
+import org.springframework.transaction.annotation.EnableTransactionManagement;
+
+import com.urpsys.common.util.DataSourceUtil;
+import com.urpsys.common.crypto.Aes256Cipher;
+import com.urpsys.common.exception.CustomException;
+
+/**
+ * primary db config 클래스
+ *
+ * @author 나혁제
+ * @since 2023.02.28
+ * @version 1.0.0
+ * @see
+ *
+ *
+ *
+ * << 개정이력(Modification information) >>
+ *
+ * 수정일 수정자 수정내용
+ * ----------- --------- ------------------------
+ * 2023.02.28 나혁제 최초작성
+ *
+ *
+ */
+
+@Configuration
+@EnableTransactionManagement
+@MapperScan(value="com.urpsys.baseauth.dao", sqlSessionFactoryRef="primarySqlSessionFactory")
+public class PrimaryDbConfig
+{
+ /* spring environment class */
+ @Autowired
+ private Environment env;
+
+ /* aes256 암호화 유틸리티 */
+ @Autowired
+ private Aes256Cipher aes256Cipher;
+
+
+ /**
+ * 데이터소스 등록하는 메소드
+ * @return
+ */
+ @Bean(name="primaryDataSource")
+ public DataSource primaryDataSource()
+ {
+ return new LazyConnectionDataSourceProxy(DataSourceUtil.createDataSource("primarydb", env, aes256Cipher));
+ }
+
+ /**
+ * sqlsessionfactory 등록하는 메소드
+ *
+ * @param dataSource
+ * @param context
+ * @return
+ * @throws SchedulerException
+ * @throws IOException
+ */
+ @Bean(name="primarySqlSessionFactory")
+ public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource, ApplicationContext context)
+ throws CustomException, IOException
+ {
+ SqlSessionFactory sqlSessionFactory = DataSourceUtil.createSqlSessionFactory( dataSource
+ , context.getResource ("classpath:mapper/primarydb/config/MybatisConfig.xml")
+ , context.getResources("classpath:mapper/primarydb/sqlmap/**/*Mapper*.xml")
+ );
+
+ sqlSessionFactory.getConfiguration().setDefaultExecutorType(ExecutorType.SIMPLE);
+
+ return sqlSessionFactory;
+ }
+
+ /**
+ * sqlsessiontemplate 등록하는 메소드
+ * @param primarySqlSessionFactory
+ * @return
+ */
+ @Bean("primarySqlSessionTemplate")
+ public SqlSessionTemplate mainSqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory primarySqlSessionFactory)
+ {
+ return new SqlSessionTemplate(primarySqlSessionFactory);
+ }
+
+ /**
+ * 트랜잭션 매니저 등록하는 메소드
+ * @param dataSource
+ * @return
+ */
+ @Bean(name="primaryTxManager")
+ public PlatformTransactionManager primaryTxManager(@Qualifier("primaryDataSource") DataSource dataSource)
+ {
+ return DataSourceUtil.createTxManager(dataSource);
+ }
+}
+
diff --git a/batch/build.gradle b/batch/build.gradle
index 7ee31cbd..907d56f3 100644
--- a/batch/build.gradle
+++ b/batch/build.gradle
@@ -32,7 +32,9 @@ ext
}
dependencies
-{
+{
+ implementation project(':common')
+
implementation 'org.springframework.boot:spring-boot-starter-batch'
implementation 'org.springframework.boot:spring-boot-starter-quartz'
diff --git a/batch/src/main/java/com/urpsys/basebatch/common/crypto/Aes256Cipher.java b/batch/src/main/java/com/urpsys/basebatch/common/crypto/Aes256Cipher.java
deleted file mode 100644
index e390933d..00000000
--- a/batch/src/main/java/com/urpsys/basebatch/common/crypto/Aes256Cipher.java
+++ /dev/null
@@ -1,152 +0,0 @@
-package com.urpsys.basebatch.common.crypto;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.security.InvalidKeyException;
-import java.util.Properties;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.IvParameterSpec;
-import javax.crypto.spec.SecretKeySpec;
-
-import com.urpsys.basebatch.common.util.CommonUtil;
-
-import org.apache.commons.codec.DecoderException;
-import org.apache.commons.codec.binary.Base64;
-import org.apache.commons.codec.binary.Hex;
-import org.springframework.core.io.ClassPathResource;
-
-/**
- * aes 256 암호화 클래스
- *
- * @author urp 인프라본부 나혁제
- * @since 2025.04.03
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2025.04.03 나혁제 최초작성
- *
- *
- */
-
-public class Aes256Cipher
-{
- private SecretKey keySpec; // keySpec
- private IvParameterSpec ivSpec; // ivSpec
-
- /**
- * Aes256Cipher 생성자
- *
- * @param keyFile 키 파일 위치를 입력 받음
- * @throws IOException 파일 io 시 발생하는 익셉션
- * @throws InvalidKeyException key가 잘못되었을 경우 발생하는 익셉션
- * @throws DecoderException 암호화된 문자열을 decoding할 때 발생하는 익셉션
- */
- public Aes256Cipher() throws IOException, InvalidKeyException, DecoderException
- {
-
- String activeProfile = (CommonUtil.nvl(System.getProperty("spring.profiles.active")));
-
- InputStream fis = null;
- String secretKey = null;
-
- try
- {
- fis = new ClassPathResource("secrets/UrpSystem.keystore").getInputStream();
-
- Properties props = new Properties();
- props.load(fis);
- secretKey = props.getProperty("aes256.key");
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- }
- finally
- {
- fis.close();
- }
-
- byte[] secretKeyBytes = Hex.decodeHex(secretKey);
-
- if (secretKeyBytes.length != 32) {
- throw new InvalidKeyException("Invalid key (key length is not valid) ");
- }
-
- byte[] ivBytes = new byte[16];
-
- System.arraycopy(secretKeyBytes, 0, ivBytes, 0, 16);
-
- keySpec = new SecretKeySpec(secretKeyBytes, "AES");
- ivSpec = new IvParameterSpec(ivBytes);
- }
-
- /**
- * encryption 하는 메소드
- *
- * @param plainStr 평문을 입력 받음
- * @return 암호화된 문자열
- */
- public String encrypt(String plainStr)
- {
- if (plainStr == null)
- {
- return null;
- }
-
- String encryptedStr = null;
-
- try
- {
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
- cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
- byte[] encrypted = cipher.doFinal(plainStr.getBytes("UTF-8"));
- encryptedStr = new String(Base64.encodeBase64(encrypted));
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- }
-
- return encryptedStr;
- }
-
- /**
- * 암호화된 문자열을 복호화하는 메소드
- *
- * @param encryptedStr 암호화된 문자열
- * @return 암호화가 해제된 문자열
- */
- public String decrypt(String encryptedStr)
- {
- if (encryptedStr == null)
- {
- return null;
- }
-
- String decryptedStr = null;
-
- try
- {
- Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
-
- cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
- byte[] byteStr = Base64.decodeBase64(encryptedStr.getBytes("UTF-8"));
- decryptedStr = new String(cipher.doFinal(byteStr), "UTF-8");
- }
- catch (Exception ex)
- {
- ex.printStackTrace();
- }
-
- return decryptedStr;
- }
-}
diff --git a/batch/src/main/java/com/urpsys/basebatch/common/exception/CustomException.java b/batch/src/main/java/com/urpsys/basebatch/common/exception/CustomException.java
deleted file mode 100644
index 6f355f6f..00000000
--- a/batch/src/main/java/com/urpsys/basebatch/common/exception/CustomException.java
+++ /dev/null
@@ -1,124 +0,0 @@
-package com.urpsys.basebatch.common.exception;
-
-import java.sql.SQLSyntaxErrorException;
-
-import lombok.Getter;
-
-/**
- * Custom exception 클래스
- *
- * @author urp 인프라본부 나혁제
- * @since 2025.04.03
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2025.04.03 나혁제 최초작성
- *
- *
- */
-
-public class CustomException extends Exception
-{
- private static final long serialVersionUID = 3559302713942492181L;
-
- @Getter
- private String errorCode;
-
- @Getter
- private String errorMsg;
-
- /**
- * 생성자(throwable를 받아서 exception 종류에 따라 에러 코드 정의하는 클래스)
- * 에러코드 처리 부분은 향후 db에서 에러코드 읽어와서 매핑하는 것으로
- * 변경 가능성 있음
- * @param throwable
- */
- public CustomException(Throwable throwable)
- {
- Throwable rootThrowable = getRootCause(throwable);
-
- // TODO 에러 코드는 상세 정의해서 define 해야 함
- if(rootThrowable instanceof SQLSyntaxErrorException)
- {
- this.errorCode = "100";
- this.errorMsg = "SQL 오류";
- }
- else if(rootThrowable instanceof ArithmeticException)
- {
- this.errorCode = "200";
- this.errorMsg = "연산 오류";
- }
- else
- {
- this.errorCode = "900";
- this.errorMsg = "Unknown Error";
- }
- }
-
- /**
- * 생성자(에러메시지만 받을 경우 에러코드를 0을 default로 세팅)
- * @param errorMsg
- */
- public CustomException(String errorMsg)
- {
- super(errorMsg);
- this.errorCode = "0";
- this.errorMsg = errorMsg;
- }
-
- /**
- * 생성자(errorcode, errmsg를 받아 세팅, 소스코드에서 편하게 사용하기 위해
- * 에러코드를 int 값으로 받으면 string으로 변환하여 저장)
- * @param errorCode
- * @param errorMsg
- */
- public CustomException(int errorCode, String errorMsg)
- {
- super(errorMsg);
- this.errorCode = String.valueOf(errorCode);
- this.errorMsg = errorMsg;
- }
-
- /**
- * 생성자(에러코드, 에러메시지를 받아 세팅)
- * @param errorCode
- * @param errorMsg
- */
- public CustomException(String errorCode, String errorMsg)
- {
- super(errorMsg);
- this.errorCode = errorCode;
- this.errorMsg = errorMsg;
- }
-
- /**
- * stack에서 에러코드 중 root cause를 찾아내는 메소드
- * @param throwable
- * @return
- */
- private Throwable getRootCause(Throwable throwable)
- {
- Throwable cause = throwable.getCause();
-
- if (cause == null) {
- return throwable;
- }
-
- while (true) {
-
- if(cause.getCause() == null) {
- break;
- } else {
- cause = cause.getCause();
- }
- }
-
- return cause;
- }
-}
diff --git a/batch/src/main/java/com/urpsys/basebatch/common/util/CommonUtil.java b/batch/src/main/java/com/urpsys/basebatch/common/util/CommonUtil.java
index 933591ad..c11dd1a8 100644
--- a/batch/src/main/java/com/urpsys/basebatch/common/util/CommonUtil.java
+++ b/batch/src/main/java/com/urpsys/basebatch/common/util/CommonUtil.java
@@ -1,524 +1,524 @@
-package com.urpsys.basebatch.common.util;
-
-import java.text.SimpleDateFormat;
-import java.util.Arrays;
-import java.util.Base64;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-import java.util.Locale;
-import java.util.SimpleTimeZone;
-import java.util.Vector;
-
-import com.urpsys.basebatch.common.exception.CustomException;
-
-/**
- * 공통 유틸리티를 모아둔 클래스
- *
- * @author urp 인프라본부 나혁제
- * @since 2025.04.03
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2025.04.03 나혁제 최초작성
- *
- *
- */
-
-public class CommonUtil
-{
- /**
- * nvl 메소드
- * @param inputStr
- * @return
- */
- public static String nvl(String inputStr)
- {
- return (inputStr != null) ? inputStr.trim() : "";
- }
-
- /**
- * nvl 메소드
- * @param inputStr
- * @param defaultValue
- * @return
- */
- public static String nvl(String inputStr, String defaultValue)
- {
- return nvl(inputStr).contentEquals("") ? defaultValue : inputStr.trim();
- }
-
- /**
- * nvl 메소드
- * @param inputObj
- * @return
- */
- public static String nvl(Object inputObj)
- {
- return (inputObj != null) ? String.valueOf(inputObj).trim() : "";
- }
-
- /**
- * long 타입의 시간을 입력받아 날짜 형태로 변환해서 리턴해주는 함수
- *
- * @param longTime long type 시간
- * @param dateFormat 변환할 포맷
- * @return 변환된 날짜 String
- * @throws SystemException
- */
- public static String getTimeString(long longTime, String dateFormat) throws CustomException
- {
- SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, Locale.KOREA);
-
- if (longTime < 0)
- {
- return "";
- }
- else
- {
- try
- {
- return sdf.format(new Date(longTime));
- }
- catch (Exception e)
- {
- throw new CustomException("Date 변환 오류");
- }
- }
- }
-
- /**
- * 현재(한국기준) 시간정보를 얻는다.
- * (예) 입력파리미터인 format string에 "yyyyMMddhh"를 셋팅하면 1998121011과 같이 Return.
- * (예) format string에 "yyyyMMddHHmmss"를 셋팅하면 19990114232121과 같이
- * 0~23시간 타입으로 Return.
- * String CurrentDate = CtosUtil2.getKST("yyyyMMddHH");
- * @param format 얻고자하는 현재시간의 Type
- * @return str 현재 한국 시간.
- */
- public static String getKST(String format)
- {
- //1hour(ms) = 60s * 60m * 1000ms
- int millisPerHour = 60 * 60 * 1000;
- SimpleDateFormat fmt= new SimpleDateFormat(format);
-
- SimpleTimeZone timeZone = new SimpleTimeZone(9*millisPerHour,"KST");
- fmt.setTimeZone(timeZone);
-
- long time=System.currentTimeMillis();
- String str=fmt.format(new java.util.Date(time));
- return str;
- }
-
- /**
- * 입력한 날짜 기준으로 몇일 전,후 (주의)입력날짜는 구분자가 없는 string형
- *
- * @param date
- * string date (19991002)
- * @param Day
- * 기준이 되는 시간
- * @return String
- */
- public static String getDatewithSpan(String date, long Day)
- {
- /*
- * int millisPerHour = 60 * 60 * 1000; SimpleDateFormat fmt= new
- * SimpleDateFormat("yyyy/MM/dd"); SimpleTimeZone timeZone = new
- * SimpleTimeZone(9*millisPerHour,"KST"); fmt.setTimeZone(timeZone);
- *
- * int year = Integer.valueOf(date.substring(0,4)).intValue(); int month
- * = Integer.valueOf(date.substring(4,6)).intValue(); int day =
- * Integer.valueOf(date.substring(6,8)).intValue();
- *
- * java.util.Calendar aDay = Calendar.getInstance();
- * aDay.set(year+1900,month,day); java.util.Calendar bDay
- * =Calendar.getInstance(); bDay.set(1970+1900,1,1); java.util.Date cDay
- * = new java.util.Date((aDay.getTime()).getTime() -
- * (bDay.getTime()).getTime() + ((Day+1)*86400000) );
- *
- * return fmt.format(cDay);
- */
- // 2006-09-04 7:03오후 오동원수정
- String vFORMAT = "yyyy/MM/dd";
- return getDatewithSpan(date, Day, "D", vFORMAT);
-
- }
-
- /**
- * 입력한 날짜 기준으로 몇(일,시간,분) 전,후 (주의)입력날짜는 구분자가 없는 string형
- *
- * @param date
- * string date (20000315/2000031509/200003150915)
- * @param unit
- * long unit: 몇(일,시간,분) 전, 몇(일,시간,분) 후
- * @param type
- * String type: D:Day H:Hour M:Minute
- * @return String 계산된 문자열의 값.
- */
- public static String getDatewithSpan(String date, long unit, String type, String strFormatType)
- {
- /*
- * String formatType = strFormatType; int ihour = 0; int itime = 0;
- *
- * long dhm = 24 * 60 * 60 * 1000;
- *
- * if (type.equals("D")) { dhm =dhm + unit * 24 * 60 * 60 * 1000; } else
- * if (type.equals("H")){ dhm =dhm + unit * 60 * 60 * 1000; } else if
- * (type.equals("M")){ dhm =dhm + unit * 60 * 1000; } else{ return type
- * + "은 부적절한 Type값입니다"; }
- *
- * switch (date.length()){ case (8): if (type.equals("H") ||
- * type.equals("M")) { return "HM-ERROR"; }
- *
- * break; case (10): if (type.equals("M")) { return "M-ERROR"; }
- *
- * ihour = Integer.valueOf(date.substring(8,10)).intValue(); break; case
- * (12):
- *
- * ihour = Integer.valueOf(date.substring(8,10)).intValue(); itime =
- * Integer.valueOf(date.substring(10,12)).intValue(); break; default:
- * return "date Length Error"; }
- *
- * int millisPerHour = 60 * 60 * 1000; SimpleDateFormat fmt= new
- * SimpleDateFormat(formatType); SimpleTimeZone timeZone = new
- * SimpleTimeZone(9*millisPerHour,"KST"); fmt.setTimeZone(timeZone);
- *
- * int iyear = Integer.valueOf(date.substring(0,4)).intValue(); int
- * imonth = Integer.valueOf(date.substring(4,6)).intValue(); int iday =
- * Integer.valueOf(date.substring(6,8)).intValue(); java.util.Calendar
- * aDay = Calendar.getInstance();
- * aDay.set(iyear+1900,imonth,iday,ihour,itime); java.util.Calendar bDay
- * = Calendar.getInstance(); bDay.set(1970+1900,1,1,9,0); java.util.Date
- * cDay = new java.util.Date((aDay.getTime()).getTime() -
- * (bDay.getTime()).getTime() + dhm); return fmt.format(cDay);
- */
- // 2006-09-04 7:03오후 오동원수정
- String formatType = strFormatType;
- int ihour = 0;
- int itime = 0;
- if(!(type.equals("D") || type.equals("H") || type.equals("M")))
- {
- return type + "은 부적절한 Type값입니다";
- }
-
- switch(date.length())
- {
- case (8):
- if(type.equals("H") || type.equals("M"))
- {
- return "HM-ERROR";
- }
- break;
- case (10):
- if(type.equals("M"))
- {
- return "M-ERROR";
- }
- ihour = Integer.parseInt(date.substring(8, 10));
- // ihour = Integer.valueOf(date.substring(8, 10)).intValue();
- break;
- case (12):
- ihour = Integer.parseInt(date.substring(8, 10));
- itime = Integer.parseInt(date.substring(10, 12));
-
- // ihour = Integer.valueOf(date.substring(8, 10)).intValue();
- // itime = Integer.valueOf(date.substring(10, 12)).intValue();
- break;
- default:
- return "date Length Error";
- }
- int iyear = Integer.parseInt(date.substring(0, 4));
- int imonth = Integer.parseInt(date.substring(4, 6));
- int iday = Integer.parseInt(date.substring(6, 8));
-
- /*
- int iyear = Integer.valueOf(date.substring(0, 4)).intValue();
- int imonth = Integer.valueOf(date.substring(4, 6)).intValue();
- int iday = Integer.valueOf(date.substring(6, 8)).intValue();
- */
-
- int imonth1 = imonth - 1; // 달은 0달부터 시작한다.
- java.util.Calendar zDay = Calendar.getInstance();
- zDay.set(iyear, imonth1, iday, ihour, itime);
-
- if(type.equals("D"))
- {
- zDay.add(Calendar.DATE, (int) unit);
- }
- else if(type.equals("H"))
- {
- zDay.add(Calendar.HOUR_OF_DAY, (int) unit);
- }
- else if(type.equals("M"))
- {
- zDay.add(Calendar.MINUTE, (int) unit);
- }
- else
- {
- return type + "은 부적절한 Type값입니다";
- }
- java.util.Date z1Day = zDay.getTime();
- java.text.SimpleDateFormat fmt2 = new java.text.SimpleDateFormat(formatType);
- return fmt2.format(z1Day);
-
- }
-
- /**
- * 현재 시간을 기준으로 몇 일후 시간 시간의 형태는 (yyyy/mm/dd)
- *
- * @param day
- * 더하려는 날짜
- * @return str 현재 시간에 입력 시간을 더한 DATE형 시간
- */
- public static String getDatewithSpan(long day)
- {
- /*
- * int millisPerHour = 60 * 60 * 1000; SimpleDateFormat fmt= new
- * SimpleDateFormat("yyyy/MM/dd"); SimpleTimeZone timeZone = new
- * SimpleTimeZone(9*millisPerHour,"KST"); fmt.setTimeZone(timeZone);
- *
- * long time = System.currentTimeMillis(); long span = ( 60 * 60 * 1000
- * * 24 ) * day; //하루에 대한 millisecond... long time2 = time + span;
- * String str=fmt.format(new java.util.Date(time2));
- *
- * return str;
- */
- String strSYSDATE = CommonUtil.getKST("yyyyMMddHH"); // 지금 시간
- String vFORMAT = "yyyy/MM/dd";
- return getDatewithSpan(strSYSDATE, day, "D", vFORMAT);
-
- }
-
- public static long stol(String str)
- {
- if(str == null ) return 0;
- return (Long.valueOf(str).longValue());
- }
-
- /**
- 문자열을 중 특정 문자열을 변환시킨다.
- @version 1.0
- @author Yoon Su-wan
- @since JDK1.0
- @param targeter 대상문자열
- @param target_str 변환될 대상문자열
- @param replace_str 변환될 문자열
- @return target_str이 replace_str로 변환된 문자열
- */
- public static String getReplacedString(String targeter, String target_str, String replace_str)
- {
- if( targeter == null
- || target_str == null
- || replace_str == null )
- return "debug : parameter value is null";
-
- if(target_str.length() == 0)
- return targeter;
-
- StringBuffer str = new StringBuffer();
- int start_ptr = 0;
- int current_ptr = 0;
- int increment_size = replace_str.length();
- if(increment_size == 0 ) increment_size = 1;
-
- while((current_ptr = targeter.indexOf(target_str, start_ptr)) != -1)
- {
- str.append(targeter.substring(start_ptr, current_ptr));
- str.append(replace_str);
- start_ptr = current_ptr + increment_size;
- if(start_ptr >= targeter.length())
- break;
- }//end while
-
- if(start_ptr == 0)
- return targeter;
-
- if(start_ptr < targeter.length())
- str.append(targeter.substring(start_ptr));
-
- return str.toString();
- }//getReplacedString(String targeter, String target_str, String replace_str)
-
- /**
- 받은메세지에서 v_s1값을 찾아서 v_s2로 대치한다.
- @version 1.0
- @author Yoon Su-wan
- @since JDK1.0
- @param v_msg 대상문자열
- @param v_s1 변환될 대상문자열
- @param v_s2 변환될 문자열
- @return v_s1이 v_s2 변환된 문자열
- */
-
- public static String getReplacedString2(String v_msg, String v_s1, String v_s2)
- {
- int idx = v_msg.indexOf(v_s1);
-
- if (idx == -1) return v_msg;
- else
- {
- try
- {
- return v_msg.substring(0, idx) + v_s2 + v_msg.substring(idx+2);
- } catch (Exception e)
- {
- return v_msg.substring(0, idx) + v_s2;
- }
- }
-
- }
-
- public static String getReplacedString3(String sStr, String n1, String n2)
- {
- int iTmp = 0;
- if (sStr == null) return "";
-
- String sTmp = sStr;
- StringBuffer sbSave = new StringBuffer();
- sbSave.append("");
- while (sTmp.indexOf(n1) > -1)
- {
- iTmp = sTmp.indexOf(n1);
- sbSave.append(sTmp.substring(0,iTmp));
- sbSave.append(n2);
- sTmp = sTmp.substring(iTmp + n1.length());
- }
- sbSave.append(sTmp);
- return sbSave.toString();
- }
-
- public static Vector arrToDouVector(String strArray, String strDelimt)
- {
- String[] stArray = strArray.split(strDelimt);
-
- double[] dArray = Arrays.stream(stArray).mapToDouble(Double::parseDouble).toArray();
- Vector vReturn = new Vector();
-
- if(dArray==null) return vReturn;
-
- for(double dTemp: dArray)
- {
- vReturn.add(dTemp);
- }
-
- return vReturn;
-
- }
-
- public static String arrListToString(List list)
- {
- String strReturn="";
-
- if(list == null ) return "";
-
- for(int i=0; i"+strTemp);
- // double dou = Double.parseDouble(strTemp);
- // strReturn = strReturn+","+dou;
- strReturn = strReturn+","+strTemp;
- }
-
- strReturn = strReturn.substring(1);
-
- return strReturn;
-
- }
-
- /**
- 보고서 body base64 변환
- front로 부터 받아서 DB저장시 사용
- @version 1.0
- @author 나혁제
- @since 2025.02.06
- @param txt String
- @return String
- */
- public static String base64encode(String txt)
- {
- try
- {
- byte[] bytes = Base64.getEncoder().encode((txt).getBytes("utf-8"));
- return new String(bytes);
- }
- catch(Exception e)
- {
- e.printStackTrace();
- byte[] bytes = Base64.getEncoder().encode((txt).getBytes());
- return new String(bytes);
- }
- }
-
- /**
- 서버(DB)에서 front로 전달시 사용
- @version 1.0
- @author 나혁제
- @since 2025.02.06
- @param txt String
- @return String
- */
- public static String base64decode(String txt)
- {
- byte[] bytes = Base64.getDecoder().decode(txt.getBytes());
-
- try
- {
- return new String(bytes, "utf-8");
- }
- catch(Exception e)
- {
- e.printStackTrace();
- return new String(bytes);
- }
- }
-
- /**
- *
- * 인자로 받은 String이 null일 경우 "0"로 리턴한다.
- * @param src null값일 가능성이 있는 String 값.
- * @return 만약 String이 null 값일 경우 "0"로 바꾼 String 값.
- *
- */
- public static int zeroConvert(Object src)
- {
- String src2 = src+"";
- if (src == null || src.equals("null"))
- {
- return 0;
- }
- else
- {
- return Integer.parseInt(((String)src2).trim());
- }
- }
-
- /**
- *
- * 인자로 받은 String이 null일 경우 ""로 리턴한다.
- * @param src null값일 가능성이 있는 String 값.
- * @return 만약 String이 null 값일 경우 ""로 바꾼 String 값.
- *
- */
- public static int zeroConvert(String src)
- {
-
- if (src == null || src.equals("null") || "".equals(src) || " ".equals(src))
- {
- return 0;
- }
- else
- {
- return Integer.parseInt(src.trim());
- }
- }
-
-
-
-}
+package com.urpsys.basebatch.common.util;
+
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.SimpleTimeZone;
+import java.util.Vector;
+
+import com.urpsys.common.exception.CustomException;
+
+/**
+ * 공통 유틸리티를 모아둔 클래스
+ *
+ * @author urp 인프라본부 나혁제
+ * @since 2025.04.03
+ * @version 1.0.0
+ * @see
+ *
+ *
+ *
+ * << 개정이력(Modification information) >>
+ *
+ * 수정일 수정자 수정내용
+ * ----------- --------- ------------------------
+ * 2025.04.03 나혁제 최초작성
+ *
+ *
+ */
+
+public class CommonUtil
+{
+ /**
+ * nvl 메소드
+ * @param inputStr
+ * @return
+ */
+ public static String nvl(String inputStr)
+ {
+ return (inputStr != null) ? inputStr.trim() : "";
+ }
+
+ /**
+ * nvl 메소드
+ * @param inputStr
+ * @param defaultValue
+ * @return
+ */
+ public static String nvl(String inputStr, String defaultValue)
+ {
+ return nvl(inputStr).contentEquals("") ? defaultValue : inputStr.trim();
+ }
+
+ /**
+ * nvl 메소드
+ * @param inputObj
+ * @return
+ */
+ public static String nvl(Object inputObj)
+ {
+ return (inputObj != null) ? String.valueOf(inputObj).trim() : "";
+ }
+
+ /**
+ * long 타입의 시간을 입력받아 날짜 형태로 변환해서 리턴해주는 함수
+ *
+ * @param longTime long type 시간
+ * @param dateFormat 변환할 포맷
+ * @return 변환된 날짜 String
+ * @throws SystemException
+ */
+ public static String getTimeString(long longTime, String dateFormat) throws CustomException
+ {
+ SimpleDateFormat sdf = new SimpleDateFormat(dateFormat, Locale.KOREA);
+
+ if (longTime < 0)
+ {
+ return "";
+ }
+ else
+ {
+ try
+ {
+ return sdf.format(new Date(longTime));
+ }
+ catch (Exception e)
+ {
+ throw new CustomException("Date 변환 오류");
+ }
+ }
+ }
+
+ /**
+ * 현재(한국기준) 시간정보를 얻는다.
+ * (예) 입력파리미터인 format string에 "yyyyMMddhh"를 셋팅하면 1998121011과 같이 Return.
+ * (예) format string에 "yyyyMMddHHmmss"를 셋팅하면 19990114232121과 같이
+ * 0~23시간 타입으로 Return.
+ * String CurrentDate = CtosUtil2.getKST("yyyyMMddHH");
+ * @param format 얻고자하는 현재시간의 Type
+ * @return str 현재 한국 시간.
+ */
+ public static String getKST(String format)
+ {
+ //1hour(ms) = 60s * 60m * 1000ms
+ int millisPerHour = 60 * 60 * 1000;
+ SimpleDateFormat fmt= new SimpleDateFormat(format);
+
+ SimpleTimeZone timeZone = new SimpleTimeZone(9*millisPerHour,"KST");
+ fmt.setTimeZone(timeZone);
+
+ long time=System.currentTimeMillis();
+ String str=fmt.format(new java.util.Date(time));
+ return str;
+ }
+
+ /**
+ * 입력한 날짜 기준으로 몇일 전,후 (주의)입력날짜는 구분자가 없는 string형
+ *
+ * @param date
+ * string date (19991002)
+ * @param Day
+ * 기준이 되는 시간
+ * @return String
+ */
+ public static String getDatewithSpan(String date, long Day)
+ {
+ /*
+ * int millisPerHour = 60 * 60 * 1000; SimpleDateFormat fmt= new
+ * SimpleDateFormat("yyyy/MM/dd"); SimpleTimeZone timeZone = new
+ * SimpleTimeZone(9*millisPerHour,"KST"); fmt.setTimeZone(timeZone);
+ *
+ * int year = Integer.valueOf(date.substring(0,4)).intValue(); int month
+ * = Integer.valueOf(date.substring(4,6)).intValue(); int day =
+ * Integer.valueOf(date.substring(6,8)).intValue();
+ *
+ * java.util.Calendar aDay = Calendar.getInstance();
+ * aDay.set(year+1900,month,day); java.util.Calendar bDay
+ * =Calendar.getInstance(); bDay.set(1970+1900,1,1); java.util.Date cDay
+ * = new java.util.Date((aDay.getTime()).getTime() -
+ * (bDay.getTime()).getTime() + ((Day+1)*86400000) );
+ *
+ * return fmt.format(cDay);
+ */
+ // 2006-09-04 7:03오후 오동원수정
+ String vFORMAT = "yyyy/MM/dd";
+ return getDatewithSpan(date, Day, "D", vFORMAT);
+
+ }
+
+ /**
+ * 입력한 날짜 기준으로 몇(일,시간,분) 전,후 (주의)입력날짜는 구분자가 없는 string형
+ *
+ * @param date
+ * string date (20000315/2000031509/200003150915)
+ * @param unit
+ * long unit: 몇(일,시간,분) 전, 몇(일,시간,분) 후
+ * @param type
+ * String type: D:Day H:Hour M:Minute
+ * @return String 계산된 문자열의 값.
+ */
+ public static String getDatewithSpan(String date, long unit, String type, String strFormatType)
+ {
+ /*
+ * String formatType = strFormatType; int ihour = 0; int itime = 0;
+ *
+ * long dhm = 24 * 60 * 60 * 1000;
+ *
+ * if (type.equals("D")) { dhm =dhm + unit * 24 * 60 * 60 * 1000; } else
+ * if (type.equals("H")){ dhm =dhm + unit * 60 * 60 * 1000; } else if
+ * (type.equals("M")){ dhm =dhm + unit * 60 * 1000; } else{ return type
+ * + "은 부적절한 Type값입니다"; }
+ *
+ * switch (date.length()){ case (8): if (type.equals("H") ||
+ * type.equals("M")) { return "HM-ERROR"; }
+ *
+ * break; case (10): if (type.equals("M")) { return "M-ERROR"; }
+ *
+ * ihour = Integer.valueOf(date.substring(8,10)).intValue(); break; case
+ * (12):
+ *
+ * ihour = Integer.valueOf(date.substring(8,10)).intValue(); itime =
+ * Integer.valueOf(date.substring(10,12)).intValue(); break; default:
+ * return "date Length Error"; }
+ *
+ * int millisPerHour = 60 * 60 * 1000; SimpleDateFormat fmt= new
+ * SimpleDateFormat(formatType); SimpleTimeZone timeZone = new
+ * SimpleTimeZone(9*millisPerHour,"KST"); fmt.setTimeZone(timeZone);
+ *
+ * int iyear = Integer.valueOf(date.substring(0,4)).intValue(); int
+ * imonth = Integer.valueOf(date.substring(4,6)).intValue(); int iday =
+ * Integer.valueOf(date.substring(6,8)).intValue(); java.util.Calendar
+ * aDay = Calendar.getInstance();
+ * aDay.set(iyear+1900,imonth,iday,ihour,itime); java.util.Calendar bDay
+ * = Calendar.getInstance(); bDay.set(1970+1900,1,1,9,0); java.util.Date
+ * cDay = new java.util.Date((aDay.getTime()).getTime() -
+ * (bDay.getTime()).getTime() + dhm); return fmt.format(cDay);
+ */
+ // 2006-09-04 7:03오후 오동원수정
+ String formatType = strFormatType;
+ int ihour = 0;
+ int itime = 0;
+ if(!(type.equals("D") || type.equals("H") || type.equals("M")))
+ {
+ return type + "은 부적절한 Type값입니다";
+ }
+
+ switch(date.length())
+ {
+ case (8):
+ if(type.equals("H") || type.equals("M"))
+ {
+ return "HM-ERROR";
+ }
+ break;
+ case (10):
+ if(type.equals("M"))
+ {
+ return "M-ERROR";
+ }
+ ihour = Integer.parseInt(date.substring(8, 10));
+ // ihour = Integer.valueOf(date.substring(8, 10)).intValue();
+ break;
+ case (12):
+ ihour = Integer.parseInt(date.substring(8, 10));
+ itime = Integer.parseInt(date.substring(10, 12));
+
+ // ihour = Integer.valueOf(date.substring(8, 10)).intValue();
+ // itime = Integer.valueOf(date.substring(10, 12)).intValue();
+ break;
+ default:
+ return "date Length Error";
+ }
+ int iyear = Integer.parseInt(date.substring(0, 4));
+ int imonth = Integer.parseInt(date.substring(4, 6));
+ int iday = Integer.parseInt(date.substring(6, 8));
+
+ /*
+ int iyear = Integer.valueOf(date.substring(0, 4)).intValue();
+ int imonth = Integer.valueOf(date.substring(4, 6)).intValue();
+ int iday = Integer.valueOf(date.substring(6, 8)).intValue();
+ */
+
+ int imonth1 = imonth - 1; // 달은 0달부터 시작한다.
+ java.util.Calendar zDay = Calendar.getInstance();
+ zDay.set(iyear, imonth1, iday, ihour, itime);
+
+ if(type.equals("D"))
+ {
+ zDay.add(Calendar.DATE, (int) unit);
+ }
+ else if(type.equals("H"))
+ {
+ zDay.add(Calendar.HOUR_OF_DAY, (int) unit);
+ }
+ else if(type.equals("M"))
+ {
+ zDay.add(Calendar.MINUTE, (int) unit);
+ }
+ else
+ {
+ return type + "은 부적절한 Type값입니다";
+ }
+ java.util.Date z1Day = zDay.getTime();
+ java.text.SimpleDateFormat fmt2 = new java.text.SimpleDateFormat(formatType);
+ return fmt2.format(z1Day);
+
+ }
+
+ /**
+ * 현재 시간을 기준으로 몇 일후 시간 시간의 형태는 (yyyy/mm/dd)
+ *
+ * @param day
+ * 더하려는 날짜
+ * @return str 현재 시간에 입력 시간을 더한 DATE형 시간
+ */
+ public static String getDatewithSpan(long day)
+ {
+ /*
+ * int millisPerHour = 60 * 60 * 1000; SimpleDateFormat fmt= new
+ * SimpleDateFormat("yyyy/MM/dd"); SimpleTimeZone timeZone = new
+ * SimpleTimeZone(9*millisPerHour,"KST"); fmt.setTimeZone(timeZone);
+ *
+ * long time = System.currentTimeMillis(); long span = ( 60 * 60 * 1000
+ * * 24 ) * day; //하루에 대한 millisecond... long time2 = time + span;
+ * String str=fmt.format(new java.util.Date(time2));
+ *
+ * return str;
+ */
+ String strSYSDATE = CommonUtil.getKST("yyyyMMddHH"); // 지금 시간
+ String vFORMAT = "yyyy/MM/dd";
+ return getDatewithSpan(strSYSDATE, day, "D", vFORMAT);
+
+ }
+
+ public static long stol(String str)
+ {
+ if(str == null ) return 0;
+ return (Long.valueOf(str).longValue());
+ }
+
+ /**
+ 문자열을 중 특정 문자열을 변환시킨다.
+ @version 1.0
+ @author Yoon Su-wan
+ @since JDK1.0
+ @param targeter 대상문자열
+ @param target_str 변환될 대상문자열
+ @param replace_str 변환될 문자열
+ @return target_str이 replace_str로 변환된 문자열
+ */
+ public static String getReplacedString(String targeter, String target_str, String replace_str)
+ {
+ if( targeter == null
+ || target_str == null
+ || replace_str == null )
+ return "debug : parameter value is null";
+
+ if(target_str.length() == 0)
+ return targeter;
+
+ StringBuffer str = new StringBuffer();
+ int start_ptr = 0;
+ int current_ptr = 0;
+ int increment_size = replace_str.length();
+ if(increment_size == 0 ) increment_size = 1;
+
+ while((current_ptr = targeter.indexOf(target_str, start_ptr)) != -1)
+ {
+ str.append(targeter.substring(start_ptr, current_ptr));
+ str.append(replace_str);
+ start_ptr = current_ptr + increment_size;
+ if(start_ptr >= targeter.length())
+ break;
+ }//end while
+
+ if(start_ptr == 0)
+ return targeter;
+
+ if(start_ptr < targeter.length())
+ str.append(targeter.substring(start_ptr));
+
+ return str.toString();
+ }//getReplacedString(String targeter, String target_str, String replace_str)
+
+ /**
+ 받은메세지에서 v_s1값을 찾아서 v_s2로 대치한다.
+ @version 1.0
+ @author Yoon Su-wan
+ @since JDK1.0
+ @param v_msg 대상문자열
+ @param v_s1 변환될 대상문자열
+ @param v_s2 변환될 문자열
+ @return v_s1이 v_s2 변환된 문자열
+ */
+
+ public static String getReplacedString2(String v_msg, String v_s1, String v_s2)
+ {
+ int idx = v_msg.indexOf(v_s1);
+
+ if (idx == -1) return v_msg;
+ else
+ {
+ try
+ {
+ return v_msg.substring(0, idx) + v_s2 + v_msg.substring(idx+2);
+ } catch (Exception e)
+ {
+ return v_msg.substring(0, idx) + v_s2;
+ }
+ }
+
+ }
+
+ public static String getReplacedString3(String sStr, String n1, String n2)
+ {
+ int iTmp = 0;
+ if (sStr == null) return "";
+
+ String sTmp = sStr;
+ StringBuffer sbSave = new StringBuffer();
+ sbSave.append("");
+ while (sTmp.indexOf(n1) > -1)
+ {
+ iTmp = sTmp.indexOf(n1);
+ sbSave.append(sTmp.substring(0,iTmp));
+ sbSave.append(n2);
+ sTmp = sTmp.substring(iTmp + n1.length());
+ }
+ sbSave.append(sTmp);
+ return sbSave.toString();
+ }
+
+ public static Vector arrToDouVector(String strArray, String strDelimt)
+ {
+ String[] stArray = strArray.split(strDelimt);
+
+ double[] dArray = Arrays.stream(stArray).mapToDouble(Double::parseDouble).toArray();
+ Vector vReturn = new Vector();
+
+ if(dArray==null) return vReturn;
+
+ for(double dTemp: dArray)
+ {
+ vReturn.add(dTemp);
+ }
+
+ return vReturn;
+
+ }
+
+ public static String arrListToString(List list)
+ {
+ String strReturn="";
+
+ if(list == null ) return "";
+
+ for(int i=0; i"+strTemp);
+ // double dou = Double.parseDouble(strTemp);
+ // strReturn = strReturn+","+dou;
+ strReturn = strReturn+","+strTemp;
+ }
+
+ strReturn = strReturn.substring(1);
+
+ return strReturn;
+
+ }
+
+ /**
+ 보고서 body base64 변환
+ front로 부터 받아서 DB저장시 사용
+ @version 1.0
+ @author 나혁제
+ @since 2025.02.06
+ @param txt String
+ @return String
+ */
+ public static String base64encode(String txt)
+ {
+ try
+ {
+ byte[] bytes = Base64.getEncoder().encode((txt).getBytes("utf-8"));
+ return new String(bytes);
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ byte[] bytes = Base64.getEncoder().encode((txt).getBytes());
+ return new String(bytes);
+ }
+ }
+
+ /**
+ 서버(DB)에서 front로 전달시 사용
+ @version 1.0
+ @author 나혁제
+ @since 2025.02.06
+ @param txt String
+ @return String
+ */
+ public static String base64decode(String txt)
+ {
+ byte[] bytes = Base64.getDecoder().decode(txt.getBytes());
+
+ try
+ {
+ return new String(bytes, "utf-8");
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ return new String(bytes);
+ }
+ }
+
+ /**
+ *
+ * 인자로 받은 String이 null일 경우 "0"로 리턴한다.
+ * @param src null값일 가능성이 있는 String 값.
+ * @return 만약 String이 null 값일 경우 "0"로 바꾼 String 값.
+ *
+ */
+ public static int zeroConvert(Object src)
+ {
+ String src2 = src+"";
+ if (src == null || src.equals("null"))
+ {
+ return 0;
+ }
+ else
+ {
+ return Integer.parseInt(((String)src2).trim());
+ }
+ }
+
+ /**
+ *
+ * 인자로 받은 String이 null일 경우 ""로 리턴한다.
+ * @param src null값일 가능성이 있는 String 값.
+ * @return 만약 String이 null 값일 경우 ""로 바꾼 String 값.
+ *
+ */
+ public static int zeroConvert(String src)
+ {
+
+ if (src == null || src.equals("null") || "".equals(src) || " ".equals(src))
+ {
+ return 0;
+ }
+ else
+ {
+ return Integer.parseInt(src.trim());
+ }
+ }
+
+
+
+}
diff --git a/batch/src/main/java/com/urpsys/basebatch/common/util/DataSourceUtil.java b/batch/src/main/java/com/urpsys/basebatch/common/util/DataSourceUtil.java
deleted file mode 100644
index 7b87c9b2..00000000
--- a/batch/src/main/java/com/urpsys/basebatch/common/util/DataSourceUtil.java
+++ /dev/null
@@ -1,113 +0,0 @@
-package com.urpsys.basebatch.common.util;
-
-import javax.sql.DataSource;
-
-import org.apache.ibatis.session.SqlSessionFactory;
-import org.mybatis.spring.SqlSessionFactoryBean;
-import org.springframework.core.env.Environment;
-import org.springframework.core.io.Resource;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-
-import com.urpsys.basebatch.common.crypto.Aes256Cipher;
-import com.urpsys.basebatch.common.exception.CustomException;
-import com.zaxxer.hikari.HikariConfig;
-import com.zaxxer.hikari.HikariDataSource;
-
-import java.util.LinkedHashMap;
-
-/**
- * Datasource 생성하는 유틸리티
- *
- * @author 나혁제
- * @since 2025.04.03
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2025.04.03 나혁제 최초작성
- *
- *
- */
-
-public class DataSourceUtil
-{
- /**
- * 데이터 소스 만드는 메소드
- * @param dataSourceName
- * @param env
- * @param cipher
- * @return
- */
- public static DataSource createDataSource(String dataSourceName, Environment env, Aes256Cipher cipher)
- {
- HikariConfig config = new HikariConfig();
-
- config.setDriverClassName (env.getProperty(dataSourceName + ".driverClassName" ));
- config.setJdbcUrl (env.getProperty(dataSourceName + ".jdbcUrl" ));
-
- config.setUsername (cipher.decrypt(env.getProperty(dataSourceName + ".username")));
- config.setPassword (cipher.decrypt(env.getProperty(dataSourceName + ".password")));
-
- config.setAutoCommit(false);
-
- config.setMaximumPoolSize (Integer.parseInt(env.getProperty(dataSourceName + ".maximumPoolSize" )));
- config.setMinimumIdle (Integer.parseInt(env.getProperty(dataSourceName + ".minimumIdle" )));
- config.setConnectionTimeout (Long.parseLong (env.getProperty(dataSourceName + ".connectionTimeout" )));
- config.setIdleTimeout (Long.parseLong (env.getProperty(dataSourceName + ".idleTimeout" )));
-
- config.addDataSourceProperty("cachePrepStmts" , "true");
- config.addDataSourceProperty("prepStmtCacheSize" , "250");
- config.addDataSourceProperty("prepStmtCacheSqlLimit" , "2048");
-
- return new HikariDataSource(config);
- }
-
- /**
- * SqlSessionFactory 만드는 메소드
- * @param dataSource
- * @param configLocation
- * @param mapperLocation
- * @return
- * @throws CustomException
- */
- public static SqlSessionFactory createSqlSessionFactory(DataSource dataSource, Resource configLocation,
- Resource[] mapperLocation) throws CustomException
- {
- SqlSessionFactory sqlSessionFactory;
-
- try {
- SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
- sessionFactoryBean.setDataSource(dataSource);
- sessionFactoryBean.setConfigLocation(configLocation);
- sessionFactoryBean.setMapperLocations(mapperLocation);
-
- sqlSessionFactory = sessionFactoryBean.getObject();
- }
- catch (Exception ex)
- {
- throw new CustomException(ex.getMessage());
- }
-
- return sqlSessionFactory;
- }
-
- /**
- * 트랜잭션 처리 메소드
- * @param dataSource
- * @return
- */
- public static DataSourceTransactionManager createTxManager(DataSource dataSource)
- {
- DataSourceTransactionManager txManager = new DataSourceTransactionManager(dataSource);
- txManager.setGlobalRollbackOnParticipationFailure(false);
-
- return txManager;
- }
-
- //end method
-}
diff --git a/batch/src/main/java/com/urpsys/basebatch/common/util/RestApiCallUtil.java b/batch/src/main/java/com/urpsys/basebatch/common/util/RestApiCallUtil.java
index 6cffd813..94dc15d9 100644
--- a/batch/src/main/java/com/urpsys/basebatch/common/util/RestApiCallUtil.java
+++ b/batch/src/main/java/com/urpsys/basebatch/common/util/RestApiCallUtil.java
@@ -1,375 +1,375 @@
-package com.urpsys.basebatch.common.util;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.crypto.Mac;
-import javax.crypto.spec.SecretKeySpec;
-
-import org.apache.commons.codec.binary.Base64;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.core.env.Environment;
-import org.springframework.stereotype.Component;
-
-import com.urpsys.basebatch.common.exception.CustomException;
-import com.urpsys.basebatch.domain.TokenInfo;
-import com.urpsys.basebatch.common.util.ConvertUtils;
-
-import kong.unirest.HttpRequestWithBody;
-import kong.unirest.HttpResponse;
-import kong.unirest.JsonNode;
-import kong.unirest.Unirest;
-import kong.unirest.json.JSONObject;
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * Rest Api 을 호출하는 필요한 유틸리티 클래스
- *
- * @author urp 인프라본부 나혁제
- * @since 2025.03.20
- * @version 1.0.0
- * @see
- *
- *
- *
- * << 개정이력(Modification information) >>
- *
- * 수정일 수정자 수정내용
- * ----------- --------- ------------------------
- * 2025.03.20 나혁제 최초작성
- *
- *
- */
-
-
-@Slf4j
-@Component("RestApiCallUtil")
-public class RestApiCallUtil
-{
- @Value("${custom.sendkakaoTalk.serviceId}")
- private String strServiceId;
-
- @Value("${custom.sendkakaoTalk.accessKey}")
- private String strAccessKey;
-
- @Value("${custom.sendkakaoTalk.secretKey}")
- private String strSecretKey;
-
- @Value("${custom.sendkakaoTalk.friendId}")
- private String strFriendId;
-
- @Value("${custom.api_search_server}")
- private String strApiSearchSvr; // API 서버
-
-
- @Value("${custom.api_kic_mail_server}")
- private String strKicMailSvr; // KIC 메일서버
-
- @Value("${custom.api_kic_msg_server}")
- private String strKicMsgSvr; // KIC 메신저서버
-
- /**
- 네이버 클라우드 카톡 서비스 호출
- @author 나혁제
- @since 2025.03.20
- @param : TokenInfo tokenInfo
- , Map bodyMap
- , String strRestUrl
- @return Map
- * @throws CustomException
- */
- public Map RestApiCallNaverCloudKaKao(String strTemplateCd, String to, String msg) throws CustomException
- {
- log.info(">>>>>>>>>>>>>>> RestApiCallNaverCloudKaKao <<<<<<<<<<<<<<<");
-
- long timestamp = System.currentTimeMillis();
-
- String strTime = timestamp+"";
-
- String strContentType = "application/json; charset=utf-8" ;
-
- String strSignature = makeSignature(strTime, strServiceId, strAccessKey, strSecretKey);
-
- // Header Setting Start ---------------------------------
- Map headers = new HashMap<>();
- headers.put("Content-Type" , strContentType );
- headers.put("x-ncp-apigw-timestamp" , strTime );
- headers.put("x-ncp-iam-access-key" , strAccessKey );
- headers.put("x-ncp-apigw-signature-v2" , strSignature );
- // Header Setting End ---------------------------------
-
- log.info("headers 입력값 확인 => [{}]", headers.toString());
-
- Map bodyMap = new HashMap<>();
-
- bodyMap.put("plusFriendId" , "@"+strFriendId );
- bodyMap.put("templateCode" , strTemplateCd );
-
- List