0

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 -->

Hungry
  • 39
  • 12
  • 1
    Please post some of your C# code that's leading to error – BytesOfMetal Feb 23 '17 at 08:22
  • given 404 is "page not found" that tells me your url is wrong. – Takarii Feb 23 '17 at 09:02
  • @msanz, added the code above. – Hungry Feb 23 '17 at 09:09
  • @Takarii, I am using the same code without changing a bit :) just edited the config after configuring the app Ids. The enviornment that I am using is SandBox – Hungry Feb 23 '17 at 09:11
  • Not sure the date formats are correct, try parsing only `2015-03-01`and `2017-02-01`, I have it working omitting the time. Such a wide date range may cause a timeout though – BytesOfMetal Feb 23 '17 at 09:17
  • No Luck... [](https://management.azure.com/subscriptions/xxxxxxxxxxx/providers/Microsoft.Commerce/UsageAggregates?api-version=2015-06-01-preview&reportedStartTime=2015-03-01&reportedEndTime=2017-02-01&aggregationGranularity=Hourly&showDetails=true) – Hungry Feb 23 '17 at 09:22
  • Here `` it should go the Tentant ID, so when creating the `AuthenticationContext`, the string looks like `"https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"` ... Is that method working??? – BytesOfMetal Feb 23 '17 at 09:27
  • Yes its working and I am able to login as well... error I am getting on the line below: HttpWebResponse response = (HttpWebResponse)request.GetResponse(); – Hungry Feb 23 '17 at 09:34

1 Answers1

1

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.

Rod
  • 245
  • 2
  • 10