示例#1
0
        public static async Task <bool> Transfer(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var transferOperation = context.GetInput <TransferOperation>();

            bool transferSuccessful = false;

            EntityId fromAccountId = new EntityId(nameof(Account), transferOperation.FromAccountId);
            EntityId toAccountId   = new EntityId(nameof(Account), transferOperation.ToAccountId);

            using (await context.LockAsync(fromAccountId, toAccountId))
            {
                var fromAccountBalance = await context.CallEntityAsync <int>(fromAccountId, "balance");

                if (fromAccountBalance >= transferOperation.Amount)
                {
                    var taskList = new List <Task>();
                    taskList.Add(context.CallEntityAsync <int>(fromAccountId, "withdraw", transferOperation.Amount));
                    taskList.Add(context.CallEntityAsync <int>(toAccountId, "deposit", transferOperation.Amount));
                    await Task.WhenAll(taskList.ToArray());

                    transferSuccessful = true;
                }
            }

            return(transferSuccessful);
        }
#pragma warning restore 618

        public static async Task <string> SignalAndCallStringStore([OrchestrationTrigger] IDurableOrchestrationContext ctx)
        {
            // construct entity id from entity name and a supplied GUID
            var entity = new EntityId("StringStore2", ctx.GetInput <Guid>().ToString());

            // signal and call (both of these will be delivered close together)
            ctx.SignalEntity(entity, "set", "333");

            var result = await ctx.CallEntityAsync <string>(entity, "get");

            if (result != "333")
            {
                return($"fail: wrong entity state: expected 333, got {result}");
            }

            // make another call to see if the state survives replay
            result = await ctx.CallEntityAsync <string>(entity, "get");

            if (result != "333")
            {
                return($"fail: wrong entity state: expected 333, got {result}");
            }

            return("ok");
        }
示例#3
0
        public async Task <int> IncrementOrchestration(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var entityId = new EntityId(nameof(Counter), CounterName);
            await context.CallEntityAsync(entityId, "Add", 1);

            var counter = await context.CallEntityAsync <int>(entityId, "Get");

            counter++;
            return(counter);
        }
        public static async Task UpdateTwoCounters([OrchestrationTrigger] IDurableOrchestrationContext ctx)
        {
            var entity1 = new EntityId("CounterEntity", "1");
            var entity2 = new EntityId("CounterEntity", "2");

            using (await ctx.LockAsync(entity1, entity2))
            {
                await Task.WhenAll(
                    ctx.CallEntityAsync(entity1, "add", 42),
                    ctx.CallEntityAsync(entity2, "add", -42));
            }
        }
示例#5
0
        public async Task ProcessUserOrchestration([OrchestrationTrigger] IDurableOrchestrationContext context, ILogger logger)
        {
            //------------------------------------------------------------------------------------------------------------------------------------
            // Get the user ID that will be processed in the current orchestration.
            var userId = context.GetInput <string>();

            if (string.IsNullOrEmpty(userId))
            {
                logger.LogError($"No user ID was passed as input to the '{context.Name}' orchestration running with instance ID '{context.InstanceId}'. The orchestration cannot continue and will now exit.");
                return;
            }
            //------------------------------------------------------------------------------------------------------------------------------------



            //------------------------------------------------------------------------------------------------------------------------------------
            // Create a reference to the entity, and initialize the entity with the orchestration ID for the current instance.
            // This will make the current orchestration the current for handling processing of a given user, invalidating any other
            // running instance that has been started for the same user.
            var eid = new EntityId(Names.ProcessUserState, userId);
            await context.CallEntityAsync(eid, nameof(ProcessUserState.InitializeUserProcessing), context.InstanceId);

            //------------------------------------------------------------------------------------------------------------------------------------



            //------------------------------------------------------------------------------------------------------------------------------------
            // Simulating some work performed in the orchestration to allow other orchestrations to be triggered while this is still running.
            await context.CallActivityAsync(Names.Delay, 5000);

            //------------------------------------------------------------------------------------------------------------------------------------



            //------------------------------------------------------------------------------------------------------------------------------------
            // After we've done some processing, we check if the currently running orchestration is still the current orchestration for
            // the user that the orchestration is processing. We then make decisions based on the information returned from the entity.

            // We can repeat this process as many times we need in the orchestration, for instance if processing involves several steps that
            // call into sub orchestrations or activity functions. Whatever makes sense for your particular case.
            var isCurrent = await context.CallEntityAsync <bool>(eid, nameof(ProcessUserState.IsCurrentOrchestration), context.InstanceId);

            if (isCurrent)
            {
                logger.LogInformation($"The orchestration '{context.Name}' with instance '{context.InstanceId}' is still the current orchestration and will continue running.");
            }
            else
            {
                logger.LogWarning($"A newer orchestration instance of the orchestation '{context.Name}' for user ID '{userId}' has been started. This instance ('{context.InstanceId}') should not perform any processing anymore.");
            }
            //------------------------------------------------------------------------------------------------------------------------------------
        }
        public static async Task <(int, int)> LockedTransfer([OrchestrationTrigger] IDurableOrchestrationContext ctx)
        {
            var(from, to) = ctx.GetInput <(EntityId, EntityId)>();

            if (from.Equals(to))
            {
                throw new ArgumentException("from and to must be distinct");
            }

            if (ctx.IsLocked(out _))
            {
                throw new Exception("test failed: lock context is incorrect");
            }

            int fromBalance;
            int toBalance;

            using (await ctx.LockAsync(from, to))
            {
                if (!ctx.IsLocked(out var ownedLocks) ||
                    ownedLocks.Count != 2 ||
                    !ownedLocks.Contains(from) ||
                    !ownedLocks.Contains(to))
                {
                    throw new Exception("test failed: lock context is incorrect");
                }

                // read balances in parallel
                var t1 = ctx.CallEntityAsync <int>(from, "get");
                var t2 = ctx.CallEntityAsync <int>(to, "get");
                fromBalance = await t1;
                toBalance   = await t2;

                // modify
                fromBalance--;
                toBalance++;

                // write balances in parallel
                var   t3 = ctx.CallEntityAsync(from, "set", fromBalance);
                var   t4 = ctx.CallEntityAsync(to, "set", toBalance);
                await t3;
                await t4;
            }

            if (ctx.IsLocked(out _))
            {
                throw new Exception("test failed: lock context is incorrect");
            }

            return(fromBalance, toBalance);
        }
示例#7
0
        public async Task RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            await context.CallEntityAsync(new EntityId(nameof(RegistrationAggregate), context.InstanceId),
                                          nameof(RegistrationAggregate.Create), context.CurrentUtcDateTime);

            var finishRegistration = await context.WaitForExternalEvent(nameof(FinishRegistration), TimeSpan.FromMinutes(5), Status.TimeOut);

            await context.CallEntityAsync(new EntityId(nameof(RegistrationAggregate), context.InstanceId),
                                          nameof(RegistrationAggregate.SetState), new UpdateStatusCommand()
            {
                Status = finishRegistration,
                Time   = context.CurrentUtcDateTime
            });
        }
示例#8
0
        public static async Task PatchCard(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var entityOperation = context.GetInput <EntityOperation>();

            await context.CallEntityAsync(entityOperation.EntityId, "Patch", entityOperation.Document);
        }
        public static async Task <string> RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context, ILogger log)
        {
            string endpoint = context.GetInput <object>().ToString();
            var    request  = new DurableHttpRequest(HttpMethod.Get, new Uri(endpoint));
            DurableHttpResponse endpointResponse = await context.CallHttpAsync(request);

            if (endpointResponse.StatusCode != HttpStatusCode.OK)
            {
                throw new ArgumentException($"Failed to contact endpoint: {endpointResponse.StatusCode}: {endpointResponse.Content}");
            }
            log.LogInformation($"Information retrieved from endpoint = {endpointResponse.Content}.");

            string[] words = endpointResponse.Content.Split(" ");
            log.LogInformation($"Words count = {words.Count()}.");

            var entityId = new EntityId("OrchestrationSample_Counter", "charCounter");

            context.SignalEntity(entityId, "reset");

            foreach (string word in words)
            {
                context.SignalEntity(entityId, "Add", word);
            }

            await context.CallActivityAsync("OrchestrationSample_LogBlob", endpoint.Replace("/", "bar"));

            int count = await context.CallEntityAsync <int>(entityId, "Get");

            return($"Endpoint: {endpoint} has the total of {count} chars");
        }
        public static async Task <string> BasicObjects([OrchestrationTrigger] IDurableOrchestrationContext ctx)
        {
            var chatroom = ctx.GetInput <EntityId>();

            // signals
            ctx.SignalEntity(chatroom, "post", "a");
            ctx.SignalEntity(chatroom, "post", "b");

            // call returning a task, but no result
            await ctx.CallEntityAsync(chatroom, "post", "c");

            // calls returning a result
            var result = await ctx.CallEntityAsync <List <KeyValuePair <DateTime, string> > >(chatroom, "get");

            return(string.Join(",", result.Select(kvp => kvp.Value)));
        }
示例#11
0
        public static async Task RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var(userId, location) = context.GetInput <(string, int)>();

            var userEntity = new EntityId(nameof(UserEntity), userId);

            // first, update the user information to advertise the location.

            await context.CallEntityAsync(userEntity, nameof(UserEntity.SetLocation), location);

            // next, try to match this user with
            // someone who has already advertised their location in a nearby region

            var nearbyRegions = ZipCodes.GetProximityList(location);

            foreach (var region in nearbyRegions)
            {
                var regionProxy = context.CreateEntityProxy <IRegionEntity>(region.ToString());

                string[] candidates = await(userId.StartsWith("R") ? regionProxy.GetAvailableDrivers() : regionProxy.GetAvailableRiders());

                foreach (var candidate in candidates)
                {
                    if (await TryFinalizeMatch(userId, candidate, context))
                    {
                        return;
                    }
                }
            }

            // we could not find a match.
            // we will just wait until someone else finds us.
        }
示例#12
0
        public async Task SaveState([OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            (string nonce, string state) = context.GetInput <(string, string)>();

            EntityId nonceEntityId = new EntityId(nameof(Nonce), nonce);
            await context.CallEntityAsync(nonceEntityId, nameof(Nonce.SetState), state);
        }
        public static async Task <string> LargeEntity([OrchestrationTrigger] IDurableOrchestrationContext ctx)
        {
            var entityId = ctx.GetInput <EntityId>();

            string content = new string('.', 100000);
            await ctx.CallEntityAsync <int>(entityId, "set", content);

            var result = await ctx.CallEntityAsync <string>(entityId, "get");

            if (result != content)
            {
                return($"fail: wrong entity state");
            }

            return("ok");
        }
示例#14
0
        public async Task OrchestratorAsync(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var entity = new EntityId("EntityState", "global");

            using (await context.LockAsync(entity))
            {
                var lastId = await context.CallEntityAsync <long>(entity, "Get");

                var nextLastId = await context.CallActivityAsync <long>("TimerTrigger-Activity", lastId);

                if (lastId != nextLastId)
                {
                    await context.CallEntityAsync(entity, "Set", nextLastId);
                }
            }
        }
        public static async Task SignalAndCallChatRoom([OrchestrationTrigger] IDurableOrchestrationContext ctx)
        {
            var entity = new EntityId("ChatRoom", "myChat");

            ctx.SignalEntity(entity, "Post", "Hello World");

            var result = await ctx.CallEntityAsync <List <KeyValuePair <DateTime, string> > >(entity, "Get");
        }
示例#16
0
        public async Task Orchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var cIContext = context.GetInput <CIContext>();
            // Get issues
            SearchIssue issues = await context.CallActivityAsync <SearchIssue>(nameof(CreatePRReviewDecorator) + "_GetIssues", cIContext);

            // Get issues that already created
            var pullRequestState =
                await context.CallActivityAsync <PullRequestState>("PullRequestStateUtility_GetPullRequestState", new PullRequestStateKey
            {
                PartitionKey = _repositoryContext.GetFullNameWithUnderscore(),
                RowKey       = cIContext.PullRequestId
            });

            string entityId = pullRequestState?.EntityId ?? context.NewGuid().ToString();
            EntityStateResponse <PullRequestStateContext> response =
                await context.CallActivityAsync <EntityStateResponse <PullRequestStateContext> >(
                    nameof(CreatePRReviewDecorator) + "_GetPullRequestStateContext", entityId);

            var pullRequestDetailContext = response.EntityState;

            pullRequestDetailContext = pullRequestDetailContext ?? new PullRequestStateContext()
            {
                PullRequestNumber = int.Parse(cIContext.PullRequestId)
            };

            var unCommentedIssue = issues.issues.Where(issue => !pullRequestDetailContext.CreatedReviewComment.Contains(new CreatedReviewComment()
            {
                IssueId = issue.key
            })).ToList();


            foreach (var issue in unCommentedIssue)
            {
                var issueContext           = (cIContext, issue);
                var createdPrReviewComment = await context.CallActivityAsync <JObject>(nameof(CreatePRReviewDecorator) + "_CreatePRReviewComment", issueContext);

                if (createdPrReviewComment != null)
                {
                    pullRequestDetailContext.Add(new CreatedReviewComment()
                    {
                        IssueId = issue.key, CommentId = (int)createdPrReviewComment["Id"], ProjectKey = cIContext.ProjectKey
                    });
                }
            }


            await context.CallEntityAsync <PullRequestStateContext>(new EntityId(nameof(PullRequestEntity), entityId), "update", pullRequestDetailContext);

            pullRequestState              = pullRequestState ?? new PullRequestState();
            pullRequestState.EntityId     = entityId;
            pullRequestState.PartitionKey = pullRequestState.PartitionKey ??
                                            _repositoryContext.Owner + "_" + _repositoryContext.Name;
            pullRequestState.RowKey = pullRequestState.RowKey ?? cIContext.PullRequestId;

            await context.CallActivityAsync("PullRequestStateUtility_CreateOrUpdatePullRequestState", pullRequestState);
        }
        public static async Task WaitingOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext ctx,
            ILogger log)
        {
            var orchestratorArgs = ctx.GetInput <OrchestratorArgs>();

            // Using an entity as a cache for the data of the device like
            // - OfflineAfter, static metadata, typically coming from a device registry (loaded during initialization of entity)
            // - LastMessageReceived, 'hot' data, not essential for current PoC but could be usefull later on
            var entity = new EntityId(nameof(DeviceEntity), orchestratorArgs.DeviceId);

            var offlineAfter = await ctx.CallEntityAsync <TimeSpan>(entity, "GetOfflineAfter");

            var lastActivity = await ctx.CallEntityAsync <DateTime?>(entity, "GetLastMessageReceived");

            if (!ctx.IsReplaying && (!lastActivity.HasValue || ctx.CurrentUtcDateTime - lastActivity > offlineAfter))
            {
                // This runs for the first message ever for a device id
                // Also, after a device has gone offline and comes back online, this orchestrator starts again Last Activity should then be longer ago then the offline after
                log.LogInformation($"Device {orchestratorArgs.DeviceId}, was unkown or offline and is now online!");
                await ctx.CallActivityAsync(nameof(SendStatusUpdate), new StatusUpdateArgs(orchestratorArgs.DeviceId, true));
            }

            try
            {
                await ctx.WaitForExternalEvent("MessageReceived", offlineAfter);

                if (!ctx.IsReplaying)
                {
                    log.LogInformation($"Message received for device {orchestratorArgs.DeviceId}, resetting timeout of {offlineAfter.TotalSeconds} seconds offline detection...");
                }
                ctx.ContinueAsNew(orchestratorArgs);
                return;
            }
            catch (TimeoutException)
            {
                if (!ctx.IsReplaying)
                {
                    log.LogWarning($"Device {orchestratorArgs.DeviceId}, is now offline after waiting for {offlineAfter.TotalSeconds} seconds");
                }
                await ctx.CallActivityAsync(nameof(SendStatusUpdate), new StatusUpdateArgs(orchestratorArgs.DeviceId, false));

                return;
            }
        }
示例#18
0
        public static async Task <string> DatabasePutOrchestratorAsync(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var operation = context.GetInput <WriteOperation>();

            EntityId id = new EntityId(nameof(Register), operation.Key);

            return(await context.CallEntityAsync <string>(id, "set", operation.Value));
        }
示例#19
0
        public static async Task <int> GetBalance(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var accountId = context.GetInput <string>();

            EntityId id = new EntityId(nameof(Account), accountId);

            return(await context.CallEntityAsync <int>(id, "balance"));
        }
示例#20
0
        public static async Task <string> Withdraw(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var accountOperation = context.GetInput <AccountOperation>();

            EntityId id = new EntityId(nameof(Account), accountOperation.AccountId);

            return(await context.CallEntityAsync <string>(id, "withdraw", accountOperation.Amount));
        }
示例#21
0
        public static async Task <string> DatabaseGetOrchestratorAsync(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var key = context.GetInput <string>();

            EntityId id = new EntityId(nameof(Register), key);

            return(await context.CallEntityAsync <string>(id, "get"));
        }
        public static async Task <string> LaunchOrchestrationFromEntity([OrchestrationTrigger] IDurableOrchestrationContext ctx)
        {
            var entityId = new EntityId("Launcher", ctx.NewGuid().ToString());

            await ctx.CallEntityAsync(entityId, "launch", "hello");

            while (true)
            {
                var orchestrationId = await ctx.CallEntityAsync <string>(entityId, "get");

                if (orchestrationId != null)
                {
                    return(orchestrationId);
                }

                await ctx.CreateTimer(DateTime.UtcNow + TimeSpan.FromSeconds(1), CancellationToken.None);
            }
        }
示例#23
0
        public static async Task RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            VMInfo   input = context.GetInput <VMInfo>();
            EntityId id    = new EntityId("VM", input.VMId);

            await context.CallEntityAsync(id, input.Action, input.Hour);

            return;
        }
        public static async Task ProjectCommandSerializationOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context,
            ILogger log)
        {
            if (context is null)
            {
                throw new ArgumentNullException(nameof(context));
            }

            var command = context.GetInput <ICommand>();

            if (command.ProjectId.HasValue)
            {
                var commandEntityId     = new EntityId(nameof(ProjectCommandSerializationEntity), command.ProjectId.ToString());
                var commandDependencyId = default(string);

                using (await context.LockAsync(commandEntityId).ConfigureAwait(true))
                {
                    // register the new command is a critical section and needs a lock
                    // if there's an dependency it's guid is returned; otherwise null

                    commandDependencyId = await context
                                          .CallEntityAsync <string>(commandEntityId, null, command)
                                          .ConfigureAwait(true);
                }

                if (Guid.TryParse(commandDependencyId, out var correlationId))
                {
                    var notification = new ProjectCommandNotification()
                    {
                        InstanceId    = context.InstanceId,
                        CorrelationId = correlationId
                    };

                    var waitForExternalEvent = await context
                                               .CallActivityAsync <bool>(nameof(ProjectCommandSerializationActivity), notification)
                                               .ConfigureAwait(true);

                    if (waitForExternalEvent)
                    {
                        context
                        .CreateReplaySafeLogger(log)
                        .LogWarning($"{notification.InstanceId} - Waiting for command {notification.CorrelationId}");

                        await context
                        .WaitForExternalEvent(notification.CorrelationId.ToString())
                        .ConfigureAwait(true);

                        context
                        .CreateReplaySafeLogger(log)
                        .LogWarning($"{notification.InstanceId} - Resuming");
                    }
                }
            }
        }
示例#25
0
        public static async Task <Status> RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext ctx)
        {
            var actArgs = ctx.GetInput <ExecuteActionArguments>();

            var entityId = new EntityId(typeof(ReportingManagementState).Name, actArgs.StateDetails.Username);

            await ctx.CallEntityAsync <object>(entityId, "SavePowerBIConnection", actArgs.ActionRequest);

            return(Status.Success);
        }
示例#26
0
        public async Task <bool> IsExecutionPermitted(string breakerId, ILogger log, IDurableOrchestrationContext orchestrationContext)
        {
            if (string.IsNullOrEmpty(breakerId))
            {
                throw new ArgumentNullException($"{nameof(breakerId)}");
            }

            log?.LogCircuitBreakerMessage(breakerId, $"Asking IsExecutionPermitted (consistency priority) for circuit-breaker = '{breakerId}'.");

            return(await orchestrationContext.CallEntityAsync <bool>(DurableCircuitBreakerEntity.GetEntityId(breakerId), DurableCircuitBreakerEntity.Operation.IsExecutionPermitted));
        }
        public static async Task RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            EntityId id = new EntityId(nameof(Entity), "key");

            // Signal an entity
            context.SignalEntity(id, "MyOperation", "helloSignal");

            // Call an entity
            await context.CallEntityAsync(id, "MyOperation", "helloCall");
        }
示例#28
0
        public static async Task RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext ctx,
            ILogger log)
        {
            var delayTimeSpan = ctx.GetInput <TimeSpan>();
            var maxRetries    = 10;
            var count         = 0;

            // The following loop will execute for as long as the garage door remains open
            // up to max number of retries.
            while (true)
            {
                DateTime timer = ctx.CurrentUtcDateTime.Add(delayTimeSpan);
                log.LogInformation($"Setting timer to expire at {timer.ToLocalTime()}");
                await ctx.CreateTimer(timer, CancellationToken.None);

                log.LogInformation("Timer fired!");

                try
                {
                    using (await ctx.LockAsync(EntityId))
                    {
                        log.LogInformation("Entity lock acquired.");
                        var currentState = await ctx.CallEntityAsync <string>(EntityId, "read", null);

                        log.LogInformation($"Current state is {currentState}.");
                        // If the door is closed already, then don't do anything.
                        if (currentState.ToLowerInvariant() == "closed")
                        {
                            log.LogInformation("Looks like the door was already closed. Will skip sending text message.");
                            break;
                        }
                        await ctx.CallActivityAsync("SendTextMessage", null);
                    }
                }
                catch (LockingRulesViolationException ex)
                {
                    log.LogError(ex, "Failed to lock/call the entity.");
                }
                catch (Exception ex)
                {
                    log.LogError(ex, "Unexpected exception occurred.");
                }

                if (count >= maxRetries)
                {
                    log.LogInformation("Reached max retry count, but the garage door is still open. Will stop checking now.");
                    break;
                }
                log.LogInformation("Door is still open. Will schedule another timer to check again.");
                count++;
            }
        }
示例#29
0
        public async Task Orchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var commandHookContext = context.GetInput <CommandHookContext>();

            var response = await context.CallActivityAsync <EntityStateResponse <PullRequestStateContext> >(nameof(PullRequestEntity) + "_GetPullRequestStateContext", commandHookContext.PullRequestUri.GetEntityId());

            // Ignore if the Decoration has not finished.
            if (response.EntityExists)
            {
                PullRequestStateContext pullRequestStateContext = response.EntityState;
                switch (CommandRouter.GetValueOrDefault(commandHookContext.Command))
                {
                case CommandRouter.CreateWorkItemCommand:
                    // GetIssue that match Scan Provider. You can find the ScanProvider from response.
                    await CreateWorkItem(context, pullRequestStateContext, commandHookContext);

                    break;

                case CommandRouter.IssueTransitionCommand:
                    await TransitIssueAsync(context, pullRequestStateContext, commandHookContext);

                    break;

                default:
                    // Create Sorry Comment
                    await context.CallActivityAsync(nameof(CommandOrchestrator) + "_" + BotConfiguration.RepositoryProvider +
                                                    "_CreateSimpleReplyComment", new CreateSimpleReplyCommentContext()
                    {
                        Body          = $"Command [{commandHookContext.Command}] hasn't been supported. Ask bot administrator.",
                        InReplyTo     = commandHookContext.ReplyToId,
                        PullRequestId = commandHookContext.PullRequestId
                    });

                    break;
                }
                // Update the CurrentPullRequestStatus
                await context.CallEntityAsync <PullRequestStateContext>(
                    new EntityId(nameof(PullRequestEntity), commandHookContext.PullRequestUri.GetEntityId()), "update",
                    pullRequestStateContext);
            }
            else
            {
                await context.CallActivityAsync(nameof(CommandOrchestrator) + "_" + BotConfiguration.RepositoryProvider +
                                                "_CreateSimpleReplyComment", new CreateSimpleReplyCommentContext()
                {
                    Body          = "Security Decoration seems not finished. Wait until the PullRequest validation CI has done.",
                    InReplyTo     = commandHookContext.ReplyToId,
                    PullRequestId = commandHookContext.PullRequestId
                });
            }
        }
示例#30
0
        public async Task <List <string> > RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            var outputs = new List <string>();

            // Get Parent Info
            // Ask the entity or StorageAccount if there is duplication
            // Create a work item

            var comment = context.GetInput <PRCommentCreated>();

            // Get the parent review comment
            // PullRequestReviewComment can't deserialize.
            var parentReviewComment = await context.CallActivityAsync <JObject>(nameof(CommandBaseCommand) + "_GetParentReview", comment);

            // Get the State of the PullRequestState
            var pullRequestState =
                await context.CallActivityAsync <PullRequestState>("PullRequestStateUtility_GetPullRequestState", new PullRequestStateKey {
                PartitionKey = comment.repository.full_name.ToPartitionKey(),
                RowKey       = comment.pull_request.number.ToString()
            });

            // Ask the entity has duplication
            string entityId = pullRequestState?.EntityId ?? context.NewGuid().ToString();
            EntityStateResponse <PullRequestStateContext> response =
                await context.CallActivityAsync <EntityStateResponse <PullRequestStateContext> >(
                    nameof(CommandBaseCommand) + "_GetPullRequestStateContext", entityId);

            var pullRequestDetailContext = response.EntityState;

            // If you don't start CI however, already have a work item comment. (maybe it is rare case)
            pullRequestDetailContext = pullRequestDetailContext ?? new PullRequestStateContext();

            // create a work item
            pullRequestDetailContext = await ExecuteAsync(context, pullRequestDetailContext, comment, parentReviewComment, new EntityId(nameof(PullRequestEntity), entityId));

            // update Entity

            await context.CallEntityAsync <PullRequestStateContext>(
                new EntityId(nameof(PullRequestEntity), entityId), "update", pullRequestDetailContext);

            // update Status.

            pullRequestState              = pullRequestState ?? new PullRequestState();
            pullRequestState.EntityId     = entityId;
            pullRequestState.PartitionKey = pullRequestState.PartitionKey ?? comment.repository.full_name.ToPartitionKey();
            pullRequestState.RowKey       = pullRequestState.RowKey ?? comment.pull_request.number.ToString();

            await context.CallActivityAsync("PullRequestStateUtility_CreateOrUpdatePullRequestState", pullRequestState);

            return(outputs);
        }