Compartir vía


Clientes y canalizaciones HTTP en Azure SDK para Java

En este artículo se proporciona información general sobre el uso de la funcionalidad de clientes y canalizaciones HTTP en Azure SDK para Java. Esta funcionalidad proporciona una experiencia coherente, eficaz y flexible para los desarrolladores que usan todas las bibliotecas de Azure SDK para Java.

Clientes HTTP

Azure SDK para Java se implementa mediante la abstracción HttpClient. Esta abstracción habilita una arquitectura conectable que acepta varias bibliotecas cliente HTTP o implementaciones personalizadas. Sin embargo, para simplificar la administración de dependencias para la mayoría de los usuarios, todas las bibliotecas cliente de Azure dependen de azure-core-http-netty. Por lo tanto, el cliente HTTP de Netty es el cliente predeterminado que se usa en todas las bibliotecas de Azure SDK para Java.

Aunque Netty es el cliente HTTP predeterminado, el SDK proporciona tres implementaciones de cliente, en función de las dependencias que ya tenga en el proyecto. Estas implementaciones son para:

Nota:

El JDK HttpClient en combinación con el SDK de Azure para Java solo se admite con JDK 12 y versiones posteriores.

Sustitución del cliente HTTP predeterminado

Si prefiere otra implementación, puede eliminar la dependencia de Netty mediante su exclusión de los archivos de configuración de compilación. En un archivo pom.xml de Maven, se excluye la dependencia de Netty y se incluye otra dependencia.

En el ejemplo siguiente se muestra cómo excluir la dependencia de Netty de una dependencia real en la biblioteca azure-security-keyvault-secrets. Asegúrese de excluir Netty de todas las bibliotecas com.azure apropiadas, como se muestra aquí:

<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:

Si quita la dependencia de Netty pero no proporciona ninguna implementación en su lugar, la aplicación no se puede iniciar. Debe existir una implementación de HttpClient en la ruta de clases.

Configuración de clientes HTTP

Al compilar un cliente de servicio, el valor predeterminado es usar HttpClient.createDefault(). Este método devuelve una instancia de HttpClient básica en función de la implementación del cliente HTTP proporcionada. En caso de que necesite un cliente HTTP más complejo, como un proxy, cada implementación ofrece un generador que le permite construir una instancia de HttpClient configurada. Los generadores son NettyAsyncHttpClientBuilder, OkHttpAsyncHttpClientBuilder y JdkAsyncHttpClientBuilder.

En los siguientes ejemplos se muestra cómo crear instancias de HttpClient mediante Netty, OkHttp y el cliente HTTP de JDK 11. Estas instancias se redirigen mediante proxy a través de http://localhost:3128 y se autentican con el usuario example y la contraseña 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();

Ahora puede pasar la instancia de HttpClient construida a un generador de cliente del servicio para su uso como cliente para comunicarse con el servicio. En el ejemplo siguiente se usa la nueva instancia de HttpClient para crear un cliente de Azure Storage Blob.

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

En el caso de las bibliotecas de administración, puede establecer la instancia de HttpClient durante la configuración del administrador.

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

Canalización HTTP

La canalización HTTP es uno de los componentes clave para lograr la coherencia y la capacidad de diagnóstico en las bibliotecas cliente de Java para Azure. Una canalización HTTP se compone de:

  • Un transporte HTTP
  • Directivas de canalización HTTP

Puede proporcionar su propia canalización HTTP personalizada al crear un cliente. Si no proporciona una canalización, la biblioteca cliente crea una configurada para trabajar con esa biblioteca cliente específica.

Transporte HTTP

El transporte HTTP es responsable de establecer la conexión con el servidor y de enviar y recibir mensajes HTTP. El transporte HTTP forma la puerta de enlace para que las bibliotecas cliente de Azure SDK interactúen con los servicios de Azure. Como se indicó anteriormente en este artículo, Azure SDK para Java usa Netty de forma predeterminada para su transporte HTTP. Sin embargo, el SDK también proporciona un transporte HTTP conectable para que pueda usar otras implementaciones cuando corresponda. El SDK también proporciona otras dos implementaciones de transporte HTTP para OkHttp y el cliente HTTP que se incluye con JDK 11 y versiones posteriores.

Directivas de canalización HTTP

Una canalización consta de una secuencia de pasos que se ejecutan para la ida y vuelta de cada solicitud-respuesta HTTP. Cada directiva tiene un propósito dedicado y actúa en una solicitud o una respuesta o a veces ambas. Dado que todas las bibliotecas cliente tienen una capa "Azure Core" estándar, esta capa garantiza que cada directiva se ejecute en orden en la canalización. Cuando se envía una solicitud, las directivas se ejecutan en el orden en el que se agregan a la canalización. Cuando se recibe una respuesta del servicio, las directivas se ejecutan en el orden inverso. Todas las directivas agregadas a la canalización se ejecutan antes de enviar la solicitud y después de recibir una respuesta. La directiva tiene que decidir si actúa en la solicitud, en la respuesta o en ambas. Por ejemplo, una directiva de registro registra la solicitud y la respuesta, pero la directiva de autenticación solo está interesada en modificar la solicitud.

Azure Core Framework proporciona la directiva con los datos de solicitud y respuesta necesarios junto con cualquier contexto necesario para ejecutar la directiva. A continuación, la directiva puede realizar su operación con los datos especificados y pasar el control a la siguiente directiva de la canalización.

HTTP pipeline diagram

Posición de la directiva de canalización HTTP

Cuando realiza solicitudes HTTP a servicios en la nube, es importante controlar los errores transitorios y reintentar los intentos con errores. Dado que esta funcionalidad es un requisito común, Azure Core proporciona una directiva de reintentos que puede inspeccionar los errores transitorios y reintentar automáticamente la solicitud.

Esta directiva de reintentos, por lo tanto, divide la canalización en dos partes: directivas que se ejecutan antes de la directiva de reintentos y directivas que se ejecutan después de la directiva de reintentos. Las directivas agregadas antes de la directiva de reintentos se ejecutan una sola vez por operación de API y las directivas agregadas después de la directiva de reintentos se ejecutan tantas veces como reintentos.

Por lo tanto, al crear la canalización HTTP, debe saber si desea ejecutar una directiva para cada reintento de solicitud o una vez por operación de API.

Directivas de canalización HTTP comunes

Las canalizaciones HTTP para servicios basados en REST tienen configuraciones con directivas para la autenticación, los reintentos, el registro, la telemetría y la especificación del identificador de solicitud en el encabezado. Azure Core se carga previamente con estas directivas HTTP habitualmente necesarias que puede agregar a la canalización.

Directiva Vínculo de GitHub
directiva de reintento RetryPolicy.java
directiva de autenticación BearerTokenAuthenticationPolicy.java
Directiva de registro HttpLoggingPolicy.java
directiva de identificador de solicitud RequestIdPolicy.java
directiva de telemetría UserAgentPolicy.java

Directiva de canalización HTTP personalizada

La directiva de canalización HTTP proporciona un mecanismo cómodo para modificar o decorar la solicitud y la respuesta. Puede agregar directivas personalizadas a la canalización que creó el usuario o el desarrollador de la biblioteca cliente. Al agregar la directiva a la canalización, puede especificar si esta directiva se debe ejecutar por llamada o por reintento.

Para crear una directiva de canalización HTTP personalizada, basta con extender un tipo de directiva base e implementar algún método abstracto. Después, puede conectar la directiva a la canalización.

Encabezados personalizados en solicitudes HTTP

Las bibliotecas cliente de Azure SDK para Java proporcionan una manera coherente de definir encabezados personalizados a través Context de objetos de la API pública, como se muestra en el ejemplo siguiente:

// 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 obtener más información, vea La clase AddHeadersFromContextPolicy.

Biblioteca TLS/SSL predeterminada

Todas las bibliotecas cliente, de forma predeterminada, usan la biblioteca SSL de Boring nativa de Tomcat para habilitar el rendimiento de nivel nativo para las operaciones TLS/SSL. La biblioteca SSL boring es un archivo JAR uber que contiene bibliotecas nativas para Linux, macOS y Windows, y proporciona un mejor rendimiento en comparación con la implementación predeterminada de TLS/SSL dentro del JDK.

Reducción del tamaño de dependencia de TLS/SSL nativo de Tomcat

De forma predeterminada, el uber JAR de la biblioteca SSL de Boring nativo de Tomcat se usa en los SDK de Azure para Java. Para reducir el tamaño de esta dependencia, debe incluir la dependencia con un os clasificador según netty-tcnative, como se muestra en el ejemplo siguiente:

<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>

Uso de TLS/SSL de JDK

Si prefiere usar el JDK TLS/SSL predeterminado en lugar de Tomcat-Native Boring SSL, debe excluir la biblioteca SSL de boring nativa de Tomcat. Tenga en cuenta que, en función de nuestras pruebas, el rendimiento de TLS/SSL de JDK es un 30 % más lento en comparación con Tomcat-Native Boring SSL. Cuando se usa com.azure:azure-core:1.28.0 o posterior, la HttpClientbiblioteca -implementing (como com.azure:azure-core-http-netty) administra la dependencia en Tomcat-Native Boring SSL. Para excluir la dependencia, agregue la siguiente configuración al archivo 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>

Pasos siguientes

Ahora que está familiarizado con la funcionalidad del cliente HTTP en El SDK de Azure para Java, aprenda a personalizar aún más el cliente HTTP que usa. Para más información, consulte Configuración de servidores proxy en El SDK de Azure para Java.