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

Commit 87e0050

Browse files
authored
Merge pull request #44 from MindFlavor/develop
Put block list
2 parents b023f25 + d148261 commit 87e0050

21 files changed

+735
-101
lines changed

Cargo.toml

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "azure_sdk_for_rust"
3-
version = "0.7.1"
3+
version = "0.7.2"
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>"]
@@ -15,23 +15,25 @@ categories = ["api-bindings"]
1515
[dependencies]
1616
ring = "0.12.1"
1717
RustyXML = "0.1.1"
18-
base64 = "0.9.1"
18+
base64 = "0.9.2"
1919
chrono = "0.4.2"
2020
env_logger = "0.5.10"
2121
futures = "0.1.21"
2222
hyper = "0.11.27"
2323
hyper-tls = "0.1.3"
24-
log = "0.4.1"
24+
log = "0.4.2"
2525
mime = "0.3.7"
2626
native-tls = "0.1.5"
2727
quick-error = "1.2.2"
28-
serde = "1.0.64"
29-
serde_derive = "1.0.64"
28+
serde = "1.0.66"
29+
serde_derive = "1.0.66"
3030
serde_json = "1.0.19"
3131
time = "0.1.40"
3232
tokio-core = "0.1.17"
3333
url = "1.7.0"
3434
uuid = "0.6.5"
35+
rust-crypto = "0.2.36"
36+
failure = "0.1.1"
3537
smallvec = { version = "0.6", features = ["serde"] }
3638

3739
[features]

README.md

+6-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88

99
[![Crate](https://img.shields.io/crates/v/azure_sdk_for_rust.svg)](https://crates.io/crates/azure_sdk_for_rust) [![cratedown](https://img.shields.io/crates/d/azure_sdk_for_rust.svg)](https://crates.io/crates/azure_sdk_for_rust) [![cratelastdown](https://img.shields.io/crates/dv/azure_sdk_for_rust.svg)](https://crates.io/crates/azure_sdk_for_rust)
1010

11-
[![tag](https://img.shields.io/github/tag/mindflavor/AzureSDKForRust.svg)](https://github.com/MindFlavor/AzureSDKForRust/tree/0.7.1)
12-
[![release](https://img.shields.io/github/release/mindflavor/AzureSDKForRust.svg)](https://github.com/MindFlavor/AzureSDKForRust/tree/0.7.1)
13-
[![commitssince](https://img.shields.io/github/commits-since/mindflavor/AzureSDKForRust/0.7.1.svg)](https://img.shields.io/github/commits-since/mindflavor/AzureSDKForRust/0.7.1.svg)
11+
[![tag](https://img.shields.io/github/tag/mindflavor/AzureSDKForRust.svg)](https://github.com/MindFlavor/AzureSDKForRust/tree/0.7.2)
12+
[![release](https://img.shields.io/github/release/mindflavor/AzureSDKForRust.svg)](https://github.com/MindFlavor/AzureSDKForRust/tree/0.7.2)
13+
[![commitssince](https://img.shields.io/github/commits-since/mindflavor/AzureSDKForRust/0.7.2.svg)](https://img.shields.io/github/commits-since/mindflavor/AzureSDKForRust/0.7.2.svg)
1414

1515
![GitHub contributors](https://img.shields.io/github/contributors/mindflavor/AzureSDKForRust.svg)
1616

@@ -19,6 +19,8 @@ Microsoft Azure expose its technologies via REST API. These APIs are easily cons
1919

2020
This crate relies heavily on the excellent crate called [Hyper](https://github.com/hyperium/hyper). As of this library version [0.4.0](https://github.com/MindFlavor/AzureSDKForRust/releases/tag/0.4.0) all the methods are future-aware.
2121

22+
From the version 0.7.2 I've used the TryFrom and TryTrait options. This means the library is once again nighlty only (until those lints are stabilized).
23+
2224
> **NOTE:** This repository is under heavy development and is likely to break over time. The current releases will probabily contain bugs. As usual open issues if you find any.
2325
2426
## Disclaimer
@@ -215,6 +217,7 @@ If you want to contribute please do! No formality required! :wink:. Please note
215217
| Put blob page | [https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx](https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx) |
216218
| Clear blob page | [https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx](https://msdn.microsoft.com/en-us/library/azure/dd179451.aspx) |
217219
| Put block | [https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx](https://msdn.microsoft.com/en-us/library/azure/dd135726.aspx) |
220+
| Put block list | [https://docs.microsoft.com/en-us/rest/api/storageservices/put-block-list](https://docs.microsoft.com/en-us/rest/api/storageservices/put-block-list) |
218221
| Lease blob | [https://msdn.microsoft.com/library/azure/ee691972.aspx](https://msdn.microsoft.com/library/azure/ee691972.aspx) |
219222

220223
#### Event Hubs

examples/put_block_list.rs

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
extern crate azure_sdk_for_rust;
2+
3+
extern crate chrono;
4+
extern crate env_logger;
5+
extern crate futures;
6+
extern crate hyper;
7+
extern crate hyper_tls;
8+
extern crate tokio_core;
9+
10+
use std::error::Error;
11+
12+
use futures::future::*;
13+
use tokio_core::reactor::Core;
14+
15+
use azure_sdk_for_rust::{
16+
core::lease::{LeaseState, LeaseStatus},
17+
storage::blob::{Blob, BlobType, PUT_BLOCK_OPTIONS_DEFAULT}, storage::client::Client,
18+
};
19+
20+
use azure_sdk_for_rust::storage::blob::{put_block_list, BlobBlockType, BlockList};
21+
22+
use hyper::mime::Mime;
23+
24+
fn main() {
25+
env_logger::init();
26+
code().unwrap();
27+
}
28+
29+
// We run a separate method to use the elegant quotation mark operator.
30+
// A series of unwrap(), unwrap() would have achieved the same result.
31+
fn code() -> Result<(), Box<Error>> {
32+
// First we retrieve the account name and master key from environment variables.
33+
let account =
34+
std::env::var("STORAGE_ACCOUNT").expect("Set env variable STORAGE_ACCOUNT first!");
35+
let master_key =
36+
std::env::var("STORAGE_MASTER_KEY").expect("Set env variable STORAGE_MASTER_KEY first!");
37+
38+
let container_name = std::env::args()
39+
.nth(1)
40+
.expect("please specify container name as first command line parameter");
41+
42+
let mut core = Core::new()?;
43+
44+
let client = Client::new(&core.handle(), &account, &master_key)?;
45+
46+
let name = "asdkrustputblock.txt";
47+
48+
let contents1 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
49+
let contents2 = "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB";
50+
let contents3 = "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
51+
52+
let new_blob = Blob {
53+
name: name.to_owned(),
54+
container_name: container_name.to_owned(),
55+
snapshot_time: None,
56+
last_modified: chrono::Utc::now(),
57+
etag: "".to_owned(),
58+
content_length: 0,
59+
// here we pass text/plain as content_type. This means your browser will
60+
// try to show you the file if you click on it in the Azure portal.
61+
// Make sure to send a text file :)
62+
content_type: Some("text/plain".parse::<Mime>().unwrap()),
63+
content_encoding: None,
64+
content_language: None,
65+
content_md5: None,
66+
cache_control: None,
67+
x_ms_blob_sequence_number: None,
68+
blob_type: BlobType::BlockBlob,
69+
lease_status: LeaseStatus::Unlocked,
70+
lease_state: LeaseState::Available,
71+
lease_duration: None,
72+
copy_id: None,
73+
copy_status: None,
74+
copy_source: None,
75+
copy_progress: None,
76+
copy_completion: None,
77+
copy_status_description: None,
78+
};
79+
80+
let mut block_list = BlockList::default();
81+
82+
let future = new_blob
83+
.put_block(
84+
&client,
85+
"block1",
86+
&PUT_BLOCK_OPTIONS_DEFAULT,
87+
&contents1.as_bytes(),
88+
)
89+
.map(|encoded_block_id| {
90+
println!("block1 blob for blob {} created", name);
91+
block_list
92+
.blocks
93+
.push(BlobBlockType::Uncommitted(encoded_block_id));
94+
block_list
95+
})
96+
.and_then(|mut block_list| {
97+
new_blob
98+
.put_block(
99+
&client,
100+
"block2",
101+
&PUT_BLOCK_OPTIONS_DEFAULT,
102+
&contents2.as_bytes(),
103+
)
104+
.map(|encoded_block_id| {
105+
println!("block2 blob for blob {} created", name);
106+
block_list
107+
.blocks
108+
.push(BlobBlockType::Uncommitted(encoded_block_id));
109+
block_list
110+
})
111+
})
112+
.and_then(|mut block_list| {
113+
new_blob
114+
.put_block(
115+
&client,
116+
"block3",
117+
&PUT_BLOCK_OPTIONS_DEFAULT,
118+
&contents3.as_bytes(),
119+
)
120+
.map(|encoded_block_id| {
121+
println!("block3 blob for blob {} created", name);
122+
block_list
123+
.blocks
124+
.push(BlobBlockType::Uncommitted(encoded_block_id));
125+
block_list
126+
})
127+
})
128+
.map(|block_list| {
129+
println!("{:?}", block_list);
130+
block_list
131+
});
132+
133+
let block_list = core.run(future)?;
134+
135+
// now we can finalize the blob with put_block_list
136+
let future = put_block_list(
137+
&client,
138+
&(&container_name as &str, name),
139+
None,
140+
None,
141+
&block_list,
142+
).map(|_| {
143+
println!("blob finalized!");
144+
});
145+
core.run(future)?;
146+
147+
let future =
148+
Blob::delete(&client, &container_name, &name, None).map(|_| println!("Blob deleted!"));
149+
150+
core.run(future)?;
151+
152+
Ok(())
153+
}

src/azure/core/ba512_range.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,7 @@ impl BA512Range {
2626
return Err(Not512ByteAlignedError::EndRange(end));
2727
}
2828

29-
Ok(BA512Range {
30-
start: start,
31-
end: end,
32-
})
29+
Ok(BA512Range { start, end })
3330
}
3431

3532
#[inline]

src/azure/core/errors.rs

+49-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,24 @@ use std::string;
1616
use url::ParseError as URLParseError;
1717
use xml::BuilderError as XMLError;
1818

19+
quick_error! {
20+
#[derive(Debug)]
21+
pub enum AzurePathParseError {
22+
PathSeparatorNotFoundError {
23+
display("Path separator not found")
24+
}
25+
MultiplePathSeparatorsFoundError {
26+
display("Multiple path separators found")
27+
}
28+
MissingContainerError {
29+
display("Missing container name")
30+
}
31+
MissingBlobError {
32+
display("Missing blob name")
33+
}
34+
}
35+
}
36+
1937
#[derive(Debug, Clone, PartialEq)]
2038
pub struct UnexpectedHTTPResult {
2139
expected: StatusCode,
@@ -26,8 +44,8 @@ pub struct UnexpectedHTTPResult {
2644
impl UnexpectedHTTPResult {
2745
pub fn new(expected: StatusCode, received: StatusCode, body: &str) -> UnexpectedHTTPResult {
2846
UnexpectedHTTPResult {
29-
expected: expected,
30-
received: received,
47+
expected,
48+
received,
3149
body: body.to_owned(),
3250
}
3351
}
@@ -80,7 +98,12 @@ quick_error! {
8098
display("XML error: {}", err)
8199
cause(err)
82100
}
83-
UnexpectedHTTPResult(err: UnexpectedHTTPResult){
101+
AzurePathParseError(err: AzurePathParseError){
102+
from()
103+
display("Azure Path parse error: {}", err)
104+
cause(err)
105+
}
106+
UnexpectedHTTPResult(err: UnexpectedHTTPResult){
84107
from()
85108
display("UnexpectedHTTPResult error")
86109
}
@@ -175,6 +198,10 @@ quick_error! {
175198
from()
176199
display("Parsing error: {:?}", err)
177200
}
201+
BlockListParseError(err: BlockListParseError){
202+
from()
203+
display("Block list XML parsing error: {:?}", err)
204+
}
178205
}
179206
}
180207

@@ -184,6 +211,24 @@ impl From<()> for AzureError {
184211
}
185212
}
186213

214+
#[derive(Debug, Fail)]
215+
pub enum BlockListParseError {
216+
#[fail(display = "invalid BlockList XML")]
217+
InvalidBlockListXML,
218+
#[fail(display = "Invalid Block type: {}", name)]
219+
InvalidBlockType { name: String },
220+
#[fail(display = "Token not found: {}", token)]
221+
TokemNotFound { token: String },
222+
#[fail(display = "Gneric parse error")]
223+
GenericParseError,
224+
}
225+
226+
impl std::convert::From<std::option::NoneError> for BlockListParseError {
227+
fn from(_: std::option::NoneError) -> Self {
228+
BlockListParseError::GenericParseError
229+
}
230+
}
231+
187232
#[inline]
188233
pub fn extract_status_headers_and_body(
189234
resp: hyper::client::FutureResponse,
@@ -246,7 +291,7 @@ pub fn check_status_extract_body(
246291
err(AzureError::UnexpectedHTTPResult(UnexpectedHTTPResult {
247292
expected: expected_status_code,
248293
received: status,
249-
body: body,
294+
body,
250295
}))
251296
}
252297
})

src/azure/core/incompletevector.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,7 @@ pub struct IncompleteVector<T> {
1010

1111
impl<T> IncompleteVector<T> {
1212
pub fn new(token: Option<String>, vector: Vec<T>) -> IncompleteVector<T> {
13-
IncompleteVector {
14-
token: token,
15-
vector: vector,
16-
}
13+
IncompleteVector { token, vector }
1714
}
1815

1916
pub fn is_complete(&self) -> bool {

src/azure/core/range.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ pub struct Range {
1212

1313
impl Range {
1414
pub fn new(start: u64, end: u64) -> Range {
15-
Range {
16-
start: start,
17-
end: end,
18-
}
15+
Range { start, end }
1916
}
2017
}
2118

src/azure/cosmos/authorization_token.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ impl AuthorizationToken {
2727
v_hmac_key.extend(base64::decode(&base64_encoded)?);
2828

2929
Ok(AuthorizationToken {
30-
account: account,
31-
token_type: token_type,
32-
base64_encoded: base64_encoded,
30+
account,
31+
token_type,
32+
base64_encoded,
3333
binary_form: v_hmac_key,
3434
})
3535
}

0 commit comments

Comments
 (0)