Skip to content

Commit

Permalink
Merge pull request #101 from mauroservienti/infrastructure-failure-sc…
Browse files Browse the repository at this point in the history
…enario

Infrastructure failure scenario
  • Loading branch information
mauroservienti authored Oct 29, 2019
2 parents c0f1b37 + fd13b06 commit 8b8b3ca
Show file tree
Hide file tree
Showing 26 changed files with 256 additions and 332 deletions.
11 changes: 9 additions & 2 deletions src/All our Aggregates are Wrong - Demos.sln
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27004.2009
# Visual Studio Version 16
VisualStudioVersion = 16.0.29326.143
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ITOps", "ITOps", "{98143115-D3C4-41A3-8715-BA4604CBBCF5}"
EndProject
Expand Down Expand Up @@ -72,6 +72,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "JsonUtils", "JsonUtils\Json
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NServiceBus.Shared.Hosting", "NServiceBus.Shared.Hosting\NServiceBus.Shared.Hosting.csproj", "{7C57A932-D422-432D-AD92-C427F6F6F330}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sales.ViewModelComposition.Messages", "Sales.ViewModelComposition.Messages\Sales.ViewModelComposition.Messages.csproj", "{ECD9299D-E306-4089-8481-501CD1E23AD5}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -194,6 +196,10 @@ Global
{7C57A932-D422-432D-AD92-C427F6F6F330}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C57A932-D422-432D-AD92-C427F6F6F330}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C57A932-D422-432D-AD92-C427F6F6F330}.Release|Any CPU.Build.0 = Release|Any CPU
{ECD9299D-E306-4089-8481-501CD1E23AD5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ECD9299D-E306-4089-8481-501CD1E23AD5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ECD9299D-E306-4089-8481-501CD1E23AD5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ECD9299D-E306-4089-8481-501CD1E23AD5}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -226,6 +232,7 @@ Global
{72FBC1E1-0391-4930-87DA-1826F5656065} = {A795372A-2BB5-4F97-81EF-744DE5A60A05}
{EA9D77E5-9EC7-49BC-BC02-C629DFF5E8F7} = {A795372A-2BB5-4F97-81EF-744DE5A60A05}
{7C57A932-D422-432D-AD92-C427F6F6F330} = {A795372A-2BB5-4F97-81EF-744DE5A60A05}
{ECD9299D-E306-4089-8481-501CD1E23AD5} = {115B91B0-8DD8-4CD0-9FE0-6906278F72FA}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {F1E91020-9272-4261-9A94-79C9D1B91447}
Expand Down
73 changes: 0 additions & 73 deletions src/Sales.Api/Controllers/ShoppingCartController.cs
Original file line number Diff line number Diff line change
@@ -1,88 +1,15 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NServiceBus;
using Sales.Data;
using Sales.Data.Models;
using Sales.Messages.Events;
using System;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;

namespace Sales.Api.Controllers
{
[Route("api/shopping-cart")]
[ApiController]
public class ShoppingCartController : ControllerBase
{
IMessageSession messageSession;
public ShoppingCartController(IMessageSession messageSession)
{
this.messageSession = messageSession;
}

[HttpPost]
[Route("")]
public async Task<IActionResult> AddToCart(JsonElement data)
{
var cartId = data.GetProperty("CartId").GetGuid();
var productId = int.Parse(data.GetProperty("ProductId").GetString());
var quantity = data.GetProperty("Quantity").GetInt32();
var requestId = Request.Headers["request-id"].Single();

if (quantity <= 0)
{
return BadRequest();
}

using (var db = SalesContext.Create())
{
var requestAlreadyHandled = await db.ShoppingCarts
.Where(o => o.Items.Any(i => i.RequestId == requestId))
.AnyAsync();

if (!requestAlreadyHandled)
{
var cart = db.ShoppingCarts
.Include(c => c.Items)
.Where(o => o.Id == cartId)
.SingleOrDefault();

if (cart == null)
{
cart = db.ShoppingCarts.Add(new ShoppingCart()
{
Id = cartId
}).Entity;
}

var product = db.ProductsPrices
.Where(o => o.Id == productId)
.Single();

cart.Items.Add(new ShoppingCartItem()
{
CartId = cartId,
RequestId = requestId,
ProductId = productId,
CurrentPrice = product.Price,
LastPrice = product.Price,
Quantity = quantity
});

await messageSession.Publish<ProductAddedToCart>(e =>
{
e.CartId = cartId;
e.ProductId = productId;
});

await db.SaveChangesAsync();
}
}

return StatusCode(200);
}

[HttpGet]
[Route("{id}")]
public dynamic GetCart(Guid id)
Expand Down
10 changes: 0 additions & 10 deletions src/Sales.Messages/CleanupFailedCartRequest.cs

This file was deleted.

12 changes: 12 additions & 0 deletions src/Sales.Messages/Commands/AddItemToCart.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace Sales.Messages.Commands
{
public class AddItemToCart
{
public int ProductId { get; set; }
public int Quantity { get; set; }
public Guid CartId { get; set; }
public string RequestId { get; set; }
}
}
62 changes: 62 additions & 0 deletions src/Sales.Service/Handlers/AddItemToCartHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using Microsoft.EntityFrameworkCore;
using NServiceBus;
using Sales.Data;
using Sales.Data.Models;
using Sales.Messages.Commands;
using Sales.Messages.Events;
using System.Linq;
using System.Threading.Tasks;

namespace Sales.Service.Handlers
{
class AddItemToCartHandler : IHandleMessages<AddItemToCart>
{
public async Task Handle(AddItemToCart message, IMessageHandlerContext context)
{
using (var db = SalesContext.Create())
{
var requestAlreadyHandled = await db.ShoppingCarts
.Where(o => o.Items.Any(i => i.RequestId == message.RequestId))
.AnyAsync();

if (!requestAlreadyHandled)
{
var cart = db.ShoppingCarts
.Include(c => c.Items)
.Where(o => o.Id == message.CartId)
.SingleOrDefault();

if (cart == null)
{
cart = db.ShoppingCarts.Add(new ShoppingCart()
{
Id = message.CartId
}).Entity;
}

var product = db.ProductsPrices
.Where(o => o.Id == message.ProductId)
.Single();

cart.Items.Add(new ShoppingCartItem()
{
CartId = message.CartId,
RequestId = message.RequestId,
ProductId = message.ProductId,
CurrentPrice = product.Price,
LastPrice = product.Price,
Quantity = message.Quantity
});

await context.Publish<ProductAddedToCart>(e =>
{
e.CartId = message.CartId;
e.ProductId = message.ProductId;
});

await db.SaveChangesAsync();
}
}
}
}
}
34 changes: 0 additions & 34 deletions src/Sales.Service/Handlers/CleanupFailedCartRequestHandler.cs

This file was deleted.

11 changes: 11 additions & 0 deletions src/Sales.ViewModelComposition.Events/AddItemToCartRequested.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Collections.Generic;

namespace Sales.ViewModelComposition.Events
{
public class AddItemToCartRequested
{
public string RequestId { get; set; }
public string CartId { get; set; }
public Dictionary<string, string> RequestData { get; set; }
}
}
12 changes: 12 additions & 0 deletions src/Sales.ViewModelComposition.Messages/AddToCartRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;

namespace Sales.ViewModelComposition.Messages
{
public class AddToCartRequest
{
public Dictionary<string, string> RequestData { get; set; }
public string RequestId { get; set; }
public Guid CartId { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>

</Project>
21 changes: 21 additions & 0 deletions src/Sales.ViewModelComposition/Handlers/AddToCartRequestHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using NServiceBus;
using Sales.Messages.Commands;
using Sales.ViewModelComposition.Messages;
using System.Threading.Tasks;

namespace Sales.ViewModelComposition.Handlers
{
class AddToCartRequestHandler : IHandleMessages<AddToCartRequest>
{
public Task Handle(AddToCartRequest message, IMessageHandlerContext context)
{
return context.Send("Sales.Service", new AddItemToCart()
{
RequestId = message.RequestId,
CartId = message.CartId,
ProductId = int.Parse(message.RequestData["sales-product-id"]),
Quantity = int.Parse(message.RequestData["sales-quantity"]),
});
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<ProjectReference Include="..\Marketing.ViewModelComposition.Events\Marketing.ViewModelComposition.Events.csproj" />
<ProjectReference Include="..\Sales.Messages\Sales.Messages.csproj" />
<ProjectReference Include="..\Sales.ViewModelComposition.Events\Sales.ViewModelComposition.Events.csproj" />
<ProjectReference Include="..\Sales.ViewModelComposition.Messages\Sales.ViewModelComposition.Messages.csproj" />
</ItemGroup>

</Project>
47 changes: 15 additions & 32 deletions src/Sales.ViewModelComposition/ShoppingCartAddPostHandler.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Newtonsoft.Json;
using NServiceBus;
using Sales.Messages;
using Sales.ViewModelComposition.Events;
using Sales.ViewModelComposition.Messages;
using ServiceComposer.AspNetCore;
using System;
using System.Net.Http;
using System.Text;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Sales.ViewModelComposition
{
class ShoppingCartAddPostHandler : IHandleRequests, IHandleRequestsErrors
class ShoppingCartAddPostHandler : IHandleRequests
{
IMessageSession messageSession;

Expand All @@ -33,40 +32,24 @@ public bool Matches(RouteData routeData, string httpVerb, HttpRequest request)

public async Task Handle(string requestId, dynamic vm, RouteData routeData, HttpRequest request)
{
var postData = new
var requestData = new Dictionary<string, string>()
{
ProductId = (string)routeData.Values["id"],
Quantity = int.Parse(request.Form["quantity"][0]),
CartId = request.Cookies["cart-id"]
{ "sales-product-id", (string)routeData.Values["id"] },
{ "sales-quantity", request.Form["quantity"][0] },
};

var url = $"http://localhost:5001/api/shopping-cart";
var client = new HttpClient();

var requestMessage = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(
JsonConvert.SerializeObject(postData),
Encoding.UTF8,
"application/json")
};
requestMessage.Headers.Add("request-id", requestId);

var response = await client.SendAsync(requestMessage);

if (!response.IsSuccessStatusCode)
await vm.RaiseEvent(new AddItemToCartRequested()
{
throw new InvalidOperationException(response.ReasonPhrase);
}
}
CartId = request.Cookies["cart-id"],
RequestId = requestId,
RequestData = requestData
});

public Task OnRequestError(string requestId, Exception ex, dynamic vm, RouteData routeData, HttpRequest request)
{
return messageSession.Send("Sales.Service", new CleanupFailedCartRequest()
await messageSession.SendLocal(new AddToCartRequest()
{
RequestId = requestId,
CartId = new Guid(request.Cookies["cart-id"]),
RequestId = requestId
});
RequestData = requestData });
}
}
}
10 changes: 0 additions & 10 deletions src/Shipping.Messages/CleanupFailedCartRequest.cs

This file was deleted.

Loading

0 comments on commit 8b8b3ca

Please sign in to comment.