26个不稳定版本 (11个破坏性更新)
0.12.0 | 2019年6月1日 |
---|---|
0.11.0 | 2019年3月12日 |
0.10.3 | 2018年12月22日 |
0.10.0 | 2018年8月26日 |
0.1.3 | 2016年2月5日 |
#212 in #iot
每月33次下载
620KB
16K SLoC
微软Azure SDK for Rust
简介
微软Azure通过REST API公开其技术。这些API易于从任何语言中消费(优点),但类型较弱。使用这个库及其相关的crate,您可以用一种符合Rust风格的方式利用微软Azure的功能。
此crate严重依赖名为Hyper的出色crate。截至本库版本0.4.0,所有方法都是未来感知的。
从版本0.8.0的Cosmos和0.9.0的Storage开始,仓库开始采用builder模式。截至0.10.0,大多数存储API已迁移到builder模式,但仍有方法缺失。请检查相关问题以跟踪更新过程。这仍然是一个进行中的过渡,但生成的API要容易使用得多。此外,大多数检查都已移动到编译时。遗憾的是,这些更改不是向后兼容的。我在这里记录了我的方法:https://dev.to/mindflavor/rust-builder-pattern-with-types-3chf。
从版本0.12.0开始,库从hyper-tls切换到hyper-rustls,这是bmc-msft在问题#120中建议的。这应该允许库实现100%的rust。
注意:此仓库正在积极开发中,可能会在一段时间内出现故障。当前版本可能包含错误。如往常一样,如果发现问题,请提交问题。
免责声明
尽管我是微软员工,但这不是一个微软认可的项目。这仅仅是我个人的项目:我喜欢Rust(谁不喜欢呢?😏)以及微软Azure技术,所以我想弥合它们之间的差距。这也是学习Rust的好项目。此库严重依赖于Hyper。我们使用最新的Hyper代码,因此此库完全异步,具有Futures和Tokio。
示例
您可以在examples
文件夹中找到示例。这里是一瞥:
main.rs
extern crate azure_sdk_for_rust;
extern crate chrono;
extern crate futures;
extern crate hyper;
extern crate hyper_tls;
extern crate tokio;
extern crate tokio_core;
use std::error::Error;
use futures::future::*;
use tokio_core::reactor::Core;
use azure_sdk_for_rust::cosmos::{AuthorizationToken, Client, TokenType};
#[macro_use]
extern crate serde_derive;
use azure_sdk_for_rust::cosmos;
#[derive(Serialize, Deserialize, Debug)]
struct MySampleStruct<'a> {
id: &'a str,
a_string: &'a str,
a_number: u64,
a_timestamp: i64,
}
// Following the official azure cosmos db tutorial: https://docs.microsoft.com/pt-br/azure/cosmos-db/sql-api-dotnetcore-get-started
// Master key is the Primary Key from Keys section in your CosmosDB screen
// Account is the first part of URI from Keys section, if your URI is https://test.documents.azure.com:443/ the account is test
// DATABASES are the base objects in your Data Explorer section
// COLLECTIONS are the objects inside the DATABASES
const DATABASE: &'static str = "azuresdktestdb";
const COLLECTION: &'static str = "azuresdktc";
fn main() {
code().unwrap();
}
// This code will perform these tasks:
// 1. Find an Azure Cosmos DB called *DATABASE*. If it does not exist, create it.
// 2. Find an Azure Cosmos collection called *COLLECTION* in *DATABASE*.
// If it does not exist, create it.
// 3. Store an entry in collection *COLLECTION* of database *DATABASE*.
// 4. Delete everything.
//
// We will use multiple futures for this hoping to make the code clearer.
// There is no need to proceed this way in your code.
// You can go crazy with future combinators if you want to :)
fn code() -> Result<(), Box<Error>> {
// Let's get Cosmos account and master key from env variables.
// This helps automated testing.
let master_key =
std::env::var("COSMOSDB_MASTER_KEY").expect("Set env variable COSMOS_MASTER_KEY first!");
let account =
std::env::var("COSMOSDB_ACCOUNT").expect("Set env variable COSMOS_ACCOUNT first!");
// First, we create an authorization token. There are two types of tokens, master and resource
// constrained. Please check the Azure documentation for details. You can change tokens
// at will and it's a good practice to raise your privileges only when needed.
let authorization_token = AuthorizationToken::new(account, TokenType::Master, &master_key)?;
// We will create a tokio-core reactor which will drive our futures.
let mut core = Core::new()?;
// Next we will create a Cosmos client. You need an authorization_token but you can later
// change it if needed. Notice the client will be tied to your reactor.
let client = Client::new(authorization_token)?;
// list_databases will give us the databases available in our account. If there is
// an error (for example, the given key is not valid) you will receive a
// specific AzureError. In this example we will look for a specific database
// so we chain a filter operation.
let future = client
.list_databases()
.and_then(|databases| ok(databases.into_iter().find(|db| db.id == DATABASE)));
// Now we run the future and check the answer. If the requested database
// is not found we create it.
let database = match core.run(future)? {
Some(db) => db,
None => core.run(client.create_database(DATABASE))?,
};
println!("database == {:?}", database);
// Now we look for a specific collection. If is not already present
// we will create it. The collection creation is more complex and
// has many options (such as indexing and so on).
let collection = {
let collections = core.run(client.list_collections(&DATABASE))?;
if let Some(collection) = collections.into_iter().find(|coll| coll.id == COLLECTION) {
collection
} else {
let indexes = cosmos::collection::IncludedPathIndex {
kind: cosmos::collection::KeyKind::Hash,
data_type: cosmos::collection::DataType::String,
precision: Some(3),
};
let ip = cosmos::collection::IncludedPath {
path: "/*".to_owned(),
indexes: vec![indexes],
};
let ip = cosmos::collection::IndexingPolicy {
automatic: true,
indexing_mode: cosmos::collection::IndexingMode::Consistent,
included_paths: vec![ip],
excluded_paths: vec![],
};
let coll = cosmos::collection::Collection::new(COLLECTION, ip);
// Notice here we specify the expected performance level.
// Performance levels have price impact. Also, higher
// performance levels force you to specify an indexing
// strategy. Consult the documentation for more details.
core.run(client.create_collection(&DATABASE, 400, &coll))?
}
};
println!("collection = {:?}", collection);
// Now that we have a database and a collection we can insert
// data in them. Let's create a struct. The only constraint
// is that the struct should be Serializable.
let doc = MySampleStruct {
id: "unique_id1",
a_string: "Something here",
a_number: 100,
a_timestamp: chrono::Utc::now().timestamp(),
};
// Now we store the struct in Azure Cosmos DB.
// Notice how easy it is! :)
// The method create_document will return, upon success,
// the document attributes.
let document_attributes = core.run(
client
.create_document(&DATABASE, &COLLECTION, &doc)
.execute(),
)?;
println!("document_attributes == {:?}", document_attributes);
// We will perform some cleanup. First we delete the collection...
core.run(client.delete_collection(DATABASE, &COLLECTION))?;
println!("collection deleted");
// And then we delete the database.
core.run(client.delete_database(DATABASE))?;
println!("database deleted");
Ok(())
}
最先进的技术
目前,关键框架已经到位(身份验证、枚举、解析等)。如果您想贡献,请随时!方法每天都在增加,请检查发布页面以获取进度更新。请注意,该项目处于早期阶段,因此API可能会随时更改。我会努力保持稳定,但因为我刚接触Rust,我肯定在不久的将来需要纠正一些严重的错误😄。我通常为最新的夜间版本构建,并让Travis检查向后兼容性。
贡献
如果您想贡献,请随时!无需拘泥于形式!😉。请注意,提出拉取请求表示您同意按照Apache许可证,版本2.0将您的代码作为贡献。
实现的方法
存储容器
存储Blob
事件中心
方法 | URL |
---|---|
发送事件 | https://msdn.microsoft.com/en-us/library/azure/dn790664.aspx |
Cosmos数据库
数据库
集合
文档
Azure表
Azure 表实体可以批量操作。实体以 JSON
格式序列化。
运行端到端测试
Linux
export STORAGE_ACCOUNT=<account>
export STORAGE_MASTER_KEY=<key>
export AZURE_SERVICE_BUS_NAMESPACE=<azure_service_bus_namespace>
export AZURE_EVENT_HUB_NAME=<azure_event_hub_name>
export AZURE_POLICY_NAME=<azure_policy_name>
export AZURE_POLICY_KEY=<azure policy key>
cargo test --features=test_e2e
Windows
set STORAGE_ACCOUNT=<account>
set STORAGE_MASTER_KEY=<key>
set AZURE_SERVICE_BUS_NAMESPACE=<azure_service_bus_namespace>
set AZURE_EVENT_HUB_NAME=<azure_event_hub_name>
set AZURE_POLICY_NAME=<azure_policy_name>
set AZURE_POLICY_KEY=<azure policy key>
cargo test --features=test_e2e
许可协议
本项目采用 Apache 许可协议,版本 2.0 发布。
依赖项
~22MB
~515K SLoC