Clientes HTTP e pipelines no SDK do Azure para Java

Este artigo fornece uma visão geral do uso do cliente HTTP e da funcionalidade de pipeline no SDK do Azure para Java. Essa funcionalidade fornece uma experiência consistente, poderosa e flexível para desenvolvedores que usam todas as bibliotecas do SDK do Azure para Java.

Clientes HTTP

O SDK do Azure para Java é implementado usando uma HttpClient abstração. Essa abstração permite uma arquitetura conectável que aceita várias bibliotecas de cliente HTTP ou implementações personalizadas. No entanto, para simplificar o gerenciamento de dependência para a maioria dos usuários, todas as bibliotecas de cliente do Azure dependem do azure-core-http-netty. Como tal, o cliente Netty HTTP é o cliente padrão usado em todas as bibliotecas do SDK do Azure para Java.

Embora Netty seja o cliente HTTP padrão, o SDK fornece três implementações de cliente, dependendo de quais dependências você já tem em seu projeto. Estas implementações destinam-se a:

Nota

O JDK em combinação com o SDK do Azure para Java só é suportado com o JDK HttpClient 12 e superior.

Substitua o cliente HTTP padrão

Se preferir outra implementação, você pode remover a dependência do Netty excluindo-a nos arquivos de configuração de compilação. Em um arquivo pom.xml Maven, você exclui a dependência Netty e inclui outra dependência.

O exemplo a seguir mostra como excluir a dependência Netty de uma dependência real da azure-security-keyvault-secrets biblioteca. Certifique-se de excluir o Netty de todas as bibliotecas apropriadas com.azure , conforme mostrado aqui:

<dependency>
    <groupId>com.azure</groupId>
    <artifactId>azure-security-keyvault-secrets</artifactId>
    <version>4.2.2.</version>
    <exclusions>
      <exclusion>
        <groupId>com.azure</groupId>
        <artifactId>azure-core-http-netty</artifactId>
      </exclusion>
    </exclusions>
</dependency>

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-core-http-okhttp</artifactId>
  <version>1.3.3</version>
</dependency>

Nota

Se você remover a dependência Netty, mas não fornecer nenhuma implementação em seu lugar, o aplicativo não será iniciado. Uma HttpClient implementação deve existir no classpath.

Configurar clientes HTTP

Quando você cria um cliente de serviço, o padrão é usar HttpClient.createDefault()o . Esse método retorna uma instância básica HttpClient com base na implementação do cliente HTTP fornecida. Caso você precise de um cliente HTTP mais complexo, como um proxy, cada implementação oferece um construtor que permite construir uma instância configurada HttpClient . Os construtores são NettyAsyncHttpClientBuilder, OkHttpAsyncHttpClientBuildere JdkAsyncHttpClientBuilder.

Os exemplos a seguir mostram como criar HttpClient instâncias usando Netty, Okhttp e o cliente HTTP JDK 11. Essas instâncias fazem proxy e http://localhost:3128 autenticam com exemplo de usuário com senha weakPassword.

// Netty
HttpClient httpClient = new NettyAsyncHttpClientBuilder()
    .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
        .setCredentials("example", "weakPassword"))
    .build();

// OkHttp
HttpClient httpClient = new OkHttpAsyncHttpClientBuilder()
    .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
        .setCredentials("example", "weakPassword"))
    .build();

// JDK 11 HttpClient
HttpClient client = new JdkAsyncHttpClientBuilder()
    .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
        .setCredentials("example", "weakPassword"))
    .build();

Agora você pode passar a instância construída HttpClient para um construtor de cliente de serviço para uso como o cliente para comunicação com o serviço. O exemplo a seguir usa a nova HttpClient instância para criar um cliente de Blob de Armazenamento do Azure.

BlobClient blobClient = new BlobClientBuilder()
    .connectionString(<connection string>)
    .containerName("container")
    .blobName("blob")
    .httpClient(httpClient)
    .build();

Para bibliotecas de gerenciamento, você pode definir a configuração durante o HttpClient Manager.

AzureResourceManager azureResourceManager = AzureResourceManager.configure()
    .withHttpClient(httpClient)
    .authenticate(credential, profile)
    .withDefaultSubscription();

Pipeline HTTP

O pipeline HTTP é um dos principais componentes para obter consistência e capacidade de diagnóstico nas bibliotecas de cliente Java para Azure. Um pipeline HTTP é composto por:

  • Um transporte HTTP
  • Políticas de pipeline HTTP

Você pode fornecer seu próprio pipeline HTTP personalizado ao criar um cliente. Se você não fornecer um pipeline, a biblioteca de cliente criará uma configurada para trabalhar com essa biblioteca de cliente específica.

Transporte HTTP

O transporte HTTP é responsável por estabelecer a conexão com o servidor e enviar e receber mensagens HTTP. O transporte HTTP forma o gateway para as bibliotecas de cliente do SDK do Azure interagirem com os serviços do Azure. Conforme observado anteriormente neste artigo, o SDK do Azure para Java usa Netty por padrão para seu transporte HTTP. No entanto, o SDK também fornece um transporte HTTP conectável para que você possa usar outras implementações quando apropriado. O SDK também fornece mais duas implementações de transporte HTTP para OkHttp e o cliente HTTP fornecido com o JDK 11 e posterior.

Políticas de pipeline HTTP

Um pipeline consiste em uma sequência de etapas executadas para cada ida e volta de solicitação-resposta HTTP. Cada política tem um objetivo específico e atua de acordo com um pedido ou uma resposta ou, por vezes, ambos. Como todas as bibliotecas de cliente têm uma camada padrão 'Azure Core', essa camada garante que cada política seja executada em ordem no pipeline. Quando você envia uma solicitação, as políticas são executadas na ordem em que são adicionadas ao pipeline. Quando você recebe uma resposta do serviço, as políticas são executadas na ordem inversa. Todas as políticas adicionadas ao pipeline são executadas antes de enviar a solicitação e depois de receber uma resposta. A política tem de decidir se deve dar seguimento ao pedido, à resposta ou a ambos. Por exemplo, uma política de registro em log registra a solicitação e a resposta, mas a política de autenticação só está interessada em modificar a solicitação.

A estrutura do Azure Core fornece à política os dados de solicitação e resposta necessários, juntamente com qualquer contexto necessário para executar a política. A política pode então executar sua operação com os dados fornecidos e passar o controle para a próxima política no pipeline.

HTTP pipeline diagram

Posição da política de pipeline HTTP

Quando você faz solicitações HTTP para serviços de nuvem, é importante lidar com falhas transitórias e tentar novamente tentativas falhadas. Como essa funcionalidade é um requisito comum, o Azure Core fornece uma política de repetição que pode observar falhas transitórias e repetir automaticamente a solicitação.

Essa política de repetição, portanto, divide todo o pipeline em duas partes: políticas que são executadas antes da política de repetição e políticas que são executadas após a política de nova tentativa. As políticas adicionadas antes da política de repetição são executadas apenas uma vez por operação de API, e as políticas adicionadas após a política de repetição são executadas tantas vezes quanto as tentativas.

Portanto, ao criar o pipeline HTTP, você deve entender se deve executar uma política para cada nova tentativa de solicitação ou uma vez por operação de API.

Políticas comuns de pipeline HTTP

Os pipelines HTTP para serviços baseados em REST têm configurações com políticas para autenticação, tentativas, registro, telemetria e especificação da ID da solicitação no cabeçalho. O Azure Core é pré-carregado com essas políticas HTTP comumente necessárias que você pode adicionar ao pipeline.

Política Link do GitHub
Política de repetição RetryPolicy.java
política de autenticação BearerTokenAuthenticationPolicy.java
Política de registo HttpLoggingPolicy.java
política de ID de solicitação RequestIdPolicy.java
Política de telemetria UserAgentPolicy.java

Política de pipeline HTTP personalizada

A política de pipeline HTTP fornece um mecanismo conveniente para modificar ou decorar a solicitação e a resposta. Você pode adicionar políticas personalizadas ao pipeline que o usuário ou o desenvolvedor da biblioteca de cliente criou. Ao adicionar a política ao pipeline, você pode especificar se essa política deve ser executada por chamada ou por nova tentativa.

Para criar uma política de pipeline HTTP personalizada, basta estender um tipo de política base e implementar algum método abstrato. Em seguida, você pode conectar a política ao pipeline.

Cabeçalhos personalizados em solicitações HTTP

O SDK do Azure para bibliotecas de cliente Java fornece uma maneira consistente de definir cabeçalhos personalizados por meio de Context objetos na API pública, conforme mostrado no exemplo a seguir:

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

// The three headers are now be added to the outgoing HTTP request.

Para obter mais informações, consulte a classe AddHeadersFromContextPolicy.

Biblioteca TLS/SSL padrão

Todas as bibliotecas de cliente, por padrão, usam a biblioteca Boring SSL nativa do Tomcat para habilitar o desempenho de nível nativo para operações TLS/SSL. A biblioteca Boring SSL é um uber JAR contendo bibliotecas nativas para Linux, macOS e Windows, e fornece melhor desempenho em comparação com a implementação padrão de TLS/SSL dentro do JDK.

Reduza o tamanho da dependência de TLS/SSL nativo do Tomcat

Por padrão, o uber JAR da biblioteca SSL Boring do Tomcat-Native é usado em SDKs do Azure para Java. Para reduzir o tamanho dessa dependência, você precisa incluir a dependência com um os classificador como por netty-tcnative, conforme mostrado no exemplo a seguir:

<project>
  ...
  <dependencies>
    ...
    <dependency>
      <groupId>io.netty</groupId>
      <artifactId>netty-tcnative-boringssl-static</artifactId>
      <version>2.0.25.Final</version>
      <classifier>${os.detected.classifier}</classifier>
    </dependency>
    ...
  </dependencies>
  ...
  <build>
    ...
    <extensions>
      <extension>
        <groupId>kr.motd.maven</groupId>
        <artifactId>os-maven-plugin</artifactId>
        <version>1.4.0.Final</version>
      </extension>
    </extensions>
    ...
  </build>
  ...
</project>

Usar JDK TLS/SSL

Se você preferir usar o padrão JDK TLS/SSL em vez do Tomcat-Native Boring SSL, então você precisa excluir a biblioteca Boring SSL nativa do Tomcat. Esteja ciente de que, com base em nossos testes, o desempenho do JDK TLS/SSL é 30% mais lento em comparação com o Tomcat-Native Boring SSL. Quando você usa com.azure:azure-core:1.28.0 ou mais tarde, a biblioteca -implementing (como com.azure:azure-core-http-netty) gerencia a HttpClientdependência do Tomcat-Native Boring SSL. Para excluir a dependência, adicione a seguinte configuração ao arquivo POM:

<project>
  ...
  <dependencies>
    ...
    <dependency>
     <groupId>com.azure</groupId>
       <artifactId>azure-core-http-netty</artifactId>
       <version>1.13.6</version>
       <exclusions>
         <exclusion>
           <groupId>io.netty</groupId>
           <artifactId>netty-tcnative-boringssl-static</artifactId>
         </exclusion>
       </exclusions>
    </dependency>
    ...
  </dependencies>
  ...
</project>

Próximos passos

Agora que você está familiarizado com a funcionalidade do cliente HTTP no SDK do Azure para Java, saiba como personalizar ainda mais o cliente HTTP que você está usando. Para obter mais informações, consulte Configurar proxies no SDK do Azure para Java.