From a3bf961431366df82aed9298e0f62bcc2a942586 Mon Sep 17 00:00:00 2001 From: Jan David Date: Sat, 19 Mar 2022 11:13:34 +0100 Subject: [PATCH] Create API to inspect ATC itself A new API service and endpoint have been created to inspect ATC itself. The only endpoint of the service returns the version of the game, which can be used by clients to determine if they are running on the same version as the server. The service might be extended in the future to include more information about the game itself as well as its operation. --- Cargo.lock | 9 +++++- api/atc/v1/atc.proto | 19 ++++++++++++ game/Cargo.toml | 1 + game/src/api/atc.rs | 72 ++++++++++++++++++++++++++++++++++++++++++++ game/src/api/mod.rs | 12 +++++--- 5 files changed, 108 insertions(+), 5 deletions(-) create mode 100644 api/atc/v1/atc.proto create mode 100644 game/src/api/atc.rs diff --git a/Cargo.lock b/Cargo.lock index 0b2574b..6ed8011 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -228,6 +228,7 @@ dependencies = [ "parking_lot 0.12.0", "prost", "rand", + "semver 1.0.6", "tokio", "tokio-stream", "tonic", @@ -2928,7 +2929,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" dependencies = [ - "semver", + "semver 0.9.0", ] [[package]] @@ -2978,6 +2979,12 @@ dependencies = [ "semver-parser", ] +[[package]] +name = "semver" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d" + [[package]] name = "semver-parser" version = "0.7.0" diff --git a/api/atc/v1/atc.proto b/api/atc/v1/atc.proto new file mode 100644 index 0000000..bcf914e --- /dev/null +++ b/api/atc/v1/atc.proto @@ -0,0 +1,19 @@ +syntax = "proto3"; + +package atc.v1; + +message Version { + uint64 major = 1; + uint64 minor = 2; + uint64 patch = 3; + string pre = 4; +} + +message GetVersionRequest {} +message GetVersionResponse { + Version version = 1; +} + +service AtcService { + rpc GetVersion(GetVersionRequest) returns (GetVersionResponse); +} diff --git a/game/Cargo.toml b/game/Cargo.toml index b9ed4cc..06fe4e1 100644 --- a/game/Cargo.toml +++ b/game/Cargo.toml @@ -27,6 +27,7 @@ geo = "0.19.0" parking_lot = "0.12.0" prost = "0.9.0" rand = "0.8.5" +semver = "1.0.6" tokio = { version = "1.17.0", features = ["macros", "rt-multi-thread", "sync"] } tokio-stream = { version = "0.1.8", features = ["sync"] } tonic = "0.6.2" diff --git a/game/src/api/atc.rs b/game/src/api/atc.rs new file mode 100644 index 0000000..902aa64 --- /dev/null +++ b/game/src/api/atc.rs @@ -0,0 +1,72 @@ +use semver::Version as SemVer; +use tonic::{Request, Response, Status}; + +use atc::v1::{GetVersionRequest, GetVersionResponse, Version}; + +pub struct AtcService; + +#[tonic::async_trait] +impl atc::v1::atc_service_server::AtcService for AtcService { + async fn get_version( + &self, + _request: Request, + ) -> Result, Status> { + let semver = SemVer::parse(env!("CARGO_PKG_VERSION")).unwrap(); + let version = Version { + major: semver.major, + minor: semver.minor, + patch: semver.patch, + pre: semver.pre.to_string(), + }; + + Ok(Response::new(GetVersionResponse { + version: Some(version), + })) + } +} + +#[cfg(test)] +mod tests { + use tonic::Request; + + use atc::v1::atc_service_server::AtcService as ServiceTrait; + use atc::v1::GetVersionRequest; + + use super::AtcService; + + #[tokio::test] + async fn get_version() { + let response = AtcService + .get_version(Request::new(GetVersionRequest {})) + .await + .unwrap(); + + let version = response.into_inner().version.unwrap(); + + assert_eq!( + env!("CARGO_PKG_VERSION_MAJOR").parse::().unwrap(), + version.major + ); + assert_eq!( + env!("CARGO_PKG_VERSION_MINOR").parse::().unwrap(), + version.minor + ); + assert_eq!( + env!("CARGO_PKG_VERSION_PATCH").parse::().unwrap(), + version.patch + ); + assert_eq!(env!("CARGO_PKG_VERSION_PRE"), version.pre); + } + + #[test] + fn trait_send() { + fn assert_send() {} + assert_send::(); + } + + #[test] + fn trait_sync() { + fn assert_sync() {} + assert_sync::(); + } +} diff --git a/game/src/api/mod.rs b/game/src/api/mod.rs index 248e101..6c9cd44 100644 --- a/game/src/api/mod.rs +++ b/game/src/api/mod.rs @@ -4,10 +4,11 @@ use std::sync::Arc; use tonic::transport::{Error, Server as GrpcServer}; -use atc::v1::airplane_service_server::AirplaneServiceServer; -use atc::v1::event_service_server::EventServiceServer; -use atc::v1::game_service_server::GameServiceServer; -use atc::v1::map_service_server::MapServiceServer; +use ::atc::v1::airplane_service_server::AirplaneServiceServer; +use ::atc::v1::atc_service_server::AtcServiceServer; +use ::atc::v1::event_service_server::EventServiceServer; +use ::atc::v1::game_service_server::GameServiceServer; +use ::atc::v1::map_service_server::MapServiceServer; use crate::command::CommandSender; use crate::event::EventSender; @@ -15,11 +16,13 @@ use crate::store::Store; use crate::SharedGameState; use self::airplane::AirplaneService; +use self::atc::AtcService; use self::event::EventService; use self::game::GameService; use self::map::MapService; mod airplane; +mod atc; mod event; mod game; mod map; @@ -40,6 +43,7 @@ impl Api { command_sender.clone(), store, ))) + .add_service(AtcServiceServer::new(AtcService)) .add_service(EventServiceServer::new(EventService::new(event_sender))) .add_service(GameServiceServer::new(GameService::new( command_sender,