Skip to content

Commit

Permalink
refactor: convert the Hyper server setup to use Tower
Browse files Browse the repository at this point in the history
  • Loading branch information
rholshausen committed May 24, 2023
1 parent 1b1b3d8 commit 027f563
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 26 deletions.
119 changes: 118 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 19 additions & 17 deletions Cargo.toml
Expand Up @@ -14,31 +14,33 @@ exclude = [
]

[dependencies]
clap = { version = "4.2.1", features = ["env", "std", "cargo"] }
serde = "1.0.137"
serde_json = "1.0.81"
anyhow = "1.0.71"
base64 = "0.21.1"
clap = { version = "4.3.0", features = ["env", "std", "cargo"] }
futures = "0.3.28"
http = "0.2.9"
hyper = { version = "0.14.26", features = ["full"] }
itertools = "0.10.5"
maplit = "1.0.2"
pact_matching = "~1.1.0"
pact_verifier = "~1.0.0"
pact_models = "~1.1.2"
maplit = "1.0.2"
itertools = "0.10.5"
hyper = { version = "0.14.25", features = ["full"] }
http = "0.2.9"
tokio = { version = "1.27.0", features = ["full"] }
futures = "0.3.28"
base64 = "0.21.0"
regex = "1.7.3"
reqwest = { version = "0.11.16", default-features = false, features = ["json", "rustls-tls-native-roots"] }
tower-service = "0.3.2"
anyhow = "1.0.70"
regex = "1.8.2"
reqwest = { version = "0.11.18", default-features = false, features = ["json", "rustls-tls-native-roots"] }
serde = "1.0.163"
serde_json = "1.0.96"
tokio = { version = "1.28.1", features = ["full"] }
tower = { version = "0.4.13", features = [ "full" ] }
tower-service = { version = "0.3.2" }
tower-http = { version = "0.4.0", features = [ "full" ] }
tracing = { version = "0.1.37", features = [ "log" ] }
tracing-core = "0.1.30"
tracing-subscriber = "0.3.16"
tracing-core = "0.1.31"
tracing-subscriber = "0.3.17"

[dev-dependencies]
expectest = "0.12.0"
rand = "0.8.5"
pretty_assertions = "1.3.0"
test-log = "0.2.11"
env_logger = "0.10.0"
trycmd = "0.14.13"
trycmd = "0.14.16"
46 changes: 38 additions & 8 deletions src/server.rs
@@ -1,3 +1,4 @@
use std::future::{Ready, ready};
use std::pin::Pin;
use std::process::ExitCode;

Expand All @@ -8,15 +9,18 @@ use futures::stream::StreamExt;
use futures::task::{Context, Poll};
use http::{Error, StatusCode};
use hyper::{Body, Request as HyperRequest, Response as HyperResponse, Server};
use hyper::server::conn::AddrStream;
use itertools::Itertools;
use maplit::*;
use maplit::hashmap;
use pact_matching::{CoreMatchingContext, DiffConfig, Mismatch};
use pact_models::generators::GeneratorTestMode;
use pact_models::prelude::*;
use pact_models::prelude::v4::*;
use pact_models::v4::http_parts::{HttpRequest, HttpResponse};
use pact_models::v4::V4InteractionType;
use regex::Regex;
use tower::ServiceBuilder;
use tower_http::trace::TraceLayer;
use tower_service::Service;
use tracing::{debug, error, info, warn};

Expand All @@ -32,6 +36,38 @@ pub struct ServerHandler {
empty_provider_states: bool
}

#[derive(Clone)]
struct ServerHandlerFactory {
inner: ServerHandler
}

impl ServerHandlerFactory {
pub fn new(handler: ServerHandler) -> Self {
ServerHandlerFactory {
inner: handler
}
}
}

impl Service<&AddrStream> for ServerHandlerFactory {
type Response = ServerHandler;
type Error = anyhow::Error;
type Future = Ready<Result<Self::Response, Self::Error>>;

fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
Poll::Ready(Ok(()))
}

fn call(&mut self, req: &AddrStream) -> Self::Future {
debug!("Accepting a new connection from {}", req.remote_addr());
let service = ServiceBuilder::new()
.layer(TraceLayer::new_for_http())
.service(self.inner.clone())
.into_inner();
ready(Ok(service))
}
}

impl ServerHandler {
pub fn new(
sources: Vec<(V4Pact, PactSource)>,
Expand All @@ -55,13 +91,7 @@ impl ServerHandler {
let addr = ([0, 0, 0, 0], port).into();
match Server::try_bind(&addr) {
Ok(builder) => {
let server = builder
.serve(hyper::service::make_service_fn(|_| {
let inner = self.clone();
async {
Ok::<_, hyper::Error>(inner)
}
}));
let server = builder.serve(ServerHandlerFactory::new(self));
info!("Server started on port {}", server.local_addr().port());
block_on(server).map_err(|err| {
error!("error occurred scheduling server future on Tokio runtime: {}", err);
Expand Down

0 comments on commit 027f563

Please sign in to comment.