Szybki start: tworzenie funkcji Java na platformie Azure z poziomu wiersza polecenia

W tym artykule użyjesz narzędzi wiersza polecenia, aby utworzyć funkcję Java, która odpowiada na żądania HTTP. Po przetestowaniu kodu lokalnie wdrożysz go w środowisku bezserwerowym Azure Functions.

Jeśli narzędzie Maven nie jest preferowanym narzędziem deweloperów, zapoznaj się z naszymi podobnymi samouczkami dla deweloperów języka Java:

Ukończenie tego przewodnika Szybki start wiąże się z niewielkimi kosztami w wysokości kilku centów usd lub mniej na koncie platformy Azure.

Konfigurowanie środowiska lokalnego

Przed rozpoczęciem musisz mieć następujące elementy:

Sprawdzanie wymagań wstępnych

  • W oknie terminalu lub polecenia uruchom poleceniefunc --version, aby sprawdzić, czy narzędzia Azure Functions Core Tools są w wersji 4.x.

  • Uruchom polecenie , az --version aby sprawdzić, czy interfejs wiersza polecenia platformy Azure ma wersję 2.4 lub nowszą.

  • Uruchom polecenie az login , aby zalogować się na platformie Azure i zweryfikować aktywną subskrypcję.

Tworzenie projektu funkcji lokalnej

W Azure Functions projekt funkcji jest kontenerem dla co najmniej jednej pojedynczej funkcji, która odpowiada na określony wyzwalacz. Wszystkie funkcje w projekcie współdzielą te same konfiguracje lokalne i hostujące. W tej sekcji utworzysz projekt funkcji zawierający jedną funkcję.

  1. W pustym folderze uruchom następujące polecenie, aby wygenerować projekt usługi Functions z archetypu narzędzia Maven.

    mvn archetype:generate -DarchetypeGroupId=com.microsoft.azure -DarchetypeArtifactId=azure-functions-archetype -DjavaVersion=8
    

    Ważne

    • Użyj polecenia -DjavaVersion=11, jeśli chcesz, aby funkcje działały w języku Java 11. Aby dowiedzieć się więcej, zobacz Wersje języka Java.
    • Aby JAVA_HOME ukończyć ten artykuł, należy ustawić zmienną środowiskową na lokalizację instalacji poprawnej wersji zestawu JDK.
  2. Narzędzie Maven prosi o wartości potrzebne do zakończenia generowania projektu we wdrożeniu.
    Po wyświetleniu monitu podaj następujące wartości:

    Monit Wartość Opis
    groupId com.fabrikam Wartość, która jednoznacznie identyfikuje projekt we wszystkich projektach, zgodnie z regułami nazewnictwa pakietów dla języka Java.
    artifactId fabrikam-functions Wartość, która jest nazwą pliku jar bez numeru wersji.
    Wersja 1.0-SNAPSHOT Wybierz wartość domyślną.
    Pakiet com.fabrikam Wartość, która jest pakietem Java dla wygenerowanego kodu funkcji. Użyj wartości domyślnej.
  3. Wpisz Y lub naciśnij klawisz Enter, aby potwierdzić.

    Narzędzie Maven tworzy pliki projektu w nowym folderze o nazwie artifactId, która w tym przykładzie to fabrikam-functions.

  4. Przejdź do folderu projektu:

    cd fabrikam-functions
    

    Ten folder zawiera różne pliki dla projektu, w tym pliki konfiguracji o nazwie local.settings.json i host.json. Ponieważ plik local.settings.json może zawierać wpisy tajne pobrane z platformy Azure, plik jest domyślnie wykluczony z kontroli źródła w pliku gitignore .

(Opcjonalnie) Sprawdzanie zawartości pliku

W razie potrzeby możesz przejść do pozycji Uruchom funkcję lokalnie i sprawdzić zawartość pliku później.

Function.java

Function.java zawiera metodę run , która odbiera dane żądania w request zmiennej, to httpRequestMessage ozdobiona adnotacją HttpTrigger , która definiuje zachowanie wyzwalacza.

/**
 * Copyright (c) Microsoft Corporation. All rights reserved.
 * Licensed under the MIT License. See License.txt in the project root for
 * license information.
 */

package com.functions;

import com.microsoft.azure.functions.ExecutionContext;
import com.microsoft.azure.functions.HttpMethod;
import com.microsoft.azure.functions.HttpRequestMessage;
import com.microsoft.azure.functions.HttpResponseMessage;
import com.microsoft.azure.functions.HttpStatus;
import com.microsoft.azure.functions.annotation.AuthorizationLevel;
import com.microsoft.azure.functions.annotation.FixedDelayRetry;
import com.microsoft.azure.functions.annotation.FunctionName;
import com.microsoft.azure.functions.annotation.HttpTrigger;

import java.io.File;
import java.nio.file.Files;
import java.util.Optional;

/**
 * Azure Functions with HTTP Trigger.
 */
public class Function {
    /**
     * This function listens at endpoint "/api/HttpExample". Two ways to invoke it using "curl" command in bash:
     * 1. curl -d "HTTP Body" {your host}/api/HttpExample
     * 2. curl "{your host}/api/HttpExample?name=HTTP%20Query"
     */
    @FunctionName("HttpExample")
    public HttpResponseMessage run(
            @HttpTrigger(
                name = "req",
                methods = {HttpMethod.GET, HttpMethod.POST},
                authLevel = AuthorizationLevel.ANONYMOUS)
                HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        // Parse query parameter
        final String query = request.getQueryParameters().get("name");
        final String name = request.getBody().orElse(query);

        if (name == null) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build();
        } else {
            return request.createResponseBuilder(HttpStatus.OK).body("Hello, " + name).build();
        }
    }

    public static int count = 1;

    /**
     * This function listens at endpoint "/api/HttpExampleRetry". The function is re-executed in case of errors until the maximum number of retries occur.
     * Retry policies: https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-error-pages?tabs=java
     */
    @FunctionName("HttpExampleRetry")
    @FixedDelayRetry(maxRetryCount = 3, delayInterval = "00:00:05")
    public HttpResponseMessage HttpExampleRetry(
        @HttpTrigger(
            name = "req",
            methods = {HttpMethod.GET, HttpMethod.POST},
            authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context) throws Exception {
        context.getLogger().info("Java HTTP trigger processed a request.");

        if(count<3) {
            count ++;
            throw new Exception("error");
        }

        // Parse query parameter
        final String query = request.getQueryParameters().get("name");
        final String name = request.getBody().orElse(query);

        if (name == null) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST).body("Please pass a name on the query string or in the request body").build();
        } else {
            return request.createResponseBuilder(HttpStatus.OK).body(name).build();
        }
    }

    /**
     * This function listens at endpoint "/api/HttpTriggerJavaVersion".
     * It can be used to verify the Java home and java version currently in use in your Azure function
     */
    @FunctionName("HttpTriggerJavaVersion")
    public static HttpResponseMessage HttpTriggerJavaVersion(
        @HttpTrigger(
            name = "req",
            methods = {HttpMethod.GET, HttpMethod.POST},
            authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context
    ) {
        context.getLogger().info("Java HTTP trigger processed a request.");
        final String javaVersion = getJavaVersion();
        context.getLogger().info("Function - HttpTriggerJavaVersion" + javaVersion);
        return request.createResponseBuilder(HttpStatus.OK).body("HttpTriggerJavaVersion").build();
    }

    public static String getJavaVersion() {
        return String.join(" - ", System.getProperty("java.home"), System.getProperty("java.version"));
    }

    /**
     * This function listens at endpoint "/api/StaticWebPage".
     * It can be used to read and serve a static web page.
     * Note: Read the file from the right location for local machine and azure portal usage.
     */
    @FunctionName("StaticWebPage")
    public HttpResponseMessage getStaticWebPage(
        @HttpTrigger(
            name = "req",
            methods = {HttpMethod.GET, HttpMethod.POST},
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context) {
        context.getLogger().info("Java HTTP trigger processed a request.");

        File htmlFile = new File("index.html");
        try{
            byte[] fileContent = Files.readAllBytes(htmlFile.toPath());
            return request.createResponseBuilder(HttpStatus.OK).body(fileContent).build();
        }catch (Exception e){
            context.getLogger().info("Error reading file.");
            return request.createResponseBuilder(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }
}

Komunikat odpowiedzi jest generowany przez interfejs API HttpResponseMessage.Builder .

pom.xml

Ustawienia zasobów platformy Azure utworzonych do hostowania aplikacji są definiowane w elemecie konfiguracji wtyczki z identyfikatorem groupIdcom.microsoft.azure w wygenerowanym pliku pom.xml. Na przykład poniższy element konfiguracji instruuje wdrożenie oparte na narzędziu Maven w celu utworzenia aplikacji funkcji w java-functions-group grupie zasobów w westus regionie. Sama aplikacja funkcji działa w systemie Windows hostowanym java-functions-app-service-plan w planie, który domyślnie jest bezserwerowym planem Zużycie.

        <encoding>${project.build.sourceEncoding}</encoding>
    </configuration>
</plugin>
<plugin>
    <groupId>com.microsoft.azure</groupId>
    <artifactId>azure-functions-maven-plugin</artifactId>
    <version>${azure.functions.maven.plugin.version}</version>
    <configuration>
        <!-- function app name -->
        <appName>${functionAppName}</appName>
        <!-- function app resource group -->
        <resourceGroup>${functionResourceGroup}</resourceGroup>
        <!-- function app service plan name -->
        <appServicePlanName>${functionServicePlan}</appServicePlanName>
        <!-- function app region-->
        <!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-regions for all valid values -->
        <region>${functionAppRegion}</region>
        <!-- function pricingTier, default to be consumption if not specified -->
        <!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details#supported-pricing-tiers for all valid values -->
        <pricingTier>${functionPricingTier}</pricingTier>
        <!-- Whether to disable application insights, default is false -->
        <!-- refers https://github.com/microsoft/azure-maven-plugins/wiki/Azure-Functions:-Configuration-Details for all valid configurations for application insights-->
        <!-- <disableAppInsights></disableAppInsights> -->

        <runtime>
            <!-- runtime os, could be windows, linux or docker-->
            <os>windows</os>
            <javaVersion>8</javaVersion>
            <!-- for docker function, please set the following parameters -->
            <!-- <image>[hub-user/]repo-name[:tag]</image> -->
            <!-- <serverId></serverId> -->
            <!-- <registryUrl></registryUrl>  -->
        </runtime>
        <appSettings>
            <property>
                <name>FUNCTIONS_EXTENSION_VERSION</name>
                <value>~4</value>
            </property>
        </appSettings>
    </configuration>
    <executions>
        <execution>
            <id>package-functions</id>
            <goals>
                <goal>package</goal>
            </goals>

Możesz zmienić te ustawienia, aby kontrolować sposób tworzenia zasobów na platformie Azure, takich jak zmiana runtime.os z na windowslinux przed początkowym wdrożeniem. Aby uzyskać pełną listę ustawień obsługiwanych przez wtyczkę Maven, zobacz szczegóły konfiguracji.

FunctionTest.java

Archetyp generuje również test jednostkowy dla funkcji. Po zmianie funkcji w celu dodania powiązań lub dodania nowych funkcji do projektu należy również zmodyfikować testy w pliku FunctionTest.java .

Lokalne uruchamianie funkcji

  1. Uruchom funkcję, uruchamiając lokalny host środowiska uruchomieniowego Azure Functions z folderu LocalFunctionProj:

    mvn clean package
    mvn azure-functions:run
    

    Na końcu danych wyjściowych powinny zostać wyświetlone następujące wiersze:

     ...
    
     Now listening on: http://0.0.0.0:7071
     Application started. Press Ctrl+C to shut down.
    
     Http Functions:
    
             HttpExample: [GET,POST] http://localhost:7071/api/HttpExample
     ...
    
     

    Uwaga

    Jeśli funkcja HttpExample nie jest wyświetlana, jak pokazano powyżej, prawdopodobnie uruchomiono hosta spoza folderu głównego projektu. W takim przypadku użyj klawiszy Ctrl+C , aby zatrzymać hosta, przejdź do folderu głównego projektu i ponownie uruchom poprzednie polecenie.

  2. Skopiuj adres URL funkcji z tych danych wyjściowych HttpExample do przeglądarki i dołącz ciąg ?name=<YOUR_NAME>zapytania , tworząc pełny adres URL, taki jak http://localhost:7071/api/HttpExample?name=Functions. W przeglądarce powinien zostać wyświetlony komunikat, który odzwierciedla wartość ciągu zapytania. Terminal, w którym rozpoczęto projekt, pokazuje również dane wyjściowe dziennika podczas wysyłania żądań.

  3. Gdy wszystko będzie gotowe, użyj klawiszy Ctrl+C i wybierz, y aby zatrzymać hosta funkcji.

Wdrażanie projektu funkcji na platformie Azure

Aplikacja funkcji i powiązane zasoby są tworzone na platformie Azure podczas pierwszego wdrażania projektu funkcji. Ustawienia zasobów platformy Azure utworzonych do hostowania aplikacji są zdefiniowane w plikupom.xml. W tym artykule zaakceptujesz wartości domyślne.

Porada

Aby utworzyć aplikację funkcji działającą w systemie Linux zamiast systemu Windows, zmień runtime.os element w pliku pom.xml z windows na linux. Uruchamianie systemu Linux w planie użycia jest obsługiwane w tych regionach. Nie można mieć aplikacji uruchamianych w systemie Linux i aplikacjach uruchamianych w systemie Windows w tej samej grupie zasobów.

  1. Przed wdrożeniem zaloguj się do subskrypcji platformy Azure przy użyciu interfejsu wiersza polecenia platformy Azure lub Azure PowerShell.

    az login
    

    Polecenie az login powoduje zalogowanie się do konta platformy Azure.

  2. Użyj następującego polecenia, aby wdrożyć projekt w nowej aplikacji funkcji.

    mvn azure-functions:deploy
    

    Spowoduje to utworzenie następujących zasobów na platformie Azure:

    • Grupa zasobów. Nazwana jako java-functions-group.
    • Konto magazynu. Wymagane przez funkcje. Nazwa jest generowana losowo na podstawie wymagań dotyczących nazwy konta magazynu.
    • Plan hostingu. Hostowanie bezserwerowe dla aplikacji funkcji w regionie westus . Nazwa to java-functions-app-service-plan.
    • Aplikacja funkcji. Aplikacja funkcji jest jednostką wdrażania i wykonywania funkcji. Nazwa jest generowana losowo na podstawie identyfikatora artifactId, dołączana z losowo wygenerowaną liczbą.

    Wdrożenie pakuje pliki projektu i wdraża je w nowej aplikacji funkcji przy użyciu wdrożenia zip. Kod jest uruchamiany z pakietu wdrożeniowego na platformie Azure.

Wywoływanie funkcji na platformie Azure

Ponieważ funkcja używa wyzwalacza HTTP, należy wywołać go, wysyłając żądanie HTTP do jego adresu URL w przeglądarce lub za pomocą narzędzia takiego jak curl.

Skopiuj pełny adres URL wywołania widoczny w danych wyjściowych polecenia publikowania na pasku adresu przeglądarki, dołączając parametr ?name=Functionszapytania . Przeglądarka powinna wyświetlać podobne dane wyjściowe, jak podczas lokalnego uruchamiania funkcji.

Dane wyjściowe funkcji uruchomionej na platformie Azure w przeglądarce

Uruchom następujące polecenie, aby wyświetlić dzienniki przesyłania strumieniowego niemal w czasie rzeczywistym:

func azure functionapp logstream <APP_NAME> 

W osobnym oknie terminalu lub w przeglądarce ponownie wywołaj funkcję zdalną. Pełny dziennik wykonywania funkcji na platformie Azure jest wyświetlany w terminalu.

Czyszczenie zasobów

Jeśli przejdziesz do następnego kroku i dodasz powiązanie wyjściowe kolejki usługi Azure Storage, zachowaj wszystkie zasoby na swoim miejscu, ponieważ będziesz opierać się na tym, co zostało już zrobione.

W przeciwnym razie użyj następującego polecenia, aby usunąć grupę zasobów i wszystkie zawarte w niej zasoby, aby uniknąć ponoszenia dalszych kosztów.

az group delete --name java-functions-group

Następne kroki