Async SchemaResolver
Opened this issue · 0 comments
Ezward commented
I'm using an async S3 client to load schemas from a bucket. I've hit a wall in that SchemaResolver is not async, but I need to call an async method within it. Is AsyncSchemaResolver on the roadmap or is there a known work around?
///
/// Download an object from the S3 bucket and turn the result as Bytes
///
pub async fn download_object(client: &Client, bucket_name: &str, key: &str) -> Result<Bytes, S3Error> {
let resp = client
.get_object()
.bucket(bucket_name)
.key(key)
.send()
.await?;
let data = match resp.body.collect().await {
Ok(data) => data,
Err(e) => return Err(S3Error::GetObjectError{ bucket_name: bucket_name.to_string(), key: key.to_string(), msg: e.to_string() }),
};
let data = data.into_bytes();
Ok(data)
}
///
/// Download and object from the S3 bucket and return the results as a json Value
///
pub async fn download_json(client: &Client, bucket_name: &str, path: &str) -> Result<serde_json::Value, JsonError> {
let data = download_object(client, bucket_name, path).await?;
let json: serde_json::Value = serde_json::from_slice(&data)?;
Ok(json)
}
struct S3SchemaResolver {
client: Client, // S3 client
bucket_name: String // name of bucket that holds schemas
}
impl SchemaResolver for S3SchemaResolver {
fn resolve(&self, root_schema: &Value, url: &Url, original_reference: &str) -> Result<Arc<Value>, SchemaResolverError> {
//
// add the base path to the reference
//
match download_json(&self.client, &self.bucket_name, original_reference).await {
Ok(schema_value) => Ok(Arc::new(schema_value)),
Err(json_error) => {
let msg = format!("{}", json_error);
log::error!("{}", msg);
Err(anyhow::anyhow!(msg))
}
}
}
}