Esempio n. 1
0
        internal HttpMessage CreatePostUsageEventRequest(UsageEvent body, Guid?requestId, Guid?correlationId)
        {
            var message = _pipeline.CreateMessage();
            var request = message.Request;

            request.Method = RequestMethod.Post;
            var uri = new RawRequestUriBuilder();

            uri.Reset(endpoint);
            uri.AppendPath("/usageEvent", false);
            uri.AppendQuery("api-version", apiVersion, true);
            request.Uri = uri;
            if (requestId != null)
            {
                request.Headers.Add("x-ms-requestid", requestId.Value);
            }
            if (correlationId != null)
            {
                request.Headers.Add("x-ms-correlationid", correlationId.Value);
            }
            request.Headers.Add("Accept", "application/json");
            request.Headers.Add("Content-Type", "application/json");
            var content = new Utf8JsonRequestContent();

            content.JsonWriter.WriteObjectValue(body);
            request.Content = content;
            return(message);
        }
 public CsvUsageEvent(UsageEvent usageEvent)
 {
     CustomerId  = usageEvent.CustomerId;
     ItemId      = usageEvent.ItemId;
     EventType   = usageEvent.EventType.ToString();
     CreatedDate = usageEvent.CreatedDate.ToString("s");
 }
        /// <summary>
        /// Manage Subscription Usage.
        /// </summary>
        /// <param name="subscriptionUsageRequest">The subscription usage request.</param>
        /// <returns>
        /// Subscription Usage.
        /// </returns>
        public async Task <MeteringUsageResult> EmitUsageEventAsync(MeteringUsageRequest subscriptionUsageRequest)
        {
            this.Logger?.Info($"Inside ManageSubscriptionUsageAsync() of FulfillmentApiClient, trying to Manage Subscription Usage :: {subscriptionUsageRequest.ResourceId}");

            var usage = new UsageEvent()
            {
                ResourceId         = subscriptionUsageRequest.ResourceId,
                PlanId             = subscriptionUsageRequest.PlanId,
                Dimension          = subscriptionUsageRequest.Dimension,
                Quantity           = subscriptionUsageRequest.Quantity,
                EffectiveStartTime = subscriptionUsageRequest.EffectiveStartTime,
            };

            try
            {
                var updateResult = (await this.meteringClient.Metering.PostUsageEventAsync(usage)).Value;
                return(new MeteringUsageResult()
                {
                    Dimension = updateResult.Dimension,
                    MessageTime = updateResult.MessageTime.Value.UtcDateTime,
                    PlanId = updateResult.PlanId,
                    Quantity = (long)updateResult.Quantity,
                    ResourceId = updateResult.ResourceId.Value,
                    Status = updateResult.Status.ToString(),
                    UsagePostedDate = updateResult.EffectiveStartTime.Value.UtcDateTime,
                    UsageEventId = updateResult.UsageEventId.Value
                });
            }
            catch (Exception ex)
            {
                this.ProcessErrorResponse(MarketplaceActionEnum.SUBSCRIPTION_USAGEEVENT, ex);
                return(null);
            }
        }
 public virtual Response <UsageEventOkResponse> PostUsageEvent(UsageEvent body, Guid?requestId = null, Guid?correlationId = null, CancellationToken cancellationToken = default)
 {
     using var scope = _clientDiagnostics.CreateScope("MeteringOperations.PostUsageEvent");
     scope.Start();
     try
     {
         return(RestClient.PostUsageEvent(body, requestId, correlationId, cancellationToken));
     }
     catch (Exception e)
     {
         scope.Failed(e);
         throw;
     }
 }
Esempio n. 5
0
        public async Task <IActionResult> SubscriptionDimensionUsage(DimensionEventViewModel model, CancellationToken cancellationToken)
        {
            if (model == null)
            {
                throw new ArgumentNullException(nameof(model));
            }

            var usage = new UsageEvent()
            {
                ResourceId         = model.SubscriptionId,
                PlanId             = model.PlanId,
                Dimension          = model.SelectedDimension,
                Quantity           = model.Quantity,
                EffectiveStartTime = model.EventTime,
            };

            var updateResult = await this.meteringClient.MeteringOperations.PostUsageEventAsync(usage, null, null, cancellationToken).ConfigureAwait(false);

            DimensionUsageRecord dimRecord = new DimensionUsageRecord(usage.ResourceId?.ToString(), DateTime.Now.ToString("o"));

            bool errorMessage = true;

            if (updateResult != null)
            {
                dimRecord.UsageEventId       = updateResult.UsageEventId;
                dimRecord.Status             = updateResult.Status.ToString();
                dimRecord.Quantity           = updateResult.Quantity;
                dimRecord.Dimension          = updateResult.Dimension;
                dimRecord.EffectiveStartTime = updateResult.MessageTime;
                dimRecord.PlanId             = updateResult.PlanId;
                errorMessage = false;
            }
            else
            {
                dimRecord.Status             = UsageEventStatusEnum.InvalidDimensionBadArgument.ToString();
                dimRecord.Quantity           = usage.Quantity;
                dimRecord.Dimension          = usage.Dimension;
                dimRecord.EffectiveStartTime = usage.EffectiveStartTime;
                dimRecord.PlanId             = usage.PlanId;
            }

            await this.dimensionUsageStore.RecordAsync(model.SubscriptionId, dimRecord, cancellationToken).ConfigureAwait(false);

            return(this.RedirectToAction("SubscriptionDimensionUsage", new { model.SubscriptionId, errorMessage }));
        }
Esempio n. 6
0
        public virtual UsageEvent ToModel(UsageEvent usageEvent)
        {
            if (usageEvent == null)
            {
                throw new ArgumentNullException("usageEvent");
            }

            usageEvent.Id           = Id;
            usageEvent.CreatedBy    = CreatedBy;
            usageEvent.CreatedDate  = CreatedDate;
            usageEvent.ModifiedBy   = ModifiedBy;
            usageEvent.ModifiedDate = ModifiedDate;
            usageEvent.CustomerId   = CustomerId;
            usageEvent.StoreId      = StoreId;
            usageEvent.ItemId       = ItemId;
            usageEvent.EventType    = (UsageEventType)Enum.Parse(typeof(UsageEventType), EventType);

            return(usageEvent);
        }
Esempio n. 7
0
        public async Task <Response <UsageEventOkResponse> > PostUsageEventAsync(UsageEvent body, Guid?requestId = null, Guid?correlationId = null, CancellationToken cancellationToken = default)
        {
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }

            using var message = CreatePostUsageEventRequest(body, requestId, correlationId);
            await _pipeline.SendAsync(message, cancellationToken).ConfigureAwait(false);

            switch (message.Response.Status)
            {
            case 200:
            {
                UsageEventOkResponse value = default;
                using var document = await JsonDocument.ParseAsync(message.Response.ContentStream, default, cancellationToken).ConfigureAwait(false);

                value = UsageEventOkResponse.DeserializeUsageEventOkResponse(document.RootElement);
                return(Response.FromValue(value, message.Response));
            }
Esempio n. 8
0
        public virtual UsageEventEntity FromModel(UsageEvent usageEvent, PrimaryKeyResolvingMap pkMap)
        {
            if (usageEvent == null)
            {
                throw new ArgumentNullException("usageEvent");
            }

            pkMap.AddPair(usageEvent, this);

            Id           = usageEvent.Id;
            CreatedBy    = usageEvent.CreatedBy;
            CreatedDate  = usageEvent.CreatedDate;
            ModifiedBy   = usageEvent.ModifiedBy;
            ModifiedDate = usageEvent.ModifiedDate;
            CustomerId   = usageEvent.CustomerId;
            StoreId      = usageEvent.StoreId;
            ItemId       = usageEvent.ItemId;
            EventType    = usageEvent.EventType.ToString();

            return(this);
        }
Esempio n. 9
0
        public static void AddUsageEvent(string userName, string homeOrgName, string partnerName, string certFile, string validationStatus,
                                         TimeSpan executionTime, string testFileName, string service, IDalManager dal)
        {
            // Hardcoded order since we don't create order during sign up yet.
            Order order = new Order()
            {
                Id        = Guid.Parse("75654e42-c3fe-482b-b52a-024d073e1ea7"),
                OfferId   = Guid.Parse("5ddd32f3-1783-4bbe-854f-4c5d5955df7f"),
                SeatCount = 1,
                TenantId  = "GCom",
                UserId    = userName,
            };

            UsageEvent usageEvent = new UsageEvent()
            {
                Id             = Guid.NewGuid(),
                OrderId        = order.Id,
                ResourceId     = "EdiValidation",
                TenantId       = order.TenantId,
                Timestamp      = DateTime.UtcNow,
                WhenConsumed   = DateTime.UtcNow,
                UserId         = order.UserId,
                AmountConsumed = 1.0d,

                HomeOrgName          = homeOrgName,
                PartnerName          = partnerName,
                SpecCertName         = certFile,
                InstanceFileName     = testFileName,
                ValidationStatus     = validationStatus,
                TimeOfValidationInMs = (int)executionTime.TotalMilliseconds,

                Service = service,
            };

            // For unit tests dal will be null
            if (dal != null)
            {
                dal.TrackUsage(usageEvent);
            }
        }
Esempio n. 10
0
        public bool TrackUsage(UsageEvent usage)
        {
            int          statusCode         = -1;
            BillingCycle currentBillingCyle = this.manager.FetchOrCreateCurrentBillingCycle();

            usage.BillingCycleId = currentBillingCyle.Id;

            //PartitionKey = orderId + billingCycleId
            //RowKey = NewGuid
            usage.PartitionKey = string.Format("{0}-{1}", usage.OrderId.ToString(), usage.BillingCycleId.ToString());
            usage.RowKey       = Guid.NewGuid().ToString();

            //locking to reduce contention for aggregate update if multiple events for same order are coming at the same time
            //this is not foolproff though. TODO - when updates happen from different servers. check what error Azure
            //returns when server1 read, server2 updated, server1 updated
            //based on that tweak the business logic
            lock (lockObject)
            {
                //step1 - fetchORcreate and increment aggregate usage
                UsageAggregateByBillingCycle aggregate = GetUsageAggregateByBillingCycle(usage.OrderId, usage.BillingCycleId, usage.ResourceId);
                bool isNew = false;
                if (aggregate == null)
                {
                    aggregate = new UsageAggregateByBillingCycle {
                        OrderId = usage.OrderId, BillingCycleId = usage.BillingCycleId, ResourceId = usage.ResourceId
                    };
                    aggregate.PartitionKey = string.Format("{0}-{1}", usage.OrderId.ToString(), usage.BillingCycleId.ToString());
                    aggregate.RowKey       = usage.ResourceId;
                    isNew = true;
                }

                aggregate.AmountConsumed += usage.AmountConsumed;

                //step2 - save raw usage
                this.tableContext.AddObject(RawUsageTableName, usage);

                if (isNew)
                {
                    this.aggregateTableServiceContext.AddObject(AggregateUsageTableName, aggregate);
                }

                else
                {
                    this.aggregateTableServiceContext.UpdateObject(aggregate);
                }


                //Now add logic for per user aggregate
                UsageAggregatePerUserByBillingCycle aggregatePerUser = GetUsageAggregatePerUserByBillingCycle(usage.OrderId, usage.BillingCycleId, usage.ResourceId, usage.UserId);
                isNew = false;
                if (aggregatePerUser == null)
                {
                    aggregatePerUser = new UsageAggregatePerUserByBillingCycle {
                        OrderId = usage.OrderId, BillingCycleId = usage.BillingCycleId, ResourceId = usage.ResourceId,
                        UserId  = usage.UserId
                    };
                    aggregatePerUser.PartitionKey = string.Format("{0}-{1}", usage.OrderId.ToString(), usage.BillingCycleId.ToString());
                    aggregatePerUser.RowKey       = string.Format("{0}-{1}", usage.ResourceId, usage.UserId);
                    isNew = true;
                }

                aggregatePerUser.AmountConsumed += usage.AmountConsumed;


                if (isNew)
                {
                    this.aggregatePerUserTableServiceContext.AddObject(AggregatePerUserUsageTableName, aggregatePerUser);
                }

                else
                {
                    this.aggregatePerUserTableServiceContext.UpdateObject(aggregatePerUser);
                }

                //end

                DataServiceResponse response = this.tableContext.SaveChangesWithRetries(SaveChangesOptions.Batch);
                response   = this.aggregateTableServiceContext.SaveChangesWithRetries(SaveChangesOptions.Batch);
                statusCode = response.BatchStatusCode;
            }

            return(statusCode == Http200 || statusCode == 202);
        }
Esempio n. 11
0
        public bool TrackUsage(UsageEvent usageEvent)
        {
            DalUsageEvent dal = new DalUsageEvent(this, this.storageAccount);

            return(dal.TrackUsage(usageEvent));
        }