forked from dotnet/aspire
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBasketService.cs
147 lines (122 loc) · 5.13 KB
/
BasketService.cs
1
2
3
4
5
6
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
using System.Text.Json;
using BasketService.Models;
using BasketService.Repositories;
using Grpc.Core;
using GrpcBasket;
using RabbitMQ.Client;
namespace BasketService;
public class BasketService(IBasketRepository repository, IConfiguration configuration, IServiceProvider serviceProvider, ILogger<BasketService> logger) : Basket.BasketBase
{
private readonly IBasketRepository _repository = repository;
private readonly IConfiguration _configuration = configuration;
private readonly ILogger<BasketService> _logger = logger;
private IConnection? _messageConnection;
public override async Task<CustomerBasketResponse> GetBasketById(BasketRequest request, ServerCallContext context)
{
// Uncomment to force a delay for testing resiliency, etc.
//await Task.Delay(5000);
var data = await _repository.GetBasketAsync(request.Id);
if (data != null)
{
return MapToCustomerBasketResponse(data);
}
return new CustomerBasketResponse();
}
public override async Task<CustomerBasketResponse?> UpdateBasket(CustomerBasketRequest request, ServerCallContext context)
{
var customerBasket = MapToCustomerBasket(request);
var response = await _repository.UpdateBasketAsync(customerBasket);
if (response is null)
{
throw new RpcException(new Status(StatusCode.NotFound, $"Basket with buyer id {request.BuyerId} does not exist"));
}
return MapToCustomerBasketResponse(response);
}
public override async Task<CheckoutCustomerBasketResponse> CheckoutBasket(CheckoutCustomerBasketRequest request, ServerCallContext context)
{
var buyerId = request.BuyerId;
var basket = await _repository.GetBasketAsync(buyerId);
if (basket is null)
{
throw new RpcException(new Status(StatusCode.NotFound, $"Basket with buyer id {request.BuyerId} does not exist"));
}
var order = new Order()
{
Id = Guid.NewGuid().ToString(),
BuyerId = buyerId,
Items = basket.Items,
};
_logger.LogInformation("Checking out {Count} item(s) for BuyerId: {BuyerId}.", order.Items.Count, buyerId);
_messageConnection ??= serviceProvider.GetService<IConnection>();
if (_messageConnection is null)
{
_logger.LogWarning("RabbitMQ is unavailable. Ensure you have configured it in AppHosts's config / user secrets under 'ConnectionStrings:messaging'.");
}
else
{
const string configKeyName = "Aspire:RabbitMQ:Client:OrderQueueName";
string? queueName = _configuration[configKeyName];
if (string.IsNullOrEmpty(queueName))
{
context.Status = new Status(StatusCode.Internal, $"Queue name not found. Please add a valid name for configuration key '{configKeyName}'.");
return new();
}
using var channel = await _messageConnection.CreateChannelAsync();
await channel.QueueDeclareAsync(queueName, durable: true, exclusive: false);
var props = new BasicProperties();
props.Persistent = true; // or props.DeliveryMode = 2;
await channel.BasicPublishAsync(
exchange: string.Empty,
routingKey: queueName,
mandatory: true,
basicProperties: props,
body: JsonSerializer.SerializeToUtf8Bytes(order));
}
await _repository.DeleteBasketAsync(buyerId);
_logger.LogInformation("Order Id {Id} submitted.", order.Id);
return new CheckoutCustomerBasketResponse();
}
public override async Task<DeleteCustomerBasketResponse> DeleteBasket(DeleteCustomerBasketRequest request, ServerCallContext context)
{
await _repository.DeleteBasketAsync(request.BuyerId);
return new DeleteCustomerBasketResponse();
}
private static CustomerBasketResponse MapToCustomerBasketResponse(CustomerBasket customerBasket)
{
var response = new CustomerBasketResponse
{
BuyerId = customerBasket.BuyerId
};
foreach (var item in customerBasket.Items)
{
response.Items.Add(new BasketItemResponse
{
Id = item.Id ?? Guid.NewGuid().ToString(),
OldUnitPrice = item.OldUnitPrice,
ProductId = item.ProductId,
Quantity = item.Quantity,
UnitPrice = item.UnitPrice
});
}
return response;
}
private static CustomerBasket MapToCustomerBasket(CustomerBasketRequest customerBasketRequest)
{
var response = new CustomerBasket
{
BuyerId = customerBasketRequest.BuyerId
};
foreach (var item in customerBasketRequest.Items)
{
response.Items.Add(new BasketItem
{
Id = item.Id,
OldUnitPrice = item.OldUnitPrice,
ProductId = item.ProductId,
Quantity = item.Quantity,
UnitPrice = item.UnitPrice
});
}
return response;
}
}