Partager via


Prise en charge de la configuration des applications

Cet article décrit la bibliothèque Spring Cloud Azure App Configuration. Cette bibliothèque charge les configurations et les indicateurs de fonctionnalité à partir du service Azure App Configuration. La bibliothèque génère des PropertySource abstractions pour correspondre aux abstractions déjà générées par l’environnement Spring, telles que les variables d’environnement, les configurations de ligne de commande, les fichiers de configuration locaux, etc.

Spring est un framework d’application open source développé par VMware qui fournit une approche simplifiée et modulaire pour créer des applications Java. Azure Spring Cloud est un projet open source qui fournit une intégration de Spring fluide aux services Azure.

Prérequis

Mise en place de votre application Configuration store

Utilisez la commande suivante pour créer votre magasin Azure App Configuration :

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

Cette commande crée un nouveau magasin de configuration vide. Vous pouvez charger vos configurations à l’aide de la commande d’importation suivante :

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

Vérifiez vos configurations avant de les charger. Vous pouvez charger des fichiers YAML en modifiant le format en YAML. Le champ de préfixe est important, car il s’agit du préfixe par défaut chargé par la bibliothèque cliente.

Utilisation de la bibliothèque

Pour utiliser la fonctionnalité dans une application, vous pouvez la générer en tant qu’application Spring Boot. Le moyen le plus pratique d’ajouter la dépendance est avec le starter Spring Boot com.azure.spring:spring-cloud-azure-starter-appconfiguration-config. L’exemple suivant pom.xml fichier utilise 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>

L’exemple suivant montre une application Spring Boot de base à l’aide d’App Configuration :

@SpringBootApplication
@RestController
public class Application {

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

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

Pour cet exemple, le fichier application.properties contient la ligne suivante :

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

CONFIG_STORE_ENDPOINT est une variable d’environnement avec l’URL du point de terminaison de votre Magasin Azure App Configuration.

Remarque

Microsoft vous recommande d’utiliser le flux d’authentification le plus sécurisé disponible. Le flux d’authentification décrit dans cette procédure, par exemple pour les bases de données, les caches, la messagerie ou les services IA, nécessite un niveau de confiance très élevé dans l’application et comporte des risques non présents dans d’autres flux. Utilisez ce flux uniquement lorsque des options plus sécurisées, telles que les identités managées pour les connexions sans mot de passe ou sans clé, ne sont pas viables. Pour les opérations d’ordinateur local, préférez les identités utilisateur pour les connexions sans mot de passe ou sans clé.

Par défaut, si aucune configuration n’est définie, les configurations commençant /application/ par sont chargées avec une étiquette par défaut, (No Label) sauf si un profil Spring est défini, auquel cas l’étiquette par défaut est votre profil Spring.

Une source de propriété nommée /application/https://<name-of-your-store>.azconfig.io/ est créée contenant les propriétés de ce magasin. L’étiquette utilisée dans la requête est ajoutée à la fin du nom. Si aucune étiquette n’est définie, le caractère \0 est présent sous la forme d’un espace vide.

Chargement de la configuration

La bibliothèque prend en charge le chargement d'un ou de plusieurs magasins de configuration d'applications. Dans le cas où une clé est dupliquée sur plusieurs magasins, la dernière gagne.

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

Dans cet exemple, si les deux magasins ont la même clé de configuration, la configuration du deuxième magasin a la priorité la plus élevée.

Remarque

Vous pouvez utiliser les paramètres Azure App Configuration comme n’importe quelle autre configuration Spring. Pour plus d’informations, consultez Les fonctionnalités principales de la documentation Spring Boot ou du guide de démarrage rapide : Créer une application Spring Java avec Azure App Configuration.

Sélection de configurations

La bibliothèque charge les configurations à l’aide de leur clé et de leur étiquette. Par défaut, les configurations qui commencent par la clé /application/ sont chargées. L’étiquette par défaut est \0, qui apparaît comme (No Label) dans le portail Azure. Si un profil Spring est défini et qu’aucune étiquette n’est fournie, l’étiquette par défaut est votre profil Spring, qui est ${spring.profiles.active}.

Vous pouvez configurer les configurations chargées en sélectionnant différentes filtres de clé et d’étiquette :

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

La key-filter propriété prend en charge les filtres suivants :

Filtre principal Résultat
* Correspond à n’importe quelle clé.
abc Correspond à une clé nommée abc.
abc* Correspond aux noms de clés qui commencent par abc.
abc,xyz Correspond aux noms de clés abc ou xyz. Limité à cinq valeurs séparées par des virgules.

La label-filter propriété prend en charge les filtres suivants :

Étiquette Descriptif
* Correspond à n’importe quelle étiquette, y compris \0.
\0 Correspond aux null étiquettes, qui apparaissent comme (No Label) dans le Portail Azure.
1.0.0 Correspond exactement à l’étiquette 1.0.0.
1.0.* Correspond aux étiquettes qui commencent par 1.0.*.
,1.0.0 Correspond aux étiquettes null et 1.0.0. Limité à cinq valeurs séparées par des virgules.

Si vous utilisez YAML avec des filtres d’étiquettes et que vous souhaitez charger des configurations sans étiquette et d’autres configurations avec d’autres étiquettes, vous devez inclure un élément vide ,. Par exemple, ,dev correspondances \0 et dev. Dans ce cas, entourez le filtre d’étiquette avec des guillemets simples. Cette valeur vous permet de charger la configuration sans étiquette en premier, suivie de configurations avec des étiquettes spécifiques, dans le même filtre :

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

Remarque

Vous ne pouvez pas les combiner *, dans les filtres. Dans ce cas, vous devez utiliser une valeur de sélection supplémentaire.

Lorsque vous utilisez * le filtre d’étiquette et que plusieurs configurations avec la même clé sont chargées, elles sont chargées par ordre alphabétique, et l’étiquette la dernière dans l’ordre alphabétique est utilisée.

Profils de Spring

Par défaut, spring.profiles.active est défini comme valeur par défaut label-filter pour toutes les configurations sélectionnées. Vous pouvez remplacer cette fonctionnalité à l’aide de label-filter. Vous pouvez utiliser les profils Spring dans le label-filter en utilisant ${spring.profiles.active}, comme illustré dans l'exemple suivant :

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

Dans le premier, la bibliothèque charge d’abord label-filtertoutes les configurations avec l’étiquette \0 , suivie de toutes les configurations correspondant aux profils Spring. Les profils Spring ont la priorité sur les \0 configurations, car ils arrivent en dernier.

Dans la deuxième label-filter, la chaîne _local est ajoutée à la fin des profils Spring, mais uniquement au dernier Spring Profile s’il y en a plusieurs.

Magasins désactivés

En utilisant la configuration spring.cloud.azure.appconfiguration.enabled, vous pouvez désactiver le chargement de tous les magasins de configuration. Avec la spring.cloud.azure.appconfiguration.stores[0].enabled configuration, vous pouvez désactiver un magasin individuel.

Remarque

Si vous utilisez des métriques de santé, vous verrez toujours vos magasins répertoriés, mais avec la valeur NOT LOADED. Lorsque vous vérifiez les sources de propriétés déjà chargées, vous les voyez toujours répertoriées, mais elles ne contiennent aucune valeur. Ce comportement est dû à la définition de la spring.config.import propriété. Si azureAppConfiguration n’est pas définie pour spring.config.import, aucune valeur n’est affichée.

Authentification

La bibliothèque prend en charge toutes les formes d’identité prises en charge par la bibliothèque d’identités Azure. Vous pouvez effectuer l’authentification par le biais de la configuration des chaîne de connexion et de l’identité managée.

Remarque

Microsoft vous recommande d’utiliser le flux d’authentification le plus sécurisé disponible. Le flux d’authentification décrit dans cette procédure, par exemple pour les bases de données, les caches, la messagerie ou les services IA, nécessite un niveau de confiance très élevé dans l’application et comporte des risques non présents dans d’autres flux. Utilisez ce flux uniquement lorsque des options plus sécurisées, telles que les identités managées pour les connexions sans mot de passe ou sans clé, ne sont pas viables. Pour les opérations d’ordinateur local, préférez les identités utilisateur pour les connexions sans mot de passe ou sans clé.

L’authentification par le biais de la chaîne de connexion est le formulaire le plus simple à configurer, même s’il n’est pas recommandé. Vous pouvez accéder aux chaîne de connexion d’un magasin à l’aide de la commande suivante :

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

Vous pouvez ensuite définir la spring.cloud.azure.appconfiguration.stores[0].connection-string propriété sur la chaîne de connexion. Lorsque vous utilisez cette approche, nous vous recommandons vivement de définir la chaîne de connexion dans le fichier de configuration local sur une valeur d’espace réservé qui est mappée à une variable d’environnement. Cette approche vous permet d’éviter d’ajouter les chaînes de connexion à la gestion de code source.

Configuration de Spring Cloud Azure

Vous pouvez utiliser la configuration d’Azure Spring Cloud pour configurer la bibliothèque. Vous pouvez utiliser les propriétés suivantes pour configurer la bibliothèque :

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

Quand seul le point de terminaison est défini, la bibliothèque cliente utilise DefaultAzureCredential pour s’authentifier.

Vous devez affecter l’identité utilisée pour lire les configurations. Vous pouvez créer cette affectation à l’aide de la commande suivante :

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>

Remarque

Vous ne pouvez définir qu’une seule méthode d’authentification par point de terminaison : chaîne de connexion, identité affectée par l’utilisateur ou informations d’identification de jeton. Si vous avez besoin de combiner et de faire correspondre, vous pouvez l’utiliser pour modifier l’utilisation ConfigurationClientCustomizerConfigurationClientBuilder de différentes méthodes.

Remarque

Microsoft vous recommande d’utiliser le flux d’authentification le plus sécurisé disponible. Le flux d’authentification décrit dans cette procédure, par exemple pour les bases de données, les caches, la messagerie ou les services IA, nécessite un niveau de confiance très élevé dans l’application et comporte des risques non présents dans d’autres flux. Utilisez ce flux uniquement lorsque des options plus sécurisées, telles que les identités managées pour les connexions sans mot de passe ou sans clé, ne sont pas viables. Pour les opérations d’ordinateur local, préférez les identités utilisateur pour les connexions sans mot de passe ou sans clé.

Géoréplication

La bibliothèque prend en charge la fonctionnalité de géoréplication d’Azure App Configuration. Cette fonctionnalité vous permet de répliquer vos données vers d’autres emplacements. Cette fonctionnalité est utile pour la haute disponibilité et la récupération d’urgence.

Chaque réplica que vous créez a un point de terminaison dédié. Si votre application réside dans plusieurs géolocalisations, vous pouvez mettre à jour chaque déploiement de votre application dans un emplacement pour vous connecter au réplica le plus proche de cet emplacement, ce qui permet de réduire la latence réseau entre votre application et App Configuration. Étant donné que chaque réplica a son quota de requêtes distinct, cette configuration permet également l’extensibilité de votre application alors qu’elle augmente vers un service distribué multirégion.

Par défaut, la bibliothèque découvre automatiquement tous les réplicas qui existent pour un magasin de configuration. Lorsqu’une demande est envoyée au magasin fourni et échoue, la bibliothèque retente automatiquement la requête sur les réplicas disponibles.

Le basculement peut se produire si la bibliothèque observe l’une des conditions suivantes :

  • Reçoit des réponses avec le code d'état de service indisponible (HTTP 500 ou supérieur) depuis un point de terminaison.
  • Elle rencontre des problèmes de connectivité réseau.
  • Les requêtes sont limitées (code d’état HTTP 429)

Une fois que le magasin fourni est revenu en ligne, la bibliothèque retente automatiquement la demande sur le magasin fourni.

Si vous souhaitez contrôler le comportement de basculement, vous pouvez fournir manuellement une liste de magasins à utiliser pour le basculement.

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

ou

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]

Si tous les points de terminaison de réplica fournis échouent, la bibliothèque tente de se connecter aux réplicas détectés automatiquement du magasin principal.

Vous pouvez désactiver la réplication avec le paramètre spring.cloud.azure.appconfiguration.stores[0].replica-discovery-enabled=false.

Création d'un magasin de configuration avec géo-réplication

Pour créer un réplica de votre magasin de configuration, vous pouvez utiliser Azure CLI ou le Portail Azure. L’exemple suivant utilise l'Azure CLI pour créer une réplique dans la région de l’Est des États-Unis 2 :

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

Valeurs de clé

Azure App Configuration prend en charge plusieurs types de valeurs clés, dont certaines ont des fonctionnalités spéciales intégrées. Azure App Configuration prend en charge le type de contenu JSON, les variables de substitution Spring et les références au Key Vault.

Espaces réservés

La bibliothèque prend en charge les configurations avec des espaces réservés d'environnement de type ${} Lorsque vous référencez une clé Azure App Configuration avec un espace réservé, supprimez les préfixes de la référence. Par exemple, /application/config.message est référencé en tant que ${config.message}.

Remarque

Le préfixe en cours de suppression correspond à la valeur spring.cloud.azure.appconfiguration.stores[0].selects[0].key-filter. Le préfixe en cours de découpage peut être modifié en définissant une valeur pour spring.cloud.azure.appconfiguration.stores[0].trim-key-prefix[0].

JSON

Les configurations qui ont un type application/json de contenu sont traitées en tant qu’objets JSON. Cette fonctionnalité vous permet de mapper une configuration à un objet complexe à l’intérieur d’un @ConfigurationProperties. Par exemple, considérez la clé /application/config.colors JSON avec la valeur suivante :

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

Cette clé correspond au code suivant :

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

    private Map<String, Color> colors;

}

Références Key Vault

Azure App Configuration et ses bibliothèques prennent en charge le référencement des secrets stockés dans Key Vault. Dans App Configuration, vous pouvez créer des clés avec des valeurs qui mappent aux secrets stockés dans un coffre de clés. Les secrets restent sécurisés dans Key Vault, mais vous pouvez y accéder de la même façon que toute autre configuration lors du chargement de l’application.

Votre application utilise le fournisseur client pour récupérer les références Key Vault, tout comme pour les autres clés stockées dans App Configuration. Étant donné que le client reconnaît les clés en tant que références Key Vault, ils ont un type de contenu unique et le client se connecte à Key Vault pour récupérer leurs valeurs pour vous.

Remarque

Key Vault ne permet de récupérer qu'un seul secret à la fois, de sorte que chaque référence à Key Vault stockée dans App Configuration entraîne un appel à Key Vault.

Créer des références Key Vault

Vous pouvez créer une référence Key Vault dans le portail Azure en accédant à Explorateur de configuration>Créer>référence Key Vault. Vous pouvez ensuite sélectionner un secret à référencer parmi les coffres de clés auquel vous avez accès. Vous pouvez également créer des références arbitraires de coffre de clés à partir de l’onglet Entrée. Dans le portail Azure, entrez un URI valide.

Vous pouvez également créer une référence Key Vault via Azure CLI à l’aide de la commande suivante :

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

Vous pouvez créer n’importe quel identificateur secret via Azure CLI. Les identificateurs de secret nécessitent simplement le format {vault}/{collection}/{name}/{version?} dans lequel la section de version est facultative.

Utiliser les références de "Key Vault"

Vous pouvez utiliser la configuration d’Azure Spring Cloud pour configurer la bibliothèque. Vous pouvez utiliser les mêmes informations d’identification que celles utilisées pour vous connecter à App Configuration pour vous connecter à Azure Key Vault.

Vous pouvez également créer la SecretClientCustomizer même façon que vous le ConfigurationClientCustomizer feriez pour fournir votre propre méthode d’authentification.

Résoudre les secrets non Key Vault

La bibliothèque App Configuration fournit une méthode pour remplacer la résolution des références de coffre de clés. Par exemple, vous pouvez l’utiliser pour résoudre localement les secrets dans un environnement de développement. Cette résolution est effectuée par le biais du KeyVaultSecretProvider. Le KeyVaultSecretProviderfichier , s’il est fourni, est appelé sur chaque référence de coffre de clés. Si getSecret elle retourne une valeur non null, elle est utilisée comme valeur secrète. Sinon, la référence key vault est résolue normalement.

public class MySecretProvider implements KeyVaultSecretProvider {

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

}

Gestion des fonctionnalités

La gestion des fonctionnalités permet aux applications Spring Boot d’accéder dynamiquement au contenu. La gestion des fonctionnalités a différentes fonctions, telles que les suivantes :

  • Indicateurs de fonctionnalité qui peuvent activer ou désactiver le contenu
  • Filtres de fonctionnalités pour le ciblage lorsque le contenu est affiché
  • Filtres de fonctionnalités personnalisés
  • Indicateurs de fonctionnalités pour l'activation dynamique des points de terminaison

Vous pouvez activer les indicateurs de fonctionnalité via la configuration suivante :

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

Les indicateurs de fonctionnalité activés sont chargés dans le système de configuration Spring avec le préfixe feature-management. Vous pouvez également inscrire des indicateurs de fonctionnalité dans le fichier de configuration local. Pour plus d’informations, consultez la section Déclaration de l’indicateur de fonction.

Le moyen le plus simple d’utiliser la gestion des fonctionnalités est d'utiliser les bibliothèques spring-cloud-azure-feature-management et spring-cloud-azure-feature-management-web. La différence entre les deux bibliothèques est que spring-cloud-azure-feature-management-web utilise une dépendance sur les bibliothèques spring-web et spring-webmvc pour ajouter d'autres fonctionnalités, telles que les portes de fonctionnalité.

Par défaut, tous les indicateurs de fonctionnalité avec une \0 étiquette, vus comme (No Label), sont chargés. Vous pouvez configurer les indicateurs de fonctionnalité chargés en définissant un filtre d’étiquette, comme illustré dans l’exemple suivant :

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

Principes de base de la gestion des fonctionnalités

Indicateurs de fonctionnalités

Les indicateurs de fonctionnalité sont composés de plusieurs parties, y compris un nom et une liste de filtres de fonctionnalités utilisés pour activer la fonctionnalité. Les indicateurs de fonctionnalité peuvent avoir un état booléen activé ou désactivé, ou avoir une liste de filtres de fonctionnalités. Les indicateurs de fonctionnalité évaluent les filtres de fonctionnalités jusqu’à ce qu’une valeur soit retournée true. Si aucun filtre de fonctionnalité n’est retourné true, l’indicateur de fonctionnalité retourne false.

Filtres de fonctionnalités

Les filtres de fonctionnalités définissent un scénario pour lequel une fonctionnalité doit être activée. Les filtres de fonctionnalités sont évalués de façon synchrone.

La bibliothèque de gestion des fonctionnalités est fournie avec quatre filtres prédéfinis : AlwaysOnFilter, PercentageFilter, TimeWindowFilter et TargetingFilter.

Vous pouvez créer des filtres de fonctionnalités personnalisés. Par exemple, vous pouvez utiliser un filtre de fonctionnalités pour fournir une expérience personnalisée aux clients qui utilisent un navigateur Microsoft Edge. Vous pouvez personnaliser les fonctionnalités de ce filtre de fonctionnalités, par exemple, pour afficher un en-tête spécifique pour l’audience du navigateur Microsoft Edge.

Déclaration d’indicateur de fonctionnalité

La bibliothèque de gestion des fonctionnalités prend en charge Azure App Configuration avec application.yml ou application.properties comme sources pour les indicateurs de fonctionnalité. Voici un exemple du format utilisé pour configurer des indicateurs de fonctionnalité dans un fichier 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

Cet exemple présente les indicateurs de fonctionnalité suivants :

  • feature-t est défini sur false. Ce paramètre retourne toujours la valeur de l’indicateur de fonctionnalité.
  • feature-u est utilisé avec des filtres de fonctionnalités. Ces filtres sont définis sous la enabled-for propriété. Dans ce cas, feature-u dispose d’un filtre de fonctionnalité appelé Random, qui ne nécessite aucune configuration, de sorte que seule la propriété de nom est requise.
  • feature-v spécifie un filtre de fonctionnalités nommé TimeWindowFilter. Ce filtre de fonctionnalités peut recevoir des paramètres à utiliser comme configuration. Dans cet exemple, un TimeWindowFilter, passe les heures de début et de fin pendant lesquelles la fonctionnalité est active.
  • feature-w est utilisé pour le AlwaysOnFilter, qui prend toujours la valeur true. Le champ evaluate est utilisé pour arrêter l’évaluation des filtres de fonctionnalités, ce qui fait que le filtre de fonctionnalités renvoie toujours false.

Évaluation des indicateurs de fonctionnalité

La spring-cloud-azure-feature-management bibliothèque fournit FeatureManager pour déterminer si un indicateur de fonctionnalité est activé. FeatureManager fournit un moyen asynchrone de vérifier l’état de l’indicateur.

spring-cloud-azure-feature-management-web, ainsi que la fourniture de FeatureManager, contient FeatureManagerSnapshot, qui met en cache l’état des indicateurs de fonctionnalités précédemment évalués dans @RequestScope pour garantir que toutes les requêtes retournent la même valeur. En outre, la bibliothèque web fournit @FeatureGate, qui peut bloquer ou rediriger des requêtes web vers différents points de terminaison.

Vérification d’indicateur de fonctionnalité

FeatureManager est un @Bean qui peut être @Autowired ou injecté dans des objets de type @Component. FeatureManager a une méthode isEnabled qui, lorsqu’elle a passé le nom d’un indicateur de fonctionnalité, retourne son état.

@Autowired
FeatureManager featureManager;

...

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

Remarque

FeatureManager possède également une version asynchrone appelée isEnabledisEnabledAsync.

Sans configuration de gestion des fonctionnalités ou lorsque l’indicateur de fonctionnalité n’existe pas, isEnabled retourne falsetoujours . Si un indicateur de fonctionnalité existant est configuré avec un filtre de fonctionnalité inconnu, un FilterNotFoundException est généré. Vous pouvez modifier ce comportement pour revenir false en configurant fail-fast sur false. Le tableau suivant décrit fail-fast:

Nom Descriptif Obligatoire Par défaut
spring.cloud.azure.feature.management.fail-fast Si une exception se produit, un RuntimeException est généré. Si cette propriété est définie sur false, alors isEnabled retourne false à la place. Non true

La seule différence entre FeatureManagerSnapshot et FeatureManager est la mise en cache des résultats dans le @RequestScope.

Porte de fonctionnalité

Avec la bibliothèque web de gestion des fonctionnalités, vous pouvez exiger qu’une fonctionnalité donnée soit activée pour exécuter un point de terminaison. Vous pouvez configurer cette exigence à l’aide de l’annotation @FeatureGate , comme illustré dans l’exemple suivant :

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

Vous ne pouvez accéder au featureT point de terminaison que si « feature-t » est activé.

Gestion des actions désactivées

Lorsqu’un point de terminaison est bloqué, car la fonctionnalité spécifiée est désactivée, DisabledFeaturesHandler est appelée. Par défaut, un HTTP 404 est retourné. Vous pouvez remplacer ce comportement en implémentant DisabledFeaturesHandler, comme illustré dans l’exemple suivant :

@Component
public class MyDisabledFeaturesHandler implements DisabledFeaturesHandler {

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

}
Routage

Certains itinéraires peuvent exposer les fonctionnalités d’application qui sont contrôlées par les fonctionnalités. Si une fonctionnalité est désactivée, vous pouvez rediriger ces itinéraires vers un autre point de terminaison, comme illustré dans l’exemple suivant :

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

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

Filtres de fonctionnalités intégrés

Il existe quelques filtres de fonctionnalités fournis avec le spring-cloud-azure-feature-management package. Ces filtres de fonctionnalités sont ajoutés automatiquement.

AlwaysOnFilter

Ce filtre retourne toujours true. Pour un exemple d'utilisation, reportez-vous à la section relative à la déclaration de l'indicateur de fonctionnalité.

Filtre en pourcentage

Chaque fois qu’elle est vérifiée, l’évaluation PercentageFilter peut retourner un résultat différent. Vous pouvez contourner cette incohérence à l’aide du FeatureManagementSnapshot, qui met en cache le résultat de l’indicateur de fonctionnalité par requête.

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

TimeWindowFilter

Ce filtre permet d’activer une fonctionnalité en fonction d’une fenêtre de temps. Si vous spécifiez uniquement End, la fonctionnalité est considérée comme activée jusqu’à ce moment. Si vous spécifiez uniquement Start, la fonctionnalité est considérée comme activée à partir de ce moment. Si vous spécifiez les deux, la fonctionnalité est considérée comme valide entre les deux fois.

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"

Ce filtre prend également en charge les filtres de fenêtre de temps périodiques. Il prend en charge les périodicités quotidiennes et hebdomadaires, ainsi qu’un délai d’expiration.

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

Ce modèle de périodicité se produit chaque semaine le lundi et le mercredi de 00:00:00 GMT à 12:00:00 GMT et n’expire pas.

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"

Ce modèle de périodicité se produit tous les autres jours de 00:00:00 GMT à 12:00:00 GMT jusqu’à la date de fin.

Filtre de ciblage

Ce filtre permet d’activer une fonctionnalité pour un public cible. Pour une explication approfondie du ciblage, consultez la section ciblage. Les paramètres de filtre incluent un objet d’audience qui décrit les utilisateurs, les groupes et un pourcentage par défaut de la base d’utilisateurs qui doit avoir accès à la fonctionnalité. Pour chaque objet de groupe répertorié dans l’audience cible, un pourcentage est requis qui définit le pourcentage des membres de ce groupe ayant accès à la fonctionnalité. Un utilisateur dispose de la fonctionnalité activée dans les cas suivants :

  • L’utilisateur est spécifié directement dans la section des utilisateurs.
  • L'utilisateur fait partie du pourcentage inclus dans l'un des déploiements de groupe.
  • L’utilisateur tombe dans le pourcentage de déploiement par défaut.
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

Filtres de fonctionnalités personnalisés

La création d’un filtre de fonctionnalités personnalisé permet d’activer les fonctionnalités en fonction des critères que vous définissez. Pour créer un filtre de fonctionnalités personnalisé, vous devez implémenter l’interface FeatureFilter . FeatureFilter a une seule méthode evaluate. Lorsqu’une fonctionnalité spécifie qu’elle peut être activée avec un filtre de fonctionnalités, la evaluate méthode est appelée. Si evaluate retourne true, cela signifie que la fonctionnalité doit être activée. S'il renvoie false, il continue d'évaluer les filtres de fonctionnalités jusqu'à ce que l'un d'entre eux renvoie true. Si tous les filtres retournent false, la fonctionnalité est désactivée.

Les filtres de fonctionnalités sont définis en tant que Spring Beans, de sorte qu’ils sont définis comme @Component ou définis dans un @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;
    }

}

Filtres de fonctionnalités paramétrables

Certains filtres de fonctionnalités nécessitent des paramètres pour déterminer si une fonctionnalité doit être activée. Par exemple, un filtre de fonctionnalités de navigateur peut activer une fonctionnalité pour un certain ensemble de navigateurs. Vous souhaiterez peut-être qu’une fonctionnalité soit activée pour les navigateurs Microsoft Edge et Chrome, mais pas Firefox. Pour configurer cette situation, vous pouvez concevoir un filtre de fonctionnalités pour attendre des paramètres. Ces paramètres sont spécifiés dans la configuration des fonctionnalités et dans le code, et sont accessibles via le FeatureFilterEvaluationContext paramètre de evaluate. FeatureFilterEvaluationContext a une propriété parameters, qui est un Map<String, Object>.

Ciblage

Le ciblage est une stratégie de gestion des fonctionnalités qui permet aux développeurs de déployer progressivement de nouvelles fonctionnalités sur leur base d’utilisateurs. La stratégie repose sur le concept de ciblage d’un ensemble d’utilisateurs appelés public cible. Un public est constitué d’utilisateurs, de groupes spécifiques et d’un pourcentage désigné de l’ensemble de la base d’utilisateurs. Les groupes inclus dans le public peuvent être divisés en pourcentages de leurs membres totaux.

Les étapes suivantes illustrent un exemple de déploiement progressif d’une nouvelle fonctionnalité « Bêta » :

  1. Les utilisateurs individuels Jeff et Alicia ont accès à la version bêta.
  2. Un autre utilisateur, Mark, demande à participer et est inclus.
  3. Vingt pour cent d’un groupe appelé utilisateurs « Ring1 » sont inclus dans la version Bêta.
  4. Le nombre d’utilisateurs « Ring1 » inclus dans la version bêta est passé à 100 %.
  5. Cinq pour cent de la base d’utilisateurs sont inclus dans la version Bêta.
  6. Le pourcentage de déploiement est passé à 100 % et la fonctionnalité est entièrement déployée.

Cette stratégie de déploiement d’une fonctionnalité est intégrée à la bibliothèque via le filtre de fonctionnalités inclus TargetingFilter .

Ciblage dans une application

Un exemple d’application web qui utilise le filtre de fonctionnalités de ciblage est disponible dans l’exemple de projet.

Pour commencer à utiliser le TargetingFilter dans une application, vous devez l'ajouter en tant que @Bean, comme tout autre filtre de fonctionnalité. TargetingFilter s'appuie sur un autre @Bean pour être ajouté à l'application TargetingContextAccessor. Le TargetingContextAccessor permet de définir l'actuel TargetingContext à utiliser pour définir l'ID d'utilisateur et les groupes actuels, comme illustré dans l'exemple suivant :

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

}

Options de ciblage pour l'évaluation

Les options sont disponibles pour personnaliser la façon dont l’évaluation du ciblage est effectuée dans un ensemble donné TargetingFilter. Vous pouvez définir un paramètre facultatif, TargetingEvaluationOptionspendant la TargetingFilter création.

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

Actualisation de la configuration

Activer l'actualisation des configurations vous permet de récupérer les versions les plus récentes de vos configurations à partir de votre ou de vos magasins App Configuration sans avoir à redémarrer l'application.

Pour activer l'actualisation, il est nécessaire d'activer la surveillance ainsi que ses déclencheurs. Un déclencheur d’analyse est une clé avec une étiquette facultative que le système surveille pour les modifications de valeur pour déclencher des mises à jour. La valeur du déclencheur de surveillance peut être n’importe quelle valeur, tant qu’elle change lorsqu’une actualisation est nécessaire.

Remarque

Toute opération qui modifie l’ETag d’un déclencheur de surveillance provoque une actualisation, telle qu’une modification de type de contenu.

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

Pour déclencher une actualisation de la configuration, modifiez la valeur d’une clé dans votre magasin de configuration. Ensuite, mettez à jour l'une des clés de surveillance avec une nouvelle valeur. Cette modification déclenche la création d’un journal. Par exemple, la modification de la valeur de /application/config.message déclenche le message de journalisation suivant :

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

Après que l'application a généré le journal, elle actualise tous les @Bean dans la portée d'actualisation.

Remarque

Par défaut, @ConfigurationProperties les haricots annotés sont inclus dans cette étendue.

Actualisation basée sur la traction

Les bibliothèques Spring App Configuration prennent en charge la possibilité de vérifier régulièrement l’intervalle d’actualisation des modifications apportées aux déclencheurs de surveillance. Par défaut, l’intervalle d’actualisation est défini sur 30 secondes. Une fois l’intervalle d’actualisation passé, lorsqu’une tentative d’actualisation est effectuée, tous les déclencheurs sont archivés dans le magasin donné pour les modifications. Toute modification de la clé entraîne le déclenchement d'une gâchette d'actualisation. Étant donné que les bibliothèques s’intègrent au système d’actualisation Spring, toutes les actualisations rechargent toutes les configurations de tous les magasins. Vous pouvez définir l’intervalle d’actualisation sur un intervalle de plus de 1 seconde. Les unités prises en charge pour l’intervalle d’actualisation sont s, met hd pour les secondes, les minutes, les heures et les jours respectivement. L’exemple suivant définit l’intervalle d’actualisation sur 5 minutes :

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

Automatisé

Lorsque vous utilisez la spring-cloud-azure-appconfiguration-config-web bibliothèque, l’application recherche automatiquement une actualisation chaque fois qu’une demande servlet se produit, en particulier ServletRequestHandledEvent. La façon la plus courante d’envoyer cet événement est par des demandes adressées aux points de terminaison dans un @RestController.

Manuel

Dans les applications qui utilisent uniquement spring-cloud-azure-appconfiguration-config, telles que les applications console, vous pouvez déclencher manuellement une actualisation en appelant la méthode AppConfigurationRefresh de refreshConfiguration. AppConfigurationRefresh est un @Bean que vous pouvez injecter dans n’importe quel @Component.

En outre, étant donné que la bibliothèque utilise le système de configuration de Spring, le déclenchement d’une actualisation entraîne une actualisation de toutes vos configurations, pas seulement un rechargement des configurations à partir de votre magasin Azure App Configuration.

Remarque

Cette méthode n’est plus recommandée, mais elle est toujours prise en charge.

Vous pouvez configurer la spring-cloud-azure-appconfiguration-config-web bibliothèque pour recevoir des notifications Push de votre magasin Azure App Configuration pour actualiser vos valeurs de configuration. Vous pouvez configurer cette configuration via un Web Hook Azure Event Grid, que vous pouvez configurer pour envoyer des notifications de modifications à des clés spécifiées. En ajoutant la bibliothèque Spring Actuator en tant que dépendance, vous pouvez exposer les points de terminaison d’actualisation d’App Configuration. Il existe deux points de terminaison différents : appconfiguration-refresh et appconfiguration-refresh-bus. Ces points de terminaison fonctionnent de la même façon que leurs équivalents refresh et refresh-bus, où les points de terminaison de configuration d’application expirent l’intervalle d’actualisation au lieu de forcer une actualisation lors de la réception. Vous pouvez toujours utiliser le refresh et le refresh-bus, mais vous ne pouvez pas les connecter directement à Azure Event Grid avec un Web Hook, car ils nécessitent une réponse lors du paramétrage.

L'intervalle d'actualisation expire avec la propriété appconfiguration-refresh. Par conséquent, l'intervalle d'actualisation restant n'est pas attendu avant la vérification de l'actualisation suivante. La appconfiguration-refresh-bus propriété envoie une notification à un service de messagerie connecté, tel qu’Azure Service Bus, pour notifier toutes les instances d’une application à actualiser. Dans les deux cas, il n’expire pas complètement à l’intervalle d’actualisation, mais est désactivé par une petite gigue. Cette variabilité garantit que chaque instance de votre application n'essaie pas de se rafraîchir en même temps.

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

En plus d’exposer les points de terminaison d’actualisation, la bibliothèque nécessite un paramètre de requête pour la sécurité. Aucun nom ou valeur de jeton n’existe par défaut, mais vous devez en définir un pour utiliser les points de terminaison, comme illustré dans l’exemple suivant :

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]

Configuration des webhooks

Pour configurer un hook web, ouvrez votre magasin Azure App Configuration et ouvrez Événements à partir du menu de navigation. Ensuite, sélectionnez Abonnement aux événements. Définissez le nom de votre événement et sélectionnez le type de point de terminaison comme Web Hook. Si vous sélectionnez Web Hook, une option de point de terminaison s’affiche. Choisissez Sélectionner un point de terminaison. Votre point de terminaison doit ressembler à l’exemple suivant : https://www.myaplication.com/actuator/appconfiguration-refresh?myTokenName=mySecret.

Confirmation de la sélection envoie une notification de configuration à l'URI spécifié et attend une réponse. Si aucune réponse n’est retournée, le programme d’installation échoue. La configuration de la bibliothèque azure-spring-cloud-appconfiguration-web pour les points de terminaison renvoie la bonne réponse si le stockage Azure App Configuration est configuré pour l’application. Cette confirmation peut être envoyée d’une autre manière. Pour plus d'informations sur la livraison de web hook, voir Livraison d'événements Webhook.

Remarque

Cette validation se produit uniquement lors de la création ou de la modification du point de terminaison.

Nous vous recommandons vivement de configurer des filtres, car sinon, une actualisation est déclenchée après chaque création et modification de clé.

Actualisation forcée du client

Vous pouvez configurer la bibliothèque pour forcer l’actualisation de toutes les configurations à un intervalle d’actualisation. Le tableau suivant décrit la refresh-interval propriété :

Nom Descriptif Obligatoire Par défaut
spring.cloud.azure.appconfiguration.refresh-interval Durée standard entre les actualisations. Est un Duration. Non zéro

Actualiser avec spring.cloud.azure.appconfiguration.refresh-interval ne vérifie aucune clé de surveillance configurée. Cette propriété est utilisée pour vous assurer que les secrets Key Vault sont conservés à jour, car Azure App Configuration ne peut pas savoir quand ils sont mis à jour.

Étant donné qu’Azure Key Vault stocke la paire de clés publique et privée d’un certificat en tant que secret, votre application peut récupérer n’importe quel certificat en tant que référence Key Vault dans App Configuration. Étant donné que les certificats doivent faire l’objet d’une rotation périodique, les applications clientes doivent être mises à jour aussi fréquemment, ce qui peut être effectué à l’aide de l’intervalle d’actualisation du client.

Actualisation de l’indicateur de fonctionnalité

Si les indicateurs de fonctionnalité et la surveillance sont tous les deux activés, l’intervalle d’actualisation par défaut pour les indicateurs de fonctionnalité est défini sur 30 secondes. Lorsque l’intervalle d’actualisation se termine, le système vérifie tous les indicateurs de fonctionnalité dans le magasin donné pour les modifications. Toute modification de la clé entraîne le déclenchement d'une gâchette d'actualisation. Étant donné que les bibliothèques s’intègrent au système d’actualisation Spring, toutes les actualisations rechargent toutes les configurations de tous les magasins. Vous pouvez définir l’intervalle d’actualisation sur un intervalle de plus de 1 seconde. Les unités prises en charge pour l’intervalle d’actualisation sont s, met hd pour les secondes, les minutes, les heures et les jours respectivement. L’exemple suivant définit l’intervalle d’actualisation sur 5 minutes :

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

Indicateur de santé

La bibliothèque client est livrée avec un indicateur de santé qui vérifie si la connexion au magasin ou aux magasins Azure App Configuration est saine. Si elle est activée pour chaque magasin, elle donne l’une des valeurs d’état suivantes :

  • UP : la dernière connexion a été réussie.
  • DOWN- La dernière connexion a donné lieu à un code d'erreur non-200. Cet état peut être dû à des problèmes allant des informations d’identification arrivant à expiration à un problème de service. La bibliothèque cliente retente automatiquement de se connecter au magasin à l’intervalle d’actualisation suivant.
  • NOT LOADED : le magasin de configuration est répertorié dans le fichier de configuration local, mais le magasin de configuration n’a pas été chargé à partir du fichier au démarrage. Le magasin de configuration est désactivé dans le fichier de configuration ou la ou les configurations n'ont pas été chargées au démarrage alors que la configuration fail-fast pour le magasin était définie sur false.

Vous pouvez activer l'indicateur de santé en définissant management.health.azure-app-configuration.enabled=true.

Personnalisation du client

La bibliothèque App Configuration utilise le Kit de développement logiciel (SDK) Azure pour Java pour la connexion à Azure App Configuration et Azure Key Vault. Deux interfaces, ConfigurationClientCustomizer et SecretClientCustomizer, sont fournies pour modifier les clients. Chaque interface a une customize méthode qui prend comme argument leur générateur respectif ainsi que la String valeur de l’URI pour laquelle le client est configuré, comme indiqué dans les définitions d’interface suivantes :

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

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

Ces interfaces permettent la personnalisation du client HTTP et de ses configurations. L’exemple suivant remplace la valeur par défaut HttpClient par une autre qui utilise un proxy pour tout le trafic dirigé vers App Configuration et Key Vault.

Remarque

Les ConfigurationClientBuilder et SecretClientBuilder sont déjà configurés pour être utilisés lorsqu'ils sont passés à customize. Toutes les modifications apportées aux clients, y compris les informations d’identification et la stratégie de nouvelle tentative, remplacent les valeurs par défaut déjà en place.

Vous pouvez également effectuer cette configuration à l’aide de la configuration d’Azure Spring Cloud.

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

}