Stage 3: DtrackServer haelt SharedClient (laufzeit-austauschbar)
CI / test (push) Failing after 5m24s

This commit is contained in:
2026-06-23 20:09:51 +00:00
parent 5418698b34
commit 650709cc2e
+23 -9
View File
@@ -1,3 +1,5 @@
use std::sync::Arc;
use dtrack_core::DtrackClient; use dtrack_core::DtrackClient;
use rmcp::{ use rmcp::{
handler::server::router::tool::ToolRouter, handler::server::router::tool::ToolRouter,
@@ -10,8 +12,20 @@ use rmcp::{
}; };
use schemars::JsonSchema; use schemars::JsonSchema;
use serde::Deserialize; use serde::Deserialize;
use tokio::sync::RwLock;
/// MCP-Server fuer Dependency-Track. Haelt den DT-Client + den vom Macro /// Laufzeit-austauschbarer Client-Handle.
///
/// Die Admin-UI kann den Client neu bauen (geaenderte URL/Key); laufende
/// Sessions ziehen die Aenderung beim naechsten Tool-Aufruf, ohne Neustart.
pub type SharedClient = Arc<RwLock<DtrackClient>>;
/// Verpackt einen Client in einen geteilten, austauschbaren Handle.
pub fn shared_client(client: DtrackClient) -> SharedClient {
Arc::new(RwLock::new(client))
}
/// MCP-Server fuer Dependency-Track. Haelt den Client-Handle + den vom Macro
/// generierten ToolRouter. /// generierten ToolRouter.
/// ///
/// Bewusst transport-unabhaengig: `dtrack-stdio` und `dtrack-http` bauen /// Bewusst transport-unabhaengig: `dtrack-stdio` und `dtrack-http` bauen
@@ -19,7 +33,7 @@ use serde::Deserialize;
/// davor. /// davor.
#[derive(Clone)] #[derive(Clone)]
pub struct DtrackServer { pub struct DtrackServer {
client: DtrackClient, client: SharedClient,
tool_router: ToolRouter<Self>, tool_router: ToolRouter<Self>,
} }
@@ -32,7 +46,7 @@ pub struct ProjectArg {
#[tool_router] #[tool_router]
impl DtrackServer { impl DtrackServer {
pub fn new(client: DtrackClient) -> Self { pub fn new(client: SharedClient) -> Self {
Self { Self {
client, client,
tool_router: Self::tool_router(), tool_router: Self::tool_router(),
@@ -41,8 +55,8 @@ impl DtrackServer {
#[tool(description = "Listet aktive Dependency-Track-Projekte auf (Name, Version, UUID).")] #[tool(description = "Listet aktive Dependency-Track-Projekte auf (Name, Version, UUID).")]
async fn list_projects(&self) -> Result<CallToolResult, McpError> { async fn list_projects(&self) -> Result<CallToolResult, McpError> {
let body = self let client = self.client.read().await.clone();
.client let body = client
.list_projects() .list_projects()
.await .await
.map_err(|e| McpError::internal_error(e.to_string(), None))?; .map_err(|e| McpError::internal_error(e.to_string(), None))?;
@@ -54,8 +68,8 @@ impl DtrackServer {
&self, &self,
Parameters(arg): Parameters<ProjectArg>, Parameters(arg): Parameters<ProjectArg>,
) -> Result<CallToolResult, McpError> { ) -> Result<CallToolResult, McpError> {
let body = self let client = self.client.read().await.clone();
.client let body = client
.project_findings(&arg.uuid) .project_findings(&arg.uuid)
.await .await
.map_err(|e| McpError::internal_error(e.to_string(), None))?; .map_err(|e| McpError::internal_error(e.to_string(), None))?;
@@ -67,8 +81,8 @@ impl DtrackServer {
&self, &self,
Parameters(arg): Parameters<ProjectArg>, Parameters(arg): Parameters<ProjectArg>,
) -> Result<CallToolResult, McpError> { ) -> Result<CallToolResult, McpError> {
let body = self let client = self.client.read().await.clone();
.client let body = client
.project_metrics(&arg.uuid) .project_metrics(&arg.uuid)
.await .await
.map_err(|e| McpError::internal_error(e.to_string(), None))?; .map_err(|e| McpError::internal_error(e.to_string(), None))?;