use std::collections::HashSet;
use apollo_federation::connectors::expand::Connectors;
use apq::APQIncompatPlugin;
use authentication::AuthIncompatPlugin;
use batching::BatchingIncompatPlugin;
use coprocessor::CoprocessorIncompatPlugin;
use entity_cache::EntityCacheIncompatPlugin;
use headers::HeadersIncompatPlugin;
use rhai::RhaiIncompatPlugin;
use telemetry::TelemetryIncompatPlugin;
use tls::TlsIncompatPlugin;
use traffic_shaping::TrafficShapingIncompatPlugin;
use url_override::UrlOverrideIncompatPlugin;
use crate::Configuration;
mod apq;
mod authentication;
mod batching;
mod coprocessor;
mod entity_cache;
mod headers;
mod rhai;
mod telemetry;
mod tls;
mod traffic_shaping;
mod url_override;
#[derive(Default)]
struct ConfiguredSubgraphs<'a> {
enabled: HashSet<&'a String>,
disabled: HashSet<&'a String>,
}
trait IncompatiblePlugin {
fn is_applied_to_all(&self) -> bool;
fn configured_subgraphs(&self) -> ConfiguredSubgraphs<'_>;
fn inform_incompatibilities(&self, subgraphs: HashSet<&String>, connectors: &Connectors);
}
pub(crate) fn warn_incompatible_plugins(config: &Configuration, connectors: &Connectors) {
let connector_enabled_subgraphs: HashSet<&String> = connectors
.by_service_name
.values()
.map(|v| &v.id.subgraph_name)
.collect();
if connector_enabled_subgraphs.is_empty() {
return;
}
macro_rules! boxify {
() => {
|a| {
let boxed: Box<dyn IncompatiblePlugin> = Box::new(a);
boxed
}
};
}
let incompatible_plugins: Vec<Box<dyn IncompatiblePlugin>> = vec![
APQIncompatPlugin::from_config(config).map(boxify!()),
AuthIncompatPlugin::from_config(config).map(boxify!()),
BatchingIncompatPlugin::from_config(config).map(boxify!()),
CoprocessorIncompatPlugin::from_config(config).map(boxify!()),
EntityCacheIncompatPlugin::from_config(config).map(boxify!()),
HeadersIncompatPlugin::from_config(config).map(boxify!()),
RhaiIncompatPlugin::from_config(config).map(boxify!()),
TelemetryIncompatPlugin::from_config(config).map(boxify!()),
TlsIncompatPlugin::from_config(config).map(boxify!()),
TrafficShapingIncompatPlugin::from_config(config).map(boxify!()),
UrlOverrideIncompatPlugin::from_config(config).map(boxify!()),
]
.into_iter()
.flatten()
.collect();
for plugin in incompatible_plugins {
let ConfiguredSubgraphs { enabled, disabled } = plugin.configured_subgraphs();
let incompatible = if plugin.is_applied_to_all() {
connector_enabled_subgraphs
.difference(&disabled)
.copied()
.collect::<HashSet<&String>>()
} else {
enabled
.intersection(&connector_enabled_subgraphs)
.copied()
.collect::<HashSet<&String>>()
};
if !incompatible.is_empty() {
plugin.inform_incompatibilities(incompatible, connectors);
}
}
}