-
Notifications
You must be signed in to change notification settings - Fork 196
/
Copy pathmain.rs
114 lines (98 loc) · 4.03 KB
/
main.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
mod authz;
mod plugin;
use std::{net::SocketAddr, sync::Arc};
use aws_smithy_http_server::{
extension::OperationExtensionExt,
instrumentation::InstrumentExt,
layer::alb_health_check::AlbHealthCheckLayer,
plugin::{HttpPlugins, ModelPlugins, Scoped},
request::request_id::ServerRequestIdProviderLayer,
AddExtensionLayer,
};
use clap::Parser;
use hyper::StatusCode;
use plugin::PrintExt;
use pokemon_service::{
do_nothing_but_log_request_ids, get_storage_with_local_approved, DEFAULT_ADDRESS, DEFAULT_PORT,
};
use pokemon_service_common::{
capture_pokemon, check_health, get_pokemon_species, get_server_statistics, setup_tracing,
stream_pokemon_radio, State,
};
use pokemon_service_server_sdk::{scope, PokemonService, PokemonServiceConfig};
use crate::authz::AuthorizationPlugin;
#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
struct Args {
/// Hyper server bind address.
#[clap(short, long, action, default_value = DEFAULT_ADDRESS)]
address: String,
/// Hyper server bind port.
#[clap(short, long, action, default_value_t = DEFAULT_PORT)]
port: u16,
}
#[tokio::main]
pub async fn main() {
let args = Args::parse();
setup_tracing();
scope! {
/// A scope containing `GetPokemonSpecies` and `GetStorage`.
struct PrintScope {
includes: [GetPokemonSpecies, GetStorage]
}
}
// Scope the `PrintPlugin`, defined in `plugin.rs`, to `PrintScope`.
let print_plugin = Scoped::new::<PrintScope>(HttpPlugins::new().print());
let http_plugins = HttpPlugins::new()
// Apply the scoped `PrintPlugin`
.push(print_plugin)
// Apply the `OperationExtensionPlugin` defined in `aws_smithy_http_server::extension`. This allows other
// plugins or tests to access a `aws_smithy_http_server::extension::OperationExtension` from
// `Response::extensions`, or infer routing failure when it's missing.
.insert_operation_extension()
// Adds `tracing` spans and events to the request lifecycle.
.instrument();
let authz_plugin = AuthorizationPlugin::new();
let model_plugins = ModelPlugins::new().push(authz_plugin);
let config = PokemonServiceConfig::builder()
// Set up shared state and middlewares.
.layer(AddExtensionLayer::new(Arc::new(State::default())))
// Handle `/ping` health check requests.
.layer(AlbHealthCheckLayer::from_handler("/ping", |_req| async {
StatusCode::OK
}))
// Add server request IDs.
.layer(ServerRequestIdProviderLayer::new())
.http_plugin(http_plugins)
.model_plugin(model_plugins)
.build();
let app = PokemonService::builder(config)
// Build a registry containing implementations to all the operations in the service. These
// are async functions or async closures that take as input the operation's input and
// return the operation's output.
.get_pokemon_species(get_pokemon_species)
.get_storage(get_storage_with_local_approved)
.get_server_statistics(get_server_statistics)
.capture_pokemon(capture_pokemon)
.do_nothing(do_nothing_but_log_request_ids)
.check_health(check_health)
.stream_pokemon_radio(stream_pokemon_radio)
.build()
.expect("failed to build an instance of PokemonService");
// Using `into_make_service_with_connect_info`, rather than `into_make_service`, to adjoin the `SocketAddr`
// connection info.
let make_app = app.into_make_service_with_connect_info::<SocketAddr>();
// Bind the application to a socket.
let bind: SocketAddr = format!("{}:{}", args.address, args.port)
.parse()
.expect("unable to parse the server bind address and port");
let server = hyper::Server::bind(&bind).serve(make_app);
// Run forever-ish...
if let Err(err) = server.await {
eprintln!("server error: {}", err);
}
}