private async Task <List <AggregatedEvent> > GetAllArtistWorkAggregatedEvents(AggregateTimeRange timeRange)
        {
            List <AggregatedEvent> result;
            string localStorageKey = LOCALSTORAGEKEY_ALLARTISTWORKAGGREGATEDEVENTS + timeRange;
            TimeCachedObject <List <AggregatedEvent> > cachedObject = await _localStorageService.GetItemAsync <TimeCachedObject <List <AggregatedEvent> > >(localStorageKey);

            if (cachedObject == null || cachedObject.NextUpdateHour < DateTimeOffset.UtcNow)
            {
                ArtistWorkAggregatedEventsRequest request = new ArtistWorkAggregatedEventsRequest()
                {
                    ArtistWorkIds = new List <int>(), TimeSeries = timeRange
                };
                HttpResponseMessage responseMessage = await _httpClient.PostAsJsonAsync(_endpointAddress + "ArtistWorkAggregatedEvents", request);

                string responseBody = await responseMessage.Content.ReadAsStringAsync();

                result = JsonConvert.DeserializeObject <List <AggregatedEvent> >(responseBody);
                DateTimeOffset nextUpdate = TimeCachedObject <object> .CalculateNextUpdateHour();

                cachedObject = new TimeCachedObject <List <AggregatedEvent> >()
                {
                    CachedObject   = result,
                    NextUpdateHour = nextUpdate
                };
                await _localStorageService.SetItemAsync(localStorageKey, cachedObject);
            }
            else
            {
                result = cachedObject.CachedObject;
            }
            return(result);
        }
        public async Task <List <ItemCount> > GetSongPlayedOverTime(AggregateTimeRange timeRange, int artistWorkId)
        {
            string           localStorageKey = LOCALSTORAGEKEY_ARTISTWORKPLAYEDOVERTIME + artistWorkId + "-" + timeRange;
            List <ItemCount> result;
            TimeCachedObject <List <ItemCount> > cachedObject = await _localStorageService.GetItemAsync <TimeCachedObject <List <ItemCount> > >(localStorageKey);


            if (cachedObject == null || cachedObject.NextUpdateHour < DateTimeOffset.UtcNow)
            {
                ArtistWorkAggregatedEventsRequest request = new ArtistWorkAggregatedEventsRequest()
                {
                    ArtistWorkIds = new List <int>()
                    {
                        artistWorkId
                    }, TimeSeries = timeRange
                };
                HttpResponseMessage responseMessage = await _httpClient.PostAsJsonAsync(_endpointAddress + "ArtistWorkAggregatedEvents", request);

                string responseBody = await responseMessage.Content.ReadAsStringAsync();

                AggregatedEvent  temp  = JsonConvert.DeserializeObject <List <AggregatedEvent> >(responseBody)?.FirstOrDefault();
                List <ItemCount> items = temp.AggregatedEventSumSource.Select((x, i) => new ItemCount()
                {
                    Count = x.Value, ItemId = artistWorkId, Name = x.Timestamp.ToString()
                }).ToList();
                Dictionary <string, (ItemCount itemCount, DateTimeOffset sortOrder)> buckets = GetItemCountBuckets(timeRange, artistWorkId);
                foreach (var item in items)
                {
                    if (buckets.ContainsKey(item.Name))
                    {
                        buckets[item.Name].itemCount.Count = item.Count;
                    }
                }
                result = buckets.Values.OrderBy(x => x.sortOrder).Select(x => x.itemCount).ToList();
                DateTimeOffset nextUpdate = TimeCachedObject <object> .CalculateNextUpdateHour();

                cachedObject = new TimeCachedObject <List <ItemCount> >()
                {
                    CachedObject   = result,
                    NextUpdateHour = nextUpdate
                };
                await _localStorageService.SetItemAsync(localStorageKey, cachedObject);
            }
            else
            {
                result = cachedObject.CachedObject;
            }
            return(result);
        }