openzeppelin_relayer/api/controllers/
plugin.rs

1//! # Plugin Controller
2//!
3//! Handles HTTP endpoints for plugin operations including:
4//! - Calling plugins
5use crate::{
6    jobs::JobProducerTrait,
7    models::{ApiError, ApiResponse, AppState, PluginCallRequest},
8    services::plugins::{PluginCallResponse, PluginRunner, PluginService, PluginServiceTrait},
9};
10use actix_web::{web, HttpResponse};
11use eyre::Result;
12use std::sync::Arc;
13
14/// Call plugin
15///
16/// # Arguments
17///
18/// * `plugin_id` - The ID of the plugin to call.
19/// * `plugin_call_request` - The plugin call request.
20/// * `state` - The application state containing the plugin repository.
21///
22/// # Returns
23///
24/// The result of the plugin call.
25pub async fn call_plugin<J: JobProducerTrait + 'static>(
26    plugin_id: String,
27    plugin_call_request: PluginCallRequest,
28    state: web::ThinData<AppState<J>>,
29) -> Result<HttpResponse, ApiError> {
30    let plugin = state
31        .plugin_repository
32        .get_by_id(&plugin_id)
33        .await?
34        .ok_or_else(|| ApiError::NotFound(format!("Plugin with id {} not found", plugin_id)))?;
35
36    let plugin_runner = PluginRunner;
37    let plugin_service = PluginService::new(plugin_runner);
38    let result = plugin_service
39        .call_plugin(plugin.path, plugin_call_request, Arc::new(state))
40        .await;
41
42    match result {
43        Ok(plugin_result) => Ok(HttpResponse::Ok().json(ApiResponse::success(plugin_result))),
44        Err(e) => Ok(HttpResponse::Ok().json(ApiResponse::<PluginCallResponse>::error(e))),
45    }
46}
47
48#[cfg(test)]
49mod tests {
50    use super::*;
51    use crate::{models::PluginModel, utils::mocks::mockutils::create_mock_app_state};
52
53    #[actix_web::test]
54    async fn test_call_plugin() {
55        let plugin = PluginModel {
56            id: "test-plugin".to_string(),
57            path: "test-path".to_string(),
58        };
59        let app_state = create_mock_app_state(None, None, None, Some(vec![plugin])).await;
60        let plugin_call_request = PluginCallRequest {
61            params: serde_json::json!({"key":"value"}),
62        };
63        let response = call_plugin(
64            "test-plugin".to_string(),
65            plugin_call_request,
66            web::ThinData(app_state),
67        )
68        .await;
69        assert!(response.is_ok());
70    }
71}