From 1c3ece0070a281cb96f44a08feab9590289d13b8 Mon Sep 17 00:00:00 2001 From: Wenjie Yu Date: Thu, 3 Jun 2021 09:41:41 +0800 Subject: [PATCH 1/4] Updating F# doc to the new SDKs. --- .../snippets/fsharp/azure/file-storage.fsx | 155 ++++++++++-------- 1 file changed, 83 insertions(+), 72 deletions(-) diff --git a/samples/snippets/fsharp/azure/file-storage.fsx b/samples/snippets/fsharp/azure/file-storage.fsx index 573a48bb9b0d0..68240e1927dff 100644 --- a/samples/snippets/fsharp/azure/file-storage.fsx +++ b/samples/snippets/fsharp/azure/file-storage.fsx @@ -1,8 +1,11 @@ open System open System.IO -open Microsoft.Azure // Namespace for CloudConfigurationManager -open Microsoft.Azure.Storage // Namespace for CloudStorageAccount -open Microsoft.Azure.Storage.File // Namespace for File storage types +open Azure.Storage.Files.Shares // Namespace for File storage types +open Azure +open Azure.Storage.Blobs +open Azure.Storage.Sas +open Azure.Storage +open Azure.Storage.Files.Shares.Models // // Get your connection string. @@ -14,127 +17,135 @@ let storageConnString = "..." // fill this in from your storage account let storageConnString = CloudConfigurationManager.GetSetting("StorageConnectionString") *) -// -// Parse the connection string. -// - -// Parse the connection string and return a reference to the storage account. -let storageAccount = CloudStorageAccount.Parse(storageConnString) +let shareName = "..." // fill this with the name of the share // // Create the File service client. // -let fileClient = storageAccount.CreateCloudFileClient() - -// -// Create a file share. -// - -let share = fileClient.GetShareReference("myfiles") -share.CreateIfNotExists() +let share = ShareClient(storageConnString, shareName) +share.CreateIfNotExistsAsync() // // Create a root directory and a subdirectory // -let rootDir = share.GetRootDirectoryReference() -let subDir = rootDir.GetDirectoryReference("myLogs") -subDir.CreateIfNotExists() +// Get a reference to the sample directory +let directory = share.GetDirectoryClient("directoryName") + +// Create the directory if it doesn't already exist +directory.CreateIfNotExistsAsync() // -// Upload a file to a subdirectory +// Upload a file to the sample directory // -let file = subDir.GetFileReference("log.txt") -file.UploadText("This is the content of the log file") +let file = directory.GetFileClient("fileName") +let stream = File.OpenRead("localFilePath") +file.Create(stream.Length) +file.UploadRange( + HttpRange(0L, stream.Length), + stream) // -// Download a file to a local fie +// Download a file to a local file // -file.DownloadToFile("log.txt", FileMode.Append) +let download = file.Download() +let downStream = File.OpenWrite("Save_Download_Path") +download.Value.Content.CopyTo(stream) // // Set the maximum size for a file share. // // stats.Usage is current usage in GB -let stats = share.GetStats() -share.FetchAttributes() +let ONE_GIBIBYTE = 10737420000L // Number of bytes in 1 gibibyte +let stats = share.GetStatistics().Value +let currentGiB = (int)(stats.ShareUsageInBytes / ONE_GIBIBYTE) // Set the quota to 10 GB plus current usage -share.Properties.Quota <- stats.Usage + 10 |> Nullable -share.SetProperties() +share.SetQuotaAsync(currentGiB + 10) // Remove the quota -share.Properties.Quota <- Nullable() -share.SetProperties() +share.SetQuotaAsync(0) // // Generate a shared access signature for a file or file share. // -// Create a 24-hour read/write policy. -let policy = - SharedAccessFilePolicy - (SharedAccessExpiryTime = (DateTimeOffset.UtcNow.AddHours(24.) |> Nullable), - Permissions = (SharedAccessFilePermissions.Read ||| SharedAccessFilePermissions.Write)) +let accountName = "..." // Input your storage account name +let accountKey = "..." // Input your storage account key +// Create a 24-hour read/write policy. +let expiration = DateTimeOffset.UtcNow.AddHours(24.) +let fileSAS = ShareSasBuilder( + ShareName = shareName, + FilePath = "filePath", + Resource = "f", + ExpiresOn = expiration) -// Set the policy on the share. -let permissions = share.GetPermissions() -permissions.SharedAccessPolicies.Add("policyName", policy) -share.SetPermissions(permissions) +// Set the permissions for the SAS +let permissions = ShareFileSasPermissions.All +fileSAS.SetPermissions(permissions) -let sasToken = file.GetSharedAccessSignature(policy) -let sasUri = Uri(file.StorageUri.PrimaryUri.ToString() + sasToken) +// Create a SharedKeyCredential that we can use to sign the SAS token +let credential = StorageSharedKeyCredential(accountName, accountKey) -let fileSas = CloudFile(sasUri) -fileSas.UploadText("This write operation is authenticated via SAS") +// Build a SAS URI +let fileSasUri = UriBuilder($"https://{accountName}.file.core.windows.net/{fileSAS.ShareName}/{fileSAS.FilePath}") +fileSasUri.Query = fileSAS.ToSasQueryParameters(credential).ToString() // // Copy a file to another file. // - -let destFile = subDir.GetFileReference("log_copy.txt") -destFile.StartCopy(file) +let sourceFile = ShareFileClient(storageConnString, shareName, "sourceFilePath") +let destFile = ShareFileClient(storageConnString, shareName, "destFilePath") +destFile.StartCopyAsync(sourceFile.Uri) // // Copy a file to a blob. // -// Get a reference to the blob to which the file will be copied. -let blobClient = storageAccount.CreateCloudBlobClient() -let container = blobClient.GetContainerReference("myContainer") -container.CreateIfNotExists() -let destBlob = container.GetBlockBlobReference("log_blob.txt") +// Create a new file SAS +let fileSAS2 = ShareSasBuilder( + ShareName = shareName, + FilePath = "sourceFilePath", + Resource = "f", + ExpiresOn = DateTimeOffset.UtcNow.AddHours(24.)) +let permissions2 = ShareFileSasPermissions.Read +fileSAS2.SetPermissions(permissions2) +let fileSasUri2 = UriBuilder($"https://{accountName}.file.core.windows.net/{fileSAS.ShareName}/{fileSAS.FilePath}") -let filePolicy = - SharedAccessFilePolicy - (Permissions = SharedAccessFilePermissions.Read, - SharedAccessExpiryTime = (DateTimeOffset.UtcNow.AddHours(24.) |> Nullable)) +// Get a reference to the file we created previously +let sourceFile2 = ShareFileClient(fileSasUri2.Uri) -let fileSas2 = file.GetSharedAccessSignature(filePolicy) -let sasUri2 = Uri(file.StorageUri.PrimaryUri.ToString() + fileSas2) -destBlob.StartCopy(sasUri2) +// Get a reference to the blob to which the file will be copied. +let container = BlobContainerClient(storageConnString, "containerName"); +container.CreateIfNotExists() +let destBlob = container.GetBlobClient("blobName") +destBlob.StartCopyFromUriAsync(sourceFile2.Uri) // // Troubleshooting File storage using metrics. // -open Microsoft.Azure.Storage.File.Protocol -open Microsoft.Azure.Storage.Shared.Protocol +// Instatiate a ShareServiceClient +let shareService = ShareServiceClient(storageConnString); + +// Set metrics properties for File service +let props = ShareServiceProperties() + +props.HourMetrics = ShareMetrics( + Enabled = true, + IncludeApis = true, + Version = "1.0", + RetentionPolicy = ShareRetentionPolicy(Enabled = true,Days = 14)) -let props = - FileServiceProperties( - (HourMetrics = MetricsProperties( - MetricsLevel = MetricsLevel.ServiceAndApi, - RetentionDays = (14 |> Nullable), - Version = "1.0"), - MinuteMetrics = MetricsProperties( - MetricsLevel = MetricsLevel.ServiceAndApi, - RetentionDays = (7 |> Nullable), - Version = "1.0")) +props.MinuteMetrics = ShareMetrics( + Enabled = true, + IncludeApis = true, + Version = "1.0", + RetentionPolicy = ShareRetentionPolicy(Enabled = true,Days = 7)) -fileClient.SetServiceProperties(props) +shareService.SetPropertiesAsync(props) From 6d69abd7c6e20362974f6f921d001af34fd65465 Mon Sep 17 00:00:00 2001 From: Wenjie Yu Date: Thu, 3 Jun 2021 17:17:24 +0800 Subject: [PATCH 2/4] Update F# docs with the new SDKs in file-storage --- .../using-fsharp-on-azure/file-storage.md | 52 ++++++++----------- .../snippets/fsharp/azure/file-storage.fsx | 40 +++++++------- 2 files changed, 44 insertions(+), 48 deletions(-) diff --git a/docs/fsharp/using-fsharp-on-azure/file-storage.md b/docs/fsharp/using-fsharp-on-azure/file-storage.md index 0fa4e8a70e5b5..ce701d46e7c9b 100644 --- a/docs/fsharp/using-fsharp-on-azure/file-storage.md +++ b/docs/fsharp/using-fsharp-on-azure/file-storage.md @@ -26,7 +26,7 @@ Next, use a [package manager](package-management.md) such as [Paket](https://fsp Add the following `open` statements to the top of the `files.fsx` file: -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L1-L5)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L1-L8)] ### Get your connection string @@ -34,29 +34,21 @@ You'll need an Azure Storage connection string for this tutorial. For more infor For the tutorial, you'll enter your connection string in your script, like this: -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L11-L11)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L14-L14)] However, this is **not recommended** for real projects. Your storage account key is similar to the root password for your storage account. Always be careful to protect your storage account key. Avoid distributing it to other users, hard-coding it, or saving it in a plain-text file that is accessible to others. You can regenerate your key using the Azure portal if you believe it may have been compromised. For real applications, the best way to maintain your storage connection string is in a configuration file. To fetch the connection string from a configuration file, you can do this: -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L13-L15)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L16-L18)] Using Azure Configuration Manager is optional. You can also use an API such as the .NET Framework's `ConfigurationManager` type. -### Parse the connection string - -To parse the connection string, use: - -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L21-L22)] - -This will return a `CloudStorageAccount`. - ### Create the File service client -The `CloudFileClient` type enables you to programmatically use files stored in File storage. Here's one way to create the service client: +The `ShareClient` type enables you to programmatically use files stored in File storage. Here's one way to create the service client: -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L28-L28)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L25-L25)] Now you are ready to write code that reads data from and writes data to File storage. @@ -64,39 +56,39 @@ Now you are ready to write code that reads data from and writes data to File sto This example shows how to create a file share if it does not already exist: -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L34-L35)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L31-L31)] -## Create a root directory and a subdirectory +## Create a directory -Here, you get the root directory and get a subdirectory of the root. You create both if they don't already exist. +Here, you get the directory. You create if it doesn't already exist. -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L41-L43)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L37-L41)] -## Upload text as a file +## Upload a file to the sample directory -This example shows how to upload text as a file. +This example shows how to upload a file to the sample directory. -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L49-L50)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L47-L52)] -### Download a file to a local copy of the file +### Download a file to a local file Here you download the file just created, appending the contents to a local file. -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L56-L56)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L58-L60)] ### Set the maximum size for a file share -The example below shows how to check the current usage for a share and how to set the quota for the share. `FetchAttributes` must be called to populate a share's `Properties`, and `SetProperties` to propagate local changes to Azure File Storage. +The example below shows how to check the current usage for a share and how to set the quota for the share. -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L62-L72)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L66-L75)] ### Generate a shared access signature for a file or file share -You can generate a shared access signature (SAS) for a file share or for an individual file. You can also create a shared access policy on a file share to manage shared access signatures. Creating a shared access policy is recommended, as it provides a means of revoking the SAS if it should be compromised. +You can generate a shared access signature (SAS) for a file share or for an individual file. You can also create a shared access policy on a file share to manage shared access signatures. Creating a shared access permissions is recommended, as it provides a means of revoking the SAS if it should be compromised. -Here, you create a shared access policy on a share, and then use that policy to provide the constraints for a SAS on a file in the share. +Here, you create a shared access permissions on a share, and then set that permissions to provide the constraints for a SAS on a file in the share. -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L78-L94)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L81-L101)] For more information about creating and using shared access signatures, see [Using Shared Access Signatures (SAS)](/azure/storage/storage-dotnet-shared-access-signature-part-1) and [Create and use a SAS with Blob storage](/azure/storage/storage-dotnet-shared-access-signature-part-2). @@ -108,13 +100,13 @@ You can copy a file to another file or to a blob, or a blob to a file. If you ar Here, you copy a file to another file in the same share. Because this copy operation copies between files in the same storage account, you can use Shared Key authentication to perform the copy. -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L100-L101)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L106-L108)] ### Copy a file to a blob Here, you create a file and copy it to a blob within the same storage account. You create a SAS for the source file, which the service uses to authenticate access to the source file during the copy operation. -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L107-L120)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L114-L131)] You can copy a blob to a file in the same way. If the source object is a blob, then create a SAS to authenticate access to that blob during the copy operation. @@ -124,7 +116,7 @@ Azure Storage Analytics supports metrics for File storage. With metrics data, yo You can enable metrics for File storage from the [Azure portal](https://portal.azure.com), or you can do it from F# like this: -[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L126-L140)] +[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L137-L155)] ## Next steps diff --git a/samples/snippets/fsharp/azure/file-storage.fsx b/samples/snippets/fsharp/azure/file-storage.fsx index 68240e1927dff..6838175015ff6 100644 --- a/samples/snippets/fsharp/azure/file-storage.fsx +++ b/samples/snippets/fsharp/azure/file-storage.fsx @@ -17,20 +17,24 @@ let storageConnString = "..." // fill this in from your storage account let storageConnString = CloudConfigurationManager.GetSetting("StorageConnectionString") *) -let shareName = "..." // fill this with the name of the share // // Create the File service client. // -let share = ShareClient(storageConnString, shareName) +let share = ShareClient(storageConnString, "shareName") + +// +// Create a file share. +// + share.CreateIfNotExistsAsync() // -// Create a root directory and a subdirectory +// Create a directory // -// Get a reference to the sample directory +// Get a reference to the directory let directory = share.GetDirectoryClient("directoryName") // Create the directory if it doesn't already exist @@ -80,7 +84,7 @@ let accountKey = "..." // Input your storage account key // Create a 24-hour read/write policy. let expiration = DateTimeOffset.UtcNow.AddHours(24.) let fileSAS = ShareSasBuilder( - ShareName = shareName, + ShareName = "shareName", FilePath = "filePath", Resource = "f", ExpiresOn = expiration) @@ -99,8 +103,8 @@ fileSasUri.Query = fileSAS.ToSasQueryParameters(credential).ToString() // // Copy a file to another file. // -let sourceFile = ShareFileClient(storageConnString, shareName, "sourceFilePath") -let destFile = ShareFileClient(storageConnString, shareName, "destFilePath") +let sourceFile = ShareFileClient(storageConnString, "shareName", "sourceFilePath") +let destFile = ShareFileClient(storageConnString, "shareName", "destFilePath") destFile.StartCopyAsync(sourceFile.Uri) // @@ -108,23 +112,23 @@ destFile.StartCopyAsync(sourceFile.Uri) // // Create a new file SAS -let fileSAS2 = ShareSasBuilder( - ShareName = shareName, +let fileSASCopyToBlob = ShareSasBuilder( + ShareName = "shareName", FilePath = "sourceFilePath", Resource = "f", ExpiresOn = DateTimeOffset.UtcNow.AddHours(24.)) -let permissions2 = ShareFileSasPermissions.Read -fileSAS2.SetPermissions(permissions2) -let fileSasUri2 = UriBuilder($"https://{accountName}.file.core.windows.net/{fileSAS.ShareName}/{fileSAS.FilePath}") +let permissionsCopyToBlob = ShareFileSasPermissions.Read +fileSASCopyToBlob.SetPermissions(permissionsCopyToBlob) +let fileSasUriCopyToBlob = UriBuilder($"https://{accountName}.file.core.windows.net/{fileSASCopyToBlob.ShareName}/{fileSASCopyToBlob.FilePath}") -// Get a reference to the file we created previously -let sourceFile2 = ShareFileClient(fileSasUri2.Uri) +// Get a reference to the file. +let sourceFileCopyToBlob = ShareFileClient(fileSasUriCopyToBlob.Uri) // Get a reference to the blob to which the file will be copied. -let container = BlobContainerClient(storageConnString, "containerName"); -container.CreateIfNotExists() -let destBlob = container.GetBlobClient("blobName") -destBlob.StartCopyFromUriAsync(sourceFile2.Uri) +let containerCopyToBlob = BlobContainerClient(storageConnString, "containerName"); +containerCopyToBlob.CreateIfNotExists() +let destBlob = containerCopyToBlob.GetBlobClient("blobName") +destBlob.StartCopyFromUriAsync(sourceFileCopyToBlob.Uri) // // Troubleshooting File storage using metrics. From 475c39a9315ee8bbd458a034a9f127f531fd4932 Mon Sep 17 00:00:00 2001 From: Wenjie Yu Date: Fri, 4 Jun 2021 09:26:05 +0800 Subject: [PATCH 3/4] Sort the namespace --- samples/snippets/fsharp/azure/file-storage.fsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/samples/snippets/fsharp/azure/file-storage.fsx b/samples/snippets/fsharp/azure/file-storage.fsx index 6838175015ff6..1f4469ecf3838 100644 --- a/samples/snippets/fsharp/azure/file-storage.fsx +++ b/samples/snippets/fsharp/azure/file-storage.fsx @@ -1,11 +1,11 @@ open System open System.IO -open Azure.Storage.Files.Shares // Namespace for File storage types open Azure -open Azure.Storage.Blobs -open Azure.Storage.Sas -open Azure.Storage -open Azure.Storage.Files.Shares.Models +open Azure.Storage // Namespace for StorageSharedKeyCredential +open Azure.Storage.Blobs // Namespace for BlobContainerClient +open Azure.Storage.Sas // Namespace for ShareSasBuilder +open Azure.Storage.Files.Shares // Namespace for File storage types +open Azure.Storage.Files.Shares.Models // Namespace for ShareServiceProperties // // Get your connection string. From b2a1815f52f0fe491ca64e4be46b2a8bceca620b Mon Sep 17 00:00:00 2001 From: Wenjie Yu Date: Mon, 7 Jun 2021 17:03:45 +0800 Subject: [PATCH 4/4] some code changes --- samples/snippets/fsharp/azure/file-storage.fsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/samples/snippets/fsharp/azure/file-storage.fsx b/samples/snippets/fsharp/azure/file-storage.fsx index 1f4469ecf3838..3b55ae428483a 100644 --- a/samples/snippets/fsharp/azure/file-storage.fsx +++ b/samples/snippets/fsharp/azure/file-storage.fsx @@ -64,9 +64,9 @@ download.Value.Content.CopyTo(stream) // // stats.Usage is current usage in GB -let ONE_GIBIBYTE = 10737420000L // Number of bytes in 1 gibibyte +let ONE_GIBIBYTE = 10_737_420_000L // Number of bytes in 1 gibibyte let stats = share.GetStatistics().Value -let currentGiB = (int)(stats.ShareUsageInBytes / ONE_GIBIBYTE) +let currentGiB = int (stats.ShareUsageInBytes / ONE_GIBIBYTE) // Set the quota to 10 GB plus current usage share.SetQuotaAsync(currentGiB + 10)