diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 00000000..3729ff0c
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,25 @@
+**/.classpath
+**/.dockerignore
+**/.env
+**/.git
+**/.gitignore
+**/.project
+**/.settings
+**/.toolstarget
+**/.vs
+**/.vscode
+**/*.*proj.user
+**/*.dbmdl
+**/*.jfm
+**/azds.yaml
+**/bin
+**/charts
+**/docker-compose*
+**/Dockerfile*
+**/node_modules
+**/npm-debug.log
+**/obj
+**/secrets.dev.yaml
+**/values.dev.yaml
+LICENSE
+README.md
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..a49cfb28
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,21 @@
+################################################################################
+# Este arquivo .gitignore foi criado automaticamente pelo Microsoft(R) Visual Studio.
+################################################################################
+
+/.vs
+/src/building blocks/Wappa.Core/bin/Debug/netcoreapp3.1
+/src/building blocks/Wappa.Core/obj
+/src/services/Wappa.Motorista.API/bin/Debug/netcoreapp3.1
+/src/services/Wappa.Motorista.API/obj
+/obj
+/bin/Debug
+/src/services/Wappa.Motoristas.API/obj/Docker
+/src/building blocks/Wappa.MessageBus/obj
+/src/building blocks/Wappa.MessageBus/bin/Debug/netcoreapp3.1
+/src/services/Wappa.Geolocalizacao.API/bin/Debug/netcoreapp3.1
+/src/services/Wappa.Geolocalizacao.API/obj
+/src/services/Wappa.CoordenadasGeograficas.API/bin/Debug/netcoreapp3.1
+/src/services/Wappa.CoordenadasGeograficas.API/obj
+/src/building blocks/Wappa.WebAPI.Core/bin/Debug/netcoreapp3.1
+/src/building blocks/Wappa.WebAPI.Core/obj
+/src/services/Wappa.Motorista.API/bin/Debug
diff --git a/Wappa.sln b/Wappa.sln
new file mode 100644
index 00000000..fd81d85a
--- /dev/null
+++ b/Wappa.sln
@@ -0,0 +1,81 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30804.86
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Building Blocks", "Building Blocks", "{DC4A0A94-B314-410C-803D-95E4A3F5C0FA}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{D7CC5A53-341D-41FD-9A24-0BD3C5569258}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Core", "Core", "{C5A6B0DC-3A32-46A4-858D-73410D1A81E9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wappa.Core", "src\building blocks\Wappa.Core\Wappa.Core.csproj", "{F1EF41B4-CA77-4B64-8C64-8AA0E16626A1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Motorista", "Motorista", "{545ADEF2-79F6-4825-97A7-AD34D64A94EC}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wappa.Motoristas.API", "src\services\Wappa.Motorista.API\Wappa.Motoristas.API.csproj", "{9AB883F8-6E98-41BF-87A0-F7AA0B0F3C60}"
+EndProject
+Project("{E53339B2-1760-4266-BCC7-CA923CBCF16C}") = "docker-compose", "docker-compose.dcproj", "{496BCAED-C350-4AD3-AEDE-5810E67E724C}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MessageBus", "MessageBus", "{C94A4B68-ABAF-4566-8E42-3D603870A4F2}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Wappa.MessageBus", "src\building blocks\Wappa.MessageBus\Wappa.MessageBus.csproj", "{D4975541-0CC6-493B-90B2-AB3757D2A1B2}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Coordenadas Geograficas", "Coordenadas Geograficas", "{951C0702-1109-463A-8FB3-276221ADB711}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wappa.CoordenadasGeograficas.API", "src\services\Wappa.CoordenadasGeograficas.API\Wappa.CoordenadasGeograficas.API.csproj", "{B6B9227F-7CBE-426E-90C6-53D015B86357}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Services", "Services", "{DC09A6A3-F2B1-48A3-B3ED-268E650A7EB0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Wappa.WebAPI.Core", "src\building blocks\Wappa.WebAPI.Core\Wappa.WebAPI.Core.csproj", "{8155999B-3EB8-44D2-BA43-86C97F42AE38}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F1EF41B4-CA77-4B64-8C64-8AA0E16626A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F1EF41B4-CA77-4B64-8C64-8AA0E16626A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F1EF41B4-CA77-4B64-8C64-8AA0E16626A1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F1EF41B4-CA77-4B64-8C64-8AA0E16626A1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9AB883F8-6E98-41BF-87A0-F7AA0B0F3C60}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9AB883F8-6E98-41BF-87A0-F7AA0B0F3C60}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9AB883F8-6E98-41BF-87A0-F7AA0B0F3C60}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9AB883F8-6E98-41BF-87A0-F7AA0B0F3C60}.Release|Any CPU.Build.0 = Release|Any CPU
+ {496BCAED-C350-4AD3-AEDE-5810E67E724C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {496BCAED-C350-4AD3-AEDE-5810E67E724C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {496BCAED-C350-4AD3-AEDE-5810E67E724C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {496BCAED-C350-4AD3-AEDE-5810E67E724C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D4975541-0CC6-493B-90B2-AB3757D2A1B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D4975541-0CC6-493B-90B2-AB3757D2A1B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D4975541-0CC6-493B-90B2-AB3757D2A1B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D4975541-0CC6-493B-90B2-AB3757D2A1B2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B6B9227F-7CBE-426E-90C6-53D015B86357}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B6B9227F-7CBE-426E-90C6-53D015B86357}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B6B9227F-7CBE-426E-90C6-53D015B86357}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B6B9227F-7CBE-426E-90C6-53D015B86357}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8155999B-3EB8-44D2-BA43-86C97F42AE38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8155999B-3EB8-44D2-BA43-86C97F42AE38}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8155999B-3EB8-44D2-BA43-86C97F42AE38}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8155999B-3EB8-44D2-BA43-86C97F42AE38}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {C5A6B0DC-3A32-46A4-858D-73410D1A81E9} = {DC4A0A94-B314-410C-803D-95E4A3F5C0FA}
+ {F1EF41B4-CA77-4B64-8C64-8AA0E16626A1} = {C5A6B0DC-3A32-46A4-858D-73410D1A81E9}
+ {545ADEF2-79F6-4825-97A7-AD34D64A94EC} = {D7CC5A53-341D-41FD-9A24-0BD3C5569258}
+ {9AB883F8-6E98-41BF-87A0-F7AA0B0F3C60} = {545ADEF2-79F6-4825-97A7-AD34D64A94EC}
+ {C94A4B68-ABAF-4566-8E42-3D603870A4F2} = {DC4A0A94-B314-410C-803D-95E4A3F5C0FA}
+ {D4975541-0CC6-493B-90B2-AB3757D2A1B2} = {C94A4B68-ABAF-4566-8E42-3D603870A4F2}
+ {951C0702-1109-463A-8FB3-276221ADB711} = {D7CC5A53-341D-41FD-9A24-0BD3C5569258}
+ {B6B9227F-7CBE-426E-90C6-53D015B86357} = {951C0702-1109-463A-8FB3-276221ADB711}
+ {DC09A6A3-F2B1-48A3-B3ED-268E650A7EB0} = {DC4A0A94-B314-410C-803D-95E4A3F5C0FA}
+ {8155999B-3EB8-44D2-BA43-86C97F42AE38} = {DC09A6A3-F2B1-48A3-B3ED-268E650A7EB0}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {1ABF1BAA-6091-41E7-93DE-3428D39E26BC}
+ EndGlobalSection
+EndGlobal
diff --git a/docker-compose.dcproj b/docker-compose.dcproj
new file mode 100644
index 00000000..6f758b48
--- /dev/null
+++ b/docker-compose.dcproj
@@ -0,0 +1,18 @@
+
+
+
+ 2.1
+ Linux
+ 496bcaed-c350-4ad3-aede-5810e67e724c
+ LaunchBrowser
+ {Scheme}://localhost:{ServicePort}/swagger
+ wappa.motoristas.api
+
+
+
+ docker-compose.yml
+
+
+
+
+
\ No newline at end of file
diff --git a/docker-compose.override.yml b/docker-compose.override.yml
new file mode 100644
index 00000000..2e101b74
--- /dev/null
+++ b/docker-compose.override.yml
@@ -0,0 +1,74 @@
+version: '3.4'
+
+services:
+ banco:
+ container_name: banco_sql
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - SA_PASSWORD=yourStrong(!)Password
+ - ACCEPT_EULA=Y
+ healthcheck:
+ test: ["CMD", "/opt/mssql-tools/bin/sqlcmd", "-Usa", "-PyourStrong(!)Password", "-Q", "select 1"]
+ interval: 1s
+ retries: 20
+ ports:
+ - "1435:1433"
+ networks:
+ - local
+
+ rabbitmq:
+ image: rabbitmq:management
+ hostname: rabbit-host
+ container_name: rabbit
+ ports:
+ - 5672:5672
+ - 15672:15672
+ networks:
+ - local
+
+ portainer:
+ image: portainer/portainer
+ hostname: portainer-host
+ container_name: portainer-local
+ command: -H unix:///var/run/docker.sock
+ restart: always
+ ports:
+ - 9000:9000
+ - 8000:8000
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock
+ - portainer_data:/data
+
+ wappa.motoristas.api:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=https://+:5001;http://+:4001
+ - CONTAINER=true
+ ports:
+ - "4001:4001"
+ - "5001:5001"
+ volumes:
+ - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
+ - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
+ networks:
+ - local
+
+ wappa.coordenadasgeograficas.api:
+ environment:
+ - ASPNETCORE_ENVIRONMENT=Development
+ - ASPNETCORE_URLS=https://+:5002;http://+:4002
+ ports:
+ - "4002:4002"
+ - "5002:5002"
+ volumes:
+ - ${APPDATA}/Microsoft/UserSecrets:/root/.microsoft/usersecrets:ro
+ - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
+ networks:
+ - local
+
+networks:
+ local:
+ driver: bridge
+
+volumes:
+ portainer_data:
\ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 00000000..bb66042f
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,23 @@
+version: '3.4'
+
+services:
+ banco:
+ image: mcr.microsoft.com/mssql/server:2017-latest
+
+ rabbitmq:
+ image: rabbitmq:management
+
+ portainer:
+ image: portainer/portainer
+
+ wappa.motoristas.api:
+ image: ${DOCKER_REGISTRY-}wappamotoristasapi
+ build:
+ context: .
+ dockerfile: src/services/Wappa.Motorista.API/Dockerfile
+
+ wappa.coordenadasgeograficas.api:
+ image: ${DOCKER_REGISTRY-}coordenadasgeograficasapi
+ build:
+ context: .
+ dockerfile: src/services/Wappa.CoordenadasGeograficas.API/Dockerfile
\ No newline at end of file
diff --git a/src/building blocks/Wappa.Core/Communication/ResponseResult.cs b/src/building blocks/Wappa.Core/Communication/ResponseResult.cs
new file mode 100644
index 00000000..26e3cc09
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Communication/ResponseResult.cs
@@ -0,0 +1,26 @@
+using System.Collections.Generic;
+
+namespace Wappa.Core.Communication
+{
+ public class ResponseResult
+ {
+ public ResponseResult()
+ {
+ Errors = new ResponseErrorMessages();
+ }
+
+ public string Title { get; set; }
+ public int Status { get; set; }
+ public ResponseErrorMessages Errors { get; set; }
+ }
+
+ public class ResponseErrorMessages
+ {
+ public ResponseErrorMessages()
+ {
+ Mensagens = new List();
+ }
+
+ public List Mensagens { get; set; }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Data/IRepository.cs b/src/building blocks/Wappa.Core/Data/IRepository.cs
new file mode 100644
index 00000000..7ce95f12
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Data/IRepository.cs
@@ -0,0 +1,10 @@
+using System;
+using Wappa.Core.DomainObjects;
+
+namespace Wappa.Core.Data
+{
+ public interface IRepository : IDisposable where T : IAggregateRoot
+ {
+ IUnitOfWork UnitOfWork { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/building blocks/Wappa.Core/Data/IUnitOfWork.cs b/src/building blocks/Wappa.Core/Data/IUnitOfWork.cs
new file mode 100644
index 00000000..f182272e
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Data/IUnitOfWork.cs
@@ -0,0 +1,9 @@
+using System.Threading.Tasks;
+
+namespace Wappa.Core.Data
+{
+ public interface IUnitOfWork
+ {
+ Task Commit();
+ }
+}
\ No newline at end of file
diff --git a/src/building blocks/Wappa.Core/DomainObjects/Entity.cs b/src/building blocks/Wappa.Core/DomainObjects/Entity.cs
new file mode 100644
index 00000000..bcb31d24
--- /dev/null
+++ b/src/building blocks/Wappa.Core/DomainObjects/Entity.cs
@@ -0,0 +1,54 @@
+using System;
+
+namespace Wappa.Core.DomainObjects
+{
+ public abstract class Entity
+ {
+ public Guid Id { get; set; }
+
+ protected Entity()
+ {
+ Id = Guid.NewGuid();
+ }
+
+ #region Comparações
+
+ public override bool Equals(object obj)
+ {
+ var compareTo = obj as Entity;
+
+ if (ReferenceEquals(this, compareTo)) return true;
+ if (ReferenceEquals(null, compareTo)) return false;
+
+ return Id.Equals(compareTo.Id);
+ }
+
+ public static bool operator ==(Entity a, Entity b)
+ {
+ if (ReferenceEquals(a, null) && ReferenceEquals(b, null))
+ return true;
+
+ if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
+ return false;
+
+ return a.Equals(b);
+ }
+
+ public static bool operator !=(Entity a, Entity b)
+ {
+ return !(a == b);
+ }
+
+ public override int GetHashCode()
+ {
+ return (GetType().GetHashCode() * 907) + Id.GetHashCode();
+ }
+
+ public override string ToString()
+ {
+ return $"{GetType().Name} [Id={Id}]";
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/building blocks/Wappa.Core/DomainObjects/IAggregateRoot.cs b/src/building blocks/Wappa.Core/DomainObjects/IAggregateRoot.cs
new file mode 100644
index 00000000..8c3dc9bb
--- /dev/null
+++ b/src/building blocks/Wappa.Core/DomainObjects/IAggregateRoot.cs
@@ -0,0 +1,4 @@
+namespace Wappa.Core.DomainObjects
+{
+ public interface IAggregateRoot { }
+}
\ No newline at end of file
diff --git a/src/building blocks/Wappa.Core/DomainObjects/Localizacao.cs b/src/building blocks/Wappa.Core/DomainObjects/Localizacao.cs
new file mode 100644
index 00000000..21749a95
--- /dev/null
+++ b/src/building blocks/Wappa.Core/DomainObjects/Localizacao.cs
@@ -0,0 +1,7 @@
+namespace Wappa.Core.DomainObjects
+{
+ public class Localizacao
+ {
+
+ }
+}
\ No newline at end of file
diff --git a/src/building blocks/Wappa.Core/Extensions/AppSettings.cs b/src/building blocks/Wappa.Core/Extensions/AppSettings.cs
new file mode 100644
index 00000000..e0fb101a
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Extensions/AppSettings.cs
@@ -0,0 +1,8 @@
+namespace Wappa.Core.Extensions
+{
+ public class AppSettings
+ {
+ public string GoogleGeocodingUrl { get; set; }
+ public string GoogleAPiKey { get; set; }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Mediator/IMediatorHandler.cs b/src/building blocks/Wappa.Core/Mediator/IMediatorHandler.cs
new file mode 100644
index 00000000..c8e125d5
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Mediator/IMediatorHandler.cs
@@ -0,0 +1,12 @@
+using FluentValidation.Results;
+using Wappa.Core.Messages;
+using System.Threading.Tasks;
+
+namespace Wappa.Core.Mediator
+{
+ public interface IMediatorHandler
+ {
+ Task PublicarEvento(T evento) where T : Event;
+ Task EnviarComando(T comando) where T : Command;
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Mediator/MediatorHandler.cs b/src/building blocks/Wappa.Core/Mediator/MediatorHandler.cs
new file mode 100644
index 00000000..95623e36
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Mediator/MediatorHandler.cs
@@ -0,0 +1,27 @@
+using FluentValidation.Results;
+using MediatR;
+using Wappa.Core.Messages;
+using System.Threading.Tasks;
+
+namespace Wappa.Core.Mediator
+{
+ public class MediatorHandler : IMediatorHandler
+ {
+ private readonly IMediator _mediator;
+
+ public MediatorHandler(IMediator mediator)
+ {
+ _mediator = mediator;
+ }
+
+ public async Task EnviarComando(T comando) where T : Command
+ {
+ return await _mediator.Send(comando);
+ }
+
+ public async Task PublicarEvento(T evento) where T : Event
+ {
+ await _mediator.Publish(evento);
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Messages/Command.cs b/src/building blocks/Wappa.Core/Messages/Command.cs
new file mode 100644
index 00000000..679778e3
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Messages/Command.cs
@@ -0,0 +1,24 @@
+using FluentValidation.Results;
+using MediatR;
+using System;
+using System.Text.Json.Serialization;
+
+namespace Wappa.Core.Messages
+{
+ public abstract class Command : Message, IRequest
+ {
+ public DateTime TimeStamp { get; private set; }
+ [JsonIgnore]
+ public ValidationResult ValidationResult { get; set; }
+
+ protected Command()
+ {
+ TimeStamp = DateTime.Now;
+ }
+
+ public virtual bool EhValido()
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Messages/CommandHandler.cs b/src/building blocks/Wappa.Core/Messages/CommandHandler.cs
new file mode 100644
index 00000000..54a4e93a
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Messages/CommandHandler.cs
@@ -0,0 +1,28 @@
+using FluentValidation.Results;
+using System.Threading.Tasks;
+using Wappa.Core.Data;
+
+namespace Wappa.Core.Messages
+{
+ public abstract class CommandHandler
+ {
+ protected ValidationResult ValidationResult;
+
+ protected CommandHandler()
+ {
+ ValidationResult = new ValidationResult();
+ }
+
+ protected void AdicionarErro(string message)
+ {
+ ValidationResult.Errors.Add(new ValidationFailure(string.Empty, message));
+ }
+
+ protected async Task PersistirDados(IUnitOfWork unitOfWork)
+ {
+ if (!await unitOfWork.Commit()) AdicionarErro("Houve um erro ao persistir os dados");
+
+ return ValidationResult;
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Messages/Event.cs b/src/building blocks/Wappa.Core/Messages/Event.cs
new file mode 100644
index 00000000..fd3d3dc4
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Messages/Event.cs
@@ -0,0 +1,15 @@
+using MediatR;
+using System;
+
+namespace Wappa.Core.Messages
+{
+ public class Event : Message, INotification
+ {
+ public DateTime Timestamp { get; private set; }
+
+ protected Event()
+ {
+ Timestamp = DateTime.Now;
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Messages/Integration/IntegrationEvent.cs b/src/building blocks/Wappa.Core/Messages/Integration/IntegrationEvent.cs
new file mode 100644
index 00000000..2d34d32c
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Messages/Integration/IntegrationEvent.cs
@@ -0,0 +1,10 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Wappa.Core.Messages.Integration
+{
+ public abstract class IntegrationEvent : Event
+ {
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Messages/Integration/ResponseMessage.cs b/src/building blocks/Wappa.Core/Messages/Integration/ResponseMessage.cs
new file mode 100644
index 00000000..034d0a1a
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Messages/Integration/ResponseMessage.cs
@@ -0,0 +1,18 @@
+using FluentValidation.Results;
+
+namespace Wappa.Core.Messages.Integration
+{
+ public class ResponseMessage : Message
+ {
+ public ValidationResult ValidationResult { get; set; }
+ public decimal Longitude { get; set; }
+ public decimal Latitude { get; set; }
+
+ public ResponseMessage(ValidationResult validationResult, decimal longitude, decimal latitude)
+ {
+ ValidationResult = validationResult;
+ Longitude = longitude;
+ Latitude = latitude;
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Messages/Integration/SolicitouCadastroMotoristaIntegrationEvent.cs b/src/building blocks/Wappa.Core/Messages/Integration/SolicitouCadastroMotoristaIntegrationEvent.cs
new file mode 100644
index 00000000..0f012306
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Messages/Integration/SolicitouCadastroMotoristaIntegrationEvent.cs
@@ -0,0 +1,56 @@
+using FluentValidation;
+using FluentValidation.Results;
+
+namespace Wappa.Core.Messages.Integration
+{
+ public class SolicitouCadastroMotoristaIntegrationEvent : IntegrationEvent
+ {
+ public SolicitouCadastroMotoristaIntegrationEvent(string logradouro, string numero, string complemento, string bairro, string cep, string cidade, string estado)
+ {
+ Logradouro = logradouro;
+ Numero = numero;
+ Complemento = complemento;
+ Bairro = bairro;
+ Cep = cep;
+ Cidade = cidade;
+ Estado = estado;
+ }
+
+ public string Logradouro { get; set; }
+ public string Numero { get; set; }
+ public string Complemento { get; set; }
+ public string Bairro { get; set; }
+ public string Cep { get; set; }
+ public string Cidade { get; set; }
+ public string Estado { get; set; }
+
+ public ValidationResult ValidationResult { get; protected set; }
+
+ public bool EhValido()
+ {
+ var erros = new SolicitouCadastroMotoristaIntegrationEventValidation().Validate(this).Errors;
+
+ ValidationResult = new ValidationResult(erros);
+
+ return ValidationResult.IsValid;
+ }
+
+ public class SolicitouCadastroMotoristaIntegrationEventValidation : AbstractValidator
+ {
+ public SolicitouCadastroMotoristaIntegrationEventValidation()
+ {
+ RuleFor(c => c.Logradouro)
+ .NotNull()
+ .WithMessage("Informe o logradouro");
+
+ RuleFor(c => c.Cidade)
+ .NotNull()
+ .WithMessage("Informe a cidade");
+
+ RuleFor(c => c.Estado)
+ .NotNull()
+ .WithMessage("Informe o estado");
+ }
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Messages/Message.cs b/src/building blocks/Wappa.Core/Messages/Message.cs
new file mode 100644
index 00000000..859d3555
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Messages/Message.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Wappa.Core.Messages
+{
+ public abstract class Message
+ {
+ public string MessageType { get; protected set; }
+ public Guid AggregateId { get; protected set; }
+
+ protected Message()
+ {
+ MessageType = GetType().Name;
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Utils/ConfigurationExtensions.cs b/src/building blocks/Wappa.Core/Utils/ConfigurationExtensions.cs
new file mode 100644
index 00000000..45d122e0
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Utils/ConfigurationExtensions.cs
@@ -0,0 +1,12 @@
+using Microsoft.Extensions.Configuration;
+
+namespace Wappa.Core.Utils
+{
+ public static class ConfigurationExtensions
+ {
+ public static string GetMessageQueueConnection(this IConfiguration configuration, string name)
+ {
+ return configuration?.GetSection("MessageQueueConnection")?[name];
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.Core/Wappa.Core.csproj b/src/building blocks/Wappa.Core/Wappa.Core.csproj
new file mode 100644
index 00000000..c41a7514
--- /dev/null
+++ b/src/building blocks/Wappa.Core/Wappa.Core.csproj
@@ -0,0 +1,13 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
diff --git a/src/building blocks/Wappa.MessageBus/DependencyInjectionExtensions.cs b/src/building blocks/Wappa.MessageBus/DependencyInjectionExtensions.cs
new file mode 100644
index 00000000..4cc82597
--- /dev/null
+++ b/src/building blocks/Wappa.MessageBus/DependencyInjectionExtensions.cs
@@ -0,0 +1,17 @@
+using Microsoft.Extensions.DependencyInjection;
+using System;
+
+namespace Wappa.MessageBus
+{
+ public static class DependencyInjectionExtensions
+ {
+ public static IServiceCollection AddMessageBus(this IServiceCollection services, string connection)
+ {
+ if (string.IsNullOrEmpty(connection)) throw new ArgumentNullException();
+
+ services.AddSingleton(new MessageBus(connection));
+
+ return services;
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.MessageBus/IMessageBus.cs b/src/building blocks/Wappa.MessageBus/IMessageBus.cs
new file mode 100644
index 00000000..dd0d36c0
--- /dev/null
+++ b/src/building blocks/Wappa.MessageBus/IMessageBus.cs
@@ -0,0 +1,37 @@
+using EasyNetQ;
+using System;
+using System.Threading.Tasks;
+using Wappa.Core.Messages.Integration;
+
+namespace Wappa.MessageBus
+{
+ public interface IMessageBus : IDisposable
+ {
+ bool IsConnected { get; }
+ IAdvancedBus AdvancedBus { get; }
+
+ void Publish(T message) where T : IntegrationEvent;
+
+ Task PublishAsync(T message) where T : IntegrationEvent;
+
+ void Subscribe(string subscriptionId, Action onMessage) where T : class;
+
+ void SubscribeAsync(string subscriptionId, Func onMessage) where T : class;
+
+ TResponse Request(TRequest request)
+ where TRequest : IntegrationEvent
+ where TResponse : ResponseMessage;
+
+ Task RequestAsync(TRequest request)
+ where TRequest : IntegrationEvent
+ where TResponse : ResponseMessage;
+
+ IDisposable Respond(Func responder)
+ where TRequest : IntegrationEvent
+ where TResponse : ResponseMessage;
+
+ IDisposable RespondAsync(Func> responder)
+ where TRequest : IntegrationEvent
+ where TResponse : ResponseMessage;
+ }
+}
\ No newline at end of file
diff --git a/src/building blocks/Wappa.MessageBus/MessageBus.cs b/src/building blocks/Wappa.MessageBus/MessageBus.cs
new file mode 100644
index 00000000..86a5555d
--- /dev/null
+++ b/src/building blocks/Wappa.MessageBus/MessageBus.cs
@@ -0,0 +1,109 @@
+using System;
+using System.Threading.Tasks;
+using EasyNetQ;
+using Wappa.Core.Messages.Integration;
+using Polly;
+using RabbitMQ.Client.Exceptions;
+
+namespace Wappa.MessageBus
+{
+ public class MessageBus : IMessageBus
+ {
+ private IBus _bus;
+ private IAdvancedBus _advancedBus;
+
+ private readonly string _connectionString;
+
+ public MessageBus(string connectionString)
+ {
+ _connectionString = connectionString;
+ TryConnect();
+ }
+
+ public bool IsConnected => _bus?.IsConnected ?? false;
+ public IAdvancedBus AdvancedBus => _bus?.Advanced;
+
+ public void Publish(T message) where T : IntegrationEvent
+ {
+ TryConnect();
+ _bus.Publish(message);
+ }
+
+ public async Task PublishAsync(T message) where T : IntegrationEvent
+ {
+ TryConnect();
+ await _bus.PublishAsync(message);
+ }
+
+ public void Subscribe(string subscriptionId, Action onMessage) where T : class
+ {
+ TryConnect();
+ _bus.Subscribe(subscriptionId, onMessage);
+ }
+
+ public void SubscribeAsync(string subscriptionId, Func onMessage) where T : class
+ {
+ TryConnect();
+ _bus.SubscribeAsync(subscriptionId, onMessage);
+ }
+
+ public TResponse Request(TRequest request) where TRequest : IntegrationEvent
+ where TResponse : ResponseMessage
+ {
+ TryConnect();
+ return _bus.Request(request);
+ }
+
+ public async Task RequestAsync(TRequest request)
+ where TRequest : IntegrationEvent where TResponse : ResponseMessage
+ {
+ TryConnect();
+ return await _bus.RequestAsync(request);
+ }
+
+ public IDisposable Respond(Func responder)
+ where TRequest : IntegrationEvent where TResponse : ResponseMessage
+ {
+ TryConnect();
+ return _bus.Respond(responder);
+ }
+
+ public IDisposable RespondAsync(Func> responder)
+ where TRequest : IntegrationEvent where TResponse : ResponseMessage
+ {
+ TryConnect();
+ return _bus.RespondAsync(responder);
+ }
+
+ private void TryConnect()
+ {
+ if (IsConnected) return;
+
+ var policy = Policy.Handle()
+ .Or()
+ .WaitAndRetry(3, retryAttempt =>
+ TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
+
+ policy.Execute(() =>
+ {
+ _bus = RabbitHutch.CreateBus(_connectionString);
+ _advancedBus = _bus.Advanced;
+ _advancedBus.Disconnected += OnDisconnect;
+ });
+ }
+
+ private void OnDisconnect(object s, EventArgs e)
+ {
+ var policy = Policy.Handle()
+ .Or()
+ .RetryForever();
+
+ policy.Execute(TryConnect);
+ }
+
+ public void Dispose()
+ {
+ _bus.Dispose();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/building blocks/Wappa.MessageBus/Wappa.MessageBus.csproj b/src/building blocks/Wappa.MessageBus/Wappa.MessageBus.csproj
new file mode 100644
index 00000000..e04efcb9
--- /dev/null
+++ b/src/building blocks/Wappa.MessageBus/Wappa.MessageBus.csproj
@@ -0,0 +1,17 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/building blocks/Wappa.WebAPI.Core/Controllers/MainController.cs b/src/building blocks/Wappa.WebAPI.Core/Controllers/MainController.cs
new file mode 100644
index 00000000..c82a502c
--- /dev/null
+++ b/src/building blocks/Wappa.WebAPI.Core/Controllers/MainController.cs
@@ -0,0 +1,83 @@
+using FluentValidation.Results;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc.ModelBinding;
+using System.Collections.Generic;
+using System.Linq;
+using Wappa.Core.Communication;
+
+namespace Wappa.WebAPI.Core.Controllers
+{
+ [ApiController]
+ public abstract class MainController : ControllerBase
+ {
+ protected ICollection Erros = new List();
+
+ protected ActionResult CustomResponse(object result = null)
+ {
+ if (OperacaoValida())
+ {
+ return Ok(result ?? new { sucesso = true});
+ }
+
+ return BadRequest(new ValidationProblemDetails(new Dictionary
+ {
+ { "Mensagens", Erros.ToArray() }
+ }));
+ }
+
+ protected ActionResult CustomResponse(ModelStateDictionary modelState)
+ {
+ var erros = modelState.Values.SelectMany(e => e.Errors);
+ foreach (var erro in erros)
+ {
+ AdicionarErroProcessamento(erro.ErrorMessage);
+ }
+
+ return CustomResponse();
+ }
+
+ protected ActionResult CustomResponse(ValidationResult validationResult)
+ {
+ foreach (var erro in validationResult.Errors)
+ {
+ AdicionarErroProcessamento(erro.ErrorMessage);
+ }
+
+ return CustomResponse();
+ }
+
+ protected ActionResult CustomResponse(ResponseResult resposta)
+ {
+ ResponsePossuiErros(resposta);
+
+ return CustomResponse();
+ }
+
+ protected bool ResponsePossuiErros(ResponseResult resposta)
+ {
+ if (resposta == null || !resposta.Errors.Mensagens.Any()) return false;
+
+ foreach (var mensagem in resposta.Errors.Mensagens)
+ {
+ AdicionarErroProcessamento(mensagem);
+ }
+
+ return true;
+ }
+
+ protected bool OperacaoValida()
+ {
+ return !Erros.Any();
+ }
+
+ protected void AdicionarErroProcessamento(string erro)
+ {
+ Erros.Add(erro);
+ }
+
+ protected void LimparErrosProcessamento()
+ {
+ Erros.Clear();
+ }
+ }
+}
diff --git a/src/building blocks/Wappa.WebAPI.Core/Wappa.WebAPI.Core.csproj b/src/building blocks/Wappa.WebAPI.Core/Wappa.WebAPI.Core.csproj
new file mode 100644
index 00000000..94c25438
--- /dev/null
+++ b/src/building blocks/Wappa.WebAPI.Core/Wappa.WebAPI.Core.csproj
@@ -0,0 +1,15 @@
+
+
+
+ netcoreapp3.1
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Application/Events/CoordenadaEventHandler.cs b/src/services/Wappa.CoordenadasGeograficas.API/Application/Events/CoordenadaEventHandler.cs
new file mode 100644
index 00000000..0633012f
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Application/Events/CoordenadaEventHandler.cs
@@ -0,0 +1,14 @@
+using MediatR;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Wappa.CoordenadasGeograficas.API.Application.Events
+{
+ public class CoordenadaEventHandler : INotificationHandler
+ {
+ public Task Handle(SolicitouCadastroMotoristaEvent notification, CancellationToken cancellationToken)
+ {
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Application/Events/SolicitouCadastroMotoristaEvent.cs b/src/services/Wappa.CoordenadasGeograficas.API/Application/Events/SolicitouCadastroMotoristaEvent.cs
new file mode 100644
index 00000000..2ccf0e81
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Application/Events/SolicitouCadastroMotoristaEvent.cs
@@ -0,0 +1,10 @@
+using Wappa.CoordenadasGeograficas.API.Models;
+using Wappa.Core.Messages;
+
+namespace Wappa.CoordenadasGeograficas.API.Application.Events
+{
+ public class SolicitouCadastroMotoristaEvent : Event
+ {
+ public Endereco Endereco { get; set; }
+ }
+}
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Configuration/ApiConfig.cs b/src/services/Wappa.CoordenadasGeograficas.API/Configuration/ApiConfig.cs
new file mode 100644
index 00000000..34cd73d4
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Configuration/ApiConfig.cs
@@ -0,0 +1,44 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+
+
+namespace Wappa.CoordenadasGeograficas.API.Configuration
+{
+ public static class ApiConfig
+ {
+ public static void AddApiConfiguration(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddControllers();
+
+ services.AddCors(options =>
+ {
+ options.AddPolicy("Total",
+ builder =>
+ builder
+ .AllowAnyOrigin()
+ .AllowAnyMethod()
+ .AllowAnyHeader());
+ });
+ }
+
+ public static void UseApiConfiguration(this IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ app.UseRouting();
+
+ app.UseCors("Total");
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Configuration/DependencyInjectionConfig.cs b/src/services/Wappa.CoordenadasGeograficas.API/Configuration/DependencyInjectionConfig.cs
new file mode 100644
index 00000000..03127f71
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Configuration/DependencyInjectionConfig.cs
@@ -0,0 +1,43 @@
+using Microsoft.Extensions.DependencyInjection;
+using Polly;
+using Polly.Extensions.Http;
+using Polly.Retry;
+using System;
+using System.Net.Http;
+using Wappa.CoordenadasGeograficas.API.Services;
+
+namespace Wappa.CoordenadasGeograficas.API.Configuration
+{
+ public static class DependencyInjectionConfig
+ {
+ public static void RegisterServices(this IServiceCollection services)
+ {
+ services.AddHttpClient()
+ .AddPolicyHandler(PollyExtensions.EsperarTentar())
+ .AddTransientHttpErrorPolicy(
+ p => p.CircuitBreakerAsync(5, TimeSpan.FromSeconds(30)));
+ }
+ }
+
+ public class PollyExtensions
+ {
+ public static AsyncRetryPolicy EsperarTentar()
+ {
+ var retry = HttpPolicyExtensions
+ .HandleTransientHttpError()
+ .WaitAndRetryAsync(new[]
+ {
+ TimeSpan.FromSeconds(1),
+ TimeSpan.FromSeconds(5),
+ TimeSpan.FromSeconds(10),
+ }, (outcome, timespan, retryCount, context) =>
+ {
+ Console.ForegroundColor = ConsoleColor.Blue;
+ Console.WriteLine($"Tentando pela {retryCount} vez!");
+ Console.ForegroundColor = ConsoleColor.White;
+ });
+
+ return retry;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Configuration/MessageBusConfig.cs b/src/services/Wappa.CoordenadasGeograficas.API/Configuration/MessageBusConfig.cs
new file mode 100644
index 00000000..176e7991
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Configuration/MessageBusConfig.cs
@@ -0,0 +1,18 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Wappa.CoordenadasGeograficas.API.Services;
+using Wappa.Core.Utils;
+using Wappa.MessageBus;
+
+namespace Wappa.CoordenadasGeograficas.API.Configuration
+{
+ public static class MessageBusConfig
+ {
+ public static void AddMessageBusConfiguration(this IServiceCollection services,
+ IConfiguration configuration)
+ {
+ services.AddMessageBus(configuration.GetMessageQueueConnection("MessageBus"))
+ .AddHostedService();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Configuration/SwaggerConfig.cs b/src/services/Wappa.CoordenadasGeograficas.API/Configuration/SwaggerConfig.cs
new file mode 100644
index 00000000..1fd95a0a
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Configuration/SwaggerConfig.cs
@@ -0,0 +1,67 @@
+using System;
+using System.IO;
+using System.Reflection;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.OpenApi.Models;
+
+namespace Wappa.CoordenadasGeograficas.API.Configuration
+{
+ public static class SwaggerConfig
+ {
+ public static void AddSwaggerConfiguration(this IServiceCollection services)
+ {
+ services.AddSwaggerGen(c =>
+ {
+ var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
+ var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
+
+ c.IncludeXmlComments(xmlPath);
+ c.SwaggerDoc("v1", new OpenApiInfo()
+ {
+ Title = "Wappa Coordenadas Geográficas API",
+ Description = "Esta API faz a consulta de do endereõ do motorista e retorna sua coordenada geográfica.",
+ Contact = new OpenApiContact() { Name = "Phillipe R Souza", Email = "phillrog@hotmail.com" },
+
+ });
+
+ c.EnableAnnotations();
+
+ c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
+ {
+ Description = "Insira o token JWT desta maneira: Bearer {seu token}",
+ Name = "Authorization",
+ Scheme = "Bearer",
+ BearerFormat = "JWT",
+ In = ParameterLocation.Header,
+ Type = SecuritySchemeType.ApiKey
+ });
+
+ c.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = "Bearer"
+ }
+ },
+ new string[] {}
+ }
+ });
+
+ });
+ }
+
+ public static void UseSwaggerConfiguration(this IApplicationBuilder app)
+ {
+ app.UseSwagger();
+ app.UseSwaggerUI(c =>
+ {
+ c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Controllers/CoordenadaGeograficaController.cs b/src/services/Wappa.CoordenadasGeograficas.API/Controllers/CoordenadaGeograficaController.cs
new file mode 100644
index 00000000..23eca6af
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Controllers/CoordenadaGeograficaController.cs
@@ -0,0 +1,38 @@
+using Microsoft.AspNetCore.Mvc;
+using Swashbuckle.AspNetCore.Annotations;
+using System.Net;
+using System.Threading.Tasks;
+using Wappa.CoordenadasGeograficas.API.Models;
+using Wappa.CoordenadasGeograficas.API.Services;
+using Wappa.WebAPI.Core.Controllers;
+
+namespace Wappa.CoordenadasGeograficas.API.Controllers
+{
+ ///
+ /// API para consultar coordenadas geográficas
+ ///
+ [Route("api/geocoordenada")]
+ public class CoordenadaGeograficaController : MainController
+ {
+ private readonly IGoogleGeocondingService _googleGeocondingService;
+
+ public CoordenadaGeograficaController(IGoogleGeocondingService googleGeocondingService)
+ {
+ _googleGeocondingService = googleGeocondingService;
+ }
+
+ ///
+ /// Busca coordenada geográfica de um endereço
+ ///
+ /// Dados do endereço
+ /// 200 ou 400 ou 404
+ [HttpPost]
+ [SwaggerResponse((int)HttpStatusCode.OK, Description = "Retorna quando sucesso.")]
+ [SwaggerResponse((int)HttpStatusCode.BadRequest, Description = "Retorna quando ocorre alguma falha.")]
+ [SwaggerResponse((int)HttpStatusCode.NotFound, Description = "Retorna quando ocorre alguma falha.")]
+ public async Task BuscarCoordenadaPorEndereco(Endereco endereco)
+ {
+ return CustomResponse(await _googleGeocondingService.BuscarCoordenadas(endereco));
+ }
+ }
+}
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Dockerfile b/src/services/Wappa.CoordenadasGeograficas.API/Dockerfile
new file mode 100644
index 00000000..c7a32fab
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Dockerfile
@@ -0,0 +1,22 @@
+#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
+WORKDIR /app
+EXPOSE 4002
+EXPOSE 5002
+
+FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
+WORKDIR /src
+COPY ["src/services/Wappa.CoordenadasGeograficas.API/Wappa.CoordenadasGeograficas.API.csproj", "src/services/Wappa.CoordenadasGeograficas.API/"]
+RUN dotnet restore "src/services/Wappa.CoordenadasGeograficas.API/Wappa.CoordenadasGeograficas.API.csproj"
+COPY . .
+WORKDIR "/src/src/services/Wappa.CoordenadasGeograficas.API"
+RUN dotnet build "Wappa.CoordenadasGeograficas.API.csproj" -c Release -o /app/build
+
+FROM build AS publish
+RUN dotnet publish "Wappa.CoordenadasGeograficas.API.csproj" -c Release -o /app/publish
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "Wappa.CoordenadasGeograficas.API.dll"]
\ No newline at end of file
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Models/Coordenadas.cs b/src/services/Wappa.CoordenadasGeograficas.API/Models/Coordenadas.cs
new file mode 100644
index 00000000..abc0d287
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Models/Coordenadas.cs
@@ -0,0 +1,13 @@
+namespace Wappa.CoordenadasGeograficas.API.Models
+{
+ public class Coordenadas
+ {
+ public decimal Longitude { get; set; }
+ public decimal Latitude { get; set; }
+
+ public bool EhValido()
+ {
+ return Longitude != 0 && Latitude != 0;
+ }
+ }
+}
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Models/Endereco.cs b/src/services/Wappa.CoordenadasGeograficas.API/Models/Endereco.cs
new file mode 100644
index 00000000..fd3b2f9a
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Models/Endereco.cs
@@ -0,0 +1,21 @@
+using System;
+
+namespace Wappa.CoordenadasGeograficas.API.Models
+{
+ public class Endereco
+ {
+ public string Logradouro { get; set; }
+ public string Numero { get; set; }
+ public string Complemento { get; set; }
+ public string Bairro { get; set; }
+ public string Cep { get; set; }
+ public string Cidade { get; set; }
+ public string Estado { get; set; }
+
+
+ public string Consultar()
+ {
+ return string.Join(Logradouro, "+", Numero, "+", Complemento, "+", Bairro, "+", Cep, "+", Cidade, "+", Estado);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Program.cs b/src/services/Wappa.CoordenadasGeograficas.API/Program.cs
new file mode 100644
index 00000000..cba3f716
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Program.cs
@@ -0,0 +1,26 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Wappa.CoordenadasGeograficas.API
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ });
+ }
+}
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Properties/launchSettings.json b/src/services/Wappa.CoordenadasGeograficas.API/Properties/launchSettings.json
new file mode 100644
index 00000000..a52f1d55
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Properties/launchSettings.json
@@ -0,0 +1,56 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:52127",
+ "sslPort": 44381
+ }
+ },
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "IIS Development": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS Staging": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Staging"
+ }
+ },
+ "IIS Production": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Production"
+ }
+ },
+ "SelfHosting - Development": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:5002;http://localhost:4002"
+ },
+ "Docker": {
+ "commandName": "Docker",
+ "launchBrowser": true,
+ "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "publishAllPorts": true,
+ "useSSL": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Services/CoordenadasIntegrationHandler.cs b/src/services/Wappa.CoordenadasGeograficas.API/Services/CoordenadasIntegrationHandler.cs
new file mode 100644
index 00000000..47b30bdd
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Services/CoordenadasIntegrationHandler.cs
@@ -0,0 +1,54 @@
+using FluentValidation.Results;
+using Microsoft.Extensions.Hosting;
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Wappa.CoordenadasGeograficas.API.Models;
+using Wappa.Core.Messages.Integration;
+using Wappa.MessageBus;
+
+namespace Wappa.CoordenadasGeograficas.API.Services
+{
+ public class CoordenadasIntegrationHandler : BackgroundService
+ {
+ private readonly IMessageBus _bus;
+ private readonly IGoogleGeocondingService _googleGeocondingService;
+
+ public CoordenadasIntegrationHandler(IMessageBus bus, IGoogleGeocondingService googleGeocondingService)
+ {
+ _bus = bus;
+ _googleGeocondingService = googleGeocondingService;
+ }
+
+ private void SetResponder()
+ {
+ _bus.RespondAsync(async request =>
+ await ConsultarCoordenada(request));
+ }
+
+ private async Task ConsultarCoordenada(SolicitouCadastroMotoristaIntegrationEvent request)
+ {
+ var enderecoConsultar = new Endereco();
+
+ enderecoConsultar.Logradouro = request.Logradouro;
+ enderecoConsultar.Numero = request.Numero;
+ enderecoConsultar.Complemento = request.Complemento;
+ enderecoConsultar.Bairro = request.Bairro;
+ enderecoConsultar.Cep = request.Cep;
+ enderecoConsultar.Cidade = request.Cidade;
+ enderecoConsultar.Estado = request.Estado;
+
+ var result = await _googleGeocondingService.BuscarCoordenadas(enderecoConsultar);
+
+ var coordenadaResponse = new ResponseMessage(new ValidationResult(), result.Longitude, result.Latitude);
+
+ return coordenadaResponse;
+ }
+
+ protected override Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ SetResponder();
+ return Task.CompletedTask;
+ }
+ }
+}
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Services/GoogleGeocondingService.cs b/src/services/Wappa.CoordenadasGeograficas.API/Services/GoogleGeocondingService.cs
new file mode 100644
index 00000000..9f9d2e7c
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Services/GoogleGeocondingService.cs
@@ -0,0 +1,55 @@
+using Microsoft.Extensions.Options;
+using Newtonsoft.Json;
+using System;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Threading.Tasks;
+using Wappa.CoordenadasGeograficas.API.Models;
+using Wappa.Core.Extensions;
+
+namespace Wappa.CoordenadasGeograficas.API.Services
+{
+ public interface IGoogleGeocondingService
+ {
+ public Task BuscarCoordenadas(Endereco endereco);
+ }
+
+ public class GoogleGeocondingService : IGoogleGeocondingService
+ {
+ private readonly HttpClient _httpClient;
+ private readonly string _key;
+
+ public GoogleGeocondingService(HttpClient httpClient,
+ IOptions settings)
+ {
+ _httpClient = httpClient;
+ _httpClient.BaseAddress = new Uri(settings.Value.GoogleGeocodingUrl);
+ _httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
+ _key = settings.Value.GoogleAPiKey;
+ }
+
+ public async Task BuscarCoordenadas(Endereco endereco)
+ {
+ var response = await _httpClient.GetAsync($"?address={endereco.Consultar()}&key={_key}");
+ var coordeandas = new Coordenadas();
+
+ if (response.IsSuccessStatusCode)
+ {
+ string result = response.Content.ReadAsStringAsync().Result;
+
+ var data = JsonConvert.DeserializeObject(result);
+
+ foreach (var item in data.results)
+ {
+ coordeandas.Latitude = (decimal)(item.geometry.location.lat);
+ coordeandas.Longitude = (decimal)(item.geometry.location.lng);
+
+ if (coordeandas.EhValido())
+ break;
+ }
+ }
+
+ return coordeandas;
+ }
+ }
+}
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Startup.cs b/src/services/Wappa.CoordenadasGeograficas.API/Startup.cs
new file mode 100644
index 00000000..78215000
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Startup.cs
@@ -0,0 +1,51 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Wappa.CoordenadasGeograficas.API.Configuration;
+using Wappa.Core.Extensions;
+
+namespace Wappa.CoordenadasGeograficas.API
+{
+ public class Startup
+ {
+ public IConfiguration Configuration { get; }
+
+ public Startup(IHostEnvironment hostEnvironment)
+ {
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(hostEnvironment.ContentRootPath)
+ .AddJsonFile("appsettings.json", true, true)
+ .AddJsonFile($"appsettings.{hostEnvironment.EnvironmentName}.json", true, true)
+ .AddEnvironmentVariables();
+
+ if (hostEnvironment.IsDevelopment())
+ {
+ builder.AddUserSecrets();
+ }
+
+ Configuration = builder.Build();
+ }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddApiConfiguration(Configuration);
+
+ services.AddSwaggerConfiguration();
+
+ services.RegisterServices();
+
+ services.AddMessageBusConfiguration(Configuration);
+
+ services.Configure(Configuration);
+ }
+
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+ {
+ app.UseSwaggerConfiguration();
+
+ app.UseApiConfiguration(env);
+ }
+ }
+}
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Wappa.CoordenadasGeograficas.API.csproj b/src/services/Wappa.CoordenadasGeograficas.API/Wappa.CoordenadasGeograficas.API.csproj
new file mode 100644
index 00000000..e4f3aa69
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Wappa.CoordenadasGeograficas.API.csproj
@@ -0,0 +1,31 @@
+
+
+
+ netcoreapp3.1
+ 0a6d6e79-de6b-4994-9749-aeaa7f18fc1b
+ Linux
+ ..\..\..
+
+
+
+ bin\Debug\netcoreapp3.1\Wappa.CoordenadasGeograficas.API.xml
+ bin\Debug\netcoreapp3.1\
+ 1701;1702;1591
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/Wappa.CoordenadasGeograficas.API.csproj.user b/src/services/Wappa.CoordenadasGeograficas.API/Wappa.CoordenadasGeograficas.API.csproj.user
new file mode 100644
index 00000000..e681dafe
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/Wappa.CoordenadasGeograficas.API.csproj.user
@@ -0,0 +1,6 @@
+
+
+
+ Docker
+
+
\ No newline at end of file
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/appsettings.Development.json b/src/services/Wappa.CoordenadasGeograficas.API/appsettings.Development.json
new file mode 100644
index 00000000..a8c18945
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/appsettings.Development.json
@@ -0,0 +1,14 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "GoogleGeocodingUrl": "https://maps.googleapis.com/maps/api/geocode/json?",
+ "GoogleAPiKey": "AIzaSyDMoSwDGKl0QsrzjD3U3IVD8sLdRGtmOxQ",
+ "MessageQueueConnection": {
+ "MessageBus": "host=rabbit:5672;publisherConfirms=true;timeout=10"
+ }
+}
diff --git a/src/services/Wappa.CoordenadasGeograficas.API/appsettings.json b/src/services/Wappa.CoordenadasGeograficas.API/appsettings.json
new file mode 100644
index 00000000..d9d9a9bf
--- /dev/null
+++ b/src/services/Wappa.CoordenadasGeograficas.API/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*"
+}
diff --git a/src/services/Wappa.Motorista.API/Application/Commands/AdicionarMotoristaCommand.cs b/src/services/Wappa.Motorista.API/Application/Commands/AdicionarMotoristaCommand.cs
new file mode 100644
index 00000000..30f0700f
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/Commands/AdicionarMotoristaCommand.cs
@@ -0,0 +1,50 @@
+using FluentValidation;
+using Wappa.Core.Messages;
+using System;
+using Wappa.Motoristas.API.Application.DTO;
+using Wappa.Motoristas.API.Models;
+using System.Text.Json.Serialization;
+
+namespace Wappa.Motoristas.API.Application.Commands
+{
+ public class AdicionarMotoristaCommand : Command
+ {
+ // Motorista
+ public string Nome { get; set; }
+ public string SobreNome { get; set; }
+
+ // Carro
+ public CarroDTO Carro { get; set; }
+
+ // Endereco
+ public EnderecoDTO Endereco { get; set; }
+
+ public override bool EhValido()
+ {
+ ValidationResult = new AdicionarMotoristaValidation().Validate(this);
+ return ValidationResult.IsValid;
+ }
+
+ public class AdicionarMotoristaValidation : AbstractValidator
+ {
+ public AdicionarMotoristaValidation()
+ {
+ RuleFor(c => c.Nome)
+ .NotNull()
+ .WithMessage("Inform o nome do motorista");
+
+ RuleFor(c => c.SobreNome)
+ .NotNull()
+ .WithMessage("Inform o sobrenome do motorista");
+
+ RuleFor(c => c.Carro)
+ .NotNull()
+ .WithMessage("Informe o carro do motorista");
+
+ RuleFor(c => c.Endereco)
+ .NotNull()
+ .WithMessage("Informe o endereço do motorista");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Application/Commands/AtualizarMotoristaCommand.cs b/src/services/Wappa.Motorista.API/Application/Commands/AtualizarMotoristaCommand.cs
new file mode 100644
index 00000000..00f3cc87
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/Commands/AtualizarMotoristaCommand.cs
@@ -0,0 +1,54 @@
+using FluentValidation;
+using Wappa.Core.Messages;
+using System;
+using Wappa.Motoristas.API.Application.DTO;
+using System.Text.Json.Serialization;
+
+namespace Wappa.Motoristas.API.Application.Commands
+{
+ public class AtualizarMotoristaCommand : Command
+ {
+ public Guid Id { get; set; }
+ // Motorista
+ public string Nome { get; set; }
+ public string SobreNome { get; set; }
+
+ // Carro
+ public CarroDTO Carro { get; set; }
+
+ // Endereco
+ public EnderecoDTO Endereco { get; set; }
+
+ public override bool EhValido()
+ {
+ ValidationResult = new AtualizarMotoristaValidation().Validate(this);
+ return ValidationResult.IsValid;
+ }
+
+ public class AtualizarMotoristaValidation : AbstractValidator
+ {
+ public AtualizarMotoristaValidation()
+ {
+ RuleFor(c => c.Id)
+ .NotEqual(Guid.Empty)
+ .WithMessage("Id do motorista inválido");
+
+ RuleFor(c => c.Nome)
+ .NotNull()
+ .WithMessage("Inform o nome do motorista");
+
+ RuleFor(c => c.SobreNome)
+ .NotNull()
+ .WithMessage("Inform o sobrenome do motorista");
+
+ RuleFor(c => c.Carro)
+ .NotNull()
+ .WithMessage("Informe o carro do motorista");
+
+ RuleFor(c => c.Endereco)
+ .NotNull()
+ .WithMessage("Informe o endereço do motorista");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Application/Commands/DeletarMotoristaCommand.cs b/src/services/Wappa.Motorista.API/Application/Commands/DeletarMotoristaCommand.cs
new file mode 100644
index 00000000..56633e3a
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/Commands/DeletarMotoristaCommand.cs
@@ -0,0 +1,27 @@
+using FluentValidation;
+using Wappa.Core.Messages;
+using System;
+
+namespace Wappa.Motoristas.API.Application.Commands
+{
+ public class DeletarMotoristaCommand : Command
+ {
+ // Motorista
+ public Guid Id { get; set; }
+ public override bool EhValido()
+ {
+ ValidationResult = new DeletarMotoristaValidation().Validate(this);
+ return ValidationResult.IsValid;
+ }
+
+ public class DeletarMotoristaValidation : AbstractValidator
+ {
+ public DeletarMotoristaValidation()
+ {
+ RuleFor(c => c.Id)
+ .NotEqual(Guid.Empty)
+ .WithMessage("Id do motorista inválido");
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Application/Commands/MotoristaCommandHandler.cs b/src/services/Wappa.Motorista.API/Application/Commands/MotoristaCommandHandler.cs
new file mode 100644
index 00000000..59cdecd9
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/Commands/MotoristaCommandHandler.cs
@@ -0,0 +1,70 @@
+using FluentValidation.Results;
+using MediatR;
+using System.Threading;
+using System.Threading.Tasks;
+using Wappa.Core.Messages;
+using Wappa.Motoristas.API.Application.Extensions;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Application.Commands
+{
+ public class MotoristaCommandHandler : CommandHandler,
+ IRequestHandler,
+ IRequestHandler,
+ IRequestHandler
+ {
+ private readonly IMotoristaRepository _motoristaRepository;
+
+ public MotoristaCommandHandler(IMotoristaRepository motoristaRepository)
+ {
+ _motoristaRepository = motoristaRepository;
+ }
+
+ public async Task Handle(AdicionarMotoristaCommand message, CancellationToken cancellationToken)
+ {
+ if (!message.EhValido()) return message.ValidationResult;
+
+ var motorista = message.MapearMotorista();
+
+ _motoristaRepository.Adicionar(motorista);
+
+ return await PersistirDados(_motoristaRepository.UnitOfWork);
+ }
+
+ public async Task Handle(AtualizarMotoristaCommand message, CancellationToken cancellationToken)
+ {
+ if (!message.EhValido()) return message.ValidationResult;
+
+ var motorista = await _motoristaRepository.ObterPorId(message.Id);
+
+ if (motorista == null)
+ {
+ AdicionarErro("Motorista não foi encontrado");
+ return ValidationResult;
+ }
+
+ message.MapearMotorista(motorista);
+
+ _motoristaRepository.Atualizar(motorista);
+
+ return await PersistirDados(_motoristaRepository.UnitOfWork);
+ }
+
+ public async Task Handle(DeletarMotoristaCommand message, CancellationToken cancellationToken)
+ {
+ if (!message.EhValido()) return message.ValidationResult;
+
+ var motorista = await _motoristaRepository.ObterPorId(message.Id);
+
+ if (motorista == null)
+ {
+ AdicionarErro("Motorista não foi encontrado");
+ return ValidationResult;
+ }
+
+ _motoristaRepository.Deletar(motorista);
+
+ return await PersistirDados(_motoristaRepository.UnitOfWork);
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Application/DTO/CarroDTO.cs b/src/services/Wappa.Motorista.API/Application/DTO/CarroDTO.cs
new file mode 100644
index 00000000..7c9dd8ec
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/DTO/CarroDTO.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace Wappa.Motoristas.API.Application.DTO
+{
+ public class CarroDTO
+ {
+ public string Marca { get; set; }
+ public string Modelo { get; set; }
+ public string Placa { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Application/DTO/CoordenadasDTO.cs b/src/services/Wappa.Motorista.API/Application/DTO/CoordenadasDTO.cs
new file mode 100644
index 00000000..9babd92c
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/DTO/CoordenadasDTO.cs
@@ -0,0 +1,14 @@
+namespace Wappa.Motoristas.API.Application.DTO
+{
+ public class CoordenadasDTO
+ {
+ public CoordenadasDTO(decimal longitude, decimal latitude)
+ {
+ Longitude = longitude;
+ Latitude = latitude;
+ }
+
+ public decimal Longitude { get; set; }
+ public decimal Latitude { get; set; }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Application/DTO/EnderecoDTO.cs b/src/services/Wappa.Motorista.API/Application/DTO/EnderecoDTO.cs
new file mode 100644
index 00000000..b2abcbf6
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/DTO/EnderecoDTO.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Text.Json.Serialization;
+
+namespace Wappa.Motoristas.API.Application.DTO
+{
+ public class EnderecoDTO
+ {
+ public string Logradouro { get; set; }
+ public string Numero { get; set; }
+ public string Complemento { get; set; }
+ public string Bairro { get; set; }
+ public string Cep { get; set; }
+ public string Cidade { get; set; }
+ public string Estado { get; set; }
+ public CoordenadasDTO Coordenadas { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Application/DTO/MotoristaDTO.cs b/src/services/Wappa.Motorista.API/Application/DTO/MotoristaDTO.cs
new file mode 100644
index 00000000..0a5f1964
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/DTO/MotoristaDTO.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Application.DTO
+{
+ public class MotoristaDTO
+ {
+ public Guid Id { get; set; }
+ public string Nome { get; set; }
+ public string SobreNome { get; set; }
+
+ public EnderecoDTO Endereco { get; set; }
+ public CarroDTO Carro { get; set; }
+
+ public static List ParaMotoristaDTO(dynamic motoristas)
+ {
+ var listaDeMotoristas = new List();
+
+ foreach (var motorista in motoristas)
+ {
+ var motoristaDTO = new MotoristaDTO
+ {
+ Id = Guid.Parse(Convert.ToString(motorista.ID)),
+ Nome = motorista.NOME,
+ SobreNome = motorista.SOBRENOME,
+ Carro = new CarroDTO(),
+ Endereco = new EnderecoDTO()
+ };
+
+ motoristaDTO.Endereco = new EnderecoDTO
+ {
+ Logradouro = motorista.LOGRADOURO,
+ Numero = motorista.NUMERO,
+ Complemento = motorista.COMPLEMENTO,
+ Bairro = motorista.BAIRRO,
+ Cep = motorista.CEP,
+ Cidade = motorista.CIDADE,
+ Estado = motorista.ESTADO,
+ Coordenadas = new CoordenadasDTO(motorista.LONGITUDE, motorista.LATITUDE)
+ };
+
+ motoristaDTO.Carro = new CarroDTO
+ {
+ Marca = motorista.MARCA,
+ Modelo = motorista.MODELO,
+ Placa = motorista.PLACA
+ };
+
+ listaDeMotoristas.Add(motoristaDTO);
+
+ }
+ return listaDeMotoristas;
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Application/Extensions/AdicionarMotoristaCommandExtension.cs b/src/services/Wappa.Motorista.API/Application/Extensions/AdicionarMotoristaCommandExtension.cs
new file mode 100644
index 00000000..3a5fb572
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/Extensions/AdicionarMotoristaCommandExtension.cs
@@ -0,0 +1,33 @@
+using Wappa.Motoristas.API.Application.Commands;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Application.Extensions
+{
+ public static class AdicionarMotoristaCommandExtension
+ {
+ public static Motorista MapearMotorista(this AdicionarMotoristaCommand message)
+ {
+ var endereco = new Endereco
+ {
+ Logradouro = message.Endereco.Logradouro,
+ Numero = message.Endereco.Numero,
+ Complemento = message.Endereco.Complemento,
+ Bairro = message.Endereco.Bairro,
+ Cep = message.Endereco.Cep,
+ Cidade = message.Endereco.Cidade,
+ Estado = message.Endereco.Estado,
+ Latitude = message.Endereco.Coordenadas.Latitude,
+ Longitude = message.Endereco.Coordenadas.Longitude,
+ };
+
+ var carro = new Carro(message.Carro.Marca, message.Carro.Modelo, message.Carro.Placa);
+
+ var motorista = new Motorista(message.Nome, message.SobreNome);
+
+ motorista.Carro = carro;
+ motorista.Endereco = endereco;
+
+ return motorista;
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Application/Extensions/AtualizarMotoristaCommandExtension.cs b/src/services/Wappa.Motorista.API/Application/Extensions/AtualizarMotoristaCommandExtension.cs
new file mode 100644
index 00000000..9dce2d32
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/Extensions/AtualizarMotoristaCommandExtension.cs
@@ -0,0 +1,31 @@
+using Wappa.Motoristas.API.Application.Commands;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Application.Extensions
+{
+ public static class AtualizarMotoristaCommandExtension
+ {
+ public static Motorista MapearMotorista(this AtualizarMotoristaCommand message, Motorista motorista)
+ {
+ motorista.Carro.Marca = message.Carro.Marca;
+ motorista.Carro.Modelo = message.Carro.Modelo;
+ motorista.Carro.Placa = message.Carro.Placa;
+
+ motorista.Endereco.Logradouro = message.Endereco.Logradouro;
+ motorista.Endereco.Numero = message.Endereco.Numero;
+ motorista.Endereco.Complemento = message.Endereco.Complemento;
+ motorista.Endereco.Bairro = message.Endereco.Bairro;
+ motorista.Endereco.Cep = message.Endereco.Cep;
+ motorista.Endereco.Cidade = message.Endereco.Cidade;
+ motorista.Endereco.Estado = message.Endereco.Estado;
+
+ motorista.Endereco.Longitude = message.Endereco.Coordenadas.Longitude;
+ motorista.Endereco.Latitude = message.Endereco.Coordenadas.Latitude;
+
+ motorista.Nome = message.Nome;
+ motorista.SobreNome = message.SobreNome;
+
+ return motorista;
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Application/Queries/MotoristaQueries.cs b/src/services/Wappa.Motorista.API/Application/Queries/MotoristaQueries.cs
new file mode 100644
index 00000000..cf292fd8
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Application/Queries/MotoristaQueries.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using Dapper;
+using Wappa.Motoristas.API.Application.DTO;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Application.Queries
+{
+ public interface IMotoristaQueries
+ {
+ Task> ObterListaMotoristas();
+ }
+
+ public class MotoristaQueries : IMotoristaQueries
+ {
+ #region Sql
+ const string _sql_Motoristas = @"SELECT
+ M.ID,
+ M.NOME,
+ M.SOBRENOME,
+ E.LOGRADOURO,
+ E.NUMERO,
+ E.BAIRRO,
+ E.CEP,
+ E.COMPLEMENTO,
+ E.CIDADE,
+ E.ESTADO,
+ E.LATITUDE,
+ E.LONGITUDE,
+ C.MARCA,
+ C.MODELO,
+ C.PLACA
+ FROM
+ MOTORISTAS M
+ INNER JOIN
+ ENDERECOS E
+ ON E.MOTORISTAID = M.ID
+ INNER JOIN
+ CARROS C
+ ON C.MOTORISTAID = M.ID
+ ORDER BY M.NOME";
+ #endregion
+ private readonly IMotoristaRepository _motoristaRepository;
+
+ public MotoristaQueries(IMotoristaRepository motoristaRepository)
+ {
+ _motoristaRepository = motoristaRepository;
+ }
+
+ public async Task> ObterListaMotoristas()
+ {
+ var motorista = await _motoristaRepository.ObterConexao()
+ .QueryAsync(_sql_Motoristas);
+
+ return MotoristaDTO.ParaMotoristaDTO(motorista);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Configuration/ApiConfig.cs b/src/services/Wappa.Motorista.API/Configuration/ApiConfig.cs
new file mode 100644
index 00000000..4b98a22a
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Configuration/ApiConfig.cs
@@ -0,0 +1,58 @@
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using System;
+using Wappa.Motoristas.API.Data;
+
+namespace Wappa.Motoristas.API.Configuration
+{
+ public static class ApiConfig
+ {
+ public static void AddApiConfiguration(this IServiceCollection services, IConfiguration configuration)
+ {
+ var conn = "";
+
+ if (Environment.GetEnvironmentVariable("CONTAINER") == "true")
+ conn = configuration.GetConnectionString("Container");
+ else
+ conn = configuration.GetConnectionString("Localhost");
+
+ services.AddDbContext(options =>
+ options.UseSqlServer(conn, m => m.MigrationsAssembly("Wappa.Motoristas.API")));
+
+ services.AddControllers();
+
+ services.AddCors(options =>
+ {
+ options.AddPolicy("Total",
+ builder =>
+ builder
+ .AllowAnyOrigin()
+ .AllowAnyMethod()
+ .AllowAnyHeader());
+ });
+ }
+
+ public static void UseApiConfiguration(this IApplicationBuilder app, IWebHostEnvironment env, MotoristaContext motoristaContext)
+ {
+ if (env.IsDevelopment())
+ {
+ app.UseDeveloperExceptionPage();
+ }
+
+ //motoristaContext.Database.Migrate();
+
+ app.UseRouting();
+
+ app.UseCors("Total");
+
+ app.UseEndpoints(endpoints =>
+ {
+ endpoints.MapControllers();
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Configuration/DependencyInjectionConfig.cs b/src/services/Wappa.Motorista.API/Configuration/DependencyInjectionConfig.cs
new file mode 100644
index 00000000..ea8e0d34
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Configuration/DependencyInjectionConfig.cs
@@ -0,0 +1,33 @@
+using FluentValidation.Results;
+using MediatR;
+using Microsoft.Extensions.DependencyInjection;
+using Wappa.Core.Mediator;
+using Wappa.Motoristas.API.Application.Commands;
+using Wappa.Motoristas.API.Application.Queries;
+using Wappa.Motoristas.API.Data;
+using Wappa.Motoristas.API.Data.Repository;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Configuration
+{
+ public static class DependencyInjectionConfig
+ {
+ public static void RegisterServices(this IServiceCollection services)
+ {
+ // Commands
+ services.AddScoped, MotoristaCommandHandler>();
+ services.AddScoped, MotoristaCommandHandler>();
+ services.AddScoped, MotoristaCommandHandler>();
+
+ services.AddScoped();
+
+ // Application
+ services.AddScoped();
+ services.AddScoped();
+
+ // Data
+ services.AddScoped();
+ services.AddScoped();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Configuration/MessageBusConfig.cs b/src/services/Wappa.Motorista.API/Configuration/MessageBusConfig.cs
new file mode 100644
index 00000000..889ec5db
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Configuration/MessageBusConfig.cs
@@ -0,0 +1,15 @@
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Wappa.Core.Utils;
+using Wappa.MessageBus;
+
+namespace Wappa.Motoristas.API.Configuration
+{
+ public static class MessageBusConfig
+ {
+ public static void AddMessageBusConfiguration(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddMessageBus(configuration.GetMessageQueueConnection("MessageBus"));
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Configuration/SwaggerConfig.cs b/src/services/Wappa.Motorista.API/Configuration/SwaggerConfig.cs
new file mode 100644
index 00000000..e1b59db2
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Configuration/SwaggerConfig.cs
@@ -0,0 +1,67 @@
+using System;
+using System.IO;
+using System.Reflection;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.OpenApi.Models;
+
+namespace Wappa.Motoristas.API.Configuration
+{
+ public static class SwaggerConfig
+ {
+ public static void AddSwaggerConfiguration(this IServiceCollection services)
+ {
+ services.AddSwaggerGen(c =>
+ {
+ var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
+ var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
+
+ c.IncludeXmlComments(xmlPath);
+ c.SwaggerDoc("v1", new OpenApiInfo()
+ {
+ Title = "Wappa Challenge Dev Motorista API",
+ Description = "Esta API faz controle o cadastro de motoristas.",
+ Contact = new OpenApiContact() { Name = "Phillipe R Souza", Email = "phillrog@hotmail.com" },
+
+ });
+
+ c.EnableAnnotations();
+
+ c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
+ {
+ Description = "Insira o token JWT desta maneira: Bearer {seu token}",
+ Name = "Authorization",
+ Scheme = "Bearer",
+ BearerFormat = "JWT",
+ In = ParameterLocation.Header,
+ Type = SecuritySchemeType.ApiKey
+ });
+
+ c.AddSecurityRequirement(new OpenApiSecurityRequirement
+ {
+ {
+ new OpenApiSecurityScheme
+ {
+ Reference = new OpenApiReference
+ {
+ Type = ReferenceType.SecurityScheme,
+ Id = "Bearer"
+ }
+ },
+ new string[] {}
+ }
+ });
+
+ });
+ }
+
+ public static void UseSwaggerConfiguration(this IApplicationBuilder app)
+ {
+ app.UseSwagger();
+ app.UseSwaggerUI(c =>
+ {
+ c.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Controllers/MotoristaController.cs b/src/services/Wappa.Motorista.API/Controllers/MotoristaController.cs
new file mode 100644
index 00000000..b46deb66
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Controllers/MotoristaController.cs
@@ -0,0 +1,119 @@
+using Microsoft.AspNetCore.Mvc;
+using System.Threading.Tasks;
+using Wappa.Core.Mediator;
+using Wappa.Motoristas.API.Application.Commands;
+using System.Net;
+using FluentValidation.Results;
+using Swashbuckle.AspNetCore.Annotations;
+using Wappa.Motoristas.API.Application.Queries;
+using Wappa.WebAPI.Core.Controllers;
+using Wappa.MessageBus;
+using Wappa.Core.Messages.Integration;
+using Wappa.Motoristas.API.Application.DTO;
+
+namespace Wappa.Motoristas.API.Controllers
+{
+ ///
+ /// cadastro de motoristas
+ ///
+ [Route("api/motorista")]
+ public class MotoristaController : MainController
+ {
+ private readonly IMediatorHandler _mediator;
+ private readonly IMotoristaQueries _motoristaQueries;
+ private readonly IMessageBus _bus;
+
+ public MotoristaController(IMediatorHandler mediator,
+ IMotoristaQueries motoristaQueries,
+ IMessageBus bus)
+ {
+ _mediator = mediator;
+ _motoristaQueries = motoristaQueries;
+ _bus = bus;
+ }
+
+ ///
+ /// Adiciona um novo motorista ao sistema
+ ///
+ /// Dados do motoristas
+ /// Retorna um 200 ou 400
+ [HttpPost]
+ [SwaggerResponse((int)HttpStatusCode.OK, Description = "Retorna quando sucesso.")]
+ [SwaggerResponse((int)HttpStatusCode.BadRequest, Description = "Retorna quando ocorre alguma falha.")]
+ public async Task AdicionarMotorista(AdicionarMotoristaCommand motorista)
+ {
+ var solicitacaoCoordenadaEvent = new SolicitouCadastroMotoristaIntegrationEvent(motorista.Endereco.Logradouro,
+ motorista.Endereco.Numero,
+ motorista.Endereco.Complemento,
+ motorista.Endereco.Bairro,
+ motorista.Endereco.Cep,
+ motorista.Endereco.Cidade,
+ motorista.Endereco.Estado);
+
+ if (!solicitacaoCoordenadaEvent.EhValido())
+ return CustomResponse(solicitacaoCoordenadaEvent.ValidationResult);
+
+ var coordenadas = await _bus.RequestAsync(solicitacaoCoordenadaEvent);
+
+ motorista.Endereco.Coordenadas = new CoordenadasDTO(coordenadas.Longitude, coordenadas.Latitude);
+
+ return CustomResponse(await _mediator.EnviarComando(motorista));
+ }
+
+ ///
+ /// Atualiza os dados de um motorista cadastrado no sistema
+ ///
+ /// Dados do motoristas
+ /// Retorna um 200 ou 400
+ [HttpPut]
+ [SwaggerResponse((int)HttpStatusCode.OK, Description = "Retorna quando sucesso.")]
+ [SwaggerResponse((int)HttpStatusCode.BadRequest, Description = "Retorna quando ocorre alguma falha.")]
+ public async Task AtualizarMotorista(AtualizarMotoristaCommand motorista)
+ {
+ var solicitacaoCoordenadaEvent = new SolicitouCadastroMotoristaIntegrationEvent(motorista.Endereco.Logradouro,
+ motorista.Endereco.Numero,
+ motorista.Endereco.Complemento,
+ motorista.Endereco.Bairro,
+ motorista.Endereco.Cep,
+ motorista.Endereco.Cidade,
+ motorista.Endereco.Estado);
+
+ if (!solicitacaoCoordenadaEvent.EhValido())
+ return CustomResponse(solicitacaoCoordenadaEvent.ValidationResult);
+
+ var coordenadas = await _bus.RequestAsync(solicitacaoCoordenadaEvent);
+
+ motorista.Endereco.Coordenadas = new CoordenadasDTO(coordenadas.Longitude, coordenadas.Latitude);
+
+ return CustomResponse(await _mediator.EnviarComando(motorista));
+ }
+
+ ///
+ /// Deleta o cadastro do motorista do sistema
+ ///
+ /// Dados do motoristas
+ /// Retorna um 200 ou 400
+ [HttpDelete]
+ [SwaggerResponse((int)HttpStatusCode.OK, Description = "Retorna quando sucesso.", Type = typeof(ValidationResult))]
+ [SwaggerResponse((int)HttpStatusCode.BadRequest, Description = "Retorna quando ocorre alguma falha.", Type = typeof(ValidationResult))]
+ public async Task DeletarMotorista(DeletarMotoristaCommand motorista)
+ {
+ return CustomResponse(await _mediator.EnviarComando(motorista));
+ }
+
+ ///
+ /// Busca todos os motoristas cadastrados no sistema
+ ///
+ /// Retorna um 200 ou 400 ou 404
+ [HttpGet]
+ [SwaggerResponse((int)HttpStatusCode.OK, Description = "Retorna quando sucesso.")]
+ [SwaggerResponse((int)HttpStatusCode.BadRequest, Description = "Retorna quando ocorre alguma falha.")]
+ [SwaggerResponse((int)HttpStatusCode.NotFound, Description = "Retorna quando ocorre alguma falha.")]
+ public async Task ListarMotorista()
+ {
+ var motoristas = await _motoristaQueries.ObterListaMotoristas();
+
+ return motoristas == null ? NotFound() : CustomResponse(motoristas);
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Data/Mappings/CarroMapping.cs b/src/services/Wappa.Motorista.API/Data/Mappings/CarroMapping.cs
new file mode 100644
index 00000000..6054695c
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Data/Mappings/CarroMapping.cs
@@ -0,0 +1,29 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Data.Mappings
+{
+ public class CarroMapping : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ builder.HasKey(c => c.Id);
+
+ builder.Property(c => c.Marca)
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ builder.Property(c => c.Modelo)
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ builder.Property(c => c.Placa)
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+
+ builder.ToTable("Carros");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Data/Mappings/EnderecoMapping.cs b/src/services/Wappa.Motorista.API/Data/Mappings/EnderecoMapping.cs
new file mode 100644
index 00000000..a5cd1fbf
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Data/Mappings/EnderecoMapping.cs
@@ -0,0 +1,49 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Data.Mappings
+{
+ public class EnderecoMapping : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ builder.HasKey(c => c.Id);
+
+ builder.Property(c => c.Logradouro)
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ builder.Property(c => c.Numero)
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ builder.Property(c => c.Cep)
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ builder.Property(c => c.Complemento)
+ .HasColumnType("varchar(250)");
+
+ builder.Property(c => c.Bairro)
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ builder.Property(c => c.Cidade)
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ builder.Property(c => c.Estado)
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ builder.Property(c => c.Longitude)
+ .HasColumnType("decimal(18)");
+
+ builder.Property(c => c.Latitude)
+ .HasColumnType("decimal(18)");
+
+ builder.ToTable("Enderecos");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Data/Mappings/MotoristaMapping.cs b/src/services/Wappa.Motorista.API/Data/Mappings/MotoristaMapping.cs
new file mode 100644
index 00000000..d85e31ad
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Data/Mappings/MotoristaMapping.cs
@@ -0,0 +1,32 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Data.Mappings
+{
+ public class MotoristaMapping : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder builder)
+ {
+ builder.HasKey(c => c.Id);
+
+ builder.Property(c => c.Nome)
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ builder.Property(c => c.SobreNome)
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ // 1 : 1 => Motorista : Endereco
+ builder.HasOne(c => c.Endereco)
+ .WithOne(c => c.Motorista);
+
+ // 1 : 1 => Motorista : Carro
+ builder.HasOne(c => c.Carro)
+ .WithOne(c => c.Motorista);
+
+ builder.ToTable("Motoristas");
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Data/MotoristaContext.cs b/src/services/Wappa.Motorista.API/Data/MotoristaContext.cs
new file mode 100644
index 00000000..01d8b56d
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Data/MotoristaContext.cs
@@ -0,0 +1,48 @@
+using System.Linq;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Wappa.Motoristas.API.Models;
+using Wappa.Core.Data;
+using Wappa.Core.DomainObjects;
+using FluentValidation.Results;
+
+namespace Wappa.Motoristas.API.Data
+{
+ public sealed class MotoristaContext : DbContext, IUnitOfWork
+ {
+
+ public MotoristaContext(DbContextOptions options)
+ : base(options)
+ {
+ ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
+ ChangeTracker.AutoDetectChangesEnabled = false;
+ }
+
+ public DbSet Motorista { get; set; }
+ public DbSet Enderecos { get; set; }
+ public DbSet Carros { get; set; }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.Ignore();
+
+ foreach (var property in modelBuilder.Model.GetEntityTypes().SelectMany(
+ e => e.GetProperties().Where(p => p.ClrType == typeof(string))))
+ property.SetColumnType("varchar(100)");
+
+ foreach (var relationship in modelBuilder.Model.GetEntityTypes()
+ .SelectMany(e => e.GetForeignKeys())) relationship.DeleteBehavior = DeleteBehavior.Cascade;
+
+ modelBuilder.ApplyConfigurationsFromAssembly(typeof(MotoristaContext).Assembly);
+
+ base.OnModelCreating(modelBuilder);
+ }
+
+ public async Task Commit()
+ {
+ var sucesso = await base.SaveChangesAsync() > 0;
+
+ return sucesso;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Data/Repository/MotoristaRepository.cs b/src/services/Wappa.Motorista.API/Data/Repository/MotoristaRepository.cs
new file mode 100644
index 00000000..d4d817e2
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Data/Repository/MotoristaRepository.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
+using System.Threading.Tasks;
+using Microsoft.EntityFrameworkCore;
+using Wappa.Core.Data;
+using Wappa.Motoristas.API.Models;
+
+namespace Wappa.Motoristas.API.Data.Repository
+{
+ public class MotoristaRepository : IMotoristaRepository
+ {
+ private readonly MotoristaContext _context;
+
+ public MotoristaRepository(MotoristaContext context)
+ {
+ _context = context;
+ }
+
+ public IUnitOfWork UnitOfWork => _context;
+ public DbConnection ObterConexao() => _context.Database.GetDbConnection();
+
+ public async Task> ObterTodos()
+ {
+ return await _context.Motorista.AsNoTracking().ToListAsync();
+ }
+
+ public void Adicionar(Motorista motorista)
+ {
+ _context.Motorista.Add(motorista);
+ }
+
+
+ public void Atualizar(Motorista motorista)
+ {
+ _context.Motorista.Update(motorista);
+ }
+
+ public void Deletar(Motorista motorista)
+ {
+ _context.Motorista.Remove(motorista);
+ }
+
+ public Task ObterPorId(Guid id)
+ {
+ return _context.Motorista
+ .Include(d => d.Carro)
+ .Include(f=>f.Endereco)
+ .FirstOrDefaultAsync(f => f.Id == id);
+ }
+
+ public void Dispose()
+ {
+ _context.Dispose();
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Dockerfile b/src/services/Wappa.Motorista.API/Dockerfile
new file mode 100644
index 00000000..01792a49
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Dockerfile
@@ -0,0 +1,23 @@
+#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging.
+
+FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-buster-slim AS base
+WORKDIR /app
+EXPOSE 4001
+EXPOSE 5001
+
+FROM mcr.microsoft.com/dotnet/core/sdk:3.1-buster AS build
+WORKDIR /src
+COPY ["src/services/Wappa.Motorista.API/Wappa.Motoristas.API.csproj", "src/services/Wappa.Motorista.API/"]
+COPY ["src/building blocks/Wappa.Core/Wappa.Core.csproj", "src/building blocks/Wappa.Core/"]
+RUN dotnet restore "src/services/Wappa.Motorista.API/Wappa.Motoristas.API.csproj"
+COPY . .
+WORKDIR "/src/src/services/Wappa.Motorista.API"
+RUN dotnet build "Wappa.Motoristas.API.csproj" -c Release -o /app/build
+
+FROM build AS publish
+RUN dotnet publish "Wappa.Motoristas.API.csproj" -c Release -o /app/publish
+
+FROM base AS final
+WORKDIR /app
+COPY --from=publish /app/publish .
+ENTRYPOINT ["dotnet", "Wappa.Motoristas.API.dll"]
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Migrations/20210309031025_Motorista.Designer.cs b/src/services/Wappa.Motorista.API/Migrations/20210309031025_Motorista.Designer.cs
new file mode 100644
index 00000000..36459b05
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Migrations/20210309031025_Motorista.Designer.cs
@@ -0,0 +1,136 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Wappa.Motoristas.API.Data;
+
+namespace Wappa.Motoristas.API.Migrations
+{
+ [DbContext(typeof(MotoristaContext))]
+ [Migration("20210309031025_Motorista")]
+ partial class Motorista
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "3.1.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128)
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Carro", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Marca")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.Property("Modelo")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("MotoristaId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Placa")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MotoristaId")
+ .IsUnique();
+
+ b.ToTable("Carros");
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Endereco", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Bairro")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("Cep")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.Property("Cidade")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("Complemento")
+ .HasColumnType("varchar(250)");
+
+ b.Property("Estado")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.Property("Logradouro")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.Property("MotoristaId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Numero")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MotoristaId")
+ .IsUnique();
+
+ b.ToTable("Enderecos");
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Motorista", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Nome")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.Property("SobreNome")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Motoristas");
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Carro", b =>
+ {
+ b.HasOne("Wappa.Motoristas.API.Models.Motorista", "Motorista")
+ .WithOne("Carro")
+ .HasForeignKey("Wappa.Motoristas.API.Models.Carro", "MotoristaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Endereco", b =>
+ {
+ b.HasOne("Wappa.Motoristas.API.Models.Motorista", "Motorista")
+ .WithOne("Endereco")
+ .HasForeignKey("Wappa.Motoristas.API.Models.Endereco", "MotoristaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Migrations/20210309031025_Motorista.cs b/src/services/Wappa.Motorista.API/Migrations/20210309031025_Motorista.cs
new file mode 100644
index 00000000..440db8b2
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Migrations/20210309031025_Motorista.cs
@@ -0,0 +1,94 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Wappa.Motoristas.API.Migrations
+{
+ public partial class Motorista : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.CreateTable(
+ name: "Motoristas",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ Nome = table.Column(type: "varchar(200)", nullable: false),
+ SobreNome = table.Column(type: "varchar(200)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Motoristas", x => x.Id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Carros",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ Marca = table.Column(type: "varchar(200)", nullable: false),
+ Modelo = table.Column(type: "varchar(100)", nullable: false),
+ Placa = table.Column(type: "varchar(20)", nullable: false),
+ MotoristaId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Carros", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Carros_Motoristas_MotoristaId",
+ column: x => x.MotoristaId,
+ principalTable: "Motoristas",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "Enderecos",
+ columns: table => new
+ {
+ Id = table.Column(nullable: false),
+ Logradouro = table.Column(type: "varchar(200)", nullable: false),
+ Numero = table.Column(type: "varchar(50)", nullable: false),
+ Complemento = table.Column(type: "varchar(250)", nullable: true),
+ Bairro = table.Column(type: "varchar(100)", nullable: false),
+ Cep = table.Column(type: "varchar(20)", nullable: false),
+ Cidade = table.Column(type: "varchar(100)", nullable: false),
+ Estado = table.Column(type: "varchar(50)", nullable: false),
+ MotoristaId = table.Column(nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Enderecos", x => x.Id);
+ table.ForeignKey(
+ name: "FK_Enderecos_Motoristas_MotoristaId",
+ column: x => x.MotoristaId,
+ principalTable: "Motoristas",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Carros_MotoristaId",
+ table: "Carros",
+ column: "MotoristaId",
+ unique: true);
+
+ migrationBuilder.CreateIndex(
+ name: "IX_Enderecos_MotoristaId",
+ table: "Enderecos",
+ column: "MotoristaId",
+ unique: true);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "Carros");
+
+ migrationBuilder.DropTable(
+ name: "Enderecos");
+
+ migrationBuilder.DropTable(
+ name: "Motoristas");
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Migrations/20210310071419_Coordenadas.Designer.cs b/src/services/Wappa.Motorista.API/Migrations/20210310071419_Coordenadas.Designer.cs
new file mode 100644
index 00000000..8357b0ad
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Migrations/20210310071419_Coordenadas.Designer.cs
@@ -0,0 +1,142 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Wappa.Motoristas.API.Data;
+
+namespace Wappa.Motoristas.API.Migrations
+{
+ [DbContext(typeof(MotoristaContext))]
+ [Migration("20210310071419_Coordenadas")]
+ partial class Coordenadas
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "3.1.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128)
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Carro", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Marca")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.Property("Modelo")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("MotoristaId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Placa")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MotoristaId")
+ .IsUnique();
+
+ b.ToTable("Carros");
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Endereco", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Bairro")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("Cep")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.Property("Cidade")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("Complemento")
+ .HasColumnType("varchar(250)");
+
+ b.Property("Estado")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.Property("Latitude")
+ .HasColumnType("decimal(18)");
+
+ b.Property("Logradouro")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.Property("Longitute")
+ .HasColumnType("decimal(18)");
+
+ b.Property("MotoristaId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Numero")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MotoristaId")
+ .IsUnique();
+
+ b.ToTable("Enderecos");
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Motorista", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Nome")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.Property("SobreNome")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Motoristas");
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Carro", b =>
+ {
+ b.HasOne("Wappa.Motoristas.API.Models.Motorista", "Motorista")
+ .WithOne("Carro")
+ .HasForeignKey("Wappa.Motoristas.API.Models.Carro", "MotoristaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Endereco", b =>
+ {
+ b.HasOne("Wappa.Motoristas.API.Models.Motorista", "Motorista")
+ .WithOne("Endereco")
+ .HasForeignKey("Wappa.Motoristas.API.Models.Endereco", "MotoristaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Migrations/20210310071419_Coordenadas.cs b/src/services/Wappa.Motorista.API/Migrations/20210310071419_Coordenadas.cs
new file mode 100644
index 00000000..52770ae0
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Migrations/20210310071419_Coordenadas.cs
@@ -0,0 +1,35 @@
+using Microsoft.EntityFrameworkCore.Migrations;
+
+namespace Wappa.Motoristas.API.Migrations
+{
+ public partial class Coordenadas : Migration
+ {
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AddColumn(
+ name: "Latitude",
+ table: "Enderecos",
+ type: "decimal(18,10)",
+ nullable: false,
+ defaultValue: 0m);
+
+ migrationBuilder.AddColumn(
+ name: "Longitude",
+ table: "Enderecos",
+ type: "decimal(18,10)",
+ nullable: false,
+ defaultValue: 0m);
+ }
+
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropColumn(
+ name: "Latitude",
+ table: "Enderecos");
+
+ migrationBuilder.DropColumn(
+ name: "Longitude",
+ table: "Enderecos");
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Migrations/MotoristaContextModelSnapshot.cs b/src/services/Wappa.Motorista.API/Migrations/MotoristaContextModelSnapshot.cs
new file mode 100644
index 00000000..7644ec5d
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Migrations/MotoristaContextModelSnapshot.cs
@@ -0,0 +1,140 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Metadata;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Wappa.Motoristas.API.Data;
+
+namespace Wappa.Motoristas.API.Migrations
+{
+ [DbContext(typeof(MotoristaContext))]
+ partial class MotoristaContextModelSnapshot : ModelSnapshot
+ {
+ protected override void BuildModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "3.1.3")
+ .HasAnnotation("Relational:MaxIdentifierLength", 128)
+ .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Carro", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Marca")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.Property("Modelo")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("MotoristaId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Placa")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MotoristaId")
+ .IsUnique();
+
+ b.ToTable("Carros");
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Endereco", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Bairro")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("Cep")
+ .IsRequired()
+ .HasColumnType("varchar(20)");
+
+ b.Property("Cidade")
+ .IsRequired()
+ .HasColumnType("varchar(100)");
+
+ b.Property("Complemento")
+ .HasColumnType("varchar(250)");
+
+ b.Property("Estado")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.Property("Latitude")
+ .HasColumnType("decimal(18,10)");
+
+ b.Property("Logradouro")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.Property("Longitude")
+ .HasColumnType("decimal(18,10)");
+
+ b.Property("MotoristaId")
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Numero")
+ .IsRequired()
+ .HasColumnType("varchar(50)");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MotoristaId")
+ .IsUnique();
+
+ b.ToTable("Enderecos");
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Motorista", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uniqueidentifier");
+
+ b.Property("Nome")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.Property("SobreNome")
+ .IsRequired()
+ .HasColumnType("varchar(200)");
+
+ b.HasKey("Id");
+
+ b.ToTable("Motoristas");
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Carro", b =>
+ {
+ b.HasOne("Wappa.Motoristas.API.Models.Motorista", "Motorista")
+ .WithOne("Carro")
+ .HasForeignKey("Wappa.Motoristas.API.Models.Carro", "MotoristaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("Wappa.Motoristas.API.Models.Endereco", b =>
+ {
+ b.HasOne("Wappa.Motoristas.API.Models.Motorista", "Motorista")
+ .WithOne("Endereco")
+ .HasForeignKey("Wappa.Motoristas.API.Models.Endereco", "MotoristaId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired();
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Models/Carro.cs b/src/services/Wappa.Motorista.API/Models/Carro.cs
new file mode 100644
index 00000000..5df38728
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Models/Carro.cs
@@ -0,0 +1,24 @@
+using Wappa.Core.DomainObjects;
+using System;
+
+namespace Wappa.Motoristas.API.Models
+{
+ public class Carro: Entity
+ {
+ public string Marca { get; set; }
+ public string Modelo { get; set; }
+ public string Placa { get; set; }
+
+ public Guid MotoristaId { get; set; }
+
+ // EF Relation
+ public Motorista Motorista { get; protected set; }
+
+ public Carro(string marca, string modelo, string placa)
+ {
+ Marca = marca;
+ Modelo = modelo;
+ Placa = placa;
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Models/Endereco.cs b/src/services/Wappa.Motorista.API/Models/Endereco.cs
new file mode 100644
index 00000000..22798946
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Models/Endereco.cs
@@ -0,0 +1,35 @@
+using Wappa.Core.DomainObjects;
+using System;
+
+namespace Wappa.Motoristas.API.Models
+{
+ public class Endereco: Entity
+ {
+ public string Logradouro { get; set; }
+ public string Numero { get; set; }
+ public string Complemento { get; set; }
+ public string Bairro { get; set; }
+ public string Cep { get; set; }
+ public string Cidade { get; set; }
+ public string Estado { get; set; }
+ public Guid MotoristaId { get; set; }
+ public decimal Longitude { get; set; }
+ public decimal Latitude{ get; set; }
+
+
+ public Motorista Motorista { get; protected set; }
+
+ public Endereco(){}
+
+ public Endereco(string logradouro, string numero, string complemento, string bairro, string cep, string cidade, string estado)
+ {
+ Logradouro = logradouro;
+ Numero = numero;
+ Complemento = complemento;
+ Bairro = bairro;
+ Cep = cep;
+ Cidade = cidade;
+ Estado = estado;
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Models/IMotoristaRepository.cs b/src/services/Wappa.Motorista.API/Models/IMotoristaRepository.cs
new file mode 100644
index 00000000..812fec77
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Models/IMotoristaRepository.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Common;
+using System.Threading.Tasks;
+using Wappa.Core.Data;
+
+namespace Wappa.Motoristas.API.Models
+{
+ public interface IMotoristaRepository : IRepository
+ {
+ void Adicionar(Motorista motorista);
+ void Atualizar(Motorista motorista);
+ void Deletar(Motorista motorista);
+
+ Task ObterPorId(Guid id);
+ Task> ObterTodos();
+
+ DbConnection ObterConexao();
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Models/Motorista.cs b/src/services/Wappa.Motorista.API/Models/Motorista.cs
new file mode 100644
index 00000000..502894ab
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Models/Motorista.cs
@@ -0,0 +1,22 @@
+using Wappa.Core.DomainObjects;
+using System;
+using FluentValidation;
+
+namespace Wappa.Motoristas.API.Models
+{
+ public class Motorista : Entity, IAggregateRoot
+ {
+ public string Nome { get; set; }
+ public string SobreNome { get; set; }
+ public Carro Carro { get; set; }
+ public Endereco Endereco { get; set; }
+
+ protected Motorista() { }
+
+ public Motorista(string nome, string sobreNome)
+ {
+ Nome = nome;
+ SobreNome = sobreNome;
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Program.cs b/src/services/Wappa.Motorista.API/Program.cs
new file mode 100644
index 00000000..e31df427
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Program.cs
@@ -0,0 +1,26 @@
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace Wappa.Motoristas.API
+{
+ public class Program
+ {
+ public static void Main(string[] args)
+ {
+ CreateHostBuilder(args).Build().Run();
+ }
+
+ public static IHostBuilder CreateHostBuilder(string[] args) =>
+ Host.CreateDefaultBuilder(args)
+ .ConfigureWebHostDefaults(webBuilder =>
+ {
+ webBuilder.UseStartup();
+ });
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Properties/launchSettings.json b/src/services/Wappa.Motorista.API/Properties/launchSettings.json
new file mode 100644
index 00000000..391048f5
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Properties/launchSettings.json
@@ -0,0 +1,56 @@
+{
+ "iisSettings": {
+ "windowsAuthentication": false,
+ "anonymousAuthentication": true,
+ "iisExpress": {
+ "applicationUrl": "http://localhost:52004",
+ "sslPort": 44317
+ }
+ },
+ "$schema": "http://json.schemastore.org/launchsettings.json",
+ "profiles": {
+ "IIS Development": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ }
+ },
+ "IIS Staging": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Staging"
+ }
+ },
+ "IIS Production": {
+ "commandName": "IISExpress",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Production"
+ }
+ },
+ "SelfHosting - Development": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "launchUrl": "swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:5001;http://localhost:4001"
+ },
+ "Docker": {
+ "commandName": "Docker",
+ "launchBrowser": true,
+ "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "publishAllPorts": true,
+ "useSSL": true
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/Startup.cs b/src/services/Wappa.Motorista.API/Startup.cs
new file mode 100644
index 00000000..4a802e90
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Startup.cs
@@ -0,0 +1,52 @@
+using MediatR;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Wappa.Motoristas.API.Configuration;
+using Wappa.Motoristas.API.Data;
+
+namespace Wappa.Motoristas.API
+{
+ public class Startup
+ {
+ public IConfiguration Configuration { get; }
+
+ public Startup(IHostEnvironment hostEnvironment)
+ {
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(hostEnvironment.ContentRootPath)
+ .AddJsonFile("appsettings.json", true, true)
+ .AddJsonFile($"appsettings.{hostEnvironment.EnvironmentName}.json", true, true)
+ .AddEnvironmentVariables();
+
+ if (hostEnvironment.IsDevelopment())
+ {
+ builder.AddUserSecrets();
+ }
+
+ Configuration = builder.Build();
+ }
+
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddApiConfiguration(Configuration);
+
+ services.AddSwaggerConfiguration();
+
+ services.AddMediatR(typeof(Startup));
+
+ services.RegisterServices();
+
+ services.AddMessageBusConfiguration(Configuration);
+ }
+
+ public void Configure(IApplicationBuilder app, IWebHostEnvironment env, MotoristaContext motoristaContext)
+ {
+ app.UseSwaggerConfiguration();
+
+ app.UseApiConfiguration(env, motoristaContext);
+ }
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/Wappa.Motoristas.API.csproj b/src/services/Wappa.Motorista.API/Wappa.Motoristas.API.csproj
new file mode 100644
index 00000000..069a7c8d
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Wappa.Motoristas.API.csproj
@@ -0,0 +1,50 @@
+
+
+
+ netcoreapp3.1
+ Linux
+ ..\..\..
+ 0caf6535-96f2-4d67-a416-3089d65205c3
+ ..\..\..\docker-compose.dcproj
+
+
+
+ bin\Debug\netcoreapp3.1\Wappa.Motoristas.API.xml
+ bin\Debug\netcoreapp3.1\
+ 1701;1702;1591
+
+
+
+
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/services/Wappa.Motorista.API/Wappa.Motoristas.API.csproj.user b/src/services/Wappa.Motorista.API/Wappa.Motoristas.API.csproj.user
new file mode 100644
index 00000000..195b56e1
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/Wappa.Motoristas.API.csproj.user
@@ -0,0 +1,9 @@
+
+
+
+ IIS Development
+
+
+ ProjectDebugger
+
+
\ No newline at end of file
diff --git a/src/services/Wappa.Motorista.API/appsettings.Development.json b/src/services/Wappa.Motorista.API/appsettings.Development.json
new file mode 100644
index 00000000..a27611d5
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/appsettings.Development.json
@@ -0,0 +1,22 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AppSettings": {
+ "Secret": "MEUSEGREDOSUPERSECRETO",
+ "ExpiracaoHoras": 2,
+ "Emissor": "MeuSistema",
+ "ValidoEm": "https://localhost"
+ },
+ "ConnectionStrings": {
+ "Container": "Server=banco_sql,1433;Database=WappaDev; User=sa; Password=yourStrong(!)Password;Trusted_Connection=False;MultipleActiveResultSets=true",
+ "Localhost": "Server=localhost,1435;Database=WappaDev; User=sa; Password=yourStrong(!)Password;Trusted_Connection=False;MultipleActiveResultSets=true"
+ },
+ "MessageQueueConnection": {
+ "MessageBus": "host=rabbit:5672;publisherConfirms=true;timeout=10"
+ }
+}
diff --git a/src/services/Wappa.Motorista.API/appsettings.json b/src/services/Wappa.Motorista.API/appsettings.json
new file mode 100644
index 00000000..d9d9a9bf
--- /dev/null
+++ b/src/services/Wappa.Motorista.API/appsettings.json
@@ -0,0 +1,10 @@
+{
+ "Logging": {
+ "LogLevel": {
+ "Default": "Information",
+ "Microsoft": "Warning",
+ "Microsoft.Hosting.Lifetime": "Information"
+ }
+ },
+ "AllowedHosts": "*"
+}