azureazure-sdk-for-java

io.netty.channel.ChannelInitializer exceptionCaught accessing cost management api with azure java sdk to a csp account. Has anyone solve this before?


Thanks in advance. I'm trying to access programmatically the costs of each azure subscription to represent it in an app. I used the following code, but it gives this netty error that seems to deal with invalid access. Have you solve this before? I have three hypotheses:

import com.azure.core.credential.TokenCredential;
import com.azure.core.http.policy.HttpLogDetailLevel;
import com.azure.core.management.AzureEnvironment;
import com.azure.core.management.Region;
import com.azure.core.management.profile.AzureProfile;
import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.core.util.Context;
import com.azure.resourcemanager.billing.BillingManager;
import com.azure.resourcemanager.costmanagement.CostManagementManager;
import com.azure.resourcemanager.costmanagement.models.ExportType;
import com.azure.resourcemanager.costmanagement.models.FunctionType;
import com.azure.resourcemanager.costmanagement.models.GranularityType;
import com.azure.resourcemanager.costmanagement.models.OperatorType;
import com.azure.resourcemanager.costmanagement.models.QueryAggregation;
import com.azure.resourcemanager.costmanagement.models.QueryColumnType;
import com.azure.resourcemanager.costmanagement.models.QueryComparisonExpression;
import com.azure.resourcemanager.costmanagement.models.QueryDataset;
import com.azure.resourcemanager.costmanagement.models.QueryDefinition;
import com.azure.resourcemanager.costmanagement.models.QueryFilter;
import com.azure.resourcemanager.costmanagement.models.QueryGrouping;
import com.azure.resourcemanager.costmanagement.models.TimeframeType;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

// Sample to query in a table
public class Query {

  public static void main(String[] args) {

    AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE);
    TokenCredential credential = new DefaultAzureCredentialBuilder()
            .authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint())
            .build();
    // System.out.println(profile.getTenantId());
    CostManagementManager manager = CostManagementManager
            .authenticate(credential, profile);
    System.out.println(System.getenv("AZURE_TENANT_ID"));
    System.out.println(System.getenv("AZURE_CLIENT_ID"));
    System.out.println(System.getenv("AZURE_CLIENT_SECRET"));

    try{
        customerQueryGroupingModern(manager);
    }
     catch (final Exception e) {
        System.out.println(e);
    }
  }


  //https://github.com/Azure/azure-sdk-for-java/blob/main/sdk/costmanagement/azure-resourcemanager-costmanagement/src/samples/java/com/azure/resourcemanager/costmanagement/QueryUsageSamples.java
      /**
     * Sample code: CustomerQueryGrouping-Modern.
     *
     * @param costManagementManager Entry point to CostManagementManager.
     */
    public static void customerQueryGroupingModern(
        com.azure.resourcemanager.costmanagement.CostManagementManager costManagementManager) {
        costManagementManager
            .queries()
            .usageWithResponse(
                "providers/Microsoft.Billing/billingAccounts/xxxxxxxx/customers/5678",
                new QueryDefinition()
                    .withType(ExportType.USAGE)
                    .withTimeframe(TimeframeType.THE_LAST_MONTH)
                    .withDataset(
                        new QueryDataset()
                            .withGranularity(GranularityType.fromString("None"))
                            .withAggregation(
                                mapOf(
                                    "totalCost",
                                    new QueryAggregation().withName("PreTaxCost").withFunction(FunctionType.SUM)))
                            .withGrouping(
                                Arrays
                                    .asList(
                                        new QueryGrouping()
                                            .withType(QueryColumnType.DIMENSION)
                                            .withName("ResourceGroup")))),
                Context.NONE);
    }

    @SuppressWarnings("unchecked")
    private static <T> Map<String, T> mapOf(Object... inputs) {
        Map<String, T> map = new HashMap<>();
        for (int i = 0; i < inputs.length; i += 2) {
            String key = (String) inputs[i];
            T value = (T) inputs[i + 1];
            map.put(key, value);
        }
        return map;
    }

}

Solution

  • I looked for similar errors in google and it was said this issue was relating to a netty package not included. In the readme it was described to use netty for authentication but no package was written. Finally, I found one in the resource manager part of the sdk and included it in the pom.xml:

        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-core-http-netty</artifactId>
            <version>1.12.4</version>
        </dependency>