Java 用 Azure ライブラリを使用した開発のパターンとベスト プラクティスPatterns and best practices for development with the Azure libraries for Java

この記事では、プロジェクトで Java 用 Azure ライブラリを使用する際の一連のパターンとベスト プラクティスを示します。This article lists a series of patterns and best practices when using the Azure libraries for Java in your projects. これらのパターンやガイドラインに従って開発すると、管理するコードの量が減り、管理ライブラリの今後の更新時にリソースの追加や構成が容易になります。Develop with these patterns and guidelines to reduce the amount of code to maintain and make it easier to add or configure additional resources in future updates to the management libraries.

fluent インターフェイスを通じたリソースの作成Build resources through a fluent interface

fluent インターフェイスとは、オブジェクトの属性を正しく構成するメソッド チェーンを使ってオブジェクトを作成するパターンです。A fluent interface is a pattern that creates objects using a method chain that correctly configures the object's attributes. たとえば新しい Azure ストレージ アカウントを作成するには、次のように記述します。For example, to create a new Azure Storage account

StorageAccount storage = azure.storageAccounts().define(storageAccountName)
    .withRegion(region)
    .withNewResourceGroup(resourceGroup)
    .create();

メソッド チェーンを記述する過程で、次に呼び出すメソッドの候補が、流暢な対話形式で IDE に表示されます。As you go through the method chain, your IDE suggests the next method to call in the fluent conversation.

IntelliJ の fluent チェーンによるコマンド補完を示す GIF

定義しようとする Azure リソースに合ったメソッドを、IDE に表示される候補の中から選んでつなげていきます。Chain the methods suggested by the IDE as long as they make sense for the Azure resource being defined. 必要なメソッドがチェーンに欠落している場合、その部分がエラーとして IDE によって強調表示されます。If you are missing a required method in the chain your IDE will highlight it with an error.

リソースのコレクションResource collections

管理ライブラリは、最上位の com.microsoft.azure.management.Azure オブジェクトを通じてリソースを作成したり更新したりする際の、1 つの入口としての役割を果たします。The management library has a single point of entry through the top-level com.microsoft.azure.management.Azure object to create and update resources. 操作の対象となるリソースの種類は、Azure オブジェクトに定義されているリソース コレクションのメソッドを使って選択します。Select which type of resources to work with using the resource collection methods defined in the Azure object. たとえば SQL Database の場合は次のように記述します。For example, SQL Database:

SqlServer sqlServer = azure.sqlServers().define(sqlServerName)
    .withRegion(Region.US_EAST)
    .withNewResourceGroup(rgName)
    .withAdministratorLogin(administratorLogin)
    .withAdministratorPassword(administratorPassword)
    .create();

リストと反復Lists and iterations

それぞれのリソース コレクションには、そのリソースのすべてのインスタンスを現在のサブスクリプションから返す list() メソッドがあります。Each resource collection has a list() method to return every instance of that resource in your current subscription. たとえば、azure.sqlServers().list() とした場合、そのサブスクリプションに存在する SQL データベースがすべて返されます。For example, azure.sqlServers().list() returns all SQL databases in the subscription.

取得するリストの範囲を特定の Azure リソース グループに限定するには、listByResourceGroup(String groupname) メソッドを使用します。Use the listByResourceGroup(String groupname) method to scope the returned List to a specific Azure resource group.

返された PagedList<T> コレクションは、通常の List<T> とまったく同じように、検索したり反復処理を行ったりすることができます。Search and iterate over the returned PagedList<T> collection just as you would a normal List<T>:

PagedList<VirtualMachine> vms = azure.virtualMachines().list();
for (VirtualMachine vm : vms) {
    System.out.println("Found virtual machine with ID " + vm.id());
}

クエリから返されるコレクションCollections returned from queries

管理ライブラリは、クエリ結果の構造に基づく特定のコレクション型を返します。The management libraries return specific collection types from queries based on the structure of the results.

  • List<T>:順序付けされていないデータで、検索と反復処理を簡単に行うことができます。List<T>: Unordered data that is easy to search and iterate over.
  • Map<T>:Map はキー/値のペアです。一意のキーを持ちますが、値が一意であるとは限りません。Map<T>: Maps are key/value pairs with unique keys, but not necessarily unique values. Map の例としては、App Service Web Apps のアプリケーション設定があります。An example of a Map would be app settings for an App Service Web App.
  • Set<T>:Set は、一意のキーと値を持ちます。Set<T>: Sets have unique keys and values. たとえば仮想マシンにアタッチされたネットワークは Set であり、一意の識別子 (キー) と一意のネットワーク構成 (値) の両方を持ちます。An example of a Set would be networks attached to a virtual machine, which would have both an unique identifier (the key) and a unique network configuration (the value).

アクション可能な動詞Actionable verbs

名前に動詞を含んだメソッドを実行すると、Azure で何らかのアクションが直ちに実行されます。Methods with verbs in their names take immediate action in Azure. これらのメソッドは同期的に動作するため、現在のスレッドで実行されている処理は、メソッドが完了するまでブロックされます。These methods work synchronously and block execution in the current thread until they complete.

動詞Verb 使用例Sample Usage
createcreate azure.virtualMachines().create(listOfVMCreatables)
applyapply virtualMachineScaleSet.update().withCapacity(6).apply()
deletedelete azure.disks().deleteById(id)
listlist azure.sqlServers().list()
getget VirtualMachine vm = azure.virtualMachines().getByResourceGroup(group, vmName)

注意

define()update() は動詞ですが、その後で create() または apply() が続かない限り、他の処理がブロックされることはありません。define() and update() are verbs but do not block unless followed by a create() or apply().

いくつかのメソッドには、Reactive 拡張機能を使った非同期版が存在し、Async というサフィックスが付きます。Asynchronous versions of some of these methods exist with the Async suffix using Reactive extensions.

一部のオブジェクトには、他にも、Azure のリソースの状態を変更するメソッドが存在します。Some objects have other methods with that change the state of the resource in Azure. たとえば VirtualMachinerestart() があります。For example, restart() on a VirtualMachine.

VirtualMachine vmToRestart = azure.getVirtualMachines().getById(id);
vmToRestart.restart();

これらのメソッドには必ずしも非同期版があるとは限らず、同じスレッド上で実行されている処理は、メソッドの完了までブロックされます。These methods do not always have asynchronous versions and will block execution on their thread until they complete.

リソースの遅延作成Lazy resource creation

Azure リソースを作成するとき、まだ存在しない別のリソースに新しいリソースが依存していると、作成には困難が伴います。A challenge when creating Azure resources arises when a new resource depends on another resource that doesn't yet exist. たとえば、新しい仮想マシンを作成するときに、パブリック IP アドレスを予約したり、ディスクを設定したりする場合があります。An example of this scenario is reserving a public IP address and setting up a disk when creating a new virtual machine. 開発者が求めているのは、仮想マシンを作成するときに、これらのリソースが確実に割り当てられるようにすることです。アドレスが正しく予約されたかどうかやディスクが正しく作成されたかどうかを確かめることではありません。You don't want to verify reserving the address or the creating the disk, you just want to ensure the virtual machine has those resources when it is created.

Creatable<T> オブジェクトを使用すると、コード内で使用する Azure リソースを事前に、つまり実際のサブスクリプションで作成されるのを待たずに定義することができます。Creatable<T> objects let you define Azure resources for use in your code without waiting around for them to be created in your subscription. Creatable<T> オブジェクトの作成は、実際に必要になるまで、管理ライブラリによって先延ばしされます。The management libraries defer creating Creatable<T> objects until they are needed.

Azure リソースの Creatable<T> オブジェクトは、define() 動詞を使って作成します。Generate Creatable<T> objects for Azure resources through the define() verb:

Creatable<PublicIPAddress> publicIPAddressCreatable = azure.publicIPAddresses().define(publicIPAddressName)
    .withRegion(Region.US_EAST)
    .withNewResourceGroup(rgName);

この例の Creatable<PublicIPAddress> によって定義される Azure リソースは、このコードが実行される時点では、サブスクリプションに存在しません。The Azure resource defined by the Creatable<PublicIPAddress> in this example does not yet exist in your subscription when this code executes. この IP アドレスを使って他の Azure リソースを作成するには、publicIPAddressCreatable オブジェクトを使用します。Use the publicIPAddressCreatable object to create other Azure resources with this IP address.

Creatable<VirtualMachine> vmCreatable = azure.virtualMachines().define("creatableVM")
    .withNewPrimaryPublicIPAddress(publicIPAddressCreatable)

Creatable<T> のリソースがサブスクリプションに作成されるのは、そのオブジェクトを使って定義されたリソースが、create() を使って Azure に作成されたときです。The Creatable<T> resources are generated in your subscription when any resource that is defined using the object is built in Azure using create(). 引き続き IP アドレスと仮想マシンの例を次に示します。Continuing the IP address and virtual machine example:

CreatedResources<VirtualMachine> virtualMachine = azure.virtualMachines().create(vmCreatable);

create() の呼び出しに Creatable<T> を渡すと、単一のリソース オブジェクトではなく CreatedResources オブジェクトが返されます。Passing the Creatable<T> to create() calls returns a CreatedResources object instead of a single resource object. CreatedResources<T> オブジェクトを使用すると、create() の呼び出しで作成された (呼び出しの中で型指定したリソースだけでなく) すべてのリソースにアクセスすることができます。The CreatedResources<T> object lets you access all resources created by the create() call, not just the typed resource in the call. 上の例で作成した仮想マシンに関して Azure に作成されたパブリック IP アドレスには、次のようにしてアクセスできます。To access the public IP address created in Azure for the virtual machine created in the above example:

PublicIPAddress pip = (PublicIPAddress) virtualMachine.createdRelatedResource(publicIPAddressCreatable.key());

例外処理Exception handling

管理ライブラリの Exception クラスは com.microsoft.rest.RestException を拡張したものです。The management libraries' Exception classes extend com.microsoft.rest.RestException. 管理ライブラリによって生成された例外は、対応する try ステートメントに続く catch (RestException exception) ブロックでキャッチします。Catch exceptions generated by the management libraries with a catch (RestException exception) block after the relevant try statement.

ログとトレースLogs and trace

エントリ ポイントとなる Azure オブジェクトを作成するときに管理ライブラリから出力されるログの量は、withLogLevel() を使って構成することができます。Configure the amount of logging from the management library when you build the entry point Azure object using withLogLevel(). 次のトレース レベルが存在します。The following trace levels exist:

トレース レベルTrace level 有効になるログLogging enabled
com.microsoft.rest.LogLevel.NONEcom.microsoft.rest.LogLevel.NONE 出力なしNo output
com.microsoft.rest.LogLevel.BASICcom.microsoft.rest.LogLevel.BASIC 基になる REST 呼び出しの URL、応答コード、時間がログに記録されますLogs the URLs to underlying REST calls, response codes and times
com.microsoft.rest.LogLevel.BODYcom.microsoft.rest.LogLevel.BODY BASIC の全出力内容に加えて、REST 呼び出しの要求と応答の本文がログに記録されますEverything in BASIC plus request and response bodies for the REST calls
com.microsoft.rest.LogLevel.HEADERScom.microsoft.rest.LogLevel.HEADERS BASIC の全出力内容に加えて、REST 呼び出しの要求と応答のヘッダーがログに記録されますEverything in BASIC plus the request and response headers REST calls
com.microsoft.rest.LogLevel.BODY_AND_HEADERScom.microsoft.rest.LogLevel.BODY_AND_HEADERS BODY と HEADERS の両ログ レベルの全出力内容が記録されますEverything in both BODY and HEADERS log level

Log4J 2 などのログ記録フレームワークに出力する必要がある場合は、SLF4J のログ記録の実装をバインドしてください。Bind a SLF4J logging implementation if you need to log output to a logging framework like Log4J 2.