Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion api/messages.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,23 @@ message PingResponse {
bool IsSuccessful = 1;
}

message CreateWorldRequest {
int32 SizeX = 1;
int32 SizeY = 2;
repeated Bot Bots = 3;
}

message CreateWorldResponse {
string MapId = 1;
}

message GetBotsRequest {
string MapId = 1;
}

message GetBotsResponse {
repeated Bot Bots = 1;
string MapId = 1;
repeated Bot Bots = 2;
}

message SelectBotRequest {
Expand Down
3 changes: 2 additions & 1 deletion api/pathfinder.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ import "messages.proto";
import "google/protobuf/empty.proto";

service PathfinderService {
rpc CreateWorld(pathfinder.messages.CreateWorldRequest) returns(pathfinder.messages.CreateWorldResponse);
rpc Ping(google.protobuf.Empty) returns(pathfinder.messages.PingResponse);
rpc GetBots(google.protobuf.Empty) returns(pathfinder.messages.GetBotsResponse);
rpc GetBots(pathfinder.messages.GetBotsRequest) returns(pathfinder.messages.GetBotsResponse);
rpc SelectBot(pathfinder.messages.SelectBotRequest) returns(pathfinder.messages.SelectBotResponse);
rpc ResetBot(pathfinder.messages.ResetBotRequest) returns(pathfinder.messages.ResetBotResponse);
rpc SendMessage(stream pathfinder.messages.SendMessageRequest) returns (stream pathfinder.messages.SendMessageResponse);
Expand Down
6 changes: 6 additions & 0 deletions cd/stage/docker-compose.local.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
nasa-server:
image: ghcr.io/karmeev/mars-pathfinder:stage
container_name: nasa-server
ports:
- "5000:5000"
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public async Task<bool> PingAsync()

public async Task<IEnumerable<Bot>> GetBotsAsync()
{
var response = await grpcService.GetBotsAsync(new Empty(), GetHeader());
var response = await grpcService.GetBotsAsync(new GetBotsRequest{MapId = "1"}, GetHeader());

return response.Bots.Select(bot => new Bot
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,25 @@ internal class BotConsumer(
{
public async Task Consume(MoveCommand command, CancellationToken ct = default)
{
var project = await worldMap.TryReachPosition(command.Bot.MapId, command.DesiredPosition, ct);
var project = await worldMap.ReachPosition(command.Bot.MapId, command.Bot.Position, command.OperatorCommands , ct);

if (project is PositionNotChanged)
{
var stand = new StandCommand(command.ClientId, command.Bot.Id, command.Bot.Position, command.CorrelationId);
var stand = new StandCommand(command.ClientId, command.Bot.Id, project.Position,
command.CorrelationId);
processor.Publish(stand);
return;
}

if (project is PositionOutOfMap)
if (project is PositionOutOfMap outOfMap)
{
var lost = new DeadCommand(command.ClientId, command.Bot.Id, command.DesiredPosition, command.Bot.MapId,
command.Bot.LastWords, command.CorrelationId);
var lost = new DeadCommand(command.ClientId, command.Bot.Id, command.Bot.MapId,
outOfMap.Previous, command.CorrelationId);
processor.Publish(lost);
return;
}

var walk = new WalkCommand(command.ClientId, command.Bot.Id, command.DesiredPosition,
var walk = new WalkCommand(command.ClientId, command.Bot.Id, project.Position,
command.CorrelationId);
processor.Publish(walk);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ internal class BotDeadWalkerConsumer(
public async Task Consume(DeadCommand command, CancellationToken ct = default)
{
await botRepository.ChangeBotStatusAsync(command.BotId, BotStatus.Dead, ct);
await botRepository.ChangeBotPositionAsync(command.BotId, command.DesiredPosition, ct);
await botRepository.ChangeBotPositionAsync(command.BotId, command.CurrentPosition, ct);

var funeral = new Funeral
{
Id = Guid.CreateVersion7().ToString(),
ETag = Guid.NewGuid(),
Value = command.DesiredPosition,
Value = command.CurrentPosition,
MapId = command.MapId,
};
await funeralRepository.AddNewFuneral(funeral, ct);
var notificationText = messageDecoder.EncodeBotMessage(command.DesiredPosition, true);
var notificationText = messageDecoder.EncodeBotMessage(command.CurrentPosition, true);
var request = new SendMessageRequest(command.ClientId, command.BotId, notificationText, true,
false, command.LastWords);
false);
processor.SendMessage(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ internal class BotInvalidCommandConsumer(IOperatorProcessor processor) : IBotCon
public Task Consume(InvalidCommand command, CancellationToken ct = default)
{
var request = new SendMessageRequest(command.ClientId, command.BotId, command.Message, true,
true, string.Empty);
true);

processor.SendMessage(request);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public async Task Consume(StandCommand command, CancellationToken ct = default)
{
var notificationText = messageDecoder.EncodeBotMessage(command.CurrentPosition, false);
var request = new SendMessageRequest(command.ClientId, command.BotId, notificationText, false,
false, string.Empty);
false);
processor.SendMessage(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ internal class BotWalkerConsumer(
{
public async Task Consume(WalkCommand command, CancellationToken ct = default)
{
await repository.ChangeBotPositionAsync(command.BotId, command.DesiredPosition, ct);
var notificationText = messageDecoder.EncodeBotMessage(command.DesiredPosition, false);
await repository.ChangeBotPositionAsync(command.BotId, command.CurrentPosition, ct);
var notificationText = messageDecoder.EncodeBotMessage(command.CurrentPosition, false);
var request = new SendMessageRequest(command.ClientId, command.BotId, notificationText, false,
false, string.Empty);
false);
processor.SendMessage(request);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@ namespace Nasa.Pathfinder.Data.Contracts.Repositories;

public interface IBotRepository
{
Task AddRangeAsync(IEnumerable<Bot> bots, CancellationToken ct = default);
Task<Bot?> TryGetAsync(string botId, CancellationToken ct = default);
Task<IEnumerable<Bot>> GetBotsAsync(CancellationToken ct = default);
Task<IEnumerable<Bot>> GetBotsAsync(string mapId, CancellationToken ct = default);
Task<Bot?> ChangeBotStatusAsync(string botId, BotStatus status, CancellationToken ct = default);
Task ChangeBotPositionAsync(string botId, Position position, CancellationToken ct = default);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ namespace Nasa.Pathfinder.Data.Contracts.Repositories;
public interface IMapRepository
{
Task<MapInfo?> TryGetAsync(string id, CancellationToken ct = default);
Task<MapInfo> AddAsync(MapInfo map, CancellationToken ct = default);
}
22 changes: 20 additions & 2 deletions src/nasa-server/src/Nasa.Pathfinder.Data/Internal/BotRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,33 @@ namespace Nasa.Pathfinder.Data.Internal;

internal class BotRepository(IDataContext dataContext) : IBotRepository
{
public async Task AddRangeAsync(IEnumerable<Bot> bots, CancellationToken ct = default)
{
await dataContext.AcquireAsync<Bot>("all", ct);
try
{
foreach (var bot in bots)
{
bot.ETag = Guid.NewGuid();
}

await dataContext.PushManyAsync(bots, ct);
}
finally
{
await dataContext.ReleaseAsync<Bot>("all", CancellationToken.None);
}
}

public async Task<Bot?> TryGetAsync(string botId, CancellationToken ct = default)
{
return await dataContext.GetAsync<Bot>(botId, ct);
}

public async Task<IEnumerable<Bot>> GetBotsAsync(CancellationToken ct = default)
public async Task<IEnumerable<Bot>> GetBotsAsync(string mapId, CancellationToken ct = default)
{
var bots = await dataContext.GetAllAsync<Bot>(ct);
return bots;
return bots.Where(x => x.MapId == mapId);
}

public async Task<Bot?> ChangeBotStatusAsync(string botId, BotStatus status, CancellationToken ct = default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,13 @@ internal class MapRepository(IDataContext context) : IMapRepository
{
return await context.GetAsync<MapInfo>(id, ct);
}

public async Task<MapInfo> AddAsync(MapInfo map, CancellationToken ct = default)
{
map.Id = Guid.NewGuid().ToString();
map.ETag = Guid.NewGuid();

await context.PushAsync(map, ct);
return map;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,4 @@ public class Bot : IEntity
public BotStatus Status { get; set; }
public Position Position { get; set; }
public string MapId { get; set; }
public string LastWords { get; set; }
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using Nasa.Pathfinder.Domain.Bots;
using Nasa.Pathfinder.Domain.Entities.Bots;
using Nasa.Pathfinder.Domain.World;

Expand All @@ -12,13 +11,13 @@ public interface IBotCommand
public record MoveCommand(
string ClientId,
Bot Bot,
Position DesiredPosition,
Stack<IOperatorCommand> OperatorCommands,
Guid CorrelationId = default) : IBotCommand;

public record WalkCommand(
string ClientId,
string BotId,
Position DesiredPosition,
Position CurrentPosition,
Guid CorrelationId = default) : IBotCommand;

public record StandCommand(
Expand All @@ -30,9 +29,8 @@ public record StandCommand(
public record DeadCommand(
string ClientId,
string BotId,
Position DesiredPosition,
string MapId,
string LastWords,
Position CurrentPosition,
Guid CorrelationId = default) : IBotCommand;

public record InvalidCommand(
Expand Down
22 changes: 12 additions & 10 deletions src/nasa-server/src/Nasa.Pathfinder.Domain/World/PositionProject.cs
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
namespace Nasa.Pathfinder.Domain.World;

public interface IPositionProject
{ }
{
public Position Position { get; }
}

public record PositionChanged : IPositionProject;
public record PositionNotChanged : IPositionProject;
public record PositionOutOfMap : IPositionProject;
public record PositionChanged(Position Position) : IPositionProject;
public record PositionNotChanged(Position Position) : IPositionProject;
public record PositionOutOfMap(Position Position, Position Previous) : IPositionProject;

public static class PositionProject
{
public static IPositionProject Changed()
public static IPositionProject Changed(Position position)
{
return new PositionChanged();
return new PositionChanged(position);
}

public static IPositionProject NotChanged()
public static IPositionProject NotChanged(Position position)
{
return new PositionNotChanged();
return new PositionNotChanged(position);
}

public static IPositionProject OutOfMap()
public static IPositionProject OutOfMap(Position position, Position previous)
{
return new PositionOutOfMap();
return new PositionOutOfMap(position, previous);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
using Nasa.Pathfinder.Domain.Bots;
using System.Numerics;
using Nasa.Pathfinder.Domain.Entities.Bots;

namespace Nasa.Pathfinder.Facades.Contracts;

public interface IBotFacade
{
Task<IEnumerable<Bot>> GetBotsAsync(CancellationToken ct = default);
Task<string> CreateWorldAsync(Vector2 coordinates, IEnumerable<Bot> bots, CancellationToken ct = default);
Task<IEnumerable<Bot>> GetBotsAsync(string mapId, CancellationToken ct = default);
Task<Bot?> SelectBotAsync(string botId, CancellationToken ct = default);
Task<Bot?> ResetBotAsync(string botId, CancellationToken ct = default);
}
29 changes: 26 additions & 3 deletions src/nasa-server/src/Nasa.Pathfinder.Facades/Internal/BotFacade.cs
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
using System.Numerics;
using Nasa.Pathfinder.Data.Contracts.Exceptions;
using Nasa.Pathfinder.Data.Contracts.Repositories;
using Nasa.Pathfinder.Domain.Bots;
using Nasa.Pathfinder.Domain.Entities.Bots;
using Nasa.Pathfinder.Domain.Entities.World;
using Nasa.Pathfinder.Facades.Contracts;
using Nasa.Pathfinder.Facades.Contracts.Exceptions;

namespace Nasa.Pathfinder.Facades.Internal;

internal class BotFacade(IBotRepository repository) : IBotFacade
internal class BotFacade(
IBotRepository repository,
IMapRepository mapRepository) : IBotFacade
{
public async Task<IEnumerable<Bot>> GetBotsAsync(CancellationToken ct = default)
public async Task<string> CreateWorldAsync(Vector2 coordinates, IEnumerable<Bot> bots, CancellationToken ct = default)
{
var map = new MapInfo
{
SizeX = (int)coordinates.X,
SizeY = (int)coordinates.Y,
};
var createdMap = await mapRepository.AddAsync(map, ct);

foreach (var bot in bots)
{
bot.MapId = createdMap.Id;
}

await repository.AddRangeAsync(bots.ToList(), ct);

return createdMap.Id;
}

public async Task<IEnumerable<Bot>> GetBotsAsync(string mapId, CancellationToken ct = default)
{
try
{
var bots = await repository.GetBotsAsync(ct);
var bots = await repository.GetBotsAsync(mapId, ct);
return bots;
}
catch (Exception ex) when (ex is OperationCanceledException)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ namespace Nasa.Pathfinder.Facades.Internal;
internal class MessageFacade(
IBotRepository repository,
IMessageDecoderService messageDecoder,
IWorldMapService worldMap,
IBotProcessor processor) : IMessageFacade
{
public async Task ReceiveMessageAsync(IMessage message, CancellationToken ct = default)
Expand All @@ -37,9 +36,7 @@ public async Task ReceiveMessageAsync(IMessage message, CancellationToken ct = d
}

var bot = await repository.TryGetAsync(operatorMessage.BotId, ct);

var desiredPosition = worldMap.CalculateDesiredPosition(bot.Position, commands);

processor.Publish(new MoveCommand(operatorMessage.ClientId, bot, desiredPosition, correlationId));

processor.Publish(new MoveCommand(operatorMessage.ClientId, bot, commands, correlationId));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Nasa.Pathfinder.Infrastructure.Contracts.DataContexts;
public interface IDataContext
{
Task PushAsync<T>(T entry, CancellationToken ct = default) where T : class, IEntity;
Task PushManyAsync<T>(IEnumerable<T> entry, CancellationToken ct = default) where T : class, IEntity;
Task<ErrorOr<T>> UpdateAsync<T>(T entry, CancellationToken ct = default) where T : class, IEntity;
Task<T?> GetAsync<T>(string id, CancellationToken ct = default) where T : class, IEntity;
Task<List<T>> GetAllAsync<T>(CancellationToken ct = default);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@ public record SendMessageRequest(
string BotId,
string Message,
bool IsLost,
bool IsInvalidCommand,
string LastWords);
bool IsInvalidCommand);
Loading
Loading