Skip to content

Commit

Permalink
fix: Missing Content-Type header in responses issue, (#464)
Browse files Browse the repository at this point in the history
* fix issue for schemathesis running

* add new ErrorMessage type

* refactor health endpoints

* remove unused test endpoints

* refactor legacy endpoints

* refactor catalyst endpoints, use a fixed version of poem

* remove poem-extensions crate

* update dart code

* fix fmt

* provide a common ErrorResponses type and convinient other abstractions

* enable schematisis test

* fix

* fix

* wip

* increase max_response_time

* add comment

* wip

* fix

* wip

* update ValidationError handling

* fix documentation

* fixed legacy endpoints responses

* Update catalyst-gateway/bin/src/service/api/cardano/registration_get.rs

Co-authored-by: Steven Johnson <[email protected]>

* Update catalyst-gateway/bin/src/service/api/cardano/sync_state_get.rs

Co-authored-by: Steven Johnson <[email protected]>

* Update catalyst-gateway/bin/src/service/api/cardano/sync_state_get.rs

Co-authored-by: Steven Johnson <[email protected]>

* Update catalyst-gateway/bin/src/service/api/cardano/staked_ada_get.rs

Co-authored-by: Steven Johnson <[email protected]>

* Update catalyst-gateway/bin/src/service/api/cardano/staked_ada_get.rs

Co-authored-by: Steven Johnson <[email protected]>

* Update catalyst-gateway/bin/src/service/api/cardano/registration_get.rs

Co-authored-by: Steven Johnson <[email protected]>

* provide a custom 503 response for health endpoints

* wip

* fix spelling

* fix

* update set_started fn

---------

Co-authored-by: Stefano Cunego <[email protected]>
Co-authored-by: Steven Johnson <[email protected]>
  • Loading branch information
3 people authored May 16, 2024
1 parent dfbb9f8 commit d00fa4a
Show file tree
Hide file tree
Showing 45 changed files with 611 additions and 1,038 deletions.
1 change: 0 additions & 1 deletion catalyst-gateway/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ serde = "1.0"
serde_json = "1.0"
poem = "3.0.0"
poem-openapi = "5.0.0"
poem-extensions = "0.9.0"
prometheus = "0.13.0"
cryptoxide = "0.4.4"
uuid = "1"
Expand Down
1 change: 0 additions & 1 deletion catalyst-gateway/bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ poem-openapi = { workspace = true, features = [
"url",
"chrono",
] }
poem-extensions = { workspace = true }
prometheus = { workspace = true }
cryptoxide = { workspace = true }
uuid = { workspace = true, features = ["v4", "serde"] }
Expand Down
5 changes: 2 additions & 3 deletions catalyst-gateway/bin/src/cardano/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ pub type StakeCredentialKey = String;
pub(crate) const BLAKE_2B_256_HASH_SIZE: usize = 256 / 8;

/// Helper function to generate the `blake2b_256` hash of a byte slice
#[allow(dead_code)]
pub(crate) fn hash(bytes: &[u8]) -> [u8; BLAKE_2B_256_HASH_SIZE] {
let mut digest = [0u8; BLAKE_2B_256_HASH_SIZE];
let mut context = Blake2b::new(BLAKE_2B_256_HASH_SIZE);
Expand Down Expand Up @@ -54,7 +53,7 @@ pub struct PolicyAsset {
}

/// Extract assets
pub fn parse_policy_assets(assets: &[MultiEraPolicyAssets<'_>]) -> Vec<PolicyAsset> {
pub(crate) fn parse_policy_assets(assets: &[MultiEraPolicyAssets<'_>]) -> Vec<PolicyAsset> {
assets
.iter()
.map(|asset| {
Expand All @@ -67,7 +66,7 @@ pub fn parse_policy_assets(assets: &[MultiEraPolicyAssets<'_>]) -> Vec<PolicyAss
}

/// Parse child assets
pub fn parse_child_assets(assets: &[MultiEraAsset]) -> Vec<Asset> {
fn parse_child_assets(assets: &[MultiEraAsset]) -> Vec<Asset> {
assets
.iter()
.filter_map(|asset| {
Expand Down
10 changes: 6 additions & 4 deletions catalyst-gateway/bin/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ use tracing::{error, info};

use crate::{
cardano::start_followers,
logger, service,
logger,
service::{self, started},
settings::{DocsSettings, ServiceSettings},
state::State,
};
Expand Down Expand Up @@ -54,13 +55,14 @@ impl Cli {
}
});

start_followers(
let followers_fut = start_followers(
event_db.clone(),
settings.follower_settings.check_config_tick,
settings.follower_settings.data_refresh_tick,
machine_id,
)
.await?;
);
started();
followers_fut.await?;

Ok(())
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
//! Implementation of the GET `/date_time_to_slot_number` endpoint

use poem_extensions::{response, UniResponse::T200};
use poem_openapi::payload::Json;
use poem_openapi::{payload::Json, ApiResponse};

use crate::{
event_db::{
Expand All @@ -13,22 +12,21 @@ use crate::{
network::Network,
slot_info::{Slot, SlotInfo},
},
responses::{
resp_2xx::OK,
resp_4xx::ApiValidationError,
resp_5xx::{handle_5xx_response, ServerError, ServiceUnavailable},
},
responses::WithErrorResponses,
},
state::State,
};

/// # All Responses
pub(crate) type AllResponses = response! {
200: OK<Json<SlotInfo>>,
400: ApiValidationError,
500: ServerError,
503: ServiceUnavailable,
};
/// Endpoint responses.
#[derive(ApiResponse)]
pub(crate) enum Responses {
/// Returns the slot info.
#[oai(status = 200)]
Ok(Json<SlotInfo>),
}

/// All responses.
pub(crate) type AllResponses = WithErrorResponses<Responses>;

/// # GET `/date_time_to_slot_number`
#[allow(clippy::unused_async)]
Expand Down Expand Up @@ -71,20 +69,21 @@ pub(crate) async fn endpoint(

let current = match process_slot_info_result(current) {
Ok(current) => current,
Err(err) => return handle_5xx_response!(err),
Err(err) => return AllResponses::handle_error(&err),
};
let previous = match process_slot_info_result(previous) {
Ok(current) => current,
Err(err) => return handle_5xx_response!(err),
Err(err) => return AllResponses::handle_error(&err),
};
let next = match process_slot_info_result(next) {
Ok(current) => current,
Err(err) => return handle_5xx_response!(err),
Err(err) => return AllResponses::handle_error(&err),
};

T200(OK(Json(SlotInfo {
Responses::Ok(Json(SlotInfo {
previous,
current,
next,
})))
}))
.into()
}
31 changes: 0 additions & 31 deletions catalyst-gateway/bin/src/service/api/cardano/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,6 @@ impl CardanoApi {
///
/// This endpoint returns the total Cardano's staked ada amount to the corresponded
/// user's stake address.
///
/// ## Responses
/// * 200 OK - Returns the staked ada amount.
/// * 400 Bad Request.
/// * 404 Not Found.
/// * 500 Server Error - If anything within this function fails unexpectedly.
/// * 503 Service Unavailable - Service is not ready, requests to other
/// endpoints should not be sent until the service becomes ready.
async fn staked_ada_get(
&self, data: Data<&Arc<State>>,
/// The stake address of the user.
Expand Down Expand Up @@ -80,14 +72,6 @@ impl CardanoApi {
///
/// This endpoint returns the registration info followed by the [CIP-36](https://cips.cardano.org/cip/CIP-36/) to the
/// corresponded user's stake address.
///
/// ## Responses
/// * 200 OK - Returns the registration info.
/// * 400 Bad Request.
/// * 404 Not Found.
/// * 500 Server Error - If anything within this function fails unexpectedly.
/// * 503 Service Unavailable - Service is not ready, requests to other
/// endpoints should not be sent until the service becomes ready.
async fn registration_get(
&self, data: Data<&Arc<State>>,
/// The stake address of the user.
Expand Down Expand Up @@ -119,14 +103,6 @@ impl CardanoApi {
/// Get Cardano follower's sync state.
///
/// This endpoint returns the current cardano follower's sync state info.
///
/// ## Responses
/// * 200 OK - Returns the follower's sync state.
/// * 400 Bad Request.
/// * 404 Not Found.
/// * 500 Server Error - If anything within this function fails unexpectedly.
/// * 503 Service Unavailable - Service is not ready, requests to other
/// endpoints should not be sent until the service becomes ready.
async fn sync_state_get(
&self, data: Data<&Arc<State>>,
/// Cardano network type.
Expand All @@ -149,13 +125,6 @@ impl CardanoApi {
///
/// This endpoint returns the closest cardano slot info to the provided
/// date-time.
///
/// ## Responses
/// * 200 OK - Returns the slot info.
/// * 400 Bad Request.
/// * 500 Server Error - If anything within this function fails unexpectedly.
/// * 503 Service Unavailable - Service is not ready, requests to other
/// endpoints should not be sent until the service becomes ready.
async fn date_time_to_slot_number_get(
&self, data: Data<&Arc<State>>,
/// The date-time for which the slot number should be calculated.
Expand Down
46 changes: 22 additions & 24 deletions catalyst-gateway/bin/src/service/api/cardano/registration_get.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
//! Implementation of the GET `/registration` endpoint

use poem_extensions::{
response,
UniResponse::{T200, T400, T404},
};
use poem_openapi::payload::Json;
use poem_openapi::{payload::Json, ApiResponse};

use crate::{
event_db::{cardano::chain_state::SlotNumber, error::NotFoundError},
Expand All @@ -13,26 +9,27 @@ use crate::{
objects::cardano::{
network::Network, registration_info::RegistrationInfo, stake_address::StakeAddress,
},
responses::{
resp_2xx::OK,
resp_4xx::{ApiValidationError, NotFound},
resp_5xx::{handle_5xx_response, ServerError, ServiceUnavailable},
},
responses::WithErrorResponses,
},
utilities::check_network,
},
state::State,
};

/// # All Responses
#[allow(dead_code)]
pub(crate) type AllResponses = response! {
200: OK<Json<RegistrationInfo>>,
400: ApiValidationError,
404: NotFound,
500: ServerError,
503: ServiceUnavailable,
};
/// Endpoint responses
#[derive(ApiResponse)]
pub(crate) enum Responses {
/// The registration information for the stake address queried.
#[oai(status = 200)]
Ok(Json<RegistrationInfo>),
/// No valid registration found for the provided stake address
/// and provided slot number.
#[oai(status = 404)]
NotFound,
}

/// All responses
pub(crate) type AllResponses = WithErrorResponses<Responses>;

/// # GET `/registration`
pub(crate) async fn endpoint(
Expand All @@ -45,7 +42,7 @@ pub(crate) async fn endpoint(
let stake_credential = stake_address.payload().as_hash().to_vec();
let network = match check_network(stake_address.network(), provided_network) {
Ok(network) => network,
Err(err) => return T400(err),
Err(err) => return AllResponses::handle_error(&err),
};

// get the total utxo amount from the database
Expand All @@ -54,14 +51,15 @@ pub(crate) async fn endpoint(
.await
{
Ok((tx_id, payment_address, voting_info, nonce)) => {
T200(OK(Json(RegistrationInfo::new(
Responses::Ok(Json(RegistrationInfo::new(
tx_id,
&payment_address,
voting_info,
nonce,
))))
)))
.into()
},
Err(err) if err.is::<NotFoundError>() => T404(NotFound),
Err(err) => handle_5xx_response!(err),
Err(err) if err.is::<NotFoundError>() => Responses::NotFound.into(),
Err(err) => AllResponses::handle_error(&err),
}
}
44 changes: 21 additions & 23 deletions catalyst-gateway/bin/src/service/api/cardano/staked_ada_get.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
//! Implementation of the GET `/staked_ada` endpoint

use poem_extensions::{
response,
UniResponse::{T200, T400, T404},
};
use poem_openapi::payload::Json;
use poem_openapi::{payload::Json, ApiResponse};

use crate::{
event_db::{cardano::chain_state::SlotNumber, error::NotFoundError},
Expand All @@ -13,25 +9,26 @@ use crate::{
objects::cardano::{
network::Network, stake_address::StakeAddress, stake_info::StakeInfo,
},
responses::{
resp_2xx::OK,
resp_4xx::{ApiValidationError, NotFound},
resp_5xx::{handle_5xx_response, ServerError, ServiceUnavailable},
},
responses::WithErrorResponses,
},
utilities::check_network,
},
state::State,
};

/// # All Responses
pub(crate) type AllResponses = response! {
200: OK<Json<StakeInfo>>,
400: ApiValidationError,
404: NotFound,
500: ServerError,
503: ServiceUnavailable,
};
/// Endpoint responses.
#[derive(ApiResponse)]
pub(crate) enum Responses {
/// The amount of ADA staked by the queried stake address, as at the indicated slot.
#[oai(status = 200)]
Ok(Json<StakeInfo>),
/// The queried stake address was not found at the requested slot number.
#[oai(status = 404)]
NotFound,
}

/// All responses.
pub(crate) type AllResponses = WithErrorResponses<Responses>;

/// # GET `/staked_ada`
pub(crate) async fn endpoint(
Expand All @@ -45,7 +42,7 @@ pub(crate) async fn endpoint(

let network = match check_network(stake_address.network(), provided_network) {
Ok(network) => network,
Err(err) => return T400(err),
Err(err) => return AllResponses::handle_error(&err),
};

// get the total utxo amount from the database
Expand All @@ -54,12 +51,13 @@ pub(crate) async fn endpoint(
.await
{
Ok((amount, slot_number)) => {
T200(OK(Json(StakeInfo {
Responses::Ok(Json(StakeInfo {
amount,
slot_number,
})))
}))
.into()
},
Err(err) if err.is::<NotFoundError>() => T404(NotFound),
Err(err) => handle_5xx_response!(err),
Err(err) if err.is::<NotFoundError>() => Responses::NotFound.into(),
Err(err) => AllResponses::handle_error(&err),
}
}
Loading

0 comments on commit d00fa4a

Please sign in to comment.