Skip to content

Commit 81b75e6

Browse files
committed
Merging changes synced from https://github.com/MicrosoftDocs/azure-docs-pr (branch live)
2 parents 2f53fa9 + 8b44498 commit 81b75e6

File tree

111 files changed

+1584
-663
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

111 files changed

+1584
-663
lines changed

articles/active-directory/develop/v2-oauth-ropc.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ ms.workload: identity
1313
ms.tgt_pltfrm: na
1414
ms.devlang: na
1515
ms.topic: conceptual
16-
ms.date: 08/30/2019
16+
ms.date: 10/11/2019
1717
ms.author: ryanwi
1818
ms.reviewer: hirsin
1919
ms.custom: aaddev
@@ -30,6 +30,7 @@ Microsoft identity platform supports the [resource owner password credential (RO
3030
> * Personal accounts that are invited to an Azure AD tenant can't use ROPC.
3131
> * Accounts that don't have passwords can't sign in through ROPC. For this scenario, we recommend that you use a different flow for your app instead.
3232
> * If users need to use multi-factor authentication (MFA) to log in to the application, they will be blocked instead.
33+
> * ROPC is not supported in [hybrid identity federation](/azure/active-directory/hybrid/whatis-fed) scenarios (for example, Azure AD and ADFS used to authenticate on-premise accounts). If users are full-page redirected to an on-premises identity providers, Azure AD is not able to test the username and password against that identity provider. [Pass-through authentication](/azure/active-directory/hybrid/how-to-connect-pta) is supported with ROPC, however.
3334
3435
## Protocol diagram
3536

articles/automation/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@
123123
href: automation-scenario-source-control-integration-with-VSTS.md
124124
- name: Troubleshoot
125125
items:
126+
- name: Data to collect when you open a case for Microsoft Azure Automation
127+
href: troubleshoot/collect-data-microsoft-azure-automation-case.md
126128
- name: Troubleshoot Hybrid Runbook Worker
127129
href: troubleshoot/hybrid-runbook-worker.md
128130
displayName: troubleshoot, HRW, hybrid worker

articles/azure-app-configuration/TOC.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@
101101
href: https://go.microsoft.com/fwlink/?linkid=2091601
102102
- name: Resources
103103
items:
104+
- name: Pricing
105+
href: https://azure.microsoft.com/en-us/pricing/details/app-configuration/
104106
- name: Videos
105107
items:
106108
- name: Getting started

articles/azure-functions/durable/TOC.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@
9393
href: durable-functions-unit-testing.md
9494
- name: Create as WebJobs
9595
href: durable-functions-webjobs-sdk.md
96+
- name: Durable entities in .NET
97+
href: durable-functions-dotnet-entities.md
9698
- name: Deploy
9799
items:
98100
- name: Continuous deployment
@@ -101,6 +103,8 @@
101103
href: ../deployment-zip-push.md?toc=%2fazure%2fazure-functions%2fdurable%2ftoc.json
102104
- name: Run from package
103105
href: ../run-functions-from-deployment-package.md?toc=%2fazure%2fazure-functions%2fdurable%2ftoc.json
106+
- name: Zero downtime deployment
107+
href: durable-functions-zero-downtime-deployment.md
104108
- name: Monitor
105109
items:
106110
- name: Diagnostics

articles/azure-functions/durable/durable-functions-bindings.md

Lines changed: 48 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -368,62 +368,62 @@ Any state changes made to an entity during its execution will be automatically p
368368

369369
Every entity function has a parameter type of `IDurableEntityContext`, which has the following members:
370370

371-
* **EntityName**: Gets the name of the currently executing entity.
372-
* **EntityKey**: Gets the key of the currently executing entity.
373-
* **EntityId**: Gets the ID of the currently executing entity.
374-
* **OperationName**: gets the name of the current operation.
375-
* **IsNewlyConstructed**: returns `true` if the entity did not exist prior to the operation.
376-
* **GetState\<TState>()**: gets the current state of the entity. The `TState` parameter must be a primitive or JSON-serializeable type.
377-
* **SetState(object)**: updates the state of the entity. The `object` parameter must be a primitive or JSON-serializeable object.
378-
* **GetInput\<TInput>()**: gets the input for the current operation. The `TInput` type parameter must represent a primitive or JSON-serializeable type.
379-
* **Return(object)**: returns a value to the orchestration that called the operation. The `object` parameter must be a primitive or JSON-serializeable object.
380-
* **DestructOnExit()**: deletes the entity after finishing the current operation.
381-
* **SignalEntity(EntityId, string, object)**: sends a one-way message to an entity. The `object` parameter must be a primitive or JSON-serializeable object.
382-
383-
When using the class-based entity programming mode, the `IDurableEntityContext` object can be referenced using the `Entity.Current` thread-static property.
384-
385-
### Trigger sample - entity function
386-
387-
The following code is an example of a simple *Counter* entity implemented as a standard function. This function defines three *operations*, `add`, `reset`, and `get`, each of which operate on an integer state value, `currentValue`.
371+
* **EntityName**: the name of the currently executing entity.
372+
* **EntityKey**: the key of the currently executing entity.
373+
* **EntityId**: the ID of the currently executing entity.
374+
* **OperationName**: the name of the current operation.
375+
* **HasState**: whether the entity exists, that is, has some state.
376+
* **GetState\<TState>()**: gets the current state of the entity. If it does not already exist, it is created and initialized to `default<TState>`. The `TState` parameter must be a primitive or JSON-serializeable type.
377+
* **GetState\<TState>(initfunction)**: gets the current state of the entity. If it does not already exist, it is created by calling the provided `initfunction` parameter. The `TState` parameter must be a primitive or JSON-serializeable type.
378+
* **SetState(arg)**: creates or updates the state of the entity. The `arg` parameter must be a JSON-serializeable object or primitive.
379+
* **DeleteState()**: deletes the state of the entity.
380+
* **GetInput\<TInput>()**: gets the input for the current operation. The `TInput` type parameter must be a primitive or JSON-serializeable type.
381+
* **Return(arg)**: returns a value to the orchestration that called the operation. The `arg` parameter must be a primitive or JSON-serializeable object.
382+
* **SignalEntity(EntityId, operation, input)**: sends a one-way message to an entity. The `operation` parameter must be a non-null string, and the `input` parameter must be a primitive or JSON-serializeable object.
383+
* **CreateNewOrchestration(orchestratorFunctionName, input)**: starts a new orchestration. The `input` parameter must be a primitive or JSON-serializeable object.
384+
385+
The `IDurableEntityContext` object passed to the entity function can be accessed using the `Entity.Current` async-local property. This approach is convenient when using the class-based programming model.
386+
387+
### Trigger sample (function-based syntax)
388+
389+
The following code is an example of a simple *Counter* entity implemented as a durable function. This function defines three operations, `add`, `reset`, and `get`, each of which operate on an integer state.
388390

389391
```csharp
390-
[FunctionName(nameof(Counter))]
392+
[FunctionName("Counter")]
391393
public static void Counter([EntityTrigger] IDurableEntityContext ctx)
392394
{
393-
int currentValue = ctx.GetState<int>();
394-
395395
switch (ctx.OperationName.ToLowerInvariant())
396396
{
397397
case "add":
398-
int amount = ctx.GetInput<int>();
399-
currentValue += operand;
398+
ctx.SetState(ctx.GetState<int>() + ctx.GetInput<int>());
400399
break;
401400
case "reset":
402-
currentValue = 0;
401+
ctx.SetState(0);
403402
break;
404403
case "get":
405-
ctx.Return(currentValue);
404+
ctx.Return(ctx.GetState<int>()));
406405
break;
407406
}
408-
409-
ctx.SetState(currentValue);
410407
}
411408
```
412409

413-
### Trigger sample - entity class
410+
For more information on the function-based syntax and how to use it, see [Function-Based Syntax](durable-functions-dotnet-entities.md#function-based-syntax).
414411

415-
The following example is an equivalent implementation of the previous `Counter` entity using .NET classes and methods.
412+
### Trigger sample (class-based syntax)
413+
414+
The following example is an equivalent implementation of the `Counter` entity using classes and methods.
416415

417416
```csharp
417+
[JsonObject(MemberSerialization.OptIn)]
418418
public class Counter
419419
{
420420
[JsonProperty("value")]
421421
public int CurrentValue { get; set; }
422422

423423
public void Add(int amount) => this.CurrentValue += amount;
424-
424+
425425
public void Reset() => this.CurrentValue = 0;
426-
426+
427427
public int Get() => this.CurrentValue;
428428

429429
[FunctionName(nameof(Counter))]
@@ -432,10 +432,14 @@ public class Counter
432432
}
433433
```
434434

435+
The state of this entity is an object of type `Counter`, which contains a field that stores the current value of the counter. To persist this object in storage, it is serialized and deserialized by the [Json.NET](https://www.newtonsoft.com/json) library.
436+
437+
For more information on the class-based syntax and how to use it, see [Defining entity classes](durable-functions-dotnet-entities.md#defining-entity-classes).
438+
435439
> [!NOTE]
436440
> The function entry point method with the `[FunctionName]` attribute *must* be declared `static` when using entity classes. Non-static entry point methods may result in multiple object initialization and potentially other undefined behaviors.
437441
438-
Entity classes have special mechanisms for interacting with bindings and .NET dependency injection. For more information, see the [Durable Entities](durable-functions-entities.md) article.
442+
Entity classes have special mechanisms for interacting with bindings and .NET dependency injection. For more information, see [Entity construction](durable-functions-dotnet-entities.md#entity-construction).
439443

440444
## Entity client
441445

@@ -468,17 +472,15 @@ If you're using scripting languages (for example, *.csx* or *.js* files) for dev
468472

469473
In .NET functions, you typically bind to `IDurableEntityClient`, which gives you full access to all client APIs supported by Durable Entities. You can also bind to the `IDurableClient` interface, which provides access to client APIs for both entities and orchestrations. APIs on the client object include:
470474

471-
* **ReadEntityStateAsync\<T>**: reads the state of an entity.
475+
* **ReadEntityStateAsync\<T>**: reads the state of an entity. It returns a response that indicates whether the target entity exists, and if so, what its state is.
472476
* **SignalEntityAsync**: sends a one-way message to an entity, and waits for it to be enqueued.
473-
* **SignalEntityAsync\<TEntityInterface>**: same as `SignalEntityAsync` but uses a generated proxy object of type `TEntityInterface`.
474-
* **CreateEntityProxy\<TEntityInterface>**: dynamically generates a dynamic proxy of type `TEntityInterface` for making type-safe calls to entities.
475477

476-
> [!NOTE]
477-
> It's important to understand that the previous "signal" operations are all asynchronous. It is not possible to invoke an entity function and get back a return value from a client. Similarly, the `SignalEntityAsync` may return before the entity starts executing the operation. Only orchestrator functions can invoke entity functions synchronously and process return values.
478+
There is no need to create the target entity before sending a signal - the entity state can be created from within the entity function that handles the signal.
478479

479-
The `SignalEntityAsync` APIs require specifying the unique identifier of the entity as an `EntityId`. These APIs also optionally take the name of the entity operation as a `string` and the payload of the operation as a JSON-serializeable `object`. If the target entity does not exist, it will be created automatically with the specified entity ID.
480+
> [!NOTE]
481+
> It's important to understand that the "signals" sent from the client are simply enqueued, to be processed asynchronously at a later time. In particular, the `SignalEntityAsync` usually returns before the entity even starts the operation, and it is not possible to get back the return value or observe exceptions. If stronger guarantees are required (e.g. for workflows), *orchestrator functions* should be used, which can wait for entity operations to complete, and can process return values and observe exceptions.
480482
481-
### Client sample (untyped)
483+
### Example: client signals entity directly
482484

483485
Here is an example queue-triggered function that invokes a "Counter" entity.
484486

@@ -495,16 +497,16 @@ public static Task Run(
495497
}
496498
```
497499

498-
### Client sample (typed)
500+
### Example: client signals entity via interface
499501

500-
It's possible to generate a proxy object for type-safe access to entity operations. To generate a type-safe proxy, the entity type must implement an interface. For example, suppose the `Counter` entity mentioned earlier implemented an `ICounter` interface, defined as follows:
502+
Where possible, we recommend [accessing entities through interfaces](durable-functions-dotnet-entities.md#accessing-entities-through-interfaces) because it provides more type checking. For example, suppose the `Counter` entity mentioned earlier implemented an `ICounter` interface, defined as follows:
501503

502504
```csharp
503505
public interface ICounter
504506
{
505507
void Add(int amount);
506508
void Reset();
507-
int Get();
509+
Task<int> Get();
508510
}
509511

510512
public class Counter : ICounter
@@ -513,7 +515,7 @@ public class Counter : ICounter
513515
}
514516
```
515517

516-
Client code could then use `SignalEntityAsync<TEntityInterface>` and specify the `ICounter` interface as the type parameter to generate a type-safe proxy. This use of type-safe proxies is demonstrated in the following code sample:
518+
Client code can then use `SignalEntityAsync<ICounter>` to generate a type-safe proxy:
517519

518520
```csharp
519521
[FunctionName("UserDeleteAvailable")]
@@ -527,28 +529,19 @@ public static async Task AddValueClient(
527529
}
528530
```
529531

530-
In the previous example, the `proxy` parameter is a dynamically generated instance of `ICounter`, which internally translates the call to `Add` into the equivalent (untyped) call to `SignalEntityAsync`.
531-
532-
There are a few rules for defining entity interfaces:
533-
534-
* The type parameter `TEntityInterface` in `SignalEntityAsync<TEntityInterface>` must be an interface.
535-
* Entity interfaces must only define methods.
536-
* Entity interface methods must not define more than one parameter.
537-
* Entity interface methods must return `void`, `Task`, or `Task<T>` where `T` is some return value.
538-
* Entity interfaces must have exactly one concrete implementation class within the same assembly (that is, the entity class).
539-
540-
If any of these rules are violated, an `InvalidOperationException` will be thrown at runtime. The exception message will explain which rule was broken.
532+
The `proxy` parameter is a dynamically generated instance of `ICounter`, which internally translates the call to `Add` into the equivalent (untyped) call to `SignalEntityAsync`.
541533

542534
> [!NOTE]
543535
> The `SignalEntityAsync` APIs represent one-way operations. If an entity interfaces returns `Task<T>`, the value of the `T` parameter will always be null or `default`.
544536
545-
<a name="host-json"></a>
537+
In particular, it does not make sense to signal the `Get` operation, as no value is returned. Instead, clients can use either `ReadStateAsync` to access the counter state directly, or can start an orchestrator function that calls the `Get` operation.
546538

539+
<a name="host-json"></a>
547540
## host.json settings
548541

549542
[!INCLUDE [durabletask](../../../includes/functions-host-json-durabletask.md)]
550543

551544
## Next steps
552545

553546
> [!div class="nextstepaction"]
554-
> [Built-in HTTP API reference for instance management](durable-functions-http-api.md)
547+
> [Built-in HTTP API reference for instance management](durable-functions-http-api.md)

0 commit comments

Comments
 (0)