diff --git a/libraries/Microsoft.Bot.Builder.Azure.Queues/QueuesStorage.cs b/libraries/Microsoft.Bot.Builder.Azure.Queues/AzureQueueStorage.cs similarity index 77% rename from libraries/Microsoft.Bot.Builder.Azure.Queues/QueuesStorage.cs rename to libraries/Microsoft.Bot.Builder.Azure.Queues/AzureQueueStorage.cs index 294616d7e1..d92c22cb78 100644 --- a/libraries/Microsoft.Bot.Builder.Azure.Queues/QueuesStorage.cs +++ b/libraries/Microsoft.Bot.Builder.Azure.Queues/AzureQueueStorage.cs @@ -15,14 +15,14 @@ namespace Microsoft.Bot.Builder.Azure.Queues /// /// Service used to add messages to an Azure.Storage.Queues. /// - public class QueuesStorage + public class AzureQueueStorage : QueueStorage { - private JsonSerializerSettings _jsonSettings; + private readonly JsonSerializerSettings _jsonSettings; private bool _createQueueIfNotExists = true; private readonly QueueClient _queueClient; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// Azure Storage connection string. /// Name of the storage queue where entities will be queued. @@ -31,7 +31,7 @@ public class QueuesStorage /// jsonSerializer.TypeNameHandling = TypeNameHandling.None. /// jsonSerializer.NullValueHandling = NullValueHandling.Ignore. /// - public QueuesStorage(string queuesStorageConnectionString, string queueName, JsonSerializerSettings jsonSerializerSettings = null) + public AzureQueueStorage(string queuesStorageConnectionString, string queueName, JsonSerializerSettings jsonSerializerSettings = null) { if (string.IsNullOrEmpty(queuesStorageConnectionString)) { @@ -44,16 +44,17 @@ public QueuesStorage(string queuesStorageConnectionString, string queueName, Jso } _jsonSettings = jsonSerializerSettings ?? new JsonSerializerSettings - { - TypeNameHandling = TypeNameHandling.None, - NullValueHandling = NullValueHandling.Ignore - }; + { + TypeNameHandling = TypeNameHandling.None, + NullValueHandling = NullValueHandling.Ignore + }; _queueClient = new QueueClient(queuesStorageConnectionString, queueName); } /// - /// Queue and Activity, with option in the Activity.Value to Azure.Storage.Queues. + /// Queue an Activity to an Azure.Storage.Queues.QueueClient. The visibility timeout specifies how long the message should be invisible + /// to Dequeue and Peek operations. The message content must be a UTF-8 encoded string that is up to 64KB in size. /// /// This is expected to be an retrieved from a call to /// activity.GetConversationReference().GetContinuationActivity(). This enables restarting the conversation @@ -62,7 +63,7 @@ public QueuesStorage(string queuesStorageConnectionString, string queueName, Jso /// Specifies the time-to-live interval for the message. /// Cancellation token for the async operation. /// as a Json string, from the QueueClient SendMessageAsync operation. - public async Task QueueActivityAsync(Activity activity, TimeSpan? visibilityTimeout = null, TimeSpan? timeToLive = null, CancellationToken cancellationToken = default) + public override async Task QueueActivityAsync(Activity activity, TimeSpan? visibilityTimeout = null, TimeSpan? timeToLive = null, CancellationToken cancellationToken = default) { if (_createQueueIfNotExists) { diff --git a/libraries/Microsoft.Bot.Builder.Azure.Queues/Microsoft.Bot.Builder.Azure.Queues.csproj b/libraries/Microsoft.Bot.Builder.Azure.Queues/Microsoft.Bot.Builder.Azure.Queues.csproj index eca57ae99d..1c435d1bfd 100644 --- a/libraries/Microsoft.Bot.Builder.Azure.Queues/Microsoft.Bot.Builder.Azure.Queues.csproj +++ b/libraries/Microsoft.Bot.Builder.Azure.Queues/Microsoft.Bot.Builder.Azure.Queues.csproj @@ -38,12 +38,9 @@ - - - diff --git a/libraries/Microsoft.Bot.Builder.Azure.Queues/ContinueConversationLater.cs b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ContinueConversationLater.cs similarity index 79% rename from libraries/Microsoft.Bot.Builder.Azure.Queues/ContinueConversationLater.cs rename to libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ContinueConversationLater.cs index ec44448832..520cf5bb80 100644 --- a/libraries/Microsoft.Bot.Builder.Azure.Queues/ContinueConversationLater.cs +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Actions/ContinueConversationLater.cs @@ -6,13 +6,12 @@ using System.Threading; using System.Threading.Tasks; using AdaptiveExpressions.Properties; -using Microsoft.Bot.Builder.Dialogs; using Newtonsoft.Json; -namespace Microsoft.Bot.Builder.Azure.Queues +namespace Microsoft.Bot.Builder.Dialogs.Adaptive.Actions { /// - /// Action which schedules a conversation to be continued later by writing a EventActivity(Name=ContinueConversation) to a Azure Storage queue. + /// Action which schedules a conversation to be continued later by writing an EventActivity(Name=ContinueConversation) to a queue. /// /// /// This class works by writing an EventActivity(Name=ConversationUpdate) to an azure storage queue with visibility policy to @@ -32,7 +31,7 @@ public class ContinueConversationLater : Dialog /// The Kind name for this dialog. /// [JsonProperty("$kind")] - public const string Kind = "AzureQueues.ContinueConversationLater"; + public const string Kind = "Microsoft.ContinueConversationLater"; /// /// Initializes a new instance of the class. @@ -74,23 +73,6 @@ public ContinueConversationLater([CallerFilePath] string callerPath = "", [Calle [JsonProperty("value")] public ValueExpression Value { get; set; } - /// - /// Gets or sets the connectionString for the azure storage queue to use. - /// - /// - /// The connectionString for the azure storage queue to use. - /// - /// '=settings.ConnectionString'. - [JsonProperty("connectionString")] - public StringExpression ConnectionString { get; set; } - - /// - /// Gets or sets the name of the queue to use. - /// - /// default is 'activities'. - [JsonProperty("queueName")] - public StringExpression QueueName { get; set; } = "activities"; - /// public override async Task BeginDialogAsync(DialogContext dc, object options = null, CancellationToken cancellationToken = default(CancellationToken)) { @@ -105,12 +87,11 @@ public ContinueConversationLater([CallerFilePath] string callerPath = "", [Calle } var dateString = Date.GetValue(dc.State); - DateTime date; - if (!DateTime.TryParse(dateString, out date)) + if (!DateTime.TryParse(dateString, out var date)) { throw new ArgumentException($"{nameof(Date)} is invalid"); } - + date = date.ToUniversalTime(); if (date <= DateTime.UtcNow) { @@ -124,10 +105,7 @@ public ContinueConversationLater([CallerFilePath] string callerPath = "", [Calle var visibility = date - DateTime.UtcNow; var ttl = visibility + TimeSpan.FromMinutes(2); - var queueName = QueueName.GetValue(dc.State); - var connectionString = ConnectionString.GetValue(dc.State); - - var queueStorage = new QueuesStorage(connectionString, queueName); + var queueStorage = dc.Context.TurnState.Get() ?? throw new NullReferenceException("Unable to locate QueueStorage in HostContext"); var receipt = await queueStorage.QueueActivityAsync(activity, visibility, ttl, cancellationToken).ConfigureAwait(false); // return the receipt as the result. diff --git a/libraries/Microsoft.Bot.Builder.Azure.Queues/Schemas/AzureQueues.ContinueConversationLater.schema b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ContinueConversationLater.schema similarity index 67% rename from libraries/Microsoft.Bot.Builder.Azure.Queues/Schemas/AzureQueues.ContinueConversationLater.schema rename to libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ContinueConversationLater.schema index 82dcdb1919..c5738e852e 100644 --- a/libraries/Microsoft.Bot.Builder.Azure.Queues/Schemas/AzureQueues.ContinueConversationLater.schema +++ b/libraries/Microsoft.Bot.Builder.Dialogs.Adaptive/Schemas/Actions/Microsoft.ContinueConversationLater.schema @@ -30,23 +30,6 @@ "=addHours(utcNow(), 1)" ] }, - "connectionString": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Connection String", - "description": "Connection string for connecting to an Azure Storage account.", - "examples": [ - "=settings.connectionString" - ] - }, - "queueName": { - "$ref": "schema:#/definitions/stringExpression", - "title": "Queue Name", - "description": "Name of the queue that your azure function is bound to.", - "examples": [ - "activities" - ], - "default": "activities" - }, "value": { "$ref": "schema:#/definitions/valueExpression", "title": "Value", diff --git a/libraries/Microsoft.Bot.Builder/QueueStorage.cs b/libraries/Microsoft.Bot.Builder/QueueStorage.cs new file mode 100644 index 0000000000..0e8a3eb77d --- /dev/null +++ b/libraries/Microsoft.Bot.Builder/QueueStorage.cs @@ -0,0 +1,27 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Bot.Schema; + +namespace Microsoft.Bot.Builder +{ + /// + /// A base class for enqueueing an Activity for later processing. + /// + public abstract class QueueStorage + { + /// + /// Enqueues an Activity for later processing. The visibility timeout specifies how long the message should be invisible + /// to Dequeue and Peek operations. The message content must be a UTF-8 encoded string that is up to 64KB in size. + /// + /// The to be queued for later processing. + /// Visibility timeout. Optional with a default value of 0. Cannot be larger than 7 days. + /// Specifies the time-to-live interval for the message. + /// Cancellation token for the async operation. + /// A result string. + public abstract Task QueueActivityAsync(Activity activity, TimeSpan? visibilityTimeout = null, TimeSpan? timeToLive = null, CancellationToken cancellationToken = default); + } +} diff --git a/tests/Microsoft.Bot.Builder.Azure.Tests/AzureQueueTests.cs b/tests/Microsoft.Bot.Builder.Azure.Tests/AzureQueueTests.cs index 2af3d42ee7..16647567f4 100644 --- a/tests/Microsoft.Bot.Builder.Azure.Tests/AzureQueueTests.cs +++ b/tests/Microsoft.Bot.Builder.Azure.Tests/AzureQueueTests.cs @@ -8,6 +8,7 @@ using Microsoft.Bot.Builder.Adapters; using Microsoft.Bot.Builder.Azure.Queues; using Microsoft.Bot.Builder.Dialogs; +using Microsoft.Bot.Builder.Dialogs.Adaptive.Actions; using Microsoft.Bot.Builder.Tests; using Microsoft.Bot.Schema; using Newtonsoft.Json; @@ -40,13 +41,15 @@ public async Task ContinueConversationLaterTests() .UseStorage(new MemoryStorage()) .UseBotState(new ConversationState(new MemoryStorage()), new UserState(new MemoryStorage())); + var queueStorage = new AzureQueueStorage(ConnectionString, queueName); var dm = new DialogManager(new ContinueConversationLater() { - ConnectionString = ConnectionString, - QueueName = queueName, Date = "=addSeconds(utcNow(), 2)", Value = "foo" }); + + dm.InitialTurnState.Set(queueStorage); + await new TestFlow((TestAdapter)adapter, dm.OnTurnAsync) .Send("hi") .StartTestAsync();