public static List <UsageRecord> GetUsageDetails(string restUrl, Guid orgId, RateCardPayload rateCardInfo) { string nextLink = ""; List <UsageRecord> usageRecords = new List <UsageRecord>(); do { HttpWebResponse httpWebResponse = null; try { if (nextLink != "") { httpWebResponse = AzureResourceManagerUtil.BillingRestApiCall(nextLink, orgId); } else { httpWebResponse = AzureResourceManagerUtil.BillingRestApiCall(restUrl, orgId); } if (httpWebResponse == null) { Trace.TraceWarning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); Trace.TraceWarning($"{nameof(httpWebResponse)} == null"); Trace.TraceWarning($" {nameof(GetUsageDetails)}({nameof(restUrl)}, {nameof(orgId)})"); Trace.TraceWarning($" {nameof(restUrl)}: {restUrl}"); Trace.TraceWarning($" {nameof(orgId)}: {orgId}"); // throw exception to start from scretch and retry. //throw new Exception("Possible reason: Bad request (400), Forbidden (403) to access. Server busy. Client blacklisted."); } else { // look response codes @ https://msdn.microsoft.com/en-us/library/azure/mt219001.aspx if (httpWebResponse.StatusCode == HttpStatusCode.OK) { Trace.TraceInformation($"Received Rest Call Response: {nameof(HttpStatusCode.OK)}. Processing..."); string streamContent; using (Stream receiveStream = httpWebResponse.GetResponseStream()) { // Pipes the stream to a higher level stream reader with the required encoding format. using (StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8)) { streamContent = readStream.ReadToEnd(); } } UsagePayload usagePayload = JsonConvert.DeserializeObject <UsagePayload>(streamContent); foreach (UsageAggregate ua in usagePayload.Value) { // handle adding cost in var usageRecord = new UsageRecord(ua); try { var meterInfo = rateCardInfo.Meters.Where(p => p.MeterId == usageRecord.MeterId).SingleOrDefault(); if (meterInfo.MeterRates.Count > 1) { Trace.TraceWarning("Multiple rates for meter: " + usageRecord.MeterId); } usageRecord.Cost = (double)meterInfo.MeterRates["0"] * usageRecord.Quantity; //if (usageRecord.cost < 0.01) usageRecord.cost = 0; // TODO: usage cost is definitelly NOT rounded like this } catch (Exception ex) { Trace.TraceError("Exception trying to apply cost info for meter: " + usageRecord.MeterId); } usageRecords.Add(usageRecord); } ContinuationToken contToken = JsonConvert.DeserializeObject <ContinuationToken>(streamContent); nextLink = contToken.NextLink ?? ""; } else if (httpWebResponse.StatusCode == HttpStatusCode.Accepted) { Trace.TraceWarning($"Data not ready. {nameof(HttpStatusCode.Accepted)}. Waiting 6 min. now: {DateTime.UtcNow}"); Thread.Sleep(1000 * 60 * 6); // wait a bit to have data get prepared by azure nextLink = restUrl; // set next link to same URL for second call } else { Trace.TraceWarning("NEW RESPONSE TYPE. HANDLE THIS!"); Trace.TraceWarning($"code:{httpWebResponse.StatusCode} desc:{httpWebResponse.StatusDescription}"); } } } finally { httpWebResponse?.Dispose(); } } while (nextLink != ""); return(usageRecords); }
public static List <UsageRecord> GetUsageDetails(string restURL, string orgID, RateCardPayload rateCardInfo) { string nextLink = ""; List <UsageRecord> usageRecords = new List <UsageRecord>(); do { HttpWebResponse httpWebResponse = null; if (nextLink != "") { httpWebResponse = AzureResourceManagerUtil.BillingRestApiCall(nextLink, orgID); } else { httpWebResponse = AzureResourceManagerUtil.BillingRestApiCall(restURL, orgID); } if (httpWebResponse == null) { Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); Console.WriteLine("httpWebResponse == null"); Console.WriteLine(" GetUsageDetails(string restURL, string orgID)"); Console.WriteLine(" restURL: {0}", restURL); Console.WriteLine(" orgID: {0}", orgID); // throw exception to start from scretch and retry. //throw new Exception("Possible reason: Bad request (400), Forbidden (403) to access. Server busy. Client blacklisted."); } else { // look response codes @ https://msdn.microsoft.com/en-us/library/azure/mt219001.aspx if (httpWebResponse.StatusCode == HttpStatusCode.OK) { Console.WriteLine("Received Rest Call Response: HttpStatusCode.OK. Processing..."); Stream receiveStream = httpWebResponse.GetResponseStream(); // Pipes the stream to a higher level stream reader with the required encoding format. StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8); string streamContent = readStream.ReadToEnd(); UsagePayload usagePayload = JsonConvert.DeserializeObject <UsagePayload>(streamContent); foreach (UsageAggregate ua in usagePayload.value) { //Handle adding cost in var ur = new UsageRecord(ua); try { var meterInfo = rateCardInfo.Meters.Where(p => p.MeterId == ur.meterId).SingleOrDefault(); ur.cost = meterInfo.MeterRates["0"] * Convert.ToDecimal(ur.quantity); if (ur.cost < 0.01M) { ur.cost = 0; } } catch (Exception ex) { Console.WriteLine("Exception trying to apply cost info for meter: " + ur.meterId); } usageRecords.Add(ur); } ContinuationToken contToken = JsonConvert.DeserializeObject <ContinuationToken>(streamContent); if (contToken.nextLink != null) { nextLink = contToken.nextLink; } else { nextLink = ""; } } else if (httpWebResponse.StatusCode == HttpStatusCode.Accepted) { Console.WriteLine("Data not ready. HttpStatusCode.Accepted. Waiting 6 min. now: {0}", DateTime.Now.ToString()); Thread.Sleep(1000 * 60 * 6); // wait a bit to have data get prepared by azure nextLink = restURL; // set next link to same URL for second call } else { Console.WriteLine("NEW RESPONSE TYPE. HANDLE THIS!"); Console.WriteLine("code:{0} desc:{1}", httpWebResponse.StatusCode, httpWebResponse.StatusDescription); } } } while (nextLink != ""); return(usageRecords); }
/// <summary> /// /// </summary> /// <param name="subscriptionId"></param> /// <param name="organizationId"></param> /// <returns></returns> public static UsagePayload GetUsage(string subscriptionId, string organizationId, string accessToken) { UsagePayload usagePayLoad = new UsagePayload(); usagePayLoad.value = new List<UsageAggregate>(); string UsageResponse = ""; try { Dictionary<string, string> startAndEndDates = new Dictionary<string, string>(); for (int i = 0; i > -3 ; i--) { var lastDayInMonth = i == 0 ? DateTime.Now.Day : DateTime.DaysInMonth(DateTime.UtcNow.Year, DateTime.UtcNow.AddMonths(i).Month); string endDate = DateTime.UtcNow.AddMonths(i).ToString(string.Format("yyyy-MM-{0}", lastDayInMonth)); string startDate = DateTime.UtcNow.AddMonths(i).ToString("yyyy-MM-01"); startAndEndDates.Add(startDate, endDate); } foreach (var key in startAndEndDates.Keys) { // Aquire Access Token to call Azure Resource Manager string requesturl = String.Format("https://management.azure.com/subscriptions/{0}/providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview&reportedstartTime={1}+00%3a00%3a00Z&reportedEndTime={2}+00%3a00%3a00Z", subscriptionId, key, startAndEndDates[key]); //Crafting the HTTP call HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requesturl); request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + accessToken); request.ContentType = "application/json"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); Stream receiveStream = response.GetResponseStream(); // Pipes the stream to a higher level stream reader with the required encoding format. StreamReader readStream = new StreamReader(receiveStream, Encoding.UTF8); UsageResponse = readStream.ReadToEnd(); var usagePayLoadResponse = JsonConvert.DeserializeObject<UsagePayload>(UsageResponse); usagePayLoad.value.AddRange(usagePayLoadResponse.value); } } catch (Exception ex) { throw ex; } return usagePayLoad; }