private async Task <CustomerRewardsProfile> GetCacheDataAsync(Guid customerId)
        {
            CustomerRewardsProfile result = null;

            try
            {
                logger.LogInformation($"Retrieving data for {LoyaltyConstants.CUSTOMER_ID}:{customerId} from cache data source.");
                result = await cacheDataSource.GetRewardsInfoAsync(customerId).TimeoutAfter(this.cacheDataTimeout);

                logger.LogInformation($"Received data from cache data source for {LoyaltyConstants.CUSTOMER_ID}:{customerId}.");
            }
            catch (Exception e)
            {
                logger.LogError(e, "Exception encountered while trying to get data from cache.");
            }

            // If we have a cache miss. Fetch data from live source and backfill cache.
            // TODO: ADD A CONFIG FLAG HERE SO WE CAN CONTROLL THE FALLBACK BEHAVIOR, SO THAT THE FALLBACK MECHANISM WILL NOT BRING DOWN OUR VENDOR'S DB.
            //       Without fallback, return will be null with cache miss.
            if (result == null)
            {
                logger.LogWarning($"Unable to retrieve data for {LoyaltyConstants.CUSTOMER_ID}:{customerId} from cache. Attempt to retrieve data from live data source and backfill cache.");
                try
                {
                    logger.LogInformation($"Retrieving data for {LoyaltyConstants.CUSTOMER_ID}:{customerId} from live data source.");
                    result = await liveDataSource.GetRewardsInfoAsync(customerId).TimeoutAfter(this.liveDataTimeout);

                    logger.LogInformation($"Received data from live data source for {LoyaltyConstants.CUSTOMER_ID}:{customerId}. Backfilling cache..");

                    var cacheUpdateResult = await cacheUpdater.UpdateRewardsInfoAsync(result).ConfigureAwait(false);

                    logger.LogInformation($"Cache data for {LoyaltyConstants.CUSTOMER_ID}:{customerId} is backfilled:{cacheUpdateResult}");

                    return(result);
                }
                catch (TimeoutException te)
                {
                    var errorMsg = $"Unable to retrieve data from live data source to backfill cache for {LoyaltyConstants.CUSTOMER_ID}:{customerId}. Timed out after {this.liveDataTimeout.TotalMilliseconds}ms.";
                    logger.LogError(te, errorMsg);

                    //TODO: POSSIBILY CREATE A CUSTOM EXCEPTION FOR BETTER TRACKING/HANDLING
                    throw new TimeoutException(errorMsg, te);
                }
                catch (Exception e)
                {
                    logger.LogError(e, "Exception encountered while trying to get data from live data source as a fallback mechanism.");
                    throw;
                }
            }

            return(result);
        }
        /// <summary>
        /// Mapper function to transform vendor's model to our model
        /// </summary>
        /// <param name="vendorData"></param>
        /// <returns></returns>
        /// <remarks>In real code, mapper libraries will be used.</remarks>
        private CustomerRewardsProfile TransformData(VendorXRewardsData vendorData)
        {
            var mappedData = new CustomerRewardsProfile()
            {
                LevelInformation = new RewardsLevel()
                {
                    Level                = vendorData.Level,
                    PointsEarnedYTD      = vendorData.PointsEarnedYTD,
                    PointsEarnedLifetime = vendorData.PointsEarnedLifetime
                },
                NotesInformation = vendorData.Notes
            };

            return(mappedData);
        }
 public Task <bool> UpdateRewardsInfoAsync(CustomerRewardsProfile customerId)
 {
     //TODO: IMPLEMENT THE REAL CACHE UPDATE LOGIC
     return(Task.FromResult(true));
 }