public async Task UsesDefaultDurableClientForDefaultConnection() { // Arrange var request = new DefaultHttpContext().Request; request.Headers["x-dfm-nonce"] = Shared.Nonce; var durableClientMoq = new Mock <IDurableClient>(); var queryResult = new OrchestrationStatusQueryResult() { DurableOrchestrationState = new DurableOrchestrationStatus[0] }; durableClientMoq .Setup(c => c.ListInstancesAsync(It.IsAny <OrchestrationStatusQueryCondition>(), It.IsAny <CancellationToken>())) .Returns(Task.FromResult(queryResult)); var logMoq = new Mock <ILogger>(); Environment.SetEnvironmentVariable(EnvVariableNames.DFM_NONCE, Shared.Nonce); // Act var result = (ContentResult)(await new IdSuggestions(null).DfmGetIdSuggestionsFunction(request, durableClientMoq.Object, "-", "TestHub", "abc", logMoq.Object)); // Assert Assert.AreEqual("application/json", result.ContentType); Assert.AreEqual("[]", result.Content); }
// Intentionally NOT using async/await here, because we need yield return. // The magic is to only load all the pages, when it is really needed (e.g. when sorting is used). private static IEnumerable <DurableOrchestrationStatus> ListAllInstances(this IDurableClient durableClient, DateTime?timeFrom, DateTime?timeTill, bool showInput) { var queryCondition = new OrchestrationStatusQueryCondition() { PageSize = ListInstancesPageSize, ShowInput = showInput }; if (timeFrom.HasValue) { queryCondition.CreatedTimeFrom = timeFrom.Value; } if (timeTill.HasValue) { queryCondition.CreatedTimeTo = timeTill.Value; } OrchestrationStatusQueryResult response = null; do { queryCondition.ContinuationToken = response == null ? null : response.ContinuationToken; response = durableClient.ListInstancesAsync(queryCondition, CancellationToken.None).Result; foreach (var item in response.DurableOrchestrationState) { yield return(item); } }while (!string.IsNullOrEmpty(response.ContinuationToken)); }
/// <inheritdoc /> internal override async Task <OrchestrationStatusQueryResult> GetStatusAsync( DateTime createdTimeFrom, DateTime?createdTimeTo, IEnumerable <OrchestrationRuntimeStatus> runtimeStatus, int pageSize, string continuationToken, CancellationToken cancellationToken = default(CancellationToken)) { var serviceClient = (AzureStorageOrchestrationService)this.client.ServiceClient; var statusContext = await serviceClient.GetOrchestrationStateAsync(createdTimeFrom, createdTimeTo, runtimeStatus.Select(x => (OrchestrationStatus)x), pageSize, continuationToken, cancellationToken); var results = new List <DurableOrchestrationStatus>(); foreach (var state in statusContext.OrchestrationState) { results.Add(this.ConvertFrom(state)); } var result = new OrchestrationStatusQueryResult { DurableOrchestrationState = results, ContinuationToken = statusContext.ContinuationToken, }; return(result); }
public async Task Run( [TimerTrigger(PurgeFrequencyVariable)] TimerInfo myTimer, [DurableClient] IDurableOrchestrationClient client, ILogger log, CancellationToken hostCancellationToken) { EnsureArg.IsNotNull(client, nameof(client)); EnsureArg.IsNotNull(myTimer, nameof(myTimer)); EnsureArg.IsNotNull(log, nameof(log)); var orchestrationInstanceIdList = new List <string>(); log.LogInformation("Purging orchestration instance history at: {Timestamp}", _getUtcNow()); if (myTimer.IsPastDue) { log.LogWarning("Current function invocation is later than scheduled."); } // Specify conditions for orchestration instances. var condition = new OrchestrationStatusQueryCondition { RuntimeStatus = _purgeConfig.RuntimeStatuses, CreatedTimeFrom = DateTime.MinValue, CreatedTimeTo = _getUtcNow().AddDays(-_purgeConfig.MinimumAgeDays), ContinuationToken = null }; do { OrchestrationStatusQueryResult listOfOrchestrators = await client.ListInstancesAsync(condition, hostCancellationToken); condition.ContinuationToken = listOfOrchestrators.ContinuationToken; // Loop through the orchestration instances and purge them. foreach (DurableOrchestrationStatus orchestration in listOfOrchestrators.DurableOrchestrationState) { orchestrationInstanceIdList.Add(orchestration.InstanceId); await client.PurgeInstanceHistoryAsync(orchestration.InstanceId); } } while (condition.ContinuationToken != null); if (orchestrationInstanceIdList.Count != 0) { log.LogInformation("{Count} Durable Functions cleaned up successfully.", orchestrationInstanceIdList.Count); log.LogDebug("List of cleaned instance IDs: {list}", string.Join(", ", orchestrationInstanceIdList)); } else { log.LogInformation("No Orchestration instances found within given conditions."); } }
public static async Task AF_WAITINGFORAPPROVAL( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "raiseEvent/{instanceId}")] HttpRequest req, string instanceId, [DurableClient] IDurableOrchestrationClient client, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); var noFilter = new OrchestrationStatusQueryCondition(); OrchestrationStatusQueryResult result = await client.ListInstancesAsync( noFilter, CancellationToken.None); foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState) { log.LogInformation(JsonConvert.SerializeObject(instance)); } await client.RaiseEventAsync(instanceId, "WaitingForApproval", true); }
public static async Task <IActionResult> AF_GETINSTANCES( [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = "instances/{instanceId}")] HttpRequest req, string instanceId, [DurableClient] IDurableOrchestrationClient client, ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); var noFilter = new OrchestrationStatusQueryCondition(); OrchestrationStatusQueryResult result = await client.ListInstancesAsync( noFilter, CancellationToken.None); foreach (DurableOrchestrationStatus instance in result.DurableOrchestrationState) { log.LogInformation(JsonConvert.SerializeObject(instance.InstanceId)); } return(new OkObjectResult(result.DurableOrchestrationState)); }
// Intentionally NOT using async/await here, because we need yield return. // The magic is to only load all the pages, when it is really needed (e.g. when sorting is used). private static IEnumerable <DurableOrchestrationStatus> ListAllInstances(this IDurableClient durableClient, DateTime?timeFrom, DateTime?timeTill, bool showInput, string[] statuses) { var queryCondition = new OrchestrationStatusQueryCondition() { PageSize = ListInstancesPageSize, ShowInput = showInput }; if (timeFrom.HasValue) { queryCondition.CreatedTimeFrom = timeFrom.Value; } if (timeTill.HasValue) { queryCondition.CreatedTimeTo = timeTill.Value; } if (statuses != null) { var runtimeStatuses = statuses.ToRuntimeStatuses().ToList(); // Durable Entities are always 'Running' if (statuses.Contains(DurableEntityRuntimeStatus, StringComparer.OrdinalIgnoreCase)) { runtimeStatuses.Add(OrchestrationRuntimeStatus.Running); } queryCondition.RuntimeStatus = runtimeStatuses; } OrchestrationStatusQueryResult response = null; do { queryCondition.ContinuationToken = response == null ? null : response.ContinuationToken; response = durableClient.ListInstancesAsync(queryCondition, CancellationToken.None).Result; foreach (var item in response.DurableOrchestrationState) { yield return(item); } }while (!string.IsNullOrEmpty(response.ContinuationToken)); }
public static async Task<IActionResult> CountCities( [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "countcities")] HttpRequest req, [DurableClient] IDurableClient client, ILogger log) { var queryCondition = new OrchestrationStatusQueryCondition() { InstanceIdPrefix = "Orch", }; int completed = 0; int pending = 0; int running = 0; int other = 0; do { OrchestrationStatusQueryResult result = await client.ListInstancesAsync(queryCondition, CancellationToken.None); queryCondition.ContinuationToken = result.ContinuationToken; foreach (var status in result.DurableOrchestrationState) { if (status.RuntimeStatus == OrchestrationRuntimeStatus.Pending) { pending++; } else if (status.RuntimeStatus == OrchestrationRuntimeStatus.Running) { running++; } else if (status.RuntimeStatus == OrchestrationRuntimeStatus.Completed) { completed++; } else { other++; } } } while (queryCondition.ContinuationToken != null); return new OkObjectResult($"{pending+running+completed+other} orchestration instances ({pending} pending, {running} running, {completed} completed, {other} other)\n"); }
public async Task GetQueryStatusWithPaging_is_Success() { var list = (IList <DurableOrchestrationStatus>) new List <DurableOrchestrationStatus> { new DurableOrchestrationStatus { InstanceId = "01", CreatedTime = new DateTime(2018, 3, 10, 10, 10, 10, DateTimeKind.Utc), RuntimeStatus = OrchestrationRuntimeStatus.Running, }, new DurableOrchestrationStatus { InstanceId = "02", CreatedTime = new DateTime(2018, 3, 10, 10, 6, 10, DateTimeKind.Utc), RuntimeStatus = OrchestrationRuntimeStatus.Running, }, }; var ctx = new OrchestrationStatusQueryResult { DurableOrchestrationState = list, ContinuationToken = "YYYY-YYYYYYYY-YYYYYYYYYYYY", }; var createdTimeFrom = new DateTime(2018, 3, 10, 10, 1, 0, DateTimeKind.Utc); var createdTimeTo = new DateTime(2018, 3, 10, 10, 23, 59, DateTimeKind.Utc); var runtimeStatus = new List <OrchestrationRuntimeStatus>(); runtimeStatus.Add(OrchestrationRuntimeStatus.Running); var runtimeStatusString = OrchestrationRuntimeStatus.Running.ToString(); var pageSize = 100; var continuationToken = "XXXX-XXXXXXXX-XXXXXXXXXXXX"; var clientMock = new Mock <DurableOrchestrationClientBase>(); clientMock .Setup(x => x.GetStatusAsync(createdTimeFrom, createdTimeTo, runtimeStatus, pageSize, continuationToken, It.IsAny <CancellationToken>())) .Returns(Task.FromResult(ctx)); var httpApiHandler = new ExtendedHttpApiHandler(clientMock.Object); var getStatusRequestUriBuilder = new UriBuilder(TestConstants.NotificationUrl); getStatusRequestUriBuilder.Path += $"/Instances/"; getStatusRequestUriBuilder.Query = $"createdTimeFrom={WebUtility.UrlEncode(createdTimeFrom.ToString())}&createdTimeTo={WebUtility.UrlEncode(createdTimeTo.ToString())}&runtimeStatus={runtimeStatusString}&top=100"; var requestMessage = new HttpRequestMessage { Method = HttpMethod.Get, RequestUri = getStatusRequestUriBuilder.Uri, }; requestMessage.Headers.Add("x-ms-continuation-token", "XXXX-XXXXXXXX-XXXXXXXXXXXX"); var responseMessage = await httpApiHandler.HandleRequestAsync(requestMessage); Assert.Equal(HttpStatusCode.OK, responseMessage.StatusCode); Assert.Equal("YYYY-YYYYYYYY-YYYYYYYYYYYY", responseMessage.Headers.GetValues("x-ms-continuation-token").FirstOrDefault()); var actual = JsonConvert.DeserializeObject <IList <StatusResponsePayload> >(await responseMessage.Content.ReadAsStringAsync()); clientMock.Verify(x => x.GetStatusAsync(createdTimeFrom, createdTimeTo, runtimeStatus, pageSize, continuationToken, It.IsAny <CancellationToken>())); Assert.Equal("01", actual[0].InstanceId); Assert.Equal("Running", actual[0].RuntimeStatus); Assert.Equal("02", actual[1].InstanceId); Assert.Equal("Running", actual[1].RuntimeStatus); }