reactive_graph_plugin_graphql_schema/query/mod.rs
1use async_graphql::*;
2use reactive_graph_plugin_api::PluginState;
3use reactive_graph_plugin_service_api::PluginContainerManager;
4use std::sync::Arc;
5use uuid::Uuid;
6
7pub use plugin::*;
8
9pub mod plugin;
10
11pub struct PluginQuery;
12
13/// Search queries for the type system, the instances and the flows.
14#[Object(name = "Query")]
15impl PluginQuery {
16 #[allow(clippy::too_many_arguments)]
17 async fn plugins(
18 &self,
19 context: &Context<'_>,
20 id: Option<Uuid>,
21 stem: Option<String>,
22 name: Option<String>,
23 state: Option<String>,
24 has_dependencies: Option<bool>,
25 has_unsatisfied_dependencies: Option<bool>,
26 ) -> Result<Vec<GraphQLPlugin>> {
27 let plugin_container_manager = context.data::<Arc<dyn PluginContainerManager + Send + Sync>>()?;
28 let plugins = plugin_container_manager
29 .get_plugins()
30 .into_iter()
31 .filter(|plugin_id| match &id {
32 Some(id) => plugin_id == id,
33 None => true,
34 })
35 .filter(|plugin_id| match &stem {
36 Some(stem) => match plugin_container_manager.get_id(stem.as_ref()) {
37 Some(id) => plugin_id == &id,
38 None => false,
39 },
40 None => true,
41 })
42 .filter(|plugin_id| match &name {
43 Some(name) => match plugin_container_manager.name(plugin_id) {
44 Some(plugin_name) => &plugin_name == name,
45 None => false,
46 },
47 None => true,
48 })
49 .filter(|plugin_id| match &state {
50 Some(state) => match plugin_container_manager.get_plugin_state(plugin_id) {
51 Some(PluginState::Installed) => state == "Installed",
52 Some(PluginState::Resolving(_)) => state == "Resolving",
53 Some(PluginState::Resolved) => state == "Resolved",
54 Some(PluginState::Starting(_)) => state == "Starting",
55 Some(PluginState::Active) => state == "Active",
56 Some(PluginState::Stopping(_)) => state == "Stopping",
57 Some(PluginState::Refreshing(_)) => state == "Refreshing",
58 Some(PluginState::Uninstalling(_)) => state == "Uninstalling",
59 Some(PluginState::Uninstalled) => state == "Uninstalled",
60 Some(PluginState::Disabled) => state == "Disabled",
61 None => false,
62 },
63 None => true,
64 })
65 .filter(|plugin_id| match &has_dependencies {
66 Some(true) => plugin_container_manager.has_dependencies(plugin_id),
67 Some(false) => !plugin_container_manager.has_dependencies(plugin_id),
68 None => true,
69 })
70 .filter(|plugin_id| match &has_unsatisfied_dependencies {
71 Some(true) => plugin_container_manager.has_unsatisfied_dependencies(plugin_id),
72 Some(false) => !plugin_container_manager.has_unsatisfied_dependencies(plugin_id),
73 None => true,
74 })
75 .map(|id| GraphQLPlugin { id })
76 .collect();
77 Ok(plugins)
78 }
79}
80
81// #[cfg(test)]
82// mod tests {
83// use std::sync::Arc;
84//
85// use serde::Deserialize;
86// use uuid::Uuid;
87//
88// use reactive_graph_graphql_api::GraphQLQueryService;
89// use reactive_graph_plugin_api::serde_json;
90// use reactive_graph_runtime_api::Runtime;
91// use reactive_graph_runtime_impl::RuntimeBuilder;
92//
93// #[derive(Deserialize, Debug)]
94// #[serde(rename_all = "camelCase")]
95// struct Plugin {
96// id: Uuid,
97// }
98//
99// #[derive(Deserialize, Debug)]
100// #[serde(rename_all = "camelCase")]
101// struct System {
102// plugins: Vec<Plugin>,
103// }
104//
105// #[derive(Deserialize, Debug)]
106// struct Data {
107// system: System,
108// }
109//
110// #[tokio::test(flavor = "multi_thread")]
111// async fn test_get_all_plugins() {
112// RuntimeBuilder::new()
113// .ignore_config_files()
114// .disable_all_plugins(true)
115// .pick_free_port()
116// .init()
117// .await
118// .post_init()
119// .await
120// .spawn()
121// .await
122// .with_runtime(|runtime: Arc<dyn Runtime + Send + Sync>| async move {
123// let query_service = runtime.get_graphql_query_service();
124// let plugin_container_manager = runtime.get_plugin_container_manager();
125// let rt_plugins = plugin_container_manager.get_plugins();
126// let gql_plugins: Vec<Uuid> = query_get_all_plugins(&query_service).await.iter().map(|plugin| plugin.id).collect();
127// assert_eq!(rt_plugins, gql_plugins);
128// })
129// .await
130// .stop()
131// .await
132// .pre_shutdown()
133// .await
134// .shutdown()
135// .await;
136// }
137//
138// const QUERY_GET_ALL_PLUGIN_IDS: &str = include_str!("../../graphql/get_all_ids.graphql");
139//
140// async fn query_get_all_plugins(query_service: &Arc<dyn GraphQLQueryService + Send + Sync>) -> Vec<Plugin> {
141// let response = query_service.query_response(QUERY_GET_ALL_PLUGIN_IDS).await;
142// assert!(response.errors.is_empty());
143// let data = response.data.into_json().expect("Failed to get json data from graphql response");
144// let data: Data = serde_json::from_value(data).expect("Failed to deserialize json into target data model");
145// data.system.plugins
146// }
147// }