public static ConsumptionMetricsDestinationRecord CaptureDestinationRecord(
            Guid subscriptionId,
            Guid resourceId,
            string meter,
            int amount,
            DateTimeOffset consumedDateTime,
            string reason,
            IDictionary <string, string> internalContext,
            IDictionary <string, string> subOwnerContext)
        {
            var mockedDestination = new Mock <IConsumptionMetricsDestination>();

            var capturedInternalContext = new Dictionary <string, string>();

            mockedDestination
            .Setup(d => d.ForInternalContext(It.IsAny <string>(), It.IsAny <string>()))
            .Callback((string propertyName, string value) => capturedInternalContext.Add(propertyName, value))
            .Returns(mockedDestination.Object);

            var capturedSubOwnerContext = new Dictionary <string, string>();

            mockedDestination
            .Setup(d => d.ForSubscriptionOwnerContext(It.IsAny <string>(), It.IsAny <string>()))
            .Callback((string propertyName, string value) => capturedSubOwnerContext.Add(propertyName, value))
            .Returns(mockedDestination.Object);

            var capturedSubscriptionId   = default(Guid);
            var capturedResourceId       = default(Guid);
            var capturedMeter            = default(string);
            var capturedAmount           = default(int);
            var capturedConsumedDateTime = default(DateTimeOffset);
            var capturedReason           = default(string);

            mockedDestination
            .Setup(d => d.Write(It.IsAny <Guid>(), It.IsAny <Guid>(), It.IsAny <string>(), It.IsAny <int>(), It.IsAny <DateTimeOffset>(), It.IsAny <string>()))
            .Callback((Guid callbackSubscriptionId, Guid callbackResourceId, string callbackMeter, int callbackAmount, DateTimeOffset callbackConsumedDateTime, string callbackReason) =>
                      (capturedSubscriptionId, capturedResourceId, capturedMeter, capturedAmount, capturedConsumedDateTime, capturedReason) =
                          (callbackSubscriptionId, callbackResourceId, callbackMeter, callbackAmount, callbackConsumedDateTime, callbackReason));

            IConsumptionMetrics consumption = new ConsumptionMetrics(mockedDestination.Object);

            consumption = internalContext?.Aggregate(consumption, (client, kvp) => client.ForInternalContext(kvp.Key, kvp.Value)) ?? consumption;
            consumption = subOwnerContext?.Aggregate(consumption, (client, kvp) => client.ForSubscriptionOwnerContext(kvp.Key, kvp.Value)) ?? consumption;

            consumption.Record(subscriptionId, resourceId, meter, amount, consumedDateTime, reason);

            return(new ConsumptionMetricsDestinationRecord(
                       subscriptionId: capturedSubscriptionId,
                       resourceId: capturedResourceId,
                       meter: capturedMeter,
                       amount: capturedAmount,
                       consumedDateTime: consumedDateTime,
                       reason: capturedReason,
                       internalContext: capturedInternalContext,
                       subscriptionOwnerContext: capturedSubOwnerContext));
        }
        private static void RecordConsumedAmount(
            IAudit auditClient,
            int numberOfEvents,
            int numberOfThreads,
            string eventHubsTopic,
            string eventHubsHost,
            AppConfigMeterData meterData,
            AppConfigConsumedAmountData consumedAmountData)
        {
            var auditConsumptionDestination = new AuditClientConsumptionMetricsDestination(auditClient);

            var groupId        = Guid.NewGuid();
            var subscriptionId = meterData.SubscriptionId;
            var resourceId     = meterData.ResourceId;
            var meter          = meterData.Meter;
            var resourceType   = consumedAmountData.ResourceType;
            var resourceName   = consumedAmountData.ResourceName;

            Log.Information(
                "Sending {NumberOfEvents} {EventKind} events ({NumberOfThreads} threads) in GroupId {GroupId} to the {EventHubsTopic} topic on EventHubs {EventHubsHost}",
                numberOfEvents,
                ConsumptionKind.ConsumedAmount,
                numberOfThreads,
                groupId,
                eventHubsTopic,
                eventHubsHost);

            var consumptionClient = new ConsumptionMetrics(auditConsumptionDestination);

            using (Operation.Time(
                       "Sending {NumberOfEvents} {EventKind} events ({NumberOfThreads} threads) in GroupId {GroupId} to the {EventHubsTopic} topic on EventHubs {EventHubsHost}",
                       numberOfEvents,
                       ConsumptionKind.ConsumedAmount,
                       numberOfThreads,
                       groupId,
                       eventHubsTopic,
                       eventHubsHost))
            {
                Enumerable
                .Range(0, numberOfEvents)
                .AsParallel()
                .WithDegreeOfParallelism(degreeOfParallelism: numberOfThreads)
                .WithExecutionMode(ParallelExecutionMode.ForceParallelism)
                .Select(eventNumber =>
                {
                    consumptionClient
                    .ForInternalContext("GroupId", $"{groupId}")
                    .ForInternalContext("EventNumber", $"{eventNumber}")
                    .ForSubscriptionOwnerContext("Resource Type", resourceType)
                    .ForSubscriptionOwnerContext("Resource Name", resourceName)
                    .Record(
                        subscriptionId: subscriptionId,
                        resourceId: resourceId,
                        meter: meter,
                        amount: consumedAmountData.Amount,
                        consumedDateTime: consumedAmountData.ConsumedDateTime,
                        reason: consumedAmountData.Reason);

                    return(eventNumber);
                })
                .ToArray();
            }
        }