diff --git a/src/cartservice/CartServiceImpl.cs b/src/cartservice/CartServiceImpl.cs index e1cbb49..c6c4887 100644 --- a/src/cartservice/CartServiceImpl.cs +++ b/src/cartservice/CartServiceImpl.cs @@ -2,6 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using cartservice.interfaces; using Grpc.Core; using Hipstershop; using static Hipstershop.CartService; @@ -11,65 +12,29 @@ namespace cartservice // Cart wrapper to deal with grpc communication internal class CartServiceImpl : CartServiceBase { - private CartStore cartStore; + private ICartStore cartStore; + private readonly static Empty Empty = new Empty(); - public CartServiceImpl(CartStore cartStore) + public CartServiceImpl(ICartStore cartStore) { this.cartStore = cartStore; } - public override Task AddItem(AddItemRequest request, Grpc.Core.ServerCallContext context) + public async override Task AddItem(AddItemRequest request, Grpc.Core.ServerCallContext context) { - cartStore.AddItem(request.UserId, request.Item.ProductId, request.Item.Quantity); - return Task.FromResult(new Empty()); + await cartStore.AddItemAsync(request.UserId, request.Item.ProductId, request.Item.Quantity); + return Empty; } - public override Task EmptyCart(EmptyCartRequest request, ServerCallContext context) + public async override Task EmptyCart(EmptyCartRequest request, ServerCallContext context) { - cartStore.EmptyCart(request.UserId); - return Task.FromResult(new Empty()); + await cartStore.EmptyCartAsync(request.UserId); + return Empty; } - public override Task GetCart(GetCartRequest request, ServerCallContext context) + public async override Task GetCart(GetCartRequest request, ServerCallContext context) { - var cart = cartStore.GetCart(request.UserId); - return Task.FromResult(cart.ToHipsterCart()); - } - } - - internal class CartStore - { - // Maps between user and their cart - private ConcurrentDictionary userCartItems = new ConcurrentDictionary(); - - public void AddItem(string userId, string productId, int quantity) - { - Cart cart; - if (!userCartItems.TryGetValue(userId, out cart)) - { - cart = new Cart(userId); - } - else - { - cart = userCartItems[userId]; - } - cart.AddItem(productId, quantity); - } - - public void EmptyCart(string userId) - { - Cart cart; - if (userCartItems.TryGetValue(userId, out cart)) - { - cart.EmptyCart(); - } - } - - public Cart GetCart(string userId) - { - Cart cart = null; - userCartItems.TryGetValue(userId, out cart); - return cart; + return await cartStore.GetCartAsync(request.UserId); } } diff --git a/src/cartservice/Program.cs b/src/cartservice/Program.cs index 8d4e396..1902144 100644 --- a/src/cartservice/Program.cs +++ b/src/cartservice/Program.cs @@ -1,29 +1,41 @@ using System; +using System.IO; +using cartservice.cartstore; using CommandLine; using Grpc.Core; +using Microsoft.Extensions.Configuration; namespace cartservice { class Program { + const string CART_SERVICE_ADDRESS = "CART_SERVICE_ADDR"; + const string REDIS_ADDRESS = "REDIS_ADDR"; + [Verb("start", HelpText = "Starts the server listening on provided port")] class ServerOptions { + [Option('h', "hostname", HelpText = "The ip on which the server is running. If not provided, CART_SERVICE_ADDR environment variable value will be used. If not defined, localhost is used")] + public string Host { get; set; } [Option('p', "port", HelpText = "The port on for running the server", Required = true)] public int Port { get; set; } + + [Option('r', "redis", HelpText = "The ip of redis cache")] + public string Redis { get; set; } + } - static object StartServer(string host, int port) + static object StartServer(string host, int port, string redisAddress) { - var store = new CartStore(); + var store = new RedisCartStore(redisAddress); Server server = new Server { Services = { Hipstershop.CartService.BindService(new CartServiceImpl(store)) }, Ports = { new ServerPort(host, port, ServerCredentials.Insecure) } }; - Console.WriteLine("Cart server is listening on port " + port); + Console.WriteLine($"Cart server is listening at {host}:{port}"); Console.WriteLine("Press any key to stop the server..."); server.Start(); @@ -33,6 +45,7 @@ namespace cartservice return null; } + static void Main(string[] args) { if (args.Length == 0) @@ -45,15 +58,34 @@ namespace cartservice { case "start": Parser.Default.ParseArguments(args).MapResult( - (ServerOptions options) => StartServer("localhost", options.Port), + (ServerOptions options) => + { + string host = options.Host; + if (string.IsNullOrEmpty(host)) + { + Console.WriteLine($"Reading host address from {CART_SERVICE_ADDRESS} environment variable..."); + host = Environment.GetEnvironmentVariable(CART_SERVICE_ADDRESS); + if (string.IsNullOrEmpty(host)) + { + Console.WriteLine("Setting the host to 127.0.0.1"); + host = "127.0.0.1"; + } + } + + string redis = options.Redis; + if (string.IsNullOrEmpty(redis)) + { + Console.WriteLine("Reading redis cache address from environment variable"); + redis = Environment.GetEnvironmentVariable(REDIS_ADDRESS); + } + return StartServer(host, options.Port, redis); + }, errs => 1); break; default: Console.WriteLine("Invalid command"); break; } - - Console.WriteLine("Hello World!"); } } } diff --git a/src/cartservice/cartservice.csproj b/src/cartservice/cartservice.csproj index fddba5c..6298870 100644 --- a/src/cartservice/cartservice.csproj +++ b/src/cartservice/cartservice.csproj @@ -11,6 +11,9 @@ + + +