次の方法で共有


アプリ構成のサポート

この記事では、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>6.0.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>

次の例は、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);
    }
}

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

spring.config.import=azureAppConfiguration
spring.cloud.azure.appconfiguration.stores[0].endpoint=${CONFIG_STORE_ENDPOINT}

CONFIG_STORE_ENDPOINT は、Azure App Configuration Store へのエンドポイント URL を持つ環境変数です。

メモ

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

デフォルトでは、構成が設定されていない場合、/application/ で始まる構成は (No Label) のデフォルトラベルで読み込まれます。ただし、Spring Profile が設定されている場合は、デフォルトラベルがその Spring Profile になります。

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

構成の読み込み中

ライブラリは、1 つまたは複数の App Configuration ストアの読み込みをサポートします。 キーが複数のストア間で重複している状況では、最後のストアが優先されます。

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

この例では、両方のストアが同じ構成キーを持つ場合、2 番目のストアの構成の優先度が最も高くなります。

メモ

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

構成を選択する

ライブラリは、キーとラベルを使用して構成を読み込みます。 デフォルトでは、キー /application/ で始まる構成が読み込まれます。 既定のラベルは \0であり、Azure portal では (No Label) として表示されます。 Spring プロファイルが設定されていて、ラベルが指定されていない場合、既定のラベルは Spring Profile ( ${spring.profiles.active}) です。

読み込む構成を選択するには、さまざまなキー フィルターとラベル フィルターを選んで設定します。

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 プロパティは、次のフィルターをサポートします。

ラベル 説明
* \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 を使用していて、ラベルのない構成を読み込み、他のラベルを含む構成を増やす場合は、空の ,を含める必要があります。 たとえば、 ,dev\0devに一致します。 この場合は、ラベル フィルターを一重引用符で囲む必要があります。 この値を使用すると、最初にラベルのない構成を読み込み、次に特定のラベルを持つ構成を同じフィルターで読み込むことができます。

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

メモ

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

ラベル フィルターで * を使用し、同じキーを持つ複数の構成が読み込まれると、アルファベット順に読み込まれ、最後のラベルがアルファベット順に読み込まれます。

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では、ライブラリはまず、 \0 ラベルを持つすべての構成を読み込み、その後に Spring Profiles に一致するすべての構成を読み込みます。 終的な構成であるため、Spring Profiles は、\0 構成よりも優先されます。

2 番目の label-filterでは、文字列 _local は Spring Profiles の末尾に追加されますが、複数ある場合は最後の Spring Profile にのみ追加されます。

無効化されたストア

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

メモ

ヘルスメトリクスを使用している場合でも、ストアは一覧表示されますが、値はNOT LOADEDです。 読み込まれたプロパティ ソースを確認しても、一覧に表示されますが、値は含まれません。 この動作は、 spring.config.import プロパティが設定されていることが原因です。 azureAppConfigurationspring.config.importに設定されていない場合、値は表示されません。

認証

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

メモ

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 を使用して認証を行います。

構成の読み取りに使用する 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>

メモ

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

メモ

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

ジオレプリケーション

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

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

既定では、ライブラリは、構成ストアに存在するすべてのレプリカを自動検出します。 指定されたストアに対して要求が行われ、失敗すると、ライブラリは使用可能なレプリカに対して要求を自動的に再試行します。

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

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

指定されたストアがオンラインに戻ると、ライブラリは指定されたストアに対して要求を自動的に再試行します。

フェールオーバーの動作を制御する場合は、フェールオーバーに使用するストアの一覧を手動で指定できます。

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

又は

spring.cloud.azure.appconfiguration.stores[0].connection-strings[0]=[your primary store connection string]
spring.cloud.azure.appconfiguration.stores[0].connection-strings[1]=[your replica store connection string]

指定されたすべてのレプリカ エンドポイントが失敗した場合、ライブラリはプライマリ ストアの自動検出されたレプリカへの接続を試みます。

spring.cloud.azure.appconfiguration.stores[0].replica-discovery-enabled=false設定を使用してレプリケーションを無効にできます。

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

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

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

基幹価値

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

プレースホルダー

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

メモ

削除されるプレフィックスは値 spring.cloud.azure.appconfiguration.stores[0].selects[0].key-filterと一致します。 トリミングされるプレフィックスは、 spring.cloud.azure.appconfiguration.stores[0].trim-key-prefix[0]の値を設定することで変更できます。

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 に接続して値を取得します。

メモ

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 に接続する場合と同じ資格情報を使用できます。

独自の認証方法を提供するSecretClientCustomizerを作成するのと同じ方法でConfigurationClientCustomizerを作成することもできます。

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

App Configuration ライブラリは、キー ボールト参照のリゾルブをオーバーライドするメソッドを提供します。 たとえば、開発環境でシークレットをローカルに解決するために使用できます。 この解決策は、KeyVaultSecretProvider を介して完了します。 KeyVaultSecretProviderが指定されている場合は、すべてのキー ボールト参照で呼び出されます。 getSecretが null 以外の値を返す場合は、シークレット値として使用されます。 それ以外の場合、Key Vault 参照は正常に解決されます。

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 の依存関係を使用して、 機能ゲートなどの機能をさらに追加します。

既定では、\0と見なされる(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

機能管理の基本

機能フラグ

機能フラグは、機能を有効にするために使用される名前と機能フィルターの一覧を含む複数のパーツで構成されます。 機能フラグは、ブール値の状態をオンまたはオフにするか、機能フィルターの一覧を持つことができます。 機能フラグは、true が返されるまで、機能フィルターを評価します。 機能フィルターが true を返さない場合は、機能フィルターは false を返します。

機能フィルター

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

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

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

機能フラグの宣言

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

feature-management:
  feature_flags:
  - id: feature-t
    enabled: false
  - id: feature-u
    conditions:
      client_filters:
      - name: Random
  - id: feature-v
    conditions:
      client_filters:
      - name: TimeWindowFilter
        parameters:
          Start: "Wed, 01 May 2019 13:59:59 GMT"
          End: "Mon, 01 July 2019 00:00:00 GMT"

  - id: feature-w
    evaluate: false
    conditions:
      client_filters:
      - 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
}

メモ

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

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

名前 説明 必須 既定値
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 パッケージに付属する新しい機能フィルターがいくつかあります。 これらの機能フィルターは自動的に追加されます。

AlwaysOnフィルター

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

パーセンテージフィルター

チェックするたびに、 PercentageFilter の評価によって異なる結果が返される場合があります。 要求ごとに機能フラグの結果をキャッシュする FeatureManagementSnapshotを使用して、この不整合を回避できます。

feature-management:
  feature_flags:
  - name: feature-v
    conditions:
      client_filters:
      - name: PercentageFilter
        parameters:
          Value: 50

タイムウィンドウフィルター

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

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

このフィルターは、定期的な時間枠フィルターもサポートしています。 有効期限と共に、毎日と毎週の繰り返しの両方をサポートします。

feature-management:
  feature_flags:
  - name: feature-v
    conditions:
      client_filters:
      - name: TimeWindowFilter
        parameters:
          Start: "Mon, 01 July 2019 00:00:00 GMT"
          End: "Mon, 01 July 2019 12:00:00 GMT"
          Recurrence:
            Pattern:
              Type: Weekly
              Interval: 1
              FirstDayOfWeek: Sunday
              DaysOfWeek:
              - Monday
              - Wednesday

この繰り返しパターンは、毎週月曜日と水曜日の 00:00:00 GMT から 12:00:00 GMT に発生し、有効期限はありません。

feature-management:
  feature_flags:
  - name: feature-v
    conditions:
      client_filters:
      - name: TimeWindowFilter
        parameters:
          Start: "Mon, 01 July 2019 00:00:00 GMT"
          End: "Mon, 01 July 2019 12:00:00 GMT"
          Recurrence:
            Pattern:
              Type: Daily
              Interval: 2
            Range:
              Type: EndDate
              EndDate: "Fri, 15 Aug 2025 07:00:00 GMT"

この繰り返しパターンは、1 日おきに 00:00:00 GMT から 12:00:00 GMT から終了日まで発生します。

ターゲティングフィルター

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

  • ユーザーは、ユーザーのセクションで直接指定されます。
  • ユーザーは、任意のグループ ロールアウトの含まれる割合内にあります。
  • ユーザーは、デフォルトの展開割合に当てはまります。
feature-management:
  feature_flags:
  - name: target
    conditions:
      client_filters:
      - 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 という Map<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 configureTargetingContext(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 ストアまたは複数のストアから最新の値をプルできます。

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

メモ

監視トリガーの 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 を更新します。

メモ

デフォルトでは、@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の 2 つがあります。 これらのエンドポイントは、対応する refreshrefresh-busと同様に機能します。アプリ構成エンドポイントは、受信時に強制的に更新するのではなく、更新間隔を期限切れにします。 refreshrefresh-busは引き続き使用できますが、Web フックを使用して 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イベント配信」を参照してください。

メモ

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

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

クライアントの強制更新

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

名前 説明 必須 既定値
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 に設定されている上に起動時に構成の読み込みに失敗しました。

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

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

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

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

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

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

メモ

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();
    }

}