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); }
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); }