Condividi tramite


Databricks SDK per Java

Questo articolo illustra come automatizzare le operazioni in account, aree di lavoro e risorse correlate di Azure Databricks con Databricks SDK per Java. Questo articolo integra Databricks SDK per Java README, informazioni di riferimento sulle API ed esempi.

Nota

Questa funzionalità è in versione beta e può essere usata nell'ambiente di produzione.

Durante il periodo beta, Databricks consiglia di aggiungere una dipendenza dalla versione secondaria specifica di Databricks SDK per Java da cui dipende il codice. Ad esempio, è possibile aggiungere dipendenze nei file, pom.xml ad esempio per Maven. Per altre informazioni sull'aggiunta delle dipendenze, vedere Introduzione al meccanismo di dipendenza.

Operazioni preliminari

Prima di iniziare a usare Databricks SDK per Java, il computer di sviluppo deve avere:

  • Autenticazione di Azure Databricks configurata.
  • Java Development Kit (JDK) compatibile con Java 8 o versione successiva. I test di integrazione continua con Databricks SDK per Java sono compatibili con Java versioni 8, 11, 17 e 20.
  • È consigliabile un ambiente di sviluppo integrato compatibile con Java. Databricks consiglia IntelliJ IDEA.

Introduzione a Databricks SDK per Java

  1. Nel file del progetto indicare al sistema di pom.xml compilazione di accettare una dipendenza da Databricks SDK per Java. A tale scopo, aggiungere quanto segue <dependency> alla pom.xml sezione esistente <dependencies> del file. Se la <dependencies> sezione non esiste già all'interno del pom.xml file, è necessario aggiungere anche l'elemento <dependencies> padre al pom.xml file.

    Ad esempio, per aprire il file del pom.xml progetto in IntelliJ IDEA, fare clic su Visualizza > progetto finestre > strumento e quindi fare doppio clic per aprire il file src > nome-progetto> pom.xml.

    <dependencies>
      <dependency>
        <groupId>com.databricks</groupId>
        <artifactId>databricks-sdk-java</artifactId>
        <version>0.0.1</version>
      </dependency>
    </dependencies>
    

    Nota

    Assicurarsi di sostituire 0.0.1 con la versione più recente di Databricks SDK per Java. È possibile trovare la versione più recente nel repository centrale Maven.

  2. Indicare al progetto di accettare la dipendenza dichiarata da Databricks SDK per Java. Ad esempio, in IntelliJ IDEA, nella finestra dello strumento Progetto del progetto fare clic con il pulsante destro del mouse sul nodo radice del progetto e quindi scegliere Ricarica progetto.

  3. Aggiungere il codice per importare Databricks SDK per Java e elencare tutti i cluster nell'area di lavoro di Azure Databricks. Ad esempio, nel file di Main.java un progetto il codice potrebbe essere il seguente:

    import com.databricks.sdk.WorkspaceClient;
    import com.databricks.sdk.service.compute.ClusterInfo;
    import com.databricks.sdk.service.compute.ListClustersRequest;
    
    public class Main {
      public static void main(String[] args) {
        WorkspaceClient w = new WorkspaceClient();
    
        for (ClusterInfo c : w.clusters().list(new ListClustersRequest())) {
          System.out.println(c.getClusterName());
        }
      }
    }
    

    Nota

    Non impostando argomenti nella chiamata precedente a WorkspaceClient w = new WorkspaceClient(), Databricks SDK per Java usa il processo predefinito per tentare di eseguire l'autenticazione di Azure Databricks. Per eseguire l'override di questo comportamento predefinito, vedere la sezione di autenticazione seguente.

  4. Crea il progetto. Ad esempio, per eseguire questa operazione in IntelliJ IDEA, scegliere Compila > progetto di compilazione dal menu principale.

  5. Eseguire il file principale. Ad esempio, per eseguire questa operazione in IntelliJ IDEA per il file di Main.java un progetto, dal menu principale fare clic su Esegui > 'Main'.

  6. Viene visualizzato l'elenco dei cluster. Ad esempio, in IntelliJ IDEA, si trova nella finestra Esegui strumento. Per visualizzare questa finestra degli strumenti, scegliere Visualizza > esecuzione strumento> dal menu principale.

Autenticare Databricks SDK per Java con l'account o l'area di lavoro di Azure Databricks

Databricks SDK per Java implementa lo standard di autenticazione unificata del client Databricks, un approccio architetturale e programmatico consolidato e coerente all'autenticazione. Questo approccio consente di configurare e automatizzare l'autenticazione con Azure Databricks più centralizzato e prevedibile. Consente di configurare l'autenticazione di Databricks una sola volta e quindi di usarla tra più strumenti e SDK di Databricks senza ulteriori modifiche alla configurazione dell'autenticazione. Per altre informazioni, inclusi esempi di codice più completi in Java, vedere Autenticazione unificata del client Databricks.

Nota

Databricks SDK per Java non ha ancora implementato l'autenticazione delle identità gestite di Azure.

Alcuni dei modelli di codifica disponibili per inizializzare l'autenticazione di Databricks con Databricks SDK per Java includono:

  • Usare l'autenticazione predefinita di Databricks eseguendo una delle operazioni seguenti:

    • Creare o identificare un profilo di configurazione di Databricks personalizzato con i campi obbligatori per il tipo di autenticazione databricks di destinazione. Impostare quindi la DATABRICKS_CONFIG_PROFILE variabile di ambiente sul nome del profilo di configurazione personalizzato.
    • Impostare le variabili di ambiente necessarie per il tipo di autenticazione di Databricks di destinazione.

    Creare quindi un'istanza di un WorkspaceClient oggetto con l'autenticazione predefinita di Databricks come indicato di seguito:

    import com.databricks.sdk.WorkspaceClient;
    // ...
    WorkspaceClient w = new WorkspaceClient();
    // ...
    
  • Il hardcoded dei campi obbligatori è supportato ma non consigliato, perché rischia di esporre informazioni riservate nel codice, ad esempio i token di accesso personale di Azure Databricks. L'esempio seguente imposta come hardcoded azure Databricks host e valori dei token di accesso per l'autenticazione del token di Databricks:

    import com.databricks.sdk.WorkspaceClient;
    import com.databricks.sdk.core.DatabricksConfig;
    // ...
    DatabricksConfig cfg = new DatabricksConfig()
      .setHost("https://...")
      .setToken("...");
    WorkspaceClient w = new WorkspaceClient(cfg);
    // ...
    

Vedere anche Autenticazione in Databricks SDK per Java README.

Usare le utilità di Databricks e Java con Databricks SDK per Java

Databricks Utilities offre diverse funzioni helper per semplificare l'uso dell'archiviazione di oggetti in modo efficiente, concatenare e parametrizzare i notebook e usare segreti. Databricks offre una libreria Databricks Utilities per Scala , che è possibile chiamare con codice Java, per consentire di accedere a livello di codice alle utilità di Databricks.

Per usare il codice Java per chiamare le utilità di Databricks per Scala, eseguire le operazioni seguenti:

  1. Nel progetto Java dichiarare una dipendenza da Databricks SDK per Java, come descritto nella sezione precedente.

  2. Dichiarare una dipendenza dalle utilità di Databricks per la libreria Scala. A tale scopo, aggiungere quanto segue <dependency> alla pom.xml sezione esistente <dependencies> del file:

    <dependency>
      <groupId>com.databricks</groupId>
      <artifactId>databricks-dbutils-scala_2.12</artifactId>
      <version>0.1.4</version>
    </dependency>
    

    Nota

    Assicurarsi di sostituire 0.1.4 con la versione più recente della libreria Databricks Utilities for Scala. È possibile trovare la versione più recente nel repository centrale Maven.

  3. Indicare al progetto di accettare la dipendenza dichiarata dalle utilità di Databricks per Scala. Ad esempio, in IntelliJ IDEA, nella finestra dello strumento Project del progetto fare clic sul nodo radice del progetto e quindi su Maven > Reload Project.

  4. Aggiungere il codice da importare e quindi chiamare l'utilità Databricks per Scala. Ad esempio, il codice seguente automatizza un volume del catalogo Unity. Questo esempio crea un file denominato zzz_hello.txt nel percorso del volume all'interno dell'area di lavoro, legge i dati dal file e quindi elimina il file:

    import com.databricks.sdk.core.DatabricksConfig;
    import com.databricks.sdk.scala.dbutils.DBUtils;
    
    public class Main {
      public static void main(String[] args) {
        String filePath = "/Volumes/main/default/my-volume/zzz_hello.txt";
        String fileData = "Hello, Databricks!";
        DBUtils dbutils = DBUtils.getDBUtils(new DatabricksConfig().setProfile("DEFAULT"));
    
        dbutils.fs().put(filePath, fileData, true);
    
        System.out.println(dbutils.fs().head(filePath, 18));
    
        dbutils.fs().rm(filePath, false);
      }
    }
    
  5. Compilare il progetto ed eseguire il file principale.

Esempi di codice

Gli esempi di codice seguenti illustrano come usare Databricks SDK per Java per creare ed eliminare cluster, creare processi ed elencare gruppi a livello di account. Questi esempi di codice usano il processo di autenticazione predefinito di Azure Databricks SDK per Java.

Per altri esempi di codice, vedere la cartella degli esempi nel repository Databricks SDK per Java in GitHub.

Creare un cluster

Questo esempio di codice crea un cluster con la versione di Databricks Runtime e il tipo di nodo del cluster specificati. Questo cluster ha un ruolo di lavoro e il cluster terminerà automaticamente dopo 15 minuti di inattività.

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.compute.CreateCluster;
import com.databricks.sdk.service.compute.CreateClusterResponse;

public class Main {
  public static void main(String[] args) {
    WorkspaceClient w = new WorkspaceClient();

    CreateClusterResponse c = w.clusters().create(
      new CreateCluster()
        .setClusterName("my-cluster")
        .setSparkVersion("12.2.x-scala2.12")
        .setNodeTypeId("Standard_DS3_v2")
        .setAutoterminationMinutes(15L)
        .setNumWorkers(1L)
    ).getResponse();

    System.out.println("View the cluster at " +
      w.config().getHost() +
      "#setting/clusters/" +
      c.getClusterId() +
      "/configuration\n");
  }
}

Creare un cluster che usa JDK 17

Nota

JDK 8 è completamente supportato. JDK 17 è disponibile in anteprima pubblica per Databricks Runtime versioni 13.1 e successive.

Questa sezione fornisce una guida alla creazione di un cluster con Java Development Kit (JDK). Informazioni su come creare un cluster con JDK 17 per usare Java nei notebook e nei processi.

Quando si crea un cluster, specificare che il cluster usa JDK 17 sia per il driver che per l'executor aggiungendo la variabile di ambiente seguente a Opzioni avanzate Variabili >di ambiente Spark>:

JNAME=zulu17-ca-amd64

Eliminare definitivamente un cluster

Questo esempio di codice elimina definitivamente il cluster con l'ID cluster specificato dall'area di lavoro.

import com.databricks.sdk.WorkspaceClient;
import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    System.out.println("ID of cluster to delete (for example, 1234-567890-ab123cd4):");

    Scanner in = new Scanner(System.in);
    String c_id = in.nextLine();
    WorkspaceClient w = new WorkspaceClient();

    w.clusters().permanentDelete(c_id);
  }
}

Creare un processo

Questo esempio di codice crea un processo di Azure Databricks che può essere usato per eseguire il notebook specificato nel cluster specificato. Durante l'esecuzione di questo codice, ottiene il percorso del notebook esistente, l'ID cluster esistente e le impostazioni del processo correlate dall'utente nel terminale.

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.jobs.JobTaskSettings;
import com.databricks.sdk.service.jobs.NotebookTask;
import com.databricks.sdk.service.jobs.NotebookTaskSource;
import com.databricks.sdk.service.jobs.CreateResponse;
import com.databricks.sdk.service.jobs.CreateJob;

import java.util.Scanner;
import java.util.Map;
import java.util.Collection;
import java.util.Arrays;

public class Main {
  public static void main(String[] args) {
    System.out.println("Some short name for the job (for example, my-job):");
    Scanner in = new Scanner(System.in);
    String jobName = in.nextLine();

    System.out.println("Some short description for the job (for example, My job):");
    String description = in.nextLine();

    System.out.println("ID of the existing cluster in the workspace to run the job on (for example, 1234-567890-ab123cd4):");
    String existingClusterId = in.nextLine();

    System.out.println("Workspace path of the notebook to run (for example, /Users/someone@example.com/my-notebook):");
    String notebookPath = in.nextLine();

    System.out.println("Some key to apply to the job's tasks (for example, my-key): ");
    String taskKey = in.nextLine();

    System.out.println("Attempting to create the job. Please wait...");

    WorkspaceClient w = new WorkspaceClient();

    Map<String, String> map = Map.of("", "");

    Collection<JobTaskSettings> tasks = Arrays.asList(new JobTaskSettings()
      .setDescription(description)
      .setExistingClusterId(existingClusterId)
      .setNotebookTask(new NotebookTask()
        .setBaseParameters(map)
        .setNotebookPath(notebookPath)
        .setSource(NotebookTaskSource.WORKSPACE))
      .setTaskKey(taskKey)
    );

    CreateResponse j = w.jobs().create(new CreateJob()
      .setName(jobName)
      .setTasks(tasks)
    );

    System.out.println("View  the job at " +
      w.config().getHost() +
      "/#job/" +
      j.getJobId()
    );
  }
}

Elencare i gruppi a livello di account

Questo esempio di codice elenca i nomi visualizzati per tutti i gruppi disponibili all'interno dell'account Azure Databricks.

import com.databricks.sdk.AccountClient;
import com.databricks.sdk.core.DatabricksConfig;
import com.databricks.sdk.service.iam.Group;
import com.databricks.sdk.service.iam.ListAccountGroupsRequest;

public class Main {
  public static void main(String[] args) {
    AccountClient a = new AccountClient();

    for (Group g : a.groups().list((new ListAccountGroupsRequest()))) {
      System.out.println(g.getDisplayName());
    }
  }
}

Usare Scala con Databricks SDK per Java

È possibile usare progetti Scala con Databricks SDK per Java. Prima di iniziare, il computer di sviluppo deve avere:

  • Autenticazione di Azure Databricks configurata.
  • È consigliabile un ambiente di sviluppo integrato compatibile con Scala. Databricks consiglia IntelliJ IDEA con il plug-in Scala. Queste istruzioni sono state testate con IntelliJ IDEA Community Edition 2023.3.6. Se si usa una versione o un'edizione diversa di IntelliJ IDEA, le istruzioni seguenti possono variare.
  • Java Development Kit (JDK) compatibile con Java 8 o versione successiva. Se si vogliono eseguire le applicazioni o usare le librerie in un cluster Azure Databricks, Databricks consiglia di usare una versione di JDK corrispondente alla versione JDK nel cluster. Per trovare la versione di JDK inclusa in un runtime di Databricks specifico, vedere Versioni e compatibilità delle note sulla versione di Databricks Runtime. Se si usa IntelliJ IDEA, è possibile scegliere un'installazione JDK locale esistente o installare un nuovo JDK in locale durante la creazione del progetto Scala.
  • Strumento di compilazione Scala. Databricks consiglia sbt. Se si usa IntelliJ IDEA, è possibile scegliere la versione da usare durante la sbt creazione del progetto Scala.
  • Scala. Se si vogliono eseguire le applicazioni o usare le librerie in un cluster Di Azure Databricks, Databricks consiglia di usare una versione di Scala corrispondente alla versione scala nel cluster. Per trovare la versione scala inclusa in un runtime di Databricks specifico, vedere Versioni e compatibilità delle note sulla versione di Databricks Runtime. Se si usa IntelliJ IDEA, è possibile scegliere la versione scala da usare durante la creazione del progetto Scala.

Per configurare, compilare ed eseguire il progetto Scala:

  1. Nel file del build.sbt progetto prendere una dipendenza dalla libreria Databricks SDK per Java aggiungendo la riga seguente alla fine del file e quindi salvare il file:

    libraryDependencies += "com.databricks" % "databricks-sdk-java" % "0.2.0"
    

    Nota

    Assicurarsi di sostituire 0.2.0 con la versione più recente della libreria Databricks SDK per Java. È possibile trovare la versione più recente nel repository centrale Maven.

  2. Indicare al progetto di accettare la dipendenza dichiarata da Databricks SDK per Java. Ad esempio, in IntelliJ IDEA fare clic sull'icona di notifica Carica modifiche sbt .

  3. Aggiungere il codice per importare Databricks SDK per Java e elencare tutti i cluster nell'area di lavoro di Azure Databricks. Ad esempio, nel file di Main.scala un progetto il codice potrebbe essere il seguente:

    import com.databricks.sdk.WorkspaceClient
    import com.databricks.sdk.service.compute.ListClustersRequest
    
    object Main {
      def main(args: Array[String]): Unit = {
        val w = new WorkspaceClient()
    
        w.clusters().list(new ListClustersRequest()).forEach{
          elem => println(elem.getClusterName)
        }
      }
    }
    

    Nota

    Non impostando argomenti nella chiamata precedente a val w = new WorkspaceClient(), Databricks SDK per Java usa il processo predefinito per tentare di eseguire l'autenticazione di Azure Databricks. Per eseguire l'override di questo comportamento predefinito, vedere la sezione di autenticazione seguente.

  4. Crea il progetto. Ad esempio, per eseguire questa operazione in IntelliJ IDEA, scegliere Compila > progetto di compilazione dal menu principale.

  5. Eseguire il file principale. Ad esempio, per eseguire questa operazione in IntelliJ IDEA per il file di Main.scala un progetto, dal menu principale fare clic su Esegui ' > Main.scala'.

  6. Viene visualizzato l'elenco dei cluster. Ad esempio, in IntelliJ IDEA, si trova nella finestra Esegui strumento. Per visualizzare questa finestra degli strumenti, scegliere Visualizza > esecuzione strumento> dal menu principale.

Usare le utilità di Databricks e Scala con Databricks SDK per Java

Databricks Utilities offre diverse funzioni helper per semplificare l'uso dell'archiviazione di oggetti in modo efficiente, concatenare e parametrizzare i notebook e usare segreti. Databricks fornisce una libreria Databricks utilities per Scala per consentire l'accesso a livello di codice alle utilità di Databricks con Scala.

Per chiamare le utilità di Databricks per Scala, eseguire le operazioni seguenti:

  1. Nel progetto Scala dichiarare una dipendenza da Databricks SDK per Java, come descritto nella sezione precedente.

  2. Dichiarare una dipendenza dalle utilità di Databricks per la libreria Scala. Ad esempio, nel file del build.sbt progetto aggiungere la riga seguente alla fine del file e quindi salvare il file:

    libraryDependencies += "com.databricks" % "databricks-dbutils-scala_2.12" % "0.1.4"
    

    Nota

    Assicurarsi di sostituire 0.1.4 con la versione più recente della libreria Databricks Utilities for Scala. È possibile trovare la versione più recente nel repository centrale Maven.

  3. Indicare al progetto di accettare la dipendenza dichiarata dalle utilità di Databricks per Scala. Ad esempio, in IntelliJ IDEA fare clic sull'icona di notifica Carica modifiche sbt .

  4. Aggiungere il codice da importare e quindi chiamare l'utilità Databricks per Scala. Ad esempio, il codice seguente automatizza un volume del catalogo Unity. Questo esempio crea un file denominato zzz_hello.txt nel percorso del volume all'interno dell'area di lavoro, legge i dati dal file e quindi elimina il file:

    import com.databricks.sdk.scala.dbutils.DBUtils
    
    object Main {
      def main(args: Array[String]): Unit = {
        val filePath = "/Volumes/main/default/my-volume/zzz_hello.txt"
        val fileData = "Hello, Databricks!"
        val dbutils = DBUtils.getDBUtils()
    
        dbutils.fs.put(
          file = filePath,
          contents = fileData,
          overwrite = true
        )
    
        println(dbutils.fs.head(filePath))
    
        dbutils.fs.rm(filePath)
      }
    }
    

    Nota

    Non impostando argomenti nella chiamata precedente a val dbutils = DBUtils.getDBUtils(), Databricks Utilities for Scala usa il processo predefinito per tentare di eseguire l'autenticazione di Azure Databricks.

    Per eseguire l'override di questo comportamento predefinito, passare un oggetto di cui è stata creata DatabricksCfg un'istanza come argomento a getDBUtils. Per altre informazioni, vedere la sezione relativa all'autenticazione precedente.

    Si noti, tuttavia, che se il codice è in esecuzione all'interno di Databricks Runtime, questo DatabricksCfg oggetto viene ignorato. Ciò è dovuto al fatto che le utilità di Databricks per i delegati Scala alle utilità databricks predefinite durante l'esecuzione all'interno del runtime di Databricks.

  5. Compilare il progetto ed eseguire il file principale.

Test in corso

Per testare il codice, usare framework di test Java come JUnit. Per testare il codice in condizioni simulate senza chiamare gli endpoint dell'API REST di Azure Databricks o modificare lo stato degli account o delle aree di lavoro di Azure Databricks, usare librerie java fittizie come Mockito.

Ad esempio, dato il file seguente denominato Helpers.java contenente una createCluster funzione che restituisce informazioni sul nuovo cluster:

// Helpers.java

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.compute.CreateCluster;
import com.databricks.sdk.service.compute.CreateClusterResponse;

public class Helpers {
  static CreateClusterResponse createCluster(
    WorkspaceClient w,
    CreateCluster   createCluster,
    String          clusterName,
    String          sparkVersion,
    String          nodeTypeId,
    Long            autoTerminationMinutes,
    Long            numWorkers
  ) {
    return w.clusters().create(
      createCluster
        .setClusterName(clusterName)
        .setSparkVersion(sparkVersion)
        .setNodeTypeId(nodeTypeId)
        .setAutoterminationMinutes(autoTerminationMinutes)
        .setNumWorkers(numWorkers)
    ).getResponse();
  }
}

E dato il file seguente denominato Main.java che chiama la createCluster funzione:

// Main.java

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.service.compute.CreateCluster;
import com.databricks.sdk.service.compute.CreateClusterResponse;

public class Main {
  public static void main(String[] args) {
    WorkspaceClient w = new WorkspaceClient();
    // Replace <spark-version> with the target Spark version string.
    // Replace <node-type-id> with the target node type string.
    CreateClusterResponse c = Helpers.createCluster(
      w,
      new CreateCluster(),
      "My Test Cluster",
      "<spark-version>",
      "<node-type-id>",
      15L,
      1L
    );
    System.out.println(c.getClusterId());
  }
}

Il file seguente denominato HelpersTest.java verifica se la createCluster funzione restituisce la risposta prevista. Anziché creare un cluster nell'area di lavoro di destinazione, questo test simula un WorkspaceClient oggetto, definisce le impostazioni dell'oggetto fittizio e quindi passa l'oggetto fittizio alla createCluster funzione. Il test verifica quindi se la funzione restituisce l'ID previsto del nuovo cluster fittizio.

// HelpersTest.java

import com.databricks.sdk.WorkspaceClient;
import com.databricks.sdk.mixin.ClustersExt;
import com.databricks.sdk.service.compute.ClusterDetails;
import com.databricks.sdk.service.compute.CreateCluster;
import com.databricks.sdk.support.Wait;
import com.databricks.sdk.service.compute.CreateClusterResponse;
import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class HelpersTest {
  @Test
  public void testCreateCluster() {
    WorkspaceClient mockWorkspaceClient = Mockito.mock(WorkspaceClient.class);
    ClustersExt mockClustersExt = Mockito.mock(ClustersExt.class);
    CreateCluster mockCreateCluster = new CreateCluster();
    Wait<ClusterDetails, CreateClusterResponse> mockWait = Mockito.mock(Wait.class);
    CreateClusterResponse mockResponse = Mockito.mock(CreateClusterResponse.class);

    Mockito.when(mockWorkspaceClient.clusters()).thenReturn(mockClustersExt);
    Mockito.when(mockClustersExt.create(Mockito.any(CreateCluster.class))).thenReturn(mockWait);
    Mockito.when(mockWait.getResponse()).thenReturn(mockResponse);

    // Replace <spark-version> with the target Spark version string.
    // Replace <node-type-id> with the target node type string.
    CreateClusterResponse response = Helpers.createCluster(
      mockWorkspaceClient,
      mockCreateCluster,
      "My Test Cluster",
      "<spark-version>",
      "<node-type-id>",
      15L,
      1L
    );
    assertEquals(mockResponse, response);
  }
}

Risorse aggiuntive

Per altre informazioni, vedi: