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)); }
/// <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) ); }
/// <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); }