feat(connection): show server versions for more datasources
This commit is contained in:
20 files changed
+408
-38
No files matched your search
@@ -1024,17 +1024,30 @@ async fn test_redis_connection(
|
||||
host: &str,
|
||||
port: u16,
|
||||
connect_timeout: std::time::Duration,
|
||||
) -> Result<String, String> {
|
||||
) -> Result<Option<DatabaseConnectionInfo>, String> {
|
||||
// Connection tests must exercise the same Redis lifecycle as a saved connection,
|
||||
// including compatibility auth, TLS, and database selection.
|
||||
if config.uses_redis_cluster() {
|
||||
drop(state.connect_redis_cluster(tunnel_id, config).await?);
|
||||
} else if config.uses_redis_sentinel() {
|
||||
drop(state.connect_redis_sentinel(tunnel_id, config).await?);
|
||||
} else {
|
||||
drop(db::redis_driver::connect_standalone(config, host, port, connect_timeout).await?);
|
||||
let connection =
|
||||
db::redis_driver::RedisConnection::Cluster(state.connect_redis_cluster(tunnel_id, config).await?);
|
||||
let info = db::redis_driver::database_connection_info(&connection).await.ok();
|
||||
drop(connection);
|
||||
return Ok(info);
|
||||
}
|
||||
Ok("Connection successful".to_string())
|
||||
if config.uses_redis_sentinel() {
|
||||
let connection = db::redis_driver::RedisConnection::Direct(tokio::sync::Mutex::new(
|
||||
state.connect_redis_sentinel(tunnel_id, config).await?,
|
||||
));
|
||||
let info = db::redis_driver::database_connection_info(&connection).await.ok();
|
||||
drop(connection);
|
||||
return Ok(info);
|
||||
}
|
||||
let connection = db::redis_driver::RedisConnection::Direct(tokio::sync::Mutex::new(
|
||||
db::redis_driver::connect_standalone(config, host, port, connect_timeout).await?,
|
||||
));
|
||||
let info = db::redis_driver::database_connection_info(&connection).await.ok();
|
||||
drop(connection);
|
||||
Ok(info)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@@ -1173,7 +1186,13 @@ async fn test_connection_with_info_inner(
|
||||
DatabaseType::Redis => {
|
||||
// Keep the result inside the outer lifecycle so temporary transports
|
||||
// are reset after both successful and failed Redis tests.
|
||||
test_redis_connection(state, &tunnel_id, &config, &host, port, connect_timeout).await
|
||||
match test_redis_connection(state, &tunnel_id, &config, &host, port, connect_timeout).await {
|
||||
Ok(info) => {
|
||||
database_info = info;
|
||||
Ok("Connection successful".to_string())
|
||||
}
|
||||
Err(error) => Err(error),
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "duckdb-sidecar")]
|
||||
DatabaseType::DuckDb => {
|
||||
@@ -1191,8 +1210,19 @@ async fn test_connection_with_info_inner(
|
||||
.connect(mongo_legacy_connect_params(&config, &host, port)?)
|
||||
.await
|
||||
.map_err(|err| mongo_legacy_error_with_auth_hint(&err))?;
|
||||
let version = client
|
||||
.mongo_server_version::<String>(config.effective_database().unwrap_or("admin"))
|
||||
.await
|
||||
.ok();
|
||||
client.disconnect().await.ok();
|
||||
return Ok(ConnectionTestResult::success("Connection successful (via legacy driver)"));
|
||||
return Ok(ConnectionTestResult::success("Connection successful (via legacy driver)")
|
||||
.with_database_info(version.map(|product_version| DatabaseConnectionInfo {
|
||||
product_name: Some("MongoDB".to_string()),
|
||||
product_version: Some(product_version),
|
||||
current_database: config.effective_database().map(str::to_string),
|
||||
driver_name: Some("MongoDB legacy Agent".to_string()),
|
||||
..Default::default()
|
||||
})));
|
||||
}
|
||||
|
||||
let native_err = match db::mongo_driver::connect_with_oidc(
|
||||
@@ -1212,7 +1242,15 @@ async fn test_connection_with_info_inner(
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(()) => return Ok(ConnectionTestResult::success("Connection successful")),
|
||||
Ok(()) => {
|
||||
let info =
|
||||
db::mongo_driver::database_connection_info(&client, config.effective_database())
|
||||
.await
|
||||
.ok();
|
||||
return Ok(
|
||||
ConnectionTestResult::success("Connection successful").with_database_info(info)
|
||||
);
|
||||
}
|
||||
Err(e) => e,
|
||||
}
|
||||
}
|
||||
@@ -1228,7 +1266,18 @@ async fn test_connection_with_info_inner(
|
||||
&mongo_legacy_error_with_auth_hint(&err),
|
||||
)
|
||||
})?;
|
||||
let version = client
|
||||
.mongo_server_version::<String>(config.effective_database().unwrap_or("admin"))
|
||||
.await
|
||||
.ok();
|
||||
client.disconnect().await.ok();
|
||||
database_info = version.map(|product_version| DatabaseConnectionInfo {
|
||||
product_name: Some("MongoDB".to_string()),
|
||||
product_version: Some(product_version),
|
||||
current_database: config.effective_database().map(str::to_string),
|
||||
driver_name: Some("MongoDB legacy Agent".to_string()),
|
||||
..Default::default()
|
||||
});
|
||||
Ok("Connection successful (via legacy driver)".to_string())
|
||||
} else {
|
||||
Err(native_err)
|
||||
@@ -1301,9 +1350,9 @@ async fn test_connection_with_info_inner(
|
||||
config.external_config.as_ref(),
|
||||
connect_timeout,
|
||||
)?;
|
||||
db::meilisearch_driver::test_connection(&client, connect_timeout)
|
||||
.await
|
||||
.map(|_| "Connection successful".to_string())
|
||||
db::meilisearch_driver::test_connection(&client, connect_timeout).await?;
|
||||
database_info = db::meilisearch_driver::database_connection_info(&client).await.ok();
|
||||
Ok("Connection successful".to_string())
|
||||
}
|
||||
DatabaseType::Hbase => {
|
||||
let client = db::hbase_driver::HBaseClient::new(
|
||||
@@ -1313,9 +1362,9 @@ async fn test_connection_with_info_inner(
|
||||
false,
|
||||
connect_timeout,
|
||||
)?;
|
||||
db::hbase_driver::test_connection(&client, connect_timeout)
|
||||
.await
|
||||
.map(|_| "Connection successful".to_string())
|
||||
db::hbase_driver::test_connection(&client, connect_timeout).await?;
|
||||
database_info = db::hbase_driver::database_connection_info(&client).await.ok().flatten();
|
||||
Ok("Connection successful".to_string())
|
||||
}
|
||||
DatabaseType::Qdrant | DatabaseType::Milvus | DatabaseType::Weaviate | DatabaseType::ChromaDb => {
|
||||
let kind = match config.db_type {
|
||||
@@ -1388,14 +1437,16 @@ async fn test_connection_with_info_inner(
|
||||
DatabaseType::VictoriaMetrics => {
|
||||
let client =
|
||||
db::victoriametrics_driver::VictoriaMetricsClient::new_for_config(&url, &config, connect_timeout)?;
|
||||
db::victoriametrics_driver::test_connection(&client, connect_timeout)
|
||||
.await
|
||||
.map(|_| "Connection successful".to_string())
|
||||
db::victoriametrics_driver::test_connection(&client, connect_timeout).await?;
|
||||
database_info =
|
||||
db::victoriametrics_driver::database_connection_info(&client, connect_timeout).await.ok();
|
||||
Ok("Connection successful".to_string())
|
||||
}
|
||||
DatabaseType::Nacos => {
|
||||
let admin_config = state.nacos_admin_config_for_connection(connection_id, &config).await?;
|
||||
let adapter = state.nacos_registry.build_transient_config(admin_config).await?;
|
||||
adapter.test_connection_with_scope_validation().await?;
|
||||
let info = adapter.test_connection_with_scope_validation().await?;
|
||||
database_info = dbx_core::nacos::service::database_info_from_connection(&info);
|
||||
Ok("Connection successful".to_string())
|
||||
}
|
||||
DatabaseType::Consul => {
|
||||
@@ -1413,6 +1464,13 @@ async fn test_connection_with_info_inner(
|
||||
} else {
|
||||
client.agent_self().await.ok()
|
||||
};
|
||||
database_info = identity.as_ref().map(|identity| DatabaseConnectionInfo {
|
||||
product_name: Some("Consul".to_string()),
|
||||
product_version: identity.version.clone(),
|
||||
server_comment: Some(format!("Agent {}", identity.node)),
|
||||
driver_name: Some("Consul HTTP API".to_string()),
|
||||
..Default::default()
|
||||
});
|
||||
Ok(identity
|
||||
.map(|identity| format!("Connection successful (Agent: {} at {})", identity.node, identity.address))
|
||||
.unwrap_or_else(|| {
|
||||
@@ -1426,7 +1484,21 @@ async fn test_connection_with_info_inner(
|
||||
let mqc = state.mq_admin_config_for_connection(connection_id, &config).await?;
|
||||
let agent_launch = dbx_core::mq::service::resolve_mq_agent_launch_spec(&mqc, state);
|
||||
let adapter = state.mq_registry.build_transient_config(mqc, agent_launch).await?;
|
||||
adapter.test_connection().await?;
|
||||
let info = adapter.test_connection().await?;
|
||||
database_info = Some(DatabaseConnectionInfo {
|
||||
product_name: Some(
|
||||
match info.system_kind {
|
||||
dbx_core::mq::types::MqSystemKind::Pulsar => "Pulsar",
|
||||
dbx_core::mq::types::MqSystemKind::Kafka => "Kafka",
|
||||
dbx_core::mq::types::MqSystemKind::RocketMq => "RocketMQ",
|
||||
dbx_core::mq::types::MqSystemKind::RabbitMq => "RabbitMQ",
|
||||
}
|
||||
.to_string(),
|
||||
),
|
||||
product_version: info.server_version,
|
||||
driver_name: Some("Message Queue Admin API".to_string()),
|
||||
..Default::default()
|
||||
});
|
||||
Ok("Connection successful".to_string())
|
||||
}
|
||||
#[cfg(not(feature = "mq-admin"))]
|
||||
|
||||
Reference in new issue
Block a user