normalian blog

Let's talk about Microsoft Azure, ASP.NET and Java!

Microsoft Azure の ARM 版 Java SDK 2回目 - リソースの存在確認をする

先日利用した ARM 版の Azure Java SDK を利用して、リソースの存在確認を行う方法を紹介する。だらだら説明する前にまずはサンプルコードを以下に記載する。

public class CheckResourceExist {
	public static void main(String[] args) throws Exception {
		Configuration config = ConfigFactory.createConfiguration();
		ResourceManagementClient resourceManagementClient = ResourceManagementService
				.create(config);
		ResourceOperations resourceOperations = resourceManagementClient
				.getResourcesOperations();

		// クラウドサービスの生存確認
		dispResourceExist(resourceOperations, "winapserver",
				"Microsoft.ClassicCompute", "domainNames", "winapserver");

		// WebApps の生存確認
		dispResourceExist(resourceOperations, "normalianwebsite",
				"Microsoft.Web", "sites", "WebSiteDeployDevelopment");
	}

	public static void dispResourceExist(ResourceOperations resourceOperations,
			String resourceName, String providerNamespace, String resourceType,
			String resourceGroupName) throws IOException, ServiceException {
		ResourceIdentity resourceIdentity = new ResourceIdentity();
		resourceIdentity.setResourceName(resourceName);
		resourceIdentity.setResourceType(resourceType);
		resourceIdentity.setResourceProviderNamespace(providerNamespace);

		// The supported api-versions are '2014-01-01, 2014-06-01, 2015-06-01'
		resourceIdentity.setResourceProviderApiVersion("2015-06-01");

		ResourceExistsResult resourceExistsResult = resourceOperations
				.checkExistence(resourceGroupName, resourceIdentity);
		StringBuilder result = new StringBuilder("@"
				+ resourceIdentity.getResourceName() + " at "
				+ resourceGroupName + "is ");
		if (resourceExistsResult.isExists() == false) {
			result.append("not ");
		}
		result.append("exists");
		System.out.println(result.toString());
	}
}

ソースコードについては GitHub HelloAzureARMSDK/src/main/java/org/mydomain/armsdksample/CheckResourceExist.java を参照頂くとして、リソースの生存確認には以下のクラスが必要になる。

  • ResourceName:コード例では normalianwebsite
  • ResoruceType:コード例では sites
  • ResourceProviderNamespace:コード例では Microsoft.Web
  • ResourceProviderApiVersion:コード例では 2015-06-01

なぜ上記の情報が必要かについては Azure リソース マネージャー REST API リファレンス を見ていただければ詳細が載っているが、PowerShell を Debug 実行しても以下の様に情報が得られる。

PS C:\Windows\System32\WindowsPowerShell\v1.0> Get-AzureWebApp -ResourceGroupName WebSiteDeployDevelopment -Name normalianwebsite -Debug

<中略>
Absolute Uri:
https://management.azure.com/subscriptions/<subscriptionId>/resourceGroups/WebSiteDeployDevelopment/providers/Microsoft.Web/sites/normalianwebsite?api-version=2014-06-01

Headers:

Body:

デバッグ: ============================ HTTP RESPONSE ============================

<中略>
Body:
{
  "id": "/subscriptions/<subscriptionId>/resourceGroups/WebSiteDeployDevelopment/providers/Microsoft.Web/sites/normalianwebsite",
  "name": "normalianwebsite",
  "type": "Microsoft.Web/sites",
  "kind": null,
  "location": "Japan West",
  "tags": {
    "hidden-related:/subscriptions/<subscriptionId>/resourceGroups/WebSiteDeployDevelopment/providers/Microsoft.Web/serverfarms/WebSiteDeployDevelopment": "Resource"
  },

上記の "Absolute Uri" から、REST API が ResourceName, ResoruceType, ResourceProviderNamespace, ResourceProviderApiVersion の情報が必要になることがわかると思う。ResourceOperations#checkExistence() の処理を見ればわかる通り、これらの情報がない場合は NullPointerException が発生する点に注意が必要だ。

また、ResourceProviderApiVersion は '2014-01-01, 2014-06-01, 2015-06-01' し利用できない。誤った API version, Location を指定した場合、以下の ServiceException が発生するので注意が必要だ*1。上記に記載した PowerShell の Debug 実行だとなぜか内部で 2014-06-01 の API Version を呼んでいるが理由は不明。

Exception in thread "main" com.microsoft.windowsazure.exception.ServiceException:{  
   "error":{  
      "code":"NoRegisteredProviderFound",
      "message":"No registered resource provider found for location 'japaneast' and API version '2015-06-15' for type 'domainNames'.
       The supported api-versions are '2014-01-01, 2014-06-01, 2015-06-01'. The supported locations are 'eastasia, southeastasia,
        eastus, eastus2, westus, northcentralus, southcentralus, centralus, northeurope, westeurope, japaneast, japanwest, brazilsouth,
        australiaeast, australiasoutheast, southindia, centralindia, westindia, eastus2stage, northcentralusstage'."
   }
}

まだまだ確認必要な点はあるがいったん終了。

参考

REST API 側では "type": "Microsoft.Web/sites" となっているのに、Azure SDK では ResourceType が sites, ResourceProviderNamespace が Microsoft.Web になっていることもあり、ちょっと混乱してしまった。この辺り、Resource Provider Namespace を一覧化している情報は公にはなっていない様で、情報が拾いきれなかったものの ドキュメント VIRTUAL NETWORK ネットワーク リソース プロバイダー では ネットワーク リソース プロバイダーの値は Microsoft.Network という記載がある。

*1:整形している点に注意