Exemplo n.º 1
0
        /// <summary>
        /// Writes data collected into the database specified in the config file element AzureAnalyticsDbModel under attribute initial catalog.
        /// </summary>
        /// <param name="cspUsageRecordsFromApi">Contains a collection of CSP usage records.</param>
        /// <returns>The number of objects written to the underlying database.</returns>
        internal static int UpdateCurrentUsageRecordsInDb(IList <CspAzureResourceUsageRecord> cspUsageRecordsFromApi)
        {
            Console.WriteLine("\nAll Usage data which exist in DB will be deleted and replaced by new line items.");
            int count;

            using (AzureAnalyticsDbModel dbContext = new AzureAnalyticsDbModel())
            {
                List <CspUsageData> itemsFromDatabase = dbContext.CspUsageDatas.ToList();
                Console.WriteLine("\n" + itemsFromDatabase.Count() + " usage records exist in DB and will be deleted.");

                if (itemsFromDatabase.Count() > 0)
                {
                    dbContext.CspUsageDatas.RemoveRange(itemsFromDatabase);
                    dbContext.SaveChanges();
                }

                List <CspUsageData> newItemsForDatabase = new List <CspUsageData>();

                foreach (CspAzureResourceUsageRecord usageRecord in cspUsageRecordsFromApi)
                {
                    newItemsForDatabase.Add(
                        new CspUsageData
                    {
                        BillingEndDate                = (DateTime?)usageRecord.BillingEndDate.Value,
                        BillingStartDate              = (DateTime?)usageRecord.BillingStartDate.Value,
                        Category                      = usageRecord.Category,
                        CustomerCommerceId            = usageRecord.CustomerCommerceId,
                        CustomerDomain                = usageRecord.CustomerDomain,
                        CustomerId                    = usageRecord.CustomerId,
                        CustomerName                  = usageRecord.CustomerName,
                        CustomerRelationshipToPartner = usageRecord.CustomerRelationshipToPartner,
                        CustomerTenantId              = usageRecord.CustomerTenantId,
                        QuantityUsed                  = usageRecord.QuantityUsed,
                        ResourceId                    = usageRecord.ResourceId,
                        ResourceName                  = usageRecord.ResourceName,
                        SubCategory                   = usageRecord.Subcategory,
                        SubscriptionContractType      = usageRecord.SubscriptionContractType,
                        SubscriptionId                = usageRecord.SubscriptionId,
                        SubscriptionName              = usageRecord.SubscriptionName,
                        SubscriptionStatus            = usageRecord.SubscriptionStatus,
                        TotalCost                     = usageRecord.TotalCost,
                        Unit = usageRecord.Unit
                    });
                }

                Console.WriteLine("\n" + newItemsForDatabase.Count() +
                                  " new usage records will be added to the database.");

                dbContext.CspUsageDatas.AddRange(newItemsForDatabase);
                count = dbContext.SaveChanges();
            }

            return(count);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Remove existing user records from database
        /// </summary>
        /// <param name="startDate">start date for data fetch</param>
        /// <param name="endDate">end date for data fetch</param>
        /// <returns></returns>
        internal static string DeleteExistingRecordsFordateRange(string startDate, string endDate)
        {
            DateTime parsedStartTime, parsedEndTime;

            DateTime.TryParse(startDate, out parsedStartTime);
            DateTime.TryParse(endDate, out parsedEndTime);
            string message;

            List <UserBillingData> rowsToBeDeleted = null;

            using (AzureAnalyticsDbModel dbContext = new AzureAnalyticsDbModel())
            {
                if (parsedStartTime != null && parsedEndTime != null)
                {
                    rowsToBeDeleted =
                        dbContext.UserBillingDatas.Where(
                            x => x.EndTime.Value >= parsedStartTime && x.StartTime <= parsedEndTime).ToList();
                }

                if (rowsToBeDeleted != null && rowsToBeDeleted.Count > 0)
                {
                    dbContext.UserBillingDatas.RemoveRange(rowsToBeDeleted);
                    int result = dbContext.SaveChanges();
                    message = result + " rows found in the date range and have been removed from database. ";
                }
                else
                {
                    message = "No data found in db for the given date range. No records were deleted.";
                }
            }
            return(message);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Business Logic to obtain the data rows to be inserted (if any) in the Database.
        /// </summary>
        /// <param name="date">Month-year date for data collection.</param>
        /// <returns>List of data returned from API.</returns>
        private static HttpOperationResponse <IList <BillingDetailLineItem> > GetFilteredEaBillingDataFromApi(string date)
        {
            HttpOperationResponse <IList <BillingDetailLineItem> > eaBillingRecordsFromApi;

            int month = int.Parse(date.Split('-')[0], CultureInfo.InvariantCulture);
            int year  = int.Parse(date.Split('-')[1], CultureInfo.InvariantCulture);

            using (AzureAnalyticsDbModel dbContext = new AzureAnalyticsDbModel())
            {
                List <EaBillingData> itemsFromDatabase;
                int recordsNums;

                // Checking records in Database
                Console.WriteLine("Checking Db for existing records for the month {0}-{1}..", month, year);
                itemsFromDatabase = dbContext.EaBillingDatas.Where(x => x.Month == month && x.Year == year).ToList();
                recordsNums       = itemsFromDatabase.Count();

                if (recordsNums == 0)
                {
                    // Call API
                    Console.WriteLine("No existing records found in Database for this month. Calling API for the data..");
                    eaBillingRecordsFromApi =
                        azureAnalyticsApi.EaBilling.GetSingleMonthDataWithHttpMessagesAsync(date).Result;
                }
                else
                {
                    // Records Found
                    Console.WriteLine("{0} records found.", recordsNums);
                    if (ConfigurationManager.AppSettings["SanityCheck"] == "0")
                    {
                        eaBillingRecordsFromApi = new HttpOperationResponse <IList <BillingDetailLineItem> >();
                    }
                    else if (ConfigurationManager.AppSettings["SanityCheck"] == "1")
                    {
                        Console.WriteLine("Deleting the existing rows for month {0}-{1}..", month, year);
                        dbContext.EaBillingDatas.RemoveRange(itemsFromDatabase);
                        int result = dbContext.SaveChanges();
                        Console.WriteLine(
                            "Successfully deleted {0} Rows for month {1}-{2} from the Database",
                            result,
                            month,
                            year);
                        Console.WriteLine("Calling API for current month's data.. ");
                        eaBillingRecordsFromApi =
                            azureAnalyticsApi.EaBilling.GetSingleMonthDataWithHttpMessagesAsync(date).Result;
                        if (eaBillingRecordsFromApi.Body == null)
                        {
                            Console.WriteLine("No data obtained from the APIs for this month..");
                        }
                    }
                    else
                    {
                        throw new Exception("Invalid value of SanityCheck");
                    }
                }

                return(eaBillingRecordsFromApi);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Update the database with the new values of CSP Records.
        /// </summary>
        /// <param name="newCspRecords">List of new CSP billing records.</param>
        /// <param name="newCspSummaryRecords">List of new CSP summary records.</param>
        /// <returns>The number of objects written to the underlying database.</returns>
        internal static int UpdateCspRecordsInDatabase(
            IList <CspBillingData> newCspRecords,
            IList <CspSummaryData> newCspSummaryRecords)
        {
            int recordsCount = 0;

            using (AzureAnalyticsDbModel dbContext = new AzureAnalyticsDbModel())
            {
                dbContext.CspBillingDatas.AddRange(newCspRecords);
                dbContext.CspSummaryDatas.AddRange(newCspSummaryRecords);
                recordsCount = dbContext.SaveChanges();
            }

            return(recordsCount);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Adding filtered Rows in the Database
        /// </summary>
        /// <param name="billingRecordsFromApi">User records obtaiend from API</param>
        /// <returns>The number of objects written to the underlying database</returns>
        public static int UpdateRecordsInDatabase(IList <UsageInfoModel> billingRecordsFromApi)
        {
            int recordsCount = 0;

            using (AzureAnalyticsDbModel dbContext = new AzureAnalyticsDbModel())
            {
                List <UserBillingData> recordsToBeAdded = new List <UserBillingData>();
                foreach (UsageInfoModel usageRecord in billingRecordsFromApi)
                {
                    DateTime parsedStartTime, parsedEndTime;
                    Decimal  parsedQuantity, parsedTotal;

                    recordsToBeAdded.Add(new UserBillingData
                    {
                        EndTime =
                            DateTime.TryParse(usageRecord.UsageEndTime, out parsedEndTime)
                                ? parsedEndTime
                                : (DateTime?)null,
                        MeterCategory    = usageRecord.MeterCategory,
                        MeterName        = usageRecord.MeterName,
                        MeterService     = usageRecord.MeteredService,
                        MeterType        = usageRecord.MeteredServiceType,
                        MeterSubcategory = usageRecord.MeterSubCategory,
                        Project          = usageRecord.UserProject,
                        Quantity         =
                            decimal.TryParse(usageRecord.Quantity.ToString(), out parsedQuantity)
                                ? parsedQuantity
                                : (decimal?)null,
                        Region    = usageRecord.MeteredRegion,
                        StartTime =
                            DateTime.TryParse(usageRecord.UsageStartTime, out parsedStartTime)
                                ? parsedStartTime
                                : (DateTime?)null,
                        SubscriptionId = usageRecord.SubceriptionId,
                        Total          =
                            decimal.TryParse(usageRecord.ItemTotal.ToString(), out parsedTotal)
                                ? parsedTotal
                                : (decimal?)null,

                        ////TODO: extract and add code for info fields
                    });
                }

                dbContext.UserBillingDatas.AddRange(recordsToBeAdded);
                recordsCount = dbContext.SaveChanges();
            }
            return(recordsCount);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Adding filtered Rows in the Database.
        /// </summary>
        /// <param name="newEaRecords">Adding the EA records into database.</param>
        /// <returns>The number of objects written to the underlying database.</returns>
        private static int UpdateEaRecordsInDatabase(List <EaBillingData> newEaRecords)
        {
            int recordsCount = 0;

            using (AzureAnalyticsDbModel dbContext = new AzureAnalyticsDbModel())
            {
                Console.WriteLine("Adding Rows in Database..");
                dbContext.EaBillingDatas.AddRange(newEaRecords);
                recordsCount = dbContext.SaveChanges();
                ////foreach (var record in newEaRecords)
                ////{
                ////    dbContext.EaBillingDatas.Add(record);
                ////    recordsCount = dbContext.SaveChanges();
                ////}
            }

            return(recordsCount);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Azure WebJob method to be run.
        /// </summary>
        /// <param name="timer">Timing configuration of web job.</param>
        public static void CronJob(
            [TimerTrigger(typeof(Helpers.ConfigurableCronSchedule), RunOnStartup = true)] TimerInfo timer)
        {
            string errorMessage   = string.Empty;
            int    status         = 0;
            int    recordsCount   = 0;
            string blobStorageUri = string.Empty;

            // determine type of customer
            string[] customerType = ConfigurationManager.AppSettings["BillingCustomerType"].Split(',');

            // definition of states
            // 0 => initialState,
            // 1 => databaseOperationCompletedSuccessfully
            // 2 => databaseAndStorageoperationCompletedSuccessfully
            // 3 => no data rows returned by API for given daterange
            // -1 => failure
            int i = 0;

            while (i < customerType.Length)
            {
                try
                {
                    // dbContext.Configuration.AutoDetectChangesEnabled = false;
                    Console.WriteLine("Job started for fetching billing data at " +
                                      DateTime.Now.ToString(CultureInfo.InvariantCulture));

                    Console.WriteLine("Starting job processing for Customer Type " + customerType[i]);

                    if (string.IsNullOrEmpty(customerType[i]))
                    {
                        Console.WriteLine(
                            "\nBillingCustomerType value is not provided in the web.config. Cannot proceed further without this input.");
                    }
                    else if (customerType[i].ToLower().Trim() == CustomerType.direct.ToString().ToLower())
                    {
                        // direct routine

                        // 1. get data from API
                        HttpOperationResponse <IList <UsageInfoModel> > billingRecordsFromApi;
                        string startDate = ConfigurationManager.AppSettings["BillingPeriodStartDate"];
                        string endDate   = ConfigurationManager.AppSettings["BillingPeriodEndDate"];

                        billingRecordsFromApi = UserHelper.GetBillingDataFromApi(startDate, endDate);

                        if (billingRecordsFromApi.Body != null && billingRecordsFromApi.Body.Count > 0)
                        {
                            // 2. remove same dated data from sql "billing data" table
                            Console.WriteLine(billingRecordsFromApi.Body.Count +
                                              " data rows returned from the pricing api.");
                            Console.WriteLine(
                                "\nChecking for existing data in database which falls in same date range, these will be deleted.");
                            string message = UserHelper.DeleteExistingRecordsFordateRange(startDate, endDate);

                            Console.WriteLine(message);

                            // 3. update data in billingdata Table
                            Console.WriteLine("\nAdding new data rows in database..");
                            recordsCount = UserHelper.UpdateRecordsInDatabase(billingRecordsFromApi.Body);
                            status       = 1;
                            Console.WriteLine("\n" + recordsCount +
                                              " records successfully appended to the database table: UserBillingData.");

                            // 4. keep a backup in Azure storage
                            Console.WriteLine("\nSaving backup of data in Azure Storage blob..");
                            blobStorageUri = UserHelper.UpdateRecordsInAzureStorage(billingRecordsFromApi.Body);
                            status         = 2;

                            Console.WriteLine("\nData backup stored in Azure blob storage at :" + blobStorageUri);
                        }
                        else
                        {
                            Console.WriteLine(
                                "\n0 data rows returned from API for the given date range. No operation performed on DB and storage. ");
                            status = 3;
                        }
                    }
                    else if (customerType[i].ToLower().Trim() == CustomerType.csp.ToString().ToLower())
                    {
                        // csp routine
                        Console.WriteLine(
                            "Starting CSP Routine. Current Usage, Historic Usage and Historic Billing data will be updated.. ");

                        // 1. Call Csp records
                        status         = recordsCount = 0;
                        blobStorageUri = null;
                        CspDataHelper.StartCspRoutine(out status, out recordsCount, out blobStorageUri);

                        // 2. Check for records count
                        if (recordsCount == 0)
                        {
                            status = 3;
                            Console.WriteLine("\nNo data rows returned by the APIs for the given date range.");
                        }
                        else
                        {
                            Console.WriteLine("\nA total of {0} rows added in the Db.", recordsCount);
                        }
                    }
                    else if (customerType[i].ToLower().Trim() == CustomerType.ea.ToString().ToLower())
                    {
                        // 1. Call Ea routine
                        status         = recordsCount = 0;
                        blobStorageUri = null;
                        EaDataHelper.StartEaRoutine(out status, out recordsCount, out blobStorageUri);

                        // 2. Check for records count
                        if (recordsCount == 0)
                        {
                            status = 3;
                            Console.WriteLine("\nNo data rows returned by the APIs for the given date range.");
                        }
                        else
                        {
                            Console.WriteLine("\nA total of {0} rows added in the Db.", recordsCount);
                        }
                    }
                    else
                    {
                        Console.WriteLine(
                            "\nThe value provided for BillingCustomerType in web.config is not valid. Cannot proceed further without correct value.");
                    }
                }
                catch (Exception ex)
                {
                    errorMessage = ex.Message;
                    Exception tempException = ex;

                    while (tempException.InnerException != null)
                    {
                        errorMessage += "\nInnerException :\n" + tempException.InnerException.Message;
                        tempException = tempException.InnerException;
                    }

                    errorMessage += "\nStackTrace :\n" + ex.StackTrace;

                    if (status == 1)
                    {
                        Console.WriteLine("\nError encountered during azure storage backup operation: \n" + errorMessage);
                    }
                    else
                    {
                        status       = -1;
                        recordsCount = 0;
                        Console.WriteLine("\nError encountered: \n" + errorMessage + " ");
                    }
                }
                finally
                {
                    Console.WriteLine("\nAdding audit information in AuditData table..\n");
                    using (AzureAnalyticsDbModel dbContext = new AzureAnalyticsDbModel())
                    {
                        dbContext.AuditDatas.Add(new AuditData
                        {
                            TimeStamp      = DateTime.Now,
                            Status         = status,
                            ErrorMessage   = errorMessage,
                            RecordCount    = recordsCount,
                            BlobStorageUrl = blobStorageUri,
                            CustomerType   = customerType[i]
                        });
                        dbContext.SaveChanges();
                    }
                }

                i++;
            }

            Console.WriteLine("\nOperation complete. Exiting this run.\n");
        }
Exemplo n.º 8
0
        /// <summary>
        /// Check Db and get billing and summary data from API, using sanity check.
        /// </summary>
        /// <param name="date">Date from which data to be fetched.</param>
        /// <param name="cspSummaryRecordsFromApi">Summary data collected from API. Sent as null. Passed as reference.</param>
        /// <param name="cspBillingRecordsFromApi">Billing data collected from API for a month. Sent as null. Passed as reference.</param>
        internal static void GetFilteredCspBillingDataFromApi(
            string date,
            out HttpOperationResponse <IList <UsageBasedLineItem> > cspSummaryRecordsFromApi,
            out HttpOperationResponse <IList <CspUsageLineItem> > cspBillingRecordsFromApi)
        {
            int month = int.Parse(date.Split('-')[0], CultureInfo.InvariantCulture);
            int year  = int.Parse(date.Split('-')[1], CultureInfo.InvariantCulture);

            using (AzureAnalyticsDbModel dbContext = new AzureAnalyticsDbModel())
            {
                List <CspSummaryData> itemsFromDatabase;
                int recordsNums;

                // Checking records in Database
                Console.WriteLine("Checking Db for existing csp billing records for the month {0}-{1}..", month, year);
                itemsFromDatabase =
                    dbContext.CspSummaryDatas.Where(
                        x => x.ChargeEndDate.Value.Month == month && x.ChargeEndDate.Value.Year == year).ToList();
                recordsNums = itemsFromDatabase.Count();

                if (recordsNums == 0)
                {
                    // Call API
                    Console.WriteLine("No existing records found in Database for this month. Calling API for the data..");
                    cspSummaryRecordsFromApi =
                        AzureAnalyticsApi.CspSummary.GetSingleMonthDataWithHttpMessagesAsync(date).Result;
                    cspBillingRecordsFromApi =
                        AzureAnalyticsApi.CspBilling.GetSingleMonthDataWithHttpMessagesAsync(date).Result;
                    Console.WriteLine(
                        "{0} data rows returned from the csp summary api.",
                        cspSummaryRecordsFromApi.Body.Count);
                    Console.WriteLine(
                        "{0} data rows returned from the csp billing api.",
                        cspBillingRecordsFromApi.Body.Count);
                }
                else
                {
                    // Records Found
                    Console.WriteLine("{0} matching records found in db in CspSummaryData table.", recordsNums);
                    if (ConfigurationManager.AppSettings["SanityCheck"] == "0")
                    {
                        cspSummaryRecordsFromApi = new HttpOperationResponse <IList <UsageBasedLineItem> >();
                        cspBillingRecordsFromApi = new HttpOperationResponse <IList <CspUsageLineItem> >();
                        Console.WriteLine("No records appended in database.");
                    }
                    else if (ConfigurationManager.AppSettings["SanityCheck"] == "1")
                    {
                        // Console.WriteLine("Deleting the existing rows for {0}-{1}..", Month, Year);
                        dbContext.CspSummaryDatas.RemoveRange(itemsFromDatabase);
                        Console.WriteLine(
                            "Deleting {0} existing rows for {1}-{2} from table: CspSummaryData..",
                            itemsFromDatabase.Count,
                            month,
                            year);

                        var billingItemsFromDatabase =
                            dbContext.CspBillingDatas.Where(
                                x => x.ChargeEndDate.Value.Month == month && x.ChargeEndDate.Value.Year == year)
                            .ToList();
                        dbContext.CspBillingDatas.RemoveRange(billingItemsFromDatabase);
                        Console.WriteLine(
                            "Deleting {0} existing rows for {1}-{2} from table: CspBillingData..",
                            billingItemsFromDatabase.Count,
                            month,
                            year);

                        int result = dbContext.SaveChanges();
                        Console.WriteLine("Successfully deleted {0} Rows.", result, month, year);
                        Console.WriteLine("Calling API for current month's data.. ");
                        cspSummaryRecordsFromApi =
                            AzureAnalyticsApi.CspSummary.GetSingleMonthDataWithHttpMessagesAsync(date).Result;
                        cspBillingRecordsFromApi =
                            AzureAnalyticsApi.CspBilling.GetSingleMonthDataWithHttpMessagesAsync(date).Result;
                        Console.WriteLine(
                            "{0} data rows returned from the csp summary api.",
                            cspSummaryRecordsFromApi.Body.Count);
                        Console.WriteLine(
                            "{0} data rows returned from the csp billing api.",
                            cspBillingRecordsFromApi.Body.Count);

                        if (cspSummaryRecordsFromApi.Body == null)
                        {
                            Console.WriteLine("No data obtained from the APIs for month {0}-{1}", month, year);
                        }
                    }
                    else
                    {
                        throw new Exception("Invalid value of SanityCheck");
                    }
                }
            }
        }