/// <summary>
 /// Initializes a new instance of the PSMetricValue class.
 /// </summary>
 /// <param name="metricValue">The input MetricValue object</param>
 public PSMetricValue(MetricValue metricValue)
 {
     this.Average = metricValue.Average;
     this.Count = metricValue.Count;
     this.Last = metricValue.Last;
     this.Maximum = metricValue.Maximum;
     this.Minimum = metricValue.Minimum;
     this.Properties = new PSDictionaryElement(metricValue.Properties);
     this.Timestamp = metricValue.Timestamp;
     this.Total = metricValue.Total;
 }
        private static MetricValue GetConvertedMetric(MetricValueBlob m)
        {
            // If count is not supplied, we assume 1, so the total / average relation works.
            var metricValue = new MetricValue
            {
                Count = m.count == 0 ? 1 : m.count,
                Maximum = m.maximum,
                Minimum = m.minimum,
                Timestamp = m.time,
            };

            // In case the RP doesn't populate average, we calculate average from total / count.
            if (m.average == 0 && m.total != 0)
            {
                metricValue.Average = m.total / metricValue.Count;
            }
            else
            {
                metricValue.Average = m.average;
            }

            // In case the RP doesn't populate total, we calculate total from the average * count.
            if (m.total == 0 && m.average != 0)
            {
                metricValue.Total = m.average * metricValue.Count;
            }
            else
            {
                metricValue.Total = m.total;
            }

            return metricValue;
        }
        private static void Aggregate(MetricValue lastSeen, MetricValueBlob m)
        {
            // If count is not supplied, we assume 1, so the total / average relation works.
            lastSeen.Count += m.count == 0 ? 1 : m.count;

            // In case the RP doesn't populate total, we calculate total from the average * count.
            if (m.total == 0 && m.average != 0)
            {
                lastSeen.Total += m.average * lastSeen.Count;
            }
            else
            {
                lastSeen.Total += m.total;
            }

            if (m.maximum > lastSeen.Maximum)
            {
                lastSeen.Maximum = m.maximum;
            }

            if (m.minimum < lastSeen.Minimum)
            {
                lastSeen.Minimum = m.minimum;
            }
        }
        public async Task<HttpResponseMessage> MetricThreshold(string triggerState,
                                        [Metadata("Resource Id", "Provide a resource Id that you want metrics from.")] string resource,
                                        [Metadata("Metric name", "Which metric you want to trigger on.")] string metricName,
                                        [Metadata("Threshold", "The threshold for the metric.")]  double threshold,
                                        [Metadata("Duration (minutes)", "Optional. The number of minutes of metric data you want. Default is 15 minutes.", VisibilityType.Advanced)]  double minutes = 15,
                                        [Metadata("Time aggregation", "Optional. How data is combined over the time window. Default is average.", VisibilityType.Advanced)] TimeAggregationType timeAggregation = TimeAggregationType.Average,
                                        [Metadata("Operator", "Optional. The operation to use when comparing the metrics with the threshold. Default is greater than.", VisibilityType.Advanced)] ComparisonOperationType operation = ComparisonOperationType.GreaterThan
            )
        {
            var data = await GetMetricData(resource, metricName, DateTime.UtcNow.AddMinutes(-1 * minutes), DateTime.UtcNow).ConfigureAwait(continueOnCapturedContext: false);

            var outValue = new Microsoft.Azure.Insights.Models.MetricValue()
            {
                Average = data.Select(x => x.Average).Average(),
                Maximum = data.Select(x => x.Maximum).Max(),
                Minimum = data.Select(x => x.Minimum).Min(),
                Count = data.Select(x => x.Count).Sum(),
                Total = data.Select(x => x.Total).Sum(),
                Timestamp = data.Select(x => x.Timestamp).Max()
            };

            var outAggregation = 0.0;
            switch (timeAggregation)
            {
                case TimeAggregationType.Count:
                    outAggregation = Convert.ToDouble(outValue.Count);
                    break;
                case TimeAggregationType.Maximum:
                    outAggregation = Convert.ToDouble(outValue.Maximum);
                    break;
                case TimeAggregationType.Minimum:
                    outAggregation = Convert.ToDouble(outValue.Minimum);
                    break;
                case TimeAggregationType.Total:
                    outAggregation = Convert.ToDouble(outValue.Total);
                    break;
                default:
                    outAggregation = Convert.ToDouble(outValue.Average);
                    break;
            }

            var thresholdPassed = false;
            switch (operation)
            {
                case ComparisonOperationType.Equals:
                    thresholdPassed = (outAggregation == threshold);
                    break;
                case ComparisonOperationType.GreaterThanOrEqual:
                    thresholdPassed = (outAggregation >= threshold);
                    break;
                case ComparisonOperationType.LessThan:
                    thresholdPassed = (outAggregation < threshold);
                    break;
                case ComparisonOperationType.LessThanOrEqual:
                    thresholdPassed = (outAggregation <= threshold);
                    break;
                case ComparisonOperationType.NotEquals:
                    thresholdPassed = (outAggregation != threshold);
                    break;
                default:
                    thresholdPassed = (outAggregation > threshold);
                    break;
            }

            if (thresholdPassed && (triggerState == null || triggerState.Equals("")))
            {
                // If there are other events to process tell the engine to get an new event every second
                return Request.EventTriggered(outValue,
                                                triggerState: "LastEvent/" + outValue.Timestamp.ToString("o"),
                                                pollAgain: null);
            }

            // Let the Logic App know we don't have any data for it
            return Request.EventWaitPoll(retryDelay: null, triggerState: thresholdPassed ? triggerState : "");
        }
        private static void Aggregate(MetricValue lastSeen, MetricValueBlob m)
        {
            lastSeen.Average += m.total;
            lastSeen.Total += m.total;
            lastSeen.Count += m.count;

            if (m.maximum > lastSeen.Maximum)
            {
                lastSeen.Maximum = m.maximum;
            }

            if (m.minimum < lastSeen.Minimum)
            {
                lastSeen.Minimum = m.minimum;
            }
        }
 private void AreEqual(MetricValue exp, MetricValue act)
 {
     if (exp != null)
     {
         Assert.Equal(exp.Average, act.Average);
         Assert.Equal(exp.Count, act.Count);
         Assert.Equal(exp.Last, act.Last);
         Assert.Equal(exp.Maximum, act.Maximum);
         Assert.Equal(exp.Minimum, act.Minimum);
         Assert.Equal(exp.Timestamp.ToUniversalTime(), act.Timestamp.ToUniversalTime());
         Assert.Equal(exp.Total, act.Total);
         AreEqual(exp.Properties, act.Properties);
     }
 }