Initial commit
This commit is contained in:
@@ -0,0 +1,489 @@
|
||||
= 시스템 설정
|
||||
|
||||
SDL은 다양한 시스템 환경에 적용 할 수 있도록 여러가지 설정파일을 제공한다. sdl-base/src/resources-{profile} 폴더안에 profile 별로 다른 설정 파일들이 실행 될 수 있도록 구성되어 있다.
|
||||
|
||||
== config.properties
|
||||
|
||||
SDL 가장 중요한 설정 파일로 시스템 전반에 영향을 준다. 로컬, 개발, 운영환경마다 내용이 달라질 수 있으니 패키징 시 설정값들이 맞는지 확인하고 배포 할 수 있도록 주의한다.
|
||||
|
||||
[cols=".^1h,.^1,.^2,.^2",options="header"]
|
||||
|====
|
||||
| key | value(예) | 설명 | 주의
|
||||
|
||||
| node-id
|
||||
| localNode
|
||||
| 서버 식별을 위한 ID
|
||||
| 서버가 여러 대 있을 경우 ID값을 다르게 해야한다.
|
||||
|
||||
| ssl-port
|
||||
| 8443
|
||||
| http로 접근 했을 때 자동으로 redirection 하기 위한 https 포트
|
||||
| 기본값은 443
|
||||
|
||||
| cors.domain
|
||||
| *
|
||||
| CORS를 허용하기 위한 값으로 브라우저에서 다른 도메인으로 데이터 호출을 가능하게 한다.
|
||||
| *, sdl.sec.sasmsung.net
|
||||
|
||||
| web-context-path
|
||||
| /
|
||||
| 웹서버의 web-context-path
|
||||
| 페이지 경로 앞에 참조
|
||||
|
||||
| datasource.driver
|
||||
| ENC(txFyC35/92LBzew8iq2DjoFINRYg6e1UMcq7Du2mvs/nIqTSAU6e2r4VcyKrNc+K)
|
||||
| DMBS의 driver class name
|
||||
| 중요 프로퍼티 정보 암호화. 자세한 내용은 <<_server_실행, 프로퍼티 값 암호화>> 관련 부분 참조
|
||||
|
||||
| datasource.url
|
||||
| ENC(N2SavucpTKhakXUzUGpVLh+Hy2UQ5EyQJKBMJfagFbTB0VR9m8KO7LmPM6GFRBPWgjEOYJx1hWtFrCsHctjYZQ==)
|
||||
| DMBS의 url
|
||||
| 중요 프로퍼티 정보 암호화. 자세한 내용은 <<_server_실행, 프로퍼티 값 암호화>> 관련 부분 참조
|
||||
|
||||
|datasource.username
|
||||
| ENC(xS5l219WYApjTijLj8gwAw==)
|
||||
| DMBS의 사용자
|
||||
| 중요 프로퍼티 정보 암호화. 자세한 내용은 <<_server_실행, 프로퍼티 값 암호화>> 관련 부분 참조
|
||||
|
||||
| datasource.password
|
||||
| ENC(WHYsCYza7ffqN8Wi7FtTwTBI0dP9wHy2)
|
||||
| DMBS의 패스워드
|
||||
| 중요 프로퍼티 정보 암호화. 자세한 내용은 <<_server_실행, 프로퍼티 값 암호화>> 관련 부분 참조
|
||||
|
||||
| db.jndi
|
||||
| sdl_ds
|
||||
| WAS Datasource의 JNDI명
|
||||
| 개발,운영 환경에서는 WAS의 Datasource를 사용한다.
|
||||
|
||||
| web-content-root-path
|
||||
| http://localhost:8081
|
||||
| Web 서버의 Root의 경로
|
||||
| 클라이언트로 redirect 할 경우 참조 (ex. AD인증 후)
|
||||
|
||||
| static-resource-path
|
||||
| http://localhost:8081/static
|
||||
| css, image가 있는 경로
|
||||
| HTML Template (ex. Velocity) 에서 참조
|
||||
|
||||
| base.package
|
||||
| com.samsung
|
||||
| 클래스를 찾을 때 해당 패키지 아래에서만 찾는다.
|
||||
| 결재 문서를 찾을 때 참조
|
||||
|
||||
| entity.package-name
|
||||
| entity
|
||||
| 결재 문서를 찾을 때 entity 패키지 아래의 클래스만 찾는다.
|
||||
| 반드시 @ApprovalDocument가 선언되어 있어야 한다.
|
||||
|
||||
| login.sso.knox-tray-private-key-path
|
||||
| /rsaprivkey8.pem
|
||||
| NewEpTray PrivateKey 경로
|
||||
| <<_로그인, 로그인>> 부분 참조
|
||||
|
||||
| login.auto-sign-up
|
||||
| true
|
||||
| Knox 및 AD 사용자 자동 가입 허용
|
||||
| 사용자 인증 후 시스템에 자동 가입된다.
|
||||
|
||||
| user.auto-permission
|
||||
| true
|
||||
| 사용자가 시스템 가입 신청시 자동 승인
|
||||
| false 시 승인대기 후 관리자 승인 절차
|
||||
|
||||
| privacy-policy.check.enabled
|
||||
| true
|
||||
| 시스템 이용 약관 동의 필터 사용 여부
|
||||
| false 시 약관 동의 여부 체크하지 않는다
|
||||
|
||||
| privacy-policy.check.exclude-path
|
||||
| /privacypolicy/terms/valid
|
||||
| 사용자가 약관을 동의 했는지 체크하는 필터 예외 path
|
||||
|
|
||||
|
||||
| email.limit-body
|
||||
| 1048576
|
||||
| email 본문의 길이
|
||||
| 발신 API에서 본문 사이즈는 최대 1mb까지 입력 가능 (Knox기준)
|
||||
|
||||
| email.limit-recipients
|
||||
| 100
|
||||
| 최대 수신인
|
||||
| 입력 가능한 최대 수신인 수는 100명 (Knox기준)
|
||||
|
||||
| batch.user.sync.retire.enabled
|
||||
| false
|
||||
| 퇴직자 처리 배치 사용여부
|
||||
| 별도의 사용자 정보 데이터가 동기화 되어 있어야 한다.
|
||||
|
||||
| batch.user.sync.cron
|
||||
| 0 10 23 * * ?
|
||||
| 사용자동기화 배치 스케줄
|
||||
|
|
||||
|
||||
| batch.user.long-term.month
|
||||
| 3
|
||||
| 장기미사용자 판단 기준(월)
|
||||
|
|
||||
|
||||
| batch.user.long-term-check.cron
|
||||
| 0 10 00 * * ?
|
||||
| 장기미사용자 처리 배치 스케줄
|
||||
|
|
||||
|
||||
| batch.user.auth-expired.alarm.before
|
||||
| 1,7,14
|
||||
| 권한만료 알림 메일 발송일
|
||||
| 1일전,7일전,14일전
|
||||
|
||||
| batch.user.auth-expired.cron
|
||||
| 0 10 02 * * ?
|
||||
| 권한만료 처리 배치 스케줄
|
||||
|
|
||||
|
||||
| batch.user.auth-expired-mailing.cron
|
||||
| 0 30 02 * * ?
|
||||
| 권한만료 알림 메일 배치 스케줄
|
||||
|
|
||||
|
||||
| batch.sys-use-log.menu-use-history.cron
|
||||
| 0 10 01 * * ?
|
||||
| 메뉴사용이력 배치 스케줄
|
||||
|
|
||||
|
||||
| batch.sys-use-log.menu-utilization.cron
|
||||
| 0 30 01 * * ?
|
||||
| 메뉴활용도 배치 스케줄
|
||||
|
|
||||
|
||||
| security.sql-injection.allowed-pattern
|
||||
| .\*[^a-zA-Z0-9_\\s,].\*
|
||||
| SQL에 허용되는 문자
|
||||
| 영문 대소문자, 숫자, 스페이스, 콤마만 허용
|
||||
|
||||
| security.authentication.exclude-path
|
||||
| /\\**/noauth/**
|
||||
| 권한,인증 체크에서 제외되는 url
|
||||
|
|
||||
|
||||
| security.jwt.secret-key
|
||||
|
|
||||
| jwt를 암복호화 하기 위한 키 (256bits 이상)
|
||||
| 시스템별로 상이해야 하며 키가 유출되지 않도록 주의해야 한다.
|
||||
|
||||
| security.jwt.expiration-time
|
||||
| 8
|
||||
| jwt 토큰 유지 시간
|
||||
| 요청시 마다 체크. 유효하지 않을 경우 로그아웃
|
||||
|
||||
| security.eptray.expiration-time
|
||||
| 24
|
||||
| eptray 유지 시간
|
||||
| eptray 로그인시 체크. 이 시간이 경과되면 Knox 재로그인 필요
|
||||
|
||||
| security.check.access.timeout
|
||||
| true
|
||||
| TimeoutCheckInterceptor 사용 여부
|
||||
| 시스템을 일정시간 사용하지 않을 경우 로그아웃
|
||||
|
||||
| security.access.limit.timeout
|
||||
| 30
|
||||
| 타임아웃 체크 기준 시간
|
||||
|
|
||||
|
||||
| security.check.duplicate.login
|
||||
| false
|
||||
| 사용자 중복 로그인 체크 여부
|
||||
|
|
||||
|
||||
| access-log.store-type
|
||||
| db
|
||||
| Access Log 저장 방식
|
||||
| db, file
|
||||
|
||||
| access-log.exclude-path
|
||||
| /\\**/noauth/**
|
||||
| Access Log에 기록 하지 않을 path
|
||||
|
|
||||
|
||||
| access-log.batch.enabled
|
||||
| true
|
||||
| 시스템 사용 이력 통계 배치 실행 여부
|
||||
|
|
||||
|
||||
| access-log.file-path
|
||||
| /logs/access
|
||||
| Access Log 파일 저장 위치
|
||||
| Access Log 저장 방식이 file 일 때 참조
|
||||
|
||||
| menu-utilization.retention-period
|
||||
| 24
|
||||
| 메뉴 활용도 보관 기간
|
||||
|
|
||||
|
||||
| common.upload-path
|
||||
| /NAS/upload
|
||||
| 업로드 파일 저장 위치
|
||||
|
|
||||
|
||||
| common.upload.directory-name-len
|
||||
| 2
|
||||
| 업로드 파일의 디렉토리명 길이
|
||||
|
|
||||
|
||||
| common.download.zipfilename
|
||||
| compressed
|
||||
| 모두 다운 받기 할때 zip 파일 이름 기본값
|
||||
|
|
||||
|
||||
| common.upload.allowed-extensions
|
||||
| xls,jpg
|
||||
| 업로드 가능한 파일의 확장자
|
||||
|
|
||||
|
||||
| common.excel-upload-path
|
||||
| /excel
|
||||
| 엑셀 업로드 임시 저장 폴더
|
||||
|
|
||||
|
||||
| common.upload.max-file-size
|
||||
| -1
|
||||
| 업로드 가능한 개별 파일 크기 (바이트)
|
||||
| -1일 때 제한 없음
|
||||
|
||||
| common.upload.max-request-size
|
||||
| -1
|
||||
| 모든 파일 및 폼 데이터를 포함한 전체 멀티파트 요청 크기 (바이트)
|
||||
| -1일 때 제한 없음
|
||||
|
||||
| common.upload.default-encoding
|
||||
| UTF-8
|
||||
| 요청을 파싱할 때 사용할 캐릭터 인코딩
|
||||
|
|
||||
|
||||
| custom.upload-path.enabled
|
||||
| false
|
||||
| 사용자지정 업로드 패스 설정 여부
|
||||
|
|
||||
|
||||
| custom.upload-path
|
||||
| notice=/nas/sdl/upload/notice,\ +
|
||||
faq=/nas/sdl/upload/faq
|
||||
| 사용자지정 업로드 패스 설정 값
|
||||
|
|
||||
|
||||
| excel.mapping.locations
|
||||
| classpath*:/excel/*.xml
|
||||
| excel mapping file 위치
|
||||
|
|
||||
|
||||
| excel.mapping.reloadInterval
|
||||
| 10000
|
||||
| excel mapping file 리로딩 시간
|
||||
| 밀리 세컨, 0일 경우 리로딩 하지 않음
|
||||
|
||||
| common.server-time-zone-id
|
||||
| Asia/Seoul
|
||||
| 서버 time zone id
|
||||
| 사용자 정보내 timezone 설정이 없을떄 기본으로 설정 되는 값
|
||||
|
||||
| common.server-time-zone
|
||||
| GMT+9:00
|
||||
| 서버 time zone
|
||||
| 사용자 정보내 timezone 설정이 없을떄 기본으로 설정 되는 값
|
||||
|
||||
| knox.approval.sync.cron
|
||||
| 0 0/3 * * * ?
|
||||
| 결재 문서 상태 동기화 주기
|
||||
|
|
||||
|
||||
| language-set
|
||||
| ko_KR,en_US
|
||||
| 시스템 언어셋
|
||||
| 메세지 프로퍼티 로케일 정보
|
||||
|
||||
| api.utrans.url
|
||||
|
|
||||
| utrans 서버 주소
|
||||
|
|
||||
|
||||
| api.utrans.type
|
||||
|
|
||||
| utrans type
|
||||
|
|
||||
|
||||
| api.utrans.key
|
||||
|
|
||||
| utrans key
|
||||
|
|
||||
|
||||
| admin.address.check
|
||||
| false
|
||||
| 시스템 관리자의 ip 제한
|
||||
|
|
||||
|
||||
| system.email
|
||||
|
|
||||
| 시스템 대표 email 주소
|
||||
| Knox에 등록된 계정이어야 함
|
||||
|====
|
||||
|
||||
== knox.properties
|
||||
|
||||
knox 서비스를 연계를 위해 필요한 설정들이다. Knox Staging, Production 에 따라 값이 다르니 반드시 환경에 맞는 값들이 설정됐는지 확인 후 배포한다.
|
||||
|
||||
IMPORTANT: 1. Knox Stage 연계 시 Knox Stage 계정이 있어야 한다. 특히 메일, 결재 연계를 개발 할 때 Stage에 없는 사용자에게 메일을 보내거나 결재를 상신한다면 오류가 발생하니 반드시 사용자 계정이 있는지 확인 한다. +
|
||||
2. Knox 연계 신청, 연계 오류 관련 문의는 Knox Support를 통해 문의 한다. +
|
||||
3. Knox 운영 거점은 한국, 구주, 미주 3곳이 있으므로 연계 신청시 사용자 위치에 따라 거점 신청에 주의하도록 한다. 거점 연계가 안되어 있는 사용자는 결재, 메일 기능을 사용 할 수 없다.
|
||||
|
||||
[cols="3*",options="header"]
|
||||
|====
|
||||
|key | value | 설명
|
||||
|
||||
| knox.system-id
|
||||
|
|
||||
| Knox 연계 신청 시 받은 시스템 ID
|
||||
|
||||
| knox.token
|
||||
| token1, token2, token3
|
||||
| Knox 연계 신청 시 받은 token
|
||||
|
||||
| knox.address.prefix
|
||||
| openapi.samsung.net,openapi.w1.samsung.net,openapi.w2.samsung.net
|
||||
| 한국,구주,미주 서비스 주소
|
||||
|====
|
||||
|
||||
CAUTION: token과 서비스 주소는 반드시 쌍으로 등록한다.
|
||||
|
||||
== 캐시 (Cache)
|
||||
|
||||
SDL은 빈번하게 요청되는 데이터 값을 저장하고 필요시 데이터를 빠르게 불러 올수 있도록 스프링 프레임워크에서 제공하는 캐시를 사용한다. 스프링 캐싱 서비스는 추상화로 제공되므로 캐시 Provider 별 CacheManager 를 구현하여 빈으로 등록을 해야한다.
|
||||
|
||||
NOTE: SDL의 로컬 개발환경에서는 스프링 Simple Provider(ConcurrentHashMap)를 사용하고 있으며, 캐시 공유가 필요한 운영 환경에서는 Redis 라이브러리를 사용하고 있다. 자세한 설정은 스프링 부트 공식문서를 참조하도록 하고 본 문서에서는 SDL에서 사용하고 있는 캐시 데이터 중심으로 설명한다.
|
||||
|
||||
* message-all
|
||||
|
||||
MessageBundleService getMessage의 결과를 저장한다. Spring MessageSource의 모든 언어에 대한 Key, Value를 리턴한다.
|
||||
[source, java]
|
||||
----
|
||||
@Cacheable(value = "message-all")
|
||||
public Map<String, Map<String, String>> getMessage() {
|
||||
Map<String, Map<String, String>> message = new HashMap<>();
|
||||
for (String locale : languageSet) {
|
||||
message.put(locale, getMessageByLang(new Locale(locale.split("_")[0], locale.split("_")[1])));
|
||||
}
|
||||
return message;
|
||||
}
|
||||
----
|
||||
|
||||
* message
|
||||
|
||||
MessageBundleService getMessageByLang의 결과를 저장한다. locale일 별로 Spring MessageSource의 Key, Value를 리턴한다.
|
||||
[source, java]
|
||||
----
|
||||
@Cacheable(value = "message", key = "#locale")
|
||||
public Map<String, String> getMessageByLang(Locale locale) {
|
||||
Set<String> beanNames = messageSource.getBasenameSet();
|
||||
Map<String, String> message = new HashMap<>();
|
||||
for (String beanName : beanNames) {
|
||||
ResourceBundle resourceBundle = ResourceBundle.getBundle(StringUtils.remove(beanName, "classpath:/"), locale);
|
||||
Enumeration<String> keys = resourceBundle.getKeys();
|
||||
while (keys.hasMoreElements()) {
|
||||
String key = keys.nextElement();
|
||||
String javaVersion = StringUtils.substringBeforeLast(System.getProperty("java.version"), ".");
|
||||
if (Float.parseFloat(javaVersion) < 1.9) {
|
||||
message.put(key, new String(resourceBundle.getString(key).getBytes(StandardCharsets.ISO_8859_1), StandardCharsets.UTF_8));
|
||||
} else {
|
||||
message.put(key, resourceBundle.getString(key));
|
||||
}
|
||||
}
|
||||
}
|
||||
return message;
|
||||
}
|
||||
----
|
||||
|
||||
* menu-all
|
||||
|
||||
MenuService getAllMenuPagePaths 시스템의 모든 메뉴, 메뉴 패스를 저장한다.
|
||||
|
||||
[source, java]
|
||||
----
|
||||
@Cacheable(value = "menu-all")
|
||||
@Override
|
||||
public List<Map<String, String>> getAllMenuPagePaths() {
|
||||
return menuDao.getAllMenuPagePaths();
|
||||
}
|
||||
----
|
||||
|
||||
* api-user
|
||||
|
||||
ApiService getUserAuthApiListByUserId 사용자ID를 기준으로 접근할 수 있는 API 목록을 저장한다. 사용자가 늘어날 수록 캐시되는 데이터가 많으니
|
||||
캐시 관리에 주의하도록 한다.
|
||||
[source, java]
|
||||
----
|
||||
@Override
|
||||
@Cacheable(value = "api-user", key = "#userId")
|
||||
public List<Api> getUserAuthApiListByUserId(String userId) {
|
||||
return apiDao.getUserAuthApiListByUserId(userId);
|
||||
}
|
||||
----
|
||||
|
||||
* api-user-menu
|
||||
|
||||
ApiService getUserAuthApiListByUserId 사용자ID와 메뉴ID를 기준으로 접근할 수 있는 API 목록을 저장한다. 사용자가 늘어날 수록 캐시되는 데이터가 많으니
|
||||
캐시 관리에 주의하도록 한다.
|
||||
[source, java]
|
||||
----
|
||||
@Override
|
||||
@Cacheable(value = "api-user-menu", key = "#userId.concat(':').concat(#menuId)")
|
||||
public List<Api> getUserAuthApiListByUserIdAndMenuId(String userId, String menuId) {
|
||||
return apiDao.getApiListByUserIdAndMenuId(userId, menuId);
|
||||
}
|
||||
----
|
||||
|
||||
* page-all-by-menu-auth
|
||||
|
||||
ResourceCacheService getAllPageListByAuth 모든 메뉴의 페이지별 권한 타입을 저장한다.
|
||||
[source, java]
|
||||
----
|
||||
@Cacheable(value = "page-all-by-menu-auth")
|
||||
public Map<String, Map<String, List<Page>>> getAllPageListByAuth() {
|
||||
log.debug("PageService Start.");
|
||||
Map<String, Map<String, List<Page>>> menuAuthMap = new HashMap<>();
|
||||
|
||||
Map<String, List<Page>> menuMap = getAllPageListByMenu();
|
||||
for (Map.Entry<String, List<Page>> entry : menuMap.entrySet()) {
|
||||
|
||||
List<Page> authPageList = entry.getValue();
|
||||
Map<String, List<Page>> authMap = new HashMap<>();
|
||||
|
||||
authMap.put("READ", authPageList.stream().filter(page -> "READ".equals(page.getAuthorizationType())).collect(Collectors.toList()));
|
||||
authMap.put("UPDATE", authPageList.stream().filter(page -> "UPDATE".equals(page.getAuthorizationType())).collect(Collectors.toList()));
|
||||
authMap.put("DOWNLOAD", authPageList.stream().filter(page -> "DOWNLOAD".equals(page.getAuthorizationType())).collect(Collectors.toList()));
|
||||
authMap.put("EXECUTE", authPageList.stream().filter(page -> "EXECUTE".equals(page.getAuthorizationType())).collect(Collectors.toList()));
|
||||
menuAuthMap.put(entry.getKey(), authMap);
|
||||
}
|
||||
log.debug("menuAuthMap : {}", menuAuthMap);
|
||||
return menuAuthMap;
|
||||
}
|
||||
----
|
||||
|
||||
* page-full-path-all
|
||||
|
||||
MenuService getPageFullPathList 모든 메뉴 full path를 저장한다.
|
||||
[source, java]
|
||||
----
|
||||
@Cacheable(value="page-full-path-all")
|
||||
@Override
|
||||
public Map<String, String> getPageFullPathList() {
|
||||
|
||||
List<Map<String, String>> pageFullPathList = menuDao.getPageFullPathList();
|
||||
|
||||
Map<String, String> pageFullPathMap = new HashMap<>();
|
||||
|
||||
for(Map<String, String> pageFullPath : pageFullPathList) {
|
||||
pageFullPathMap.put(pageFullPath.get("pageId"), pageFullPath.get("fullPath"));
|
||||
}
|
||||
|
||||
return pageFullPathMap;
|
||||
}
|
||||
----
|
||||
Reference in New Issue
Block a user