Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions internal/apiserver/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,23 @@ func NewAPIServer(logger utilLog.Logger, opts *conf.DMSOptions) (*APIServer, err
e := echo.New()
e.HideBanner = true
e.HidePort = true
e.HTTPErrorHandler = func(err error, c echo.Context) {
if c.Response().Committed {
return
}

message := err.Error()
if httpErr, ok := err.(*echo.HTTPError); ok {
if msg, ok := httpErr.Message.(string); ok && msg != "" {
message = msg
}
}

_ = c.JSON(http.StatusBadRequest, bV1.GenericResp{
Code: int(apiError.BadRequestErr),
Message: message,
})
}
return &APIServer{
logger: logger,
opts: opts,
Expand Down
9 changes: 9 additions & 0 deletions internal/pkg/locale/active.en.toml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ ProjectDesc = "Project description"
ProjectName = "Project name"
ProjectNotAvailable = "Unavailable"
ProjectStatus = "Project status"
SqlWorkbenchAuditCallSQLEErr = "The audit service is busy or unavailable. Please try again later."
SqlWorkbenchAuditDBServiceMappingNotFoundErr = "Current data source was not found. Please confirm it exists, reselect it, and try again."
SqlWorkbenchAuditGetDBServiceErr = "Current data source configuration was not found. Please confirm the data source exists and try again."
SqlWorkbenchAuditGetDBServiceMappingErr = "We couldn't get the current data source information. Please reselect the data source and try again."
SqlWorkbenchAuditGetDMSUserErr = "Your login session may have expired. Please sign in again and retry."
SqlWorkbenchAuditMissingSQLOrDatasourceErr = "SQL or data source was not detected. Please select a data source and enter SQL, then try again."
SqlWorkbenchAuditNotEnabledErr = "SQL audit is not enabled for this data source. Please enable SQL audit before running."
SqlWorkbenchAuditParseReqErr = "We couldn't parse the request content. Please try again later."
SqlWorkbenchAuditReadReqBodyErr = "We couldn't get the request content, possibly due to network instability. Please try again later."
StatDisable = "Disabled"
StatOK = "Normal"
StatUnknown = "Unknown"
9 changes: 9 additions & 0 deletions internal/pkg/locale/active.zh.toml
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,15 @@ ProjectDesc = "项目描述"
ProjectName = "项目名称"
ProjectNotAvailable = "不可用"
ProjectStatus = "项目状态"
SqlWorkbenchAuditCallSQLEErr = "审核服务当前繁忙或不可用,请稍后重试。"
SqlWorkbenchAuditDBServiceMappingNotFoundErr = "未找到当前数据源,请确认数据源存在并重新选择后重试。"
SqlWorkbenchAuditGetDBServiceErr = "未找到当前数据源配置,请确认数据源存在后重试。"
SqlWorkbenchAuditGetDBServiceMappingErr = "当前数据源信息获取失败,请重新选择数据源后重试。"
SqlWorkbenchAuditGetDMSUserErr = "当前登录状态可能已过期,请重新登录后再试。"
SqlWorkbenchAuditMissingSQLOrDatasourceErr = "未检测到 SQL 或数据源,请确认已选择数据源并输入 SQL 后重试。"
SqlWorkbenchAuditNotEnabledErr = "该数据源尚未开启 SQL 审核,请先在数据源配置中开启“SQL 审核”后再执行。"
SqlWorkbenchAuditParseReqErr = "请求内容解析失败,请稍后重试。"
SqlWorkbenchAuditReadReqBodyErr = "请求内容获取失败,可能网络不稳定,请稍后重试。"
StatDisable = "被禁用"
StatOK = "正常"
StatUnknown = "未知"
13 changes: 13 additions & 0 deletions internal/pkg/locale/message_zh.go
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,19 @@ var (
CbOpResultRowCount = &i18n.Message{ID: "CbOpResultRowCount", Other: "结果集返回行数"}
)

// SQL Workbench
var (
SqlWorkbenchAuditReadReqBodyErr = &i18n.Message{ID: "SqlWorkbenchAuditReadReqBodyErr", Other: "请求内容获取失败,可能网络不稳定,请稍后重试。"}
SqlWorkbenchAuditParseReqErr = &i18n.Message{ID: "SqlWorkbenchAuditParseReqErr", Other: "请求内容解析失败,请稍后重试。"}
SqlWorkbenchAuditMissingSQLOrDatasourceErr = &i18n.Message{ID: "SqlWorkbenchAuditMissingSQLOrDatasourceErr", Other: "未检测到 SQL 或数据源,请确认已选择数据源并输入 SQL 后重试。"}
SqlWorkbenchAuditGetDMSUserErr = &i18n.Message{ID: "SqlWorkbenchAuditGetDMSUserErr", Other: "当前登录状态可能已过期,请重新登录后再试。"}
SqlWorkbenchAuditGetDBServiceMappingErr = &i18n.Message{ID: "SqlWorkbenchAuditGetDBServiceMappingErr", Other: "当前数据源信息获取失败,请重新选择数据源后重试。"}
SqlWorkbenchAuditDBServiceMappingNotFoundErr = &i18n.Message{ID: "SqlWorkbenchAuditDBServiceMappingNotFoundErr", Other: "未找到当前数据源,请确认数据源存在并重新选择后重试。"}
SqlWorkbenchAuditGetDBServiceErr = &i18n.Message{ID: "SqlWorkbenchAuditGetDBServiceErr", Other: "未找到当前数据源配置,请确认数据源存在后重试。"}
SqlWorkbenchAuditNotEnabledErr = &i18n.Message{ID: "SqlWorkbenchAuditNotEnabledErr", Other: "该数据源尚未开启 SQL 审核,请先在数据源配置中开启“SQL 审核”后再执行。"}
SqlWorkbenchAuditCallSQLEErr = &i18n.Message{ID: "SqlWorkbenchAuditCallSQLEErr", Other: "审核服务当前繁忙或不可用,请稍后重试。"}
)

// DB Service Sync Task
var (
DBServiceSyncVersion = &i18n.Message{ID: "DBServiceSyncVersion", Other: "版本(支持DMP5.23.04.0及以上版本)"}
Expand Down
20 changes: 11 additions & 9 deletions internal/sql_workbench/service/sql_workbench_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
Expand All @@ -22,6 +23,7 @@ import (
"github.com/actiontech/dms/internal/dms/biz"
pkgConst "github.com/actiontech/dms/internal/dms/pkg/constant"
"github.com/actiontech/dms/internal/dms/storage"
"github.com/actiontech/dms/internal/pkg/locale"
dbmodel "github.com/actiontech/dms/internal/dms/storage/model"
"github.com/actiontech/dms/internal/sql_workbench/client"
config "github.com/actiontech/dms/internal/sql_workbench/config"
Expand Down Expand Up @@ -1020,7 +1022,7 @@ func (sqlWorkbenchService *SqlWorkbenchService) AuditMiddleware() echo.Middlewar
bodyBytes, err := io.ReadAll(c.Request().Body)
if err != nil {
sqlWorkbenchService.log.Errorf("failed to read request body: %v", err)
return fmt.Errorf("failed to read request body: %w", err)
return errors.New(locale.Bundle.LocalizeMsgByCtx(c.Request().Context(), locale.SqlWorkbenchAuditReadReqBodyErr))
}
// 恢复请求体,供后续处理使用
c.Request().Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
Expand All @@ -1029,51 +1031,51 @@ func (sqlWorkbenchService *SqlWorkbenchService) AuditMiddleware() echo.Middlewar
sql, datasourceID, err := sqlWorkbenchService.parseStreamExecuteRequest(bodyBytes)
if err != nil {
sqlWorkbenchService.log.Errorf("failed to parse streamExecute request, skipping audit: %v", err)
return fmt.Errorf("failed to parse streamExecute request, skipping audit: %v", err)
return errors.New(locale.Bundle.LocalizeMsgByCtx(c.Request().Context(), locale.SqlWorkbenchAuditParseReqErr))
}

if sql == "" || datasourceID == "" {
sqlWorkbenchService.log.Debugf("SQL or datasource ID is empty, skipping audit")
return fmt.Errorf("SQL or datasource ID is empty, skipping audit")
return errors.New(locale.Bundle.LocalizeMsgByCtx(c.Request().Context(), locale.SqlWorkbenchAuditMissingSQLOrDatasourceErr))
}

// 获取当前用户 ID
dmsUserId, err := sqlWorkbenchService.getDMSUserIdFromRequest(c)
if err != nil {
sqlWorkbenchService.log.Errorf("failed to get DMS user ID: %v", err)
return fmt.Errorf("failed to get DMS user ID: %v", err)
return errors.New(locale.Bundle.LocalizeMsgByCtx(c.Request().Context(), locale.SqlWorkbenchAuditGetDMSUserErr))
}

// 从缓存表获取 dms_db_service_id
dmsDBServiceID, err := sqlWorkbenchService.getDMSDBServiceIDFromCache(c.Request().Context(), datasourceID, dmsUserId)
if err != nil {
sqlWorkbenchService.log.Errorf("failed to get dms_db_service_id from cache: %v", err)
return fmt.Errorf("failed to get dms_db_service_id from cache: %v", err)
return errors.New(locale.Bundle.LocalizeMsgByCtx(c.Request().Context(), locale.SqlWorkbenchAuditGetDBServiceMappingErr))
}

if dmsDBServiceID == "" {
sqlWorkbenchService.log.Debugf("dms_db_service_id not found in cache for datasource: %s", datasourceID)
return fmt.Errorf("dms_db_service_id not found in cache for datasource: %s", datasourceID)
return errors.New(locale.Bundle.LocalizeMsgByCtx(c.Request().Context(), locale.SqlWorkbenchAuditDBServiceMappingNotFoundErr))
}

// 获取 DBService 信息
dbService, err := sqlWorkbenchService.dbServiceUsecase.GetDBService(c.Request().Context(), dmsDBServiceID)
if err != nil {
sqlWorkbenchService.log.Errorf("failed to get DBService: %v", err)
return fmt.Errorf("failed to get DBService: %v", err)
return errors.New(locale.Bundle.LocalizeMsgByCtx(c.Request().Context(), locale.SqlWorkbenchAuditGetDBServiceErr))
}

// 检查是否启用 SQL 审核
if !sqlWorkbenchService.isEnableSQLAudit(dbService) {
sqlWorkbenchService.log.Debugf("SQL audit is not enabled for DBService: %s", dmsDBServiceID)
return fmt.Errorf("SQL audit is not enabled for DBService: %s", dmsDBServiceID)
return errors.New(locale.Bundle.LocalizeMsgByCtx(c.Request().Context(), locale.SqlWorkbenchAuditNotEnabledErr))
}

// 调用 SQLE 审核接口
auditResult, err := sqlWorkbenchService.callSQLEAudit(c.Request().Context(), sql, dbService)
if err != nil {
sqlWorkbenchService.log.Errorf("call SQLE audit failed: %v", err)
return fmt.Errorf("call SQLE audit failed: %v", err)
return errors.New(locale.Bundle.LocalizeMsgByCtx(c.Request().Context(), locale.SqlWorkbenchAuditCallSQLEErr))
}

// 拦截响应并添加审核结果
Expand Down