Configuração de Aplicativos do Azure biblioteca de clientes para Java – versão 1.4.10

A Configuração de Aplicativos do Azure é um serviço gerenciado que ajuda os desenvolvedores a centralizarem as configurações de seus aplicativos de maneira simples e segura.

Programas modernos, especialmente programas executando em uma nuvem, geralmente possuem muitos componentes que são distribuídos por natureza. A distribuição das definições de configuração entre esses componentes pode levar a erros difíceis de serem resolvidos durante uma implantação de aplicativo. Use a Configuração de Aplicativo para armazenar todas as configurações do aplicativo e proteger os acessos em um só lugar.

Use a biblioteca de clientes para Configuração de Aplicativos para criar e gerenciar definições de configuração de aplicativo.

Código-fonte | Pacote (Maven) | Documentação | de referência da APIDocumentação do produto | Amostras

Introdução

Pré-requisitos

Incluir o Pacote

Incluir o arquivo da BOM

Inclua o azure-sdk-bom em seu projeto para assumir a dependência da versão ga (disponibilidade geral) da biblioteca. No trecho a seguir, substitua o espaço reservado {bom_version_to_target} pelo número de versão. Para saber mais sobre a BOM, consulte o BOM README do SDK do AZURE.

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-sdk-bom</artifactId>
            <version>{bom_version_to_target}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

e inclua a dependência direta na seção dependências sem a marca de versão, conforme mostrado abaixo.

<dependencies>
  <dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-data-appconfiguration</artifactId>
  </dependency>
</dependencies>

Incluir dependência direta

Se você quiser assumir a dependência de uma versão específica da biblioteca que não está presente na BOM, adicione a dependência direta ao seu projeto da seguinte maneira.

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-data-appconfiguration</artifactId>
  <version>1.4.10</version>
</dependency>

Criar uma Configuração de Aplicativos Store

Para criar um Repositório de Configurações, você pode usar o Portal do Azure ou a CLI do Azure.

É necessário instalar a extensão da CLI da Configuração de Aplicativo do Azure primeiro executando o seguinte comando:

az extension add -n appconfig

Depois disso, crie o Repositório de Configurações:

az appconfig create --name <config-store-name> --resource-group <resource-group-name> --location eastus

Autenticar o cliente

Para interagir com o serviço Configuração de Aplicativos, você precisará criar uma instância da classe Cliente de Configuração. Para tornar isso possível, você precisará da cadeia de conexão do Repositório de Configurações. Como alternativa, use o token do AAD para se conectar ao serviço.

Usar a cadeia de conexão

Obter credenciais

Use o snippet da CLI do Azure abaixo para obter o cadeia de conexão do Repositório de Configurações.

az appconfig credential list --name <config-store-name>

Como alternativa, obtenha o cadeia de conexão no Portal do Azure.

Criar um cliente de configuração

Depois de ter o valor do cadeia de conexão você pode criar o cliente de configuração:

ConfigurationClient configurationClient = new ConfigurationClientBuilder()
    .connectionString(connectionString)
    .buildClient();

ou

ConfigurationAsyncClient configurationClient = new ConfigurationClientBuilder()
    .connectionString(connectionString)
    .buildAsyncClient();

Usar token do AAD

Aqui, demonstramos o uso de DefaultAzureCredential para autenticar como uma entidade de serviço. No entanto, o cliente de configuração aceita qualquer credencial azure-identity . Consulte a documentação do azure-identity para obter mais informações sobre outras credenciais.

Criar uma entidade de serviço (opcional)

Este snippet da CLI do Azure mostra como criar uma nova entidade de serviço. Antes de usá-lo, substitua "your-application-name" pelo nome apropriado para sua entidade de serviço.

Criar uma entidade de serviço:

az ad sp create-for-rbac --name http://my-application --skip-assignment

Saída:

 {
     "appId": "generated app id",
     "displayName": "my-application",
     "name": "http://my-application",
     "password": "random password",
     "tenant": "tenant id"
 }

Use a saída para definir AZURE_CLIENT_ID ("appId" acima), AZURE_CLIENT_SECRET ("senha" acima) e AZURE_TENANT_ID ("locatário" acima). O exemplo a seguir mostra uma maneira de fazer isso no Bash:

export AZURE_CLIENT_ID="generated app id"
export AZURE_CLIENT_SECRET="random password"
export AZURE_TENANT_ID="tenant id"

Atribua uma das funções de Configuração de Aplicativos aplicáveis à entidade de serviço.

Criar um cliente

Depois que o AZURE_CLIENT_ID, AZURE_CLIENT_SECRET e AZURE_TENANT_ID variáveis de ambiente forem definidas, DefaultAzureCredential poderá autenticar o cliente de configuração.

Construir o cliente também requer a URL do repositório de configuração, que você pode obter da CLI do Azure ou do Portal do Azure. No Portal do Azure, a URL pode ser encontrada listada como o serviço "Ponto de extremidade".

DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();
ConfigurationClient configurationClient = new ConfigurationClientBuilder()
    .credential(credential)
    .endpoint(endpoint)
    .buildClient();

Principais conceitos

Definição de configuração

Uma definição de configuração é o recurso fundamental em um repositório de configuração. Em sua forma mais simples, é uma chave e um valor. No entanto, há propriedades adicionais, como o tipo de conteúdo modificável e os campos de marcas que permitem que o valor seja interpretado ou associado de maneiras diferentes.

A propriedade Label de uma definição de configuração fornece uma maneira de separar as definições de configuração em dimensões diferentes. Essas dimensões são definidas pelo usuário e podem assumir qualquer forma. Alguns exemplos comuns de dimensões a serem usadas para um rótulo incluem regiões, versões semânticas ou ambientes. Muitos aplicativos têm um conjunto necessário de chaves de configuração que têm valores variados à medida que o aplicativo existe em diferentes dimensões. Por exemplo, MaxRequests pode ser 100 em "NorthAmerica" e 200 em "WestEurope". Ao criar uma definição de configuração chamada MaxRequests com um rótulo de "NorthAmerica" e outro, somente com um valor diferente, no rótulo "WestEurope", uma solução pode ser obtida que permite que o aplicativo recupere perfeitamente as Definições de Configuração conforme ele é executado nessas duas dimensões.

Cliente de Configuração

O cliente executa as interações com o serviço Configuração de Aplicativos, obtendo, definindo, excluindo e selecionando definições de configuração. Um cliente assíncrono, ConfigurationAsyncCliente síncrono ConfigurationClientexiste no SDK, permitindo a seleção de um cliente com base no caso de uso de um aplicativo.

Um aplicativo que precisa recuperar configurações de inicialização é mais adequado usando o cliente síncrono, por exemplo, configurar uma conexão SQL.

ConfigurationClient configurationClient = new ConfigurationClientBuilder()
    .connectionString(connectionString)
    .buildClient();

// urlLabel is optional
String url = configurationClient.getConfigurationSetting(urlKey, urlLabel).getValue();
Connection conn = null;
try {
    conn = DriverManager.getConnection(url);
} catch (SQLException ex) {
    System.out.printf("Failed to get connection using url %s", url);
} finally {
    if (conn != null) {
        try {
            conn.close();
        } catch (SQLException ex) {
            System.out.printf("Failed to close connection, url %s", url);
        }
    }
}

Um aplicativo que tem um grande conjunto de configurações que precisa atualizar periodicamente é mais adequado usando o cliente assíncrono, por exemplo, todas as configurações com um rótulo específico são atualizadas periodicamente.

ConfigurationAsyncClient configurationClient = new ConfigurationClientBuilder()
    .connectionString(connectionString)
    .buildAsyncClient();

configurationClient.listConfigurationSettings(new SettingSelector().setLabelFilter(periodicUpdateLabel))
    .subscribe(setting -> updateConfiguration(setting));

Exemplos

As seções a seguir fornecem vários snippets de código que abrangem algumas das tarefas mais comuns do serviço de configuração, incluindo: Para definições de configuração "Sinalizador de Recurso" e "Referência secreta", consulte exemplos para obter mais detalhes.

Criar um cliente de configuração

Crie um cliente de configuração usando ConfigurationClientBuilder passando cadeia de conexão.

ConfigurationClient configurationClient = new ConfigurationClientBuilder()
    .connectionString(connectionString)
    .buildClient();

Criar uma configuração

Crie uma definição de configuração a ser armazenada no repositório de configuração. Há duas maneiras de armazenar uma configuração:

  • addConfigurationSetting cria uma configuração somente se a configuração ainda não existir no repositório.
ConfigurationSetting setting = configurationClient.addConfigurationSetting("new_key", "new_label", "new_value");

Ou

  • setConfigurationSetting criará uma configuração se ela não existir ou substituir uma configuração existente.
ConfigurationSetting setting = configurationClient.setConfigurationSetting("some_key", "some_label", "some_value");

Crie uma definição de configuração do Sinalizador de Recurso ou uma configuração de Referência secreta a ser armazenada no repositório de configuração.

String key = "some_key";
String filterName = "{filter_name}"; // such as "Microsoft.Percentage"
String filterParameterKey = "{filter_parameter_key}"; // "Value"
Object filterParameterValue = 30; // Any value. Could be String, primitive value, or Json Object
FeatureFlagFilter percentageFilter = new FeatureFlagFilter(filterName)
                                         .addParameter(filterParameterKey, filterParameterValue);
FeatureFlagConfigurationSetting featureFlagConfigurationSetting =
    new FeatureFlagConfigurationSetting(key, true)
        .setClientFilters(Arrays.asList(percentageFilter));

FeatureFlagConfigurationSetting setting = (FeatureFlagConfigurationSetting)
    configurationClient.addConfigurationSetting(featureFlagConfigurationSetting);
String key = "{some_key}";
String keyVaultReference = "{key_vault_reference}";

SecretReferenceConfigurationSetting referenceConfigurationSetting =
    new SecretReferenceConfigurationSetting(key, keyVaultReference);

SecretReferenceConfigurationSetting setting = (SecretReferenceConfigurationSetting)
    configurationClient.addConfigurationSetting(referenceConfigurationSetting);

Recuperar uma configuração

Recupere uma configuração armazenada anteriormente chamando getConfigurationSetting.

ConfigurationSetting setting = configurationClient.setConfigurationSetting("some_key", "some_label", "some_value");
ConfigurationSetting retrievedSetting = configurationClient.getConfigurationSetting("some_key", "some_label");

Para solicitação condicional, se você quiser buscar condicionalmente uma configuração, defina ifChanged como true. Quando ifChanged for true, a configuração só será recuperada se for diferente da determinada setting. Isso é determinado comparando a ETag do setting com aquele no serviço para ver se eles são iguais ou não. Se as ETags não forem as mesmas, isso significa que a configuração é diferente e seu valor é recuperado.

ConfigurationSetting setting = configurationClient.setConfigurationSetting("some_key", "some_label", "some_value");
Response<ConfigurationSetting> settingResponse = configurationClient.getConfigurationSettingWithResponse(setting, null, true, Context.NONE);

Recupere uma definição de configuração do Sinalizador de Recurso ou uma configuração de Referência secreta no repositório de configuração.

FeatureFlagConfigurationSetting setting = (FeatureFlagConfigurationSetting)
    configurationClient.getConfigurationSetting(featureFlagConfigurationSetting);
SecretReferenceConfigurationSetting setting = (SecretReferenceConfigurationSetting)
    configurationClient.getConfigurationSetting(referenceConfigurationSetting);

Atualizar uma configuração existente

Atualize uma configuração existente chamando setConfigurationSetting.

ConfigurationSetting setting = configurationClient.setConfigurationSetting("some_key", "some_label", "some_value");
ConfigurationSetting updatedSetting = configurationClient.setConfigurationSetting("some_key", "some_label", "new_value");

Para solicitação condicional, se você quiser atualizar condicionalmente uma configuração, defina o ifUnchanged parâmetro como true. Quando ifUnchanged for true, a definição de configuração só será atualizada se for igual à determinada setting. Isso é determinado comparando a ETag do setting com aquele no serviço para ver se eles são iguais ou não. Se a ETag for a mesma, isso significa que a configuração é a mesma e seu valor é atualizado.

ConfigurationSetting setting = configurationClient.setConfigurationSetting("some_key", "some_label", "some_value");
Response<ConfigurationSetting> settingResponse = configurationClient.setConfigurationSettingWithResponse(setting, true, Context.NONE);

Atualize uma definição de configuração do Sinalizador de Recurso ou uma configuração de Referência secreta no repositório de configuração.

FeatureFlagConfigurationSetting setting = (FeatureFlagConfigurationSetting)
    configurationClient.setConfigurationSetting(featureFlagConfigurationSetting);
SecretReferenceConfigurationSetting setting = (SecretReferenceConfigurationSetting)
    configurationClient.setConfigurationSetting(referenceConfigurationSetting);

Excluir uma configuração

Exclua uma configuração existente chamando deleteConfigurationSetting.

ConfigurationSetting setting = configurationClient.setConfigurationSetting("some_key", "some_label", "some_value");
ConfigurationSetting deletedSetting = configurationClient.deleteConfigurationSetting("some_key", "some_label");

Para solicitação condicional, se você quiser excluir condicionalmente uma configuração, defina o ifUnchanged parâmetro como true. Quando ifUnchanged o parâmetro for true. Quando ifUnchanged for true, a configuração só será excluída se for igual à determinada setting. Isso é determinado comparando a ETag do setting com aquele no serviço para ver se eles são iguais ou não. Se a ETag for a mesma, isso significa que a configuração é a mesma e seu valor é excluído.

ConfigurationSetting setting = configurationClient.setConfigurationSetting("some_key", "some_label", "some_value");
Response<ConfigurationSetting> settingResponse = configurationClient.deleteConfigurationSettingWithResponse(setting, true, Context.NONE);

Exclua uma definição de configuração do Sinalizador de Recurso ou uma configuração de Referência secreta no repositório de configuração.

FeatureFlagConfigurationSetting setting = (FeatureFlagConfigurationSetting)
    configurationClient.deleteConfigurationSetting(featureFlagConfigurationSetting);
SecretReferenceConfigurationSetting setting = (SecretReferenceConfigurationSetting)
    configurationClient.deleteConfigurationSetting(referenceConfigurationSetting);

Listar definições de configuração com várias chaves

Liste várias definições de configuração chamando listConfigurationSettings. Passe um nulo SettingSelector para o método se você quiser buscar todas as definições de configuração e seus campos.

String key = "some_key";
String key2 = "new_key";
configurationClient.setConfigurationSetting(key, "some_label", "some_value");
configurationClient.setConfigurationSetting(key2, "new_label", "new_value");
SettingSelector selector = new SettingSelector().setKeyFilter(key + "," + key2);
PagedIterable<ConfigurationSetting> settings = configurationClient.listConfigurationSettings(selector);

Listar revisões de várias configurações

Liste todas as revisões de uma configuração chamando listRevisions.

String key = "revisionKey";
configurationClient.setConfigurationSetting(key, "some_label", "some_value");
configurationClient.setConfigurationSetting(key, "new_label", "new_value");
SettingSelector selector = new SettingSelector().setKeyFilter(key);
PagedIterable<ConfigurationSetting> settings = configurationClient.listRevisions(selector);

Definir uma configuração para somente leitura

Defina uma configuração como somente leitura status.

configurationClient.setConfigurationSetting("some_key", "some_label", "some_value");
ConfigurationSetting setting = configurationClient.setReadOnly("some_key", "some_label", true);

Limpar somente leitura de uma configuração

Limpe somente leitura de uma definição de configuração.

ConfigurationSetting setting = configurationClient.setReadOnly("some_key", "some_label", false);

Criar um cliente com opções de proxy

Crie um cliente de configuração com opções de proxy.

// Proxy options
final String hostname = "{your-host-name}";
final int port = 447; // your port number

ProxyOptions proxyOptions = new ProxyOptions(ProxyOptions.Type.HTTP,
    new InetSocketAddress(hostname, port));
HttpClient httpClient = new NettyAsyncHttpClientBuilder()
    .proxy(proxyOptions)
    .build();
ConfigurationAsyncClient configurationAsyncClient = new ConfigurationClientBuilder()
    .connectionString("{your_connection_string}")
    .httpClient(httpClient)
    .buildAsyncClient();

Solução de problemas

Geral

Quando você interage com Configuração de Aplicativos usando essa biblioteca de clientes Java, os erros retornados pelo serviço correspondem aos mesmos códigos http status retornados para solicitações da API REST. Por exemplo, se você tentar recuperar uma configuração que não existe no repositório de configuração, um 404 erro será retornado, indicando Not Found.

Configuração de Aplicativos fornece uma maneira de definir cabeçalhos personalizados por meio Context do objeto na API pública.

// Add your headers
HttpHeaders headers = new HttpHeaders();
headers.set("my-header1", "my-header1-value");
headers.set("my-header2", "my-header2-value");
headers.set("my-header3", "my-header3-value");
// Call API by passing headers in Context.
configurationClient.addConfigurationSettingWithResponse(
    new ConfigurationSetting().setKey("key").setValue("value"),
    new Context(AddHeadersFromContextPolicy.AZURE_REQUEST_HTTP_HEADERS_KEY, headers));
// Above three HttpHeader will be added in outgoing HttpRequest.

Para obter mais informações detalhadas, marcar o AddHeadersFromContextPolicy

Cliente HTTP padrão

Por padrão, todas as bibliotecas de cliente usam o cliente HTTP do Netty. Adicionar a dependência acima configurará automaticamente a biblioteca de cliente para usar o cliente HTTP do Netty. A configuração ou a alteração do cliente HTTP é detalhada no wiki de clientes HTTP.

Biblioteca SSL padrão

Todas as bibliotecas de cliente, por padrão, usam a biblioteca SSL com o uso do Tomcat nativo para habilitar o desempenho de nível nativo para operações SSL. A biblioteca SSL é um uber jar que contém bibliotecas nativas para Linux/macOS/Windows e fornece melhor desempenho em comparação com a implementação SSL padrão no JDK. Para obter mais informações, incluindo como reduzir o tamanho da dependência, consulte a seção ajuste de desempenho da wiki.

Próximas etapas

Contribuição

Este projeto aceita contribuições e sugestões. A maioria das contribuições exige que você concorde com um CLA (Contrato de Licença do Colaborador) declarando que você tem o direito de nos conceder e de fato concede, os direitos de usar sua contribuição.

Quando você envia uma solicitação de pull, um bot do CLA determina automaticamente se você precisa fornecer um CLA e preencher a PR corretamente (por exemplo, rótulo, comentário). Basta seguir as instruções fornecidas pelo bot. Você só precisará fazer isso uma vez em todos os repositórios que usam nosso CLA.

Este projeto adotou o Código de Conduta de Software Livre da Microsoft. Para obter mais informações, confira as Perguntas frequentes sobre o Código de Conduta ou contate opencode@microsoft.com para enviar outras perguntas ou comentários.

Impressões