/// <summary>
 /// Initializes a new instance of the PSMetric class.
 /// </summary>
 /// <param name="metric">The input Metric object</param>
 public PSMetric(Metric metric)
     : base(metric)
 {
     this.DimensionName = metric.DimensionName == null ? null : metric.DimensionName.Value;
     this.DimensionValue = metric.DimensionValue == null ? null : metric.DimensionValue.Value;
     this.EndTime = metric.EndTime;
     this.MetricValues = new PSMetricValuesCollection(metric.MetricValues);
     this.Name = metric.Name == null ? null : metric.Name.Value;
     this.Properties = new PSDictionaryElement(metric.Properties);
     this.ResourceId = metric.ResourceId;
     this.StartTime = metric.StartTime;
     this.TimeGrain = metric.TimeGrain;
     this.Unit = metric.Unit;
 }
        /// <summary>
        /// Initializes a new instance of the PSMetric class.
        /// </summary>
        /// <param name="metric">The input Metric object</param>
        public PSMetricNoDetails(Metric metric)
        {
            // Keep the original value (localized string, Dictionary, List) in the base
            base.DimensionName = metric.DimensionName;
            base.DimensionValue = metric.DimensionValue;
            base.Name = metric.Name;

            this.DimensionName = metric.DimensionName == null ? null : metric.DimensionName.Value;
            this.DimensionValue = metric.DimensionValue == null ? null : metric.DimensionValue.Value;
            this.EndTime = metric.EndTime;
            this.MetricValues = metric.MetricValues;
            this.Name = metric.Name == null ? null : metric.Name.Value;
            this.Properties = metric.Properties;
            this.ResourceId = metric.ResourceId;
            this.StartTime = metric.StartTime;
            this.TimeGrain = metric.TimeGrain;
            this.Unit = metric.Unit;
        }
        public IEnumerable <IM.Metric> ToInsightsMetric()
        {
            List <IM.Metric> result = new List <IM.Metric>();

            foreach (Metric docdbMetric in Value)
            {
                IM.Metric insightsMetric = new IM.Metric();
                insightsMetric.Name = new IM.LocalizableString()
                {
                    LocalizedValue = docdbMetric.Name.LocalizedValue, Value = docdbMetric.Name.Value
                };
                insightsMetric.Unit = (IM.Unit)((int)docdbMetric.Unit);
                insightsMetric.Data = new List <IM.MetricValue>();
                if (docdbMetric.MetricValues != null)
                {
                    foreach (MetricValue mV in docdbMetric.MetricValues)
                    {
                        insightsMetric.Data.Add(JsonConvert.DeserializeObject <IM.MetricValue>(JsonConvert.SerializeObject(mV)));
                    }
                }
                result.Add(insightsMetric);
            }
            return(result);
        }
        public async Task<MetricListResponse> GetMetricsAsync(string resourceId, string filterString, IEnumerable<MetricDefinition> definitions, string invocationId)
        {
            MetricFilter filter = MetricFilterExpressionParser.Parse(filterString);

            var ongoingTasksPerBlob = new Dictionary<string, Task<Dictionary<string, List<MetricValueBlob>>>>();
            var metricsPerBlob = new Dictionary<string, Dictionary<string, List<MetricValueBlob>>>(StringComparer.OrdinalIgnoreCase);
            
            // We download all the relevant blobs first and then use the data later, to avoid download the same blob more than once.
            foreach (MetricDefinition metricDefinition in definitions)
            {
                if (!IsMetricDefinitionIncluded(filter, metricDefinition))
                {
                    continue;
                }

                foreach (MetricAvailability availability in metricDefinition.MetricAvailabilities)
                {
                    if (filter != null && filter.TimeGrain != default(TimeSpan) && filter.TimeGrain != availability.TimeGrain)
                    {
                        continue;
                    }

                    if (availability.BlobLocation == null)
                    {
                        continue;
                    }

                    foreach (BlobInfo blobInfo in availability.BlobLocation.BlobInfo)
                    {
                        string blobId = GetBlobEndpoint(blobInfo);
                        if (!metricsPerBlob.ContainsKey(blobId) && !ongoingTasksPerBlob.ContainsKey(blobId))
                        {
                            ongoingTasksPerBlob.Add(blobId, FetchMetricValuesFromBlob(blobInfo, filter));
                        }

                        if (ongoingTasksPerBlob.Count == Util.NumberOfParallelCallsForMetricBlobs)
                        {
                            foreach (var blobMetricPair in ongoingTasksPerBlob)
                            {
                                metricsPerBlob[blobMetricPair.Key] = await blobMetricPair.Value;
                            }

                            ongoingTasksPerBlob.Clear();
                        }
                    }
                }
            }

            foreach (var blobMetricPair in ongoingTasksPerBlob)
            {
                metricsPerBlob[blobMetricPair.Key] = await blobMetricPair.Value;
            }

            var result = new MetricListResponse
            {
                MetricCollection = new MetricCollection
                {
                    Value = new List<Metric>()
                }
            };

            // Populate the metrics result using the data from the blobs.
            foreach (MetricDefinition metricDefinition in definitions)
            {
                if (!IsMetricDefinitionIncluded(filter, metricDefinition))
                {
                    continue;
                }

                foreach (MetricAvailability availability in metricDefinition.MetricAvailabilities)
                {
                    if (filter != null && filter.TimeGrain != default(TimeSpan) && filter.TimeGrain != availability.TimeGrain)
                    {
                        continue;
                    }

                    if (availability.BlobLocation == null)
                    {
                        continue;
                    }

                    var metricValues = new List<MetricValueBlob>();
                    foreach (BlobInfo blobInfo in availability.BlobLocation.BlobInfo)
                    {
                        string blobId = GetBlobEndpoint(blobInfo);

                        List<MetricValueBlob> metricsInBlob;
                        if (metricsPerBlob[blobId].TryGetValue(metricDefinition.Name.Value, out metricsInBlob))
                        {
                            metricsInBlob.Sort(CompareMetrics);
                            metricValues.AddRange(metricsInBlob);
                        }
                    }

                    var metric = new Metric
                    {
                        Name = new LocalizableString
                        {
                            Value = metricDefinition.Name.Value,
                            LocalizedValue = metricDefinition.Name.LocalizedValue,
                        },
                        StartTime = filter.StartTime,
                        EndTime = filter.EndTime,
                        MetricValues = GetAggregatedByTimestamp(metricValues),
                        TimeGrain = availability.TimeGrain,
                    };

                    result.MetricCollection.Value.Add(metric);
                }
            }

            return result;
        }
        private void AreEqual(Metric exp, Metric act)
        {
            if (exp != null)
            {
                AreEqual(exp.Name, act.Name);
                Assert.Equal(exp.EndTime.ToUniversalTime(), act.EndTime.ToUniversalTime());
                Assert.Equal(exp.ResourceId, act.ResourceId);
                Assert.Equal(exp.StartTime.ToUniversalTime(), act.StartTime.ToUniversalTime());
                Assert.Equal(exp.TimeGrain, act.TimeGrain);
                Assert.Equal(exp.Unit, act.Unit);
                AreEqual(exp.Properties, act.Properties);

                if (exp.MetricValues != null)
                {
                    for (int i = 0; i < exp.MetricValues.Count; i++)
                    {
                        AreEqual(exp.MetricValues[i], act.MetricValues[i]);
                    }
                }
            }
        }