I was working on a billing sample code from GitHub
After changing all the relevant information in app.config and running the sample I am getting 404 error.
I am getting the token generated and checking the URL on fiddler is giving me status code of 404. URL is below:
https://management.azure.com/subscriptions/xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview&reportedStartTime=2016-12-01T00%3a00%3a00%2b00%3a00&reportedEndTime=2017-02-01T00%3a00%3a00%2b00%3a00
Please help me out. Find Below the code: Program.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using System.Net;
using System.IO;
using System.Linq.Expressions;
using Microsoft.Azure.Documents;
using Microsoft.Azure.Documents.Client;
using Microsoft.Azure.Documents.Linq;
using Newtonsoft.Json;
using System.Configuration;
namespace ARMAPI_Test
{
class Program
{
//This is a sample console application that shows you how to grab a token from AAD for the current user of the app, and then get usage data for the customer with that token.
//The same caveat remains, that the current user of the app needs to be part of either the Owner, Reader or Contributor role for the requested AzureSubID.
static void Main(string[] args)
{
//Get the AAD token to get authorized to make the call to the Usage API
string token = GetOAuthTokenFromAAD();
/*Setup API call to Usage API
Callouts:
* See the App.config file for all AppSettings key/value pairs
* You can get a list of offer numbers from this URL: http://azure.microsoft.com/en-us/support/legal/offer-details/
* See the Azure Usage API specification for more details on the query parameters for this API.
* The Usage Service/API is currently in preview; please use 2016-05-01-preview for api-version
* Please see the readme if you are having problems configuring or authenticating: https://github.com/Azure-Samples/billing-dotnet-usage-api
*/
// Build up the HttpWebRequest
string requestURL = String.Format("{0}/{1}/{2}/{3}",
ConfigurationManager.AppSettings["ARMBillingServiceURL"],
"subscriptions",
ConfigurationManager.AppSettings["SubscriptionID"],
"providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview&reportedStartTime=2015-03-01T00%3a00%3a00%2b00%3a00&reportedEndTime=2017-02-01T00%3a00%3a00%2b00%3a00&aggregationGranularity=Hourly&showDetails=true");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestURL);
// Add the OAuth Authorization header, and Content Type header
request.Headers.Add(HttpRequestHeader.Authorization, "Bearer " + token);
request.ContentType = "application/json";
// Call the Usage API, dump the output to the console window
try
{
// Call the REST endpoint
Console.WriteLine("Calling Usage service...");
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Console.WriteLine(String.Format("Usage service response status: {0}", response.StatusDescription));
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);
var usageResponse = readStream.ReadToEnd();
Console.WriteLine("Usage stream received. Press ENTER to continue with raw output.");
Console.ReadLine();
Console.WriteLine(usageResponse);
Console.WriteLine("Raw output complete. Press ENTER to continue with JSON output.");
Console.ReadLine();
// Convert the Stream to a strongly typed RateCardPayload object.
// You can also walk through this object to manipulate the individuals member objects.
UsagePayload payload = JsonConvert.DeserializeObject<UsagePayload>(usageResponse);
Console.WriteLine(usageResponse.ToString());
response.Close();
readStream.Close();
Console.WriteLine("JSON output complete. Press ENTER to close.");
Console.ReadLine();
}
catch (Exception e)
{
Console.WriteLine(String.Format("{0} \n\n{1}", e.Message, e.InnerException != null ? e.InnerException.Message : ""));
Console.ReadLine();
}
}
public static string GetOAuthTokenFromAAD()
{
var authenticationContext = new AuthenticationContext(String.Format("{0}/{1}",
ConfigurationManager.AppSettings["ADALServiceURL"],
ConfigurationManager.AppSettings["TenantDomain"]));
//Ask the logged in user to authenticate, so that this client app can get a token on his behalf
var result = authenticationContext.AcquireToken(String.Format("{0}/", ConfigurationManager.AppSettings["ARMBillingServiceURL"]),
ConfigurationManager.AppSettings["ClientID"],
new Uri(ConfigurationManager.AppSettings["ADALRedirectURL"]),
PromptBehavior.Always);
if (result == null)
{
throw new InvalidOperationException("Failed to obtain the JWT token");
}
return result.AccessToken;
}
}
}
Below are the keys in app.config:
<add key="ADALServiceURL" value="https://login.microsoftonline.com" />
<!-- Service root URL for Azure AD instance WITH NO TRAILING SLASH! -->
<add key="ADALRedirectURL" value="http://localhost/" />
<!-- Redirect URL for Azure AD to use which MUST MATCH YOUR AAD APP CONFIGURATION! -->
<add key="ARMBillingServiceURL" value="https://management.azure.com" />
<!-- Service root URL for ARM/Billing service WITH NO TRAILING SLASH! -->
<add key="TenantDomain" value="xxxxxx.onmicrosoft.com" />
<!-- DNS name for your Azure AD tenant, ie: contoso.onmicrosoft.com -->
<add key="SubscriptionID" value="xxxxxxxxx" />
<!-- GUID of Azure Subscription that is trusting AAD tenant specified above -->
<add key="ClientId" value="xxxxxx" />
<!-- GUID for AAD application configured as Native Client App in AAD tenant specified above -->
Check the values for your subscription and client id's. I got 404 error when I had used the tenantid instead of subscriptionid. So one of the values you are passing in is incorrect, hard to say which one. fyi, I've just been through all the same stuff. All working fine from the github sample now.