|
| 1 | +// Copyright (c) Microsoft Corporation. All rights reserved. |
| 2 | +// Licensed under the MIT License. |
| 3 | + |
| 4 | +package com.azure.resourcemanager.compute.samples; |
| 5 | + |
| 6 | +import com.azure.core.credential.TokenCredential; |
| 7 | +import com.azure.core.http.policy.HttpLogDetailLevel; |
| 8 | +import com.azure.core.http.policy.HttpLogOptions; |
| 9 | +import com.azure.core.management.AzureEnvironment; |
| 10 | +import com.azure.core.management.Region; |
| 11 | +import com.azure.core.management.profile.AzureProfile; |
| 12 | +import com.azure.identity.DefaultAzureCredentialBuilder; |
| 13 | +import com.azure.resourcemanager.AzureResourceManager; |
| 14 | +import com.azure.resourcemanager.compute.models.CachingTypes; |
| 15 | +import com.azure.resourcemanager.compute.models.KnownLinuxVirtualMachineImage; |
| 16 | +import com.azure.resourcemanager.compute.models.VirtualMachineSizeTypes; |
| 17 | +import com.azure.resourcemanager.network.models.Network; |
| 18 | +import com.azure.resourcemanager.resourcegraph.ResourceGraphManager; |
| 19 | +import com.azure.resourcemanager.resourcegraph.models.QueryRequest; |
| 20 | +import com.azure.resourcemanager.resourcegraph.models.QueryRequestOptions; |
| 21 | +import com.azure.resourcemanager.resourcegraph.models.QueryResponse; |
| 22 | +import com.azure.resourcemanager.resourcegraph.models.ResultFormat; |
| 23 | +import com.azure.resourcemanager.resources.fluentcore.utils.ResourceManagerUtils; |
| 24 | +import com.azure.resourcemanager.samples.Utils; |
| 25 | +import com.fasterxml.jackson.core.type.TypeReference; |
| 26 | +import com.fasterxml.jackson.databind.ObjectMapper; |
| 27 | + |
| 28 | +import java.time.Duration; |
| 29 | +import java.util.Collections; |
| 30 | +import java.util.List; |
| 31 | + |
| 32 | +/** |
| 33 | + * Azure Compute sample for batch create virtual machines and batch query status |
| 34 | + * - Create multiple virtual machines from PIR image with data disks |
| 35 | + * - Use Azure Resource Graph to query the count number for each [provisioningState]. |
| 36 | + */ |
| 37 | +public final class CreateMultipleVirtualMachinesAndBatchQueryStatus { |
| 38 | + |
| 39 | + /** |
| 40 | + * Main function which runs the actual sample. |
| 41 | + * |
| 42 | + * @param azureResourceManager instance of the azure client |
| 43 | + * @param resourceGraphManager instance of the azure graph client |
| 44 | + * @return true if sample runs successfully |
| 45 | + */ |
| 46 | + public static boolean runSample(AzureResourceManager azureResourceManager, ResourceGraphManager resourceGraphManager) { |
| 47 | + final Integer desiredVMCount = 6; |
| 48 | + final Region region = Region.US_EAST; |
| 49 | + final String rgName = Utils.randomResourceName(azureResourceManager, "rg-", 15); |
| 50 | + final String networkName = Utils.randomResourceName(azureResourceManager, "vnet-", 15); |
| 51 | + final String subNetName = Utils.randomResourceName(azureResourceManager, "snet-", 15); |
| 52 | + Integer succeededTotal = 0; |
| 53 | + try { |
| 54 | + System.out.println("Creating Resource Group: " + rgName); |
| 55 | + azureResourceManager.resourceGroups().define(rgName).withRegion(region).create(); |
| 56 | + |
| 57 | + System.out.println("Creating Network: " + networkName); |
| 58 | + Network primaryNetwork = azureResourceManager.networks() |
| 59 | + .define(networkName) |
| 60 | + .withRegion(region) |
| 61 | + .withExistingResourceGroup(rgName) |
| 62 | + .withAddressSpace("10.0.0.0/16") |
| 63 | + .withSubnet(subNetName, "10.0.1.0/24") |
| 64 | + .create(); |
| 65 | + |
| 66 | + System.out.println("Batch creating Virtual Machines"); |
| 67 | + for (int i = 0; i < desiredVMCount; i++) { |
| 68 | + azureResourceManager.virtualMachines() |
| 69 | + .define(Utils.randomResourceName(azureResourceManager, "javascvm", 15)) |
| 70 | + .withRegion(region) |
| 71 | + .withExistingResourceGroup(rgName) |
| 72 | + .withExistingPrimaryNetwork(primaryNetwork) |
| 73 | + .withSubnet(subNetName) |
| 74 | + .withPrimaryPrivateIPAddressDynamic() |
| 75 | + .withoutPrimaryPublicIPAddress() |
| 76 | + .withPopularLinuxImage(KnownLinuxVirtualMachineImage.UBUNTU_SERVER_18_04_LTS) |
| 77 | + .withRootUsername(Utils.randomResourceName(azureResourceManager, "tirekicker", 15)) |
| 78 | + .withSsh(Utils.sshPublicKey()) |
| 79 | + .withNewDataDisk(50, 1, CachingTypes.READ_WRITE) |
| 80 | + .withSize(VirtualMachineSizeTypes.fromString("Standard_D2a_v4")) |
| 81 | + .beginCreate(); |
| 82 | + } |
| 83 | + |
| 84 | + System.out.println("Use Azure Resource Graph to query the count number for each [provisioningState]."); |
| 85 | + StringBuilder queryBuilder = new StringBuilder(); |
| 86 | + queryBuilder.append("resources ") |
| 87 | + .append("| where (resourceGroup =~ ('").append(rgName).append("')) ") |
| 88 | + .append("| where (type =~ ('microsoft.compute/virtualmachines')) ") |
| 89 | + .append("| where (name contains 'javascvm') ") |
| 90 | + .append("| extend provisioningState = case(") |
| 91 | + .append("properties['provisioningState'] =~ 'NotSpecified','NotSpecified',") |
| 92 | + .append("properties['provisioningState'] =~ 'Accepted','Accepted',") |
| 93 | + .append("properties['provisioningState'] =~ 'Running','Running',") |
| 94 | + .append("properties['provisioningState'] =~ 'Ready','Ready',") |
| 95 | + .append("properties['provisioningState'] =~ 'Creating','Creating',") |
| 96 | + .append("properties['provisioningState'] =~ 'Created','Created',") |
| 97 | + .append("properties['provisioningState'] =~ 'Deleting','Deleting',") |
| 98 | + .append("properties['provisioningState'] =~ 'Deleted','Deleted',") |
| 99 | + .append("properties['provisioningState'] =~ 'Canceled','Canceled',") |
| 100 | + .append("properties['provisioningState'] =~ 'Failed','Failed',") |
| 101 | + .append("properties['provisioningState'] =~ 'Succeeded','Succeeded',") |
| 102 | + .append("properties['provisioningState'] =~ 'Updating','Updating',") |
| 103 | + .append("properties['provisioningState']) ") |
| 104 | + .append("| summarize count=count() by provisioningState"); |
| 105 | + |
| 106 | + while (succeededTotal < desiredVMCount) { |
| 107 | + Integer creatingTotal = 0; |
| 108 | + Integer updatingTotal = 0; |
| 109 | + Integer failedTotal = 0; |
| 110 | + Integer otherTotal = 0; |
| 111 | + succeededTotal = 0; |
| 112 | + |
| 113 | + QueryResponse queryResponse = resourceGraphManager.resourceProviders() |
| 114 | + .resources(new QueryRequest() |
| 115 | + .withSubscriptions(Collections.singletonList(azureResourceManager.subscriptionId())) |
| 116 | + .withQuery(queryBuilder.toString()) |
| 117 | + .withOptions(new QueryRequestOptions().withResultFormat(ResultFormat.OBJECT_ARRAY))); |
| 118 | + |
| 119 | + List<TotalResult> totalResultList = new ObjectMapper().convertValue(queryResponse.data(), new TypeReference<List<TotalResult>>() {}); |
| 120 | + for (TotalResult totalResult : totalResultList) { |
| 121 | + switch (totalResult.getProvisioningState()) { |
| 122 | + case "Creating": |
| 123 | + creatingTotal = totalResult.getCount(); |
| 124 | + break; |
| 125 | + case "Succeeded": |
| 126 | + succeededTotal = totalResult.getCount(); |
| 127 | + break; |
| 128 | + case "Updating": |
| 129 | + updatingTotal = totalResult.getCount(); |
| 130 | + break; |
| 131 | + case "Failed": |
| 132 | + failedTotal = totalResult.getCount(); |
| 133 | + break; |
| 134 | + default: |
| 135 | + otherTotal += totalResult.getCount(); |
| 136 | + break; |
| 137 | + } |
| 138 | + } |
| 139 | + |
| 140 | + System.out.println(new StringBuilder() |
| 141 | + .append("\n\tThe total number of Creating : ").append(creatingTotal) |
| 142 | + .append("\n\tThe total number of Updating : ").append(updatingTotal) |
| 143 | + .append("\n\tThe total number of Failed : ").append(failedTotal) |
| 144 | + .append("\n\tThe total number of Succeeded : ").append(succeededTotal) |
| 145 | + .append("\n\tThe total number of Other Status : ").append(otherTotal)); |
| 146 | + |
| 147 | + if (failedTotal > 0) { |
| 148 | + break; |
| 149 | + } else if (succeededTotal < desiredVMCount) { |
| 150 | + ResourceManagerUtils.sleep(Duration.ofSeconds(5L)); |
| 151 | + } |
| 152 | + } |
| 153 | + } catch (Exception e) { |
| 154 | + e.printStackTrace(); |
| 155 | + } finally { |
| 156 | + try { |
| 157 | + System.out.println("Deleting Resource Group: " + rgName); |
| 158 | + azureResourceManager.resourceGroups().beginDeleteByName(rgName); |
| 159 | + System.out.println("Deleted Resource Group: " + rgName); |
| 160 | + } catch (NullPointerException npe) { |
| 161 | + System.out.println("Did not create any resources in Azure. No clean up is necessary"); |
| 162 | + } catch (Exception g) { |
| 163 | + g.printStackTrace(); |
| 164 | + } |
| 165 | + } |
| 166 | + return succeededTotal.equals(desiredVMCount); |
| 167 | + } |
| 168 | + |
| 169 | + public static void main(String[] args) { |
| 170 | + try { |
| 171 | + //============================================================= |
| 172 | + // Authenticate |
| 173 | + final AzureProfile profile = new AzureProfile(AzureEnvironment.AZURE); |
| 174 | + final TokenCredential credential = new DefaultAzureCredentialBuilder() |
| 175 | + .authorityHost(profile.getEnvironment().getActiveDirectoryEndpoint()) |
| 176 | + .build(); |
| 177 | + |
| 178 | + AzureResourceManager azureResourceManager = AzureResourceManager |
| 179 | + .configure() |
| 180 | + .withLogLevel(HttpLogDetailLevel.BASIC) |
| 181 | + .authenticate(credential, profile) |
| 182 | + .withDefaultSubscription(); |
| 183 | + |
| 184 | + ResourceGraphManager resourceGraphManager = ResourceGraphManager |
| 185 | + .configure() |
| 186 | + .withLogOptions(new HttpLogOptions().setLogLevel(HttpLogDetailLevel.BASIC)) |
| 187 | + .authenticate(credential, profile); |
| 188 | + |
| 189 | + // Print selected subscription |
| 190 | + System.out.println("Selected subscription: " + azureResourceManager.subscriptionId()); |
| 191 | + |
| 192 | + runSample(azureResourceManager, resourceGraphManager); |
| 193 | + } catch (Exception e) { |
| 194 | + System.out.println(e.getMessage()); |
| 195 | + e.printStackTrace(); |
| 196 | + } |
| 197 | + } |
| 198 | + |
| 199 | + private CreateMultipleVirtualMachinesAndBatchQueryStatus() {} |
| 200 | + |
| 201 | + private static class TotalResult { |
| 202 | + private String provisioningState; |
| 203 | + private Integer count; |
| 204 | + |
| 205 | + public String getProvisioningState() { |
| 206 | + return provisioningState; |
| 207 | + } |
| 208 | + |
| 209 | + public void setProvisioningState(String provisioningState) { |
| 210 | + this.provisioningState = provisioningState; |
| 211 | + } |
| 212 | + |
| 213 | + public Integer getCount() { |
| 214 | + return count; |
| 215 | + } |
| 216 | + |
| 217 | + public void setCount(Integer count) { |
| 218 | + this.count = count; |
| 219 | + } |
| 220 | + } |
| 221 | +} |
0 commit comments