1#![allow(dead_code)]
8
9pub mod ai_integration;
10pub mod cicd;
11pub mod fuseki_integration;
12pub mod graphql_integration;
13pub mod performance;
14pub mod rule_engine;
15pub mod shex_migration;
16pub mod stream_integration;
17
18pub use ai_integration::*;
20pub use cicd::{
21 CiCdConfig, CiCdEngine, CiCdResult, CiSystem, EnvironmentConfig, ExitCodeConfig, OutputFormat,
22 RegressionAnalysis, ThresholdConfig, ThresholdResults,
23};
24pub use fuseki_integration::*;
25pub use graphql_integration::*;
26pub use performance::{
27 BottleneckType, LatencyPrediction, LoadBalancingRecommendation, PerformanceBottleneck,
28 PerformanceConfig, PerformanceMetrics, PerformanceOptimizer, PerformanceSummary, Severity,
29};
30pub use rule_engine::{
31 CacheStats, ConstraintGenerator, ConstraintPattern, ConstraintRule, ReasoningBridge,
32 ReasoningResult, ReasoningStrategy, RefinementAction, RuleBasedValidator,
33 RuleBasedValidatorBuilder, RuleEngineConfig, ShapeRefinementRule, ViolationPattern,
34};
35pub use shex_migration::{
36 AnnotationHandling, ClosedHandling, ExtraHandling, ImportHandling, MigrationConfig,
37 MigrationConfigBuilder, MigrationError, MigrationReport, MigrationResult, MigrationStatistics,
38 MigrationWarning, NodeConstraint, NumericFacets, SemanticAction, SemanticMappingConfig,
39 ShexAnnotation, ShexExpression, ShexMigrationEngine, ShexSchema, ShexShape, StringFacets,
40 TripleConstraint, UnmappedFeature, ValueSetHandling, ValueSetValue,
41};
42pub use stream_integration::*;
43
44use crate::{Result, ShaclError, ValidationReport, Validator};
45use oxirs_core::Store;
46use serde::{Deserialize, Serialize};
47use std::collections::HashMap;
48use std::sync::Arc;
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
52pub struct IntegrationConfig {
53 pub enable_graphql_integration: bool,
55 pub enable_fuseki_integration: bool,
57 pub enable_stream_integration: bool,
59 pub enable_ai_integration: bool,
61 pub custom_endpoints: HashMap<String, String>,
63 pub timeout_ms: Option<u64>,
65 pub max_concurrent_validations: usize,
67}
68
69impl Default for IntegrationConfig {
70 fn default() -> Self {
71 Self {
72 enable_graphql_integration: true,
73 enable_fuseki_integration: true,
74 enable_stream_integration: false,
75 enable_ai_integration: false,
76 custom_endpoints: HashMap::new(),
77 timeout_ms: Some(30000), max_concurrent_validations: 10,
79 }
80 }
81}
82
83#[derive(Debug)]
85pub struct IntegrationManager {
86 validator: Arc<Validator>,
87 config: IntegrationConfig,
88 #[cfg(feature = "async")]
89 runtime: Option<tokio::runtime::Handle>,
90}
91
92impl IntegrationManager {
93 pub fn new(validator: Arc<Validator>, config: IntegrationConfig) -> Self {
95 Self {
96 validator,
97 config,
98 #[cfg(feature = "async")]
99 runtime: tokio::runtime::Handle::try_current().ok(),
100 }
101 }
102
103 pub fn validator(&self) -> &Arc<Validator> {
105 &self.validator
106 }
107
108 pub fn config(&self) -> &IntegrationConfig {
110 &self.config
111 }
112
113 pub fn update_config(&mut self, config: IntegrationConfig) {
115 self.config = config;
116 }
117
118 pub fn validate_for_context(
120 &self,
121 store: &dyn Store,
122 context: IntegrationContext,
123 ) -> Result<IntegratedValidationReport> {
124 let validation_report = self.validator.validate_store(store, None)?;
125
126 Ok(IntegratedValidationReport {
127 base_report: validation_report,
128 context,
129 integration_metadata: self.create_integration_metadata(),
130 })
131 }
132
133 fn create_integration_metadata(&self) -> IntegrationMetadata {
135 IntegrationMetadata {
136 validator_version: crate::VERSION.to_string(),
137 integration_config: self.config.clone(),
138 timestamp: chrono::Utc::now(),
139 }
140 }
141}
142
143#[derive(Debug, Clone, Serialize, Deserialize)]
145pub enum IntegrationContext {
146 GraphQL {
148 operation_name: Option<String>,
149 query_complexity: usize,
150 client_info: Option<String>,
151 },
152 Fuseki {
154 endpoint_path: String,
155 operation_type: String,
156 user_agent: Option<String>,
157 },
158 Stream {
160 stream_id: String,
161 event_type: String,
162 batch_size: usize,
163 },
164 AI {
166 model_id: String,
167 confidence_threshold: f64,
168 suggestion_type: String,
169 },
170 Custom {
172 context_type: String,
173 properties: HashMap<String, String>,
174 },
175}
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
179pub struct IntegratedValidationReport {
180 pub base_report: ValidationReport,
182 pub context: IntegrationContext,
184 pub integration_metadata: IntegrationMetadata,
186}
187
188impl IntegratedValidationReport {
189 pub fn conforms(&self) -> bool {
191 self.base_report.conforms()
192 }
193
194 pub fn violations(&self) -> &[crate::validation::ValidationViolation] {
196 self.base_report.violations()
197 }
198
199 pub fn get_context_recommendations(&self) -> Vec<String> {
201 let mut recommendations = Vec::new();
202
203 match &self.context {
204 IntegrationContext::GraphQL {
205 query_complexity, ..
206 } => {
207 if *query_complexity > 500 {
208 recommendations
209 .push("Consider simplifying GraphQL query or using pagination".to_string());
210 }
211 if !self.conforms() {
212 recommendations.push(
213 "GraphQL mutations may fail due to SHACL constraint violations".to_string(),
214 );
215 }
216 }
217 IntegrationContext::Fuseki { operation_type, .. } => {
218 if operation_type == "UPDATE" && !self.conforms() {
219 recommendations.push(
220 "SPARQL UPDATE operations should be reviewed due to constraint violations"
221 .to_string(),
222 );
223 }
224 }
225 IntegrationContext::Stream { batch_size, .. } => {
226 if *batch_size > 1000 && !self.conforms() {
227 recommendations.push(
228 "Consider reducing batch size to isolate validation errors".to_string(),
229 );
230 }
231 }
232 IntegrationContext::AI {
233 confidence_threshold,
234 ..
235 } => {
236 if *confidence_threshold < 0.8 && !self.conforms() {
237 recommendations.push(
238 "AI suggestions may be unreliable due to low confidence and validation errors".to_string()
239 );
240 }
241 }
242 IntegrationContext::Custom { .. } => {
243 if !self.conforms() {
244 recommendations.push(
245 "Custom integration should handle validation errors appropriately"
246 .to_string(),
247 );
248 }
249 }
250 }
251
252 recommendations
253 }
254
255 pub fn export_for_context(&self) -> Result<String> {
257 match &self.context {
258 IntegrationContext::GraphQL { .. } => {
259 let graphql_format = serde_json::json!({
261 "data": null,
262 "errors": self.violations().iter().map(|v| {
263 serde_json::json!({
264 "message": v.result_message.as_deref().unwrap_or("Validation error"),
265 "path": ["validation"],
266 "extensions": {
267 "code": "SHACL_VALIDATION_ERROR",
268 "shape": v.source_shape.to_string(),
269 "severity": v.result_severity.to_string()
270 }
271 })
272 }).collect::<Vec<_>>()
273 });
274 Ok(serde_json::to_string_pretty(&graphql_format)?)
275 }
276 IntegrationContext::Fuseki { .. } => {
277 Ok(format!(
279 "# SHACL Validation Report\n# Conforms: {}\n# Violations: {}",
280 self.conforms(),
281 self.violations().len()
282 ))
283 }
284 _ => {
285 Ok(serde_json::to_string_pretty(&self)?)
287 }
288 }
289 }
290}
291
292#[derive(Debug, Clone, Serialize, Deserialize)]
294pub struct IntegrationMetadata {
295 pub validator_version: String,
297 pub integration_config: IntegrationConfig,
299 pub timestamp: chrono::DateTime<chrono::Utc>,
301}
302
303#[derive(Debug, thiserror::Error)]
305pub enum IntegrationError {
306 #[error("GraphQL integration error: {0}")]
307 GraphQL(String),
308
309 #[error("Fuseki integration error: {0}")]
310 Fuseki(String),
311
312 #[error("Stream integration error: {0}")]
313 Stream(String),
314
315 #[error("AI integration error: {0}")]
316 AI(String),
317
318 #[error("Custom integration error: {0}")]
319 Custom(String),
320
321 #[error("SHACL validation error: {0}")]
322 Validation(#[from] ShaclError),
323
324 #[error("Serialization error: {0}")]
325 Serialization(#[from] serde_json::Error),
326}
327
328pub type IntegrationResult<T> = std::result::Result<T, IntegrationError>;