feat: harden demo flows and observability
This commit is contained in:
@@ -16,6 +16,7 @@ use mcpaas_schema::Schema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::{Value, json};
|
||||
use time::{OffsetDateTime, format_description::well_known::Rfc3339};
|
||||
use tracing::{info, instrument};
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::{error::ApiError, storage::LocalArtifactStorage};
|
||||
@@ -170,10 +171,12 @@ impl AdminService {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub async fn list_operations(&self) -> Result<Vec<OperationSummary>, ApiError> {
|
||||
Ok(self.registry.list_operations().await?)
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub async fn get_operation(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -186,6 +189,7 @@ impl AdminService {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub async fn get_operation_version(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -202,6 +206,7 @@ impl AdminService {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(protocol = ?payload.protocol, operation_name = %payload.name))]
|
||||
pub async fn create_operation(
|
||||
&self,
|
||||
payload: OperationPayload,
|
||||
@@ -243,6 +248,7 @@ impl AdminService {
|
||||
};
|
||||
|
||||
self.registry.create_operation(&snapshot, None).await?;
|
||||
info!(operation_id = %operation_id.as_str(), version = 1, "operation created");
|
||||
|
||||
Ok(CreatedOperationResponse {
|
||||
operation_id: operation_id.as_str().to_owned(),
|
||||
@@ -251,6 +257,7 @@ impl AdminService {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(operation_id = %operation_id.as_str(), protocol = ?payload.operation.protocol))]
|
||||
pub async fn create_version(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -293,6 +300,7 @@ impl AdminService {
|
||||
created_by: None,
|
||||
})
|
||||
.await?;
|
||||
info!(operation_id = %operation_id.as_str(), version, "operation version created");
|
||||
|
||||
Ok(CreatedOperationResponse {
|
||||
operation_id: operation_id.as_str().to_owned(),
|
||||
@@ -301,6 +309,7 @@ impl AdminService {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self), fields(operation_id = %operation_id.as_str(), version))]
|
||||
pub async fn publish_operation(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -315,6 +324,7 @@ impl AdminService {
|
||||
published_by: None,
|
||||
})
|
||||
.await?;
|
||||
info!(operation_id = %operation_id.as_str(), version, "operation published");
|
||||
|
||||
Ok(PublishResponse {
|
||||
operation_id: operation_id.as_str().to_owned(),
|
||||
@@ -323,6 +333,7 @@ impl AdminService {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(operation_id = %operation_id.as_str(), version = payload.version))]
|
||||
pub async fn run_test(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -363,10 +374,12 @@ impl AdminService {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub async fn list_auth_profiles(&self) -> Result<Vec<AuthProfile>, ApiError> {
|
||||
Ok(self.registry.list_auth_profiles().await?)
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(operation_id = %operation_id.as_str(), source_name = source_name.unwrap_or("descriptor-set.bin")))]
|
||||
pub async fn upload_descriptor_set(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -412,6 +425,12 @@ impl AdminService {
|
||||
},
|
||||
})
|
||||
.await?;
|
||||
info!(
|
||||
operation_id = %operation_id.as_str(),
|
||||
descriptor_id = %descriptor_id.as_str(),
|
||||
version = summary.current_draft_version,
|
||||
"descriptor set uploaded"
|
||||
);
|
||||
|
||||
Ok(DescriptorUploadResponse {
|
||||
descriptor_id: descriptor_id.as_str().to_owned(),
|
||||
@@ -419,6 +438,7 @@ impl AdminService {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(operation_id = %operation_id.as_str(), source_name = source_name.unwrap_or("schema.proto")))]
|
||||
pub async fn upload_proto_file(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -459,6 +479,12 @@ impl AdminService {
|
||||
},
|
||||
})
|
||||
.await?;
|
||||
info!(
|
||||
operation_id = %operation_id.as_str(),
|
||||
descriptor_id = %descriptor_id.as_str(),
|
||||
version = summary.current_draft_version,
|
||||
"proto file uploaded"
|
||||
);
|
||||
|
||||
Ok(DescriptorUploadResponse {
|
||||
descriptor_id: descriptor_id.as_str().to_owned(),
|
||||
@@ -466,6 +492,7 @@ impl AdminService {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self), fields(operation_id = %operation_id.as_str(), version))]
|
||||
pub async fn list_grpc_services(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -499,6 +526,7 @@ impl AdminService {
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
}
|
||||
|
||||
#[instrument(skip(self))]
|
||||
pub async fn get_auth_profile(
|
||||
&self,
|
||||
auth_profile_id: &AuthProfileId,
|
||||
@@ -514,6 +542,7 @@ impl AdminService {
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(auth_profile_name = %payload.name, auth_kind = ?payload.kind))]
|
||||
pub async fn create_auth_profile(
|
||||
&self,
|
||||
payload: AuthProfilePayload,
|
||||
@@ -533,10 +562,12 @@ impl AdminService {
|
||||
self.registry
|
||||
.save_auth_profile(SaveAuthProfileRequest { profile: &profile })
|
||||
.await?;
|
||||
info!(auth_profile_id = %profile.id.as_str(), "auth profile created");
|
||||
|
||||
Ok(profile)
|
||||
}
|
||||
|
||||
#[instrument(skip(self), fields(operation_id = %operation_id.as_str(), version = query.version.unwrap_or_default(), mode = ?query.mode))]
|
||||
pub async fn export_operation(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -566,6 +597,7 @@ impl AdminService {
|
||||
serde_yaml::to_string(&document).map_err(|error| ApiError::internal(error.to_string()))
|
||||
}
|
||||
|
||||
#[instrument(skip(self, yaml_document), fields(mode = ?query.mode))]
|
||||
pub async fn import_operation(
|
||||
&self,
|
||||
query: ImportQuery,
|
||||
@@ -615,25 +647,38 @@ impl AdminService {
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(ImportResponse {
|
||||
let response = ImportResponse {
|
||||
operation_id: created.operation_id,
|
||||
version: created.version,
|
||||
import_mode: ImportMode::Upsert,
|
||||
warnings: Vec::new(),
|
||||
})
|
||||
};
|
||||
info!(
|
||||
operation_id = %response.operation_id,
|
||||
version = response.version,
|
||||
"operation imported by upsert"
|
||||
);
|
||||
Ok(response)
|
||||
} else {
|
||||
let created = self.create_operation(payload).await?;
|
||||
Ok(ImportResponse {
|
||||
let response = ImportResponse {
|
||||
operation_id: created.operation_id,
|
||||
version: created.version,
|
||||
import_mode: ImportMode::Upsert,
|
||||
warnings: Vec::new(),
|
||||
})
|
||||
};
|
||||
info!(
|
||||
operation_id = %response.operation_id,
|
||||
version = response.version,
|
||||
"operation imported by upsert"
|
||||
);
|
||||
Ok(response)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(operation_id = %operation_id.as_str(), sample_kind = ?sample_kind))]
|
||||
pub async fn save_json_sample(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -667,10 +712,17 @@ impl AdminService {
|
||||
self.registry
|
||||
.save_sample_metadata(SaveSampleMetadataRequest { sample: &metadata })
|
||||
.await?;
|
||||
info!(
|
||||
operation_id = %operation_id.as_str(),
|
||||
sample_id = %metadata.id.as_str(),
|
||||
version,
|
||||
"json sample saved"
|
||||
);
|
||||
|
||||
Ok(metadata)
|
||||
}
|
||||
|
||||
#[instrument(skip(self, payload), fields(operation_id = %operation_id.as_str()))]
|
||||
pub async fn generate_draft(
|
||||
&self,
|
||||
operation_id: &OperationId,
|
||||
@@ -722,13 +774,16 @@ impl AdminService {
|
||||
warnings: Vec::new(),
|
||||
};
|
||||
|
||||
Ok(DraftGenerationResult {
|
||||
let result = DraftGenerationResult {
|
||||
generated_draft,
|
||||
input_schema,
|
||||
output_schema,
|
||||
input_mapping,
|
||||
output_mapping,
|
||||
})
|
||||
};
|
||||
info!(operation_id = %operation_id.as_str(), "draft generated from samples");
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
fn validate_operation_payload(&self, payload: &OperationPayload) -> Result<(), ApiError> {
|
||||
|
||||
Reference in New Issue
Block a user