refs #702: externalize HMM structured data catalog
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
package com.cloudhandson.vpdbackoffice.service;
|
||||
|
||||
import com.cloudhandson.vpdbackoffice.domain.structured.StructuredDataCatalog;
|
||||
import com.cloudhandson.vpdbackoffice.domain.structured.StructuredDataPreview;
|
||||
import com.cloudhandson.vpdbackoffice.domain.structured.StructuredDataTable;
|
||||
import java.util.List;
|
||||
@@ -11,33 +12,35 @@ import org.springframework.stereotype.Service;
|
||||
@Service
|
||||
public class StructuredDataService {
|
||||
|
||||
private static final String OWNER = "POC_2";
|
||||
private static final int ROW_LIMIT = 50;
|
||||
private static final List<StructuredDataTable> TABLES = List.of(
|
||||
new StructuredDataTable("customers", "KB_CUSTOMERS", "고객원장", "고객 기본정보"),
|
||||
new StructuredDataTable("products", "KB_PRODUCTS", "상품원장", "보험상품 마스터"),
|
||||
new StructuredDataTable("contracts", "KB_CONTRACTS", "계약원장", "보험계약 정보"),
|
||||
new StructuredDataTable("coverages", "KB_COVERAGES", "담보원장", "보장·특약 정보"),
|
||||
new StructuredDataTable("claims", "KB_CLAIMS", "청구원장", "보험금 청구·지급 정보"),
|
||||
new StructuredDataTable("external-holdings", "KB_EXTERNAL_HOLDINGS", "외부보유정보 원장", "타사·외부 가입·보유 정보"),
|
||||
new StructuredDataTable("stakeholders", "KB_STAKEHOLDERS", "이해관계자 원장", "역할·담당자 매핑"));
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
private final StructuredDataCatalog catalog;
|
||||
|
||||
public StructuredDataService(JdbcTemplate jdbcTemplate) {
|
||||
public StructuredDataService(
|
||||
JdbcTemplate jdbcTemplate,
|
||||
StructuredDataCatalogProvider catalogProvider
|
||||
) {
|
||||
this.jdbcTemplate = jdbcTemplate;
|
||||
this.catalog = catalogProvider.catalog();
|
||||
}
|
||||
|
||||
public StructuredDataCatalog catalog() {
|
||||
return catalog;
|
||||
}
|
||||
|
||||
public String owner() {
|
||||
return catalog.owner();
|
||||
}
|
||||
|
||||
public List<StructuredDataTable> tables() {
|
||||
return TABLES;
|
||||
return catalog.tables();
|
||||
}
|
||||
|
||||
public String defaultKey() {
|
||||
return TABLES.getFirst().key();
|
||||
return catalog.tables().getFirst().key();
|
||||
}
|
||||
|
||||
public StructuredDataTable requireTable(String key) {
|
||||
return TABLES.stream()
|
||||
return catalog.tables().stream()
|
||||
.filter(table -> table.key().equals(key))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new AppException("선택할 수 없는 정형 데이터 테이블입니다."));
|
||||
@@ -53,17 +56,22 @@ public class StructuredDataService {
|
||||
WHERE owner = ?
|
||||
AND table_name = ?
|
||||
ORDER BY column_id
|
||||
""",
|
||||
(resultSet, rowNum) -> resultSet.getString(1), OWNER, table.tableName());
|
||||
""",
|
||||
(resultSet, rowNum) -> resultSet.getString(1), catalog.owner(), table.tableName());
|
||||
if (columns.isEmpty()) {
|
||||
throw new AppException("정형 데이터 테이블의 컬럼 정보를 찾을 수 없습니다.");
|
||||
}
|
||||
List<String> previewColumns = table.previewColumns().isEmpty() ? columns : table.previewColumns();
|
||||
if (!columns.containsAll(previewColumns)) {
|
||||
throw new AppException("정형 데이터 JSON의 미리보기 컬럼이 실제 테이블과 일치하지 않습니다.");
|
||||
}
|
||||
|
||||
List<Map<String, Object>> rows = jdbcTemplate.queryForList(
|
||||
previewSql(table), ROW_LIMIT);
|
||||
return new StructuredDataPreview(table, columns, rows, ROW_LIMIT);
|
||||
previewSql(table, previewColumns), catalog.rowLimit());
|
||||
return new StructuredDataPreview(table, previewColumns, rows, catalog.rowLimit());
|
||||
} catch (DataAccessException exception) {
|
||||
throw new AppException("정형 데이터를 조회할 수 없습니다. POC_2 조회 권한과 대상 테이블 상태를 확인하세요.");
|
||||
throw new AppException("정형 데이터를 조회할 수 없습니다. " + catalog.sourceName() + "의 "
|
||||
+ catalog.owner() + " 조회 권한과 대상 테이블 상태를 확인하세요.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,16 +79,20 @@ public class StructuredDataService {
|
||||
* The table is selected from a closed application whitelist, so the query
|
||||
* text remains fixed and no request value can become a SQL identifier.
|
||||
*/
|
||||
private String previewSql(StructuredDataTable table) {
|
||||
return switch (table.key()) {
|
||||
case "customers" -> "SELECT * FROM POC_2.KB_CUSTOMERS WHERE ROWNUM <= ?";
|
||||
case "products" -> "SELECT * FROM POC_2.KB_PRODUCTS WHERE ROWNUM <= ?";
|
||||
case "contracts" -> "SELECT * FROM POC_2.KB_CONTRACTS WHERE ROWNUM <= ?";
|
||||
case "coverages" -> "SELECT * FROM POC_2.KB_COVERAGES WHERE ROWNUM <= ?";
|
||||
case "claims" -> "SELECT * FROM POC_2.KB_CLAIMS WHERE ROWNUM <= ?";
|
||||
case "external-holdings" -> "SELECT * FROM POC_2.KB_EXTERNAL_HOLDINGS WHERE ROWNUM <= ?";
|
||||
case "stakeholders" -> "SELECT * FROM POC_2.KB_STAKEHOLDERS WHERE ROWNUM <= ?";
|
||||
default -> throw new AppException("선택할 수 없는 정형 데이터 테이블입니다.");
|
||||
};
|
||||
String previewSql(StructuredDataTable table) {
|
||||
return previewSql(table, table.previewColumns());
|
||||
}
|
||||
|
||||
private String previewSql(StructuredDataTable table, List<String> previewColumns) {
|
||||
StructuredDataTable approved = requireTable(table.key());
|
||||
if (!approved.tableName().equals(table.tableName())) {
|
||||
throw new AppException("선택할 수 없는 정형 데이터 테이블입니다.");
|
||||
}
|
||||
String projection = previewColumns == null || previewColumns.isEmpty()
|
||||
? "*"
|
||||
: previewColumns.stream().map(column -> "\"" + column + "\"")
|
||||
.reduce((left, right) -> left + ", " + right).orElseThrow();
|
||||
return "SELECT " + projection + " FROM \"" + catalog.owner() + "\".\"" + approved.tableName()
|
||||
+ "\" WHERE ROWNUM <= ?";
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user