Skip to content

Commit

Permalink
Merge pull request #1210 from Microsoft/daveta-appinsight-dialogset
Browse files Browse the repository at this point in the history
Add DialogSet.SetTelemetryClient(), and modify ComponentDialog
  • Loading branch information
daveta committed Dec 5, 2018
2 parents 5b707fe + c4e964f commit b49e476
Show file tree
Hide file tree
Showing 6 changed files with 298 additions and 9 deletions.
20 changes: 20 additions & 0 deletions libraries/Microsoft.Bot.Builder.Dialogs/ComponentDialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ public ComponentDialog(string dialogId)
_dialogs = new DialogSet();
}

/// <summary>
/// Gets or sets or set the <see cref="IBotTelemetryClient"/> to use.
/// When setting this property, all the contained dialogs TelemetryClient properties are also set.
/// </summary>
/// <value>The <see cref="IBotTelemetryClient"/> to use when logging.</value>
public new IBotTelemetryClient TelemetryClient
{
get
{
return base.TelemetryClient;
}

set
{
base.TelemetryClient = value ?? NullBotTelemetryClient.Instance;
_dialogs.TelemetryClient = base.TelemetryClient;
}
}

protected string InitialDialogId { get; set; }

public override async Task<DialogTurnResult> BeginDialogAsync(DialogContext outerDc, object options = null, CancellationToken cancellationToken = default(CancellationToken))
Expand Down Expand Up @@ -114,6 +133,7 @@ public override async Task EndDialogAsync(ITurnContext turnContext, DialogInstan
/// </summary>
/// <param name="dialog">The dialog to add.</param>
/// <returns>The updated <see cref="ComponentDialog"/>.</returns>
/// <remarks>Adding a new dialog will inherit the <see cref="IBotTelemetryClient"/> of the ComponentDialog.</remarks>
public ComponentDialog AddDialog(Dialog dialog)
{
_dialogs.Add(dialog);
Expand Down
15 changes: 14 additions & 1 deletion libraries/Microsoft.Bot.Builder.Dialogs/Dialog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Microsoft.Bot.Builder.Dialogs
public abstract class Dialog
{
public static readonly DialogTurnResult EndOfTurn = new DialogTurnResult(DialogTurnStatus.Waiting);
private IBotTelemetryClient _telemetryClient;

public Dialog(string dialogId)
{
Expand All @@ -21,6 +22,7 @@ public Dialog(string dialogId)
throw new ArgumentNullException(nameof(dialogId));
}

_telemetryClient = NullBotTelemetryClient.Instance;
Id = dialogId;
}

Expand All @@ -30,7 +32,18 @@ public Dialog(string dialogId)
/// Gets or sets the telemetry client for logging events.
/// </summary>
/// <value>The Telemetry Client logger.</value>
public IBotTelemetryClient TelemetryClient { get; set; } = NullBotTelemetryClient.Instance;
public IBotTelemetryClient TelemetryClient
{
get
{
return _telemetryClient;
}

set
{
_telemetryClient = value;
}
}

/// <summary>
/// Method called when a new dialog has been pushed onto the stack and is being activated.
Expand Down
28 changes: 28 additions & 0 deletions libraries/Microsoft.Bot.Builder.Dialogs/DialogSet.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,50 @@ public class DialogSet
{
private readonly IStatePropertyAccessor<DialogState> _dialogState;
private readonly IDictionary<string, Dialog> _dialogs = new Dictionary<string, Dialog>();
private IBotTelemetryClient _telemetryClient;

public DialogSet(IStatePropertyAccessor<DialogState> dialogState)
{
_dialogState = dialogState ?? throw new ArgumentNullException($"missing {nameof(dialogState)}");
_telemetryClient = NullBotTelemetryClient.Instance;
}

internal DialogSet()
{
// TODO: This is only used by ComponentDialog and future release
// will refactor to use IStatePropertyAccessor from context
_dialogState = null;
_telemetryClient = NullBotTelemetryClient.Instance;
}

/// <summary>
/// Gets or sets or set the <see cref="IBotTelemetryClient"/> to use.
/// When setting this property, all the contained dialogs TelemetryClient properties are also set.
/// </summary>
/// <value>The <see cref="IBotTelemetryClient"/> to use when logging.</value>
public IBotTelemetryClient TelemetryClient
{
get
{
return _telemetryClient;
}

set
{
_telemetryClient = value ?? NullBotTelemetryClient.Instance;
foreach (var dialog in _dialogs.Values)
{
dialog.TelemetryClient = _telemetryClient;
}
}
}

/// <summary>
/// Adds a new dialog to the set and returns the added dialog.
/// </summary>
/// <param name="dialog">The dialog to add.</param>
/// <returns>The DialogSet for fluent calls to Add().</returns>
/// <remarks>Adding a new dialog will inherit the <see cref="IBotTelemetryClient"/> of the DialogSet.</remarks>
public DialogSet Add(Dialog dialog)
{
if (dialog == null)
Expand All @@ -45,7 +71,9 @@ public DialogSet Add(Dialog dialog)
throw new ArgumentException($"DialogSet.Add(): A dialog with an id of '{dialog.Id}' already added.");
}

dialog.TelemetryClient = _telemetryClient;
_dialogs[dialog.Id] = dialog;

return this;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ public async Task Waterfall()
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step1"); return Dialog.EndOfTurn; },
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step2"); return Dialog.EndOfTurn; },
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step3"); return Dialog.EndOfTurn; },
})
{ TelemetryClient = telemetryClient.Object });
}));

dialogs.TelemetryClient = telemetryClient.Object;


await new TestFlow(adapter, async (turnContext, cancellationToken) =>
{
Expand Down Expand Up @@ -71,10 +73,11 @@ public async Task WaterfallWithCallback()
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step1"); return Dialog.EndOfTurn; },
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step2"); return Dialog.EndOfTurn; },
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step3"); return Dialog.EndOfTurn; },
})
{ TelemetryClient = telemetryClient.Object };
});


dialogs.Add(waterfallDialog);
dialogs.TelemetryClient = telemetryClient.Object;

await new TestFlow(adapter, async (turnContext, cancellationToken) =>
{
Expand Down Expand Up @@ -127,10 +130,10 @@ public async Task EnsureEndDialogCalled()
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step1"); return Dialog.EndOfTurn; },
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step2"); return Dialog.EndOfTurn; },
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step3"); return Dialog.EndOfTurn; },
})
{ TelemetryClient = telemetryClient.Object };
});

dialogs.Add(waterfallDialog);
dialogs.TelemetryClient = telemetryClient.Object;

await new TestFlow(adapter, async (turnContext, cancellationToken) =>
{
Expand Down Expand Up @@ -190,10 +193,10 @@ public async Task EnsureCancelDialogCalled()
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step1"); return Dialog.EndOfTurn; },
async (step, cancellationToken) => { await step.Context.SendActivityAsync("step2"); return Dialog.EndOfTurn; },
async (step, cancellationToken) => { await step.CancelAllDialogsAsync(); return Dialog.EndOfTurn; },
})
{ TelemetryClient = telemetryClient.Object };
});

dialogs.Add(waterfallDialog);
dialogs.TelemetryClient = telemetryClient.Object;

await new TestFlow(adapter, async (turnContext, cancellationToken) =>
{
Expand Down
111 changes: 111 additions & 0 deletions tests/Microsoft.Bot.Builder.Dialogs.Tests/ComponentDialogTests.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder.Adapters;
Expand Down Expand Up @@ -54,6 +56,75 @@ public async Task BasicWaterfallTest()
.StartTestAsync();
}

[TestMethod]
public async Task TelemetryBasicWaterfallTest()
{
var testComponentDialog = new TestComponentDialog();
Assert.IsTrue(testComponentDialog.TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("test-waterfall").TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("number").TelemetryClient is NullBotTelemetryClient);

testComponentDialog.TelemetryClient = new MyBotTelemetryClient();
Assert.IsTrue(testComponentDialog.TelemetryClient is MyBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("test-waterfall").TelemetryClient is MyBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("number").TelemetryClient is MyBotTelemetryClient);
await Task.CompletedTask;
}

[TestMethod]
public async Task TelemetryHeterogeneousLoggerTest()
{
var testComponentDialog = new TestComponentDialog();
Assert.IsTrue(testComponentDialog.TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("test-waterfall").TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("number").TelemetryClient is NullBotTelemetryClient);

testComponentDialog.FindDialog("test-waterfall").TelemetryClient = new MyBotTelemetryClient();

Assert.IsTrue(testComponentDialog.FindDialog("test-waterfall").TelemetryClient is MyBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("number").TelemetryClient is NullBotTelemetryClient);
await Task.CompletedTask;
}


[TestMethod]
public async Task TelemetryAddWaterfallTest()
{
var testComponentDialog = new TestComponentDialog();
Assert.IsTrue(testComponentDialog.TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("test-waterfall").TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("number").TelemetryClient is NullBotTelemetryClient);

testComponentDialog.TelemetryClient = new MyBotTelemetryClient();
testComponentDialog.AddDialog(new WaterfallDialog("C"));

Assert.IsTrue(testComponentDialog.FindDialog("C").TelemetryClient is MyBotTelemetryClient);
await Task.CompletedTask;
}

[TestMethod]
public async Task TelemetryNullUpdateAfterAddTest()
{
var testComponentDialog = new TestComponentDialog();
Assert.IsTrue(testComponentDialog.TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("test-waterfall").TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("number").TelemetryClient is NullBotTelemetryClient);

testComponentDialog.TelemetryClient = new MyBotTelemetryClient();
testComponentDialog.AddDialog(new WaterfallDialog("C"));

Assert.IsTrue(testComponentDialog.FindDialog("C").TelemetryClient is MyBotTelemetryClient);
testComponentDialog.TelemetryClient = null;

Assert.IsTrue(testComponentDialog.FindDialog("test-waterfall").TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("number").TelemetryClient is NullBotTelemetryClient);
Assert.IsTrue(testComponentDialog.FindDialog("C").TelemetryClient is NullBotTelemetryClient);

await Task.CompletedTask;
}



[TestMethod]
public async Task BasicComponentDialogTest()
{
Expand Down Expand Up @@ -204,5 +275,45 @@ public TestNestedComponentDialog()
AddDialog(new TestComponentDialog());
}
}
private class MyBotTelemetryClient : IBotTelemetryClient
{
public MyBotTelemetryClient()
{

}

public void Flush()
{
throw new NotImplementedException();
}

public void TrackAvailability(string name, DateTimeOffset timeStamp, TimeSpan duration, string runLocation, bool success, string message = null, IDictionary<string, string> properties = null, IDictionary<string, double> metrics = null)
{
throw new NotImplementedException();
}

public void TrackDependency(string dependencyTypeName, string target, string dependencyName, string data, DateTimeOffset startTime, TimeSpan duration, string resultCode, bool success)
{
throw new NotImplementedException();
}

public void TrackEvent(string eventName, IDictionary<string, string> properties = null, IDictionary<string, double> metrics = null)
{
throw new NotImplementedException();
}

public void TrackException(Exception exception, IDictionary<string, string> properties = null, IDictionary<string, double> metrics = null)
{
throw new NotImplementedException();
}

public void TrackTrace(string message, Severity severityLevel, IDictionary<string, string> properties)
{
throw new NotImplementedException();
}
}

}

}

Loading

0 comments on commit b49e476

Please sign in to comment.