Guida per sviluppatori Java per Funzioni di AzureAzure Functions Java developer guide

Nota

Java per Funzioni di Azure è attualmente in versione di anteprima.Java for Azure Functions is currently in preview. Per ricevere aggiornamenti importanti, tra cui gli annunci relativi a modifiche di rilievo, monitorare il repository degli annunci del Servizio app di Azure.To receive important updates, including breaking changes announcements, watch the Azure App Service announcements repository.

Modello di programmazioneProgramming model

I concetti di trigger e binding sono fondamentali in Funzioni di Azure.The concepts of triggers and bindings are fundamental to Azure Functions. I trigger avviano l'esecuzione del codice,Triggers start the execution of your code. mentre i binding consentono la trasmissione dei dati e la restituzione dei dati da una funzione, senza dover scrivere codice personalizzato per l'accesso ai dati.Bindings give you a way to pass data to and return data from a function, without having to write custom data access code.

Una funzione deve essere un metodo senza stato per l'elaborazione di un input e la produzione di un output.A function should be a stateless method to process input and produce output. La funzione non deve dipendere dai campi di istanza della classe.Your function should not depend on any instance fields of the class. Tutti i metodi di funzione devono essere public e il metodo con annotazione @FunctionName deve essere univoco poiché il nome del metodo definisce la voce di una funzione.All the function methods should be public and method with annotation @FunctionName must be unique as method name defines the entry for a function.

Struttura di cartelleFolder structure

Di seguito è illustrata la struttura di cartelle di un progetto Java di Funzioni di Azure:Here is the folder structure of an Azure Function Java project:

FunctionsProject
 | - src
 | | - main
 | | | - java
 | | | | - FunctionApp
 | | | | | - MyFirstFunction.java
 | | | | | - MySecondFunction.java
 | - target
 | | - azure-functions
 | | | - FunctionApp
 | | | | - FunctionApp.jar
 | | | | - host.json
 | | | | - MyFirstFunction
 | | | | | - function.json
 | | | | - MySecondFunction
 | | | | | - function.json
 | | | | - bin
 | | | | - lib
 | - pom.xml

È presente un file host.json condiviso che può essere usato per configurare l'app per le funzioni.There's a shared host.json file that can be used to configure the function app. Ogni funzione ha il proprio file di codice (con estensione java) e il proprio file di configurazione delle associazioni (function.json).Each function has its own code file (.java) and binding configuration file (function.json).

È possibile inserire più funzioni in un progetto.You can put more than one function in a project. Evitare di inserire le funzioni in file con estensione jar separati.Avoid putting your functions into separate jars. L'elemento FunctionApp nella directory di destinazione viene distribuito all'app per le funzioni in Azure.The FunctionApp in the target directory is what gets deployed to your function app in Azure.

Trigger e annotazioniTriggers and annotations

Le funzioni di Azure vengono richiamate da un trigger, ad esempio una richiesta HTTP, un timer o un aggiornamento dati.Azure functions are invoked by a trigger, such as an HTTP request, a timer, or an update to data. La funzione deve elaborare tale trigger e qualsiasi altro input per generare uno o più output.Your function needs to process that trigger and any other inputs to produce one or more outputs.

Usare le annotazioni Java incluse nel pacchetto com.microsoft.azure.functions.annotation.* per associare input e output ai metodi dell'utente.Use the Java annotations included in the com.microsoft.azure.functions.annotation.* package to bind input and outputs to your methods. Per altre informazioni, vedere Documentazione di riferimento per Java.For more information see Java reference docs.

Importante

È necessario configurare un account di Archiviazione di Azure nel file local.settings.json per eseguire i trigger di BLOB del servizio di archiviazione di Azure o di code e tabelle di Azure.You must configure an Azure Storage account in your local.settings.json to run Azure Storage Blob, Queue, or Table triggers locally.

Esempio:Example:

public class Function {
    public String echo(@HttpTrigger(name = "req", 
      methods = {"post"},  authLevel = AuthorizationLevel.ANONYMOUS) 
        String req, ExecutionContext context) {
        return String.format(req);
    }
}

e il file function.json corrispondente generato da azure-functions-maven-plugin:here is the generated corresponding function.json by the azure-functions-maven-plugin:

{
  "scriptFile": "azure-functions-example.jar",
  "entryPoint": "com.example.Function.echo",
  "bindings": [
    {
      "type": "httpTrigger",
      "name": "req",
      "direction": "in",
      "authLevel": "anonymous",
      "methods": [ "post" ]
    },
    {
      "type": "http",
      "name": "$return",
      "direction": "out"
    }
  ]
}

Disponibilità del runtime JDK e supportoJDK runtime availability and support

Eseguire il download e usare i pacchetti JDK Azul Zulu per Azure di Azul Systems per lo sviluppo locale di app per le funzioni Java.Download and use the Azul Zulu for Azure JDKs from Azul Systems for local development of Java function apps. I pacchetti JDK sono disponibili per Windows, Linux e macOS.JDKs are available for Windows, Linux, and macOS. Il supporto di Azure è disponibile con un piano di supporto completo.Azure support is available with a qualified support plan.

Librerie di terze partiThird-party libraries

Funzioni di Azure supporta l'uso di librerie di terze parti.Azure Functions supports the use of third-party libraries. Per impostazione predefinita, tutte le dipendenze specificate nel file pom.xml del progetto verranno raggruppate automaticamente durante l'obiettivo mvn package.By default, all dependencies specified in your project pom.xml file will be automatically bundled during the mvn package goal. Inserire le librerie non specificate come dipendenze del file pom.xml in una directory lib nella directory radice della funzione.For libraries not specified as dependencies in the pom.xml file, place them in a lib directory in the function's root directory. Le dipendenze inserite nella directory lib verranno aggiunte al caricatore di classe di sistema in fase di esecuzione.Dependencies placed in the lib directory will be added to the system class loader at runtime.

La dipendenza com.microsoft.azure.functions:azure-functions-java-library è specificata in classpath per impostazione predefinita e non deve essere inclusa nella directory lib.The com.microsoft.azure.functions:azure-functions-java-library dependency is provided on the classpath by default, and does not need to be included in the lib directory. Le dipendenze elencate qui, inoltre, vengono aggiunte al classpath da azure-funzioni-java-worker.Also, dependencies listed here are added to the classpath by azure-functions-java-worker.

Supporto dei tipi di datiData type support

Per stabilire un'associazione con binding di input/output, è possibile usare Oggetti Java precedenti normali (POJO, Plain Old Java Object), tipi definiti in azure-functions-java-library o tipi di dati primitivi, ad esempio stringa o numero intero.You can use Plain old Java objects (POJOs), types defined in azure-functions-java-library or primitive dataTypes such as String, Integer to bind to input/output bindings.

Oggetti Java precedenti normali (POJO, Plain Old Java Object)Plain old Java objects (POJOs)

Per la conversione dei dati di input in oggetti POJO, azure-funzioni-java-worker usa la libreria gson.For converting input data to POJO, azure-functions-java-worker uses gson library. I tipi POJO usati come input delle funzioni devono essere public.POJO types used as inputs to functions should be public.

Dati binariBinary data

Per associare dati di input/output binari a byte[], impostare il campo dataType nel file function.json su binary:Bind binary inputs or outputs to byte[] by setting the dataType field in your function.json to binary:

   @FunctionName("BlobTrigger")
    @StorageAccount("AzureWebJobsStorage")
     public void blobTrigger(
        @BlobTrigger(name = "content", path = "myblob/{fileName}", dataType = "binary") byte[] content,
        @BindingName("fileName") String fileName,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java Blob trigger function processed a blob.\n Name: " + fileName + "\n Size: " + content.length + " Bytes");
    }

Usare Optional<T> se sono previsti valori NullUse Optional<T> for if null values are expected

BindingBindings

I binding di input e output forniscono una modalità dichiarativa per connettersi ai dati dall'interno del codice.Input and output bindings provide a declarative way to connect to data from within your code. Una funzione può avere più binding di input e output.A function can have multiple input and output bindings.

Esempio di binding di inputExample Input binding

package com.example;

import com.microsoft.azure.functions.annotation.*;

public class Function {
    @FunctionName("echo")
    public static String echo(
        @HttpTrigger(name = "req", methods = { "put" }, authLevel = AuthorizationLevel.ANONYMOUS, route = "items/{id}") String inputReq,
        @TableInput(name = "item", tableName = "items", partitionKey = "Example", rowKey = "{id}", connection = "AzureWebJobsStorage") TestInputData inputData
        @TableOutput(name = "myOutputTable", tableName = "Person", connection = "AzureWebJobsStorage") OutputBinding<Person> testOutputData,
    ) {
        testOutputData.setValue(new Person(httpbody + "Partition", httpbody + "Row", httpbody + "Name"));
        return "Hello, " + inputReq + " and " + inputData.getKey() + ".";
    }

    public static class TestInputData {
        public String getKey() { return this.RowKey; }
        private String RowKey;
    }
    public static class Person {
        public String PartitionKey;
        public String RowKey;
        public String Name;

        public Person(String p, String r, String n) {
            this.PartitionKey = p;
            this.RowKey = r;
            this.Name = n;
        }
    }
}

Questa funzione viene richiamata con una richiesta HTTP.This function is invoked with an HTTP request.

  • Il payload della richiesta HTTP viene passato come String per l'argomento inputReqHTTP request payload is passed as a String for the argument inputReq
  • Viene recuperata una voce da Archiviazione tabelle di Azure e passata come TestInputData all'argomento inputData.One entry is retrieved from the Azure Table Storage and is passed as TestInputData to the argument inputData.

Per ricevere un batch di input, è possibile stabilire un'associazione a String[], POJO[], List<String> o List<POJO>.To receive a batch of inputs, you can bind to String[], POJO[], List<String> or List<POJO>.

@FunctionName("ProcessIotMessages")
    public void processIotMessages(
        @EventHubTrigger(name = "message", eventHubName = "%AzureWebJobsEventHubPath%", connection = "AzureWebJobsEventHubSender", cardinality = Cardinality.MANY) List<TestEventData> messages,
        final ExecutionContext context)
    {
        context.getLogger().info("Java Event Hub trigger received messages. Batch size: " + messages.size());
    }

    public class TestEventData {
    public String id;
}

Questa funzione viene attivata ogni volta che sono disponibili nuovi dati nell'hub eventi configurato.This function gets triggered whenever there is new data in the configured event hub. Poiché l'oggetto cardinality è impostato su MANY, la funzione riceve un batch di messaggi dall'hub eventi.As the cardinality is set to MANY, function receives a batch of messages from event hub. L'oggetto EventData dell'hub eventi viene convertito in TestEventData per l'esecuzione della funzione.EventData from event hub gets converted to TestEventData for the function execution.

Esempio di binding di outputExample Output binding

È possibile associare un binding di output al valore restituito usando $returnYou can bind an output binding to the return value using $return

package com.example;

import com.microsoft.azure.functions.annotation.*;

public class Function {
    @FunctionName("copy")
    @StorageAccount("AzureWebJobsStorage")
    @BlobOutput(name = "$return", path = "samples-output-java/{name}")
    public static String copy(@BlobTrigger(name = "blob", path = "samples-input-java/{name}") String content) {
        return content;
    }
}

Se sono presenti più associazioni di output, usare il valore restituito per una sola di tali associazioni.If there are multiple output bindings, use the return value for only one of them.

Per inviare più valori di output, usare il tipo OutputBinding<T> definito nel pacchetto azure-functions-java-library.To send multiple output values, use OutputBinding<T> defined in the azure-functions-java-library package.

@FunctionName("QueueOutputPOJOList")
    public HttpResponseMessage QueueOutputPOJOList(@HttpTrigger(name = "req", methods = { HttpMethod.GET,
            HttpMethod.POST }, authLevel = AuthorizationLevel.ANONYMOUS) HttpRequestMessage<Optional<String>> request,
            @QueueOutput(name = "itemsOut", queueName = "test-output-java-pojo", connection = "AzureWebJobsStorage") OutputBinding<List<TestData>> itemsOut, 
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        String query = request.getQueryParameters().get("queueMessageId");
        String queueMessageId = request.getBody().orElse(query);
        itemsOut.setValue(new ArrayList<TestData>());
        if (queueMessageId != null) {
            TestData testData1 = new TestData();
            testData1.id = "msg1"+queueMessageId;
            TestData testData2 = new TestData();
            testData2.id = "msg2"+queueMessageId;

            itemsOut.getValue().add(testData1);
            itemsOut.getValue().add(testData2);

            return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + queueMessageId).build();
        } else {
            return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body("Did not find expected items in CosmosDB input list").build();
        }
    }

     public static class TestData {
        public String id;
    }

La funzione precedente viene richiamata su una HttpRequest e scrive più valori nella coda di AzureAbove function is invoked on an HttpRequest and writes multiple values to the Azure Queue

HttpRequestMessage e HttpResponseMessageHttpRequestMessage and HttpResponseMessage

I tipi HttpRequestMessage e HttpResponseMessage definiti in azure-functions-java-library sono tipi di helper per l'interazione con le funzioni HttpTriggerHttpRequestMessage and HttpResponseMessage types are defined in azure-functions-java-library are helper types to work with HttpTrigger functions

Tipo specializzatoSpecialized Type DestinazioneTarget Uso tipicoTypical Usage
HttpRequestMessage<T> Trigger HTTPHTTP Trigger Metodo Get, intestazioni o queryGet method, headers, or queries
HttpResponseMessage Associazione di output HTTPHTTP Output Binding Stato restituito diverso da 200Return status other than 200

MetadataMetadata

Alcuni trigger inviano metadati dei trigger insieme ai dati di input.Few triggers send trigger metadata along with input data. È possibile usare l'annotazione @BindingName per stabilire un'associazione con i metadati dei triggerYou can use annotation @BindingName to bind to trigger metadata

package com.example;

import java.util.Optional;
import com.microsoft.azure.functions.annotation.*;


public class Function {
    @FunctionName("metadata")
    public static String metadata(
        @HttpTrigger(name = "req", methods = { "get", "post" }, authLevel = AuthorizationLevel.ANONYMOUS) Optional<String> body,
        @BindingName("name") String queryValue
    ) {
        return body.orElse(queryValue);
    }
}

Nell'esempio precedente, queryValue è associato al parametro della stringa di query name nell'URL della richiesta http://{example.host}/api/metadata?name=test.In the example above, the queryValue is bound to query string parameter name in the Http request URL http://{example.host}/api/metadata?name=test. Di seguito è riportato un altro esempio di binding a Id dai metadati del trigger della codaFollowing is another example to binding to Id from queue trigger metadata

 @FunctionName("QueueTriggerMetadata")
    public void QueueTriggerMetadata(
        @QueueTrigger(name = "message", queueName = "test-input-java-metadata", connection = "AzureWebJobsStorage") String message,@BindingName("Id") String metadataId,
        @QueueOutput(name = "output", queueName = "test-output-java-metadata", connection = "AzureWebJobsStorage") OutputBinding<TestData> output,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java Queue trigger function processed a message: " + message + " whith metadaId:" + metadataId );
        TestData testData = new TestData();
        testData.id = metadataId;
        output.setValue(testData);
    }

Nota

Il nome specificato nell'annotazione deve corrispondere alla proprietà dei metadatiName provided in the annotation needs to match the metadata property

Contesto di esecuzioneExecution context

L'oggetto ExecutionContext definito in azure-functions-java-library contiene metodi helper per comunicare con il runtime di Funzioni.ExecutionContext defined in the azure-functions-java-library contains helper methods to communicate with the functions runtime.

LoggerLogger

Usare getLogger definito in ExecutionContext per scrivere i log dal codice della funzione.Use getLogger defined in ExecutionContext to write logs from function code.

Esempio:Example:


import com.microsoft.azure.functions.*;
import com.microsoft.azure.functions.annotation.*;

public class Function {
    public String echo(@HttpTrigger(name = "req", methods = {"post"}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) {
        if (req.isEmpty()) {
            context.getLogger().warning("Empty request body received by function " + context.getFunctionName() + " with invocation " + context.getInvocationId());
        }
        return String.format(req);
    }
}

Visualizzazione dei log e della tracciaView logs and trace

È possibile usare l'interfaccia della riga di comando di Azure per trasmettere in streaming la registrazione dei canali stdout e stderr di Java, oltre alla registrazione di altre applicazioni.You can use the Azure CLI to stream Java stdout and stderr logging as well as other application logging.

Configurare l'applicazione Funzioni per scrivere la registrazione delle applicazioni tramite l'interfaccia della riga di comando di Azure:Configure your Function application to write application logging using the Azure CLI:

az webapp log config --name functionname --resource-group myResourceGroup --application-logging true

Per eseguire lo streaming dell'output dell'applicazione di funzione usando l'interfaccia della riga di comando di Azure, aprire un nuovo prompt dei comandi o una sessione terminal o Bash o terminal e immettere il comando seguente:To stream logging output for your Function app using the Azure CLI, open a new command prompt, Bash, or Terminal session and enter the following command:

az webapp log tail --name webappname --resource-group myResourceGroup

Il comando az webapp log tail ha opzioni per filtrare l'output usando l'opzione --provider.The az webapp log tail command has options to filter output using the --provider option.

Per scaricare i file di log come un singolo file ZIP usando l'interfaccia della riga di comando di Azure, aprire un nuovo prompt dei comandi o una sessione terminal o Bash e immettere il comando seguente:To download the log files as a single ZIP file using the Azure CLI, open a new command prompt, Bash, or Terminal session and enter the following command:

az webapp log download --resource-group resourcegroupname --name functionappname

Prima di eseguire questo comando, è necessario aver abilitato la registrazione del file system nel portale di Azure o l'interfaccia della riga di comando di Azure.You must have enabled file system logging in the Azure Portal or Azure CLI before running this command.

Variabili di ambienteEnvironment variables

In Funzioni, le impostazioni dell'app, come le stringhe di connessione al servizio, vengono esposte come variabili di ambiente durante l'esecuzione.In Functions, app settings, such as service connection strings, are exposed as environment variables during execution. È possibile accedere a queste impostazioni usando System.getenv("AzureWebJobsStorage")You can access these settings using, System.getenv("AzureWebJobsStorage")

Esempio:Example:

Aggiungere AppSetting con il nome testAppSetting e il valore testAppSettingValueAdd AppSetting with name testAppSetting and value testAppSettingValue


public class Function {
    public String echo(@HttpTrigger(name = "req", methods = {"post"}, authLevel = AuthorizationLevel.ANONYMOUS) String req, ExecutionContext context) {
        context.getLogger().info("testAppSetting "+ System.getenv("testAppSettingValue"));
        return String.format(req);
    }
}

Passaggi successiviNext steps

Per altre informazioni sullo sviluppo Java delle funzioni di Azure, vedere le risorse seguenti:For more information about Azure Function Java development, see the following resources: