diff --git a/src/cartservice/Program.cs b/src/cartservice/Program.cs index ead7546..b0a4d1e 100644 --- a/src/cartservice/Program.cs +++ b/src/cartservice/Program.cs @@ -3,6 +3,7 @@ using System.IO; using System.Threading; using System.Threading.Tasks; using cartservice.cartstore; +using cartservice.interfaces; using CommandLine; using Grpc.Core; using Microsoft.Extensions.Configuration; @@ -28,22 +29,23 @@ namespace cartservice public string Redis { get; set; } } - static object StartServer(string host, int port, string redisAddress) + static object StartServer(string host, int port, ICartStore cartStore) { // Run the server in a separate thread and make the main thread busy waiting. // The busy wait is because when we run in a container, we can't use techniques such as waiting on user input (Console.Readline()) - Task.Run(() => + Task.Run(async () => { - //var store = new LocalCartStore(); - var store = new RedisCartStore(redisAddress); + Console.WriteLine($"Trying to start a grpc server at {host}:{port}"); Server server = new Server { - Services = { Hipstershop.CartService.BindService(new CartServiceImpl(store)) }, + Services = { Hipstershop.CartService.BindService(new CartServiceImpl(cartStore)) }, Ports = { new ServerPort(host, port, ServerCredentials.Insecure) } }; Console.WriteLine($"Cart server is listening at {host}:{port}"); server.Start(); + + await cartStore.InitializeAsync(); }); // Busy wait to keep the process alive @@ -75,8 +77,8 @@ namespace cartservice hostname = Environment.GetEnvironmentVariable(CART_SERVICE_ADDRESS); if (string.IsNullOrEmpty(hostname)) { - Console.WriteLine($"Environment variable {CART_SERVICE_ADDRESS} was not set. Setting the host to 127.0.0.1"); - hostname = "127.0.0.1"; + Console.WriteLine($"Environment variable {CART_SERVICE_ADDRESS} was not set. Setting the host to 0.0.0.0"); + hostname = "0.0.0.0"; } } @@ -98,19 +100,23 @@ namespace cartservice } // Set redis cache host (hostname+port) - string redis = options.Redis; - if (string.IsNullOrEmpty(redis)) + ICartStore cartStore; + string redis = ReadRedisAddress(options.Redis); + + // Redis was specified via command line or environment variable + if (!string.IsNullOrEmpty(redis)) { - Console.WriteLine($"Reading redis cache address from environment variable {REDIS_ADDRESS}"); - redis = Environment.GetEnvironmentVariable(REDIS_ADDRESS); - if (string.IsNullOrEmpty(redis)) - { - Console.WriteLine("Redis cache host(hostname+port) was not specified. It should be specified via command line or REDIS_ADDRESS environment variable."); - return -1; - } + cartStore = new RedisCartStore(redis); + return StartServer(hostname, port, cartStore); + } + else + { + Console.WriteLine("Redis cache host(hostname+port) was not specified. Starting a cart service using local store"); + Console.WriteLine("If you wanted to use Redis Cache as a backup store, you should provide its address via command line or REDIS_ADDRESS environment variable."); + cartStore = new LocalCartStore(); } - return StartServer(hostname, port, redis); + return StartServer(hostname, port, cartStore); }, errs => 1); break; @@ -119,5 +125,22 @@ namespace cartservice break; } } + + private static string ReadRedisAddress(string address) + { + if (!string.IsNullOrEmpty(address)) + { + return address; + } + + Console.WriteLine($"Reading redis cache address from environment variable {REDIS_ADDRESS}"); + string redis = Environment.GetEnvironmentVariable(REDIS_ADDRESS); + if (!string.IsNullOrEmpty(redis)) + { + return redis; + } + + return null; + } } } diff --git a/src/cartservice/cartstore/LocalCartStore.cs b/src/cartservice/cartstore/LocalCartStore.cs index 3a63de8..7ff5f61 100644 --- a/src/cartservice/cartstore/LocalCartStore.cs +++ b/src/cartservice/cartstore/LocalCartStore.cs @@ -11,6 +11,13 @@ namespace cartservice.cartstore // Maps between user and their cart private ConcurrentDictionary userCartItems = new ConcurrentDictionary(); + public Task InitializeAsync() + { + Console.WriteLine("Local Cart Store was initialized"); + + return Task.CompletedTask; + } + public Task AddItemAsync(string userId, string productId, int quantity) { Console.WriteLine($"AddItemAsync called with userId={userId}, productId={productId}, quantity={quantity}"); diff --git a/src/cartservice/cartstore/RedisCartStore.cs b/src/cartservice/cartstore/RedisCartStore.cs index 87adb2c..50f1f6f 100644 --- a/src/cartservice/cartstore/RedisCartStore.cs +++ b/src/cartservice/cartstore/RedisCartStore.cs @@ -13,9 +13,10 @@ namespace cartservice.cartstore { private const string CART_FIELD_NAME = "cart"; - private readonly ConnectionMultiplexer redis; + private static ConnectionMultiplexer redis; private readonly byte[] emptyCartBytes; + private readonly string connectionString; public RedisCartStore(string redisAddress) { @@ -23,9 +24,15 @@ namespace cartservice.cartstore var cart = new Hipstershop.Cart(); emptyCartBytes = cart.ToByteArray(); - string connectionString = $"{redisAddress},ssl=false,allowAdmin=true"; + connectionString = $"{redisAddress},ssl=false,allowAdmin=true"; + Console.WriteLine($"Going to use Redis cache at this address: {connectionString}"); + } + + public async Task InitializeAsync() + { Console.WriteLine("Connecting to Redis: " + connectionString); - redis = ConnectionMultiplexer.Connect(connectionString); + redis = await ConnectionMultiplexer.ConnectAsync(connectionString, Console.Out); + Console.WriteLine("Connected successfully to Redis"); } public async Task AddItemAsync(string userId, string productId, int quantity) diff --git a/src/cartservice/interfaces/ICartStore.cs b/src/cartservice/interfaces/ICartStore.cs index f4fa1e5..ae9702a 100644 --- a/src/cartservice/interfaces/ICartStore.cs +++ b/src/cartservice/interfaces/ICartStore.cs @@ -4,6 +4,8 @@ namespace cartservice.interfaces { internal interface ICartStore { + Task InitializeAsync(); + Task AddItemAsync(string userId, string productId, int quantity); Task EmptyCartAsync(string userId); diff --git a/src/cartservice/scripts/docker_setup.bat b/src/cartservice/scripts/docker_setup.bat index b841758..f5856a9 100644 --- a/src/cartservice/scripts/docker_setup.bat +++ b/src/cartservice/scripts/docker_setup.bat @@ -9,7 +9,7 @@ GOTO End1 :local set REDIS_PORT=6379 set REDIS_ADDR=localhost:%REDIS_PORT% - set LISTEN_ADDR=127.0.0.1 + set LISTEN_ADDR=0.0.0.0 set PORT=7070 echo running redis emulator locally on a separate window @@ -23,12 +23,12 @@ GOTO End1 :docker_local set REDIS_PORT=6379 - set REDIS_ADDR=redis:%REDIS_PORT% - set LISTEN_ADDR=127.0.0.1 + set REDIS_ADDR=0.0.0.0:%REDIS_PORT% + set LISTEN_ADDR=0.0.0.0 set PORT=7070 echo run docker container with redis - docker run -d --name=redis -p %REDIS_PORT%:%REDIS_PORT% redis + start docker run -d --name=redis -p %REDIS_PORT%:%REDIS_PORT% redis echo building container image for cart service docker build -t cartservice ..\.