Skip to content

Conversation

sylvanc
Copy link
Contributor

@sylvanc sylvanc commented Sep 26, 2016

F# Azure storage docs

Summary

Add documentation and examples for using Blob, Queue, Table and File storage with F#.

Details

Existing Azure .NET documentation and examples are C# focused. This provides an F# programmer's view of Azure storage.

Suggested Reviewers

@dsyme @cartermp

@dnfclas
Copy link

dnfclas commented Sep 26, 2016

Hi @sylvanc, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!

The agreement was validated by .NET Foundation and real humans are currently evaluating your PR.

TTYL, DNFBOT;

@qinezh
Copy link
Contributor

qinezh commented Sep 26, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: Succeeded.
Open Publishing Report.

@qinezh
Copy link
Contributor

qinezh commented Sep 26, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: Succeeded.
Open Publishing Report.

@qinezh
Copy link
Contributor

qinezh commented Sep 29, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: SucceededWithWarning. Message: Warning occurred: Unable to resolve cross-reference "SafeNCryptKeyHandle", "SafeNCryptProviderHandle", "SafeNCryptSecretHandle"..
Open Publishing Report.

@dsyme
Copy link
Contributor

dsyme commented Sep 30, 2016

@mairaw @cartermp @sylvanc I think this PR is now ready for final review! Please let us know if there's anything more to do.

@qinezh
Copy link
Contributor

qinezh commented Sep 30, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: SucceededWithWarning. Message: Warning occurred: Unable to resolve cross-reference "SafeNCryptKeyHandle", "SafeNCryptProviderHandle", "SafeNCryptSecretHandle"..
Open Publishing Report.

@qinezh
Copy link
Contributor

qinezh commented Sep 30, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: SucceededWithWarning. Message: Warning occurred: Invalid file link:(~/docs/fsharp/using-fsharp-on-azure/Azure Quickstart Templates). Referenced by file: docs/fsharp/using-fsharp-on-azure/index.md at line: 101...
Open Publishing Report.

@dsyme
Copy link
Contributor

dsyme commented Oct 3, 2016

@mairaw @cartermp @sylvanc I think this PR is now ready for final review! Please let us know if there's anything more to do.

@cartermp
Copy link
Contributor

cartermp commented Oct 3, 2016

@dsyme @sylvanc I took at a look at it and I think that the titles are a bit long. I propose renaming them to the following:

  • Azure Blob Storage with F#
  • Azure File Storage with F#
  • Azure Table Storage with F#
  • Azure Queue Storage with F#

And for the sake of longevity, I've also been wondering if it's worthwhile to place them under a sub-TOC for Azure Storage. Example:

Using F# on Azure

Azure Storage

Blob Storage

File Storage

Table Storage

Queue Storage

When more documentation lands under the "Using F# on Azure" sub-TOC, then the lack of organization could make it difficult to find what you need. However, doing the above also might hurt discoverability.

Thoughts?


To upload a file to a block blob, get a container reference and use it to get a block blob reference. Once you have a blob reference, you can upload any stream of data to it by calling the `UploadFromStream` method. This operation will create the blob if it didn't previously exist, or overwrite it if it does exist.

[!code-fsharp[BlobStorage](../../../samples/snippets/fsharp/azure/blob-storage.fsx#L55-L61)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use UploadFromFile instead of UploadFromStream here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, will change this


[!code-fsharp[BlobStorage](../../../samples/snippets/fsharp/azure/blob-storage.fsx#L67-L80)]

As shown above, you can name blobs with path information in their names. This creates a virtual directory structure that you can organize and traverse as you would a traditional file system. Note that the directory structure is virtual only - the only resources available in Blob storage are containers and blobs. However, the storage client library offers a `CloudBlobDirectory` object to refer to a virtual directory and simplify the process of working with blobs that are organized in this way.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As shown above, you can name blobs with path information in their names.

Where was this shown? All I can see is creating a blob with the name myblob.txt, which has no path information.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

adjusting the text, thanks

2016/architecture/photo5.jpg
2016/architecture/photo6.jpg
2016/architecture/description.txt
2016/photo7.jpg
Copy link
Contributor

@svick svick Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code block, and also others below, is syntax highlighted for F# in docfx, but shouldn't. If it's the same with the docs.MS template, this should be changed by using ```none instead of indentation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will also be an issue for Loc later because they'll try to localize this text. All code should be fenced in our docs.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mairaw For now I'm adjusting to use

```none

Let me know if that's not enough (or make the adjustment after integration), thanks


This example shows a flat blob listing, but you can also perform a hierarchical listing, by setting the `useFlatBlobListing` parameter of the `ListBlobsSegmentedAsync` method to `false`.

Because the sample method calls an asynchronous method, it must be prefaced with the `async` keyword, and it must return a `Task` object. The await keyword specified for the `ListBlobsSegmentedAsync` method suspends execution of the sample method until the listing task completes.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like it's copy-pasted from the C# version of this document, but it does not apply to F#, since there is no await keyword and the function does not return a Task (and the return type is not specified anyway).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch :)

// This overload allows control of the page size. You can return
// all remaining results by passing null for the maxResults
// parameter, or by calling a different overload.
let! ct = Async.CancellationToken
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line should probably be moved before the comment, so that it's clear what code the comment talks about.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, thanks


> mono nuget.exe update

# Referencing Assemblies
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think level 1 headings should be used only for the main heading of an article, not for headings inside articles.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be fixed. @svick is right.


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

[!code-fsharp[QueueStorage](../../../samples/snippets/fsharp/azure/queue-storage.fsx#L9-L13)]
Copy link
Contributor

@svick svick Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this snippet shouldn't show the commented out CloudConfigurationManager.GetSetting code, it's already shown in the next snippet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, agreed


[!code-fsharp[QueueStorage](../../../samples/snippets/fsharp/azure/queue-storage.fsx#L75-L76)]

## Use Async-Await pattern with common Queue storage APIs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it's called "Async-Await pattern" in F#.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks


To update an entity, retrieve it from the Table service, modify the entity object, and then save the changes back to the Table service using a `Replace` operation. This causes the entity to be fully replaced on the server, unless the entity on the server has changed since it was retrieved, in which case the operation will fail. This failure is to prevent your application from inadvertently overwriting changes from other sources.

[!code-fsharp[TableStorage](../../../samples/snippets/fsharp/azure/table-storage.fsx#L120-L127)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This snippet and the one below seem to be one line off: they start with an empty line and end with with e ->.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed


A table query can retrieve just a few properties from an entity instead of all of them. This technique, called projection, can improve query performance, especially for large entities. Here, you return only email addresses using `DynamicTableEntity` and `EntityResolver`. Note that projection is not supported on the local storage emulator, so this code runs only when you're using an account on the Table service.

[!code-fsharp[TableStorage](../../../samples/snippets/fsharp/azure/table-storage.fsx#L145-L156)]
Copy link
Contributor

@svick svick Oct 3, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This snippet is one line off too, it's missing the resolvedResults line.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, fixed

Copy link
Contributor

@mairaw mairaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more comments


[!code-fsharp[BlobStorage](../../../samples/snippets/fsharp/azure/blob-storage.fsx#L21-L22)]

This will return a `CloudStorageAccount`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Something to keep in mind when writing articles in the future: present tense is preferred (no pun intended 😄). Like in this line where you could say "This returns..." or in the prerequisites section that says "you'll need an Azure Storage connection" instead of "You need ..."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks!


## Upload a blob into a container

Azure Blob Storage supports block blobs and page blobs. In the majority of cases, a block blob is the recommended type to use.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the majority of -> most

2016/architecture/photo5.jpg
2016/architecture/photo6.jpg
2016/architecture/description.txt
2016/photo7.jpg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will also be an issue for Loc later because they'll try to localize this text. All code should be fenced in our docs.


[!code-fsharp[BlobStorage](../../../samples/snippets/fsharp/azure/blob-storage.fsx#L82-L89)]

and, depending on the current contents of your container, the results look like this:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Capital A in and

Should also say "the results look similar to this" since it depends on the contents of the container?

do! loop null 1
}

// Create some dummy data by upoading the same file over andd over again
Copy link
Contributor

@mairaw mairaw Oct 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typos: andd and upoading

manager: jbronsk
ms.date: 09/20/2016
ms.topic: article
ms.prod: .net-core
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Historically, F# has used the following values for these two fields, so it would be good to be consistent:
ms.prod: visual-studio-dev14
ms.technology: devlang-fsharp

We need to discuss how we want to do the rollup reports of languages in the future and discuss with the BI team to add new keywords.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, done

// Generate a shared access signature for a file or file share.
//

// Create a 24 hour read/write policy.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

24 hour -> 24-hour


### Copy files

You can copy a file to another file, a file to a blob, or a blob to a file. If you are copying a blob to a file, or a file to a blob, you *must* use a shared access signature (SAS) to authenticate the source object, even if you are copying within the same storage account.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested rewriting:
You can copy a file to another file, a file to a blob, or a blob to a file ->
You can copy a file to another file or to a blob, or a blob to a file.


## Retrieve a single entity

You can write a query to retrieve a single, specific entity. Here, you use a `TableOperation` to specify the customer "Larry Buster". Instead of a collection, you get back a `Customer`. Specifying both the partition key and the row key in a query is the fastest way to retrieve a single entity from the Table service.
Copy link
Contributor

@mairaw mairaw Oct 6, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this name "Larry Buster" come from our approved fictitious names list from CELA?

member val PhoneNumber = phone with get, set

let customer =
Customer("Larry", "Boomer", "larry@example.com", "425-555-0101")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous question re. names, does this name come from our pre-approved list?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'm adjusting to use the same names as in the samples here https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-tables/ (not sure why we changed them)

@dsyme
Copy link
Contributor

dsyme commented Oct 7, 2016

@sylvanc @mairaw @badersur @qinezh I've updated the PR addressing all the above feedback, thanks!

@qinezh
Copy link
Contributor

qinezh commented Oct 7, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: SucceededWithWarning. Message: Warning occurred: Invalid file link:(~/docs/fsharp/using-fsharp-on-azure/Azure Quickstart Templates). Referenced by file: docs/fsharp/using-fsharp-on-azure/index.md at line: 100...
Open Publishing Report.

@cartermp cartermp closed this Oct 11, 2016
@cartermp cartermp reopened this Oct 11, 2016
@dnfclas
Copy link

dnfclas commented Oct 11, 2016

Hi @sylvanc, I'm your friendly neighborhood .NET Foundation Pull Request Bot (You can call me DNFBOT). Thanks for your contribution!
You've already signed the contribution license agreement. Thanks!

The agreement was validated by .NET Foundation and real humans are currently evaluating your PR.

TTYL, DNFBOT;

@cartermp
Copy link
Contributor

Closed->reopened because there seemed to be an error with the build (which I don't think is related to your last commit, @dsyme).

@mairaw
Copy link
Contributor

mairaw commented Oct 11, 2016

It seems all builds are broken somehow. I'll open a LSI.

@qinezh
Copy link
Contributor

qinezh commented Oct 11, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: SucceededWithWarning. Message: Warning occurred: Invalid file link:(~/docs/fsharp/using-fsharp-on-azure/Azure Quickstart Templates). Referenced by file: docs/fsharp/using-fsharp-on-azure/index.md at line: 100...
Open Publishing Report.

@qinezh
Copy link
Contributor

qinezh commented Oct 11, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: Succeeded.
Open Publishing Report.

@cartermp
Copy link
Contributor

cartermp commented Oct 11, 2016

I think this looks good. Any objections to merging?

@mairaw
Copy link
Contributor

mairaw commented Oct 11, 2016

There's one bad heading that needs to be fixed before merging this one.

@qinezh
Copy link
Contributor

qinezh commented Oct 11, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: Succeeded.
Open Publishing Report.

@qinezh
Copy link
Contributor

qinezh commented Oct 12, 2016

Open Publishing Build Service: The pull request content has been published and here are some changed files links of this time:

Status: Succeeded.
Open Publishing Report.

@cartermp cartermp merged commit d1d0aa5 into dotnet:master Oct 12, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants