feat(kingbase): remove legacy Java agent

This commit is contained in:
t8y2 2026-07-24 11:26:28 +08:00
parent 5186ecfa03
commit 3fa3a5b663
No known key found for this signature in database
7 changed files with 146 additions and 2320 deletions

View File

@ -89,7 +89,6 @@ jobs:
name: agent-jars
path: |
agents/drivers/*/build/libs/dbx-agent-*.jar
!agents/drivers/kingbase/build/libs/dbx-agent-kingbase.jar
build-oracle-native:
needs: [bump-versions]
@ -306,7 +305,7 @@ jobs:
- name: Flatten artifacts
run: |
mkdir -p release
find artifacts/agent-jars -name '*.jar' ! -name 'dbx-agent-kingbase.jar' -exec cp {} release/ \;
find artifacts/agent-jars -name '*.jar' -exec cp {} release/ \;
find artifacts/oracle-native -type f -name 'dbx-agent-oracle-*' -exec cp {} release/ \;
find artifacts/xugu-native -type f -name 'dbx-agent-xugu-*' -exec cp {} release/ \;
find artifacts/kingbase-native -type f -name 'dbx-agent-kingbase-*' -exec cp {} release/ \;

View File

@ -22,6 +22,8 @@ var registerExpressionFallbackDriver sync.Once
var expressionFallbackState atomic.Pointer[fallbackDriverState]
var registerModeDetectionDriver sync.Once
var modeDetectionState atomic.Pointer[modeDetectionDriverState]
var registerMetadataDriver sync.Once
var metadataState atomic.Pointer[metadataDriverState]
type fakeDriverState struct {
queryArgs int
@ -63,6 +65,18 @@ type modeDetectionConn struct {
state *modeDetectionDriverState
}
type metadataDriverState struct {
mu sync.Mutex
queries []string
query func(string) (driver.Rows, error)
}
type metadataDriver struct{}
type metadataConn struct {
state *metadataDriverState
}
type valueRows struct {
columns []string
rows [][]driver.Value
@ -189,6 +203,23 @@ func (connection *modeDetectionConn) QueryContext(_ context.Context, query strin
}
}
func (metadataDriver) Open(string) (driver.Conn, error) {
return &metadataConn{state: metadataState.Load()}, nil
}
func (*metadataConn) Prepare(string) (driver.Stmt, error) { return nil, driver.ErrSkip }
func (*metadataConn) Close() error { return nil }
func (*metadataConn) Begin() (driver.Tx, error) { return nil, driver.ErrSkip }
func (connection *metadataConn) QueryContext(_ context.Context, query string, _ []driver.NamedValue) (driver.Rows, error) {
connection.state.mu.Lock()
connection.state.queries = append(connection.state.queries, query)
connection.state.mu.Unlock()
return connection.state.query(query)
}
func (rows *valueRows) Columns() []string { return rows.columns }
func (*valueRows) Close() error { return nil }
@ -229,6 +260,19 @@ func openModeDetectionDB(t *testing.T, state *modeDetectionDriverState) *sql.DB
return db
}
func openMetadataDB(t *testing.T, state *metadataDriverState) *sql.DB {
t.Helper()
registerMetadataDriver.Do(func() { sql.Register("kingbase-metadata-test", metadataDriver{}) })
metadataState.Store(state)
db, err := sql.Open("kingbase-metadata-test", "")
if err != nil {
t.Fatal(err)
}
db.SetMaxOpenConns(1)
t.Cleanup(func() { _ = db.Close() })
return db
}
func TestHandshakeAdvertisesMultiSession(t *testing.T) {
runtime := &runtimeServer{sessions: map[string]*agentSession{}}
result, shutdown, err := runtime.dispatch("handshake", nil)
@ -320,6 +364,106 @@ func TestMetadataNormalizationHelpers(t *testing.T) {
}
}
func TestListDatabasesFallsBackToPostgresCatalog(t *testing.T) {
state := &metadataDriverState{query: func(query string) (driver.Rows, error) {
switch {
case strings.Contains(query, "sys_catalog.sys_database"):
return nil, errors.New("sys catalog unavailable")
case strings.Contains(query, "pg_catalog.pg_database"):
return &valueRows{columns: []string{"datname"}, rows: [][]driver.Value{{"app"}, {"test"}}}, nil
default:
return nil, errors.New("unexpected query: " + query)
}
}}
server := newServer()
server.db = openMetadataDB(t, state)
server.params.Database = "configured"
databases, err := server.listDatabases()
if err != nil {
t.Fatal(err)
}
if len(databases) != 2 || databases[0].Name != "app" || databases[1].Name != "test" {
t.Fatalf("unexpected databases: %#v", databases)
}
state.mu.Lock()
defer state.mu.Unlock()
if len(state.queries) != 2 || !strings.Contains(state.queries[0], "sys_catalog.sys_database") || !strings.Contains(state.queries[1], "pg_catalog.pg_database") {
t.Fatalf("catalog fallback order changed: %v", state.queries)
}
}
func TestListTablesPreservesKingbaseObjectTypesAndComments(t *testing.T) {
state := &metadataDriverState{query: func(query string) (driver.Rows, error) {
if !strings.Contains(query, "FROM sys_catalog.sys_class c") || !strings.Contains(query, "c.relkind IN ('r','p','v','m','f')") {
return nil, errors.New("unexpected query: " + query)
}
return &valueRows{
columns: []string{"relname", "relkind", "comment"},
rows: [][]driver.Value{
{"orders", "TABLE", "orders table"},
{"sales_view", "VIEW", nil},
{"sales_cache", "MATERIALIZED_VIEW", "cached sales"},
},
}, nil
}}
server := newServer()
server.db = openMetadataDB(t, state)
tables, err := server.listTables("public", metadataListConstraints{Filter: "sales", ObjectTypes: []string{"VIEW", "MATERIALIZED_VIEW"}})
if err != nil {
t.Fatal(err)
}
if len(tables) != 2 || tables[0].TableType != "VIEW" || tables[1].TableType != "MATERIALIZED_VIEW" {
t.Fatalf("unexpected tables: %#v", tables)
}
if tables[1].Comment == nil || *tables[1].Comment != "cached sales" {
t.Fatalf("materialized view comment was lost: %#v", tables[1])
}
}
func TestListTriggersUsesCompatibilityCatalogAndDecodesTiming(t *testing.T) {
state := &metadataDriverState{query: func(query string) (driver.Rows, error) {
if !strings.Contains(query, "FROM pg_catalog.pg_trigger") || !strings.Contains(query, "NOT tg.tgisinternal") {
return nil, errors.New("unexpected query: " + query)
}
return &valueRows{
columns: []string{"tgname", "event", "tgtype"},
rows: [][]driver.Value{{"orders_before", "INSERT,UPDATE", int64(2)}, {"orders_instead", "DELETE", int64(64)}},
}, nil
}}
server := newServer()
server.db = openMetadataDB(t, state)
server.mode.postgresCatalog = true
triggers, err := server.listTriggers("public", "orders")
if err != nil {
t.Fatal(err)
}
if len(triggers) != 2 || triggers[0].Timing != "BEFORE" || triggers[1].Timing != "INSTEAD OF" {
t.Fatalf("unexpected triggers: %#v", triggers)
}
}
func TestRoutineSourceUsesKingbaseCatalogFunction(t *testing.T) {
state := &metadataDriverState{query: func(query string) (driver.Rows, error) {
if !strings.Contains(query, "SELECT sys_get_functiondef(p.oid)") || !strings.Contains(query, "FROM sys_catalog.sys_proc") {
return nil, errors.New("unexpected query: " + query)
}
return &valueRows{columns: []string{"source"}, rows: [][]driver.Value{{"CREATE FUNCTION public.format_name() RETURNS text AS $$ SELECT 'x'; $$"}}}, nil
}}
server := newServer()
server.db = openMetadataDB(t, state)
source, err := server.getObjectSource("public", "format_name", "FUNCTION")
if err != nil {
t.Fatal(err)
}
if !strings.HasPrefix(source["source"].(string), "CREATE FUNCTION public.format_name()") {
t.Fatalf("unexpected routine source: %#v", source)
}
}
func TestColumnsFallbackToPgGetExprAndCacheChoice(t *testing.T) {
registerExpressionFallbackDriver.Do(func() { sql.Register("kingbase-expression-fallback-test", fallbackDriver{}) })
state := &fallbackDriverState{}

View File

@ -1,10 +0,0 @@
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'cn.com.kingbase:kingbase8:9.0.1.jre7'
}
tasks.named('shadowJar') {
manifest {
attributes('Agent-Label': '人大金仓 KingbaseES', 'Main-Class': 'com.dbx.agent.kingbase.KingbaseAgent')
}
}

View File

@ -47,10 +47,6 @@ for platform in "${PLATFORMS[@]}"; do
# Copy all driver JARs (platform-independent)
for jar_file in "$RELEASE_DIR"/dbx-agent-*.jar; do
[ -f "$jar_file" ] || continue
# Kingbase is distributed only as a native agent; keep legacy JDBC builds out of offline bundles.
case "$(basename "$jar_file")" in
dbx-agent-kingbase.jar|dbx-agent-kingbase-*.jar) continue ;;
esac
cp "$jar_file" "$WORK/drivers/"
done

View File

@ -2,7 +2,7 @@ rootProject.name = 'dbx-agents'
def infrastructureModules = ['common', 'test-support']
def driverModules = [
'access', 'dameng', 'kingbase', 'vastbase', 'goldendb', 'databend', 'databricks', 'saphana',
'access', 'dameng', 'vastbase', 'goldendb', 'databend', 'databricks', 'saphana',
'teradata', 'vertica', 'firebird', 'exasol', 'oceanbase-oracle', 'gbase8a', 'gbase8s',
'bigquery', 'kylin', 'sundb', 'h2', 'h2-legacy', 'snowflake', 'trino', 'hive', 'spark',
'db2', 'informix', 'neo4j', 'cassandra', 'mongodb', 'highgo', 'tdengine', 'yashandb', 'oscar',