Skip to content
This repository was archived by the owner on Oct 6, 2020. It is now read-only.

Commit e52f83d

Browse files
authored
Merge pull request #106 from MindFlavor/emulator_support/pr
Added support for Azure storage emulator
2 parents 8e11687 + b636dec commit e52f83d

18 files changed

+137
-81
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "azure_sdk_for_rust"
3-
version = "0.10.0"
3+
version = "0.10.1"
44
description = "Rust wrappers around Microsoft Azure REST APIs"
55
readme = "README.md"
66
authors = ["Francesco Cogno <francesco.cogno@outlook.com>", "Max Gortman <mgortman@microsoft.com>", "Dong Liu <doliu@microsoft.com>"]

examples/emulator00.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
extern crate azure_sdk_for_rust;
2+
extern crate chrono;
3+
extern crate env_logger;
4+
extern crate futures;
5+
extern crate hyper;
6+
extern crate hyper_tls;
7+
extern crate log;
8+
extern crate md5;
9+
extern crate tokio_core;
10+
extern crate url;
11+
12+
use azure_sdk_for_rust::prelude::*;
13+
use azure_sdk_for_rust::storage::container::PublicAccess;
14+
use futures::future::*;
15+
use std::error::Error;
16+
use tokio_core::reactor::Core;
17+
use url::Url;
18+
19+
fn main() -> Result<(), Box<Error>> {
20+
env_logger::init();
21+
22+
let mut core = Core::new()?;
23+
24+
// this is how you use the emulator.
25+
let blob_storage_url = "http://127.0.0.1:10000";
26+
let table_storage_url = "http://127.0.0.1:10002";
27+
let client = Client::emulator(&Url::parse(blob_storage_url)?, &Url::parse(table_storage_url)?)?;
28+
29+
// create container
30+
let future = client
31+
.create_container()
32+
.with_container_name("emulcont")
33+
.with_public_access(PublicAccess::None)
34+
.finalize();
35+
core.run(future.map(|res| println!("{:?}", res)))?;
36+
37+
let future = client
38+
.list_blobs()
39+
.with_container_name("emulcont")
40+
.with_include_metadata()
41+
.finalize();
42+
core.run(future.map(|res| println!("{:?}", res)))?;
43+
44+
Ok(())
45+
}

src/azure/core/parsing.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,12 @@ pub fn find_subnodes<'a>(node: &'a Element, subnode: &str) -> Vec<&'a Element> {
119119
.filter(|x| match **x {
120120
ElementNode(ref mynode) => mynode.name == subnode,
121121
_ => false,
122-
}).map(|x| match *x {
122+
})
123+
.map(|x| match *x {
123124
ElementNode(ref mynode) => mynode,
124125
_ => unreachable!(),
125-
}).collect::<Vec<_>>()
126+
})
127+
.collect::<Vec<_>>()
126128
}
127129

128130
#[inline]

src/azure/storage/blob/mod.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ impl Blob {
224224
.ok_or_else(|| {
225225
static CL: header::HeaderName = header::CONTENT_LENGTH;
226226
AzureError::HeaderNotFound(CL.as_str().to_owned())
227-
})?.to_str()?
227+
})?
228+
.to_str()?
228229
.parse::<u64>()?;
229230
trace!("content_length == {:?}", content_length);
230231

@@ -370,15 +371,15 @@ where
370371
{
371372
match params {
372373
Some(ref params) => format!(
373-
"https://{}.blob.core.windows.net/{}/{}?{}",
374-
t.client().account(),
374+
"{}/{}/{}?{}",
375+
t.client().blob_uri(),
375376
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
376377
utf8_percent_encode(t.blob_name(), COMPLETE_ENCODE_SET),
377378
params
378379
),
379380
None => format!(
380-
"https://{}.blob.core.windows.net/{}/{}",
381-
t.client().account(),
381+
"{}/{}/{}",
382+
t.client().blob_uri(),
382383
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
383384
utf8_percent_encode(t.blob_name(), COMPLETE_ENCODE_SET)
384385
),

src/azure/storage/client.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@ use azure::storage::{blob, container};
55
use hyper::{self, Method};
66
use hyper_tls;
77
use std::borrow::Borrow;
8-
9-
// Can be variant for different cloud environment
10-
const SERVICE_SUFFIX_BLOB: &str = ".blob.core.windows.net";
11-
const SERVICE_SUFFIX_TABLE: &str = ".table.core.windows.net";
8+
use url::Url;
129

1310
pub trait Blob {
1411
fn list_blobs<'a>(&'a self) -> blob::requests::ListBlobBuilder<'a, No>;
@@ -50,6 +47,8 @@ pub struct Client {
5047
account: String,
5148
key: String,
5249
hc: hyper::Client<hyper_tls::HttpsConnector<hyper::client::HttpConnector>>,
50+
blob_uri: String,
51+
table_uri: String,
5352
}
5453

5554
impl Blob for Client {
@@ -174,14 +173,35 @@ impl Container for Client {
174173

175174
impl Client {
176175
pub fn new(account: &str, key: &str) -> Result<Client, AzureError> {
177-
use hyper;
176+
Client::azure(account, key)
177+
}
178178

179+
pub fn azure(account: &str, key: &str) -> Result<Client, AzureError> {
179180
let client = hyper::Client::builder().build(hyper_tls::HttpsConnector::new(4)?);
180181

181182
Ok(Client {
182183
account: account.to_owned(),
183184
key: key.to_owned(),
184185
hc: client,
186+
blob_uri: format!("https://{}.blob.core.windows.net", account),
187+
table_uri: format!("https://{}.table.core.windows.net", account),
188+
})
189+
}
190+
191+
pub fn emulator(blob_storage_url: &Url, table_storage_url: &Url) -> Result<Client, AzureError> {
192+
let client = hyper::Client::builder().build(hyper_tls::HttpsConnector::new(4)?);
193+
194+
let blob_uri = format!("{}devstoreaccount1", blob_storage_url.as_str());
195+
debug!("blob_uri == {}", blob_uri);
196+
let table_uri = format!("{}devstoreaccount1", table_storage_url.as_str());
197+
debug!("table_uri == {}", table_uri);
198+
199+
Ok(Client {
200+
account: "devstoreaccount1".to_owned(),
201+
key: "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==".to_owned(),
202+
hc: client,
203+
blob_uri,
204+
table_uri,
185205
})
186206
}
187207

@@ -193,6 +213,16 @@ impl Client {
193213
&self.key
194214
}
195215

216+
#[inline]
217+
pub(crate) fn blob_uri(&self) -> &str {
218+
&self.blob_uri
219+
}
220+
221+
#[inline]
222+
pub(crate) fn table_uri(&self) -> &str {
223+
&self.table_uri
224+
}
225+
196226
pub(crate) fn perform_request<F>(
197227
&self,
198228
uri: &str,
@@ -230,12 +260,9 @@ impl Client {
230260

231261
/// Uri scheme + authority e.g. http://myaccount.table.core.windows.net/
232262
pub(crate) fn get_uri_prefix(&self, service_type: ServiceType) -> String {
233-
"https://".to_owned()
234-
+ self.account()
235-
+ match service_type {
236-
ServiceType::Blob => SERVICE_SUFFIX_BLOB,
237-
ServiceType::Table => SERVICE_SUFFIX_TABLE,
238-
}
239-
+ "/"
263+
match service_type {
264+
ServiceType::Blob => format!("{}/", self.blob_uri()),
265+
ServiceType::Table => format!("{}/", self.table_uri()),
266+
}
240267
}
241268
}

src/azure/storage/container/create_request.rs

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/azure/storage/container/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,14 +229,14 @@ where
229229
{
230230
match params {
231231
Some(ref params) => format!(
232-
"https://{}.blob.core.windows.net/{}?{}",
233-
t.client().account(),
232+
"{}/{}?{}",
233+
t.client().blob_uri(),
234234
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
235235
params
236236
),
237237
None => format!(
238-
"https://{}.blob.core.windows.net/{}",
239-
t.client().account(),
238+
"{}/{}",
239+
t.client().blob_uri(),
240240
utf8_percent_encode(t.container_name(), COMPLETE_ENCODE_SET),
241241
),
242242
}

src/azure/storage/container/requests/acquire_lease_builder.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -250,13 +250,14 @@ impl<'a, ContainerNameSet, LeaseDurationSet> AcquireLeaseBuilder<'a, ContainerNa
250250
where
251251
ContainerNameSet: ToAssign,
252252
LeaseDurationSet: ToAssign,
253-
{}
253+
{
254+
}
254255

255256
impl<'a> AcquireLeaseBuilder<'a, Yes, Yes> {
256257
pub fn finalize(self) -> impl Future<Item = AcquireLeaseResponse, Error = AzureError> {
257258
let mut uri = format!(
258-
"https://{}.blob.core.windows.net/{}?comp=lease&restype=container",
259-
self.client().account(),
259+
"{}/{}?comp=lease&restype=container",
260+
self.client().blob_uri(),
260261
self.container_name()
261262
);
262263

src/azure/storage/container/requests/break_lease_builder.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,8 +192,8 @@ impl<'a, ContainerNameSet> BreakLeaseBuilder<'a, ContainerNameSet> where Contain
192192
impl<'a> BreakLeaseBuilder<'a, Yes> {
193193
pub fn finalize(self) -> impl Future<Item = BreakLeaseResponse, Error = AzureError> {
194194
let mut uri = format!(
195-
"https://{}.blob.core.windows.net/{}?comp=lease&restype=container",
196-
self.client().account(),
195+
"{}/{}?comp=lease&restype=container",
196+
self.client().blob_uri(),
197197
self.container_name()
198198
);
199199

src/azure/storage/container/requests/create_builder.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,8 @@ impl<'a, ContainerNameSet, PublicAccessSet> CreateBuilder<'a, ContainerNameSet,
165165
where
166166
ContainerNameSet: ToAssign,
167167
PublicAccessSet: ToAssign,
168-
{}
168+
{
169+
}
169170

170171
impl<'a, ContainerNameSet, PublicAccessSet> ContainerNameSupport<'a> for CreateBuilder<'a, ContainerNameSet, PublicAccessSet>
171172
where
@@ -214,11 +215,7 @@ impl<'a> CreateBuilder<'a, No, No> {
214215

215216
impl<'a> CreateBuilder<'a, Yes, Yes> {
216217
pub fn finalize(self) -> impl Future<Item = (), Error = AzureError> {
217-
let mut uri = format!(
218-
"https://{}.blob.core.windows.net/{}?restype=container",
219-
self.client().account(),
220-
self.container_name()
221-
);
218+
let mut uri = format!("{}/{}?restype=container", self.client().blob_uri(), self.container_name());
222219

223220
if let Some(nm) = TimeoutOption::to_uri_parameter(&self) {
224221
uri = format!("{}&{}", uri, nm);

0 commit comments

Comments
 (0)