Azure retrieving the PublicIPAddress of VirtualMachines from Azure Java SDK

Question

As the answer was Page Not Found, I was trying to retrieve size of Public IPs with the following code

Configuration config = ManagementConfiguration.configure(
          new URI(uri), 
          subscriptionId,
          keyStoreLocation, // the file path to the JKS
          keyStorePassword, // the password for the JKS
          KeyStoreType.jks // flags that I'm using a JKS keystore
        );

NetworkResourceProviderClient  networkResourceProviderClient = NetworkResourceProviderService.create(config);
           PublicIpAddressListResponse PublicIpAddressListResponse =networkResourceProviderClient.getPublicIpAddressesOperations().listAll();
           ArrayList<PublicIpAddress> PublicIpAddressList =PublicIpAddressListResponse.getPublicIpAddresses();
           System.out.println(PublicIpAddressList.size());

using Azure AD ServicePrincipal authentication, It returns - 0

using certificate authentication with the "https://management.azure.com/" API, It returns - AuthenticationFailed:

Exception in thread "main" com.microsoft.windowsazure.exception.ServiceException: AuthenticationFailed: Authentication failed. The 'Authorization' header is not present or provided in an invalid format.
    at com.microsoft.windowsazure.exception.ServiceException.createFromJson(ServiceException.java:290)
    at com.microsoft.azure.management.network.PublicIpAddressOperationsImpl.listAll(PublicIpAddressOperationsImpl.java:1443)
    at com.microsoft.azure.auth.Program.main(Program.java:50)

any Idea how to retrieve all the Virtual Machine's Public IP address? or how to Authenticate it to get the IP value?

Solution

The issue was caused by using the incorrect authentication.

The authentication code below just works for Azure Service Management.

Configuration config = ManagementConfiguration.configure(
          new URI("https://management.core.windows.net), 
          subscriptionId,
          keyStoreLocation, // the file path to the JKS
          keyStorePassword, // the password for the JKS
          KeyStoreType.jks // flags that I'm using a JKS keystore
        );

Authenticating for Azure Resource Management, the doc "Authenticating Azure Resource Management request"( https://msdn.microsoft.com/en-us/library/azure/dn790557.aspx) says "All of the tasks that you do on resources using the Azure Resource Manager must be authenticated with Azure Active Directory. ".

So you need to modify the authenticate configuration code with your subscription-id, tenant-id, client-id and client-secret as follow:

private static AuthenticationResult getAccessTokenFromServicePrincipalCredentials() throws
            ServiceUnavailableException, MalformedURLException, ExecutionException, InterruptedException {
        AuthenticationContext context;
        AuthenticationResult result = null;
        ExecutorService service = null;
        try {
            service = Executors.newFixedThreadPool(1);
            // TODO: add your tenant id
            context = new AuthenticationContext("https://login.windows.net/"   "<your tenant id>",
                    false, service);
            // TODO: add your client id and client secret
            ClientCredential cred = new ClientCredential("<your client id>",
                    "<your client secret>");
            Future<AuthenticationResult> future = context.acquireToken(
                    "https://management.azure.com/", cred, null);
            result = future.get();
        } finally {
            service.shutdown();
        }

        if (result == null) {
            throw new ServiceUnavailableException(
                    "authentication result was null");
        }
        return result;
    }


Configuration config = ManagementConfiguration.configure(
          null,
          new URI("https://management.core.windows.net), 
          "<your-subscription-id>",
          getAccessTokenFromServicePrincipalCredentials()
.getAccessToken()
        );

The complete authenticate code about ServicePrincipal for Java, please refer to https://github.com/Azure/azure-sdk-for-java/blob/master/azure-mgmt-samples/src/main/java/com/microsoft/azure/samples/authentication/ServicePrincipalExample.java.

For the thread(Retrieve List of networks for a subscription in windows azure with azure java sdk) answer's url, it moves https://github.com/Azure/azure-sdk-for-java/blob/master/service-management/azure-svc-mgmt-network/src/main/java/com/microsoft/windowsazure/management/network/NetworkOperations.java.