Skip to content

Commit 37bde81

Browse files
committed
add client version error message
1 parent 4a5a989 commit 37bde81

File tree

2 files changed

+100
-5
lines changed

2 files changed

+100
-5
lines changed

mithril-client/src/aggregator.rs

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use async_trait::async_trait;
22
use flate2::read::GzDecoder;
33
use futures::StreamExt;
4-
use reqwest::{self, StatusCode};
4+
use reqwest::{self, Response, StatusCode};
55
use reqwest::{Client, RequestBuilder};
66
use slog_scope::debug;
77
use std::env;
@@ -48,6 +48,17 @@ pub enum AggregatorHandlerError {
4848
/// [AggregatorHandler::download_snapshot] beforehand.
4949
#[error("archive not found, did you download it beforehand ? Expected path: '{0}'")]
5050
ArchiveNotFound(PathBuf),
51+
52+
/// Error raised when the server API version mismatch the client API version.
53+
#[error("API version mismatch: {0}")]
54+
ApiVersionMismatch(String),
55+
}
56+
57+
#[cfg(test)]
58+
impl AggregatorHandlerError {
59+
pub fn is_api_version_mismatch(&self) -> bool {
60+
matches!(self, Self::ApiVersionMismatch(_))
61+
}
5162
}
5263

5364
/// AggregatorHandler represents a read interactor with an aggregator
@@ -128,6 +139,22 @@ impl AggregatorHTTPClient {
128139
)),
129140
}
130141
}
142+
143+
/// API version error handling
144+
fn handle_api_error(&self, response: &Response) -> AggregatorHandlerError {
145+
if let Some(version) = response.headers().get("mithril-api-version") {
146+
AggregatorHandlerError::ApiVersionMismatch(format!(
147+
"server version: '{}', signer version: '{}'",
148+
version.to_str().unwrap(),
149+
MITHRIL_API_VERSION
150+
))
151+
} else {
152+
AggregatorHandlerError::ApiVersionMismatch(format!(
153+
"version precondition failed, sent version '{}'.",
154+
MITHRIL_API_VERSION
155+
))
156+
}
157+
}
131158
}
132159

133160
#[async_trait]
@@ -147,6 +174,7 @@ impl AggregatorHandler for AggregatorHTTPClient {
147174
Ok(snapshots) => Ok(snapshots),
148175
Err(err) => Err(AggregatorHandlerError::JsonParseFailed(err.to_string())),
149176
},
177+
StatusCode::PRECONDITION_FAILED => Err(self.handle_api_error(&response)),
150178
status_error => Err(AggregatorHandlerError::RemoteServerTechnical(
151179
status_error.to_string(),
152180
)),
@@ -172,6 +200,7 @@ impl AggregatorHandler for AggregatorHTTPClient {
172200
Ok(snapshot) => Ok(snapshot),
173201
Err(err) => Err(AggregatorHandlerError::JsonParseFailed(err.to_string())),
174202
},
203+
StatusCode::PRECONDITION_FAILED => Err(self.handle_api_error(&response)),
175204
StatusCode::NOT_FOUND => Err(AggregatorHandlerError::RemoteServerLogical(
176205
"snapshot not found".to_string(),
177206
)),
@@ -226,6 +255,7 @@ impl AggregatorHandler for AggregatorHTTPClient {
226255
}
227256
Ok(local_path.into_os_string().into_string().unwrap())
228257
}
258+
StatusCode::PRECONDITION_FAILED => Err(self.handle_api_error(&response)),
229259
StatusCode::NOT_FOUND => Err(AggregatorHandlerError::RemoteServerLogical(
230260
"snapshot archive not found".to_string(),
231261
)),
@@ -352,6 +382,20 @@ mod tests {
352382
assert_eq!(snapshots.unwrap(), snapshots_expected);
353383
}
354384

385+
#[tokio::test]
386+
async fn test_list_snapshots_ko_412() {
387+
let (server, config) = setup_test();
388+
let _snapshots_mock = server.mock(|when, then| {
389+
when.path("/snapshots");
390+
then.status(412).header("mithril-api-version", "0.0.999");
391+
});
392+
let aggregator_client =
393+
AggregatorHTTPClient::new(config.network, config.aggregator_endpoint);
394+
let error = aggregator_client.list_snapshots().await.unwrap_err();
395+
396+
assert!(error.is_api_version_mismatch());
397+
}
398+
355399
#[tokio::test]
356400
async fn test_list_snapshots_ko_500() {
357401
let (server, config) = setup_test();
@@ -403,6 +447,24 @@ mod tests {
403447
assert!(snapshot.is_err());
404448
}
405449

450+
#[tokio::test]
451+
async fn test_snapshot_details_ko_412() {
452+
let (server, config) = setup_test();
453+
let digest = "digest123";
454+
let _snapshots_mock = server.mock(|when, then| {
455+
when.path(format!("/snapshot/{}", digest));
456+
then.status(412).header("mithril-api-version", "0.0.999");
457+
});
458+
let aggregator_client =
459+
AggregatorHTTPClient::new(config.network, config.aggregator_endpoint);
460+
let error = aggregator_client
461+
.get_snapshot_details(digest)
462+
.await
463+
.unwrap_err();
464+
465+
assert!(error.is_api_version_mismatch());
466+
}
467+
406468
#[tokio::test]
407469
async fn get_snapshot_details_ko_500() {
408470
let digest = "digest123";
@@ -448,6 +510,26 @@ mod tests {
448510
assert_eq!(data_downloaded, data_expected);
449511
}
450512

513+
#[tokio::test]
514+
async fn test_download_snapshot_ko_412() {
515+
let (server, config) = setup_test();
516+
let digest = "digest123";
517+
let url_path = "/download";
518+
let _snapshots_mock = server.mock(|when, then| {
519+
when.path(url_path.to_string());
520+
then.status(412).header("mithril-api-version", "0.0.999");
521+
});
522+
let aggregator_client =
523+
AggregatorHTTPClient::new(config.network, config.aggregator_endpoint);
524+
let location = server.url(url_path);
525+
let error = aggregator_client
526+
.download_snapshot(digest, &location)
527+
.await
528+
.unwrap_err();
529+
530+
assert!(error.is_api_version_mismatch());
531+
}
532+
451533
#[tokio::test]
452534
async fn get_download_snapshot_ko_unreachable() {
453535
let digest = "digest123";
@@ -502,6 +584,22 @@ mod tests {
502584
assert!(local_dir_path.is_err());
503585
}
504586

587+
#[tokio::test]
588+
async fn test_certificate_details_412() {
589+
let (server, config) = setup_test();
590+
let certificate_hash = "certificate-hash-123";
591+
let _snapshots_mock = server.mock(|when, then| {
592+
when.path(format!("/certificate/{}", certificate_hash));
593+
then.status(412).header("mithril-api-version", "0.0.999");
594+
});
595+
let aggregator_client =
596+
AggregatorHTTPClient::new(config.network, config.aggregator_endpoint);
597+
let _error = aggregator_client
598+
.get_certificate_details(certificate_hash)
599+
.await
600+
.unwrap_err();
601+
}
602+
505603
#[tokio::test]
506604
async fn get_certificate_details_ok() {
507605
let certificate_hash = "certificate-hash-123";

mithril-signer/src/certificate_handler.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,7 @@ pub enum CertificateHandlerError {
4545
/// convenient methods to error enum
4646
impl CertificateHandlerError {
4747
pub fn is_api_version_mismatch(&self) -> bool {
48-
match self {
49-
Self::ApiVersionMismatch(_) => true,
50-
_ => false,
51-
}
48+
matches!(self, Self::ApiVersionMismatch(_))
5249
}
5350
}
5451

0 commit comments

Comments
 (0)