Client HTTP e pipeline nell'Azure SDK per Java

Questo articolo offre una panoramica dell'uso della funzionalità del client HTTP e della pipeline all'interno di Azure SDK per Java. Questa funzionalità offre un'esperienza coerente, potente e flessibile per gli sviluppatori che usano tutte le librerie di Azure SDK per Java.

Client HTTP

Azure SDK per Java viene implementato usando un'astrazione HttpClient. Questa astrazione consente un'architettura collegabile che accetta più librerie client HTTP o implementazioni personalizzate. Tuttavia, per semplificare la gestione delle dipendenze per la maggior parte degli utenti, tutte le librerie client di Azure dipendono da azure-core-http-netty. Di conseguenza, il client HTTP Netty è il client predefinito usato in tutte le librerie di Azure SDK per Java.

Importante

Assicurarsi che la dipendenza azure-core-http-netty usi la versione 1.15.12 o successiva. Se utilizzi un BOM, assicurati che la versione del BOM sia almeno 1.2.36.

Questa versione minima è necessaria per abilitare intestazioni HTTP di grandi dimensioni restituite da Azure Resource Manager durante le operazioni a esecuzione prolungata.

Anche se Netty è il client HTTP predefinito, l'SDK fornisce tre implementazioni client, a seconda delle dipendenze già presenti nel progetto. Queste implementazioni sono per:

Nota

Il HttpClient JDK in combinazione con Azure SDK per Java è supportato solo con JDK 12 e versioni successive.

Sostituire il client HTTP predefinito

Se si preferisce un'altra implementazione, rimuovere la dipendenza da Netty escludendola nei file di configurazione della compilazione. In un file Maven pom.xml, escludi la dipendenza Netty e includi un'altra dipendenza.

Nell'esempio seguente viene illustrato come escludere la dipendenza Netty da una dipendenza reale dalla azure-security-keyvault-secrets libreria. Assicurarsi di escludere Netty da tutte le librerie appropriate com.azure , come illustrato nell'esempio:

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

<!-- OkHttp -->
<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-core-http-okhttp</artifactId>
  <version>1.12.10</version>
</dependency>

<!-- JDK HttpClient -->
<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-core-http-jdk-httpclient</artifactId>
  <version>1.0.3</version>
</dependency>

Nota

Se si rimuove la dipendenza Netty ma non si specifica alcuna implementazione, l'applicazione non viene avviata. Un'implementazione di HttpClient deve esistere nel classpath.

Configurare i client HTTP

Quando crei un client di servizio, per impostazione predefinita viene utilizzato HttpClient.createDefault(). Questo metodo restituisce un'istanza di base HttpClient basata sull'implementazione del client HTTP fornita. Se è necessario un client HTTP più complesso, ad esempio un proxy, ogni implementazione offre un generatore che è possibile usare per costruire un'istanza configurata HttpClient . I costruttori sono NettyAsyncHttpClientBuilder, OkHttpAsyncHttpClientBuildere JdkAsyncHttpClientBuilder.

Gli esempi seguenti illustrano come compilare HttpClient istanze usando Netty, OkHttp e il client HTTP JDK. Queste istanze fanno il proxy tramite http://localhost:3128 ed eseguono l'autenticazione con l'utente example e la password 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 HttpClient
HttpClient client = new JdkAsyncHttpClientBuilder()
    .proxy(new ProxyOptions(ProxyOptions.Type.HTTP, new InetSocketAddress("localhost", 3128))
        .setCredentials("example", "weakPassword"))
    .build();

È ora possibile passare l'istanza di HttpClient costruita in un generatore di client del servizio per usarla come client per la comunicazione con il servizio. L'esempio seguente usa la nuova istanza di HttpClient per creare un client di archiviazione blob di Azure.

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

Per le librerie di gestione, impostare HttpClient durante la configurazione di Manager.

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

Pipeline HTTP

La pipeline HTTP è uno dei componenti chiave per ottenere coerenza e diagnosbilità nelle librerie client Java per Azure. Una pipeline HTTP è costituita da:

  • Un trasporto HTTP
  • Politiche della pipeline HTTP

È possibile fornire una pipeline HTTP personalizzata durante la creazione di un client. Se non si fornisce una pipeline, la libreria client ne crea una configurata per l'uso con tale libreria client specifica.

Trasporto HTTP

Il trasporto HTTP è responsabile della connessione al server e dell'invio e della ricezione di messaggi HTTP. Il trasporto HTTP costituisce il gateway per le librerie client di Azure SDK per interagire con i servizi di Azure. Come indicato in precedenza in questo articolo, Azure SDK per Java usa Netty per impostazione predefinita per il trasporto HTTP. Tuttavia, l'SDK fornisce anche un trasporto HTTP collegabile, in modo da poter usare altre implementazioni, se appropriato. L'SDK fornisce anche altre due implementazioni di trasporto HTTP per OkHttp e il client HTTP fornito con JDK 11 e versioni successive.

Politiche della pipeline HTTP

Una pipeline è costituita da una sequenza di passaggi eseguiti per ogni ciclo di richiesta/risposta HTTP. Ogni criterio ha uno scopo specifico e agisce su una richiesta, su una risposta o, a volte, su entrambe. Poiché tutte le librerie dei client hanno un livello "Azure Core" standard, questo livello garantisce che ogni politica venga eseguita in ordine nella pipeline. Quando si invia una richiesta, le politiche vengono eseguite nell'ordine in cui vengono aggiunte alla pipeline. Quando si riceve una risposta dal servizio, le politiche vengono eseguite nell'ordine inverso. Tutti i criteri aggiunti alla pipeline vengono eseguiti prima di inviare la richiesta e dopo aver ricevuto una risposta. Il criterio deve decidere se agire sulla richiesta, sulla risposta o su entrambi. Ad esempio, un criterio di registrazione registra la richiesta e la risposta, ma il criterio di autenticazione è interessato solo a modificare la richiesta.

Il framework di Azure Core fornisce i criteri con i dati di richiesta e risposta necessari insieme a qualsiasi contesto necessario per eseguire i criteri. La politica può quindi eseguire la sua operazione con i dati specificati e passare il controllo alla politica successiva nella pipeline.

Schermata della pipeline HTTP dell'SDK Azure per Java, che mostra l'ordine di esecuzione del livello di trasporto e dei criteri per richieste e risposte.

Posizione delle politiche della pipeline HTTP

Quando si effettuano richieste HTTP ai servizi cloud, è importante gestire gli errori temporanei e ripetere i tentativi non riusciti. Poiché questa funzionalità è un requisito comune, Azure Core fornisce un criterio di ripetizione dei tentativi in grado di controllare gli errori temporanei e ripetere automaticamente la richiesta.

Questo criterio di ripetizione dei tentativi suddivide quindi l'intera pipeline in due parti: i criteri eseguiti prima del criterio di ripetizione dei tentativi e dei criteri eseguiti dopo il criterio di ripetizione dei tentativi. I criteri aggiunti prima dei criteri di ritentativo vengono eseguiti una sola volta per ogni operazione API, mentre i criteri aggiunti dopo i criteri di ritentativo vengono eseguiti tante volte quanti sono i tentativi.

Pertanto, quando si compila la pipeline HTTP, è necessario capire se eseguire un criterio per ogni tentativo di richiesta o una volta per ogni operazione API.

Criteri comuni della pipeline HTTP

Le pipeline HTTP per i servizi basati su REST hanno configurazioni con criteri per l'autenticazione, i tentativi, la registrazione, la telemetria e l'ID della richiesta nell'intestazione. Azure Core include questi criteri HTTP comunemente necessari che è possibile aggiungere alla pipeline.

Politica Collegamento a GitHub
politica di ripetizione dei tentativi RetryPolicy.java
criteri di autenticazione BearerTokenAuthenticationPolicy.java
politica di registrazione HttpLoggingPolicy.java
politica ID richiesta RequestIdPolicy.java
criteri di telemetria UserAgentPolicy.java

Politica della pipeline HTTP personalizzata

I criteri della pipeline HTTP forniscono un meccanismo pratico per modificare o decorare la richiesta e la risposta. È possibile aggiungere criteri personalizzati alla pipeline creata dall'utente o dallo sviluppatore della libreria client. Quando si aggiunge il criterio alla pipeline, è possibile specificare se questo criterio debba essere eseguito a ogni chiamata o a ogni tentativo.

Per creare un criterio di pipeline HTTP personalizzato, estendi un tipo di criterio di base e implementa un metodo astratto. È quindi possibile collegare la politica alla pipeline.

Intestazioni HTTP personalizzate nelle richieste

Le librerie client di Azure SDK per Java offrono un modo coerente per definire intestazioni personalizzate tramite oggetti Context nella API pubblica, come illustrato nell'esempio seguente:

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

Per altre informazioni, vedere la classe AddHeadersFromContextPolicy.

Libreria TLS/SSL predefinita

Per impostazione predefinita, tutte le librerie client usano la libreria SSL Boring nativa di Tomcat. Questa libreria offre prestazioni a livello nativo per le operazioni TLS/SSL. La libreria SSL boring è un file JAR uber che contiene librerie native per Linux, macOS e Windows. Offre prestazioni migliori rispetto all'implementazione TLS/SSL predefinita all'interno di JDK.

Ridurre la dimensione della dipendenza Tomcat-Native TLS/SSL

Per impostazione predefinita, gli SDK Azure per Java usano l'uber JAR della libreria Tomcat-Native Boring SSL. Per ridurre le dimensioni di questa dipendenza, includere la dipendenza con un os classificatore come descritto in netty-tcnative, come illustrato nell'esempio seguente:

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

Usare JDK TLS/SSL

Se si preferisce usare il protocollo TLS/SSL JDK predefinito anziché Tomcat-Native SSL boring, escludere la libreria SSL boring nativa di Tomcat. In base ai test, le prestazioni di TLS/SSL JDK sono pari a 30% più lente rispetto a Tomcat-Native SSL boring. Quando si utilizza com.azure:azure-core:1.28.0 o una versione successiva, la libreria di implementazione HttpClient(ad esempio com.azure:azure-core-http-netty) gestisce la dipendenza da Boring SSL di Tomcat-Native. Per escludere la dipendenza, aggiungere la configurazione seguente al file 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>

Passaggi successivi

Ora che hai familiarità con la funzionalità client HTTP nell'Azure SDK per Java, impara come personalizzare ulteriormente il client HTTP che stai utilizzando. Per altre informazioni, vedere Configurare i proxy in Azure SDK per Java.