0
votes

I am building a Java app to automate some typical infrastructure tasks in my application. I successfully calling the Azure API, but I get a (400) Bad Request return code/message. I'm debugging this in eclipse, but can't find any more meaningful data in the connection object.

The initial simple task I'm trying to do is to add a new Data Disk to my IaaS VM, 'gildev01'. I'm following the guidance in this documentation: http://msdn.microsoft.com/en-us/library/jj157199.aspx

The HTTPS URL is correct, starting with management.core.windows.net followed by my Subscription ID, then the following:

/services/hostedservices/gildev01/deployments/gildev01/roles/gildev01/DataDisks

The payload is as follows:

<DataVirtualHardDisk xmlns="http://schemas.microsoft.com/windowsazure" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HostCaching>ReadWrite</HostCaching>
<DiskLabel>java-disklabel-1</DiskLabel>
<DiskName>javadisk1</DiskName>
<LogicalDiskSizeInGB>1000</LogicalDiskSizeInGB>
<MediaLink>http://<myacct>.blob.core.windows.net/vhds/javadisk1.vhd</MediaLink>
</DataVirtualHardDisk>

So - two questions:

1) any ideas on what I'm doing wrong with the URL or the payload?

2) any suggestions on how to get more info out of the response object?

Adding Java Code:

private String addDataDisk (URL url, String keyStore, String keyStorePassword) throws UnrecoverableKeyException, KeyManagementException, KeyStoreException, NoSuchAlgorithmException, IOException {
 SSLSocketFactory sslFactory = getSSLSocketFactory(keyStore, keyStorePassword);
 String requestBody = "<DataVirtualHardDisk xmlns=\"http://schemas.microsoft.com/windowsazure\" xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\"><HostCaching>ReadWrite</HostCaching><DiskLabel>java-disklabel-1</DiskLabel><DiskName>javadisk1</DiskName><LogicalDiskSizeInGB>1000</LogicalDiskSizeInGB><MediaLink>http://myacct.blob.core.windows.net/vhds/javadisk1.vhd</MediaLink></DataVirtualHardDisk>");
 HttpsURLConnection con = null;
    con = (HttpsURLConnection) url.openConnection();
    con.setSSLSocketFactory(sslFactory);
    con.setDoOutput(true);
    con.setRequestMethod("POST");
    con.addRequestProperty("x-ms-version", "2013-08-01");
    con.setRequestProperty("Content-Length", String.valueOf(requestBody.length()));
    con.setRequestProperty("Content-Type", "application/xml");

    DataOutputStream  requestStream = new DataOutputStream (con.getOutputStream());
    requestStream.write(requestBody.getBytes());
    requestStream.flush();
    requestStream.close();

    String responseMessage = con.getResponseMessage()+" - "+Integer.toString(con.getResponseCode());
1
Are you creating an empty data disk or trying to create a new data disk using an existing VHD? Also I'm guessing you're writing the code in Java. Can you share the code?Gaurav Mantri
creating an empty data disk - actually, assuming you are the same Guarav founder of Cynapta - this is came from your blog and worked for simple start/stop vm ... trying to add codenjscotch_lvr

1 Answers

0
votes

Yep, same guy :)

Based on the documentation:

Option 1 – Attach an empty data disk to the role by specifying the disk label and location of the disk image.

  • Do not include the DiskName and SourceMediaLink elements in the request body.

  • Include the MediaLink element and reference a blob that is in the same geographical region as the role.

  • You can also omit the MediaLink element. In this usage, Windows Azure will create the data disk in the storage account configured as default for the role.

Can you try by removing the <DiskName> element from your request body and see if that works?

Also not sure how you would do this in Java but when you get a 400 exception, if you parse the response body, you should see detailed error message. For example, in .Net we do something like this:

        catch (WebException webEx)
        {
            using (var resp = (HttpWebResponse)webEx.Response)
            {
                using (var respStreamReader = new StreamReader(resp.GetResponseStream()))
                {
                    var errorMessage = respStreamReader.ReadToEnd();//errorMessage will be XML containing detailed error message.
                }
            }
        }

UPDATE

So I just tried creating an empty data disk using the API, and I get 400 error under two situations:

  1. If I don't set the content type to application/xml.
  2. If I include <DiskName> element in my request body. Once I removed this element, I was able to successfully create a data disk. So your request body should not contain this element.

UPDATE 2

Endpoint: https://management.core.windows.net/<subscriptionid>/services/hostedservices/<cloudservicename>/deployments/<deploymentname>/roles/<rolename>/DataDisks

x-ms-version: 2013-08-01

XML Request:

<DataVirtualHardDisk xmlns=""http://schemas.microsoft.com/windowsazure"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"">
<HostCaching>ReadWrite</HostCaching>
<DiskLabel>java-disklabel-1</DiskLabel>
<LogicalDiskSizeInGB>1000</LogicalDiskSizeInGB>
<MediaLink>http://account.blob.core.windows.net/vhds/javadisk1.vhd</MediaLink>
</DataVirtualHardDisk>