diff --git a/Cargo.toml b/Cargo.toml index c9e21fc..0bd46c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,4 +43,5 @@ tokio = { version = "1", features = ["process"] } [build-dependencies] vergen = { version = "8.3.1", default-features = false, features = ["cargo"] } - +serde = "1.0" +serde_json = "1.0" diff --git a/build.rs b/build.rs index 03a664a..5ed70c1 100644 --- a/build.rs +++ b/build.rs @@ -1,7 +1,56 @@ +use serde::Deserialize; +use std::str::FromStr; + +#[derive(Deserialize)] +struct Data { + name: String, + version: String, +} + +enum ExplorerMetadata { + ExplorerVersion, + IrohaCompatibility, + Other, +} + +impl FromStr for ExplorerMetadata { + type Err = (); + fn from_str(s: &str) -> Result { + match s { + "iroha_explorer" => Ok(Self::ExplorerVersion), + "iroha_data_model" => Ok(Self::IrohaCompatibility), + _ => Ok(Self::Other), + } + } +} + fn main() { vergen::EmitBuilder::builder() .git_sha(true) .cargo_features() .emit() .unwrap(); + + let output = std::process::Command::new("cargo") + .arg("metadata") + .output() + .unwrap(); + + let metadata = std::str::from_utf8(&output.stdout).unwrap(); + let metadata = serde_json::from_str::(metadata).unwrap(); + let versions = serde_json::from_value::>(metadata["packages"].clone()).unwrap(); + + for Data { version, name } in &versions { + match name.parse::() { + Ok(ExplorerMetadata::ExplorerVersion) => { + println!("cargo:rustc-env=VERGEN_EXPLORER_VERSION={version}") + } + Ok(ExplorerMetadata::IrohaCompatibility) => { + println!("cargo:rustc-env=VERGEN_IROHA_COMPAT=v{version}") + } + _ => { + // ignore everything else... + } + } + } } diff --git a/src/endpoint.rs b/src/endpoint.rs index ada309c..9cf4c14 100644 --- a/src/endpoint.rs +++ b/src/endpoint.rs @@ -7,8 +7,8 @@ use axum::{ }; use futures_util::Stream; use futures_util::StreamExt; -use serde::Deserialize; -use utoipa::{IntoParams, OpenApi}; +use serde::{Deserialize, Serialize}; +use utoipa::{IntoParams, OpenApi, ToSchema}; use crate::schema::{Page, PaginationQueryParams, TelemetryStreamMessage, TransactionStatus}; use crate::telemetry::Telemetry; @@ -551,6 +551,30 @@ pub async fn telemetry_peers_info( Ok(Json(data)) } +/// Get information about the explorer +#[derive(Serialize, ToSchema)] +pub struct ExplorerInfo { + version: &'static str, + iroha_compatible_version: &'static str, +} + +#[utoipa::path( + get, + path = "/info", + tags = ["Explorer information"], + responses( + (status = 200, description = "OK", body = ExplorerInfo) + ) +)] +pub async fn explorer_info() -> Json { + let version = env!("VERGEN_EXPLORER_VERSION"); + let iroha_compatible_version = env!("VERGEN_IROHA_COMPAT"); + Json(ExplorerInfo { + version, + iroha_compatible_version, + }) +} + pub fn router(repo: Repo, telemetry: Telemetry) -> Router { Router::new() .route("/domains", get(domains_index)) @@ -576,6 +600,7 @@ pub fn router(repo: Repo, telemetry: Telemetry) -> Router { .route("/telemetry/peers", get(telemetry_peers)) .route("/telemetry/peers-info", get(telemetry_peers_info)) .route("/telemetry/live", get(telemetry_live)) + .route("/info", get(explorer_info)) .with_state(AppState { repo, telemetry }) } @@ -598,6 +623,7 @@ pub fn router(repo: Repo, telemetry: Telemetry) -> Router { transactions_index, transactions_show, instructions_index, + explorer_info, ), nest((path = "/telemetry", api = TelemetryApi)), tags( @@ -612,6 +638,7 @@ pub struct Api; telemetry_network, telemetry_peers, telemetry_peers_info, - telemetry_live + telemetry_live, + telemetry_network_status_live ))] struct TelemetryApi; diff --git a/src/main.rs b/src/main.rs index 7f9a0c6..791826f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -403,6 +403,7 @@ mod tests { ) .await; ensure_status(&client, path("/api/v1/telemetry/live"), StatusCode::OK).await; + ensure_status(&client, path("/api/v1/info"), StatusCode::OK).await; Ok(()) }