├── .dockerignore ├── .gitattributes ├── .gitignore ├── LoadTest-JMeter ├── TestPlanBookingAndPayment-Live.jmx └── TestPlanBookingAndPayment-Local.jmx ├── MicroCouriers.sln ├── README.md ├── Solution-Architecture.JPG ├── StartSQLonly.ps1 ├── StartSolution.ps1 ├── StopAllContainers.ps1 ├── docker-compose-sql.yml ├── docker-compose.yml ├── k8s ├── AKS-Deployment-Steps.txt ├── configuration │ ├── Booking │ │ └── appsettings.json │ ├── Payment │ │ └── appsettings.json │ ├── Tracking │ │ └── appsettings.json │ └── Web │ │ └── appsettings.json ├── deployment.yaml └── deploymentservices.yaml └── src ├── BookingDockerfile ├── BuildingBlocks └── EventBus │ ├── EventBus │ ├── Abstractions │ │ ├── IDynamicIntegrationEventHandler.cs │ │ ├── IEventBus.cs │ │ └── IIntegrationEventHandler.cs │ ├── EventBus.csproj │ ├── Events │ │ └── IntegrationEvent.cs │ ├── IEventBusSubscriptionsManager.cs │ ├── InMemoryEventBusSubscriptionsManager.cs │ └── SubscriptionInfo.cs │ ├── EventBusServiceBus │ ├── DefaultServiceBusPersisterConnection.cs │ ├── EventBusServiceBus.cs │ ├── EventBusServiceBus.csproj │ └── IServiceBusPersisterConnection.cs │ └── IntegrationEventLogEF │ ├── EventStateEnum.cs │ ├── IntegrationEventLogContext.cs │ ├── IntegrationEventLogEF.csproj │ ├── IntegrationEventLogEntry.cs │ ├── Services │ ├── IIntegrationEventLogService.cs │ └── IntegrationEventLogService.cs │ └── Utilities │ └── ResilientTransaction.cs ├── McWebDockerfile ├── PaymentDockerfile ├── Services ├── Booking │ ├── Booking.API │ │ ├── Booking.API.csproj │ │ ├── Connected Services │ │ │ └── Application Insights │ │ │ │ └── ConnectedService.json │ │ ├── Controllers │ │ │ ├── BaseController.cs │ │ │ └── BookingController.cs │ │ ├── Dockerfile │ │ ├── Infrastructure │ │ │ └── AutofacModules │ │ │ │ ├── ApplicationModule.cs │ │ │ │ └── MediatorModule.cs │ │ ├── Migrations │ │ │ ├── 20190219102837_IntegrationEventLogInitial.Designer.cs │ │ │ ├── 20190219102837_IntegrationEventLogInitial.cs │ │ │ └── IntegrationEventLogContextModelSnapshot.cs │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.Production.json │ ├── Booking.Application │ │ ├── Behaviors │ │ │ └── TransactionBehaviour.cs │ │ ├── Booking.Application.csproj │ │ ├── Booking │ │ │ ├── Commands │ │ │ │ ├── CreateBooking │ │ │ │ │ ├── CreateBookingCommand.cs │ │ │ │ │ └── CreateBookingCommandHandler.cs │ │ │ │ └── UpdateBooking │ │ │ │ │ ├── UpdateBooking.cs │ │ │ │ │ └── UpdateBookingHandler.cs │ │ │ └── Queries │ │ │ │ ├── DTO │ │ │ │ ├── BookingOrderDTO.cs │ │ │ │ └── BookingOrderDetailDTO.cs │ │ │ │ └── GetBooking │ │ │ │ ├── GetBookingQuery.cs │ │ │ │ └── GetBookingQueryHandler.cs │ │ └── IntegrationEvents │ │ │ ├── BookingIntegrationEventService.cs │ │ │ ├── Events │ │ │ ├── BookingAddIntegrationEvent.cs │ │ │ ├── OrderStatusChangedIntegrationEvent.cs │ │ │ ├── OrderStatusChangedIntegrationEventHandler.cs │ │ │ ├── PaymentProcessedIntegrationEvent.cs │ │ │ └── PaymentProcessedIntegrationEventHandler.cs │ │ │ └── IBookingIntegrationEventService.cs │ ├── Booking.Common │ │ ├── Booking.Common.csproj │ │ └── bookingStateEnum.cs │ ├── Booking.Domain │ │ ├── AggregatesModel │ │ │ └── BookingAggregate │ │ │ │ ├── BookingOrder.cs │ │ │ │ ├── BookingOrderDetail.cs │ │ │ │ └── bookingStateEnum.cs │ │ ├── Booking.Domain.csproj │ │ └── Interfaces │ │ │ └── IBookingRespository.cs │ ├── Booking.Infrastructure │ │ └── Booking.Infrastructure.csproj │ ├── Booking.Persistence │ │ ├── Booking.Persistence.csproj │ │ ├── BookingDbContext.cs │ │ ├── Configurations │ │ │ ├── BookingOrderConfiguration.cs │ │ │ └── BookingOrderDetailConfiguration.cs │ │ ├── Migrations │ │ │ ├── 20190221040547_InitialBooking.Designer.cs │ │ │ ├── 20190221040547_InitialBooking.cs │ │ │ ├── 20190225040122_createandupdatedates.Designer.cs │ │ │ ├── 20190225040122_createandupdatedates.cs │ │ │ ├── 20190308022413_OrderStatus.Designer.cs │ │ │ ├── 20190308022413_OrderStatus.cs │ │ │ └── BookingDbContextModelSnapshot.cs │ │ └── Repositories │ │ │ └── BookingRepository.cs │ └── Booking.Tests │ │ ├── Booking.Tests.csproj │ │ ├── FunctionalTests │ │ ├── Common │ │ │ ├── CustomWebApplicationFactory.cs │ │ │ └── Utilities.cs │ │ └── Controllers │ │ │ └── Booking │ │ │ └── Create.cs │ │ └── UnitTests │ │ └── Application │ │ ├── Booking │ │ ├── Commands │ │ │ └── CreateBookingCommandHandlerTests.cs │ │ └── Queries │ │ │ └── GetBookingQueryHandlerTests.cs │ │ └── Infrastructure │ │ ├── BookingContextFactory.cs │ │ ├── CommandTestBase.cs │ │ └── QueryTestFixture.cs ├── Payment │ ├── Payment.API │ │ ├── Connected Services │ │ │ └── Application Insights │ │ │ │ └── ConnectedService.json │ │ ├── Controllers │ │ │ └── PaymentController.cs │ │ ├── Dockerfile │ │ ├── Payment.API.csproj │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Startup.cs │ │ ├── appsettings.Development.json │ │ ├── appsettings.Production.json │ │ └── appsettings.json │ ├── Payment.Application │ │ ├── DTO │ │ │ ├── PaymentDTO.cs │ │ │ └── PaymentStatusDTO.cs │ │ ├── IntegrationEvents │ │ │ └── PaymentProcessedIntegrationEvent.cs │ │ ├── Interface │ │ │ ├── IPaymentExternalGateway.cs │ │ │ └── IPaymentService.cs │ │ ├── Payment.Application.csproj │ │ └── PaymentService │ │ │ └── PaymentService.cs │ ├── Payment.Domain │ │ ├── Entities │ │ │ ├── Payments.cs │ │ │ └── PaymetStatus.cs │ │ ├── Interfaces │ │ │ └── IPaymentsRepository.cs │ │ └── Payment.Domain.csproj │ ├── Payment.Infrastructure │ │ ├── Payment.Infrastructure.csproj │ │ └── PaymentProcessing │ │ │ └── PaymentExternalGateway.cs │ ├── Payment.Persistence │ │ ├── Configurations │ │ │ └── PaymentsConfiguration.cs │ │ ├── Migrations │ │ │ ├── 20190221045816_InitialPayments.Designer.cs │ │ │ ├── 20190221045816_InitialPayments.cs │ │ │ ├── 20190224235305_fixes.Designer.cs │ │ │ ├── 20190224235305_fixes.cs │ │ │ ├── 20190225025121_customerid.Designer.cs │ │ │ ├── 20190225025121_customerid.cs │ │ │ ├── 20190225035828_createandupdatedates.Designer.cs │ │ │ ├── 20190225035828_createandupdatedates.cs │ │ │ └── PaymentDbContextModelSnapshot.cs │ │ ├── Payment.Persistence.csproj │ │ ├── PaymentDbContext.cs │ │ └── Repositories │ │ │ └── PaymentsRepository.cs │ └── Payment.Tests │ │ ├── FunctionalTests │ │ ├── Common │ │ │ ├── CustomWebApplicationFactory.cs │ │ │ └── Utilities.cs │ │ └── Controllers │ │ │ └── Payment │ │ │ └── Create.cs │ │ ├── Payment.Tests.csproj │ │ └── UnitTests │ │ └── Application │ │ ├── Infrastructure │ │ ├── PaymentContextFactory.cs │ │ └── PaymentTestFixture.cs │ │ └── Payment │ │ └── PaymentServiceTest.cs ├── ReadProjections │ └── ReadModel.AzFn │ │ ├── .gitignore │ │ ├── DB │ │ └── EventStore.cs │ │ ├── Events │ │ ├── Aggregate.cs │ │ ├── BookingAddIntegrationEvent.cs │ │ ├── OrderDeliveredIntegrationEvent.cs │ │ ├── OrderPickedIntegrationEvent.cs │ │ ├── OrderStatusChangedIntegrationEvent.cs │ │ ├── OrderTransitIntegrationEvent.cs │ │ └── PaymentProcessedIntegrationEvent.cs │ │ ├── Model │ │ └── AggregateEvent.cs │ │ ├── Properties │ │ └── PublishProfiles │ │ │ └── MicroCourerisFunctionApp - Web Deploy.pubxml │ │ ├── ReadModel.AzFn.csproj │ │ ├── Redis │ │ └── RedisCacheService.cs │ │ ├── UpdateCache.cs │ │ └── host.json ├── Shipping │ ├── Shipping.API │ │ ├── Dockerfile │ │ ├── Program.cs │ │ ├── Properties │ │ │ └── launchSettings.json │ │ ├── Shipping.API.csproj │ │ ├── Startup.cs │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ ├── Shipping.Application │ │ └── Shipping.Application.csproj │ ├── Shipping.Domain │ │ ├── Entities │ │ │ ├── ShippingStatus.cs │ │ │ ├── Shippings.cs │ │ │ └── ShippingsHistory.cs │ │ ├── Interfaces │ │ │ └── IShippingRepository.cs │ │ └── Shipping.Domain.csproj │ ├── Shipping.Persistence │ │ ├── Migrations │ │ │ ├── 20190907134832_ShippingTablesAdd.Designer.cs │ │ │ ├── 20190907134832_ShippingTablesAdd.cs │ │ │ └── ShippingDbContextModelSnapshot.cs │ │ ├── Shipping.Persistence.csproj │ │ └── ShippingDbContext.cs │ └── Shipping.Tests │ │ └── Shipping.Tests.csproj └── Tracking │ ├── Tracking.API │ ├── Connected Services │ │ └── Application Insights │ │ │ └── ConnectedService.json │ ├── Controllers │ │ └── TrackingController.cs │ ├── Dockerfile │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Startup.cs │ ├── Tracking.API.csproj │ ├── appsettings.Development.json │ ├── appsettings.Production.json │ └── appsettings.json │ ├── Tracking.Application │ ├── DTO │ │ └── TrackingDTO.cs │ ├── IntegrationEvents │ │ ├── BookingAddIntegrationEvent.cs │ │ ├── BookingAddIntegrationEventHandler.cs │ │ ├── OrderDeliveredIntegrationEvent.cs │ │ ├── OrderDeliveredIntegrationEventHandler.cs │ │ ├── OrderPickedIntegrationEvent.cs │ │ ├── OrderPickedIntegrationEventHandler.cs │ │ ├── OrderStatusChangedIntegrationEvent.cs │ │ ├── OrderTransitIntegrationEvent.cs │ │ ├── OrderTransitIntegrationEventHandler.cs │ │ ├── PaymentProcessedIntegrationEvent.cs │ │ └── PaymentProcessedIntegrationEventHandler.cs │ ├── Interface │ │ └── ITrackingService.cs │ ├── Tracking.Application.csproj │ └── TrackingServices │ │ ├── TrackingSerivceWithoutCache.cs │ │ └── TrackingService.cs │ ├── Tracking.Common │ ├── Tracking.Common.csproj │ └── TypeResolver.cs │ ├── Tracking.Domain │ ├── AggregatesModel │ │ └── TrackingAggregate │ │ │ └── Track.cs │ ├── Events │ │ ├── BookingCreated.cs │ │ ├── EventBase.cs │ │ ├── OrderDelivered.cs │ │ ├── OrderInTransit.cs │ │ ├── OrderPicked.cs │ │ └── PaymentProcessed.cs │ ├── Interfaces │ │ ├── ICahce.cs │ │ └── ITrackingRepository.cs │ ├── Model │ │ └── OrderHistory.cs │ └── Tracking.Domain.csproj │ ├── Tracking.Persistence │ ├── Model │ │ ├── Aggregate.cs │ │ └── AggregateEvent.cs │ ├── Repositories │ │ └── TrackingRepository.cs │ └── Tracking.Persistence.csproj │ └── Tracking.Tests │ ├── Tracking.Tests.csproj │ └── UnitTests │ ├── Infrastructure │ └── TrackingContextFactory.cs │ └── Tracking │ └── TrackingServiceTests.cs ├── ShippingSimulation └── OrderShipping │ ├── App.config │ ├── Events │ ├── OrderDeliveredIntegrationEvent.cs │ ├── OrderPickedIntegrationEvent.cs │ └── OrderTransitIntegrationEvent.cs │ ├── OrderShipping.csproj │ ├── OrderStatusUpdate.Designer.cs │ ├── OrderStatusUpdate.cs │ ├── OrderStatusUpdate.resx │ ├── Program.cs │ ├── Properties │ ├── AssemblyInfo.cs │ ├── Resources.Designer.cs │ ├── Resources.resx │ ├── Settings.Designer.cs │ └── Settings.settings │ └── packages.config ├── TrackingDockerfile ├── Web └── MicroCourier.Web │ ├── Commands │ └── CreateBookingCommand.cs │ ├── Connected Services │ └── Application Insights │ │ └── ConnectedService.json │ ├── Controllers │ ├── BookingController.cs │ ├── HomeController.cs │ ├── PaymentController.cs │ └── TrackingController.cs │ ├── DTO │ ├── BookingOrderDTO.cs │ ├── BookingOrderDetailDTO.cs │ ├── PaymentDTO.cs │ └── TrackingDTO.cs │ ├── Dockerfile │ ├── MicroCourier.Web.csproj │ ├── Models │ └── ErrorViewModel.cs │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── RESTClients │ ├── BookingAPI.cs │ ├── IBookingAPI.cs │ ├── IPaymentAPI.cs │ ├── ITrackingAPI.cs │ ├── PaymentAPI.cs │ └── TrackingAPI.cs │ ├── Startup.cs │ ├── Views │ ├── Home │ │ ├── Booking.cshtml │ │ ├── Index.cshtml │ │ ├── Payment.cshtml │ │ ├── Privacy.cshtml │ │ └── Tracking.cshtml │ ├── Shared │ │ ├── Error.cshtml │ │ ├── _CookieConsentPartial.cshtml │ │ ├── _Layout.cshtml │ │ └── _ValidationScriptsPartial.cshtml │ ├── _ViewImports.cshtml │ └── _ViewStart.cshtml │ └── wwwroot │ ├── css │ ├── MicroCourierStyle.css │ └── site.css │ ├── favicon.ico │ ├── js │ └── site.js │ └── lib │ ├── bootstrap │ ├── LICENSE │ └── dist │ │ ├── css │ │ ├── bootstrap-grid.css │ │ ├── bootstrap-grid.css.map │ │ ├── bootstrap-grid.min.css │ │ ├── bootstrap-grid.min.css.map │ │ ├── bootstrap-reboot.css │ │ ├── bootstrap-reboot.css.map │ │ ├── bootstrap-reboot.min.css │ │ ├── bootstrap-reboot.min.css.map │ │ ├── bootstrap.css │ │ ├── bootstrap.css.map │ │ ├── bootstrap.min.css │ │ └── bootstrap.min.css.map │ │ └── js │ │ ├── bootstrap.bundle.js │ │ ├── bootstrap.bundle.js.map │ │ ├── bootstrap.bundle.min.js │ │ ├── bootstrap.bundle.min.js.map │ │ ├── bootstrap.js │ │ ├── bootstrap.js.map │ │ ├── bootstrap.min.js │ │ └── bootstrap.min.js.map │ ├── jquery-validation-unobtrusive │ ├── LICENSE.txt │ ├── jquery.validate.unobtrusive.js │ └── jquery.validate.unobtrusive.min.js │ ├── jquery-validation │ ├── LICENSE.md │ └── dist │ │ ├── additional-methods.js │ │ ├── additional-methods.min.js │ │ ├── jquery.validate.js │ │ └── jquery.validate.min.js │ └── jquery │ ├── LICENSE.txt │ └── dist │ ├── jquery.js │ ├── jquery.min.js │ └── jquery.min.map └── rebuildAllDockerImages.ps1 /.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | .env 3 | .git 4 | .gitignore 5 | .vs 6 | .vscode 7 | */bin 8 | */obj 9 | **/.toolstarget -------------------------------------------------------------------------------- /Solution-Architecture.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImranMA/MicroCouriers/ee5868522336842f727bedcdf3e83f5572d6d2a0/Solution-Architecture.JPG -------------------------------------------------------------------------------- /StartSQLonly.ps1: -------------------------------------------------------------------------------- 1 | echo "=====================" 2 | echo "====== Volumes ======" 3 | echo "=====================" 4 | docker volume create --name=sqlserverdata 5 | 6 | # Rebuild all the services that have changes 7 | # If you want to (re)build only a specific service, go to the src folder and execute `docker-compose build ` 8 | docker-compose -f .\docker-compose-sql.yml up 9 | -------------------------------------------------------------------------------- /StartSolution.ps1: -------------------------------------------------------------------------------- 1 | echo "=====================" 2 | echo "====== Volumes ======" 3 | echo "=====================" 4 | docker volume create --name=sqlserverdata 5 | 6 | # Rebuild all the services that have changes 7 | # If you want to (re)build only a specific service, go to the src folder and execute `docker-compose build ` 8 | docker-compose -f .\docker-compose.yml up 9 | -------------------------------------------------------------------------------- /StopAllContainers.ps1: -------------------------------------------------------------------------------- 1 | # Delete all containers 2 | docker rm $(docker ps -a -q) -f -------------------------------------------------------------------------------- /docker-compose-sql.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | 4 | 5 | sqlserver: 6 | image: microsoft/mssql-server-linux:latest 7 | container_name: sqlserver 8 | volumes: 9 | - sqlserverdata:/var/opt/mssql 10 | ports: 11 | - "1433:1433" 12 | environment: 13 | - ACCEPT_EULA=Y 14 | - MSSQL_PID=Developer 15 | - SA_PASSWORD=99888ukGh43hnDw89Hol8LN21112 16 | 17 | 18 | volumes: 19 | sqlserverdata: 20 | external: true 21 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | services: 3 | 4 | 5 | sqlserver: 6 | image: microsoft/mssql-server-linux:latest 7 | container_name: sqlserver 8 | volumes: 9 | - sqlserverdata:/var/opt/mssql 10 | ports: 11 | - "1433:1433" 12 | environment: 13 | - ACCEPT_EULA=Y 14 | - MSSQL_PID=Developer 15 | - SA_PASSWORD=99888ukGh43hnDw89Hol8LN21112 16 | 17 | 18 | bookingapi: 19 | container_name: bookingapi 20 | image: bookingapi:latest 21 | depends_on: 22 | - sqlserver 23 | ports: 24 | - "5000:80" 25 | environment: 26 | - ASPNETCORE_ENVIRONMENT=Production 27 | 28 | 29 | paymentapi: 30 | container_name: paymentapi 31 | image: paymentapi:latest 32 | depends_on: 33 | - sqlserver 34 | ports: 35 | - "5001:80" 36 | environment: 37 | - ASPNETCORE_ENVIRONMENT=Production 38 | 39 | 40 | trackingapi: 41 | container_name: trackingapi 42 | image: trackingapi:latest 43 | depends_on: 44 | - sqlserver 45 | ports: 46 | - "5002:80" 47 | environment: 48 | - ASPNETCORE_ENVIRONMENT=Production 49 | 50 | 51 | mcweb: 52 | container_name: mcweb 53 | image: mcweb:latest 54 | depends_on: 55 | - sqlserver 56 | ports: 57 | - "5004:80" 58 | environment: 59 | - ASPNETCORE_ENVIRONMENT=Production 60 | 61 | volumes: 62 | sqlserverdata: 63 | external: true 64 | -------------------------------------------------------------------------------- /k8s/AKS-Deployment-Steps.txt: -------------------------------------------------------------------------------- 1 | 2 | 1 open power shell and login to azure 3 | az login 4 | 5 | 6 | 2 login to your ACR (Azure container Registry) replace [acrname] with your ACR to upload the images 7 | az acr login --name [acrname] 8 | 9 | 3 tag images and push to repo 10 | 11 | 12 | 13 | docker tag trackingapi [acrname].azurecr.io/trackingapi:latest 14 | docker push [acrname].azurecr.io/trackingapi:latest 15 | 16 | 17 | docker tag bookingapi [acrname].azurecr.io/bookingapi:latest 18 | docker push [acrname].azurecr.io/bookingapi:latest 19 | 20 | 21 | docker tag paymentapi [acrname].azurecr.io/paymentapi:latest 22 | docker push [acrname].azurecr.io/paymentapi:latest 23 | 24 | 25 | docker tag mcweb [acrname].azurecr.io/mcweb:latest 26 | docker push [acrname].azurecr.io/mcweb:latest 27 | 28 | 4 Deploy service and deployment manifest 29 | 30 | kubectl apply -f PathtoyourFile\deploymentservices.yaml 31 | kubectl apply -f PathtoyourFile\deployment.yaml 32 | -------------------------------------------------------------------------------- /k8s/configuration/Booking/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "MicroCouriersDataBase": "connectionstring" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "AllowedHosts": "*", 11 | "EventBusConnection": "", 12 | "SubscriptionClientName": "booking", 13 | "ApplicationInsights": { 14 | "InstrumentationKey": "" 15 | } 16 | } 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /k8s/configuration/Payment/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "MicroCouriersDataBase": "connectionstring" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "AllowedHosts": "*", 11 | "EventBusConnection": "", 12 | "SubscriptionClientName": "payment", 13 | "ApplicationInsights": { 14 | "InstrumentationKey": "" 15 | } 16 | } -------------------------------------------------------------------------------- /k8s/configuration/Tracking/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "EventStoreCN": "connectionstring" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "cache": { 11 | "REDIS": "" 12 | }, 13 | "AllowedHosts": "*", 14 | "EventBusConnection": "", 15 | "SubscriptionClientName": "tracking", 16 | "ApplicationInsights": { 17 | "InstrumentationKey": "" 18 | } 19 | } -------------------------------------------------------------------------------- /k8s/configuration/Web/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Debug", 5 | "System": "Information", 6 | "Microsoft": "Information" 7 | } 8 | }, 9 | "APIServiceLocations": { 10 | "BookingAPI": "bookingapi:5000", 11 | "PaymentAPI": "paymentapi:5001", 12 | "TrackingAPI": "trackingapi:5002" 13 | }, 14 | "AllowedHosts": "*", 15 | "ApplicationInsights": { 16 | "InstrumentationKey": "" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /k8s/deploymentservices.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: trackingapi 6 | spec: 7 | ports: 8 | - port: 5002 9 | targetPort: 80 10 | selector: 11 | app: trackingapi 12 | type: ClusterIP 13 | 14 | 15 | 16 | 17 | --- 18 | apiVersion: v1 19 | kind: Service 20 | metadata: 21 | name: paymentapi 22 | spec: 23 | ports: 24 | - port: 5001 25 | targetPort: 80 26 | selector: 27 | app: paymentapi 28 | type: ClusterIP 29 | 30 | 31 | 32 | 33 | 34 | --- 35 | apiVersion: v1 36 | kind: Service 37 | metadata: 38 | name: bookingapi 39 | spec: 40 | ports: 41 | - port: 5000 42 | targetPort: 80 43 | selector: 44 | app: bookingapi 45 | type: ClusterIP 46 | 47 | 48 | 49 | 50 | --- 51 | apiVersion: v1 52 | kind: Service 53 | metadata: 54 | name: mcweb 55 | spec: 56 | ports: 57 | - port: 5004 58 | targetPort: 80 59 | selector: 60 | app: mcweb 61 | type: ClusterIP 62 | -------------------------------------------------------------------------------- /src/BookingDockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base 2 | WORKDIR /app 3 | EXPOSE 5000 4 | 5 | FROM microsoft/dotnet:2.2-sdk AS build 6 | WORKDIR /src 7 | 8 | COPY ["BuildingBlocks/EventBus/EventBus/EventBus.csproj", "BuildingBlocks/EventBus/EventBus/"] 9 | COPY ["BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj", "BuildingBlocks/EventBus/EventBusServiceBus/"] 10 | COPY ["BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj", "BuildingBlocks/EventBus/IntegrationEventLogEF/"] 11 | 12 | COPY ["Services/Booking/Booking.API/Booking.API.csproj", "Services/Booking/Booking.API/"] 13 | COPY ["Services/Booking/Booking.Application/Booking.Application.csproj", "Services/Booking/Booking.Application/"] 14 | COPY ["Services/Booking/Booking.Common/Booking.Common.csproj", "Services/Booking/Booking.Common/"] 15 | COPY ["Services/Booking/Booking.Domain/Booking.Domain.csproj", "Services/Booking/Booking.Domain/"] 16 | COPY ["Services/Booking/Booking.Infrastructure/Booking.Infrastructure.csproj", "Services/Booking/Booking.Infrastructure/"] 17 | COPY ["Services/Booking/Booking.Persistence/Booking.Persistence.csproj", "Services/Booking/Booking.Persistence/"] 18 | 19 | 20 | 21 | RUN dotnet restore "Services/Booking/Booking.API/Booking.API.csproj" 22 | 23 | 24 | COPY . . 25 | 26 | 27 | WORKDIR "/src/Services/Booking/Booking.API" 28 | 29 | 30 | RUN dotnet build "Booking.API.csproj" -c Release -o /app 31 | 32 | FROM build AS publish 33 | RUN dotnet publish "Booking.API.csproj" -c Release -o /app 34 | 35 | FROM base AS final 36 | WORKDIR /app 37 | COPY --from=publish /app . 38 | 39 | 40 | ENTRYPOINT ["dotnet", "Booking.API.dll"] -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBus/Abstractions/IDynamicIntegrationEventHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions 8 | { 9 | public interface IDynamicIntegrationEventHandler 10 | { 11 | Task Handle(dynamic eventData); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBus/Abstractions/IEventBus.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | 4 | namespace Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions 5 | { 6 | public interface IEventBus 7 | { 8 | void Publish(IntegrationEvent @event); 9 | 10 | void Subscribe() 11 | where T : IntegrationEvent 12 | where TH : IIntegrationEventHandler; 13 | 14 | void SubscribeDynamic(string eventName) 15 | where TH : IDynamicIntegrationEventHandler; 16 | 17 | void UnsubscribeDynamic(string eventName) 18 | where TH : IDynamicIntegrationEventHandler; 19 | 20 | void Unsubscribe() 21 | where TH : IIntegrationEventHandler 22 | where T : IntegrationEvent; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBus/Abstractions/IIntegrationEventHandler.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System.Threading.Tasks; 3 | 4 | namespace Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions 5 | { 6 | public interface IIntegrationEventHandler : IIntegrationEventHandler 7 | where TIntegrationEvent: IntegrationEvent 8 | { 9 | Task Handle(TIntegrationEvent @event); 10 | } 11 | 12 | public interface IIntegrationEventHandler 13 | { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBus/EventBus.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Microsoft.eShopOnContainers.BuildingBlocks.EventBus 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBus/Events/IntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Newtonsoft.Json; 3 | 4 | namespace Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events 5 | { 6 | public class IntegrationEvent 7 | { 8 | public IntegrationEvent() 9 | { 10 | Id = Guid.NewGuid(); 11 | CreationDate = DateTime.UtcNow; 12 | } 13 | 14 | [JsonConstructor] 15 | public IntegrationEvent(Guid id, DateTime createDate) 16 | { 17 | Id = id; 18 | CreationDate = createDate; 19 | } 20 | 21 | [JsonProperty] 22 | public Guid Id { get; private set; } 23 | 24 | [JsonProperty] 25 | public DateTime CreationDate { get; private set; } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBus/IEventBusSubscriptionsManager.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions; 2 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 3 | using System; 4 | using System.Collections.Generic; 5 | using static Microsoft.MicroCouriers.BuildingBlocks.EventBus.InMemoryEventBusSubscriptionsManager; 6 | 7 | namespace Microsoft.MicroCouriers.BuildingBlocks.EventBus 8 | { 9 | public interface IEventBusSubscriptionsManager 10 | { 11 | bool IsEmpty { get; } 12 | event EventHandler OnEventRemoved; 13 | void AddDynamicSubscription(string eventName) 14 | where TH : IDynamicIntegrationEventHandler; 15 | 16 | void AddSubscription() 17 | where T : IntegrationEvent 18 | where TH : IIntegrationEventHandler; 19 | 20 | void RemoveSubscription() 21 | where TH : IIntegrationEventHandler 22 | where T : IntegrationEvent; 23 | void RemoveDynamicSubscription(string eventName) 24 | where TH : IDynamicIntegrationEventHandler; 25 | 26 | bool HasSubscriptionsForEvent() where T : IntegrationEvent; 27 | bool HasSubscriptionsForEvent(string eventName); 28 | Type GetEventTypeByName(string eventName); 29 | void Clear(); 30 | IEnumerable GetHandlersForEvent() where T : IntegrationEvent; 31 | IEnumerable GetHandlersForEvent(string eventName); 32 | string GetEventKey(); 33 | } 34 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBus/SubscriptionInfo.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Microsoft.MicroCouriers.BuildingBlocks.EventBus 4 | { 5 | public partial class InMemoryEventBusSubscriptionsManager : IEventBusSubscriptionsManager 6 | { 7 | public class SubscriptionInfo 8 | { 9 | public bool IsDynamic { get; } 10 | public Type HandlerType{ get; } 11 | 12 | private SubscriptionInfo(bool isDynamic, Type handlerType) 13 | { 14 | IsDynamic = isDynamic; 15 | HandlerType = handlerType; 16 | } 17 | 18 | public static SubscriptionInfo Dynamic(Type handlerType) 19 | { 20 | return new SubscriptionInfo(true, handlerType); 21 | } 22 | public static SubscriptionInfo Typed(Type handlerType) 23 | { 24 | return new SubscriptionInfo(false, handlerType); 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBusServiceBus/DefaultServiceBusPersisterConnection.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.ServiceBus; 2 | using Microsoft.Extensions.Logging; 3 | using System; 4 | 5 | namespace Microsoft.MicroCouriers.BuildingBlocks.EventBusServiceBus 6 | { 7 | public class DefaultServiceBusPersisterConnection :IServiceBusPersisterConnection 8 | { 9 | private readonly ILogger _logger; 10 | private readonly ServiceBusConnectionStringBuilder _serviceBusConnectionStringBuilder; 11 | private ITopicClient _topicClient; 12 | 13 | bool _disposed; 14 | 15 | public DefaultServiceBusPersisterConnection(ServiceBusConnectionStringBuilder serviceBusConnectionStringBuilder, 16 | ILogger logger) 17 | { 18 | _logger = logger ?? throw new ArgumentNullException(nameof(logger)); 19 | 20 | _serviceBusConnectionStringBuilder = serviceBusConnectionStringBuilder ?? 21 | throw new ArgumentNullException(nameof(serviceBusConnectionStringBuilder)); 22 | _topicClient = new TopicClient(_serviceBusConnectionStringBuilder, RetryPolicy.Default); 23 | } 24 | 25 | public ServiceBusConnectionStringBuilder ServiceBusConnectionStringBuilder => _serviceBusConnectionStringBuilder; 26 | 27 | public ITopicClient CreateModel() 28 | { 29 | if(_topicClient.IsClosedOrClosing) 30 | { 31 | _topicClient = new TopicClient(_serviceBusConnectionStringBuilder, RetryPolicy.Default); 32 | } 33 | 34 | return _topicClient; 35 | } 36 | 37 | public void Dispose() 38 | { 39 | if (_disposed) return; 40 | 41 | _disposed = true; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Microsoft.eShopOnContainers.BuildingBlocks.EventBusServiceBus 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/EventBusServiceBus/IServiceBusPersisterConnection.cs: -------------------------------------------------------------------------------- 1 | namespace Microsoft.MicroCouriers.BuildingBlocks.EventBusServiceBus 2 | { 3 | using Microsoft.Azure.ServiceBus; 4 | using System; 5 | 6 | public interface IServiceBusPersisterConnection : IDisposable 7 | { 8 | ServiceBusConnectionStringBuilder ServiceBusConnectionStringBuilder { get; } 9 | 10 | ITopicClient CreateModel(); 11 | } 12 | } -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/IntegrationEventLogEF/EventStateEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF 6 | { 7 | public enum EventStateEnum 8 | { 9 | NotPublished = 0, 10 | InProgress = 1, 11 | Published = 2, 12 | PublishedFailed = 3 13 | } 14 | 15 | 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | 7 | namespace Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF 8 | { 9 | public class IntegrationEventLogContext : DbContext 10 | { 11 | public IntegrationEventLogContext(DbContextOptions options) : base(options) 12 | { 13 | } 14 | 15 | public DbSet IntegrationEventLogs { get; set; } 16 | 17 | protected override void OnModelCreating(ModelBuilder builder) 18 | { 19 | builder.Entity(ConfigureIntegrationEventLogEntry); 20 | } 21 | 22 | void ConfigureIntegrationEventLogEntry(EntityTypeBuilder builder) 23 | { 24 | builder.ToTable("IntegrationEventLog"); 25 | 26 | builder.HasKey(e => e.EventId); 27 | 28 | builder.Property(e => e.EventId) 29 | .IsRequired(); 30 | 31 | builder.Property(e => e.Content) 32 | .IsRequired(); 33 | 34 | builder.Property(e => e.CreationTime) 35 | .IsRequired(); 36 | 37 | builder.Property(e => e.State) 38 | .IsRequired(); 39 | 40 | builder.Property(e => e.TimesSent) 41 | .IsRequired(); 42 | 43 | builder.Property(e => e.EventTypeName) 44 | .IsRequired(); 45 | 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netstandard2.0 5 | Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEntry.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Newtonsoft.Json; 5 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 6 | using System.Linq; 7 | using System.ComponentModel.DataAnnotations.Schema; 8 | using System.Reflection; 9 | 10 | namespace Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF 11 | { 12 | public class IntegrationEventLogEntry 13 | { 14 | private IntegrationEventLogEntry() { } 15 | public IntegrationEventLogEntry(IntegrationEvent @event) 16 | { 17 | EventId = @event.Id; 18 | CreationTime = @event.CreationDate; 19 | EventTypeName = @event.GetType().FullName; 20 | Content = JsonConvert.SerializeObject(@event); 21 | State = EventStateEnum.NotPublished; 22 | TimesSent = 0; 23 | } 24 | public Guid EventId { get; private set; } 25 | public string EventTypeName { get; private set; } 26 | [NotMapped] 27 | public string EventTypeShortName => EventTypeName.Split('.')?.Last(); 28 | [NotMapped] 29 | public IntegrationEvent IntegrationEvent { get; private set; } 30 | public EventStateEnum State { get; set; } 31 | public int TimesSent { get; set; } 32 | public DateTime CreationTime { get; private set; } 33 | public string Content { get; private set; } 34 | 35 | public IntegrationEventLogEntry DeserializeJsonContent(Type type) 36 | { 37 | IntegrationEvent = JsonConvert.DeserializeObject(Content, type) as IntegrationEvent; 38 | return this; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/IntegrationEventLogEF/Services/IIntegrationEventLogService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Data.Common; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF.Services 9 | { 10 | public interface IIntegrationEventLogService 11 | { 12 | Task> RetrieveEventLogsPendingToPublishAsync(); 13 | Task SaveEventAsync(IntegrationEvent @event, DbTransaction transaction); 14 | Task MarkEventAsPublishedAsync(Guid eventId); 15 | Task MarkEventAsInProgressAsync(Guid eventId); 16 | Task MarkEventAsFailedAsync(Guid eventId); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/BuildingBlocks/EventBus/IntegrationEventLogEF/Utilities/ResilientTransaction.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Microsoft.EntityFrameworkCore.Storage; 3 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 4 | using Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF.Services; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Data.Common; 8 | using System.Text; 9 | using System.Threading.Tasks; 10 | 11 | namespace Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF.Utilities 12 | { 13 | public class ResilientTransaction 14 | { 15 | private DbContext _context; 16 | private ResilientTransaction(DbContext context) => 17 | _context = context ?? throw new ArgumentNullException(nameof(context)); 18 | 19 | public static ResilientTransaction New (DbContext context) => 20 | new ResilientTransaction(context); 21 | 22 | public async Task ExecuteAsync(Func action) 23 | { 24 | //Use of an EF Core resiliency strategy when using multiple DbContexts within an explicit BeginTransaction(): 25 | //See: https://docs.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency 26 | var strategy = _context.Database.CreateExecutionStrategy(); 27 | await strategy.ExecuteAsync(async () => 28 | { 29 | using (var transaction = _context.Database.BeginTransaction()) 30 | { 31 | await action(); 32 | transaction.Commit(); 33 | } 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/McWebDockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base 2 | WORKDIR /app 3 | EXPOSE 5004 4 | 5 | FROM microsoft/dotnet:2.2-sdk AS build 6 | WORKDIR /src 7 | 8 | 9 | COPY ["Web/MicroCourier.Web/MicroCourier.Web.csproj", "Web/MicroCourier.Web/"] 10 | RUN dotnet restore "Web/MicroCourier.Web/MicroCourier.Web.csproj" 11 | 12 | 13 | COPY . . 14 | 15 | 16 | WORKDIR "/src/Web/MicroCourier.Web" 17 | 18 | 19 | RUN dotnet build "MicroCourier.Web.csproj" -c Release -o /app 20 | 21 | FROM build AS publish 22 | RUN dotnet publish "MicroCourier.Web.csproj" -c Release -o /app 23 | 24 | FROM base AS final 25 | WORKDIR /app 26 | COPY --from=publish /app . 27 | 28 | 29 | 30 | ENTRYPOINT ["dotnet", "MicroCourier.Web.dll"] -------------------------------------------------------------------------------- /src/PaymentDockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base 2 | WORKDIR /app 3 | EXPOSE 5001 4 | 5 | FROM microsoft/dotnet:2.2-sdk AS build 6 | WORKDIR /src 7 | 8 | COPY ["BuildingBlocks/EventBus/EventBus/EventBus.csproj", "BuildingBlocks/EventBus/EventBus/"] 9 | COPY ["BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj", "BuildingBlocks/EventBus/EventBusServiceBus/"] 10 | COPY ["BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj", "BuildingBlocks/EventBus/IntegrationEventLogEF/"] 11 | 12 | COPY ["Services/Payment/Payment.API/Payment.API.csproj", "Services/Payment/Payment.API/"] 13 | COPY ["Services/Payment/Payment.Application/Payment.Application.csproj", "Services/Payment/Payment.Application/"] 14 | COPY ["Services/Payment/Payment.Domain/Payment.Domain.csproj", "Services/Payment/Payment.Domain/"] 15 | COPY ["Services/Payment/Payment.Infrastructure/Payment.Infrastructure.csproj", "Services/Payment/Payment.Infrastructure/"] 16 | COPY ["Services/Payment/Payment.Persistence/Payment.Persistence.csproj", "Services/Payment/Payment.Persistence/"] 17 | 18 | 19 | RUN dotnet restore "Services/Payment/Payment.API/Payment.API.csproj" 20 | 21 | 22 | COPY . . 23 | 24 | 25 | WORKDIR "/src/Services/Payment/Payment.API" 26 | 27 | 28 | RUN dotnet build "Payment.API.csproj" -c Release -o /app 29 | 30 | FROM build AS publish 31 | RUN dotnet publish "Payment.API.csproj" -c Release -o /app 32 | 33 | FROM base AS final 34 | WORKDIR /app 35 | COPY --from=publish /app . 36 | 37 | 38 | ENTRYPOINT ["dotnet", "Payment.API.dll"] -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.14.11009.1", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Controllers/BaseController.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using Microsoft.AspNetCore.Mvc; 3 | using Microsoft.Extensions.DependencyInjection; 4 | 5 | 6 | namespace Booking.API.Controllers 7 | { 8 | [ApiController] 9 | [Route("api/[controller]/[action]")] 10 | public abstract class BaseController : Controller 11 | { 12 | private IMediator _mediator; 13 | 14 | protected IMediator Mediator => _mediator ?? (_mediator = HttpContext.RequestServices.GetService()); 15 | } 16 | } -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/dotnet:2.2-sdk AS build 6 | WORKDIR /src 7 | COPY ["src/Services/Booking/Booking.API/Booking.API.csproj", "src/Services/Booking/Booking.API/"] 8 | RUN dotnet restore "src/Services/Booking/Booking.API/Booking.API.csproj" 9 | COPY . . 10 | WORKDIR "/src/src/Services/Booking/Booking.API" 11 | RUN dotnet build "Booking.API.csproj" -c Release -o /app 12 | 13 | FROM build AS publish 14 | RUN dotnet publish "Booking.API.csproj" -c Release -o /app 15 | 16 | FROM base AS final 17 | WORKDIR /app 18 | COPY --from=publish /app . 19 | ENTRYPOINT ["dotnet", "Booking.API.dll"] -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Infrastructure/AutofacModules/ApplicationModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Booking.Application.Booking.Commands.CreateBooking; 3 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Reflection; 8 | using System.Threading.Tasks; 9 | 10 | namespace Booking.API.Infrastructure.AutofacModules 11 | { 12 | public class ApplicationModule 13 | : Autofac.Module 14 | { 15 | 16 | public string QueriesConnectionString { get; } 17 | 18 | public ApplicationModule(string qconstr) 19 | { 20 | QueriesConnectionString = qconstr; 21 | 22 | } 23 | 24 | protected override void Load(ContainerBuilder builder) 25 | { 26 | 27 | builder.RegisterAssemblyTypes(typeof(CreateBookingCommandHandler).GetTypeInfo().Assembly) 28 | .AsClosedTypesOf(typeof(IIntegrationEventHandler<>)); 29 | 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Infrastructure/AutofacModules/MediatorModule.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Booking.Application.Behaviors; 3 | using Booking.Application.Booking.Commands.CreateBooking; 4 | using MediatR; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Reflection; 9 | using System.Threading.Tasks; 10 | 11 | namespace Booking.API.Infrastructure.AutofacModules 12 | { 13 | public class MediatorModule : Autofac.Module 14 | { 15 | protected override void Load(ContainerBuilder builder) 16 | { 17 | // builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly) 18 | // .AsImplementedInterfaces(); 19 | 20 | // Register all the Command classes (they implement IRequestHandler) in assembly holding the Commands 21 | // builder.RegisterAssemblyTypes(typeof(CreateBookingCommand).GetTypeInfo().Assembly) 22 | // .AsClosedTypesOf(typeof(IRequestHandler<,>)); 23 | 24 | // Register the DomainEventHandler classes (they implement INotificationHandler<>) in assembly holding the Domain Events 25 | 26 | 27 | /* 28 | builder.Register(context => 29 | { 30 | var componentContext = context.Resolve(); 31 | return t => { object o; return componentContext.TryResolve(t, out o) ? o : null; }; 32 | });*/ 33 | 34 | // builder.RegisterGeneric(typeof(LoggingBehavior<,>)).As(typeof(IPipelineBehavior<,>)); 35 | // builder.RegisterGeneric(typeof(ValidatorBehavior<,>)).As(typeof(IPipelineBehavior<,>)); 36 | //builder.RegisterGeneric(typeof(TransactionBehaviour<,>)).As(typeof(IPipelineBehavior<,>)); 37 | 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Migrations/20190219102837_IntegrationEventLogInitial.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | using Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF; 9 | 10 | namespace Booking.API.Migrations 11 | { 12 | [DbContext(typeof(IntegrationEventLogContext))] 13 | [Migration("20190219102837_IntegrationEventLogInitial")] 14 | partial class IntegrationEventLogInitial 15 | { 16 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "2.2.1-servicing-10028") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF.IntegrationEventLogEntry", b => 25 | { 26 | b.Property("EventId") 27 | .ValueGeneratedOnAdd(); 28 | 29 | b.Property("Content") 30 | .IsRequired(); 31 | 32 | b.Property("CreationTime"); 33 | 34 | b.Property("EventTypeName") 35 | .IsRequired(); 36 | 37 | b.Property("State"); 38 | 39 | b.Property("TimesSent"); 40 | 41 | b.HasKey("EventId"); 42 | 43 | b.ToTable("IntegrationEventLog"); 44 | }); 45 | #pragma warning restore 612, 618 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Migrations/20190219102837_IntegrationEventLogInitial.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | namespace Booking.API.Migrations 5 | { 6 | public partial class IntegrationEventLogInitial : Migration 7 | { 8 | protected override void Up(MigrationBuilder migrationBuilder) 9 | { 10 | migrationBuilder.CreateTable( 11 | name: "IntegrationEventLog", 12 | columns: table => new 13 | { 14 | EventId = table.Column(nullable: false), 15 | EventTypeName = table.Column(nullable: false), 16 | State = table.Column(nullable: false), 17 | TimesSent = table.Column(nullable: false), 18 | CreationTime = table.Column(nullable: false), 19 | Content = table.Column(nullable: false) 20 | }, 21 | constraints: table => 22 | { 23 | table.PrimaryKey("PK_IntegrationEventLog", x => x.EventId); 24 | }); 25 | } 26 | 27 | protected override void Down(MigrationBuilder migrationBuilder) 28 | { 29 | migrationBuilder.DropTable( 30 | name: "IntegrationEventLog"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Migrations/IntegrationEventLogContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 7 | using Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF; 8 | 9 | namespace Booking.API.Migrations 10 | { 11 | [DbContext(typeof(IntegrationEventLogContext))] 12 | partial class IntegrationEventLogContextModelSnapshot : ModelSnapshot 13 | { 14 | protected override void BuildModel(ModelBuilder modelBuilder) 15 | { 16 | #pragma warning disable 612, 618 17 | modelBuilder 18 | .HasAnnotation("ProductVersion", "2.2.1-servicing-10028") 19 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 20 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 21 | 22 | modelBuilder.Entity("Microsoft.MicroCouriers.BuildingBlocks.IntegrationEventLogEF.IntegrationEventLogEntry", b => 23 | { 24 | b.Property("EventId") 25 | .ValueGeneratedOnAdd(); 26 | 27 | b.Property("Content") 28 | .IsRequired(); 29 | 30 | b.Property("CreationTime"); 31 | 32 | b.Property("EventTypeName") 33 | .IsRequired(); 34 | 35 | b.Property("State"); 36 | 37 | b.Property("TimesSent"); 38 | 39 | b.HasKey("EventId"); 40 | 41 | b.ToTable("IntegrationEventLog"); 42 | }); 43 | #pragma warning restore 612, 618 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Booking.Persistence; 3 | using Microsoft.AspNetCore; 4 | using Microsoft.AspNetCore.Hosting; 5 | using Microsoft.EntityFrameworkCore; 6 | using Microsoft.Extensions.DependencyInjection; 7 | using Polly; 8 | 9 | namespace Booking.API 10 | { 11 | public class Program 12 | { 13 | public static void Main(string[] args) 14 | { 15 | //Migrate/Create the database if it doesn't exists 16 | var host = CreateWebHostBuilder(args).Build(); 17 | 18 | using (var scope = host.Services.CreateScope()) 19 | { 20 | try 21 | { 22 | var context = scope.ServiceProvider.GetService(); 23 | 24 | var concreteContext = (BookingDbContext)context; 25 | 26 | //We are using Linux SQL container and it may take some time to fireup . 27 | //We are retrying the connectivity 28 | Policy 29 | .Handle() 30 | .WaitAndRetry(5, r => TimeSpan.FromSeconds(10)) 31 | .Execute(() => concreteContext.Database.Migrate()); 32 | } 33 | catch (Exception) 34 | { 35 | 36 | } 37 | } 38 | 39 | host.Run(); 40 | } 41 | 42 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 43 | WebHost.CreateDefaultBuilder(args) 44 | .UseApplicationInsights() 45 | .UseStartup(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:5000", 7 | "sslPort": 0 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "Booking.API": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/booking", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "http://localhost:5000" 28 | }, 29 | "Docker": { 30 | "commandName": "Docker", 31 | "launchBrowser": true, 32 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/api/values" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "MicroCouriersDataBase": "server=localhost,1433;user id=sa;password=99888ukGh43hnDw89Hol8LN21112;database=MicroCouriersBooking;" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "AllowedHosts": "*", 11 | "EventBusConnection": "", 12 | "SubscriptionClientName": "booking", 13 | "ApplicationInsights": { 14 | "InstrumentationKey": "" 15 | } 16 | } 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.API/appsettings.Production.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "MicroCouriersDataBase": "server=sqlserver;user id=sa;password=99888ukGh43hnDw89Hol8LN21112;database=MicroCouriersBooking;" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "AllowedHosts": "*", 11 | "EventBusConnection": "", 12 | "SubscriptionClientName": "booking", 13 | "ApplicationInsights": { 14 | "InstrumentationKey": "" 15 | } 16 | } 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/Booking.Application.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/Booking/Commands/CreateBooking/CreateBookingCommand.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Text; 6 | 7 | namespace Booking.Application.Booking.Commands.CreateBooking 8 | { 9 | public class CreateBookingCommand : IRequest 10 | { 11 | [Required] 12 | public readonly ICollection BookingDetails; 13 | 14 | public CreateBookingCommand(string bookingOrderId,string customerId) 15 | { 16 | CustomerId = customerId; 17 | BookingDetails = new List(); 18 | } 19 | 20 | [Required] 21 | [MinLength(5, ErrorMessage = "Origin is required")] 22 | public string Origin { get; set; } 23 | 24 | [Required] 25 | [MinLength(5, ErrorMessage = "Destination is required")] 26 | public string Destination { get; set; } 27 | 28 | //[Required] 29 | public string CustomerId { get; set; } 30 | 31 | } 32 | 33 | public class BookingOrderDetails 34 | { 35 | public string PackageType { get; set; } 36 | public string PackageDescription { get; set; } 37 | public decimal Price { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/Booking/Commands/UpdateBooking/UpdateBooking.cs: -------------------------------------------------------------------------------- 1 | using MediatR; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Booking.Application.Booking.Commands.UpdateBooking 7 | { 8 | public class UpdateBooking : IRequest 9 | { 10 | public string BookingOrderId { get; set; } 11 | public string PaymentID { get; set; } 12 | public string NotificationID { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/Booking/Commands/UpdateBooking/UpdateBookingHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading; 5 | using System.Threading.Tasks; 6 | using Booking.Domain.AggregatesModel.BookingAggregate; 7 | using Booking.Domain.Booking; 8 | using MediatR; 9 | 10 | namespace Booking.Application.Booking.Commands.UpdateBooking 11 | { 12 | public class UpdateBookingHandler : IRequestHandler 13 | { 14 | private readonly IBookingRespository _bookingContext; 15 | 16 | public UpdateBookingHandler(IBookingRespository context) 17 | { 18 | _bookingContext = context; 19 | } 20 | 21 | public async Task Handle(UpdateBooking request, CancellationToken cancellationToken) 22 | { 23 | var bookingOrder = await _bookingContext.FindByIdAsync(request.BookingOrderId); 24 | 25 | if (bookingOrder == null) 26 | { 27 | return Unit.Value; 28 | } 29 | 30 | bookingOrder.SetPayment(request.PaymentID); 31 | await _bookingContext.UpdateAsync(bookingOrder); 32 | 33 | return Unit.Value; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/Booking/Queries/DTO/BookingOrderDTO.cs: -------------------------------------------------------------------------------- 1 | using Booking.Application.Booking.Queries.DTO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Booking.Application.Booking.Queries.GetBooking 7 | { 8 | public class BookingOrderDTO 9 | { 10 | public string BookingOrderId { get; set; } 11 | public string CustomerID { get; set; } 12 | public string Origin { get; set; } 13 | public string Destination { get; set; } 14 | 15 | public ICollection BookingDetails { get; set; } 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/Booking/Queries/DTO/BookingOrderDetailDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Booking.Application.Booking.Queries.DTO 6 | { 7 | public class BookingOrderDetailDTO 8 | { 9 | public string PackageType { get; set; } 10 | public string PackageDescription { get; set; } 11 | public decimal Price { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/Booking/Queries/GetBooking/GetBookingQuery.cs: -------------------------------------------------------------------------------- 1 | using Booking.Domain.AggregatesModel.BookingAggregate; 2 | using MediatR; 3 | 4 | namespace Booking.Application.Booking.Queries.GetBooking 5 | { 6 | public class GetBookingQuery : IRequest 7 | { 8 | public string BookingId { get; set; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/Booking/Queries/GetBooking/GetBookingQueryHandler.cs: -------------------------------------------------------------------------------- 1 | using Booking.Application.Booking.Queries.DTO; 2 | using Booking.Domain.AggregatesModel.BookingAggregate; 3 | using Booking.Domain.Booking; 4 | using MediatR; 5 | using System.Collections.Generic; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | namespace Booking.Application.Booking.Queries.GetBooking 10 | { 11 | public class GetBookingQueryHandler : IRequestHandler 12 | { 13 | private readonly IBookingRespository _context; 14 | 15 | public GetBookingQueryHandler(IBookingRespository context) 16 | { 17 | _context = context; 18 | } 19 | 20 | public async Task Handle(GetBookingQuery request, CancellationToken cancellationToken) 21 | { 22 | return await _context.FindByIdAsync(request.BookingId); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/IntegrationEvents/Events/BookingAddIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Booking.Application.IntegrationEvents.Events 7 | { 8 | public class BookingAddIntegrationEvent : IntegrationEvent 9 | { 10 | public string BookingId { get; set; } 11 | public string Origin { get; set; } 12 | public string Destination { get; set; } 13 | 14 | 15 | public BookingAddIntegrationEvent(string bookingId, string origin, string destination ) 16 | { 17 | BookingId = bookingId; 18 | Origin = origin; 19 | Destination = destination; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/IntegrationEvents/Events/OrderStatusChangedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Booking.Application.IntegrationEvents.Events 7 | { 8 | public class OrderStatusChangedIntegrationEvent : IntegrationEvent 9 | { 10 | public string BookingId { get; set; } 11 | public string CurrentStatus { get; set; } 12 | public OrderStatusChangedIntegrationEvent(string bookingId, string currentStatus) 13 | { 14 | CurrentStatus = currentStatus; 15 | BookingId = bookingId; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/IntegrationEvents/Events/OrderStatusChangedIntegrationEventHandler.cs: -------------------------------------------------------------------------------- 1 | using Booking.Domain.Booking; 2 | using Microsoft.ApplicationInsights; 3 | using Microsoft.ApplicationInsights.DataContracts; 4 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace Booking.Application.IntegrationEvents.Events 11 | { 12 | public class OrderStatusChangedIntegrationEventHandler : IIntegrationEventHandler 13 | { 14 | private readonly IBookingRespository _bookingContext; 15 | private TelemetryClient telemetry; 16 | 17 | public OrderStatusChangedIntegrationEventHandler(IBookingRespository bookingContext, TelemetryClient telemetry) 18 | { 19 | _bookingContext = bookingContext; 20 | this.telemetry = telemetry; 21 | } 22 | 23 | public async Task Handle(OrderStatusChangedIntegrationEvent eventMsg) 24 | { 25 | 26 | if (eventMsg.Id != Guid.Empty) 27 | { 28 | try 29 | { 30 | var booking = await _bookingContext.FindByIdAsync(eventMsg.BookingId); 31 | booking.OrderStatus = eventMsg.CurrentStatus; 32 | 33 | await _bookingContext.UpdateAsync(booking); 34 | } 35 | catch (Exception e) 36 | { 37 | 38 | var ExceptionTelemetry = new ExceptionTelemetry(e); 39 | ExceptionTelemetry.Properties.Add("OrderStatusChangedIntegrationEvent", eventMsg.BookingId); 40 | ExceptionTelemetry.SeverityLevel = SeverityLevel.Critical; 41 | 42 | telemetry.TrackException(ExceptionTelemetry); 43 | throw; //Throw the message so message queue abandons it 44 | } 45 | 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/IntegrationEvents/Events/PaymentProcessedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Booking.Application.IntegrationEvents.Events 7 | { 8 | public class PaymentProcessedIntegrationEvent : IntegrationEvent 9 | { 10 | public string PaymentId { get; set; } 11 | public string BookingOrderId { get; set; } 12 | public string CustomerId { get; set; } 13 | public PaymetStatus PaymentStatus { get; set; } 14 | 15 | 16 | public PaymentProcessedIntegrationEvent(string paymentId, string bookingOrderId, 17 | string customerId , PaymetStatus paymentStatus) 18 | { 19 | PaymentId = paymentId; 20 | BookingOrderId = bookingOrderId; 21 | CustomerId = customerId; 22 | PaymentStatus = paymentStatus; 23 | } 24 | } 25 | 26 | public enum PaymetStatus 27 | { 28 | Pending = 0, 29 | Completed = 1, 30 | Canceled = 2 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Application/IntegrationEvents/IBookingIntegrationEventService.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Booking.Application.IntegrationEvents 8 | { 9 | public interface IBookingIntegrationEventService 10 | { 11 | Task PublishEventsThroughEventBusAsync(); 12 | Task AddAndSaveEventAsync(IntegrationEvent evt); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Common/Booking.Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Common/bookingStateEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Booking.Common 6 | { 7 | //We can use this class to maintain booking state event 8 | public class bookingStateEnum 9 | { 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Domain/AggregatesModel/BookingAggregate/BookingOrder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Booking.Domain.AggregatesModel.BookingAggregate 5 | { 6 | //Aggreegate Model 7 | public class BookingOrder 8 | { 9 | private readonly List _bookingDetails; 10 | public IReadOnlyCollection BookingDetails => _bookingDetails; 11 | 12 | public string BookingOrderId { get; set; } 13 | public string CustomerID { get; set; } 14 | public string PaymentID { get; set; } 15 | public string NotificationID { get; set; } 16 | public string Origin { get; set; } 17 | public string Destination { get; set; } 18 | 19 | public bookingStateEnum BookingState { get; set; } 20 | 21 | public string OrderStatus { get; set; } 22 | 23 | public DateTime CreatedDate { get; set; } 24 | 25 | public DateTime? UpdatedDate { get; set; } 26 | 27 | public BookingOrder() 28 | { 29 | _bookingDetails = new List(); 30 | } 31 | 32 | 33 | public BookingOrder(string customerId, string origin, string destination, bookingStateEnum bookingState) 34 | { 35 | BookingOrderId = Guid.NewGuid().ToString(); 36 | CustomerID = customerId; 37 | Origin = origin; 38 | Destination = destination; 39 | BookingState = bookingState; 40 | _bookingDetails = new List(); 41 | } 42 | 43 | 44 | public void AddBookingDetails(string bookingOrderId, string packageType, 45 | string packageDesc, decimal price) 46 | { 47 | var bookingOrderDetail = new BookingOrderDetail(bookingOrderId, packageType, packageDesc, price); 48 | _bookingDetails.Add(bookingOrderDetail); 49 | } 50 | 51 | public void SetPayment(string paymentID) 52 | { 53 | PaymentID = paymentID; 54 | } 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Domain/AggregatesModel/BookingAggregate/BookingOrderDetail.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Booking.Domain.AggregatesModel.BookingAggregate 4 | { 5 | 6 | public class BookingOrderDetail 7 | { 8 | public BookingOrderDetail() 9 | { 10 | 11 | } 12 | 13 | public string BookingOrderDetailId { get; set; } 14 | public string BookingOrderId { get; set; } 15 | public string PackageType { get; set; } 16 | public string PackageDescription { get; set; } 17 | public decimal Price { get; set; } 18 | 19 | public BookingOrderDetail(string bookingOrderId, string packageType, 20 | string packageDescription, decimal price) 21 | { 22 | BookingOrderDetailId = Guid.NewGuid().ToString(); 23 | BookingOrderId = bookingOrderId; 24 | PackageType = packageType; 25 | PackageDescription = packageDescription; 26 | Price = price; 27 | } 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Domain/AggregatesModel/BookingAggregate/bookingStateEnum.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Booking.Domain.AggregatesModel.BookingAggregate 6 | { 7 | public enum bookingStateEnum 8 | { 9 | Pending = 0, 10 | Completed = 1, 11 | Canceled = 2 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Domain/Booking.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Domain/Interfaces/IBookingRespository.cs: -------------------------------------------------------------------------------- 1 | using Booking.Domain.AggregatesModel.BookingAggregate; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Booking.Domain.Booking 8 | { 9 | public interface IBookingRespository 10 | { 11 | Task AddAsync(BookingOrder bookingOrder); 12 | Task UpdateAsync(BookingOrder bookingOrder); 13 | Task FindByIdAsync(string bookingOrderId); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Infrastructure/Booking.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Persistence/Booking.Persistence.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | all 11 | runtime; build; native; contentfiles; analyzers 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Persistence/Configurations/BookingOrderConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Booking.Domain.AggregatesModel.BookingAggregate; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace Booking.Persistence.Configurations 6 | { 7 | public class BookingOrderConfiguration : IEntityTypeConfiguration 8 | { 9 | public void Configure(EntityTypeBuilder builder) 10 | { 11 | //defining the navigation property for booking order 12 | var navigation = builder.Metadata.FindNavigation(nameof(BookingOrder.BookingDetails)); 13 | navigation.SetPropertyAccessMode(PropertyAccessMode.Field); 14 | 15 | /*builder.HasKey(e => e.BookingOrderId); 16 | 17 | builder.Property(e => e.BookingOrderId). 18 | HasColumnName("BookingOrderID").HasMaxLength(32); 19 | 20 | builder.Property(e => e.NotificationId) 21 | .HasColumnName("NotificationID") 22 | .HasMaxLength(32); 23 | 24 | builder.Property(e => e.CustomerId) 25 | .HasColumnName("CustomerID") 26 | .HasMaxLength(32); 27 | 28 | builder.Property(e => e.PaymentId) 29 | .HasColumnName("PaymentID") 30 | .HasMaxLength(32); */ 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Persistence/Configurations/BookingOrderDetailConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Booking.Domain.AggregatesModel.BookingAggregate; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace Booking.Persistence.Configurations 6 | { 7 | public class BookingOrderDetailConfiguration : IEntityTypeConfiguration 8 | { 9 | //Property configurations are applied here for EFcore to apply 10 | public void Configure(EntityTypeBuilder builder) 11 | { 12 | builder.Property(e => e.Price).HasColumnType("money"); 13 | } 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Persistence/Migrations/20190225040122_createandupdatedates.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | namespace Booking.Persistence.Migrations 5 | { 6 | public partial class createandupdatedates : Migration 7 | { 8 | protected override void Up(MigrationBuilder migrationBuilder) 9 | { 10 | migrationBuilder.AddColumn( 11 | name: "CreatedDate", 12 | table: "Bookings", 13 | nullable: false, 14 | defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); 15 | 16 | migrationBuilder.AddColumn( 17 | name: "UpdatedDate", 18 | table: "Bookings", 19 | nullable: true); 20 | } 21 | 22 | protected override void Down(MigrationBuilder migrationBuilder) 23 | { 24 | migrationBuilder.DropColumn( 25 | name: "CreatedDate", 26 | table: "Bookings"); 27 | 28 | migrationBuilder.DropColumn( 29 | name: "UpdatedDate", 30 | table: "Bookings"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Persistence/Migrations/20190308022413_OrderStatus.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Booking.Persistence.Migrations 4 | { 5 | public partial class OrderStatus : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "OrderStatus", 11 | table: "Bookings", 12 | nullable: true); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.DropColumn( 18 | name: "OrderStatus", 19 | table: "Bookings"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Persistence/Repositories/BookingRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Booking.Domain.Booking; 3 | using Booking.Domain.AggregatesModel.BookingAggregate; 4 | using System; 5 | 6 | namespace Booking.Persistence.Repositories 7 | { 8 | public class BookingRepository : IBookingRespository 9 | { 10 | private readonly BookingDbContext _context; 11 | 12 | public BookingRepository(BookingDbContext dbContext) 13 | { 14 | _context = dbContext; 15 | } 16 | 17 | //Add the book 18 | public async Task AddAsync(BookingOrder bookingOrder) 19 | { 20 | bookingOrder.CreatedDate = DateTime.Now; 21 | 22 | _context.Set().Add(bookingOrder); 23 | await _context.SaveChangesAsync(); 24 | 25 | return bookingOrder.BookingOrderId; 26 | } 27 | 28 | //Update The Booking 29 | public async Task UpdateAsync(BookingOrder bookingOrder) 30 | { 31 | bookingOrder.UpdatedDate = DateTime.Now; 32 | 33 | //_context.Bookings.Update(bookingOrder); 34 | await _context.SaveChangesAsync(); 35 | 36 | return bookingOrder; 37 | } 38 | 39 | //Find Booking By ID 40 | public async Task FindByIdAsync(string bookingOrderId) 41 | { 42 | var bookingOrder = await _context.Bookings.FindAsync(bookingOrderId); 43 | 44 | //If booking is not empty fill the booking details 45 | if (bookingOrder != null) 46 | { 47 | await _context.Entry(bookingOrder) 48 | .Collection(i => i.BookingDetails).LoadAsync(); 49 | } 50 | 51 | return bookingOrder; 52 | } 53 | 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Tests/Booking.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | all 21 | runtime; build; native; contentfiles; analyzers 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Tests/FunctionalTests/Common/Utilities.cs: -------------------------------------------------------------------------------- 1 | using Booking.Persistence; 2 | using Newtonsoft.Json; 3 | using System.Net.Http; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Booking.Tests.FunctionalTests.Common 8 | { 9 | public class Utilities 10 | { 11 | public static StringContent GetRequestContent(object obj) 12 | { 13 | return new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json"); 14 | } 15 | 16 | public static async Task GetResponseContent(HttpResponseMessage response) 17 | { 18 | var stringResponse = await response.Content.ReadAsStringAsync(); 19 | 20 | var result = JsonConvert.DeserializeObject(stringResponse); 21 | 22 | return result; 23 | } 24 | 25 | public static void InitializeDbForTests(BookingDbContext context) 26 | { 27 | 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Tests/FunctionalTests/Controllers/Booking/Create.cs: -------------------------------------------------------------------------------- 1 | using Xunit; 2 | using System.Net.Http; 3 | using System.Threading.Tasks; 4 | using Booking.Tests.FunctionalTests.Common; 5 | using Booking.Application.Booking.Commands.CreateBooking; 6 | using Booking.API; 7 | using System.Collections.Generic; 8 | 9 | namespace Booking.Tests.FunctionalTests.Controllers.Booking 10 | { 11 | public class Create : IClassFixture> 12 | { 13 | private readonly HttpClient _client; 14 | 15 | public Create(CustomWebApplicationFactory factory) 16 | { 17 | _client = factory.CreateClient(); 18 | } 19 | 20 | [Fact] 21 | public async Task GivenCreateBookingCommand_ReturnsSuccessStatusCode() 22 | { 23 | var command = new CreateBookingCommand(string.Empty, string.Empty); 24 | command.CustomerId = string.Empty; 25 | command.Destination = "45 Terrian st"; 26 | command.Origin = "67 bloom blvd"; 27 | 28 | var content = Utilities.GetRequestContent(command); 29 | var response = await _client.PostAsync($"/api/booking", content); 30 | 31 | response.EnsureSuccessStatusCode(); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Tests/UnitTests/Application/Booking/Commands/CreateBookingCommandHandlerTests.cs: -------------------------------------------------------------------------------- 1 | using Booking.Application.Booking.Commands.CreateBooking; 2 | using Booking.Application.Booking.Queries.DTO; 3 | using Booking.Application.Booking.Queries.GetBooking; 4 | using Booking.Domain.Booking; 5 | using Booking.Persistence; 6 | using Booking.Tests.UnitTests.Application.Infrastructure; 7 | using MediatR; 8 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions; 9 | using Moq; 10 | using Shouldly; 11 | using System; 12 | using System.Collections.Generic; 13 | using System.Linq; 14 | using System.Threading; 15 | using System.Threading.Tasks; 16 | using Xunit; 17 | 18 | namespace Booking.Tests.UnitTests.Application.Booking.Commands 19 | { 20 | [Collection("CommandCollection")] 21 | 22 | public class CreateBookingCommandHandlerTests 23 | { 24 | private readonly IBookingRespository _repo; 25 | 26 | public CreateBookingCommandHandlerTests(CommandTestBase fixture) 27 | { 28 | _repo = fixture.repo; 29 | } 30 | 31 | [Fact] 32 | public async Task CreateBooking() 33 | { 34 | //Arrange 35 | var _fakeEventBus = new Mock(); 36 | var sut = new CreateBookingCommandHandler(_repo, _fakeEventBus.Object); 37 | 38 | //Act 39 | CreateBookingCommand command = new CreateBookingCommand(string.Empty, string.Empty); 40 | var result = await sut.Handle(command, CancellationToken.None); 41 | 42 | //Assert 43 | Guid bookingRef = Guid.Parse(result); 44 | result.ShouldBeOfType(); 45 | bookingRef.ShouldBeOfType(); 46 | result.Count().ShouldBe(36); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Tests/UnitTests/Application/Infrastructure/BookingContextFactory.cs: -------------------------------------------------------------------------------- 1 | using Booking.Application.Booking.Queries.GetBooking; 2 | using Booking.Domain.AggregatesModel.BookingAggregate; 3 | using Booking.Persistence; 4 | using Booking.Persistence.Repositories; 5 | using Microsoft.EntityFrameworkCore; 6 | using System; 7 | 8 | namespace Booking.Tests.UnitTests.Application.Infrastructure 9 | { 10 | public class BookingContextFactory 11 | { 12 | public static BookingRepository Create(BookingDbContext context) 13 | { 14 | context.Database.EnsureCreated(); 15 | 16 | var bookingRepo = new BookingRepository(context); 17 | 18 | BookingOrder bookingOrder = 19 | new BookingOrder 20 | { 21 | BookingOrderId = "1e4199f0-907f-4acc-b886-b12b0323c108", 22 | Origin = "NY", 23 | Destination = "Melbourne" 24 | }; 25 | 26 | bookingOrder.AddBookingDetails("1e4199f0-907f-4acc-b886-b12b0323c108", 27 | "Express", "Toys", 10); 28 | bookingOrder.AddBookingDetails("1b4199f0-907f-4acc-b886-b12b0323c108", 29 | "Standard", "Books", 50); 30 | 31 | context.Bookings.AddRange(new[] { bookingOrder, bookingOrder }); 32 | context.SaveChanges(); 33 | 34 | return bookingRepo; 35 | } 36 | 37 | public static void Destroy(BookingDbContext context) 38 | { 39 | context.Database.EnsureDeleted(); 40 | context.Dispose(); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Tests/UnitTests/Application/Infrastructure/CommandTestBase.cs: -------------------------------------------------------------------------------- 1 | using Booking.Domain.Booking; 2 | using Booking.Persistence; 3 | using Microsoft.EntityFrameworkCore; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using Xunit; 8 | 9 | namespace Booking.Tests.UnitTests.Application.Infrastructure 10 | { 11 | public class CommandTestBase : IDisposable 12 | { 13 | public BookingDbContext Context { get; private set; } 14 | public IBookingRespository repo { get; private set; } 15 | 16 | public CommandTestBase() 17 | { 18 | var options = new DbContextOptionsBuilder() 19 | .UseInMemoryDatabase(Guid.NewGuid().ToString()) 20 | .Options; 21 | 22 | Context = new BookingDbContext(options); 23 | repo = BookingContextFactory.Create(Context); 24 | } 25 | 26 | public void Dispose() 27 | { 28 | BookingContextFactory.Destroy(Context); 29 | } 30 | } 31 | 32 | [CollectionDefinition("CommandCollection")] 33 | public class CommandCollection : ICollectionFixture { } 34 | } 35 | -------------------------------------------------------------------------------- /src/Services/Booking/Booking.Tests/UnitTests/Application/Infrastructure/QueryTestFixture.cs: -------------------------------------------------------------------------------- 1 | using Booking.Domain.Booking; 2 | using Booking.Persistence; 3 | using Microsoft.EntityFrameworkCore; 4 | using System; 5 | using Xunit; 6 | 7 | namespace Booking.Tests.UnitTests.Application.Infrastructure 8 | { 9 | public class QueryTestFixture : IDisposable 10 | { 11 | public BookingDbContext Context { get; private set; } 12 | public IBookingRespository repo { get; private set; } 13 | 14 | public QueryTestFixture() 15 | { 16 | var options = new DbContextOptionsBuilder() 17 | .UseInMemoryDatabase(Guid.NewGuid().ToString()) 18 | .Options; 19 | 20 | Context = new BookingDbContext(options); 21 | repo = BookingContextFactory.Create(Context); 22 | } 23 | 24 | public void Dispose() 25 | { 26 | BookingContextFactory.Destroy(Context); 27 | } 28 | } 29 | 30 | [CollectionDefinition("QueryCollection")] 31 | public class QueryCollection : ICollectionFixture { } 32 | } 33 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.API/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.14.11009.1", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /src/Services/Payment/Payment.API/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/dotnet:2.2-sdk AS build 6 | WORKDIR /src 7 | COPY ["src/Services/Payment/Payment.API/Payment.API.csproj", "src/Services/Payment/Payment.API/"] 8 | RUN dotnet restore "src/Services/Payment/Payment.API/Payment.API.csproj" 9 | COPY . . 10 | WORKDIR "/src/src/Services/Payment/Payment.API" 11 | RUN dotnet build "Payment.API.csproj" -c Release -o /app 12 | 13 | FROM build AS publish 14 | RUN dotnet publish "Payment.API.csproj" -c Release -o /app 15 | 16 | FROM base AS final 17 | WORKDIR /app 18 | COPY --from=publish /app . 19 | ENTRYPOINT ["dotnet", "Payment.API.dll"] -------------------------------------------------------------------------------- /src/Services/Payment/Payment.API/Payment.API.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | Linux 7 | /subscriptions/37da0425-c79d-424d-9680-d7e23cc0980f/resourcegroups/MicroServicesStuff/providers/microsoft.insights/components/Payment.API 8 | /subscriptions/37da0425-c79d-424d-9680-d7e23cc0980f/resourcegroups/MicroServicesStuff/providers/microsoft.insights/components/Payment.API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.API/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.EntityFrameworkCore; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Logging; 12 | using Payment.Persistence; 13 | using Polly; 14 | 15 | namespace Payment.API 16 | { 17 | public class Program 18 | { 19 | public static void Main(string[] args) 20 | { 21 | //Create/Migrate the database 22 | var host = CreateWebHostBuilder(args).Build(); 23 | 24 | using (var scope = host.Services.CreateScope()) 25 | { 26 | try 27 | { 28 | var context = scope.ServiceProvider.GetService(); 29 | 30 | var concreteContext = (PaymentDbContext)context; 31 | 32 | //Retry logic for DB connectivity 33 | Policy 34 | .Handle() 35 | .WaitAndRetry(5, r => TimeSpan.FromSeconds(10)) 36 | .Execute(() => concreteContext.Database.Migrate()); 37 | 38 | } 39 | catch (Exception) 40 | { 41 | 42 | } 43 | } 44 | 45 | host.Run(); 46 | } 47 | 48 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 49 | WebHost.CreateDefaultBuilder(args) 50 | .UseApplicationInsights() 51 | .UseStartup(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.API/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:5001", 7 | "sslPort": 0 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/payment", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "Payment.API": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "http://localhost:5001" 28 | }, 29 | "Docker": { 30 | "commandName": "Docker", 31 | "launchBrowser": true, 32 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/api/values" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Services/Payment/Payment.API/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "MicroCouriersDataBase": "server=localhost,1433;user id=sa;password=99888ukGh43hnDw89Hol8LN21112;database=MicroCouriersPayment;" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "AllowedHosts": "*", 11 | "EventBusConnection": "", 12 | "SubscriptionClientName": "payment", 13 | "ApplicationInsights": { 14 | "InstrumentationKey": "" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.API/appsettings.Production.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "MicroCouriersDataBase": "server=sqlserver;user id=sa;password=99888ukGh43hnDw89Hol8LN21112;database=MicroCouriersPayment;" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "AllowedHosts": "*", 11 | "EventBusConnection": "", 12 | "SubscriptionClientName": "payment", 13 | "ApplicationInsights": { 14 | "InstrumentationKey": "" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.API/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Application/DTO/PaymentDTO.cs: -------------------------------------------------------------------------------- 1 | using Payment.Domain.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.ComponentModel.DataAnnotations; 5 | using System.Text; 6 | 7 | namespace Payment.Application.DTO 8 | { 9 | public class PaymentDTO 10 | { 11 | public string PaymentsId { get; set; } 12 | 13 | [Required] 14 | public string BookingOrderId { get; set; } 15 | 16 | public string CustomerId { get; set; } 17 | 18 | [Required] 19 | public decimal Price { get; set; } 20 | 21 | public PaymentStatusDTO PaymentStatus { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Application/DTO/PaymentStatusDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Payment.Application.DTO 6 | { 7 | public enum PaymentStatusDTO 8 | { 9 | Pending = 0, 10 | Completed = 1, 11 | Canceled = 2 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Application/IntegrationEvents/PaymentProcessedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Payment.Application.IntegrationEvents 7 | { 8 | public class PaymentProcessedIntegrationEvent : IntegrationEvent 9 | { 10 | public string PaymentId { get; set; } 11 | public string BookingOrderId { get; set; } 12 | public string CustomerId { get; set; } 13 | public int PaymentStatus { get; set; } 14 | 15 | 16 | public PaymentProcessedIntegrationEvent(string paymentId, string bookingOrderId, 17 | string customerId , int paymentStatus) 18 | { 19 | PaymentId = paymentId; 20 | BookingOrderId = bookingOrderId; 21 | CustomerId = customerId; 22 | PaymentStatus = paymentStatus; 23 | } 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Application/Interface/IPaymentExternalGateway.cs: -------------------------------------------------------------------------------- 1 |  2 | using Payment.Application.DTO; 3 | using Payment.Domain.Entities; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace Payment.Application.Interface 10 | { 11 | public interface IPaymentExternalGateway 12 | { 13 | Task PaymentProcess(Payments payment); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Application/Interface/IPaymentService.cs: -------------------------------------------------------------------------------- 1 | using Payment.Application.DTO; 2 | using Payment.Domain.Entities; 3 | using System.Threading.Tasks; 4 | 5 | namespace Payment.Application.Interface 6 | { 7 | public interface IPaymentService 8 | { 9 | Task AddAsync(Payments payment); 10 | Task UpdateAsync(Payments payment); 11 | Task FindByIdAsync(string paymentId); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Application/Payment.Application.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Application/PaymentService/PaymentService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using Payment.Application.Interface; 6 | using Payment.Application.DTO; 7 | using Payment.Domain.Entities; 8 | using Payment.Domain.Interfaces; 9 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions; 10 | using Payment.Application.IntegrationEvents; 11 | 12 | namespace Payment.Application.PaymentService 13 | { 14 | public class PaymentService : IPaymentService 15 | { 16 | private readonly IPaymentRepository _context; 17 | private readonly IPaymentExternalGateway _gateway; 18 | private readonly IEventBus _eventBus; 19 | 20 | public PaymentService(IPaymentRepository dbContext , IPaymentExternalGateway gateway 21 | , IEventBus eventBus) 22 | { 23 | _context = dbContext; 24 | _gateway = gateway; 25 | _eventBus = eventBus ?? throw new ArgumentNullException(nameof(eventBus)); 26 | } 27 | 28 | public async Task AddAsync(Payments payment) 29 | { 30 | var resultFromPayment= _gateway.PaymentProcess(payment); 31 | payment.PaymentStatus = PaymetStatus.Completed; 32 | 33 | var paymentRef = await _context.AddAsync(payment); 34 | 35 | //Publish the event here 36 | //Create Integration Event 37 | var paymentProcessedEvent = new PaymentProcessedIntegrationEvent(paymentRef.PaymentsId, 38 | paymentRef.BookingOrderId, 39 | paymentRef.CustomerId, (int)payment.PaymentStatus); 40 | 41 | _eventBus.Publish(paymentProcessedEvent); 42 | 43 | return paymentRef.PaymentsId; 44 | } 45 | 46 | public Task FindByIdAsync(string paymentId) 47 | { 48 | throw new NotImplementedException(); 49 | } 50 | 51 | public Task UpdateAsync(Payments payment) 52 | { 53 | throw new NotImplementedException(); 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Domain/Entities/Payments.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Payment.Domain.Entities 6 | { 7 | public class Payments 8 | { 9 | public string PaymentsId { get; set; } 10 | 11 | public string BookingOrderId { get; set; } 12 | 13 | public decimal Price { get; set; } 14 | 15 | public string CustomerId { get; set; } 16 | 17 | public PaymetStatus PaymentStatus { get; set; } 18 | 19 | public DateTime CreatedDate { get; set; } 20 | 21 | public DateTime? UpdatedDate { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Domain/Entities/PaymetStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Payment.Domain.Entities 6 | { 7 | public enum PaymetStatus 8 | { 9 | Pending = 0, 10 | Completed = 1, 11 | Canceled = 2 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Domain/Interfaces/IPaymentsRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using Payment.Domain.Entities; 6 | namespace Payment.Domain.Interfaces 7 | { 8 | public interface IPaymentRepository 9 | { 10 | Task AddAsync( Payments payment); 11 | Task UpdateAsync(Payments payment); 12 | Task FindByIdAsync(string paymentId); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Domain/Payment.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Infrastructure/Payment.Infrastructure.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Infrastructure/PaymentProcessing/PaymentExternalGateway.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | using Payment.Application.DTO; 3 | using Payment.Application.Interface; 4 | using Payment.Domain.Entities; 5 | 6 | namespace Payment.Infrastructure.PaymentProcessing 7 | { 8 | //Simulate the payment Processing 9 | public class PaymentExternalGateway : IPaymentExternalGateway 10 | { 11 | public Task PaymentProcess(Payments payment) 12 | { 13 | return Task.CompletedTask; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Configurations/PaymentsConfiguration.cs: -------------------------------------------------------------------------------- 1 | using Payment.Domain.Entities; 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Metadata.Builders; 4 | 5 | namespace Payment.Persistence.Configurations 6 | { 7 | public class PaymentsConfiguration : IEntityTypeConfiguration 8 | { 9 | //Properties are configured here for EFcore to apply them in DB 10 | public void Configure(EntityTypeBuilder builder) 11 | { 12 | builder.Property(e => e.Price).HasColumnType("money"); 13 | } 14 | 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Migrations/20190221045816_InitialPayments.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 7 | using Payment.Persistence; 8 | 9 | namespace Payment.Persistence.Migrations 10 | { 11 | [DbContext(typeof(PaymentDbContext))] 12 | [Migration("20190221045816_InitialPayments")] 13 | partial class InitialPayments 14 | { 15 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 16 | { 17 | #pragma warning disable 612, 618 18 | modelBuilder 19 | .HasAnnotation("ProductVersion", "2.2.2-servicing-10034") 20 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 21 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 22 | 23 | modelBuilder.Entity("Payment.Domain.Entities.Payments", b => 24 | { 25 | b.Property("PaymentsId") 26 | .ValueGeneratedOnAdd(); 27 | 28 | b.Property("BookingOrderId"); 29 | 30 | b.Property("Price") 31 | .HasColumnType("money"); 32 | 33 | b.Property("paymentStatus"); 34 | 35 | b.HasKey("PaymentsId"); 36 | 37 | b.ToTable("Payments"); 38 | }); 39 | #pragma warning restore 612, 618 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Migrations/20190221045816_InitialPayments.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Payment.Persistence.Migrations 4 | { 5 | public partial class InitialPayments : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.CreateTable( 10 | name: "Payments", 11 | columns: table => new 12 | { 13 | PaymentsId = table.Column(nullable: false), 14 | BookingOrderId = table.Column(nullable: true), 15 | Price = table.Column(type: "money", nullable: false), 16 | paymentStatus = table.Column(nullable: false) 17 | }, 18 | constraints: table => 19 | { 20 | table.PrimaryKey("PK_Payments", x => x.PaymentsId); 21 | }); 22 | } 23 | 24 | protected override void Down(MigrationBuilder migrationBuilder) 25 | { 26 | migrationBuilder.DropTable( 27 | name: "Payments"); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Migrations/20190224235305_fixes.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 7 | using Payment.Persistence; 8 | 9 | namespace Payment.Persistence.Migrations 10 | { 11 | [DbContext(typeof(PaymentDbContext))] 12 | [Migration("20190224235305_fixes")] 13 | partial class fixes 14 | { 15 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 16 | { 17 | #pragma warning disable 612, 618 18 | modelBuilder 19 | .HasAnnotation("ProductVersion", "2.2.2-servicing-10034") 20 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 21 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 22 | 23 | modelBuilder.Entity("Payment.Domain.Entities.Payments", b => 24 | { 25 | b.Property("PaymentsId") 26 | .ValueGeneratedOnAdd(); 27 | 28 | b.Property("BookingOrderId"); 29 | 30 | b.Property("PaymentStatus"); 31 | 32 | b.Property("Price") 33 | .HasColumnType("money"); 34 | 35 | b.HasKey("PaymentsId"); 36 | 37 | b.ToTable("Payments"); 38 | }); 39 | #pragma warning restore 612, 618 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Migrations/20190224235305_fixes.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Payment.Persistence.Migrations 4 | { 5 | public partial class fixes : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.RenameColumn( 10 | name: "paymentStatus", 11 | table: "Payments", 12 | newName: "PaymentStatus"); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.RenameColumn( 18 | name: "PaymentStatus", 19 | table: "Payments", 20 | newName: "paymentStatus"); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Migrations/20190225025121_customerid.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using Microsoft.EntityFrameworkCore; 3 | using Microsoft.EntityFrameworkCore.Infrastructure; 4 | using Microsoft.EntityFrameworkCore.Metadata; 5 | using Microsoft.EntityFrameworkCore.Migrations; 6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 7 | using Payment.Persistence; 8 | 9 | namespace Payment.Persistence.Migrations 10 | { 11 | [DbContext(typeof(PaymentDbContext))] 12 | [Migration("20190225025121_customerid")] 13 | partial class customerid 14 | { 15 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 16 | { 17 | #pragma warning disable 612, 618 18 | modelBuilder 19 | .HasAnnotation("ProductVersion", "2.2.2-servicing-10034") 20 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 21 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 22 | 23 | modelBuilder.Entity("Payment.Domain.Entities.Payments", b => 24 | { 25 | b.Property("PaymentsId") 26 | .ValueGeneratedOnAdd(); 27 | 28 | b.Property("BookingOrderId"); 29 | 30 | b.Property("CustomerId"); 31 | 32 | b.Property("PaymentStatus"); 33 | 34 | b.Property("Price") 35 | .HasColumnType("money"); 36 | 37 | b.HasKey("PaymentsId"); 38 | 39 | b.ToTable("Payments"); 40 | }); 41 | #pragma warning restore 612, 618 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Migrations/20190225025121_customerid.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore.Migrations; 2 | 3 | namespace Payment.Persistence.Migrations 4 | { 5 | public partial class customerid : Migration 6 | { 7 | protected override void Up(MigrationBuilder migrationBuilder) 8 | { 9 | migrationBuilder.AddColumn( 10 | name: "CustomerId", 11 | table: "Payments", 12 | nullable: true); 13 | } 14 | 15 | protected override void Down(MigrationBuilder migrationBuilder) 16 | { 17 | migrationBuilder.DropColumn( 18 | name: "CustomerId", 19 | table: "Payments"); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Migrations/20190225035828_createandupdatedates.Designer.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Migrations; 7 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 8 | using Payment.Persistence; 9 | 10 | namespace Payment.Persistence.Migrations 11 | { 12 | [DbContext(typeof(PaymentDbContext))] 13 | [Migration("20190225035828_createandupdatedates")] 14 | partial class createandupdatedates 15 | { 16 | protected override void BuildTargetModel(ModelBuilder modelBuilder) 17 | { 18 | #pragma warning disable 612, 618 19 | modelBuilder 20 | .HasAnnotation("ProductVersion", "2.2.2-servicing-10034") 21 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 22 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 23 | 24 | modelBuilder.Entity("Payment.Domain.Entities.Payments", b => 25 | { 26 | b.Property("PaymentsId") 27 | .ValueGeneratedOnAdd(); 28 | 29 | b.Property("BookingOrderId"); 30 | 31 | b.Property("CreatedDate"); 32 | 33 | b.Property("CustomerId"); 34 | 35 | b.Property("PaymentStatus"); 36 | 37 | b.Property("Price") 38 | .HasColumnType("money"); 39 | 40 | b.Property("UpdatedDate"); 41 | 42 | b.HasKey("PaymentsId"); 43 | 44 | b.ToTable("Payments"); 45 | }); 46 | #pragma warning restore 612, 618 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Migrations/20190225035828_createandupdatedates.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Microsoft.EntityFrameworkCore.Migrations; 3 | 4 | namespace Payment.Persistence.Migrations 5 | { 6 | public partial class createandupdatedates : Migration 7 | { 8 | protected override void Up(MigrationBuilder migrationBuilder) 9 | { 10 | migrationBuilder.AddColumn( 11 | name: "CreatedDate", 12 | table: "Payments", 13 | nullable: false, 14 | defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); 15 | 16 | migrationBuilder.AddColumn( 17 | name: "UpdatedDate", 18 | table: "Payments", 19 | nullable: true); 20 | } 21 | 22 | protected override void Down(MigrationBuilder migrationBuilder) 23 | { 24 | migrationBuilder.DropColumn( 25 | name: "CreatedDate", 26 | table: "Payments"); 27 | 28 | migrationBuilder.DropColumn( 29 | name: "UpdatedDate", 30 | table: "Payments"); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Migrations/PaymentDbContextModelSnapshot.cs: -------------------------------------------------------------------------------- 1 | // 2 | using System; 3 | using Microsoft.EntityFrameworkCore; 4 | using Microsoft.EntityFrameworkCore.Infrastructure; 5 | using Microsoft.EntityFrameworkCore.Metadata; 6 | using Microsoft.EntityFrameworkCore.Storage.ValueConversion; 7 | using Payment.Persistence; 8 | 9 | namespace Payment.Persistence.Migrations 10 | { 11 | [DbContext(typeof(PaymentDbContext))] 12 | partial class PaymentDbContextModelSnapshot : ModelSnapshot 13 | { 14 | protected override void BuildModel(ModelBuilder modelBuilder) 15 | { 16 | #pragma warning disable 612, 618 17 | modelBuilder 18 | .HasAnnotation("ProductVersion", "2.2.2-servicing-10034") 19 | .HasAnnotation("Relational:MaxIdentifierLength", 128) 20 | .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); 21 | 22 | modelBuilder.Entity("Payment.Domain.Entities.Payments", b => 23 | { 24 | b.Property("PaymentsId") 25 | .ValueGeneratedOnAdd(); 26 | 27 | b.Property("BookingOrderId"); 28 | 29 | b.Property("CreatedDate"); 30 | 31 | b.Property("CustomerId"); 32 | 33 | b.Property("PaymentStatus"); 34 | 35 | b.Property("Price") 36 | .HasColumnType("money"); 37 | 38 | b.Property("UpdatedDate"); 39 | 40 | b.HasKey("PaymentsId"); 41 | 42 | b.ToTable("Payments"); 43 | }); 44 | #pragma warning restore 612, 618 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Payment.Persistence.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | all 11 | runtime; build; native; contentfiles; analyzers 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | ..\..\..\..\..\..\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.entityframeworkcore\2.2.0\lib\netstandard2.0\Microsoft.EntityFrameworkCore.dll 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Persistence/Repositories/PaymentsRepository.cs: -------------------------------------------------------------------------------- 1 | using Payment.Domain.Entities; 2 | using Payment.Domain.Interfaces; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace Payment.Persistence.Repositories 9 | { 10 | 11 | public class PaymentsRepository : IPaymentRepository 12 | { 13 | private readonly PaymentDbContext _context; 14 | 15 | //create context 16 | public PaymentsRepository(PaymentDbContext dbContext) 17 | { 18 | _context = dbContext; 19 | } 20 | 21 | //Add Payment 22 | public async Task AddAsync(Payments payment) 23 | { 24 | payment.CreatedDate = DateTime.Now; 25 | 26 | _context.Set().Add(payment); 27 | await _context.SaveChangesAsync(); 28 | 29 | return payment; 30 | } 31 | 32 | //Find payment by ID 33 | public async Task FindByIdAsync(string paymentId) 34 | { 35 | var payment = await _context.Payments.FindAsync(paymentId); 36 | return payment; 37 | } 38 | 39 | 40 | //Update Payment 41 | public async Task UpdateAsync(Payments payment) 42 | { 43 | 44 | payment.UpdatedDate = DateTime.Now; 45 | 46 | _context.Payments.Update(payment); 47 | await _context.SaveChangesAsync(); 48 | 49 | return payment; 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Tests/FunctionalTests/Common/Utilities.cs: -------------------------------------------------------------------------------- 1 | using System.Text; 2 | using Newtonsoft.Json; 3 | using System.Net.Http; 4 | using System.Threading.Tasks; 5 | using Payment.Persistence; 6 | 7 | namespace Payment.Tests.FunctionalTests.Common 8 | { 9 | public class Utilities 10 | { 11 | public static StringContent GetRequestContent(object obj) 12 | { 13 | return new StringContent(JsonConvert.SerializeObject(obj), Encoding.UTF8, "application/json"); 14 | } 15 | 16 | public static async Task GetResponseContent(HttpResponseMessage response) 17 | { 18 | var stringResponse = await response.Content.ReadAsStringAsync(); 19 | var result = JsonConvert.DeserializeObject(stringResponse); 20 | 21 | return result; 22 | } 23 | 24 | public static void InitializeDbForTests(PaymentDbContext context) 25 | { 26 | 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Tests/FunctionalTests/Controllers/Payment/Create.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Xunit; 5 | using System.Net.Http; 6 | using System.Threading.Tasks; 7 | using Payment.Tests.FunctionalTests.Common; 8 | using Payment.API; 9 | using Payment.Application.DTO; 10 | 11 | namespace Payment.Tests.FunctionalTests.Controllers.Payment 12 | { 13 | public class Create : IClassFixture> 14 | { 15 | private readonly HttpClient _client; 16 | 17 | public Create(CustomWebApplicationFactory factory) 18 | { 19 | _client = factory.CreateClient(); 20 | } 21 | 22 | [Fact] 23 | public async Task GivenCreateBookingCommand_ReturnsSuccessStatusCode() 24 | { 25 | PaymentDTO payment = new PaymentDTO(); 26 | payment.BookingOrderId = "1e4199f0-907f-4acc-b886-b12b0323c108"; 27 | payment.Price = 100; 28 | payment.CustomerId = string.Empty; 29 | 30 | var content = Utilities.GetRequestContent(payment); 31 | var response = await _client.PostAsync($"/api/payment", content); 32 | 33 | response.EnsureSuccessStatusCode(); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Tests/Payment.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Tests/UnitTests/Application/Infrastructure/PaymentContextFactory.cs: -------------------------------------------------------------------------------- 1 | using Payment.Domain.Entities; 2 | using Payment.Persistence; 3 | using Payment.Persistence.Repositories; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | 8 | namespace Payment.Tests.UnitTests.Application.Infrastructure 9 | { 10 | public class PaymentContextFactory 11 | { 12 | public static PaymentsRepository Create(PaymentDbContext context) 13 | { 14 | context.Database.EnsureCreated(); 15 | var paymentRepo = new PaymentsRepository(context); 16 | return paymentRepo; 17 | } 18 | 19 | public static void Destroy(PaymentDbContext context) 20 | { 21 | context.Database.EnsureDeleted(); 22 | context.Dispose(); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Tests/UnitTests/Application/Infrastructure/PaymentTestFixture.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Payment.Domain.Interfaces; 3 | using Payment.Persistence; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Text; 7 | using Xunit; 8 | 9 | namespace Payment.Tests.UnitTests.Application.Infrastructure 10 | { 11 | public class PaymentTestFixture : IDisposable 12 | { 13 | public PaymentDbContext Context { get; private set; } 14 | public IPaymentRepository repo { get; private set; } 15 | 16 | public PaymentTestFixture() 17 | { 18 | var options = new DbContextOptionsBuilder() 19 | .UseInMemoryDatabase(Guid.NewGuid().ToString()) 20 | .Options; 21 | 22 | Context = new PaymentDbContext(options); 23 | repo = PaymentContextFactory.Create(Context); 24 | } 25 | 26 | public void Dispose() 27 | { 28 | PaymentContextFactory.Destroy(Context); 29 | } 30 | } 31 | 32 | [CollectionDefinition("PaymentCollection")] 33 | public class CommandCollection : ICollectionFixture { } 34 | } 35 | -------------------------------------------------------------------------------- /src/Services/Payment/Payment.Tests/UnitTests/Application/Payment/PaymentServiceTest.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Abstractions; 2 | using Moq; 3 | using Payment.Application.DTO; 4 | using Payment.Application.Interface; 5 | using Payment.Application.PaymentService; 6 | using Payment.Domain.Entities; 7 | using Payment.Domain.Interfaces; 8 | using Payment.Tests.UnitTests.Application.Infrastructure; 9 | using Shouldly; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Linq; 13 | using System.Text; 14 | using System.Threading.Tasks; 15 | using Xunit; 16 | 17 | namespace Payment.Tests.UnitTests.Application.Payment 18 | { 19 | [Collection("PaymentCollection")] 20 | 21 | public class PaymentServiceTest 22 | { 23 | private readonly IPaymentRepository _repo; 24 | 25 | public PaymentServiceTest(PaymentTestFixture fixture) 26 | { 27 | _repo = fixture.repo; 28 | } 29 | 30 | [Fact] 31 | public async Task AddPaymentAsync() 32 | { 33 | //Arrange 34 | var fakeEventBus = new Mock(); 35 | var fakeGateWay = new Mock(); 36 | 37 | Payments payment = new Payments(); 38 | payment.BookingOrderId = "1e4199f0-907f-4acc-b886-b12b0323c108"; 39 | payment.Price = 100; 40 | payment.CustomerId = string.Empty; 41 | 42 | var sut = new PaymentService(_repo,fakeGateWay.Object, fakeEventBus.Object); 43 | 44 | //Act 45 | var result = await sut.AddAsync(payment); 46 | 47 | //Assert 48 | Guid bookingRef = Guid.Parse(result); 49 | result.ShouldBeOfType(); 50 | bookingRef.ShouldBeOfType(); 51 | result.Count().ShouldBe(36); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/Events/Aggregate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace ReadModel.AzFn.Events 6 | { 7 | public class Aggregate 8 | { 9 | public string Id { get; set; } 10 | public int CurrentVersion { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/Events/BookingAddIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | 3 | namespace ReadModel.AzFn.Events 4 | { 5 | public class BookingAddIntegrationEvent : IntegrationEvent 6 | { 7 | public string BookingId { get; set; } 8 | public string Origin { get; set; } 9 | public string Destination { get; set; } 10 | 11 | 12 | public BookingAddIntegrationEvent(string bookingId, string origin, string destination) 13 | { 14 | BookingId = bookingId; 15 | Origin = origin; 16 | Destination = destination; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/Events/OrderDeliveredIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | 3 | namespace ReadModel.AzFn.Events 4 | { 5 | public class OrderDeliveredIntegrationEvent : IntegrationEvent 6 | { 7 | public string BookingId { get; set; } 8 | public string Description { get; set; } 9 | public string SignedBy { get; set; } 10 | 11 | public OrderDeliveredIntegrationEvent(string bookingId, string description ,string signedBy) 12 | { 13 | BookingId = bookingId; 14 | Description = description; 15 | SignedBy = signedBy; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/Events/OrderPickedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | namespace ReadModel.AzFn.Events 3 | { 4 | public class OrderPickedIntegrationEvent : IntegrationEvent 5 | { 6 | public string BookingId { get; set; } 7 | public string Description { get; set; } 8 | 9 | 10 | public OrderPickedIntegrationEvent(string bookingId, string description) 11 | { 12 | BookingId = bookingId; 13 | Description = description; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/Events/OrderStatusChangedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | namespace ReadModel.AzFn.Events 2 | { 3 | public class OrderStatusChangedIntegrationEvent 4 | { 5 | public string BookingId { get; set; } 6 | public string CurrentStatus { get; set; } 7 | public OrderStatusChangedIntegrationEvent(string bookingId, string currentStatus) 8 | { 9 | CurrentStatus = currentStatus; 10 | BookingId = bookingId; 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/Events/OrderTransitIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | 3 | namespace ReadModel.AzFn.Events 4 | { 5 | public class OrderTransitIntegrationEvent : IntegrationEvent 6 | { 7 | public string BookingId { get; set; } 8 | public string Description { get; set; } 9 | 10 | 11 | public OrderTransitIntegrationEvent(string bookingId, string description) 12 | { 13 | BookingId = bookingId; 14 | Description = description; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/Events/PaymentProcessedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | 3 | namespace ReadModel.AzFn.Events 4 | { 5 | public class PaymentProcessedIntegrationEvent : IntegrationEvent 6 | { 7 | public string PaymentId { get; set; } 8 | public string BookingOrderId { get; set; } 9 | public string CustomerId { get; set; } 10 | public PaymetStatus PaymentStatus { get; set; } 11 | 12 | 13 | public PaymentProcessedIntegrationEvent(string paymentId, string bookingOrderId, 14 | string customerId, PaymetStatus paymentStatus) 15 | { 16 | PaymentId = paymentId; 17 | BookingOrderId = bookingOrderId; 18 | CustomerId = customerId; 19 | PaymentStatus = paymentStatus; 20 | } 21 | } 22 | 23 | public enum PaymetStatus 24 | { 25 | Pending = 0, 26 | Completed = 1, 27 | Canceled = 2 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/Model/AggregateEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace ReadModel.AzFn.Model 6 | { 7 | public class AggregateEvent 8 | { 9 | public string Id { get; set; } 10 | public int Version { get; set; } 11 | public DateTime Timestamp { get; set; } 12 | public string MessageType { get; set; } 13 | public string EventData { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/Properties/PublishProfiles/MicroCourerisFunctionApp - Web Deploy.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 5 | 6 | 7 | MSDeploy 8 | AzureWebSite 9 | Release 10 | Any CPU 11 | https://microcourerisfunctionapp.azurewebsites.net 12 | False 13 | /subscriptions/37da0425-c79d-424d-9680-d7e23cc0980f/resourceGroups/MicroServicesStuff/providers/Microsoft.Web/sites/MicroCourerisFunctionApp 14 | $MicroCourerisFunctionApp 15 | <_SavePWD>True 16 | False 17 | microcourerisfunctionapp.scm.azurewebsites.net:443 18 | WMSVC 19 | False 20 | False 21 | True 22 | MicroCourerisFunctionApp 23 | 24 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/ReadModel.AzFn.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | netcoreapp2.2 4 | v2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | PreserveNewest 23 | Never 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/UpdateCache.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Azure.ServiceBus; 2 | using Microsoft.Azure.WebJobs; 3 | using Microsoft.Azure.WebJobs.Host; 4 | using Microsoft.Extensions.Logging; 5 | using Newtonsoft.Json; 6 | using Newtonsoft.Json.Linq; 7 | using ReadModel.AzFn.DB; 8 | using ReadModel.AzFn.Events; 9 | using System.Text; 10 | 11 | namespace ReadModel.AzFn 12 | { 13 | public static class UpdateCache 14 | { 15 | [FunctionName("UpdateCache")] 16 | public static async void Run([ServiceBusTrigger("microcouriers-topic", "readprojection", Connection = "ServiceBus")]Message serviceBusMessage, ILogger log) 17 | { 18 | //Redis is our read model.Every Event Triggered will be appended against the booking. 19 | //We are building the read Model in redis since we are using CQRS where read 20 | //model is seperate from Write 21 | 22 | EventStore eS = new EventStore(); 23 | await eS.UpdateBookingModelInCache(serviceBusMessage); 24 | 25 | // log.LogInformation($"C# ServiceBus topic trigger function processed message: {mySbMsg}"); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/Services/ReadProjections/ReadModel.AzFn/host.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0" 3 | } -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.API/Dockerfile: -------------------------------------------------------------------------------- 1 | #Depending on the operating system of the host machines(s) that will build or run the containers, the image specified in the FROM statement may need to be changed. 2 | #For more information, please see https://aka.ms/containercompat 3 | 4 | FROM microsoft/dotnet:2.2-aspnetcore-runtime-nanoserver-1803 AS base 5 | WORKDIR /app 6 | EXPOSE 80 7 | 8 | FROM microsoft/dotnet:2.2-sdk-nanoserver-1803 AS build 9 | WORKDIR /src 10 | COPY ["src/Services/Shipping/Shipping.API/Shipping.API.csproj", "src/Services/Shipping/Shipping.API/"] 11 | RUN dotnet restore "src/Services/Shipping/Shipping.API/Shipping.API.csproj" 12 | COPY . . 13 | WORKDIR "/src/src/Services/Shipping/Shipping.API" 14 | RUN dotnet build "Shipping.API.csproj" -c Release -o /app 15 | 16 | FROM build AS publish 17 | RUN dotnet publish "Shipping.API.csproj" -c Release -o /app 18 | 19 | FROM base AS final 20 | WORKDIR /app 21 | COPY --from=publish /app . 22 | ENTRYPOINT ["dotnet", "Shipping.API.dll"] -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.API/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.EntityFrameworkCore; 9 | using Microsoft.Extensions.Configuration; 10 | using Microsoft.Extensions.DependencyInjection; 11 | using Microsoft.Extensions.Logging; 12 | using Shipping.Persistence; 13 | using Polly; 14 | 15 | namespace Shipping.API 16 | { 17 | public class Program 18 | { 19 | public static void Main(string[] args) 20 | { 21 | //Create/Migrate the database 22 | var host = CreateWebHostBuilder(args).Build(); 23 | 24 | using (var scope = host.Services.CreateScope()) 25 | { 26 | try 27 | { 28 | var context = scope.ServiceProvider.GetService(); 29 | 30 | var concreteContext = (ShippingDbContext)context; 31 | 32 | //Retry logic for DB connectivity 33 | Policy 34 | .Handle() 35 | .WaitAndRetry(5, r => TimeSpan.FromSeconds(10)) 36 | .Execute(() => concreteContext.Database.Migrate()); 37 | 38 | } 39 | catch (Exception) 40 | { 41 | 42 | } 43 | } 44 | 45 | host.Run(); 46 | } 47 | 48 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 49 | WebHost.CreateDefaultBuilder(args) 50 | .UseStartup(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.API/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:65137", 7 | "sslPort": 0 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/values", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "Shipping.API": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "http://localhost:5000" 28 | }, 29 | "Docker": { 30 | "commandName": "Docker", 31 | "launchBrowser": true, 32 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/api/values" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.API/Shipping.API.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | Windows 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.API/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "MicroCouriersDataBase": "server=localhost,1433;user id=sa;password=99888ukGh43hnDw89Hol8LN21112;database=MicroCouriersShipment;" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Debug", 8 | "System": "Information", 9 | "Microsoft": "Information" 10 | } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.API/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Warning" 5 | } 6 | }, 7 | "AllowedHosts": "*" 8 | } 9 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.Application/Shipping.Application.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.Domain/Entities/ShippingStatus.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Shipping.Domain.Entities 6 | { 7 | public enum ShippingStatus 8 | { 9 | Pending = 0, 10 | Completed = 1, 11 | Canceled = 2 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.Domain/Entities/Shippings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Shipping.Domain.Entities 6 | { 7 | public class Shippings 8 | { 9 | public string ShippingsId { get; set; } 10 | 11 | public string BookingOrderId { get; set; } 12 | 13 | public string CustomerId { get; set; } 14 | 15 | public DateTime CreatedDate { get; set; } 16 | 17 | public DateTime? UpdatedDate { get; set; } 18 | 19 | public ICollection ShippingHistory { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.Domain/Entities/ShippingsHistory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Shipping.Domain.Entities 6 | { 7 | public class ShippingsHistory 8 | { 9 | public string ShippingsHistoryId { get; set; } 10 | 11 | public ShippingStatus ShippingStatus { get; set; } 12 | 13 | public Shippings Shippings { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.Domain/Interfaces/IShippingRepository.cs: -------------------------------------------------------------------------------- 1 | using Shipping.Domain.Entities; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Shipping.Domain.Interfaces 8 | { 9 | public interface IShippingRepository 10 | { 11 | Task AddShippingAsync(Shippings shippings); 12 | Task AddShippingHisotryAsync(ShippingsHistory shippingsHistory); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.Domain/Shipping.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.Persistence/Shipping.Persistence.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | all 11 | runtime; build; native; contentfiles; analyzers 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.Persistence/ShippingDbContext.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.EntityFrameworkCore; 2 | using Shipping.Domain.Entities; 3 | 4 | namespace Shipping.Persistence 5 | { 6 | public class ShippingDbContext : DbContext 7 | { 8 | 9 | public ShippingDbContext(DbContextOptions options) 10 | : base(options) 11 | { 12 | 13 | } 14 | 15 | 16 | public DbSet Shippings { get; set; } 17 | 18 | public DbSet ShippingsHistory { get; set; } 19 | 20 | //One-to-Many RelationShipSetup 21 | protected override void OnModelCreating(ModelBuilder modelBuilder) 22 | { 23 | modelBuilder.Entity() 24 | .HasOne(p => p.Shippings) 25 | .WithMany(b => b.ShippingHistory); 26 | } 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/Services/Shipping/Shipping.Tests/Shipping.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.API/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.14.11009.1", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.API/Controllers/TrackingController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.ApplicationInsights; 6 | using Microsoft.AspNetCore.Http; 7 | using Microsoft.AspNetCore.Mvc; 8 | using Tracking.Application.DTO; 9 | using Tracking.Application.Interface; 10 | 11 | namespace Tracking.API.Controllers 12 | { 13 | [Route("api/[controller]")] 14 | [ApiController] 15 | public class TrackingController : ControllerBase 16 | { 17 | private ITrackingService _trackingService; 18 | private TelemetryClient telemetry; 19 | 20 | public TrackingController(ITrackingService trackingservice, TelemetryClient telemetry) 21 | { 22 | _trackingService = trackingservice; 23 | this.telemetry = telemetry; 24 | } 25 | 26 | 27 | // GET: api/Tracking/5 28 | [HttpGet("{id}")] 29 | [ProducesResponseType(StatusCodes.Status200OK)] 30 | [ProducesResponseType(StatusCodes.Status404NotFound)] 31 | [ProducesResponseType(StatusCodes.Status500InternalServerError)] 32 | public async Task Get(string id) 33 | { 34 | try 35 | { 36 | var resultSet = await _trackingService.FindByIdAsync(id); 37 | 38 | if (resultSet == null) 39 | { 40 | return NotFound(); 41 | } 42 | 43 | return Ok(resultSet); 44 | } 45 | catch(Exception ex) 46 | { 47 | telemetry.TrackException(ex); 48 | return StatusCode(StatusCodes.Status500InternalServerError, "Sorry Some problem Occured In Tracking Service"); 49 | } 50 | } 51 | 52 | // POST: api/Tracking 53 | [HttpPost] 54 | public void Post([FromBody] string value) 55 | { 56 | } 57 | 58 | // PUT: api/Tracking/5 59 | [HttpPut("{id}")] 60 | public void Put(int id, [FromBody] string value) 61 | { 62 | } 63 | 64 | // DELETE: api/ApiWithActions/5 65 | [HttpDelete("{id}")] 66 | public void Delete(int id) 67 | { 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.API/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base 2 | WORKDIR /app 3 | EXPOSE 80 4 | 5 | FROM microsoft/dotnet:2.2-sdk AS build 6 | WORKDIR /src 7 | COPY ["src/Services/Tracking/Tracking.API/Tracking.API.csproj", "src/Services/Tracking/Tracking.API/"] 8 | RUN dotnet restore "src/Services/Tracking/Tracking.API/Tracking.API.csproj" 9 | COPY . . 10 | WORKDIR "/src/src/Services/Tracking/Tracking.API" 11 | RUN dotnet build "Tracking.API.csproj" -c Release -o /app 12 | 13 | FROM build AS publish 14 | RUN dotnet publish "Tracking.API.csproj" -c Release -o /app 15 | 16 | FROM base AS final 17 | WORKDIR /app 18 | COPY --from=publish /app . 19 | ENTRYPOINT ["dotnet", "Tracking.API.dll"] -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.API/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace Tracking.API 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseApplicationInsights() 23 | .UseStartup(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.API/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:5002", 7 | "sslPort": 0 8 | } 9 | }, 10 | "$schema": "http://json.schemastore.org/launchsettings.json", 11 | "profiles": { 12 | "IIS Express": { 13 | "commandName": "IISExpress", 14 | "launchBrowser": true, 15 | "launchUrl": "api/tracking", 16 | "environmentVariables": { 17 | "ASPNETCORE_ENVIRONMENT": "Development" 18 | } 19 | }, 20 | "Tracking.API": { 21 | "commandName": "Project", 22 | "launchBrowser": true, 23 | "launchUrl": "api/values", 24 | "environmentVariables": { 25 | "ASPNETCORE_ENVIRONMENT": "Development" 26 | }, 27 | "applicationUrl": "http://localhost:5002" 28 | }, 29 | "Docker": { 30 | "commandName": "Docker", 31 | "launchBrowser": true, 32 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/api/values" 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.API/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "EventStoreCN": "server=localhost,1433;user id=sa;password=99888ukGh43hnDw89Hol8LN21112;database=TrackingEventsStore;" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "cache": { 11 | "REDIS": "" 12 | }, 13 | "AllowedHosts": "*", 14 | "EventBusConnection": "", 15 | "SubscriptionClientName": "tracking", 16 | "ApplicationInsights": { 17 | "InstrumentationKey": "" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.API/appsettings.Production.json: -------------------------------------------------------------------------------- 1 | { 2 | "ConnectionStrings": { 3 | "EventStoreCN": "server=sqlserver;user id=sa;password=99888ukGh43hnDw89Hol8LN21112;database=TrackingEventsStore;" 4 | }, 5 | "Logging": { 6 | "LogLevel": { 7 | "Default": "Warning" 8 | } 9 | }, 10 | "cache": { 11 | "REDIS": "" 12 | }, 13 | "AllowedHosts": "*", 14 | "EventBusConnection": "", 15 | "SubscriptionClientName": "tracking", 16 | "ApplicationInsights": { 17 | "InstrumentationKey": "" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.API/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/DTO/TrackingDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Application.DTO 6 | { 7 | public class TrackingDTO 8 | { 9 | public string BookingId { get; set; } 10 | 11 | public string TrackingHistory { get; set; } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/IntegrationEvents/BookingAddIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Tracking.Application.IntegrationEvents 7 | { 8 | public class BookingAddIntegrationEvent : IntegrationEvent 9 | { 10 | public string BookingId { get; set; } 11 | public string Origin { get; set; } 12 | public string Destination { get; set; } 13 | 14 | 15 | public BookingAddIntegrationEvent(string bookingId, string origin, string destination) 16 | { 17 | BookingId = bookingId; 18 | Origin = origin; 19 | Destination = destination; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/IntegrationEvents/OrderDeliveredIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Tracking.Application.IntegrationEvents 7 | { 8 | public class OrderDeliveredIntegrationEvent : IntegrationEvent 9 | { 10 | public string BookingId { get; set; } 11 | public string Description { get; set; } 12 | public string SignedBy { get; set; } 13 | 14 | public OrderDeliveredIntegrationEvent(string bookingId, string description ,string signedBy) 15 | { 16 | BookingId = bookingId; 17 | Description = description; 18 | SignedBy = signedBy; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/IntegrationEvents/OrderPickedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Tracking.Application.IntegrationEvents 7 | { 8 | public class OrderPickedIntegrationEvent : IntegrationEvent 9 | { 10 | public string BookingId { get; set; } 11 | public string Description { get; set; } 12 | 13 | 14 | public OrderPickedIntegrationEvent(string bookingId, string description) 15 | { 16 | BookingId = bookingId; 17 | Description = description; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/IntegrationEvents/OrderStatusChangedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Tracking.Application.IntegrationEvents 7 | { 8 | public class OrderStatusChangedIntegrationEvent : IntegrationEvent 9 | { 10 | public string BookingId { get; set; } 11 | public string CurrentStatus { get; set; } 12 | public OrderStatusChangedIntegrationEvent(string bookingId ,string currentStatus) 13 | { 14 | CurrentStatus = currentStatus; 15 | BookingId = bookingId; 16 | } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/IntegrationEvents/OrderTransitIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Text; 5 | 6 | namespace Tracking.Application.IntegrationEvents 7 | { 8 | public class OrderTransitIntegrationEvent : IntegrationEvent 9 | { 10 | public string BookingId { get; set; } 11 | public string Description { get; set; } 12 | 13 | 14 | public OrderTransitIntegrationEvent(string bookingId, string description) 15 | { 16 | BookingId = bookingId; 17 | Description = description; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/IntegrationEvents/PaymentProcessedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 |  2 | 3 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 4 | 5 | namespace Tracking.Application.IntegrationEvents 6 | { 7 | public class PaymentProcessedIntegrationEvent : IntegrationEvent 8 | { 9 | public string PaymentId { get; set; } 10 | public string BookingOrderId { get; set; } 11 | public string CustomerId { get; set; } 12 | public PaymetStatus PaymentStatus { get; set; } 13 | 14 | 15 | public PaymentProcessedIntegrationEvent(string paymentId, string bookingOrderId, 16 | string customerId, PaymetStatus paymentStatus) 17 | { 18 | PaymentId = paymentId; 19 | BookingOrderId = bookingOrderId; 20 | CustomerId = customerId; 21 | PaymentStatus = paymentStatus; 22 | } 23 | } 24 | 25 | public enum PaymetStatus 26 | { 27 | Pending = 0, 28 | Completed = 1, 29 | Canceled = 2 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/Interface/ITrackingService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using System.Threading.Tasks; 5 | using Tracking.Application.DTO; 6 | 7 | namespace Tracking.Application.Interface 8 | { 9 | public interface ITrackingService 10 | { 11 | Task FindByIdAsync(string bookingId); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/Tracking.Application.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/TrackingServices/TrackingSerivceWithoutCache.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using System; 3 | using System.Threading.Tasks; 4 | using Tracking.Application.DTO; 5 | using Tracking.Application.Interface; 6 | using Tracking.Domain.Interfaces; 7 | 8 | namespace Tracking.Application.TrackingServices 9 | { 10 | //If we don't have any cahce configured we will read it from DB directly 11 | //and seralize the response 12 | public class TrackingSerivceWithoutCache : ITrackingService 13 | { 14 | private readonly ITrackingRepository _context; 15 | 16 | public TrackingSerivceWithoutCache(ITrackingRepository context) 17 | { 18 | _context = context; 19 | } 20 | 21 | public async Task FindByIdAsync(string bookingId) 22 | { 23 | var result = await _context.GetTrackingAsync(bookingId); 24 | var bookingHistroy = string.Empty; 25 | 26 | if (result != null) 27 | { 28 | //format result and serilize it 29 | bookingHistroy = JsonConvert.SerializeObject(result.orderHistory); 30 | } 31 | 32 | return new TrackingDTO 33 | { 34 | BookingId = bookingId, 35 | TrackingHistory = bookingHistroy 36 | }; 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Application/TrackingServices/TrackingService.cs: -------------------------------------------------------------------------------- 1 | using Newtonsoft.Json; 2 | using StackExchange.Redis; 3 | using System; 4 | using System.Threading.Tasks; 5 | using Tracking.Application.DTO; 6 | using Tracking.Application.Interface; 7 | using Tracking.Domain.Interfaces; 8 | 9 | namespace Tracking.Application.TrackingServices 10 | { 11 | //If we have cache service configured we will read it from cache 12 | //If we don't have event in the cache yet or expired we repopulate the cache 13 | public class TrackingService : ITrackingService 14 | { 15 | private readonly ITrackingRepository _context; 16 | private readonly IDatabase _cache; 17 | 18 | 19 | public TrackingService(ITrackingRepository context, 20 | IConnectionMultiplexer multiplexer) 21 | { 22 | _context = context; 23 | _cache = multiplexer.GetDatabase(); 24 | } 25 | 26 | public async Task FindByIdAsync(string bookingId) 27 | { 28 | //check in the redis cahce 29 | var bookingHistroy = await GetFromCache(bookingId); 30 | 31 | //if not found in the cahce 32 | if (string.IsNullOrEmpty(bookingHistroy)) 33 | { 34 | //get from database 35 | var result = await _context.GetTrackingAsync(bookingId); 36 | if (result != null) 37 | { 38 | //format result and serlize the history 39 | bookingHistroy = JsonConvert.SerializeObject(result.orderHistory); 40 | SetCache(bookingId, bookingHistroy); 41 | } 42 | } 43 | 44 | return new TrackingDTO 45 | { 46 | BookingId = bookingId, 47 | TrackingHistory = bookingHistroy 48 | }; 49 | } 50 | 51 | // 52 | private async Task GetFromCache(string bookingId) 53 | { 54 | return await _cache.StringGetAsync(bookingId); 55 | } 56 | 57 | private async void SetCache(string bookingId, string bookingHistroy) 58 | { 59 | //Update Cache , we keep booking history for 10 hours 60 | var ts = TimeSpan.FromHours(10); 61 | await _cache.StringSetAsync(bookingId, bookingHistroy, ts); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Common/Tracking.Common.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Common/TypeResolver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Text; 6 | 7 | namespace Tracking.Common 8 | { 9 | public static class TypeResolver 10 | { 11 | //We keep the reference of all the events in List 12 | public static List AssemblyTypes; 13 | 14 | //Load and save all the event types dynamically 15 | static TypeResolver() { 16 | AssemblyTypes = Assembly.Load("Tracking.Domain") 17 | .GetTypes().ToList(); 18 | } 19 | 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Events/BookingCreated.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Domain.Events 6 | { 7 | public class BookingCreated : EventBase 8 | { 9 | public string Origin { get; set; } 10 | public string Destination { get; set; } 11 | 12 | 13 | public BookingCreated(string bookingId, string description, 14 | Guid messageId, string messageType, DateTime datetime, string 15 | origin, string destination) 16 | { 17 | BookingId = bookingId; 18 | Description = description; 19 | Origin = origin; 20 | Destination = destination; 21 | base.MessageType = messageType; 22 | base.MessageId = messageId; 23 | base.Date = datetime; 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Events/EventBase.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Domain.Events 6 | { 7 | public class EventBase 8 | { 9 | public Guid MessageId; 10 | 11 | public string MessageType; 12 | 13 | public string BookingId { get; set; } 14 | 15 | public string Description { get; set; } 16 | 17 | public DateTime Date { get; set; } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Events/OrderDelivered.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Domain.Events 6 | { 7 | public class OrderDelivered : EventBase 8 | { 9 | public string SignedBy{ get; set; } 10 | 11 | public OrderDelivered(string bookingId, string description, 12 | Guid messageId, string messageType, DateTime datetime ,string signedBy) 13 | { 14 | BookingId = bookingId; 15 | Description = description; 16 | SignedBy = signedBy; 17 | base.MessageType = messageType; 18 | base.MessageId = messageId; 19 | base.Date = datetime; 20 | } 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Events/OrderInTransit.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Domain.Events 6 | { 7 | public class OrderInTransit : EventBase 8 | { 9 | public OrderInTransit(string bookingId, string description, 10 | Guid messageId, string messageType, DateTime datetime) 11 | { 12 | BookingId = bookingId; 13 | Description = description; 14 | base.MessageType = messageType; 15 | base.MessageId = messageId; 16 | base.Date = datetime; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Events/OrderPicked.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Domain.Events 6 | { 7 | public class OrderPicked : EventBase 8 | { 9 | public OrderPicked(string bookingId, string description, 10 | Guid messageId, string messageType, DateTime datetime) 11 | { 12 | BookingId = bookingId; 13 | Description = description; 14 | base.MessageType = messageType; 15 | base.MessageId = messageId; 16 | base.Date = datetime; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Events/PaymentProcessed.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Domain.Events 6 | { 7 | public class PaymentProcessed : EventBase 8 | { 9 | public PaymentProcessed(string bookingId, string description , 10 | Guid messageId , string messageType , DateTime datetime) 11 | { 12 | BookingId = bookingId; 13 | Description = description; 14 | base.MessageType = messageType; 15 | base.MessageId = messageId; 16 | base.Date = datetime; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Interfaces/ICahce.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Domain.Interfaces 6 | { 7 | public interface ICahce 8 | { 9 | bool Exists(string key); 10 | void Save(string key, string value); 11 | string Get(string key); 12 | void Remove(string key); 13 | void Clear(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Interfaces/ITrackingRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | using Tracking.Domain.AggregatesModel.TrackingAggregate; 4 | using Tracking.Domain.Events; 5 | 6 | namespace Tracking.Domain.Interfaces 7 | { 8 | public interface ITrackingRepository 9 | { 10 | void EnsureDatabase(); 11 | Task GetTrackingAsync(string bookingId); 12 | Task GetEventVersion(string bookingId); 13 | Task SaveTrackingAsync(string bookingId, int originalVersion, int newVersion, 14 | IEnumerable newEvents); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Model/OrderHistory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Domain.Model 6 | { 7 | public class OrderHistory 8 | { 9 | public string BookingOrderId { get; set; } 10 | 11 | public string CustomerId { get; set; } 12 | 13 | public string Origion { get; set; } 14 | 15 | public string Destination { get; set; } 16 | 17 | public string OrderState { get; set; } 18 | 19 | public string DateTime { get; set; } 20 | 21 | public string Description { get; set; } 22 | 23 | public string SignedBy { get; set; } 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Domain/Tracking.Domain.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Persistence/Model/Aggregate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Persistence.Model 6 | { 7 | public class Aggregate 8 | { 9 | public string Id { get; set; } 10 | public int CurrentVersion { get; set; } 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Persistence/Model/AggregateEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | 5 | namespace Tracking.Persistence.Model 6 | { 7 | public class AggregateEvent 8 | { 9 | public string Id { get; set; } 10 | public int Version { get; set; } 11 | public DateTime Timestamp { get; set; } 12 | public string MessageType { get; set; } 13 | public string EventData { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Persistence/Tracking.Persistence.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Tests/Tracking.Tests.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | netcoreapp2.2 5 | 6 | false 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/Services/Tracking/Tracking.Tests/UnitTests/Infrastructure/TrackingContextFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Text; 4 | using Tracking.Persistence.Repositories; 5 | 6 | namespace Tracking.Tests.UnitTests.Infrastructure 7 | { 8 | public class TrackingContextFactory 9 | { 10 | 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/ShippingSimulation/OrderShipping/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/ShippingSimulation/OrderShipping/Events/OrderDeliveredIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OrderShipping.Events 9 | { 10 | public class OrderDeliveredIntegrationEvent : IntegrationEvent 11 | { 12 | public string BookingId { get; set; } 13 | public string Description { get; set; } 14 | public string SignedBy { get; set; } 15 | 16 | public OrderDeliveredIntegrationEvent(string bookingId, string description, string signedBy) 17 | { 18 | BookingId = bookingId; 19 | Description = description; 20 | SignedBy = signedBy; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/ShippingSimulation/OrderShipping/Events/OrderPickedIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OrderShipping.Events 9 | { 10 | public class OrderPickedIntegrationEvent : IntegrationEvent 11 | { 12 | public string BookingId { get; set; } 13 | public string Description { get; set; } 14 | 15 | 16 | public OrderPickedIntegrationEvent(string bookingId, string description) 17 | { 18 | BookingId = bookingId; 19 | Description = description; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/ShippingSimulation/OrderShipping/Events/OrderTransitIntegrationEvent.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.MicroCouriers.BuildingBlocks.EventBus.Events; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace OrderShipping.Events 9 | { 10 | 11 | public class OrderTransitIntegrationEvent : IntegrationEvent 12 | { 13 | public string BookingId { get; set; } 14 | public string Description { get; set; } 15 | 16 | 17 | public OrderTransitIntegrationEvent(string bookingId, string description) 18 | { 19 | BookingId = bookingId; 20 | Description = description; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/ShippingSimulation/OrderShipping/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using System.Windows.Forms; 6 | 7 | namespace OrderShipping 8 | { 9 | static class Program 10 | { 11 | /// 12 | /// The main entry point for the application. 13 | /// 14 | [STAThread] 15 | static void Main() 16 | { 17 | Application.EnableVisualStyles(); 18 | Application.SetCompatibleTextRenderingDefault(false); 19 | Application.Run(new Shipping()); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/ShippingSimulation/OrderShipping/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("OrderShipping")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("OrderShipping")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("3bf67944-a301-46d3-af24-ee6538af0c7f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/ShippingSimulation/OrderShipping/Properties/Settings.Designer.cs: -------------------------------------------------------------------------------- 1 | //------------------------------------------------------------------------------ 2 | // 3 | // This code was generated by a tool. 4 | // Runtime Version:4.0.30319.42000 5 | // 6 | // Changes to this file may cause incorrect behavior and will be lost if 7 | // the code is regenerated. 8 | // 9 | //------------------------------------------------------------------------------ 10 | 11 | namespace OrderShipping.Properties 12 | { 13 | 14 | 15 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] 16 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] 17 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase 18 | { 19 | 20 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); 21 | 22 | public static Settings Default 23 | { 24 | get 25 | { 26 | return defaultInstance; 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/ShippingSimulation/OrderShipping/Properties/Settings.settings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/ShippingSimulation/OrderShipping/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/TrackingDockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base 2 | WORKDIR /app 3 | EXPOSE 5002 4 | 5 | FROM microsoft/dotnet:2.2-sdk AS build 6 | WORKDIR /src 7 | 8 | 9 | 10 | COPY ["BuildingBlocks/EventBus/EventBus/EventBus.csproj", "BuildingBlocks/EventBus/EventBus/"] 11 | COPY ["BuildingBlocks/EventBus/EventBusServiceBus/EventBusServiceBus.csproj", "BuildingBlocks/EventBus/EventBusServiceBus/"] 12 | COPY ["BuildingBlocks/EventBus/IntegrationEventLogEF/IntegrationEventLogEF.csproj", "BuildingBlocks/EventBus/IntegrationEventLogEF/"] 13 | 14 | COPY ["Services/Tracking/Tracking.API/Tracking.API.csproj", "Services/Tracking/Tracking.API/"] 15 | COPY ["Services/Tracking/Tracking.Application/Tracking.Application.csproj", "Services/Tracking/Tracking.Application/"] 16 | COPY ["Services/Tracking/Tracking.Common/Tracking.Common.csproj", "Services/Tracking/Tracking.Common/"] 17 | COPY ["Services/Tracking/Tracking.Domain/Tracking.Domain.csproj", "Services/Tracking/Tracking.Domain/"] 18 | COPY ["Services/Tracking/Tracking.Persistence/Tracking.Persistence.csproj", "Services/Tracking/Tracking.Persistence/"] 19 | 20 | RUN dotnet restore "Services/Tracking/Tracking.API/Tracking.API.csproj" 21 | 22 | 23 | COPY . . 24 | 25 | 26 | WORKDIR "/src/Services/Tracking/Tracking.API" 27 | 28 | 29 | RUN dotnet build "Tracking.API.csproj" -c Release -o /app 30 | 31 | FROM build AS publish 32 | RUN dotnet publish "Tracking.API.csproj" -c Release -o /app 33 | 34 | FROM base AS final 35 | WORKDIR /app 36 | COPY --from=publish /app . 37 | 38 | 39 | ENTRYPOINT ["dotnet", "Tracking.API.dll"] -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Commands/CreateBookingCommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MicroCourier.Web.Commands 8 | { 9 | public class CreateBookingCommand 10 | { 11 | [Required] 12 | public readonly ICollection BookingDetails; 13 | 14 | public CreateBookingCommand(string bookingOrderId, string customerId) 15 | { 16 | CustomerId = customerId; 17 | BookingDetails = new List(); 18 | } 19 | 20 | [Required] 21 | [MinLength(5, ErrorMessage = "Origin is required")] 22 | public string Origin { get; set; } 23 | 24 | [Required] 25 | [MinLength(5, ErrorMessage = "Destination is required")] 26 | public string Destination { get; set; } 27 | 28 | //[Required] 29 | public string CustomerId { get; set; } 30 | 31 | } 32 | 33 | public class BookingOrderDetails 34 | { 35 | public string PackageType { get; set; } 36 | public string PackageDescription { get; set; } 37 | public decimal Price { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Connected Services/Application Insights/ConnectedService.json: -------------------------------------------------------------------------------- 1 | { 2 | "ProviderId": "Microsoft.ApplicationInsights.ConnectedService.ConnectedServiceProvider", 3 | "Version": "8.14.11009.1", 4 | "GettingStartedDocument": { 5 | "Uri": "https://go.microsoft.com/fwlink/?LinkID=798432" 6 | } 7 | } -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Controllers/HomeController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore.Mvc; 7 | using MicroCourier.Web.Models; 8 | 9 | namespace MicroCourier.Web.Controllers 10 | { 11 | public class HomeController : Controller 12 | { 13 | public IActionResult Index() 14 | { 15 | return View(); 16 | } 17 | 18 | public IActionResult Privacy() 19 | { 20 | return View(); 21 | } 22 | 23 | public IActionResult Tracking() 24 | { 25 | return View(); 26 | } 27 | 28 | public IActionResult Booking() 29 | { 30 | return View(); 31 | } 32 | 33 | public IActionResult Payment() 34 | { 35 | return View(); 36 | } 37 | 38 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 39 | public IActionResult Error() 40 | { 41 | return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier }); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Controllers/TrackingController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using MicroCourier.Web.DTO; 6 | using MicroCourier.Web.RESTClients; 7 | using Microsoft.ApplicationInsights; 8 | using Microsoft.AspNetCore.Http; 9 | using Microsoft.AspNetCore.Mvc; 10 | using Polly.CircuitBreaker; 11 | 12 | namespace MicroCourier.Web.Controllers 13 | { 14 | [Route("api/[controller]")] 15 | [ApiController] 16 | public class TrackingController : ControllerBase 17 | { 18 | private TelemetryClient telemetry; 19 | private readonly ITrackingAPI _trackingAPI; 20 | 21 | public TrackingController(ITrackingAPI trackingAPI, TelemetryClient telemetry) 22 | { 23 | _trackingAPI = trackingAPI; 24 | this.telemetry = telemetry; 25 | } 26 | 27 | 28 | // GET: api/Tracking 29 | [HttpGet] 30 | public IEnumerable Get() 31 | { 32 | return new string[] { "value1", "value2" }; 33 | } 34 | 35 | // GET: api/Tracking/5 36 | [HttpGet("{id}")] 37 | public async Task Get(string id) 38 | { 39 | try 40 | { 41 | var res= await _trackingAPI.GetOrderHistory(id); 42 | return Ok(res); 43 | } 44 | catch (BrokenCircuitException ex) 45 | { 46 | telemetry.TrackException(ex); 47 | // Catches error when api is in circuit-opened mode 48 | return StatusCode(StatusCodes.Status500InternalServerError, "Sorry Tracking Service Is Not Available. Please try again later."); 49 | } 50 | catch (Exception ex) 51 | { 52 | telemetry.TrackException(ex); 53 | return StatusCode(StatusCodes.Status500InternalServerError, "Sorry Some problem Occured"); 54 | } 55 | 56 | } 57 | 58 | // POST: api/Tracking 59 | [HttpPost] 60 | public void Post([FromBody] string value) 61 | { 62 | } 63 | 64 | // PUT: api/Tracking/5 65 | [HttpPut("{id}")] 66 | public void Put(int id, [FromBody] string value) 67 | { 68 | } 69 | 70 | // DELETE: api/ApiWithActions/5 71 | [HttpDelete("{id}")] 72 | public void Delete(int id) 73 | { 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/DTO/BookingOrderDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MicroCourier.Web.DTO 7 | { 8 | public class BookingOrderDTO 9 | { 10 | public string BookingOrderId { get; set; } 11 | public string CustomerId { get; set; } 12 | public string Origin { get; set; } 13 | public string Destination { get; set; } 14 | 15 | public ICollection BookingDetails { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/DTO/BookingOrderDetailDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MicroCourier.Web.DTO 7 | { 8 | public class BookingOrderDetailDTO 9 | { 10 | public string PackageType { get; set; } 11 | public string Description { get; set; } 12 | public decimal Price { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/DTO/PaymentDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.DataAnnotations; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MicroCourier.Web.DTO 8 | { 9 | public class PaymentDTO 10 | { 11 | public string PaymentsId { get; set; } 12 | 13 | [Required] 14 | public string BookingOrderId { get; set; } 15 | 16 | public string CustomerId { get; set; } 17 | 18 | [Required] 19 | public decimal Price { get; set; } 20 | 21 | public PaymetStatusDTO PaymentStatus { get; set; } 22 | } 23 | 24 | public enum PaymetStatusDTO 25 | { 26 | Pending = 0, 27 | Completed = 1, 28 | Canceled = 2 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/DTO/TrackingDTO.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | 6 | namespace MicroCourier.Web.DTO 7 | { 8 | public class TrackingDTO 9 | { 10 | public string BookingId { get; set; } 11 | 12 | public string TrackingHistory { get; set; } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM microsoft/dotnet:2.2-aspnetcore-runtime AS base 2 | WORKDIR /app 3 | EXPOSE 5004 4 | 5 | FROM microsoft/dotnet:2.2-sdk AS build 6 | WORKDIR /src 7 | COPY ["src/Web/MicroCourier.Web/MicroCourier.Web.csproj", "src/Web/MicroCourier.Web/"] 8 | RUN dotnet restore "src/Web/MicroCourier.Web/MicroCourier.Web.csproj" 9 | COPY . . 10 | WORKDIR "/src/src/Web/MicroCourier.Web" 11 | RUN dotnet build "MicroCourier.Web.csproj" -c Release -o /app 12 | 13 | FROM build AS publish 14 | RUN dotnet publish "MicroCourier.Web.csproj" -c Release -o /app 15 | 16 | FROM base AS final 17 | WORKDIR /app 18 | COPY --from=publish /app . 19 | ENTRYPOINT ["dotnet", "MicroCourier.Web.dll"] -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/MicroCourier.Web.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | netcoreapp2.2 5 | InProcess 6 | Linux 7 | /subscriptions/37da0425-c79d-424d-9680-d7e23cc0980f/resourcegroups/MicroServicesStuff/providers/microsoft.insights/components/MicroCourier.Web 8 | /subscriptions/37da0425-c79d-424d-9680-d7e23cc0980f/resourcegroups/MicroServicesStuff/providers/microsoft.insights/components/MicroCourier.Web 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Models/ErrorViewModel.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace MicroCourier.Web.Models 4 | { 5 | public class ErrorViewModel 6 | { 7 | public string RequestId { get; set; } 8 | 9 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 10 | } 11 | } -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | using Microsoft.AspNetCore; 7 | using Microsoft.AspNetCore.Hosting; 8 | using Microsoft.Extensions.Configuration; 9 | using Microsoft.Extensions.Logging; 10 | 11 | namespace MicroCourier.Web 12 | { 13 | public class Program 14 | { 15 | public static void Main(string[] args) 16 | { 17 | CreateWebHostBuilder(args).Build().Run(); 18 | } 19 | 20 | public static IWebHostBuilder CreateWebHostBuilder(string[] args) => 21 | WebHost.CreateDefaultBuilder(args) 22 | .UseApplicationInsights() 23 | .UseStartup(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:5004", 7 | "sslPort": 0 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "MicroCourier.Web": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "http://localhost:5004" 25 | }, 26 | "Docker": { 27 | "commandName": "Docker", 28 | "launchBrowser": true, 29 | "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}" 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/RESTClients/BookingAPI.cs: -------------------------------------------------------------------------------- 1 | using MicroCourier.Web.Commands; 2 | using MicroCourier.Web.DTO; 3 | using Microsoft.Extensions.Configuration; 4 | using Refit; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Net; 9 | using System.Net.Http; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using Newtonsoft; 13 | using Newtonsoft.Json; 14 | using Microsoft.ApplicationInsights; 15 | 16 | namespace MicroCourier.Web.RESTClients 17 | { 18 | public class BookingAPI : IBookingAPI 19 | { 20 | 21 | private readonly HttpClient _client; 22 | 23 | public BookingAPI(IConfiguration config, HttpClient httpclient) 24 | { 25 | _client = httpclient; 26 | string apiHostAndPort = config.GetSection("APIServiceLocations").GetValue("BookingAPI"); 27 | 28 | string baseUri = $"http://{apiHostAndPort}"; 29 | _client.BaseAddress = new Uri(baseUri); 30 | } 31 | 32 | //The method is using partial resiliecy configured in startup.cs 33 | public async Task GetBookingById([AliasAs("id")] string bookingId) 34 | { 35 | try 36 | { 37 | var result = await _client.GetAsync("/api/booking/" + bookingId); 38 | 39 | if (result.StatusCode != HttpStatusCode.OK) 40 | return null; 41 | 42 | return await result.Content.ReadAsAsync(); 43 | } 44 | catch (Exception ex) 45 | { 46 | throw ex; 47 | } 48 | } 49 | 50 | //Booking create command with circuit breaker and retry logic 51 | public async Task CreatedBooking(CreateBookingCommand command) 52 | { 53 | try 54 | { 55 | var result = await _client.PostAsync("/api/booking", new StringContent(JsonConvert.SerializeObject(command), 56 | Encoding.UTF8, "application/json")); 57 | 58 | if (result.StatusCode != HttpStatusCode.Created) 59 | throw new Exception(result.ReasonPhrase); 60 | 61 | return await result.Content.ReadAsStringAsync(); 62 | } 63 | catch (Exception ex) 64 | { 65 | throw ex; 66 | } 67 | } 68 | 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/RESTClients/IBookingAPI.cs: -------------------------------------------------------------------------------- 1 | using MicroCourier.Web.Commands; 2 | using MicroCourier.Web.DTO; 3 | using Refit; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Threading.Tasks; 8 | 9 | namespace MicroCourier.Web.RESTClients 10 | { 11 | public interface IBookingAPI 12 | { 13 | Task GetBookingById(string bookingId); 14 | 15 | Task CreatedBooking(CreateBookingCommand command); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/RESTClients/IPaymentAPI.cs: -------------------------------------------------------------------------------- 1 | using MicroCourier.Web.DTO; 2 | using Refit; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Threading.Tasks; 7 | 8 | namespace MicroCourier.Web.RESTClients 9 | { 10 | public interface IPaymentAPI 11 | { 12 | Task CreatedPayment(PaymentDTO payment); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/RESTClients/ITrackingAPI.cs: -------------------------------------------------------------------------------- 1 | using MicroCourier.Web.DTO; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Threading.Tasks; 6 | 7 | namespace MicroCourier.Web.RESTClients 8 | { 9 | public interface ITrackingAPI 10 | { 11 | Task GetOrderHistory(string bookingId); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/RESTClients/PaymentAPI.cs: -------------------------------------------------------------------------------- 1 | using MicroCourier.Web.Commands; 2 | using MicroCourier.Web.DTO; 3 | using Microsoft.Extensions.Configuration; 4 | using Refit; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Net; 9 | using System.Net.Http; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using Newtonsoft; 13 | using Newtonsoft.Json; 14 | 15 | namespace MicroCourier.Web.RESTClients 16 | { 17 | public class PaymentAPI : IPaymentAPI 18 | { 19 | private readonly HttpClient _client; 20 | 21 | public PaymentAPI(IConfiguration config, HttpClient httpclient) 22 | { 23 | _client = httpclient; 24 | string apiHostAndPort = config.GetSection("APIServiceLocations").GetValue("PaymentAPI"); 25 | string baseUri = $"http://{apiHostAndPort}"; 26 | _client.BaseAddress = new Uri(baseUri); 27 | 28 | } 29 | public async Task CreatedPayment(PaymentDTO payment) 30 | { 31 | try 32 | { 33 | var result = await _client.PostAsync("/api/payment", new StringContent(JsonConvert.SerializeObject(payment), 34 | Encoding.UTF8, "application/json")); 35 | 36 | if (result.StatusCode != HttpStatusCode.Created) 37 | throw new Exception(result.ReasonPhrase); 38 | 39 | return await result.Content.ReadAsStringAsync(); 40 | } 41 | catch (Exception ex) 42 | { 43 | throw ex; 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/RESTClients/TrackingAPI.cs: -------------------------------------------------------------------------------- 1 | using MicroCourier.Web.Commands; 2 | using MicroCourier.Web.DTO; 3 | using Microsoft.Extensions.Configuration; 4 | using Refit; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Net; 9 | using System.Net.Http; 10 | using System.Text; 11 | using System.Threading.Tasks; 12 | using Newtonsoft; 13 | using Newtonsoft.Json; 14 | 15 | namespace MicroCourier.Web.RESTClients 16 | { 17 | public class TrackingAPI : ITrackingAPI 18 | { 19 | private readonly HttpClient _client; 20 | 21 | public TrackingAPI(IConfiguration config, HttpClient httpclient) 22 | { 23 | string apiHostAndPort = config.GetSection("APIServiceLocations").GetValue("TrackingAPI"); 24 | string baseUri = $"http://{apiHostAndPort}"; 25 | 26 | _client = httpclient; 27 | _client.BaseAddress = new Uri(baseUri); 28 | 29 | } 30 | 31 | public async Task GetOrderHistory(string bookingId) 32 | { 33 | try 34 | { 35 | var result = await _client.GetAsync("/api/tracking/" + bookingId); 36 | return await result.Content.ReadAsAsync(); 37 | } 38 | catch (Exception ex) 39 | { 40 | throw ex; 41 | } 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Views/Home/Index.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Home Page"; 3 | } 4 | 5 |
6 |

Welcome to Microcouriers

7 |

Learn about my project here https://github.com/ImranMA/MicroCouriers

8 |
9 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Views/Home/Privacy.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | ViewData["Title"] = "Privacy Policy"; 3 | } 4 |

@ViewData["Title"]

5 | 6 |

Use this page to detail your site's privacy policy.

7 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Views/Shared/Error.cshtml: -------------------------------------------------------------------------------- 1 | @model ErrorViewModel 2 | @{ 3 | ViewData["Title"] = "Error"; 4 | } 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (Model.ShowRequestId) 10 | { 11 |

12 | Request ID: @Model.RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

26 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Views/Shared/_CookieConsentPartial.cshtml: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Http.Features 2 | 3 | @{ 4 | var consentFeature = Context.Features.Get(); 5 | var showBanner = !consentFeature?.CanTrack ?? false; 6 | var cookieString = consentFeature?.CreateConsentCookie(); 7 | } 8 | 9 | @if (showBanner) 10 | { 11 | @**@ 17 | 25 | } 26 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Views/Shared/_ValidationScriptsPartial.cshtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 12 | 18 | 19 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Views/_ViewImports.cshtml: -------------------------------------------------------------------------------- 1 | @using MicroCourier.Web 2 | @using MicroCourier.Web.Models 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/Views/_ViewStart.cshtml: -------------------------------------------------------------------------------- 1 | @{ 2 | Layout = "_Layout"; 3 | } 4 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/wwwroot/css/MicroCourierStyle.css: -------------------------------------------------------------------------------- 1 |  2 | input[type=text], select, textarea { 3 | width: 100%; 4 | padding: 12px; 5 | border: 1px solid #ccc; 6 | border-radius: 4px; 7 | box-sizing: border-box; 8 | margin-top: 6px; 9 | margin-bottom: 16px; 10 | resize: vertical; 11 | } 12 | 13 | input[type=submit] { 14 | background-color: #4CAF50; 15 | color: white; 16 | padding: 12px 20px; 17 | border: none; 18 | border-radius: 4px; 19 | cursor: pointer; 20 | } 21 | 22 | input[type=submit]:hover { 23 | background-color: #45a049; 24 | } 25 | 26 | .Formcontainer { 27 | border-radius: 5px; 28 | background-color: #f2f2f2; 29 | padding: 20px; 30 | } 31 | 32 | .txtPrice{ 33 | width : 80% !important; 34 | } -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | /* Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | for details on configuring this project to bundle and minify static web assets. */ 3 | 4 | a.navbar-brand { 5 | white-space: normal; 6 | text-align: center; 7 | word-break: break-all; 8 | } 9 | 10 | /* Sticky footer styles 11 | -------------------------------------------------- */ 12 | html { 13 | font-size: 14px; 14 | } 15 | @media (min-width: 768px) { 16 | html { 17 | font-size: 16px; 18 | } 19 | } 20 | 21 | .border-top { 22 | border-top: 1px solid #e5e5e5; 23 | } 24 | .border-bottom { 25 | border-bottom: 1px solid #e5e5e5; 26 | } 27 | 28 | .box-shadow { 29 | box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05); 30 | } 31 | 32 | button.accept-policy { 33 | font-size: 1rem; 34 | line-height: inherit; 35 | } 36 | 37 | /* Sticky footer styles 38 | -------------------------------------------------- */ 39 | html { 40 | position: relative; 41 | min-height: 100%; 42 | } 43 | 44 | body { 45 | /* Margin bottom by footer height */ 46 | margin-bottom: 60px; 47 | } 48 | .footer { 49 | position: absolute; 50 | bottom: 0; 51 | width: 100%; 52 | white-space: nowrap; 53 | /* Set the fixed height of the footer here */ 54 | height: 60px; 55 | line-height: 60px; /* Vertically center the text there */ 56 | } 57 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ImranMA/MicroCouriers/ee5868522336842f727bedcdf3e83f5572d6d2a0/src/Web/MicroCourier.Web/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/wwwroot/js/site.js: -------------------------------------------------------------------------------- 1 | // Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification 2 | // for details on configuring this project to bundle and minify static web assets. 3 | 4 | // Write your JavaScript code. 5 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/wwwroot/lib/bootstrap/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2011-2018 Twitter, Inc. 4 | Copyright (c) 2011-2018 The Bootstrap Authors 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/wwwroot/lib/jquery-validation-unobtrusive/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) .NET Foundation. All rights reserved. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use 4 | these files except in compliance with the License. You may obtain a copy of the 5 | License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software distributed 10 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 11 | CONDITIONS OF ANY KIND, either express or implied. See the License for the 12 | specific language governing permissions and limitations under the License. 13 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/wwwroot/lib/jquery-validation/LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright Jörn Zaefferer 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/Web/MicroCourier.Web/wwwroot/lib/jquery/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright JS Foundation and other contributors, https://js.foundation/ 2 | 3 | This software consists of voluntary contributions made by many 4 | individuals. For exact contribution history, see the revision history 5 | available at https://github.com/jquery/jquery 6 | 7 | The following license applies to all parts of this software except as 8 | documented below: 9 | 10 | ==== 11 | 12 | Permission is hereby granted, free of charge, to any person obtaining 13 | a copy of this software and associated documentation files (the 14 | "Software"), to deal in the Software without restriction, including 15 | without limitation the rights to use, copy, modify, merge, publish, 16 | distribute, sublicense, and/or sell copies of the Software, and to 17 | permit persons to whom the Software is furnished to do so, subject to 18 | the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be 21 | included in all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 27 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 28 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 29 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 30 | 31 | ==== 32 | 33 | All files located in the node_modules and external directories are 34 | externally maintained libraries used by this software which have their 35 | own licenses; we recommend you read them, as their terms may differ from 36 | the terms above. 37 | -------------------------------------------------------------------------------- /src/rebuildAllDockerImages.ps1: -------------------------------------------------------------------------------- 1 | docker build -t bookingapi -f BookingDockerfile . 2 | docker build -t paymentapi -f PaymentDockerfile . 3 | docker build -t trackingapi -f TrackingDockerfile . 4 | docker build -t mcweb -f McWebDockerfile . 5 | 6 | Write-Host -NoNewLine 'Press any key to continue...'; 7 | $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown'); --------------------------------------------------------------------------------