Skip to content

Commit 8025e4c

Browse files
authored
Update F# on Azure Docs - File Storage (#24508)
* Updating F# doc to the new SDKs. * Update F# docs with the new SDKs in file-storage * Sort the namespace * some code changes Co-authored-by: Wenjie Yu <v-wenjyu@microsoft.com>
1 parent 78582cb commit 8025e4c

File tree

2 files changed

+105
-98
lines changed

2 files changed

+105
-98
lines changed

docs/fsharp/using-fsharp-on-azure/file-storage.md

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,77 +26,69 @@ Next, use a [package manager](package-management.md) such as [Paket](https://fsp
2626

2727
Add the following `open` statements to the top of the `files.fsx` file:
2828

29-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L1-L5)]
29+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L1-L8)]
3030

3131
### Get your connection string
3232

3333
You'll need an Azure Storage connection string for this tutorial. For more information about connection strings, see [Configure Storage Connection Strings](/azure/storage/storage-configure-connection-string).
3434

3535
For the tutorial, you'll enter your connection string in your script, like this:
3636

37-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L11-L11)]
37+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L14-L14)]
3838

3939
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.
4040

4141
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:
4242

43-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L13-L15)]
43+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L16-L18)]
4444

4545
Using Azure Configuration Manager is optional. You can also use an API such as the .NET Framework's `ConfigurationManager` type.
4646

47-
### Parse the connection string
48-
49-
To parse the connection string, use:
50-
51-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L21-L22)]
52-
53-
This will return a `CloudStorageAccount`.
54-
5547
### Create the File service client
5648

57-
The `CloudFileClient` type enables you to programmatically use files stored in File storage. Here's one way to create the service client:
49+
The `ShareClient` type enables you to programmatically use files stored in File storage. Here's one way to create the service client:
5850

59-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L28-L28)]
51+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L25-L25)]
6052

6153
Now you are ready to write code that reads data from and writes data to File storage.
6254

6355
## Create a file share
6456

6557
This example shows how to create a file share if it does not already exist:
6658

67-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L34-L35)]
59+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L31-L31)]
6860

69-
## Create a root directory and a subdirectory
61+
## Create a directory
7062

71-
Here, you get the root directory and get a subdirectory of the root. You create both if they don't already exist.
63+
Here, you get the directory. You create if it doesn't already exist.
7264

73-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L41-L43)]
65+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L37-L41)]
7466

75-
## Upload text as a file
67+
## Upload a file to the sample directory
7668

77-
This example shows how to upload text as a file.
69+
This example shows how to upload a file to the sample directory.
7870

79-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L49-L50)]
71+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L47-L52)]
8072

81-
### Download a file to a local copy of the file
73+
### Download a file to a local file
8274

8375
Here you download the file just created, appending the contents to a local file.
8476

85-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L56-L56)]
77+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L58-L60)]
8678

8779
### Set the maximum size for a file share
8880

89-
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.
81+
The example below shows how to check the current usage for a share and how to set the quota for the share.
9082

91-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L62-L72)]
83+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L66-L75)]
9284

9385
### Generate a shared access signature for a file or file share
9486

95-
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.
87+
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.
9688

97-
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.
89+
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.
9890

99-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L78-L94)]
91+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L81-L101)]
10092

10193
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).
10294

@@ -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
108100

109101
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.
110102

111-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L100-L101)]
103+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L106-L108)]
112104

113105
### Copy a file to a blob
114106

115107
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.
116108

117-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L107-L120)]
109+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L114-L131)]
118110

119111
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.
120112

@@ -124,7 +116,7 @@ Azure Storage Analytics supports metrics for File storage. With metrics data, yo
124116

125117
You can enable metrics for File storage from the [Azure portal](https://portal.azure.com), or you can do it from F# like this:
126118

127-
[!code-fsharp[FileStorage](~/samples/snippets/fsharp/azure/file-storage.fsx#L126-L140)]
119+
[!code-fsharp[FileStorage](../../../samples/snippets/fsharp/azure/file-storage.fsx#L137-L155)]
128120

129121
## Next steps
130122

Lines changed: 83 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
open System
22
open System.IO
3-
open Microsoft.Azure // Namespace for CloudConfigurationManager
4-
open Microsoft.Azure.Storage // Namespace for CloudStorageAccount
5-
open Microsoft.Azure.Storage.File // Namespace for File storage types
3+
open Azure
4+
open Azure.Storage // Namespace for StorageSharedKeyCredential
5+
open Azure.Storage.Blobs // Namespace for BlobContainerClient
6+
open Azure.Storage.Sas // Namespace for ShareSasBuilder
7+
open Azure.Storage.Files.Shares // Namespace for File storage types
8+
open Azure.Storage.Files.Shares.Models // Namespace for ShareServiceProperties
69

710
//
811
// Get your connection string.
@@ -14,127 +17,139 @@ let storageConnString = "..." // fill this in from your storage account
1417
let storageConnString =
1518
CloudConfigurationManager.GetSetting("StorageConnectionString")
1619
*)
17-
//
18-
// Parse the connection string.
19-
//
20-
21-
// Parse the connection string and return a reference to the storage account.
22-
let storageAccount = CloudStorageAccount.Parse(storageConnString)
2320

2421
//
2522
// Create the File service client.
2623
//
2724

28-
let fileClient = storageAccount.CreateCloudFileClient()
25+
let share = ShareClient(storageConnString, "shareName")
2926

3027
//
3128
// Create a file share.
3229
//
3330

34-
let share = fileClient.GetShareReference("myfiles")
35-
share.CreateIfNotExists()
31+
share.CreateIfNotExistsAsync()
3632

3733
//
38-
// Create a root directory and a subdirectory
34+
// Create a directory
3935
//
4036

41-
let rootDir = share.GetRootDirectoryReference()
42-
let subDir = rootDir.GetDirectoryReference("myLogs")
43-
subDir.CreateIfNotExists()
37+
// Get a reference to the directory
38+
let directory = share.GetDirectoryClient("directoryName")
39+
40+
// Create the directory if it doesn't already exist
41+
directory.CreateIfNotExistsAsync()
4442

4543
//
46-
// Upload a file to a subdirectory
44+
// Upload a file to the sample directory
4745
//
4846

49-
let file = subDir.GetFileReference("log.txt")
50-
file.UploadText("This is the content of the log file")
47+
let file = directory.GetFileClient("fileName")
48+
let stream = File.OpenRead("localFilePath")
49+
file.Create(stream.Length)
50+
file.UploadRange(
51+
HttpRange(0L, stream.Length),
52+
stream)
5153

5254
//
53-
// Download a file to a local fie
55+
// Download a file to a local file
5456
//
5557

56-
file.DownloadToFile("log.txt", FileMode.Append)
58+
let download = file.Download()
59+
let downStream = File.OpenWrite("Save_Download_Path")
60+
download.Value.Content.CopyTo(stream)
5761

5862
//
5963
// Set the maximum size for a file share.
6064
//
6165

6266
// stats.Usage is current usage in GB
63-
let stats = share.GetStats()
64-
share.FetchAttributes()
67+
let ONE_GIBIBYTE = 10_737_420_000L // Number of bytes in 1 gibibyte
68+
let stats = share.GetStatistics().Value
69+
let currentGiB = int (stats.ShareUsageInBytes / ONE_GIBIBYTE)
6570

6671
// Set the quota to 10 GB plus current usage
67-
share.Properties.Quota <- stats.Usage + 10 |> Nullable
68-
share.SetProperties()
72+
share.SetQuotaAsync(currentGiB + 10)
6973

7074
// Remove the quota
71-
share.Properties.Quota <- Nullable()
72-
share.SetProperties()
75+
share.SetQuotaAsync(0)
7376

7477
//
7578
// Generate a shared access signature for a file or file share.
7679
//
7780

78-
// Create a 24-hour read/write policy.
79-
let policy =
80-
SharedAccessFilePolicy
81-
(SharedAccessExpiryTime = (DateTimeOffset.UtcNow.AddHours(24.) |> Nullable),
82-
Permissions = (SharedAccessFilePermissions.Read ||| SharedAccessFilePermissions.Write))
81+
let accountName = "..." // Input your storage account name
82+
let accountKey = "..." // Input your storage account key
8383

84+
// Create a 24-hour read/write policy.
85+
let expiration = DateTimeOffset.UtcNow.AddHours(24.)
86+
let fileSAS = ShareSasBuilder(
87+
ShareName = "shareName",
88+
FilePath = "filePath",
89+
Resource = "f",
90+
ExpiresOn = expiration)
8491

85-
// Set the policy on the share.
86-
let permissions = share.GetPermissions()
87-
permissions.SharedAccessPolicies.Add("policyName", policy)
88-
share.SetPermissions(permissions)
92+
// Set the permissions for the SAS
93+
let permissions = ShareFileSasPermissions.All
94+
fileSAS.SetPermissions(permissions)
8995

90-
let sasToken = file.GetSharedAccessSignature(policy)
91-
let sasUri = Uri(file.StorageUri.PrimaryUri.ToString() + sasToken)
96+
// Create a SharedKeyCredential that we can use to sign the SAS token
97+
let credential = StorageSharedKeyCredential(accountName, accountKey)
9298

93-
let fileSas = CloudFile(sasUri)
94-
fileSas.UploadText("This write operation is authenticated via SAS")
99+
// Build a SAS URI
100+
let fileSasUri = UriBuilder($"https://{accountName}.file.core.windows.net/{fileSAS.ShareName}/{fileSAS.FilePath}")
101+
fileSasUri.Query = fileSAS.ToSasQueryParameters(credential).ToString()
95102

96103
//
97104
// Copy a file to another file.
98105
//
99-
100-
let destFile = subDir.GetFileReference("log_copy.txt")
101-
destFile.StartCopy(file)
106+
let sourceFile = ShareFileClient(storageConnString, "shareName", "sourceFilePath")
107+
let destFile = ShareFileClient(storageConnString, "shareName", "destFilePath")
108+
destFile.StartCopyAsync(sourceFile.Uri)
102109

103110
//
104111
// Copy a file to a blob.
105112
//
106113

107-
// Get a reference to the blob to which the file will be copied.
108-
let blobClient = storageAccount.CreateCloudBlobClient()
109-
let container = blobClient.GetContainerReference("myContainer")
110-
container.CreateIfNotExists()
111-
let destBlob = container.GetBlockBlobReference("log_blob.txt")
114+
// Create a new file SAS
115+
let fileSASCopyToBlob = ShareSasBuilder(
116+
ShareName = "shareName",
117+
FilePath = "sourceFilePath",
118+
Resource = "f",
119+
ExpiresOn = DateTimeOffset.UtcNow.AddHours(24.))
120+
let permissionsCopyToBlob = ShareFileSasPermissions.Read
121+
fileSASCopyToBlob.SetPermissions(permissionsCopyToBlob)
122+
let fileSasUriCopyToBlob = UriBuilder($"https://{accountName}.file.core.windows.net/{fileSASCopyToBlob.ShareName}/{fileSASCopyToBlob.FilePath}")
112123

113-
let filePolicy =
114-
SharedAccessFilePolicy
115-
(Permissions = SharedAccessFilePermissions.Read,
116-
SharedAccessExpiryTime = (DateTimeOffset.UtcNow.AddHours(24.) |> Nullable))
124+
// Get a reference to the file.
125+
let sourceFileCopyToBlob = ShareFileClient(fileSasUriCopyToBlob.Uri)
117126

118-
let fileSas2 = file.GetSharedAccessSignature(filePolicy)
119-
let sasUri2 = Uri(file.StorageUri.PrimaryUri.ToString() + fileSas2)
120-
destBlob.StartCopy(sasUri2)
127+
// Get a reference to the blob to which the file will be copied.
128+
let containerCopyToBlob = BlobContainerClient(storageConnString, "containerName");
129+
containerCopyToBlob.CreateIfNotExists()
130+
let destBlob = containerCopyToBlob.GetBlobClient("blobName")
131+
destBlob.StartCopyFromUriAsync(sourceFileCopyToBlob.Uri)
121132

122133
//
123134
// Troubleshooting File storage using metrics.
124135
//
125136

126-
open Microsoft.Azure.Storage.File.Protocol
127-
open Microsoft.Azure.Storage.Shared.Protocol
137+
// Instatiate a ShareServiceClient
138+
let shareService = ShareServiceClient(storageConnString);
139+
140+
// Set metrics properties for File service
141+
let props = ShareServiceProperties()
142+
143+
props.HourMetrics = ShareMetrics(
144+
Enabled = true,
145+
IncludeApis = true,
146+
Version = "1.0",
147+
RetentionPolicy = ShareRetentionPolicy(Enabled = true,Days = 14))
128148

129-
let props =
130-
FileServiceProperties(
131-
(HourMetrics = MetricsProperties(
132-
MetricsLevel = MetricsLevel.ServiceAndApi,
133-
RetentionDays = (14 |> Nullable),
134-
Version = "1.0"),
135-
MinuteMetrics = MetricsProperties(
136-
MetricsLevel = MetricsLevel.ServiceAndApi,
137-
RetentionDays = (7 |> Nullable),
138-
Version = "1.0"))
149+
props.MinuteMetrics = ShareMetrics(
150+
Enabled = true,
151+
IncludeApis = true,
152+
Version = "1.0",
153+
RetentionPolicy = ShareRetentionPolicy(Enabled = true,Days = 7))
139154

140-
fileClient.SetServiceProperties(props)
155+
shareService.SetPropertiesAsync(props)

0 commit comments

Comments
 (0)