Projects STRLCPY graphql-engine Commits 87520813
🤬
  • Add `/metadata` and `/metadata-hash` endpoints (#461)

    ## Description
    
    This PR iterates on #459.
    
    Rather than serving the engine metadata it serves an arbitrary file,
    given by the command line argument `--introspection-metadata`.
    Specifying this argument gives rise to endpoints `/metadata` and
    `/metadata-hash`.
    
    ![image](https://github.com/hasura/v3-engine/assets/358550/63040f02-876a-4c29-8cf1-52a305ffff67)
    
    Update: We only load the file in at engine startup and serve that
    version. Changing the file on disk will not change what the engine
    serves.
    
    ---------
    
    Co-authored-by: Gil Mizrahi <[email protected]>
    V3_GIT_ORIGIN_REV_ID: db88adb5c08c4489cc1abd5fb5236b8d5ba51b9a
  • Loading...
  • Philip Lykke Carlsen committed with hasura-bot 1 month ago
    87520813
    1 parent 4bc2f21f
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    v3/Cargo.lock
    skipped 3353 lines
    3354 3354   "http",
    3355 3355   "http-body",
    3356 3356   "http-range-header",
     3357 + "httpdate",
     3358 + "mime",
     3359 + "mime_guess",
     3360 + "percent-encoding",
    3357 3361   "pin-project-lite",
     3362 + "tokio",
     3363 + "tokio-util",
    3358 3364   "tower-layer",
    3359 3365   "tower-service",
    3360 3366   "tracing",
    skipped 546 lines
  • ■ ■ ■ ■ ■ ■
    v3/Cargo.toml
    skipped 1 lines
    2 2  resolver = "2"
    3 3   
    4 4  package.version = "0.1.0"
     5 + 
    5 6  package.edition = "2021"
     7 + 
    6 8  package.license = "Apache-2.0"
    7 9   
    8 10  members = [
    skipped 61 lines
  • ■ ■ ■ ■
    v3/crates/engine/Cargo.toml
    skipped 55 lines
    56 56   "rt-multi-thread",
    57 57   "signal",
    58 58  ] }
    59  -tower-http = { version = "0.4", features = ["trace", "cors"] }
     59 +tower-http = { version = "0.4", features = ["trace", "cors", "fs"] }
    60 60  transitive = "0.5.0"
    61 61  url = "2.4.1"
    62 62   
    skipped 21 lines
  • ■ ■ ■ ■ ■
    v3/crates/engine/bin/engine/main.rs
    skipped 18 lines
    19 19   TraceableError, TraceableHttpResponse,
    20 20  };
    21 21   
     22 +use base64::engine::Engine;
    22 23  use engine::{
    23 24   authentication::{AuthConfig, AuthConfig::V1 as V1AuthConfig, AuthModeConfig},
    24 25   execute::HttpContext,
    skipped 4 lines
    29 30  use hasura_authn_jwt::jwt;
    30 31  use hasura_authn_webhook::webhook;
    31 32  use lang_graphql as gql;
     33 +use std::hash;
     34 +use std::hash::{Hash, Hasher};
    32 35   
    33 36  const DEFAULT_PORT: u16 = 3000;
    34 37   
    skipped 4 lines
    39 42  struct ServerOptions {
    40 43   #[arg(long, value_name = "METADATA_FILE", env = "METADATA_PATH")]
    41 44   metadata_path: PathBuf,
     45 + #[arg(
     46 + long,
     47 + value_name = "INTROSPECTION_METADATA_FILE",
     48 + env = "INTROSPECTION_METADATA_FILE"
     49 + )]
     50 + introspection_metadata: Option<String>,
    42 51   #[arg(long, value_name = "OTLP_ENDPOINT", env = "OTLP_ENDPOINT")]
    43 52   otlp_endpoint: Option<String>,
    44 53   #[arg(long, value_name = "AUTHN_CONFIG_FILE", env = "AUTHN_CONFIG_PATH")]
    skipped 83 lines
    128 137  async fn start_engine(server: &ServerOptions) -> Result<(), StartupError> {
    129 138   let auth_config =
    130 139   read_auth_config(&server.authn_config_path).map_err(StartupError::ReadAuth)?;
    131  - let (raw_metadata, schema) =
    132  - read_schema(&server.metadata_path).map_err(StartupError::ReadSchema)?;
     140 + let schema = read_schema(&server.metadata_path).map_err(StartupError::ReadSchema)?;
    133 141   let http_context = HttpContext {
    134 142   client: reqwest::Client::new(),
    135 143   ndc_response_size_limit: None,
    skipped 3 lines
    139 147   schema,
    140 148   auth_config,
    141 149   });
    142  - 
    143  - let metadata_route = Router::new().route("/metadata", get(|| async { raw_metadata }));
    144 150   
    145 151   let graphql_route = Router::new()
    146 152   .route("/graphql", post(handle_request))
    skipped 33 lines
    180 186   
    181 187   let health_route = Router::new().route("/health", get(handle_health));
    182 188   
    183  - let app = Router::new()
     189 + let app_ = Router::new()
    184 190   // serve graphiql at root
    185 191   .route("/", get(graphiql))
    186  - .merge(metadata_route)
    187 192   .merge(graphql_route)
    188 193   .merge(explain_route)
    189 194   .merge(health_route)
    190 195   .layer(DefaultBodyLimit::max(10 * MB)); // Set request payload limit to 10 MB
     196 + 
     197 + // If `--introspection-metadata` is specified we also serve the file indicated on `/metadata`
     198 + // and its hash on `/metadata-hash`. This is a temporary workaround to enable the console to
     199 + // interact with an engine process running locally (c.f running in the hasura cloud).
     200 + let app = match &server.introspection_metadata {
     201 + None => app_,
     202 + Some(file) => {
     203 + let file_owned = file.to_string();
     204 + let file_contents = tokio::fs::read_to_string(file_owned)
     205 + .await
     206 + .map_err(|err| StartupError::ReadSchema(err.into()))?;
     207 + let mut hasher = hash::DefaultHasher::new();
     208 + file_contents.as_str().hash(&mut hasher);
     209 + let hash = hasher.finish();
     210 + let base64_hash = base64::engine::general_purpose::STANDARD.encode(hash.to_ne_bytes());
     211 + app_.merge(Router::new().route("/metadata", get(|| async { file_contents })))
     212 + .merge(Router::new().route("/metadata-hash", get(|| async { base64_hash })))
     213 + }
     214 + };
    191 215   
    192 216   // The "unspecified" IPv6 address will match any IPv4 or IPv6 address.
    193 217   let host = net::IpAddr::V6(net::Ipv6Addr::UNSPECIFIED);
    skipped 211 lines
    405 429   response
    406 430  }
    407 431   
    408  -fn read_schema(
    409  - metadata_path: &PathBuf,
    410  -) -> Result<(String, gql::schema::Schema<GDS>), anyhow::Error> {
     432 +fn read_schema(metadata_path: &PathBuf) -> Result<gql::schema::Schema<GDS>, anyhow::Error> {
    411 433   let raw_metadata = std::fs::read_to_string(metadata_path)?;
    412 434   let metadata = open_dds::Metadata::from_json_str(&raw_metadata)?;
    413  - Ok((raw_metadata, engine::build::build_schema(metadata)?))
     435 + Ok(engine::build::build_schema(metadata)?)
    414 436  }
    415 437   
    416 438  fn read_auth_config(path: &PathBuf) -> Result<AuthConfig, anyhow::Error> {
    skipped 6 lines
Please wait...
Page is in error, reload to recover