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

fix iothub device update by bumping api version to 2022-10-01 #1636

Merged
merged 4 commits into from
May 14, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 3 additions & 55 deletions sdk/iot_deviceupdate/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ use const_format::formatcp;
use serde::de::DeserializeOwned;
use std::sync::Arc;

pub(crate) const API_VERSION: &str = "2021-06-01-preview";
pub(crate) const API_VERSION: &str = "2022-10-01";
pub(crate) const API_VERSION_PARAM: &str = formatcp!("api-version={}", API_VERSION);
pub(crate) const ENDPOINT: &str = "https://api.adu.microsoft.com/.default";
heaths marked this conversation as resolved.
Show resolved Hide resolved

/// Client for Device Update operations - import, list and delete updates
///
Expand All @@ -23,7 +24,6 @@ pub(crate) const API_VERSION_PARAM: &str = formatcp!("api-version={}", API_VERSI
#[derive(Clone)]
pub struct DeviceUpdateClient {
pub(crate) device_update_url: Url,
pub(crate) endpoint: String,
pub(crate) token_credential: Arc<dyn TokenCredential>,
}

Expand All @@ -45,19 +45,17 @@ impl DeviceUpdateClient {
.with_context(ErrorKind::DataConversion, || {
format!("failed to parse update url: {device_update_url}")
})?;
let endpoint = extract_endpoint(&device_update_url)?;

let client = DeviceUpdateClient {
device_update_url,
endpoint,
token_credential,
};
Ok(client)
}

async fn get_token(&self) -> azure_core::Result<AccessToken> {
self.token_credential
.get_token(&[&self.endpoint])
.get_token(&[ENDPOINT])
.await
.context(ErrorKind::Credential, "get token failed")
}
Expand Down Expand Up @@ -135,53 +133,3 @@ impl DeviceUpdateClient {
Ok(body)
}
}

/// Helper to get vault endpoint with a scheme and a trailing slash
/// ex. `https://vault.azure.net/` where the full client url is `https://myvault.vault.azure.net`
fn extract_endpoint(url: &Url) -> azure_core::Result<String> {
let endpoint = url
.host_str()
.ok_or_else(|| {
Error::with_message(ErrorKind::DataConversion, || {
format!("could not get device update domain. url: {url}")
})
})?
.split_once('.')
.ok_or_else(|| {
Error::with_message(ErrorKind::DataConversion, || {
format!("could not parse device update domain. url: {url}")
})
})?
.1;
Ok(format!("{}://{}", url.scheme(), endpoint))
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn can_extract_endpoint() -> azure_core::Result<()> {
let url = "https://myadu.api.adu.microsoft.com";
let suffix = extract_endpoint(&Url::parse(url)?)?;
assert_eq!(suffix, "https://api.adu.microsoft.com");

let suffix = extract_endpoint(&Url::parse("https://myadu.mycustom.api.adu.server.net")?)?;
assert_eq!(suffix, "https://mycustom.api.adu.server.net");

let suffix = extract_endpoint(&Url::parse("https://myadu.internal")?)?;
assert_eq!(suffix, "https://internal");

let suffix = extract_endpoint(&Url::parse("some-scheme://myadu.api.adu.microsoft.com")?)?;
assert_eq!(suffix, "some-scheme://api.adu.microsoft.com");
Ok(())
}

#[test]
fn can_not_extract_endpoint() -> azure_core::Result<()> {
let url = "https://shouldfail";
let suffix = extract_endpoint(&Url::parse(url)?);
assert_eq!(suffix.unwrap_err().kind(), &ErrorKind::DataConversion);
Ok(())
}
}
29 changes: 14 additions & 15 deletions sdk/iot_deviceupdate/src/device_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,17 +166,16 @@ pub struct UpdateList {

impl DeviceUpdateClient {
/// Import new update version.
/// `POST https://{endpoint}/deviceupdate/{instanceId}/updates?action=import&api-version=2021-06-01-preview`
/// `POST https://{endpoint}/deviceUpdate/{instanceId}/updates:import?api-version=2022-10-01`
pub async fn import_update(
&self,
instance_id: &str,
import_json: String,
) -> azure_core::Result<UpdateOperation> {
let mut uri = self.device_update_url.clone();
let path = format!("deviceupdate/{instance_id}/updates");
let path = format!("deviceupdate/{instance_id}/updates:import");
uri.set_path(&path);
uri.set_query(Some(API_VERSION_PARAM));
uri.query_pairs_mut().append_pair("action", "import");

debug!("Import request: {}", &uri);
let resp_body = self.post(uri.to_string(), Some(import_json)).await?;
Expand Down Expand Up @@ -215,7 +214,7 @@ impl DeviceUpdateClient {
}

/// Delete a specific update version.
/// `DELETE https://{endpoint}/deviceupdate/{instanceId}/updates/providers/{provider}/names/{name}/versions/{version}?api-version=2021-06-01-preview`
/// `DELETE https://{endpoint}/deviceUpdate/{instanceId}/updates/providers/{provider}/names/{name}/versions/{version}?api-version=2022-10-01`
pub async fn delete_update(
&self,
instance_id: &str,
Expand All @@ -232,7 +231,7 @@ impl DeviceUpdateClient {
}

/// Get a specific update file from the version.
/// `GET https://{endpoint}/deviceupdate/{instanceId}/updates/providers/{provider}/names/{name}/versions/{version}/files/{fileId}?api-version=2021-06-01-previe`
/// `GET https://{endpoint}/deviceUpdate/{instanceId}/updates/providers/{provider}/names/{name}/versions/{version}/files/{fileId}?api-version=2022-10-01`
pub async fn get_file(
&self,
instance_id: &str,
Expand All @@ -250,7 +249,7 @@ impl DeviceUpdateClient {
}

/// Retrieve operation status.
/// `GET https://{endpoint}/deviceupdate/{instanceId}/updates/operations/{operationId}?api-version=2021-06-01-preview`
/// `GET https://{endpoint}/deviceUpdate/{instanceId}/updates/operations/{operationId}?api-version=2022-10-01`
pub async fn get_operation(
&self,
instance_id: &str,
Expand All @@ -265,7 +264,7 @@ impl DeviceUpdateClient {
}

/// Get a specific update version.
/// `GET https://{endpoint}/deviceupdate/{instanceId}/updates/providers/{provider}/names/{name}/versions/{version}?api-version=2021-06-01-preview`
/// `GET https://{endpoint}/deviceUpdate/{instanceId}/updates/providers/{provider}/names/{name}/versions/{version}?api-version=2022-10-01`
pub async fn get_update(
&self,
instance_id: &str,
Expand All @@ -282,7 +281,7 @@ impl DeviceUpdateClient {
}

/// Get a list of all update file identifiers for the specified version.
/// `GET https://{endpoint}/deviceupdate/{instanceId}/updates/providers/{provider}/names/{name}/versions/{version}/files?api-version=2021-06-01-preview`
/// `GET https://{endpoint}/deviceUpdate/{instanceId}/updates/providers/{provider}/names/{name}/versions/{version}/files?api-version=2022-10-01`
pub async fn list_files(
&self,
instance_id: &str,
Expand Down Expand Up @@ -317,7 +316,7 @@ impl DeviceUpdateClient {
}

/// Get a list of all update names that match the specified provider.
/// `GET https://{endpoint}/deviceupdate/{instanceId}/updates/providers/{provider}/names?api-version=2021-06-01-preview`
/// `GET https://{endpoint}/deviceUpdate/{instanceId}/updates/providers/{provider}/names?api-version=2022-10-01`
pub async fn list_names(
&self,
instance_id: &str,
Expand Down Expand Up @@ -351,7 +350,7 @@ impl DeviceUpdateClient {

/// Get a list of all import update operations.
/// Completed operations are kept for 7 days before auto-deleted. Delete operations are not returned by this API version.
/// `GET https://{endpoint}/deviceupdate/{instanceId}/updates/operations?$filter={$filter}&$top={$top}&api-version=2021-06-01-preview`
/// `GET https://{endpoint}/deviceUpdate/{instanceId}/updates/operations?filter={filter}&top={top}&api-version=2022-10-01`
pub async fn list_operations(
&self,
instance_id: &str,
Expand Down Expand Up @@ -392,7 +391,7 @@ impl DeviceUpdateClient {
}

/// Get a list of all update providers that have been imported to Device Update for `IoT` Hub.
/// `GET https://{endpoint}/deviceupdate/{instanceId}/updates/providers?api-version=2021-06-01-preview`
/// `GET https://{endpoint}/deviceUpdate/{instanceId}/updates/providers?api-version=2022-10-01`
pub async fn list_providers(&self, instance_id: &str) -> azure_core::Result<Vec<String>> {
let mut uri = self.device_update_url.clone();
let path = format!("deviceupdate/{instance_id}/updates/providers");
Expand Down Expand Up @@ -421,7 +420,7 @@ impl DeviceUpdateClient {
}

/// Get a list of all updates that have been imported to Device Update for `IoT` Hub.
/// `GET https://{endpoint}/deviceupdate/{instanceId}/updates?api-version=2021-06-01-preview&$search={$search}&$filter={$filter}`
/// `GET https://{endpoint}/deviceUpdate/{instanceId}/updates?api-version=2022-10-01&search={search}&filter={filter}`
pub async fn list_updates(
&self,
instance_id: &str,
Expand Down Expand Up @@ -463,7 +462,7 @@ impl DeviceUpdateClient {
}

/// Get a list of all update versions that match the specified provider and name.
/// `GET https://{endpoint}/deviceupdate/{instanceId}/updates/providers/{provider}/names/{name}/versions?api-version=2021-06-01-preview&$filter={$filter}`
/// `GET https://{endpoint}/deviceUpdate/{instanceId}/updates/providers/{provider}/names/{name}/versions?api-version=2022-10-01&filter={filter}`
pub async fn list_versions(
&self,
instance_id: &str,
Expand Down Expand Up @@ -516,7 +515,7 @@ mod tests {
async fn can_import_update() -> azure_core::Result<()> {
let mut server = Server::new_async().await;
let _m = server
.mock("POST", "/deviceupdate/test-instance/updates")
.mock("POST", "/deviceupdate/test-instance/updates:import")
.match_query(Matcher::UrlEncoded(
"api-version".into(),
API_VERSION.into(),
Expand All @@ -533,7 +532,7 @@ mod tests {
"lastActionDateTime":"1999-09-10T03:05:07.3845533+01:00",
"etag": "\"some_tag\"",
"operationId": "some_op_id",
"resourceLocation": "/deviceupdate/instance/updates/providers/xxx/names/yyy/versions/x.y.z?api-version=2021-06-01-preview",
"resourceLocation": "/deviceupdate/instance/updates/providers/xxx/names/yyy/versions/x.y.z?api-version=2022-10-01",
"status": "Succeeded",
"traceId": "zzzzzzzzzzzzzzzz",
"updateId": {
Expand Down
1 change: 0 additions & 1 deletion sdk/iot_deviceupdate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ mod tests {
pub(crate) fn mock_client(server_url: String) -> crate::client::DeviceUpdateClient {
crate::client::DeviceUpdateClient {
device_update_url: Url::parse(&server_url).unwrap(),
endpoint: String::new(),
token_credential: Arc::new(MockCredential),
}
}
Expand Down