From f61b43c6b646193be4b9e6705d8c3d83b2c3ba93 Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 16 Jan 2022 17:32:28 +0200 Subject: refactor: combine the chunk client into BackupClient The split doesn't seem to make sense any more. Sponsored-by: author --- src/client.rs | 105 ++++++++++++++++++++-------------------------------------- 1 file changed, 36 insertions(+), 69 deletions(-) diff --git a/src/client.rs b/src/client.rs index e9b00cd..bcc31b4 100644 --- a/src/client.rs +++ b/src/client.rs @@ -97,78 +97,16 @@ pub enum ClientError { /// Client for the Obnam server HTTP API. pub struct BackupClient { - chunk_client: ChunkClient, + client: reqwest::Client, + base_url: String, + cipher: CipherEngine, } impl BackupClient { /// Create a new backup client. pub fn new(config: &ClientConfig) -> Result { info!("creating backup client with config: {:#?}", config); - Ok(Self { - chunk_client: ChunkClient::new(config)?, - }) - } - - /// Does the server have a chunk? - pub async fn has_chunk(&self, meta: &ChunkMeta) -> Result, ClientError> { - self.chunk_client.has_chunk(meta).await - } - - /// Upload a data chunk to the srver. - pub async fn upload_chunk(&self, chunk: DataChunk) -> Result { - self.chunk_client.upload_chunk(chunk).await - } - - /// List backup generations known by the server. - pub async fn list_generations(&self) -> Result { - self.chunk_client.list_generations().await - } - - /// Fetch a data chunk from the server, given the chunk identifier. - pub async fn fetch_chunk(&self, chunk_id: &ChunkId) -> Result { - self.chunk_client.fetch_chunk(chunk_id).await - } - - async fn fetch_generation_chunk(&self, gen_id: &GenId) -> Result { - let chunk = self.fetch_chunk(gen_id.as_chunk_id()).await?; - let gen = GenerationChunk::from_data_chunk(&chunk)?; - Ok(gen) - } - /// Fetch a backup generation's metadata, given it's identifier. - pub async fn fetch_generation( - &self, - gen_id: &GenId, - dbname: &Path, - ) -> Result { - let gen = self.fetch_generation_chunk(gen_id).await?; - - // Fetch the SQLite file, storing it in the named file. - let mut dbfile = File::create(&dbname) - .map_err(|err| ClientError::FileCreate(dbname.to_path_buf(), err))?; - for id in gen.chunk_ids() { - let chunk = self.fetch_chunk(id).await?; - dbfile - .write_all(chunk.data()) - .map_err(|err| ClientError::FileWrite(dbname.to_path_buf(), err))?; - } - info!("downloaded generation to {}", dbname.display()); - - let gen = LocalGeneration::open(dbname)?; - Ok(gen) - } -} - -/// Client for using chunk part of Obnam server HTTP API. -pub struct ChunkClient { - client: reqwest::Client, - base_url: String, - cipher: CipherEngine, -} - -impl ChunkClient { - /// Create a new chunk client. - pub fn new(config: &ClientConfig) -> Result { let pass = config.passwords()?; let client = reqwest::Client::builder() @@ -190,7 +128,7 @@ impl ChunkClient { format!("{}/chunks", self.base_url()) } - /// Does server have a chunk? + /// Does the server have a chunk? pub async fn has_chunk(&self, meta: &ChunkMeta) -> Result, ClientError> { let body = match self.get("", &[("sha256", meta.sha256())]).await { Ok((_, body)) => body, @@ -209,7 +147,7 @@ impl ChunkClient { Ok(has) } - /// Upload a new chunk to the server. + /// Upload a data chunk to the srver. pub async fn upload_chunk(&self, chunk: DataChunk) -> Result { let enc = self.cipher.encrypt_chunk(&chunk)?; let res = self @@ -232,7 +170,7 @@ impl ChunkClient { Ok(chunk_id) } - /// List all generation chunks on the server. + /// List backup generations known by the server. pub async fn list_generations(&self) -> Result { let (_, body) = self.get("", &[("generation", "true")]).await?; @@ -246,7 +184,7 @@ impl ChunkClient { Ok(GenerationList::new(finished)) } - /// Fetch a chunk from the server, given its id. + /// Fetch a data chunk from the server, given the chunk identifier. pub async fn fetch_chunk(&self, chunk_id: &ChunkId) -> Result { let (headers, body) = self.get(&format!("/{}", chunk_id), &[]).await?; let meta = self.get_chunk_meta_header(chunk_id, &headers)?; @@ -257,6 +195,35 @@ impl ChunkClient { Ok(chunk) } + async fn fetch_generation_chunk(&self, gen_id: &GenId) -> Result { + let chunk = self.fetch_chunk(gen_id.as_chunk_id()).await?; + let gen = GenerationChunk::from_data_chunk(&chunk)?; + Ok(gen) + } + + /// Fetch a backup generation's metadata, given it's identifier. + pub async fn fetch_generation( + &self, + gen_id: &GenId, + dbname: &Path, + ) -> Result { + let gen = self.fetch_generation_chunk(gen_id).await?; + + // Fetch the SQLite file, storing it in the named file. + let mut dbfile = File::create(&dbname) + .map_err(|err| ClientError::FileCreate(dbname.to_path_buf(), err))?; + for id in gen.chunk_ids() { + let chunk = self.fetch_chunk(id).await?; + dbfile + .write_all(chunk.data()) + .map_err(|err| ClientError::FileWrite(dbname.to_path_buf(), err))?; + } + info!("downloaded generation to {}", dbname.display()); + + let gen = LocalGeneration::open(dbname)?; + Ok(gen) + } + async fn get( &self, path: &str, -- cgit v1.2.1