Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async SchemaResolver #385

Open
Ezward opened this issue Oct 6, 2022 · 0 comments
Open

Async SchemaResolver #385

Ezward opened this issue Oct 6, 2022 · 0 comments

Comments

@Ezward
Copy link

Ezward commented Oct 6, 2022

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))
            }
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants