[Developer] #424 use ORDS metadata datasource for handler creation
This commit is contained in:
@@ -28,6 +28,11 @@ export BACKOFFICE_ADMIN_USER="admin"
|
|||||||
export BACKOFFICE_ADMIN_PASSWORD="admin"
|
export BACKOFFICE_ADMIN_PASSWORD="admin"
|
||||||
export BACKOFFICE_ORDS_BASE_URL="https://yh0olybn5pqce4n-d8aukro81636mon0.adb.ap-seoul-1.oraclecloudapps.com/ords"
|
export BACKOFFICE_ORDS_BASE_URL="https://yh0olybn5pqce4n-d8aukro81636mon0.adb.ap-seoul-1.oraclecloudapps.com/ords"
|
||||||
export BACKOFFICE_ORDS_TIMEOUT_SECONDS="10"
|
export BACKOFFICE_ORDS_TIMEOUT_SECONDS="10"
|
||||||
|
# ORDS metadata 생성/수정 전용 계정. 비워두면 BACKOFFICE_DB_* 연결을 사용하므로
|
||||||
|
# ADMIN으로 실행 중이면 Handler 생성은 막히고 소스 보기만 사용합니다.
|
||||||
|
export BACKOFFICE_ORDS_DB_URL="${BACKOFFICE_DB_URL}"
|
||||||
|
export BACKOFFICE_ORDS_DB_USERNAME="CB_ORDS"
|
||||||
|
export BACKOFFICE_ORDS_DB_PASSWORD=""
|
||||||
|
|
||||||
# --- (2c) OpenAI 호환 AI 호출 (MCP-style Reasoning 탭) ---
|
# --- (2c) OpenAI 호환 AI 호출 (MCP-style Reasoning 탭) ---
|
||||||
export BACKOFFICE_AI_ENABLED="false"
|
export BACKOFFICE_AI_ENABLED="false"
|
||||||
|
|||||||
@@ -6,8 +6,13 @@ import com.cloudhandson.vpdbackoffice.domain.ords.OrdsObjectHandlerResult;
|
|||||||
import com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedColumn;
|
import com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedColumn;
|
||||||
import com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedObject;
|
import com.cloudhandson.vpdbackoffice.domain.protectedobject.ProtectedObject;
|
||||||
import com.cloudhandson.vpdbackoffice.mapper.OrdsMetadataMapper;
|
import com.cloudhandson.vpdbackoffice.mapper.OrdsMetadataMapper;
|
||||||
|
import com.zaxxer.hikari.HikariConfig;
|
||||||
|
import com.zaxxer.hikari.HikariDataSource;
|
||||||
|
import jakarta.annotation.PreDestroy;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -17,16 +22,38 @@ public class OrdsMetadataService {
|
|||||||
|
|
||||||
private final OrdsMetadataMapper mapper;
|
private final OrdsMetadataMapper mapper;
|
||||||
private final JdbcTemplate jdbcTemplate;
|
private final JdbcTemplate jdbcTemplate;
|
||||||
|
private final JdbcTemplate ordsMetadataJdbcTemplate;
|
||||||
|
private final HikariDataSource ordsMetadataDataSource;
|
||||||
private final ProtectedObjectService protectedObjectService;
|
private final ProtectedObjectService protectedObjectService;
|
||||||
|
|
||||||
public OrdsMetadataService(
|
public OrdsMetadataService(
|
||||||
OrdsMetadataMapper mapper,
|
OrdsMetadataMapper mapper,
|
||||||
JdbcTemplate jdbcTemplate,
|
JdbcTemplate jdbcTemplate,
|
||||||
ProtectedObjectService protectedObjectService
|
ProtectedObjectService protectedObjectService,
|
||||||
|
DataSource dataSource,
|
||||||
|
@Value("${backoffice.ords.metadata-db.url:}") String ordsMetadataUrl,
|
||||||
|
@Value("${backoffice.ords.metadata-db.username:}") String ordsMetadataUsername,
|
||||||
|
@Value("${backoffice.ords.metadata-db.password:}") String ordsMetadataPassword
|
||||||
) {
|
) {
|
||||||
this.mapper = mapper;
|
this.mapper = mapper;
|
||||||
this.jdbcTemplate = jdbcTemplate;
|
this.jdbcTemplate = jdbcTemplate;
|
||||||
this.protectedObjectService = protectedObjectService;
|
this.protectedObjectService = protectedObjectService;
|
||||||
|
if (hasText(ordsMetadataUrl) && hasText(ordsMetadataUsername)) {
|
||||||
|
HikariConfig config = new HikariConfig();
|
||||||
|
config.setPoolName("vpd-ords-metadata-pool");
|
||||||
|
config.setJdbcUrl(ordsMetadataUrl.trim());
|
||||||
|
config.setUsername(ordsMetadataUsername.trim());
|
||||||
|
config.setPassword(ordsMetadataPassword == null ? "" : ordsMetadataPassword);
|
||||||
|
config.setDriverClassName("oracle.jdbc.OracleDriver");
|
||||||
|
config.setMaximumPoolSize(2);
|
||||||
|
config.setMinimumIdle(0);
|
||||||
|
config.setConnectionTimeout(10000);
|
||||||
|
this.ordsMetadataDataSource = new HikariDataSource(config);
|
||||||
|
this.ordsMetadataJdbcTemplate = new JdbcTemplate(this.ordsMetadataDataSource);
|
||||||
|
} else {
|
||||||
|
this.ordsMetadataDataSource = null;
|
||||||
|
this.ordsMetadataJdbcTemplate = new JdbcTemplate(dataSource);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<OrdsHandlerView> findHandlers() {
|
public List<OrdsHandlerView> findHandlers() {
|
||||||
@@ -108,7 +135,7 @@ public class OrdsMetadataService {
|
|||||||
requireIdentifier(object.objectName(), "objectName");
|
requireIdentifier(object.objectName(), "objectName");
|
||||||
columns.forEach(column -> requireIdentifier(column, "column"));
|
columns.forEach(column -> requireIdentifier(column, "column"));
|
||||||
|
|
||||||
String currentUser = jdbcTemplate.queryForObject("SELECT USER FROM dual", String.class);
|
String currentUser = ordsMetadataJdbcTemplate.queryForObject("SELECT USER FROM dual", String.class);
|
||||||
if (currentUser == null || !currentUser.equalsIgnoreCase("CB_ORDS")) {
|
if (currentUser == null || !currentUser.equalsIgnoreCase("CB_ORDS")) {
|
||||||
throw new AppException("ORDS 조회 Handler 생성은 ORDS parsing schema(CB_ORDS)로 DB에 연결했을 때만 가능합니다. 현재 연결 사용자: "
|
throw new AppException("ORDS 조회 Handler 생성은 ORDS parsing schema(CB_ORDS)로 DB에 연결했을 때만 가능합니다. 현재 연결 사용자: "
|
||||||
+ currentUser + ". 현재 연결에서는 소스 보기를 눌러 기본 PL/SQL을 확인한 뒤 ORDS Handler에 적용하세요.");
|
+ currentUser + ". 현재 연결에서는 소스 보기를 눌러 기본 PL/SQL을 확인한 뒤 ORDS Handler에 적용하세요.");
|
||||||
@@ -120,7 +147,7 @@ public class OrdsMetadataService {
|
|||||||
String ordsPath = "cb-ords/" + basePath + template;
|
String ordsPath = "cb-ords/" + basePath + template;
|
||||||
String source = objectQueryHandlerSource(objectId);
|
String source = objectQueryHandlerSource(objectId);
|
||||||
|
|
||||||
jdbcTemplate.update("""
|
ordsMetadataJdbcTemplate.update("""
|
||||||
BEGIN
|
BEGIN
|
||||||
ORDS.DEFINE_MODULE(
|
ORDS.DEFINE_MODULE(
|
||||||
p_module_name => ?,
|
p_module_name => ?,
|
||||||
@@ -156,7 +183,7 @@ public class OrdsMetadataService {
|
|||||||
p_method => 'POST',
|
p_method => 'POST',
|
||||||
p_name => 'limit',
|
p_name => 'limit',
|
||||||
p_bind_variable_name => 'row_limit',
|
p_bind_variable_name => 'row_limit',
|
||||||
p_source_type => 'QUERY',
|
p_source_type => 'URI',
|
||||||
p_param_type => 'INT',
|
p_param_type => 'INT',
|
||||||
p_access_method => 'IN'
|
p_access_method => 'IN'
|
||||||
);
|
);
|
||||||
@@ -228,4 +255,15 @@ public class OrdsMetadataService {
|
|||||||
throw new AppException("ORDS Handler 생성에 사용할 수 없는 " + label + " 식별자입니다: " + value);
|
throw new AppException("ORDS Handler 생성에 사용할 수 없는 " + label + " 식별자입니다: " + value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean hasText(String value) {
|
||||||
|
return value != null && !value.isBlank();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PreDestroy
|
||||||
|
public void closeOrdsMetadataDataSource() {
|
||||||
|
if (ordsMetadataDataSource != null) {
|
||||||
|
ordsMetadataDataSource.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,10 @@ backoffice:
|
|||||||
ords:
|
ords:
|
||||||
base-url: ${BACKOFFICE_ORDS_BASE_URL:https://yh0olybn5pqce4n-d8aukro81636mon0.adb.ap-seoul-1.oraclecloudapps.com/ords}
|
base-url: ${BACKOFFICE_ORDS_BASE_URL:https://yh0olybn5pqce4n-d8aukro81636mon0.adb.ap-seoul-1.oraclecloudapps.com/ords}
|
||||||
timeout: ${BACKOFFICE_ORDS_TIMEOUT_SECONDS:10}s
|
timeout: ${BACKOFFICE_ORDS_TIMEOUT_SECONDS:10}s
|
||||||
|
metadata-db:
|
||||||
|
url: ${BACKOFFICE_ORDS_DB_URL:}
|
||||||
|
username: ${BACKOFFICE_ORDS_DB_USERNAME:}
|
||||||
|
password: ${BACKOFFICE_ORDS_DB_PASSWORD:}
|
||||||
ai:
|
ai:
|
||||||
enabled: ${BACKOFFICE_AI_ENABLED:false}
|
enabled: ${BACKOFFICE_AI_ENABLED:false}
|
||||||
base-url: ${BACKOFFICE_AI_BASE_URL:}
|
base-url: ${BACKOFFICE_AI_BASE_URL:}
|
||||||
|
|||||||
Reference in New Issue
Block a user