Suporte à configuração de aplicativos

Este artigo descreve a biblioteca de Configuração de Aplicativo do Spring Cloud Azure. Essa biblioteca carrega configurações e sinalizadores de recursos do serviço de Configuração de Aplicativo do Azure. A biblioteca gera PropertySource abstrações para corresponder às abstrações já geradas pelo ambiente Spring, como variáveis de ambiente, configurações de linha de comando, arquivos de configuração local e assim por diante.

O Spring é uma estrutura de aplicativo de software livre desenvolvida pela VMware que oferece uma abordagem simplificada e modular para a criação de aplicativos Java. O Spring Cloud Azure é um projeto de software livre que fornece integração perfeita do Spring com os serviços do Azure.

Pré-requisitos

Configurar o repositório de Configuração de Aplicativos

Use o seguinte comando para criar seu repositório de Configuração de Aplicativo do Azure:

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

Esse comando cria um novo repositório de configuração vazio. Você pode carregar suas configurações usando o seguinte comando de importação:

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

Confirme suas configurações antes de carregá-las. Você pode carregar arquivos YAML alterando o formato para YAML. O campo de prefixo é importante porque é o prefixo padrão carregado pela biblioteca do cliente.

Uso da biblioteca

Para usar o recurso em um aplicativo, você pode criá-lo como um aplicativo Spring Boot. A maneira mais conveniente de adicionar a dependência é com o iniciador com.azure.spring:spring-cloud-azure-starter-appconfiguration-configSpring Boot. O exemplo pom.xml arquivo usa a Configuração do Aplicativo do Azure:

<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.17.1</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>

Observação

Se você estiver usando o Spring Boot 2.x, certifique-se de definir a spring-cloud-azure-dependencies versão como 4.19.0. Para obter mais informações sobre a versão usada para esta BOM, consulte Qual versão do Spring Cloud Azure devo usar.

O exemplo a seguir mostra um aplicativo básico do Spring Boot usando a Configuração do Aplicativo:

@SpringBootApplication
@RestController
public class Application {

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

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

Para este exemplo, o arquivo bootstrap.properties contém a seguinte linha:

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

CONFIG_STORE_CONNECTION_STRING é uma variável de ambiente com a cadeia de conexão para o Repositório de Configuração de Aplicativos do Azure. Você pode acessar sua cadeia de conexão usando o seguinte comando:

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

Por padrão, se nenhuma configuração for definida, as configurações começando com /application/ serão carregadas com um rótulo padrão de a menos que um Perfil Spring (No Label) esteja definido, caso em que o rótulo padrão será seu Perfil Spring. Como o repositório está vazio, nenhuma configuração é carregada, mas a Origem da Propriedade de Configuração do Aplicativo do Azure ainda é gerada.

Uma fonte de propriedade chamada /application/https://<name-of-your-store>.azconfig.io/ é criada contendo as propriedades desse armazenamento. O rótulo usado na solicitação é anexado ao final do nome. Se nenhum rótulo for definido, o caractere \0 estará presente como um espaço vazio.

Carregando a configuração

A biblioteca oferece suporte ao carregamento de um ou vários repositórios de Configuração de Aplicativo. Na situação em que uma chave é duplicada em vários repositórios, carregar todos os armazenamentos resulta na configuração de armazenamentos de prioridade mais alta sendo carregada. O último vence. Esse processo é ilustrado no exemplo a seguir:

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

No exemplo, se o primeiro e o segundo repositórios tiverem a mesma configuração, a configuração no segundo repositório terá a prioridade mais alta e o último vencerá.

Observação

Você pode usar as definições de Configuração de Aplicativo do Azure como qualquer outra Configuração do Spring. Para obter mais informações, consulte Principais recursos na documentação do Spring Boot ou Guia de início rápido: criar um aplicativo Java Spring com a Configuração do Aplicativo do Azure.

Selecionando configurações

As configurações são carregadas por sua chave e rótulo. Por padrão, as configurações que começam com a chave /application/ são carregadas. O rótulo padrão é ${spring.profiles.active}. Se ${spring.profiles.active} não estiver definido, as configurações com o null rótulo serão carregadas. O null rótulo aparece como (No Label) no portal do Azure.

Você pode configurar as configurações que são carregadas selecionando diferentes filtros de chave e rótulo, conforme mostrado no exemplo a seguir:

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

A key-filter propriedade oferece suporte aos seguintes filtros:

Filtro de chave Efeito
* Corresponde a qualquer chave.
abc Corresponde a uma chave chamada abc.
abc* Corresponde aos nomes de chave que começam com abc.
abc,xyz Corresponde aos nomes de chave abc ou xyz. Limitado a cinco valores separados por vírgula.

A label-filter propriedade oferece suporte aos seguintes filtros:

Etiqueta Descrição
* Corresponde a qualquer rótulo, incluindo \0.
\0 Corresponde null a rótulos, que aparecem como (No Label) no portal do Azure.
1.0.0 Corresponde exatamente ao rótulo 1.0.0.
1.0.* Corresponde aos rótulos que começam com 1.0.*.
,1.0.0 Corresponde a rótulos null e 1.0.0. Limitado a cinco valores separados por vírgula.

Se você estiver usando YAML com filtros de rótulo e precisar começar com null, o filtro de rótulo precisará ser cercado por aspas simples, conforme mostrado no exemplo a seguir:

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

Observação

Você não pode combinar * com , em filtros. Nesse caso, você precisa usar um valor de seleção adicional.

Perfis de Spring

Por padrão, spring.profiles.active é definido como padrão label-filter para todas as configurações selecionadas. Você pode substituir essa funcionalidade usando label-filtero . Você pode usar os perfis de mola no usando ${spring.profiles.active}, label-filter conforme mostrado no exemplo a seguir:

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

No primeiro label-filter, todas as configurações com o null rótulo são carregadas, seguidas por todas as configurações correspondentes aos perfis de mola. Os perfis Spring têm prioridade sobre as null configurações, porque estão no final.

No segundo label-filter, a cadeia de caracteres _local é anexada ao final dos Perfis de Primavera, embora apenas ao último Perfil de Primavera.

Lojas com deficiência

Usando a configuração spring.cloud.azure.appconfiguration.enabled, você pode desabilitar o carregamento para todos os repositórios de configuração. Com a spring.cloud.azure.appconfiguration.stores[0].enabled configuração, você pode desabilitar uma loja individual.

Além de desabilitar os repositórios, você pode configurar os repositórios para serem desabilitados se eles não forem carregados. Para essa configuração, use spring.cloud.azure.appconfiguration.stores[0].fail-fast. Quando fail-fast é desabilitado definindo-o como false, a RuntimeException resulta no repositório de aplicativos sendo desabilitado sem configurações de que ele está sendo carregado. Se um repositório de configuração estiver desabilitado na inicialização, ele não será verificado quanto a alterações na atualização. Além disso, não há nenhuma tentativa de carregar valores a partir dele se as configurações forem atualizadas.

Se ocorrer um erro durante uma RuntimeException verificação de atualização ou ao tentar recarregar configurações, a tentativa de atualização terminará e será tentada novamente após a refresh-interval aprovação.

Autenticação

A biblioteca dá suporte a todas as formas de identidade com suporte na Biblioteca de Identidades do Azure. Você pode fazer a autenticação por meio da configuração de cadeias de conexão e identidade gerenciada.

Cadeia de conexão

A autenticação por meio da cadeia de conexão é a forma mais simples de configurar. Você pode acessar as cadeias de conexão de um repositório usando o seguinte comando:

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

Em seguida, você pode definir a spring.cloud.azure.appconfiguration.stores[0].connection-string propriedade para a cadeia de conexão. É altamente recomendável definir a cadeia de conexão no arquivo de configuração local como um valor de espaço reservado que mapeia para uma variável de ambiente. Essa abordagem permite que você evite adicionar a cadeia de conexão ao controle do código-fonte.

Configuração do Spring Cloud Azure

Você pode usar a configuração do Spring Cloud Azure para configurar a biblioteca. Você pode usar as seguintes propriedades para configurar a biblioteca:

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

Quando apenas o ponto de extremidade é definido, a biblioteca de cliente usa o DefaultAzureCredential para autenticar. O DefaultAzureCredential usa os seguintes métodos para autenticar:

  • Credencial de ambiente
  • Credencial de identidade gerenciada
  • Credencial da CLI do desenvolvedor do Azure
  • Credencial do IntelliJ
  • Credencial da CLI do Azure
  • Credencial do PowerShell do Azure

Você precisa atribuir uma identidade, como uma identidade atribuída ao sistema, para ler configurações. Você pode criar essa atribuição usando o seguinte comando:

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>

Observação

Você pode definir apenas um método de autenticação por ponto de extremidade: cadeia de conexão, identidade atribuída ao usuário ou credencial de token. Se você precisar misturar e combinar, poderá usar ConfigurationClientCustomizer para modificar lojas que usam um método diferente.

Replicação geográfica

A biblioteca dá suporte ao recurso de replicação geográfica da Configuração de Aplicativo do Azure. Esse recurso permite que você replique seus dados para outros locais. Esse recurso é útil para alta disponibilidade e recuperação de desastres.

Cada réplica criada tem um ponto de extremidade dedicado. Se o seu aplicativo residir em várias localizações geográficas, você poderá atualizar cada implantação do aplicativo em um local para se conectar com a réplica mais próxima desse local, o que ajuda a minimizar a latência de rede entre o seu aplicativo e a Configuração de Aplicativos. Como cada réplica tem sua cota de solicitação separada, essa configuração também ajuda a escalabilidade do aplicativo enquanto ele cresce para um serviço distribuído de várias regiões.

O failover pode ocorrer se a biblioteca observar qualquer uma das seguintes condições:

  • Recebe respostas com código de status de serviço indisponível (HTTP 500 ou superior) de um ponto de extremidade.
  • Enfrenta problemas de conectividade de rede.
  • As solicitações são limitadas (código de status HTTP 429).

Criando um repositório de configuração com replicação geográfica

Para criar uma réplica do seu repositório de configuração, você pode usar a CLI do Azure ou o portal do Azure. O exemplo a seguir usa a CLI do Azure para criar uma réplica na região Leste dos EUA 2:

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

Usando a réplica do repositório de configuração

Depois de criar uma réplica, você poderá usá-la em seu aplicativo. Como o repositório de origem, você pode se conectar à sua réplica usando a ID do Microsoft Entra ou uma cadeia de conexão.

Para usar a ID do Microsoft Entra para se conectar à réplica, você precisa listar as endpoints instâncias do repositório de configuração, conforme mostrado no exemplo a seguir:

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

Você pode listar quantos pontos de extremidade tiver réplicas. A biblioteca tenta se conectar aos pontos de extremidade na ordem em que eles estão listados. Se a biblioteca não conseguir se conectar a uma réplica, ela tentará a próxima na lista. Após um período de tempo, a biblioteca tenta se reconectar aos pontos de extremidade preferenciais.

Valores da chave

A Configuração de Aplicativo do Azure dá suporte a vários tipos de valores de chave, alguns dos quais têm recursos especiais incorporados a eles. A Configuração de Aplicativo do Azure tem suporte interno para o tipo de conteúdo JSON, espaços reservados Spring e referências do Cofre de Chaves.

Espaços reservados

A biblioteca oferece suporte a configurações com ${}espaços reservados de ambiente -style. Ao fazer referência a uma chave de Configuração de Aplicativo do Azure com um espaço reservado, remova os prefixos da referência. Por exemplo, /application/config.message é referenciado como ${config.message}.

Observação

O prefixo que está sendo removido corresponde ao valor spring.cloud.azure.appconfiguration.stores[0].selects[0].key-filter.

JSON

As configurações que têm um tipo application/json de conteúdo são processadas como objetos JSON. Esse recurso permite mapear uma configuração para um objeto complexo dentro de um @ConfigurationPropertiesarquivo . Por exemplo, considere a chave /application/config.colors JSON com o seguinte valor:

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

Essa chave é mapeada para o seguinte código:

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

    private Map<String, Color> colors;

}

Referências do Key Vault

A Configuração de Aplicativo do Azure e suas bibliotecas dão suporte à referência de segredos armazenados no Cofre de Chaves. Em Configuração do aplicativo, você pode criar chaves com valores mapeados para segredos armazenados em um Cofre de Chaves. Os segredos são armazenados com segurança no Cofre de Chaves, mas podem ser acessados da mesma forma que qualquer outra configuração depois de carregados.

Seu aplicativo usa o provedor do cliente para recuperar referências do Cofre de Chaves, assim como faz para quaisquer outras chaves armazenadas na Configuração do Aplicativo. Como o cliente reconhece as chaves como referências do Cofre de Chaves, elas têm um tipo de conteúdo exclusivo e o cliente se conecta ao Cofre de Chaves para recuperar seus valores para você.

Observação

O Cofre de Chaves só permite que os segredos sejam recuperados um de cada vez, portanto, cada referência do Cofre de Chaves armazenada na Configuração do Aplicativo resulta em uma atração contra o Cofre de Chaves.

Criando referências do Cofre de Chaves

Você pode criar uma referência do Cofre de Chaves no portal do Azure acessando Referência de Criar Cofre de Chaves do Gerenciador de>>Configurações. Em seguida, você pode selecionar um segredo para referenciar em qualquer um dos Cofres de Chaves aos quais você tem acesso. Você também pode criar referências arbitrárias do Cofre de Chaves na guia Entrada . No portal do Azure, insira um URI válido.

Você também pode criar uma referência do Cofre de Chaves por meio da CLI do Azure usando o seguinte comando:

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

Você pode criar qualquer identificador de segredo por meio da CLI do Azure. Os identificadores secretos exigem apenas o formato {vault}/{collection}/{name}/{version?} em que a seção de versão é opcional.

Usando referências do Cofre de Chaves

Você pode usar a configuração do Spring Cloud Azure para configurar a biblioteca. Você pode usar a mesma credencial usada para se conectar à Configuração do Aplicativo para se conectar ao Cofre de Chaves do Azure.

Resolver segredos que não sejam do Cofre de Chaves

A biblioteca Configuração do Aplicativo fornece um método para resolver localmente segredos que não têm um Cofre de Chaves associado a eles. Essa resolução é feita através do KeyVaultSecretProvider. O KeyVaultSecretProvider é chamado quando um TokenCredential não é fornecido para uma referência do Cofre de Chaves. O URI da referência do Cofre da Chave é fornecido e o valor retornado torna-se o valor do segredo.

Aviso

O uso de um KeyVaultSecretProvider substitui o uso automático da identidade gerenciada atribuída pelo sistema. Para usar ambos, você precisa usar KeyVaultCredentialProvider e retornar null para os URIs que precisam ser resolvidos.

public class MySecretProvider implements KeyVaultSecretProvider {

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

}

Gerenciamento de recursos

O gerenciamento de recursos fornece uma maneira para os aplicativos Spring Boot acessarem conteúdo dinamicamente. O gerenciamento de recursos tem várias funções, como as seguintes:

  • Sinalizadores de recursos que podem habilitar ou desabilitar conteúdo
  • Filtros de recursos para segmentação quando o conteúdo é exibido
  • Filtros de recursos personalizados
  • Portas de recursos para habilitar pontos de extremidade dinamicamente

Você pode habilitar sinalizadores de recursos por meio da seguinte configuração:

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

Os sinalizadores de recursos habilitados são carregados no sistema de configuração do Spring com o prefixo feature-management. Você também pode registrar sinalizadores de recurso no arquivo de configuração local. Para obter mais informações, consulte a seção Declaração de sinalizador de recurso.

A maneira mais fácil de usar o gerenciamento de recursos é usando as spring-cloud-azure-feature-management bibliotecas e spring-cloud-azure-feature-management-web . A diferença entre as duas bibliotecas é que spring-cloud-azure-feature-management-web é preciso uma dependência das spring-web bibliotecas e spring-webmvc para adicionar mais recursos, como portas de recursos.

Você pode habilitar sinalizadores de recurso usando filtros de chave/rótulo. Por padrão, um null rótulo, visto como (No Label), é atribuído. Você pode configurar os sinalizadores de recurso que são carregados definindo um filtro de rótulo, conforme mostrado no exemplo a seguir:

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

Noções básicas de gerenciamento de recursos

Sinalizadores de funcionalidade

Os sinalizadores de recurso são compostos de duas partes: um nome e uma lista de filtros de recurso que são usados para ativar o recurso. Os sinalizadores de recursos podem ter um estado booleano de ativar/desativar ou podem ter uma lista de filtros de recursos. Os sinalizadores de recursos avaliam os filtros de recursos até que um retorne true. Se nenhum filtro de recurso retornar true, o sinalizador de recurso retornará false.

Filtros de recursos

Os filtros de recursos definem um cenário para quando um recurso deve ser habilitado. Os filtros de recursos são avaliados de forma síncrona.

A biblioteca de gerenciamento de recursos vem com quatro filtros predefinidos: AlwaysOnFilter, PercentageFilter, TimeWindowFilter e TargetingFilter.

Você pode criar filtros de recursos personalizados. Por exemplo, você pode usar um filtro de recurso para fornecer uma experiência personalizada para clientes que estão usando um navegador Microsoft Edge. Você pode personalizar os recursos nesse filtro de recursos, por exemplo, para mostrar um cabeçalho específico para o público do navegador Microsoft Edge.

Declaração do sinalizador de recurso

A biblioteca de gerenciamento de recursos dá suporte à Configuração de Aplicativo do Azure junto com application.yml ou bootstrap.yml como fontes para sinalizadores de recursos. Aqui está um exemplo do formato usado para configurar sinalizadores de recurso em um arquivo 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

Este exemplo tem os seguintes sinalizadores de recurso:

  • feature-t é definido como false. Essa configuração sempre retorna o valor do sinalizador de recurso.
  • feature-u é usado com filtros de recursos. Esses filtros são definidos sob a enabled-for propriedade. Nesse caso, feature-u tem um filtro de recurso chamado Random, que não requer nenhuma configuração, portanto, apenas a propriedade name é necessária.
  • feature-v especifica um filtro de recurso chamado TimeWindowFilter. Esse filtro de recurso pode ser passado parâmetros para usar como configuração. Neste exemplo, um TimeWindowFilter, passa nas horas de início e término durante as quais o recurso está ativo.
  • feature-w é usado para o AlwaysOnFilter, que sempre avalia para true. O evaluate campo é usado para interromper a avaliação dos filtros de recurso e resulta no filtro de recurso sempre retornando false.

Avaliando sinalizadores de recursos

A spring-cloud-azure-feature-management biblioteca fornece FeatureManager para determinar se um sinalizador de recurso está habilitado. FeatureManager Fornece uma maneira assíncrona de verificar o estado do sinalizador.

spring-cloud-azure-feature-management-web, juntamente com o fornecimento FeatureManager, contém FeatureManagerSnapshot, que armazena em cache o estado dos sinalizadores de recursos avaliados anteriormente no @RequestScope para garantir que todas as solicitações retornem o mesmo valor. Além disso, a biblioteca da Web fornece @FeatureGate, que pode bloquear ou redirecionar solicitações da Web para diferentes pontos de extremidade.

Verificação do sinalizador de recurso

FeatureManager é um @Bean que pode ser @Autowired ou injetado em @Component objetos do tipo. FeatureManager tem um método isEnabled que, quando passado o nome de um sinalizador de recurso, retorna seu estado.

@Autowired
FeatureManager featureManager;

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

Observação

FeatureManger também tem uma versão assíncrona do isEnabled chamado isEnabledAsync.

Se você não configurou o gerenciamento de recursos ou o sinalizador de recurso não existe, isEnabled sempre retornará false. Se um sinalizador de recurso existente estiver configurado com um filtro de recurso desconhecido, um FilterNotFoundException será lançado. Você pode alterar esse comportamento para retornar false configurando fail-fast para false. A tabela a seguir descreve fail-fast:

Nome Descrição Obrigatório Padrão
spring.cloud.azure.feature.management.fail-fast Se ocorrer uma exceção, um RuntimeException será lançado. Se essa propriedade estiver definida como false, retornará false isEnabled em vez disso. Não true

A única diferença entre FeatureManagerSnapshot e FeatureManager é o cache de resultados no @RequestScope.

Portão de recursos

Com a biblioteca da Web de gerenciamento de recursos, você pode exigir que um determinado recurso esteja habilitado para executar um ponto de extremidade. Você pode configurar esse requisito usando a @FeatureGate anotação, conforme mostrado no exemplo a seguir:

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

Você só pode acessar o ponto de extremidade se o featureT "feature-t" estiver habilitado.

Tratamento de ações desabilitado

Quando um ponto de extremidade é bloqueado porque o recurso especificado está desabilitado, DisabledFeaturesHandler é invocado. Por padrão, um HTTP 404 é retornado. Você pode substituir esse comportamento implementando DisabledFeaturesHandlero , conforme mostrado no exemplo a seguir:

@Component
public class MyDisabledFeaturesHandler implements DisabledFeaturesHandler {

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

}
Roteamento

Determinadas rotas podem expor recursos de aplicativos que são limitados por recursos. Se um recurso estiver desabilitado, você poderá redirecionar essas rotas para outro ponto de extremidade, conforme mostrado no exemplo a seguir:

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

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

Filtros de recursos integrados

Existem alguns filtros de recursos que vêm com o spring-cloud-azure-feature-management pacote. Esses filtros de recursos não são adicionados automaticamente, mas você pode configurá-los em um @Configurationarquivo .

AlwaysOnFilter

Esse filtro sempre retorna true. Para obter um exemplo de uso, consulte a seção de declaração de sinalizador de recurso.

Filtro de porcentagens

Cada vez que um usuário faz uma solicitação, a avaliação de PercentageFilter pode retornar um resultado diferente. Você pode contornar essa inconsistência usando o , que armazena FeatureManagementSnapshotem cache o resultado do sinalizador de recurso por usuário. Esse recurso garante que um usuário tenha uma experiência consistente, mesmo que precise reenviar a solicitação.

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

TimeWindowFilter

Esse filtro fornece a capacidade de habilitar um recurso com base em uma janela de tempo. Se você especificar somente End, o recurso será considerado ativado até esse momento. Se você especificar somente Start, o recurso será considerado ativado em todos os pontos após esse período. Se você especificar ambos, o recurso será considerado válido entre os dois tempos.

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"

SegmentaçãoFilter

Esse filtro fornece a capacidade de habilitar um recurso para um público-alvo. Para obter uma explicação detalhada da segmentação, consulte a seção de segmentação . Os parâmetros de filtro incluem um objeto de audiência que descreve usuários, grupos e uma porcentagem padrão da base de usuários que deve ter acesso ao recurso. Para cada objeto de grupo listado no público-alvo, é necessária uma porcentagem que define a porcentagem de membros desse grupo que têm acesso ao recurso. Um usuário tem o recurso habilitado nos seguintes casos:

  • O usuário é especificado na seção de usuários diretamente.
  • O usuário está na porcentagem incluída de qualquer uma das distribuições de grupo.
  • O usuário se enquadra na porcentagem de distribuição padrão.
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

Filtros de recursos personalizados

A criação de um filtro de recurso personalizado fornece uma maneira de habilitar recursos com base em critérios definidos por você. Para criar um filtro de recurso personalizado, você deve implementar a FeatureFilter interface. FeatureFilter tem um único método evaluate. Quando um recurso especifica que ele pode ser habilitado com um filtro de recurso, o evaluate método é chamado. Se evaluate retornar true, significa que o recurso deve ser habilitado. Se ele retornar false, ele continuará avaliando filtros de recursos até que um retorne true. Se todos os filtros retornarem false, o recurso estará desativado.

Os filtros de recursos são definidos como Spring Beans, portanto, são definidos como @Component ou definidos em um @Configurationarquivo .

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

}

Filtros de recursos parametrizados

Alguns filtros de recurso exigem parâmetros para determinar se um recurso deve ser ativado. Por exemplo, um filtro de recurso do navegador pode ativar um recurso para um determinado conjunto de navegadores. Talvez você queira um recurso ativado para os navegadores Microsoft Edge e Chrome, mas não para o Firefox. Para configurar essa situação, você pode criar um filtro de recurso para esperar parâmetros. Esses parâmetros seriam especificados na configuração do recurso e no código, e seriam acessíveis por meio do FeatureFilterEvaluationContext parâmetro de evaluate. FeatureFilterEvaluationContext tem uma propriedade parameters, que é um HashMap<String, Object>.

Direcionamento

A segmentação é uma estratégia de gerenciamento de recursos que permite aos desenvolvedores implementar progressivamente novos recursos para sua base de usuários. A estratégia baseia-se no conceito de atingir um conjunto de usuários conhecido como público-alvo. Um público é composto por usuários, grupos específicos e uma porcentagem designada de toda a base de usuários. Os grupos incluídos na audiência podem ser divididos ainda mais em percentuais de seus membros totais.

As etapas a seguir demonstram um exemplo de uma distribuição progressiva para um novo recurso "Beta":

  1. Os usuários individuais Jeff e Alicia têm acesso ao Beta.
  2. Outro usuário, Mark, pede para participar e é incluído.
  3. Vinte por cento de um grupo conhecido como usuários "Ring1" estão incluídos no Beta.
  4. O número de usuários "Ring1" incluídos no beta é aumentado para 100%.
  5. Cinco por cento da base de usuários está incluída na versão beta.
  6. O percentual de distribuição é aumentado em até 100% e o recurso é completamente distribuído.

Essa estratégia para implantar um recurso é incorporada à biblioteca por meio do filtro de recursos incluído TargetingFilter .

Segmentação em um aplicativo

Um aplicativo Web de exemplo que usa o filtro de recurso de direcionamento está disponível no projeto de exemplo.

Para começar a usar o TargetingFilter em um aplicativo, você deve adicioná-lo como um filtro de @Bean recurso como qualquer outro. TargetingFilter depende de outro @Bean para ser adicionado ao aplicativo TargetingContextAccessor. O TargetingContextAccessor permite definir a corrente TargetingContext a ser usada para definir o ID de usuário e os grupos atuais, conforme mostrado no exemplo a seguir:

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

}

Opções de avaliação de segmentação

Opções estão disponíveis para personalizar como a avaliação de segmentação é executada em um determinado TargetingFilter. Você pode definir um parâmetro opcional, TargetingEvaluationOptions, durante a TargetingFilter criação.

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

Atualização de configuração

Habilitar a atualização de configuração para suas configurações permite que você extraia seus valores mais recentes do seu repositório de Configuração de Aplicativo ou lojas sem precisar reiniciar o aplicativo.

Para habilitar a atualização, você precisa habilitar o monitoramento junto com os gatilhos de monitoramento. Um gatilho de monitoramento é uma chave com um rótulo opcional que é verificado se há alterações de valor para disparar atualizações. O valor do gatilho de monitoramento pode ser qualquer valor, desde que ele seja alterado quando uma atualização for necessária.

Observação

Qualquer operação que altere o ETag de um gatilho de monitoramento causa uma atualização, como uma alteração de tipo de conteúdo.

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

Para disparar uma atualização de configuração, altere o valor de uma chave no repositório de configuração. Em seguida, atualize uma das teclas de observação para um novo valor. Essa alteração aciona a criação de um log. Por exemplo, alterar o valor de dispara a seguinte mensagem de /application/config.message log:

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

Depois que o aplicativo gera o log, ele atualiza todos @Beanos s no escopo de atualização.

Observação

Por padrão, @ConfigurationProperties os beans anotados são incluídos nesse escopo.

Atualização baseada em pull

As bibliotecas do App Configuration Spring oferecem suporte à capacidade de verificar periodicamente em um intervalo de atualização as alterações feitas nos gatilhos de monitoramento. Por padrão, o intervalo de atualização é definido como 30 segundos. Depois que o intervalo de atualização passar, todos os gatilhos são verificados no armazenamento fornecido para alterações. Qualquer alteração na chave faz com que uma atualização seja acionada. Como as bibliotecas se integram ao sistema de atualização do Spring, qualquer atualização recarrega todas as configurações de todos os repositórios. Você pode definir o intervalo de atualização para qualquer intervalo maior que 1 segundo. As unidades suportadas para o intervalo de atualização são s, m, he d para segundos, minutos, horas e dias, respectivamente. O exemplo a seguir define o intervalo de atualização como 5 minutos:

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

Automatizados

Quando você usa a spring-cloud-azure-appconfiguration-config-web biblioteca, o aplicativo verifica automaticamente se há uma atualização sempre que ocorre uma solicitação de servlet, especificamente ServletRequestHandledEvent. A maneira mais comum como esse evento é enviado é por solicitações a pontos de extremidade em um @RestControllerarquivo .

Manual

Em aplicativos que usam somente spring-cloud-azure-appconfiguration-config, como aplicativos de console, você pode disparar manualmente uma atualização chamando AppConfigurationRefresho método 's refreshConfiguration . AppConfigurationRefresh é um @Bean que você pode injetar em qualquer @Componentarquivo .

Além disso, como a biblioteca usa o sistema de configuração do Spring, acionar uma atualização causa uma atualização de todas as suas configurações, não apenas uma recarga das do repositório de Configuração de Aplicativo do Azure.

Atualização baseada em push

Você pode configurar a spring-cloud-azure-appconfiguration-config-web biblioteca para receber notificações por push do seu repositório de Configuração de Aplicativo do Azure para atualizar seus valores de configuração. Você pode configurar essa configuração por meio de um Gancho da Web da Grade de Eventos do Azure, que você pode configurar para enviar notificações de alterações em chaves especificadas. Ao adicionar a biblioteca do Spring Actuator como uma dependência, você pode expor os pontos de extremidade de atualização do App Configuration. Existem dois pontos de extremidade diferentes: appconfiguration-refresh e appconfiguration-refresh-bus. Esses pontos de extremidade funcionam de forma semelhante às suas contrapartes refresh e refresh-bus, onde os pontos de extremidade de configuração do aplicativo expiram o intervalo de atualização em vez de forçar uma atualização ao receber. Você ainda pode usar o refresh e refresh-bus, mas não pode conectá-los diretamente à Grade de Eventos do Azure com um Gancho da Web porque eles exigem uma resposta na instalação.

A appconfiguration-refresh propriedade expira o intervalo de atualização, portanto, o intervalo de atualização restante não é aguardado antes da próxima verificação de atualização. A appconfiguration-refresh-bus propriedade envia uma notificação a um serviço de mensagens conectado, como o Barramento de Serviço do Azure, para notificar todas as instâncias de um aplicativo a serem atualizadas. Em ambos os casos, ele não expira completamente no intervalo de atualização, mas é desativado por uma pequena quantidade de jitter. Esse jitter garante que todas as instâncias do seu aplicativo não tentem atualizar ao mesmo tempo.

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

Além de expor os pontos de extremidade de atualização, um parâmetro de consulta necessário foi adicionado para segurança. Nenhum nome ou valor de token é definido por padrão, mas a configuração de um é necessária para usar os pontos de extremidade, conforme mostrado no exemplo a seguir:

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]

Configurando ganchos da Web

Para configurar um gancho da Web, abra o repositório de Configuração de Aplicativo do Azure e abra Eventos no menu de navegação. Em seguida, selecione Assinatura de evento. Defina o nome do evento e selecione o tipo de ponto de extremidade a ser Web Hook. Selecionar Gancho da Web faz com que uma opção Ponto de extremidade apareça. Selecione Selecionar um ponto de extremidade. Seu ponto de extremidade deve se parecer com o exemplo a seguir: https://www.myaplication.com/actuator/appconfiguration-refresh?myTokenName=mySecret.

Confirmar seleção envia uma notificação de configuração para o URI fornecido e espera uma resposta. Se nenhuma resposta for retornada, a instalação falhará. A azure-spring-cloud-appconfiguration-web configuração da biblioteca para pontos de extremidade retornará a resposta correta se o repositório de Configuração de Aplicativo do Azure estiver configurado para o aplicativo. Essa confirmação pode ser enviada de outras formas. Para obter mais informações sobre a entrega de ganchos da Web, consulte Entrega de eventos Webhook.

Observação

Essa validação acontece somente após a criação ou modificação do ponto de extremidade.

É altamente recomendável que você configure filtros porque, caso contrário, uma atualização é acionada após cada criação e modificação de chave.

Atualização forçada do cliente

Você pode configurar a biblioteca para forçar uma atualização de todas as configurações em um intervalo de atualização. A tabela a seguir descreve a refresh-interval propriedade:

Nome Descrição Obrigatório Padrão
spring.cloud.azure.appconfiguration.refresh-interval A quantidade padrão de tempo entre as atualizações. É um Durationarquivo . Não nulo

A atualização com spring.cloud.azure.appconfiguration.refresh-interval não verifica nenhuma tecla de observação configurada. Essa propriedade é usada para garantir que os segredos do Cofre da Chave sejam mantidos atualizados porque a Configuração do Aplicativo do Azure não pode saber quando eles são atualizados.

Como o Cofre de Chaves do Azure armazena o par de chaves pública e privada de um certificado como um segredo, seu aplicativo pode recuperar qualquer certificado como uma referência do Cofre de Chaves na Configuração do Aplicativo. Como os certificados precisam ser girados periodicamente, os aplicativos cliente precisam ser atualizados com a mesma frequência, o que pode ser feito usando o intervalo de atualização do cliente.

Atualização do sinalizador de recurso

Se os sinalizadores de recurso e o monitoramento estiverem habilitados, por padrão, o intervalo de atualização para sinalizadores de recurso será definido como 30 segundos. Depois que o intervalo de atualização passar, todos os sinalizadores de recurso são verificados no armazenamento especificado para alterações. Qualquer alteração na chave faz com que uma atualização seja acionada. Como as bibliotecas se integram ao sistema de atualização do Spring, qualquer atualização recarrega todas as configurações de todos os repositórios. Você pode definir o intervalo de atualização para qualquer intervalo maior que 1 segundo. As unidades suportadas para o intervalo de atualização são s, m, he d para segundos, minutos, horas e dias, respectivamente. O exemplo a seguir define o intervalo de atualização como 5 minutos:

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

Indicador de saúde

A biblioteca do cliente vem com um indicador de integridade que verifica se a conexão com o repositório ou lojas de Configuração de Aplicativo do Azure está íntegra. Se habilitado para cada loja, ele fornece um dos seguintes valores de status:

  • UP - A última conexão foi bem-sucedida.
  • DOWN- A última conexão resultou em um código de erro não 200. Esse status pode ser devido a problemas que vão desde credenciais expirando até um problema de serviço. A biblioteca do cliente tenta se conectar novamente ao repositório no próximo intervalo de atualização.
  • NOT LOADED - O repositório de configuração está listado no arquivo de configuração local, mas o repositório de configuração não foi carregado do arquivo na inicialização. O repositório de configuração está desabilitado no arquivo de configuração ou a configuração ou configurações falharam ao carregar na inicialização enquanto a configuração do fail-fast repositório foi definida como false.

Você pode habilitar o indicador de integridade definindo management.health.azure-app-configuration.enabled=true.

Personalização do cliente

A biblioteca de Configuração de Aplicativo usa o SDK do Azure para Java para se conectar à Configuração de Aplicativo do Azure e ao Cofre de Chaves do Azure. Duas interfaces ConfigurationClientCustomizer e SecretClientCustomizer, são fornecidas para modificar os clientes. Cada interface tem um customize método que leva em seu respectivo construtor junto com o String valor do URI para o qual o cliente está sendo configurado, conforme mostrado nas seguintes definições de interface:

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

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

Essas interfaces permitem a personalização do cliente HTTP e suas configurações. O exemplo a seguir substitui o padrão HttpClient por outro que usa um proxy para todo o tráfego direcionado para a Configuração do Aplicativo e o Cofre de Chaves.

Observação

Os ConfigurationClientBuilder e SecretClientBuilder já estão configurados para uso quando passados para customize. Quaisquer alterações nos clientes, incluindo as credenciais e a política de repetição, substituem as que já estão em vigor.

Você também pode fazer essa configuração usando a configuração do 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();
    }

}