次の方法で共有


アプリ構成のサポート

この記事では、Spring Cloud Azure App Configuration ライブラリについて説明します。 このライブラリは、Azure App Configuration サービスから構成と機能グラフを読み込みます。 ライブラリは、環境変数、コマンドライン構成、ローカル構成ファイルなどの Spring 環境がすでに生成した抽象化と一致する PropertySource 抽象化を生成します。

Spring は VMware によって開発されたオープンソースのアプリケーション フレームワークであり、Java アプリケーションを作成するための簡素化されたモジュール方式のアプローチを提供します。 Spring Cloud Azure は、Spring と Azure サービスのシームレスな統合を実現するオープンソース プロジェクトです。

前提条件

App Configuration ストアを設定する

次のコマンドを使用して、Azure App Configuration ストアを作成します。

az appconfig create \
    --resource-group <your-resource-group> \
    --name <name-of-your-new-store> \
    --sku Standard

このコマンドにより、新しい空の構成ストアが作成されます。 次のインポートコマンドを使用すると、構成をアップロードできます。

az appconfig kv import \
    --name <name-of-your-new-store> \
    --source file \
    --path <location-of-your-properties-file> \
    --format properties \
    --prefix /application/

構成を読み込む前に確認します。 形式を YAML に変更することで、YAML ファイルをアップロードできます。 [プレフィックス] フィールドは、クライアント ライブラリによって読み込まれるデフォルトのプレフィックスであるため、重要です。

ライブラリの使用状況

アプリケーションでこの機能を使用するには、Spring Boot アプリケーションとしてビルドします。 依存関係を追加する最も便利な方法として、Spring Boot スターター com.azure.spring:spring-cloud-azure-starter-appconfiguration-config の使用が挙げられます。 次の pom.xml ファイルの例では、Azure App Configuration を使用します。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>{spring-boot-version}</version>
    <relativePath />
</parent>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.azure.spring</groupId>
      <artifactId>spring-cloud-azure-dependencies</artifactId>
      <version>5.19.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>com.azure.spring</groupId>
        <artifactId>spring-cloud-azure-starter-appconfiguration-config</artifactId>
    </dependency>
</dependencies>
<build>
    <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
    </plugins>
</build>

Note

Spring Boot 2.xを使用している場合は、 spring-cloud-azure-dependencies バージョンを 4.19.0に設定してください。 このBOMに使用されるバージョンの詳細については、「Spring Cloud Azureのどのバージョンを使うべきか」を参照してください。

次の例は、App Configuration を使用した基本的な Spring Boot アプリケーションを示しています。

@SpringBootApplication
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello World!";
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

この例では、bootstrap.properties ファイルには次の行が含まれています。

spring.cloud.azure.appconfiguration.stores[0].connection-string=${CONFIG_STORE_CONNECTION_STRING}

CONFIG_STORE_CONNECTION_STRING は、Azure App Configuration ストアへの接続文字列を含む環境変数です。 次のコマンドを使用すると、接続文字列にアクセスできます。

az appconfig credential list --name <name-of-your-store>

Note

Microsoft では、使用可能な最も安全な認証フローを使用することをお勧めします。 この手順で説明する認証フロー (データベース、キャッシュ、メッセージング、AI サービスなど) には、アプリケーションに対する非常に高い信頼が必要であり、他のフローには存在しないリスクが伴います。 このフローは、パスワードレス接続やキーレス接続のマネージド ID など、より安全なオプションが有効でない場合にのみ使用します。 ローカル コンピューターの操作では、パスワードレス接続またはキーレス接続にユーザー ID を使用します。

デフォルトでは、構成が設定されていない場合、Spring Profile が設定されていない限り、/application/ で開始される構成は、(No Label) のデフォルト ラベルで読み込まれません。この場合、デフォルト ラベルは、Spring Profile です。 ストアが空であるため、構成は読み込まれませんが、Azure App Configuration Property Source は引き続き生成されます。

/application/https://<name-of-your-store>.azconfig.io/ という名前のプロパティ ソース作成され、これにはストアのプロパティが含まれます。 要求で使用されるラベルは、名前の末尾に追加されます。 ラベルが設定されていない場合、文字 \0 は空のスペースとして存在します。

構成の読み込み

ライブラリは、1 つまたは複数の App Configuration ストアの読み込みをサポートします。 キーが複数のストア間で重複している状況で、すべてのストアを読み込むと、最も優先度の高いストア構成が読み込まれます。 最後の 1 つが最優先となります。 このプロセスを次の例で説明します。

spring.cloud.azure.appconfiguration.stores[0].connection-string=[first-store-connection-string]
spring.cloud.azure.appconfiguration.stores[1].connection-string=[second-store-connection-string]

この例では、1 番目と 2 番目のストアの両方の構成が同じ場合、2 番目のストアの構成の優先度が最も高く、最後のストアが優先されます。

Note

その他 Spring 構成と同様に Azure App Configuration を使用できます。 詳細については、Spring Boot のドキュメントの「コア機能」または「クイック スタート: Azure App Configuration を使用して Java Spring アプリを作成する」を参照してください。

構成を選択する

構成は、キーとラベルによって読み込まれます。 デフォルトでは、キー /application/ で始まる構成が読み込まれます。 デフォルト ラベルは、${spring.profiles.active} です。 ${spring.profiles.active} が設定されていない場合は、null ラベルが付いた構成が読み込まれます。 null ラベルは、Azure Portal で (No Label) のように表示されます。

次の例に示すように、異なるキーとラベル フィルターを選択して読み込まれた構成を構成できます。

spring.cloud.azure.appconfiguration.stores[0].selects[0].key-filter=[my-key]
spring.cloud.azure.appconfiguration.stores[0].selects[0].label-filter=[my-label]

key-filter プロパティは、次のフィルターをサポートします。

キー フィルター 結果
* すべてのキーと一致します。
abc abc という名前のキーと一致します。
abc* abc で始まるキー名に一致します。
abc,xyz キー名 abc または xyz を一致させます。 カンマ区切りの値は 5 つまでに制限されます。

label-filter プロパティは、次のフィルターをサポートします。

Label 説明
* \0 を含むすべてのラベルと一致します。
\0 Azure Portal で null のように表示される (No Label) ラベルと一致します。
1.0.0 厳密に 1.0.0 であるラベルに一致します。
1.0.* 1.0.* で始まるラベルに一致させます。
,1.0.0 null1.0.0 ラベルと一致します。 カンマ区切りの値は 5 つまでに制限されます。

ラベル フィルターで YAML を使用していて、null で開始する必要がある場合、ラベル フィルターを一重引用符で囲む必要があります。

spring:
  cloud:
    azure:
      appconfiguration:
        stores:
        - selects:
          - label-filter: ',1.0.0'

Note

フィルターで *, を組み合わせることはできません。 その場合は、追加の選択値を使用する必要があります。

Spring プロファイル

デフォルトでは、spring.profiles.active は、すべての選択済み構成に対して、デフォルト label-filter として設定されます。 label-filter を使用するとこの機能をオーバーライドできます。 次の例に示すように、label-filter を使用すると、${spring.profiles.active} で Spring Profiles を使用できます。

spring.cloud.azure.appconfiguration.stores[0].selects[0].label-filter=,${spring.profiles.active}
spring.cloud.azure.appconfiguration.stores[0].selects[1].label-filter=${spring.profiles.active}_local

最初の label-filter で、null ラベル付きのすべての構成を読み込んだら、Spring Profiles と一致するすべての構成を読み込みます。 終的な構成であるため、Spring Profiles は、null 構成よりも優先されます。

2 つ目の label-filter で、_local 文字列が Spring Profilesの最後に追加されますが、最後の Spring Profiles のみが追加されます。

無効なストア

構成 spring.cloud.azure.appconfiguration.enabled を使用すると、すべての構成ストアの読み込みを無効化できます。 spring.cloud.azure.appconfiguration.stores[0].enabled 構成を使用すると、個々のストアを無効化できます。

ストアを無効にするだけでなく、読み込みに失敗した場合にストアを無効にするように構成することもできます。 この構成の場合は、spring.cloud.azure.appconfiguration.stores[0].fail-fast を使用します。 fail-fast に設定することで false を無効化する際は、RuntimeException は、アプリケーションの構成が読み込まれないまま、アプリケーション ストアが無効になります。 起動時に構成ストがが無効になっている場合は、更新時に変更が確認されません。 また、構成が更新された場合、そこから値の読み込みは試行されません。

更新確認中、または構成の再読み込み中に RuntimeException が発生した場合、更新の試行は、終了し、refresh-interval が渡された後に再試行されます。

認証

このライブラリでは、Azure Identity Library でサポートされているすべての形式の ID がサポートされています。 接続文字列とマネージド ID の構成を使用して認証を行うことができます。

Note

Microsoft では、使用可能な最も安全な認証フローを使用することをお勧めします。 この手順で説明する認証フロー (データベース、キャッシュ、メッセージング、AI サービスなど) には、アプリケーションに対する非常に高い信頼が必要であり、他のフローには存在しないリスクが伴います。 このフローは、パスワードレス接続やキーレス接続のマネージド ID など、より安全なオプションが有効でない場合にのみ使用します。 ローカル コンピューターの操作では、パスワードレス接続またはキーレス接続にユーザー ID を使用します。

接続文字列

接続文字列を使用した認証は、設定する最も簡単な形式です。 次のコマンドを使用すると、ストアの接続文字列にアクセスできます。

az appconfig credential list --name <name-of-your-store>

その後、spring.cloud.azure.appconfiguration.stores[0].connection-string プロパティを接続文字列に設定できます。 ローカル構成ファイルの接続文字列を、環境変数にマップされるプレースホルダー値に設定することが強く推奨されます。 この方法では、ソース制御に接続文字列を追加しないようにすることができます。

Spring Cloud Azure の構成

Spring Cloud Azure 構成を使用すると、ライブラリを構成できます。 次のプロパティを使用するとライブラリを構成できます。

spring.cloud.azure.appconfiguration.stores[0].endpoint= <URI-of-your-configuration-store>

エンドポイントのみが設定されている場合、クライアント ライブラリは、DefaultAzureCredential を使用して認証を行います。 DefaultAzureCredential は次の方法を使用して認証を行います。

  • 環境資格情報
  • マネージド ID 資格情報
  • Azure Developer CLI 資格情報
  • IntelliJ の資格情報
  • Azure CLI の資格情報
  • Azure PowerShell 資格情報

システム割り当て ID などの ID を読み取り構成に割り当てる必要があります。 次のコマンドを使用して、この割り当てを作成します。

az role assignment create \
    --role "App Configuration Data Reader" \
    --assignee <your-client-ID> \
    --scope /subscriptions/<your-subscription>/resourceGroups/<your-stores-resource-group>/providers/Microsoft.AppConfiguration/configurationStores/<name-of-your-configuration-store>

Note

エンドポイントごとに定義できる認証方法は、接続文字列、ユーザー割り当て ID、トークン資格情報の 1 つだけです。 組み合わせる必要がある場合は、ConfigurationClientCustomizer を使用して、別の方法を使用するストアを変更します。

Note

Microsoft では、使用可能な最も安全な認証フローを使用することをお勧めします。 この手順で説明する認証フロー (データベース、キャッシュ、メッセージング、AI サービスなど) には、アプリケーションに対する非常に高い信頼が必要であり、他のフローには存在しないリスクが伴います。 このフローは、パスワードレス接続やキーレス接続のマネージド ID など、より安全なオプションが有効でない場合にのみ使用します。 ローカル コンピューターの操作では、パスワードレス接続またはキーレス接続にユーザー ID を使用します。

geo レプリケーション

このライブラリでは、Azure App Configuration の [geo レプリケーション] 機能をサポートします この機能を使用すると、データを他の場所にレプリケートできます。 この機能は、高可用性と障害復旧に役立ちます。

作成する各レプリカには、専用エンドポイントがあります。 アプリケーションが複数の地理位置に存在する場合、それぞれの場所にデプロイされた各アプリケーションを更新して、その場所にできるだけ近いレプリカに接続するようにすれば、アプリケーションと App Configuration との間のネットワーク待ち時間を最小限に抑えることができます。 それぞれのレプリカに与えられる要求クォータは独立しているため、この設定は、複数リージョンに分散されたサービスとして拡大するアプリケーションのスケーラビリティにも寄与します。

ライブラリで次のいずれかの条件が観察された場合、フェールオーバーが発生する可能性があります。

  • エンドポイントからサービス利用不可状態 (HTTP 500 以上) の応答を受信した。
  • ネットワーク接続の問題が発生した。
  • 要求がスロットルされた (HTTP 状態コード 429)。

geo レプリケーションを使用した構成ストアの作成

構成ストアのレプリカを作成するには、Azure CLI または Azure Portal を使用できます。 次の例では、Azure CLI を使用して、米国東部 2 リージョンにレプリカを作成します。

az appconfig replica create --location --name --store-name [--resource-group]

構成ストア レプリカの使用

レプリカを作成したら、それをアプリケーションで使用できます。 配信元ストアと同様に、Microsoft Entra ID または接続文字列を使用してレプリカに接続できます。

Note

Microsoft では、使用可能な最も安全な認証フローを使用することをお勧めします。 この手順で説明する認証フロー (データベース、キャッシュ、メッセージング、AI サービスなど) には、アプリケーションに対する非常に高い信頼が必要であり、他のフローには存在しないリスクが伴います。 このフローは、パスワードレス接続やキーレス接続のマネージド ID など、より安全なオプションが有効でない場合にのみ使用します。 ローカル コンピューターの操作では、パスワードレス接続またはキーレス接続にユーザー ID を使用します。

Microsoft Entra ID を使用してレプリカに接続するには、次の例に示すように、構成ストア インスタンスの endpoints を一覧する必要があります。

spring.cloud.azure.appconfiguration.stores[0].endpoints[0]=[your primary store endpoint]
spring.cloud.azure.appconfiguration.stores[0].endpoints[1]=[your replica store endpoint]

レプリカがある限り多くのエンドポイントを一覧表示できます。 ライブラリは、表示されている順序でエンドポイントに接続します。 ライブラリがレプリカに接続できない場合は、リスト内の次のレプリカが試行されます。 一定期間が経過すると、ライブラリは優先エンドポイントへの再接続を試みます。

キーの値

Azure App Configuration では、複数の種類のキー値がサポートされており、その一部には特別な機能が組み込まれています。 Azure アプリ Configuration には、JSON コンテンツ タイプ、Spring プレースホルダー、および Key Vault 参照のサポートが組み込まれています。

プレースホルダー

ライブラリでは、${} スタイルの環境プレースホールダーを使用した構成がサポートされています。 プレースホルダーを使用して Azure App Configuration キーを参照する場合は、参照からプレフィックスを削除します。 たとえば、/application/config.message${config.message} として参照されます。

Note

削除されるプレフィックスは値 spring.cloud.azure.appconfiguration.stores[0].selects[0].key-filterと一致します。

JSON

コンテンツ タイプ application/json を持つ構成は、JSON オブジェクトとして処理されます。 この機能を使用すると、1 つの構成を、@ConfigurationProperties 内の複雑なオブジェクトにマッピングできます。 たとえば、次の値を持つ JSON キー /application/config.colors を考察していきます。

{
 "Red": {
  "value": [255, 0, 0]
 },
 "Blue": {
  "value": [0, 255, 0]
 },
 "Green": {
  "value": [0, 0, 255]
 }
}

このキーは、次のコードにマップされます。

@ConfigurationProperties(prefix = "config")
public class MyConfigurations {

    private Map<String, Color> colors;

}

Key Vault の参照

Azure App Configuration とそのライブラリは、Key Vault に格納されているシークレットの参照をサポートします。 App Configurationでは、Key Vault に格納されているシークレットにマップされる値を持つキーを作成できます。 シークレットは Key Vault に安全に格納されますが、読み込まれた後は他の構成と同じ方法でアクセスできます。

App Configuration に格納されているその他のキーの場合と同様、お使いのアプリケーションは、クライアント プロバイダーを使用して Key Vault 参照を取得します。 クライアントはキーを Key Vault 参照として認識するため、一意のコンテンツ タイプを持ち、クライアントは Key Vault に接続して値を取得します。

Note

Key Vault ではシークレットを一度に 1 つしか取得できないため、App Configuration に格納されている各 Key Vault 参照は、Key Vault に対してプルされます。

Key Vault 参照の作成

Azure Portal の Key Vault 参照を作成するには、[構成エクスプローラー]> > [作成]> > [Key Vault 参照] の順に選択します。 その後、アクセス権を持つ任意の Key Vault から参照するシークレットを選択します。 [入力] タブから任意の Key Vault 参照を作成することもできます。Azure Portal で、有効な URI を入力します。

次のコマンドを使用して、Azure CLI 経由で Key Vault 参照を作成することもできます。

az appconfig kv set-keyvault \
    --name <name-of-your-store> \
    --key <key-name> \
    --secret-identifier <URI-to-your-secret>

Azure CLI 経由で任意のシークレット識別子を作成できます。 シークレット識別子には、バージョン セクションがオプションの形式 {vault}/{collection}/{name}/{version?} が必要です。

Key Vault 参照の使用

Spring Cloud Azure 構成を使用すると、ライブラリを構成できます。 App Configuration に接続して Azure Key Vault に接続する場合と同じ資格情報を使用できます。

Key Vault 以外のシークレットを解決する

App Configuration ライブラリには、Key Vault が関連付けられていないシークレットをローカルで解決するメソッドが用意されています。 この解決策は、KeyVaultSecretProvider を介して完了します。 KeyVaultSecretProvider が Key Vault 参照を提供しない場合は、TokenCredential が呼び出されます。 Key Vault 参照の URI が指定され、返された値がシークレットの値になります。

警告

KeyVaultSecretProvider を使用すると、システムが割り当てたマネージド ID の使用がオーバーライドされます。 両方を使用する場合は、KeyVaultCredentialProvider を使用して、解決する URI の null を返します。

public class MySecretProvider implements KeyVaultSecretProvider {

    @Override
    public String getSecret(String uri) {
        ...
    }

}

機能の管理

機能管理は、Spring Boot アプリケーションがコンテンツに動的にアクセスする方法を提供します。 機能管理には、次のようなさまざまな機能があります。

  • コンテンツを有効または無効にできる機能フラグ
  • コンテンツが表示されたときにターゲットを設定するための機能フィルター
  • カスタマイズされた機能フィルター
  • エンドポイントを動的に有効にする機能ゲート

機能フラグを有効にするには、次の構成を使用します。

spring.cloud.azure.appconfiguration.stores[0].feature-flags.enabled= true

有効な機能フラグは、プレフィックス feature-management を使用して Spring 構成システムに読み込まれます。 機能フラグは、ローカル構成ファイルに登録することもできます。 詳細については、「機能フラグ宣言」セクションを参照してください。

機能管理を使用する最も簡単な方法として、spring-cloud-azure-feature-managementspring-cloud-azure-feature-management-web ライブラリの使用が挙げられます。 2 つのライブラリの違いは、spring-cloud-azure-feature-management-web は、spring-webspring-webmvc の依存関係を使用して、 機能ゲートなどの機能をさらに追加します。

キー/ラベル フィルターを使用して機能フラグを有効にすることができます。 デフォルトでは、null と表示されている (No Label) ラベルが割り当てられます。 次の例に示すように、ラベル フィルターを設定することで、読み込まれる機能フラグを構成できます。

spring.cloud.azure.appconfiguration.stores[0].feature-flags.selects[0].key-filter=A*
spring.cloud.azure.appconfiguration.stores[0].feature-flags.selects[0].label-filter= dev

機能管理の基本

機能フラグ

機能フラグは、名マネと機能をオンにするために使用する機能フィルターの一覧の 2 つで構成されています。 機能フラグは、オン/オフのブール状態を持つか、機能フィルターの一覧を持つことができます。 機能フラグは、true が返されるまで、機能フィルターを評価します。 機能フィルターが true を返さない場合は、機能フィルターは false を返します。

機能フィルター

機能フィルターは、機能を有効にする必要があるシナリオを定義します。 機能フィルターは同期的に評価されます。

機能管理ライブラリには、AlwaysOnFilterPercentageFilterTimeWindowFilter および TargetingFilter の 4 つの事前定義されたフィルターがあります。

カスタム機能フィルターを作成できます。 たとえば、機能フィルターを使用して、Microsoft Edge ブラウザーを使用しているお客様にカスタム エクスペリエンスを提供できます。 たとえば、この機能フィルターの機能をカスタマイズして、Microsoft Edge ブラウザーの対象ユーザーの特定のヘッダーを表示できます。

機能フラグの宣言

機能管理ライブラリは、機能フラグのソースとして application.yml または bootstrap.yml がある Azure App Configuration をサポートします。 application.yml ファイルで機能フラグを設定するために使用される形式の例を次に示します。

feature-management:
  feature-t: false
  feature-u:
    enabled-for:
    - name: Random
  feature-v:
    enabled-for:
    - name: TimeWindowFilter
      parameters:
        Start: "Wed, 01 May 2019 13:59:59 GMT"
        End: "Mon, 01 July 2019 00:00:00 GMT"
  feature-w:
    evaluate: false
    enabled-for:
    - name: AlwaysOnFilter

この例には、次の機能フラグがあります。

  • feature-tfalse に設定されます。 この設定は、常に機能フラグの値を返します。
  • feature-u は、機能フィルターと共に使用されます。 これらのフィルターは、enabled-for プロパティで定義されます。 この場合、feature-u には、Random と呼ばれる機能フィルターが 1 つあり、これには、構成は不要なため、名前プロパティのみが必要です。
  • feature-v は、TimeWindowFilter という名前の機能フィルターを指定します。 この機能フィルターは、構成として使用するパラメーターに渡されます。 この例では、TimeWindowFilter がその機能が有効な開始時刻と終了時刻を渡します。
  • feature-w は、AlwaysOnFilter に対して使用され、常に true を評価します。 evaluate フィールドは、機能フィルターの評価を停止するために使用され、結果として機能フィルターは常に false を返します。

機能フラグの評価

spring-cloud-azure-feature-management ライブラリは、FeatureManager を提供して機能フラグを有効にするかどうかを判断します。 FeatureManager は、フラグの状態をチェックする非同期の方法を提供します。

spring-cloud-azure-feature-management-web と一緒に提供される FeatureManager は、FeatureManagerSnapshot を含みます。これは、@RequestScope で以前評価した機能フラグの状態をキャッシュして、すべての要求が同じ値を返すことを保証します。 さらに、Web ライブラリは、@FeatureGate を提供します。これは、異なるエンドポイントをブロックするか、Web 要求を異なるエンドポイントにリダイレクトします。

機能フラグのチェック

FeatureManager は、@Bean または、@Autowired 型オブジェクトに挿入できる @Component です。 FeatureManager には、機能フラグの名前を渡すと、その状態を返す isEnabled メソッドがあります。

@Autowired
FeatureManager featureManager;

if (featureManager.isEnabled("feature-t")) {
    // Do Something
}

Note

FeatureManger には、isEnabled と呼ばれる isEnabledAsync の非同期バージョンがあります。

機能管理を構成していない場合、または機能フラグが存在しない場合は、isEnabled は常に false を返します。 既存の機能フラグが不明な機能フィルターで構成されている場合、FilterNotFoundException がスローされます。 falsefail-fast に構成することで、false を返すようにこの動作を変更できます。 次の表では、fail-fast について説明します。

名前 説明 必要 Default
spring.cloud.azure.feature.management.fail-fast 例外が発生すると、RuntimeException がスローされます。 このプロパティが false に設定されている場合は、isEnabled は代わりに、false を返します。 いいえ true

FeatureManagerSnapshotFeatureManager の唯一の違いは、@RequestScope の結果となるキャッシュです。

機能ゲート

機能管理 Web ライブラリを使用すると、エンドポイントを実行するために特定の機能を有効にするよう求められます。 次の例に示すように、@FeatureGate 注釈を使用すると、この要件を設定できます。

@GetMapping("/featureT")
@FeatureGate(feature = "feature-t")
@ResponseBody
public String featureT() {
    ...
}

[feature-t] が有効な場合、featureT エンドポイントのみにアクセスできます。

無効なアクション処理

指定した機能が無効になっているためにエンドポイントがブロックされると、DisabledFeaturesHandler が呼び出されます。 既定では、HTTP 404 が返されます。 この動作は、次の例に示すように DisabledFeaturesHandler を実装することでこの動作をオーバーライドできます。

@Component
public class MyDisabledFeaturesHandler implements DisabledFeaturesHandler {

    @Override
    public HttpServletResponse handleDisabledFeatures(HttpServletRequest request, HttpServletResponse response) {
        ...
        return response;
    }

}
ルーティング

特定のルートでは、機能によって制御されるアプリケーション機能が公開される場合があります。 機能が無効になっている場合は、次の例に示すように、これらのルートを別のエンドポイントにリダイレクトできます。

@GetMapping("/featureT")
@FeatureGate(feature = "feature-t" fallback= "/oldEndpoint")
@ResponseBody
public String featureT() {
    ...
}

@GetMapping("/oldEndpoint")
@ResponseBody
public String oldEndpoint() {
    ...
}

組み込み機能フィルター

spring-cloud-azure-feature-management パッケージに付属する新しい機能フィルターがいくつかあります。 これらの機能フィルターは自動的に追加されませんが、@Configuration で設定できます。

AlwaysOnFilter

このフィルターは常に true を返します。 使用例については、「機能フラグ宣言」セクションを参照してください。

PercentageFilter

ユーザーが要求を行うたびにPercentageFilter の評価は、異なる結果として返されます。 この不整合は、FeatureManagementSnapshot を使用して、回避できます。これは、ユーザー別機能フラグの結果をキャッシュします。 この機能により、ユーザーが要求を再送信する必要がある場合でも、一貫したエクスペリエンスが確保されます。

feature-management:
  feature-v:
    enabled-for:
    - name: PercentageFilter
      parameters:
        Value: 50

TimeWindowFilter

このフィルターは、時間枠に基づいて機能を有効にする機能を提供します。 End を指定した場合のみ、その時点まで機能がオンと見なされます。 指定した場合のみ Start、その時点以降のすべてのポイントで機能がオンと見なされます。 両方を指定した場合、この機能は 2 回の間に有効と見なされます。

feature-management:
  feature-v:
    enabled-for:
    - name: TimeWindowFilter
      parameters:
        Start: "Wed, 01 May 2019 13:59:59 GMT",
        End: "Mon, 01 July 2019 00:00:00 GMT"

TargetingFilter

このフィルターは、対象ユーザーに対して機能を有効にする機能を提供します。 ターゲットの詳細な説明については、「ターゲット」セクションを参照してください。 フィルター パラメーターには、ユーザー、グループ、および機能にアクセスできるユーザー ベースのデフォルトの割合を説明する対象ユーザー オブジェクトが含まれます。 対象ユーザーに記載されているグループオブジェクトごとに、その機能にアクセスできるグループのメンバーの割合を定義する割合が必要です。 ユーザーは、次の場合にこの機能を有効にします。

  • ユーザーは、ユーザーのセクションで直接指定されます。
  • ユーザーは、グループのロールアウトに含まれる割合に含まれています。
  • ユーザーは、デフォルトのロールアウト率に分類されます。
feature-management: 
  target:
    enabled-for:
    - name: targetingFilter
      parameters:
        users:
        - Jeff
        - Alicia
        groups:
        - name: Ring0
          rollout-percentage: 100
        - name: Ring1
          rolloutPercentage: 100
        default-rollout-percentage: 50

カスタム機能フィルター

カスタム機能フィルターを作成すると、定義した条件に基づいて機能を有効にすることができます。 カスタム機能フィルターを作成するには、FeatureFilter インターフェイスを実装する必要があります。 FeatureFilter には メソッド evaluate が 1 つあります。 機能フィルターを使用して機能を有効にできることを指定すると、evaluate メソッドが呼び出されます。 evaluatetrue を返した場合、その機能を有効にする必要があります。 false が返された場合は、true が返されるまで機能フィルターを評価し続けます。 すべてのフィルターが false を返したら、機能をオフにします。

機能フィルターは、Spring Beans として定義され、@Component として定義されるか、@Configuration で定義します。

@Component("Random")
public class Random implements FeatureFilter {

    @Override
    public boolean evaluate(FeatureFilterEvaluationContext context) {
        double chance = Double.valueOf((String) context.getParameters().get("chance"));
        return Math.random() > chance / 100;
    }

}

パラメーター化機能フィルター

一部の機能フィルターでは、機能を有効にする必要があるかどうかを判断するためにパラメーターが必要です。 たとえば、ブラウザー機能フィルターでは、特定のブラウザー セットの機能を有効にすることができます。 Microsoft Edge ブラウザーと Chrome ブラウザーで機能を有効にできますが、Firefox では有効にできません。 この状況を設定するには、パラメーターを想定するように機能フィルターを設計します。 これらのパラメーターは、機能構成とコードで指定され、FeatureFilterEvaluationContextevaluate パラメーターを介してアクセスできます。 FeatureFilterEvaluationContext には、parameters という HashMap<String, Object> プロパティがあります。

ターゲティング

対象設定は、開発者が新しい機能をユーザー ベースに段階的にロールアウトできるようにする機能管理戦略です。 この戦略は、対象ユーザーと呼ばれる一連のユーザーをターゲットにする概念に基づいて構築されています。 対象ユーザーは、特定のユーザー、グループ、およびユーザー ベース全体の指定された割合で構成されます。 対象ユーザーに含まれるグループは、メンバーの合計数に対する割合にさらに分けることができます。

次の手順は、新しい「ベータ」機能の段階的なロールアウトの例を示しています。

  1. 個人ユーザーのジェフとアリシアには、ベータ版へのアクセスが付与されています。
  2. 別のユーザーであるマークは、オプトイン要求をして、含まれました。
  3. 「Ring1」ユーザーと呼ばれるグループの 20% がベータ版に含まれています。
  4. ベータ版に含まれる「Ring1」ユーザーの数は、最大 100% 増加します。
  5. ユーザー ベースの 5% がベータに含まれています。
  6. ロールアウト率は最大 100% まで増加し、機能は完全にロールアウトされます。

機能をロールアウトする戦略は、含まれている TargetingFilter 機能フィルターを介して、ライブラリでビルドされます。

アプリケーションでのターゲット設定

ターゲット機能フィルターを使用する Web アプリケーションの例は、プロジェクト例に記載されています。

アプリケーションで TargetingFilter の使用を開始するには、その他機能フィルターのように @Bean として追加する必要があります。 TargetingFilter は、アプリケーション @Bean に追加される別の TargetingContextAccessor に依存します。 次の例に示すように、TargetingContextAccessor は、現在のユーザー ID とグループの定義に使用される現在の TargetingContext の定義を許可します。

public class MyTargetingContextAccessor implements TargetingContextAccessor {

    @Override
    public void getContextAsync(TargetingContext context) {
        context.setUserId("Jeff");
        ArrayList<String> groups = new ArrayList<String>();
        groups.add("Ring0");
        context.setGroups(groups);
    }

}

ターゲットの評価オプション

オプションは、指定の TargetingFilter でターゲット設定評価がどのように実行されるかをカスタマイズするために使用します。 TargetingEvaluationOptions 作成中に、オプションのパラメータ TargetingFilter を設定できます。

    @Bean
    public TargetingFilter targetingFilter(MyTargetingContextAccessor contextAccessor) {
        return new TargetingFilter(contextAccessor, new TargetingEvaluationOptions().setIgnoreCase(true));
    }

構成の更新

構成の構成更新を有効にすると、アプリケーションを再起動しなくても、App Configuration ストアまたは複数のストアから最新の値をプルできます。

更新を有効にするには、監視トリガーと共に監視を有効にする必要があります。 監視トリガーは、更新をトリガーするために値の変更を確認するオプションのラベルが付けられたキーです。 更新が必要になったときに変更される限り、監視トリガーの値には任意の値を指定できます。

Note

監視トリガーの ETag を変更する操作は、コンテンツ タイプの変更などの更新を引き起こします。

spring:
  cloud:
    azure:
      appconfiguration:
        stores:
        - monitoring:
          enabled: true
          triggers:
          - key: [my-watched-key]
            label: [my-watched-label]

構成の更新をトリガーするには、構成ストアのキーの値を変更します。 次に、いずれかのウォッチ キーを新しい値に更新します。 この変更により、ログの作成がトリガーされます。 たとえば、/application/config.message トリガーの値を変更すると、次のログ メッセージが表示されます。

INFO 17496 --- [TaskScheduler-1] o.s.c.e.event.RefreshEventListener       : Refresh keys changed: [config.message]

アプリケーションはログを生成した後、更新スコープ内のすべての @Bean を更新します。

Note

デフォルトでは、@ConfigurationProperties 注釈付きBeans は、このスコープに含まれます。

プルベースの更新

App Configuration Spring ライブラリは、監視トリガーに加えられた変更の更新間隔で定期的にチェックする機能をサポートしています。 デフォルトの更新間隔は、30 秒です。 更新間隔が経過すると、すべてのトリガーが変更のために指定されたストアでチェックされます。 キーを変更すると、更新がトリガーされます。 ライブラリは Spring 更新システムと統合されるため、更新を行うと、すべてのストアのすべての構成が再読み込みされます。 更新間隔は、1 秒より長い任意の間隔に設定できます。 更新間隔でサポートされる単位は、smhdで、それぞれ、秒、分、時間、日です。 次の例では、間隔を 5 分に設定しています。

spring.cloud.azure.appconfiguration.stores[0].monitoring.refresh-interval= 5m

自動化

spring-cloud-azure-appconfiguration-config-web ライブラリを使用する際、サーブレット要求 (具体的には、ServletRequestHandledEvent) が発生するたびに、アプリケーションは、更新を自動チェックします。 このイベントが送信される最も一般的な方法は、@RestController のエンドポイントへの要求です。

手動

コンソール アプリケーションとして、spring-cloud-azure-appconfiguration-config のみを使用するアプリケーションでは、AppConfigurationRefreshrefreshConfiguration メソッドを呼び出すことで更新を手動でトリガーできます。 AppConfigurationRefresh は、任意の @Bean に居んジェクトできる @Component です。

また、ライブラリが Spring の構成システムを使用するため、更新をトリガーすると、Azure App Configuration ストアからの構成だけではなくすべての構成が更新されます。

プッシュベースの更新

Azure App Configuration ストアから、プッシュ通知を受信するように spring-cloud-azure-appconfiguration-config-web ライブラリを設定すると、構成値が更新されます。 この構成は、Azure Event Grid Web Hook を使用して設定できます。これは、指定されたキーに変更の通知を送信するように構成できます。 Spring Actuator ライブラリを依存関係として追加することで、App Configuration の更新エンドポイントを公開できます。 エンドポイントには、appconfiguration-refreshappconfiguration-refresh-bus があります。 これらのエンドポイントは、カウンターパート refreshrefresh-bus のように機能します。ここでは、アプリ構成エンドポイントは、受信時に強制的に構成するのではなく、更新間隔を期限切れにします。 refreshrefresh-bus は引き続き使用できますが、設定で応答が必要なため、Web Hook を使用して Azure Event Grid に直接接続できません。

appconfiguration-refresh プロパティは、更新間隔の有効期限を切ることで、次の更新チェック前に、残りの更新間隔は待機されません。 appconfiguration-refresh-busプロパティは、Azure Service Bus などの接続されたメッセージ サービスに通知を送信し、アプリケーションのすべてのインスタンスに通知して更新します。 どちらの場合も、更新間隔で完全に期限切れになるわけではありませんが、少量のジッターによって、オフになります。 このジッターにより、アプリケーションのすべてのインスタンスが同時更新されないようになります。

management.endpoints.web.exposure.include= appconfiguration-refresh, appconfiguration-refresh-bus

更新エンドポイントを公開するだけでなく、セキュリティに必要なクエリ パラメーターが追加されました。 デフォルトではトークン名または値は設定されませんが、次の例に示すように、エンドポイントを使用するにはトークン名または値のいずれかを設定する必要があります。

spring.cloud.azure.appconfiguration.stores[0].monitoring.push-notification.primary-token.name=[primary-token-name]
spring.cloud.azure.appconfiguration.stores[0].monitoring.push-notification.primary-token.secret=[primary-token-secret]
spring.cloud.azure.appconfiguration.stores[0].monitoring.push-notification.secondary-token.name=[secondary-token-name]
spring.cloud.azure.appconfiguration.stores[0].monitoring.push-notification.secondary-token.secret=[secondary-token-secret]

Web Hook の設定

Web Hook を設定するには、Azure App Configuration ストアを開き、[ナビゲーション] メニューで、[イベント] を開きます。 その後、[イベント サブスクリプション] を選択します。 イベントの名前を設定し、Web Hook となるエンドポイントの種類を選択します。 Web Hook を選択すると、[エンドポイント] オプションが表示されます。 [エンドポイントの選択] を選択します。 エンドポイントは https://www.myaplication.com/actuator/appconfiguration-refresh?myTokenName=mySecret のようになります。

[選択を確認] は、特定の URI にセットアップ通知を送信し、そこから応用が送信されることを想定します。 応答が返されない場合、セットアップは失敗します。 Azure App Configuration ストアがアプリケーションに構成されている場合、エンドポイントに設定された azure-spring-cloud-appconfiguration-web ライブラリは、正しい応答を返します。 この確認は、他の方法で送信できます。 Web Hook 配信の詳細については、「Web Hookイベント配信」を参照してください。

Note

この検証は、エンドポイントの作成または変更時にのみ行われます。

それ以外の場合は、キーの作成と変更のたびに更新がトリガーされるため、フィルターを設定することが強く推奨されます。

クライアントの強制更新

すべての構成を更新間隔に基づき、強制的に更新するようにライブラリを構成できます。 次の表は、refresh-interval プロパティについての説明です。

名前 説明 必要 Default
spring.cloud.azure.appconfiguration.refresh-interval 更新中の標準時間。 Duration か。 いいえ null

spring.cloud.azure.appconfiguration.refresh-interval で更新すると、構成済みウォッチ キーはチェックされません。 Azure App Configuration は、更新タイミングを判断できないため、このプロパティを使用して、Key Vault シークレットを最新の状態に保ちます。

Azure Key Vault は、シークレットとして、認定資格証の公開キーとプライベート キーの組み合わせを保管するため、アプリケーションは、App Configuration で Key Vault 参照として、認定資格証を取得します。 認定資格証は定期的にローテーションする必要があるため、クライアント アプリケーションもクライアント更新間隔に基づいて頻繁に更新する必要があります。

機能フラグの更新

機能フラグと監視の両方が有効になっている場合、機能フラグの更新間隔のデフォルト値は 30 秒に設定されます。 更新間隔が経過すると、指定ストア内のすべての機能フラグの変更が確認されます。 キーを変更すると、更新がトリガーされます。 ライブラリは Spring 更新システムと統合されるため、更新を行うと、すべてのストアのすべての構成が再読み込みされます。 更新間隔は、1 秒より長い任意の間隔に設定できます。 更新間隔でサポートされる単位は、smhdで、それぞれ、秒、分、時間、日です。 次の例では、間隔を 5 分に設定しています。

spring.cloud.azure.appconfiguration.stores[0].monitoring.feature-flag-refresh-interval= 5m

正常性インジケーター

クライアント ライブラリには、Azure App Configuration ストアまたは複数のストアへの接続が正常かどうかを確認する正常性インジケーターがあります。 ストアごとに有効にすると、次のいずれかの状態値が表示されます。

  • UP - 最後の接続が正常に行われました。
  • DOWN- 最後の接続の結果、200 以外のエラー コードが発生しました。 この状態は、資格情報の期限切れからサービスの問題までの問題が原因である可能性があります。 クライアント ライブラリは、次回の更新間隔でストアへの接続を自動的に再試行します。
  • NOT LOADED - 構成ストアはローカル構成ファイルに一覧表示されますが、起動時に構成ストアがファイルから読み込まれていませんでした。 構成ストアが構成ファイルで無効になっているか、fail-fastストアの構成が false に設定されている間、起動時に 1 つの構成または複数の構成を読み込めませんでした。

management.health.azure-app-configuration.enabled=true に設定すると、正常性インジケーターを有効化できます。

クライアントのカスタマイズ

App Configuration ライブラリは、Azure App Configuration と Azure Key Vault を接続するために、Azure SDK for Java を使用します。 クライアントを変更するために、ConfigurationClientCustomizerSecretClientCustomizer の 2 つのインターフェイスが提供されます。 各インターフェイスには、customize メソッドがあります。次のインターフェイス定義で示されているように、これは、各ビルダーとクライアントが構成する URI の String 値を受け取ります。?

public interface ConfigurationClientCustomizer {
    public void setup(ConfigurationClientBuilder builder, String endpoint);
}

public interface SecretClientCustomizer {
    public void setup(SecretClientBuilder builder, String endpoint);
}

これらのインターフェイスを使用すると、HTTP クライアントとその構成をカスタマイズできます。 次の例では、既定値 HttpClient を、App Configuration と Key Vault に送信されるすべてのトラフィックにプロキシを使用する別のものに置き換えます。

Note

ConfigurationClientBuilder に渡す際は、SecretClientBuildercustomize が既に使用用に設定されています。 資格情報や再試行ポリシーなど、クライアントに対する変更は、既に設定されている変更よりも優先されます。

Spring Cloud Azure 構成を使用しても、この構成を実行できます。

public class CustomClient implements ConfigurationClientCustomizer, SecretClientCustomizer {

    @Override
    public void customize(ConfigurationClientBuilder builder, String endpoint) {
        builder.httpClient(buildHttpClient());
    }

    @Override
    public void customize(SecretClientBuilder builder, String endpoint) {
        builder.httpClient(buildHttpClient());
    }

    private HttpClient buildHttpClient() {
        String hostname = System.getProperty("https.proxyHosts");
        String portString = System.getProperty("https.proxyPort");
        int port = Integer.valueOf(portString);

        ProxyOptions proxyOptions = new ProxyOptions(ProxyOptions.Type.HTTP,
                new InetSocketAddress(hostname, port));
        return new NettyAsyncHttpClientBuilder()
                .proxy(proxyOptions)
                .build();
    }

}