public async Task ShouldExecuteCommandButNotReplyIfShouldNotReplyImmediately(
                string content,
                Snowflake userId,
                Snowflake channelId,
                UserId identityUserId,
                [Frozen] Command command,
                [Frozen] ExecuteCommandResponse executeCommandResponse,
                [Frozen, Substitute] IMessageEmitter emitter,
                [Frozen, Substitute] IBrighidCommandsService commandsClient,
                [Frozen, Substitute] IDiscordChannelClient channelClient,
                [Frozen, Substitute] IUserService userService,
                [Target] MessageCreateEventController controller
                )
            {
                var cancellationToken = new CancellationToken(false);
                var author            = new User {
                    Id = userId
                };
                var message = new Message {
                    Content = content, Author = author, ChannelId = channelId
                };
                var @event = new MessageCreateEvent {
                    Message = message
                };

                executeCommandResponse.ReplyImmediately = false;
                userService.GetIdentityServiceUserId(Any <User>(), Any <CancellationToken>()).Returns(identityUserId);
                userService.IsUserRegistered(Any <User>(), Any <CancellationToken>()).Returns(true);

                await controller.Handle(@event, cancellationToken);

                await channelClient.DidNotReceive().CreateMessage(Is(channelId), Is <CreateMessagePayload>(payload => payload.Content == executeCommandResponse.Response), Is(cancellationToken));
            }
Exemple #2
0
        /// <summary>
        /// Unmarshaller the response from the service to the response class.
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override AmazonWebServiceResponse Unmarshall(JsonUnmarshallerContext context)
        {
            ExecuteCommandResponse response = new ExecuteCommandResponse();

            context.Read();
            int targetDepth = context.CurrentDepth;

            while (context.ReadAtDepth(targetDepth))
            {
                if (context.TestExpression("clusterArn", targetDepth))
                {
                    var unmarshaller = StringUnmarshaller.Instance;
                    response.ClusterArn = unmarshaller.Unmarshall(context);
                    continue;
                }
                if (context.TestExpression("containerArn", targetDepth))
                {
                    var unmarshaller = StringUnmarshaller.Instance;
                    response.ContainerArn = unmarshaller.Unmarshall(context);
                    continue;
                }
                if (context.TestExpression("containerName", targetDepth))
                {
                    var unmarshaller = StringUnmarshaller.Instance;
                    response.ContainerName = unmarshaller.Unmarshall(context);
                    continue;
                }
                if (context.TestExpression("interactive", targetDepth))
                {
                    var unmarshaller = BoolUnmarshaller.Instance;
                    response.Interactive = unmarshaller.Unmarshall(context);
                    continue;
                }
                if (context.TestExpression("session", targetDepth))
                {
                    var unmarshaller = SessionUnmarshaller.Instance;
                    response.Session = unmarshaller.Unmarshall(context);
                    continue;
                }
                if (context.TestExpression("taskArn", targetDepth))
                {
                    var unmarshaller = StringUnmarshaller.Instance;
                    response.TaskArn = unmarshaller.Unmarshall(context);
                    continue;
                }
            }

            return(response);
        }
            public async Task ShouldReplyWithTraceIdIfUserHasDebugModeEnabled(
                string content,
                Snowflake userId,
                Snowflake channelId,
                [Frozen] Command command,
                [Frozen] TraceContext traceContext,
                [Frozen] ExecuteCommandResponse executeCommandResponse,
                [Frozen, Substitute] IMessageEmitter emitter,
                [Frozen, Substitute] IBrighidCommandsService commandsClient,
                [Frozen, Substitute] IDiscordChannelClient channelClient,
                [Frozen, Substitute] IUserService userService,
                [Target] MessageCreateEventController controller
                )
            {
                var cancellationToken = new CancellationToken(false);
                var author            = new User {
                    Id = userId
                };
                var message = new Message {
                    Content = content, Author = author, ChannelId = channelId
                };
                var @event = new MessageCreateEvent {
                    Message = message
                };
                var identityUserId = new UserId(Guid.NewGuid(), true, true);

                executeCommandResponse.ReplyImmediately = true;
                userService.GetIdentityServiceUserId(Any <User>(), Any <CancellationToken>()).Returns(identityUserId);
                userService.IsUserRegistered(Any <User>(), Any <CancellationToken>()).Returns(true);

                await controller.Handle(@event, cancellationToken);

                await channelClient.Received().CreateMessage(
                    Is(channelId),
                    Is <CreateMessagePayload>(payload =>
                                              payload.Embed !.Value.Fields.Any(field => field.Name == "TraceId" && field.Value == traceContext.Id)
                                              ),
                    Is(cancellationToken)
                    );
            }
Exemple #4
0
        /// <summary>
        /// Execute command
        /// </summary>
        /// <param name="command"></param>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public async Task <ExecuteCommandResponse> ExecuteCommandAsync <T>(T command)
        {
            await _nodeLock.WaitAsync();

            var response = new ExecuteCommandResponse(null, false, "Unknown error");

            switch (Role)
            {
            case NodeRole.Follower:
                if (string.IsNullOrEmpty(_leaderId))
                {
                    response = new ExecuteCommandResponse(null, false, "No leader found");
                    _nodeLock.Release();
                }
                else
                {
                    var leaderNode = _cluster.Nodes?.FirstOrDefault(f => f.Id == _leaderId);
                    if (leaderNode == null)
                    {
                        response = new ExecuteCommandResponse(null, false, $"Leader {_leaderId} not found in cluster");
                        _nodeLock.Release();
                    }
                    else
                    {
                        _nodeLock.Release();
                        response = await leaderNode.ExecuteCommandAsync(command);
                    }
                }
                break;

            case NodeRole.Candidate:
                response = new ExecuteCommandResponse(null, false, $"Candidate couldn't execute command");
                _nodeLock.Release();
                break;

            case NodeRole.Leader:
                if (_cluster.IsSingleNodeCluster())
                {
                    var commandData = _commandSerializer.Serialize(command.GetType(), command);
                    var newLogEntry = new LogEntry(commandData.typeName, commandData.data, State.CurrentTerm);
                    await _log.AppendAsync(newLogEntry);

                    var executeResult = await _stateMachine.HandleAsync(newLogEntry);

                    response = new ExecuteCommandResponse(executeResult, true, null);
                    var lastTermAndIndex = await _log.GetLastTermAndIndexAsync();

                    State.SetCommitIndexAndLastApplied(lastTermAndIndex.index);
                    _nodeLock.Release();
                }
                else
                {
                    var commandData = _commandSerializer.Serialize(command.GetType(), command);
                    var newLogEntry = new LogEntry(commandData.typeName, commandData.data, State.CurrentTerm);
                    await _log.AppendAsync(newLogEntry);

                    var executeResult = await _stateMachine.HandleAsync(newLogEntry);

                    response = new ExecuteCommandResponse(executeResult, true, null);
                    var lastTermAndIndex = await _log.GetLastTermAndIndexAsync();

                    State.SetCommitIndexAndLastApplied(lastTermAndIndex.index);
                    _nodeLock.Release();
                    // If command received from client: append entry to local log, respond after entry applied to state machine (§5.3)
                    //TODO: Replicated log to followers.
                }
                break;
            }
            return(response);
        }