Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expose the custom endpoints from RouterServiceFactory #1402

Merged
merged 5 commits into from
Jul 15, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions NEXT_CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ cargo features. We now use reqwest for that.

By [@geal](https://github.com/geal) in https://github.com/apollographql/router/pull/1392

### Expose the custom endpoints from RouterServiceFactory [PR #1402](https://github.com/apollographql/router/pull/1402)
Geal marked this conversation as resolved.
Show resolved Hide resolved

Plugin HTTP endpoints registration was broken during the Tower refactoring. We now make sure that the list
of endpoints is generated from the `RouterServiceFactory` instance.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️ (`<3`)


By [@geal](https://github.com/geal) in https://github.com/apollographql/router/pull/1402

## 🛠 Maintenance

### Dependency updates [PR #1389](https://github.com/apollographql/router/issues/1389) [PR #1395](https://github.com/apollographql/router/issues/1395)
Expand Down
4 changes: 4 additions & 0 deletions apollo-router/src/axum_http_server_factory.rs
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,10 @@ mod tests {
type Future = <<TestRouterServiceFactory as NewService<
http_ext::Request<graphql::Request>,
>>::Service as Service<http_ext::Request<graphql::Request>>>::Future;

fn custom_endpoints(&self) -> HashMap<String, Handler> {
HashMap::new()
}
}

async fn init(mut mock: MockRouterService) -> (HttpServerHandle, Client) {
Expand Down
12 changes: 7 additions & 5 deletions apollo-router/src/router_factory.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::collections::HashMap;
// This entire file is license key functionality
use std::sync::Arc;

use futures::stream::BoxStream;
use indexmap::IndexMap;
use serde_json::Map;
use serde_json::Value;
use tower::BoxError;
Expand All @@ -14,8 +14,8 @@ use crate::graphql;
use crate::http_ext::Request;
use crate::http_ext::Response;
use crate::plugin::DynPlugin;
use crate::plugin::Handler;
use crate::services::new_service::NewService;
use crate::services::Plugins;
use crate::services::RouterCreator;
use crate::services::SubgraphService;
use crate::PluggableRouterServiceBuilder;
Expand All @@ -35,6 +35,8 @@ pub(crate) trait RouterServiceFactory:
Future = Self::Future,
> + Send;
type Future: Send;

fn custom_endpoints(&self) -> HashMap<String, Handler>;
}

/// Factory for creating a RouterServiceFactory
Expand All @@ -50,7 +52,7 @@ pub(crate) trait RouterServiceConfigurator: Send + Sync + 'static {
configuration: Arc<Configuration>,
schema: Arc<crate::Schema>,
previous_router: Option<&'a Self::RouterServiceFactory>,
) -> Result<(Self::RouterServiceFactory, Plugins), BoxError>;
) -> Result<Self::RouterServiceFactory, BoxError>;
}

/// Main implementation of the RouterService factory, supporting the extensions system
Expand All @@ -66,7 +68,7 @@ impl RouterServiceConfigurator for YamlRouterServiceFactory {
configuration: Arc<Configuration>,
schema: Arc<Schema>,
_previous_router: Option<&'a Self::RouterServiceFactory>,
) -> Result<(Self::RouterServiceFactory, Plugins), BoxError> {
) -> Result<Self::RouterServiceFactory, BoxError> {
let mut builder = PluggableRouterServiceBuilder::new(schema.clone());
if configuration.server.introspection {
builder = builder.with_naive_introspection();
Expand Down Expand Up @@ -95,7 +97,7 @@ impl RouterServiceConfigurator for YamlRouterServiceFactory {

let pluggable_router_service = builder.build().await?;

Ok((pluggable_router_service, IndexMap::new()))
Ok(pluggable_router_service)
}
}

Expand Down
12 changes: 12 additions & 0 deletions apollo-router/src/services/router_service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,18 @@ impl RouterServiceFactory for RouterCreator {
type Future = <<RouterCreator as NewService<Request<graphql::Request>>>::Service as Service<
Request<graphql::Request>,
>>::Future;

fn custom_endpoints(&self) -> std::collections::HashMap<String, crate::plugin::Handler> {
self.plugins
.iter()
.filter_map(|(plugin_name, plugin)| {
(plugin_name.starts_with("apollo.") || plugin_name.starts_with("experimental."))
.then(|| plugin.custom_endpoint())
.flatten()
.map(|h| (plugin_name.clone(), h))
})
.collect()
}
}

impl RouterCreator {
Expand Down
48 changes: 13 additions & 35 deletions apollo-router/src/state_machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use crate::configuration::Configuration;
use crate::configuration::ListenAddr;
use crate::plugin::Handler;
use crate::router_factory::RouterServiceConfigurator;
use crate::services::Plugins;
use crate::router_factory::RouterServiceFactory;
use crate::Schema;

/// This state maintains private information that is not exposed to the user via state listener.
Expand All @@ -44,8 +44,6 @@ enum State<RS> {
#[derivative(Debug = "ignore")]
router_service_factory: RS,
server_handle: HttpServerHandle,
#[derivative(Debug = "ignore")]
plugins: Plugins,
},
Stopped,
Errored(ApolloRouterError),
Expand Down Expand Up @@ -85,6 +83,7 @@ impl<S, FA> StateMachine<S, FA>
where
S: HttpServerFactory,
FA: RouterServiceConfigurator + Send,
FA::RouterServiceFactory: RouterServiceFactory,
{
pub(crate) fn new(http_server_factory: S, router_factory: FA) -> Self {
let ready = Arc::new(RwLock::new(None));
Expand Down Expand Up @@ -157,7 +156,6 @@ where
schema,
router_service_factory: router_service,
server_handle,
plugins,
},
UpdateSchema(new_schema),
) => {
Expand All @@ -167,7 +165,6 @@ where
schema,
router_service,
server_handle,
plugins,
None,
Some(Arc::new(*new_schema)),
)
Expand All @@ -182,7 +179,6 @@ where
schema,
router_service_factory: router_service,
server_handle,
plugins,
},
UpdateConfiguration(new_configuration),
) => {
Expand All @@ -192,7 +188,6 @@ where
schema,
router_service,
server_handle,
plugins,
Some(Arc::new(*new_configuration)),
None,
)
Expand Down Expand Up @@ -272,23 +267,15 @@ where
let configuration = Arc::new(configuration);
let schema = Arc::new(schema);

let (router_factory, plugins) = self
let router_factory = self
.router_configurator
.create(configuration.clone(), schema.clone(), None)
.await
.map_err(|err| {
tracing::error!("cannot create the router: {}", err);
Errored(ApolloRouterError::ServiceCreationError(err))
})?;
let plugin_handlers: HashMap<String, Handler> = plugins
.iter()
.filter_map(|(plugin_name, plugin)| {
(plugin_name.starts_with("apollo.") || plugin_name.starts_with("experimental."))
.then(|| plugin.custom_endpoint())
.flatten()
.map(|h| (plugin_name.clone(), h))
})
.collect();
let plugin_handlers = router_factory.custom_endpoints();

let server_handle = self
.http_server_factory
Expand All @@ -309,7 +296,6 @@ where
schema,
router_service_factory: router_factory,
server_handle,
plugins,
})
} else {
Ok(state)
Expand All @@ -323,7 +309,6 @@ where
schema: Arc<Schema>,
router_service: <FA as RouterServiceConfigurator>::RouterServiceFactory,
server_handle: HttpServerHandle,
plugins: Plugins,
new_configuration: Option<Arc<Configuration>>,
new_schema: Option<Arc<Schema>>,
) -> Result<
Expand All @@ -342,17 +327,9 @@ where
)
.await
{
Ok((new_router_service, plugins)) => {
let plugin_handlers: HashMap<String, Handler> = plugins
.iter()
.filter_map(|(plugin_name, plugin)| {
(plugin_name.starts_with("apollo.")
|| plugin_name.starts_with("experimental."))
.then(|| plugin.custom_endpoint())
.flatten()
.map(|handler| (plugin_name.clone(), handler))
})
.collect();
Ok(new_router_service) => {
let plugin_handlers =
new_router_service.custom_endpoints();
Geal marked this conversation as resolved.
Show resolved Hide resolved

let server_handle = server_handle
.restart(
Expand All @@ -371,7 +348,6 @@ where
schema: new_schema,
router_service_factory: new_router_service,
server_handle,
plugins,
})
}
Err(err) => {
Expand All @@ -384,7 +360,6 @@ where
schema,
router_service_factory: router_service,
server_handle,
plugins,
})
}
}
Expand Down Expand Up @@ -597,7 +572,8 @@ mod tests {
.returning(|_, _, _| {
let mut router = MockMyRouterFactory::new();
router.expect_clone().return_once(MockMyRouterFactory::new);
Ok((router, Default::default()))
router.expect_custom_endpoints().returning(HashMap::new);
Ok(router)
});
router_factory
.expect_create()
Expand Down Expand Up @@ -637,7 +613,7 @@ mod tests {
configuration: Arc<Configuration>,
schema: Arc<crate::Schema>,
previous_router: Option<&'a MockMyRouterFactory>,
) -> Result<(MockMyRouterFactory, Plugins), BoxError>;
) -> Result<MockMyRouterFactory, BoxError>;
}
}

Expand All @@ -648,6 +624,7 @@ mod tests {
impl RouterServiceFactory for MyRouterFactory {
type RouterService = MockMyRouter;
type Future = <Self::RouterService as Service<Request<graphql::Request>>>::Future;
fn custom_endpoints(&self) -> std::collections::HashMap<String, crate::plugin::Handler>;
}
impl NewService<Request<graphql::Request>> for MyRouterFactory {
type Service = MockMyRouter;
Expand Down Expand Up @@ -774,7 +751,8 @@ mod tests {
.returning(move |_, _, _| {
let mut router = MockMyRouterFactory::new();
router.expect_clone().return_once(MockMyRouterFactory::new);
Ok((router, Default::default()))
router.expect_custom_endpoints().returning(HashMap::new);
Ok(router)
});
router_factory
}
Expand Down