

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

# Distribuisci funzioni Java Lambda con immagini di container
<a name="java-image"></a>

Esistono tre modi per creare un'immagine di container per una funzione Lambda in Java:
+ [Utilizzo di un'immagine di AWS base per Java](#java-image-instructions)

  [Le immagini di base AWS](images-create.md#runtimes-images-lp) sono precaricate con un runtime in linguaggio, un client di interfaccia di runtime per gestire l'interazione tra Lambda e il codice della funzione e un emulatore di interfaccia di runtime per i test locali.
+ [Utilizzo di un'immagine di AWS base solo per il sistema operativo](images-create.md#runtimes-images-provided)

  [AWS Le immagini di base solo](https://gallery.ecr.aws/lambda/provided) per il sistema operativo contengono una distribuzione Amazon Linux e l'emulatore [di interfaccia di runtime](https://github.com/aws/aws-lambda-runtime-interface-emulator/). Queste immagini vengono comunemente utilizzate per creare immagini di container per linguaggi compilati, come [Go](go-image.md#go-image-provided) e [Rust](lambda-rust.md), e per un linguaggio o una versione di linguaggio per cui Lambda non fornisce un'immagine di base, come Node.js 19. Puoi anche utilizzare immagini di base solo per il sistema operativo per implementare un [runtime personalizzato](runtimes-custom.md). Per rendere l'immagine compatibile con Lambda, devi includere il [client di interfaccia di runtime per Java](#java-image-clients) nell'immagine.
+ [Utilizzo di un'immagine non di base AWS ](#java-image-clients)

  È possibile utilizzare un'immagine di base alternativa da un altro registro del container, come ad esempio Alpine Linux o Debian. Puoi anche utilizzare un'immagine personalizzata creata dalla tua organizzazione. Per rendere l'immagine compatibile con Lambda, devi includere il [client di interfaccia di runtime per Java](#java-image-clients) nell'immagine.

**Suggerimento**  
Per ridurre il tempo necessario all'attivazione delle funzioni del container Lambda, consulta [Utilizzo di compilazioni a più fasi](https://docs.docker.com/build/building/multi-stage/) nella documentazione Docker. Per creare immagini di container efficienti, segui le [best practice per scrivere file Docker](https://docs.docker.com/develop/develop-images/dockerfile_best-practices/).

Questa pagina spiega come creare, testare e implementare le immagini di container per Lambda.

**Topics**
+ [

## AWS immagini di base per Java
](#java-image-base)
+ [

## Utilizzo di un'immagine di AWS base per Java
](#java-image-instructions)
+ [

## Utilizzo di un'immagine di base alternativa con il client di interfaccia di runtime
](#java-image-clients)

## AWS immagini di base per Java
<a name="java-image-base"></a>

AWS fornisce le seguenti immagini di base per Java:


| Tag | Runtime | Sistema operativo | Dockerfile | Raggiunta obsolescenza | 
| --- | --- | --- | --- | --- | 
| 25 | Java 2.5 | Amazon Linux 2023 | [Dockerfile per Java 2.5 attivo GitHub](https://github.com/aws/aws-lambda-base-images/blob/java25/Dockerfile.java25) |   30 giugno 2029   | 
| 21 | Java 21 | Amazon Linux 2023 | [Dockerfile per Java 2.1 su GitHub](https://github.com/aws/aws-lambda-base-images/blob/java21/Dockerfile.java21) |   30 giugno 2029   | 
| 17 | Java 17 | Amazon Linux 2 | [Dockerfile per Java 17 su GitHub](https://github.com/aws/aws-lambda-base-images/blob/java17/Dockerfile.java17) |   30 giugno 2027   | 
| 11 | Java 11 | Amazon Linux 2 | [Dockerfile per Java 11 attivo GitHub](https://github.com/aws/aws-lambda-base-images/blob/java11/Dockerfile.java11) |   30 giugno 2027   | 
| 8.al2 | Java 8 | Amazon Linux 2 | [Dockerfile per Java 8 attivo GitHub](https://github.com/aws/aws-lambda-base-images/blob/java8.al2/Dockerfile.java8.al2) |   30 giugno 2027   | 

[Archivio Amazon ECR: gallery.ecr. aws/lambda/java](https://gallery.ecr.aws/lambda/java)

Le immagini di base Java 21 e versioni successive si basano sull'[immagine di container minima di Amazon Linux 2023](https://docs.aws.amazon.com/linux/al2023/ug/minimal-container.html). Le immagini di base precedenti utilizzavano Amazon Linux 2. AL2023 offre diversi vantaggi rispetto ad Amazon Linux 2, tra cui un ingombro di distribuzione ridotto e versioni aggiornate di librerie come`glibc`.

AL2023le immagini basate utilizzano `microdnf` (symlinked as`dnf`) come gestore di pacchetti anziché`yum`, che è il gestore di pacchetti predefinito in Amazon Linux 2. `microdnf`è un'implementazione autonoma di. `dnf` Per un elenco dei pacchetti inclusi nelle immagini AL2023 basate, consulta le colonne **Minimal Container** in [Comparing packages installed on Amazon Linux 2023 Container Images](https://docs.aws.amazon.com/linux/al2023/ug/al2023-container-image-types.html). Per ulteriori informazioni sulle differenze tra Amazon Linux 2 AL2023 e Amazon Linux 2, consulta [la sezione Introduzione al runtime di Amazon Linux 2023 AWS Lambda](https://aws.amazon.com/blogs/compute/introducing-the-amazon-linux-2023-runtime-for-aws-lambda/) sul AWS Compute Blog.

**Nota**  
Per eseguire immagini AL2023 basate localmente, incluso with AWS Serverless Application Model (AWS SAM), devi usare la versione Docker 20.10.10 o successiva.

## Utilizzo di un'immagine di AWS base per Java
<a name="java-image-instructions"></a>

### Prerequisiti
<a name="java-image-prerequisites"></a>

Per completare le fasi riportate in questa sezione, è necessario:
+ Java (ad esempio, [Amazon Corretto](https://aws.amazon.com/corretto))
+ [Apache Maven](https://maven.apache.org/) o [Gradle](https://gradle.org/install/)
+ [AWS CLI versione 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (versione minima 25.0.0)
+ Il [plugin buildx](https://github.com/docker/buildx/blob/master/README.md) di Docker.

### Creazione di un'immagine da un'immagine di base
<a name="java-image-create"></a>

------
#### [ Maven ]

1. Esegui il comando seguente per creare un progetto Maven utilizzando l'[archetipo per Lambda](https://github.com/aws/aws-sdk-java-v2/tree/master/archetypes/archetype-lambda). I parametri seguenti sono obbligatori:
   + **service** — Il Servizio AWS client da utilizzare nella funzione Lambda. Per un elenco delle fonti disponibili, consulta [aws-sdk-java-v2/services on](https://github.com/aws/aws-sdk-java-v2/tree/master/services). GitHub
   + **region** — Il Regione AWS luogo in cui si desidera creare la funzione Lambda.
   + **groupId**: il namespace completo del pacchetto dell'applicazione.
   + **artifactId**: il nome del progetto. Questo sarà il nome della directory per il progetto.

   In Linux e macOS, esegui questo comando:

   ```
   mvn -B archetype:generate \
      -DarchetypeGroupId=software.amazon.awssdk \
      -DarchetypeArtifactId=archetype-lambda -Dservice=s3 -Dregion=US_WEST_2 \
      -DgroupId=com.example.myapp \
      -DartifactId=myapp
   ```

   In PowerShell, esegui questo comando:

   ```
   mvn -B archetype:generate `
      "-DarchetypeGroupId=software.amazon.awssdk" `
      "-DarchetypeArtifactId=archetype-lambda" "-Dservice=s3" "-Dregion=US_WEST_2" `
      "-DgroupId=com.example.myapp" `
      "-DartifactId=myapp"
   ```

   L'archetipo Maven per Lambda è preconfigurato per la compilazione con Java SE 8 e include una dipendenza da AWS SDK per Java. Se crei il tuo progetto con un archetipo diverso o utilizzando un altro metodo, devi [configurare il compilatore Java per Maven](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#configure-maven-compiler) e [dichiarare l'SDK come dipendenza](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/setup-project-maven.html#configure-maven-compiler).

1. Apri la directory `myapp/src/main/java/com/example/myapp` e cerca il file `App.java`. Questo è il codice per la funzione Lambda. A fini di test, puoi utilizzare il codice di esempio fornito o sostituirlo con il tuo codice personalizzato.

1. Torna alla directory principale del progetto e crea un nuovo Dockerfile con la seguente configurazione:
   + Imposta la proprietà `FROM` sull'[URI dell'immagine di base](https://gallery.ecr.aws/lambda/java).
   + Imposta l'argomento `CMD` specificando il gestore della funzione Lambda.

   Nota che l'esempio Dockerfile non include un'[istruzione USER](https://docs.docker.com/reference/dockerfile/#user). Quando implementi un'immagine di container su Lambda, Lambda definisce automaticamente un utente Linux predefinito con autorizzazioni con privilegi minimi. Questo è diverso dal comportamento standard di Docker, che per impostazione predefinita è l'utente `root` quando non viene fornita alcuna istruzione `USER`.  
**Example Dockerfile**  

   ```
   FROM public.ecr.aws/lambda/java:21
     
   # Copy function code and runtime dependencies from Maven layout
   COPY target/classes ${LAMBDA_TASK_ROOT}
   COPY target/dependency/* ${LAMBDA_TASK_ROOT}/lib/
       
   # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
   CMD [ "com.example.myapp.App::handleRequest" ]
   ```

1. Compila il progetto e raccogli le dipendenze di runtime.

   ```
   mvn compile dependency:copy-dependencies -DincludeScope=runtime
   ```

1. Crea l'immagine Docker con il comando [docker build](https://docs.docker.com/engine/reference/commandline/build/). L'esempio seguente assegna un nome all'immagine `docker-image` e le assegna il [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) `test`. Per rendere l'immagine compatibile con Lambda, è necessario utilizzare l'`--provenance=false`opzione.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**Nota**  
Il comando specifica l’opzione `--platform linux/amd64` per garantire che il container sia compatibile con l'ambiente di esecuzione di Lambda, indipendentemente dall'architettura della macchina di sviluppo. Se intendi creare una funzione Lambda utilizzando l'architettura del set di ARM64 istruzioni, assicurati di modificare il comando per utilizzare invece l'`--platform linux/arm64`opzione.

------
#### [ Gradle ]

1. Crea una directory per il progetto, quindi passa a quella directory.

   ```
   mkdir example
   cd example
   ```

1. Esegui il comando seguente per fare in modo che Gradle generi un nuovo progetto di applicazione Java nella directory `example` dell'ambiente. Per **Seleziona script di creazione DSL**, scegli **2: Groovy**.

   ```
   gradle init --type java-application
   ```

1. Apri la directory `/example/app/src/main/java/example` e cerca il file `App.java`. Questo è il codice per la funzione Lambda. A fini di test, puoi utilizzare il codice di esempio seguente o sostituirlo con il tuo codice personalizzato.  
**Example App.java**  

   ```
   package com.example;
   import com.amazonaws.services.lambda.runtime.Context;
   import com.amazonaws.services.lambda.runtime.RequestHandler;
   public class App implements RequestHandler<Object, String> {
       public String handleRequest(Object input, Context context) {
           return "Hello world!";
       }
   }
   ```

1. Apri il file `build.gradle`. Se stai utilizzando il codice della funzione di esempio del passaggio precedente, sostituisci il contenuto di `build.gradle` con il seguente. Se utilizzi un codice di funzione personalizzato, modifica il file `build.gradle` secondo necessità.  
**Example build.gradle (Groovy DSL)**  

   ```
   plugins {
     id 'java'
   }
   group 'com.example'
   version '1.0-SNAPSHOT'
   sourceCompatibility = 1.8
   repositories {
     mavenCentral()
   }
   dependencies {
     implementation 'com.amazonaws:aws-lambda-java-core:1.2.1'
   }
   jar {
     manifest {
         attributes 'Main-Class': 'com.example.App'
     }
   }
   ```

1. Il comando `gradle init` del passaggio 2 ha anche generato un caso di test fittizio nella directory `app/test`. Ai fini di questo tutorial, salta l'esecuzione dei test eliminando la directory `/test`.

1. Compilare il progetto.

   ```
   gradle build
   ```

1. Nella directory root del progetto (`/example`), crea un Dockerfile con la seguente configurazione:
   + Imposta la proprietà `FROM` sull'[URI dell'immagine di base](https://gallery.ecr.aws/lambda/java).
   + Utilizza il comando COPY per copiare il codice della funzione e le dipendenze di runtime in `{LAMBDA_TASK_ROOT}`, una [variabile d'ambiente definita da Lambda](configuration-envvars.md#configuration-envvars-runtime).
   + Imposta l'argomento `CMD` specificando il gestore della funzione Lambda.

   Nota che l'esempio Dockerfile non include un'[istruzione USER](https://docs.docker.com/reference/dockerfile/#user). Quando implementi un'immagine di container su Lambda, Lambda definisce automaticamente un utente Linux predefinito con autorizzazioni con privilegi minimi. Questo è diverso dal comportamento standard di Docker, che per impostazione predefinita è l'utente `root` quando non viene fornita alcuna istruzione `USER`.  
**Example Dockerfile**  

   ```
   FROM public.ecr.aws/lambda/java:21
     
   # Copy function code and runtime dependencies from Gradle layout
   COPY app/build/classes/java/main ${LAMBDA_TASK_ROOT}
     
   # Set the CMD to your handler (could also be done as a parameter override outside of the Dockerfile)
   CMD [ "com.example.App::handleRequest" ]
   ```

1. Crea l'immagine Docker con il comando [docker build](https://docs.docker.com/engine/reference/commandline/build/). L'esempio seguente assegna un nome all'immagine `docker-image` e le assegna il [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) `test`. Per rendere l'immagine compatibile con Lambda, è necessario utilizzare l'`--provenance=false`opzione.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**Nota**  
Il comando specifica l’opzione `--platform linux/amd64` per garantire che il container sia compatibile con l'ambiente di esecuzione di Lambda, indipendentemente dall'architettura della macchina di sviluppo. Se intendi creare una funzione Lambda utilizzando l'architettura del set di ARM64 istruzioni, assicurati di modificare il comando per utilizzare invece l'`--platform linux/arm64`opzione.

------

### (Facoltativo) Test dell'immagine in locale
<a name="java-image-test"></a>

1. Avvia l'immagine Docker con il comando **docker run**. In questo esempio, `docker-image` è il nome dell'immagine e `test` è il tag.

   ```
   docker run --platform linux/amd64 -p 9000:8080 docker-image:test
   ```

   Questo comando esegue l'immagine come container e crea un endpoint locale in `localhost:9000/2015-03-31/functions/function/invocations`.
**Nota**  
Se hai creato l'immagine Docker per l'architettura del set di ARM64 istruzioni, assicurati di utilizzare l'`--platform linux/arm64`opzione invece di. `--platform linux/amd64`

1. Da una nuova finestra di terminale, invia un evento all'endpoint locale.

------
#### [ Linux/macOS ]

   Su MacOS o Linux, esegui il comando seguente `curl`:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   Questo comando richiama la funzione con un evento vuoto e restituisce una risposta. Se stai utilizzando il tuo codice della funzione anziché quello di esempio, potresti voler richiamare la funzione con un payload JSON. Esempio:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

------
#### [ PowerShell ]

   In PowerShell, esegui il seguente `Invoke-WebRequest` comando:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   Questo comando richiama la funzione con un evento vuoto e restituisce una risposta. Se stai utilizzando il tuo codice della funzione anziché quello di esempio, potresti voler richiamare la funzione con un payload JSON. Esempio:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. Ottieni l'ID del container.

   ```
   docker ps
   ```

1. Utilizza il comando [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) per arrestare il container. In questo comando, sostituisci `3766c4ab331c` con l'ID del container del passaggio precedente.

   ```
   docker kill 3766c4ab331c
   ```

### Implementazione dell'immagine
<a name="java-image-deploy"></a>

**Caricamento dell'immagine su Amazon ECR e creazione della funzione Lambda**

1. Esegui il [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html)comando per autenticare la CLI Docker nel tuo registro Amazon ECR.
   + Imposta il `--region` valore nel Regione AWS punto in cui desideri creare il repository Amazon ECR.
   + Sostituiscilo `111122223333` con il tuo ID. Account AWS 

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. Crea un repository in Amazon ECR utilizzando il commando [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html).

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**Nota**  
Il repository Amazon ECR deve corrispondere alla funzione Lambda. Regione AWS 

   In caso di esito positivo, dovresti ottenere una risposta simile a questa:

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. Copia il `repositoryUri` dall'output del passaggio precedente.

1. Esegui il comando [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) per etichettare l'immagine locale nel repository Amazon ECR come versione più recente. In questo comando:
   + `docker-image:test` è il nome e [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) dell'immagine Docker. Si tratta del nome e del tag dell'immagine specificati nel comando `docker build`.
   + Sostituisci l’`<ECRrepositoryUri>` con l’`repositoryUri` copiato. Assicurati di includere `:latest` alla fine dell'URI.

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   Esempio:

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. Esegui il comando [docker push](https://docs.docker.com/engine/reference/commandline/push/) per implementare la tua immagine locale sul repository Amazon ECR. Assicurati di includere `:latest` alla fine dell'URI del repository.

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [Crea un ruolo di esecuzione](lambda-intro-execution-role.md#permissions-executionrole-api) per la funzione, se non lo hai già fatto. Il nome della risorsa Amazon (ARN) del ruolo ti occorrerà nel passaggio successivo.

1. Creazione della funzione Lambda Per `ImageUri`, specifica l'URI del repository creato in precedenza. Assicurati di includere `:latest` alla fine dell'URI.

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**Nota**  
È possibile creare una funzione utilizzando un'immagine in un AWS account diverso, purché l'immagine si trovi nella stessa regione della funzione Lambda. Per ulteriori informazioni, consulta [Autorizzazioni multiaccount Amazon ECR](images-create.md#configuration-images-xaccount-permissions).

1. Richiama la funzione.

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   Dovresti ottenere una risposta simile a questa:

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. Per vedere l'output della funzione, controlla il file `response.json`.

Per aggiornare il codice della funzione, devi creare nuovamente l'immagine, caricare la nuova immagine nell'archivio Amazon ECR e quindi utilizzare il [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html)comando per distribuire l'immagine nella funzione Lambda.

Lambda risolve il tag dell'immagine in un digest di immagine specifico. Ciò significa che se punti il tag immagine utilizzato per implementare la funzione su una nuova immagine in Amazon ECR, Lambda non aggiorna automaticamente la funzione per utilizzare la nuova immagine.

Per distribuire la nuova immagine nella stessa funzione Lambda, è necessario utilizzare [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html)il comando, anche se il tag dell'immagine in Amazon ECR rimane lo stesso. Nell'esempio seguente, l'opzione `--publish` crea una nuova versione della funzione utilizzando l'immagine del container aggiornata.

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```

## Utilizzo di un'immagine di base alternativa con il client di interfaccia di runtime
<a name="java-image-clients"></a>

Se utilizzi un'[immagine di base solo per il sistema operativo](images-create.md#runtimes-images-provided) o un'immagine di base alternativa, devi includere il client dell'interfaccia di runtime nell'immagine. Il client dell'interfaccia di runtime estende l'[API Runtime](runtimes-api.md), che gestisce l'interazione tra Lambda e il codice della funzione.

Installa il client di interfaccia di runtime per Java nel tuo Dockerfile o come dipendenza nel tuo progetto. Ad esempio, per installare il client di interfaccia di runtime utilizzando il gestore di pacchetti Maven, aggiungi quanto segue al file `pom.xml`:

```
<dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-lambda-java-runtime-interface-client</artifactId>
    <version>2.3.2</version>
</dependency>
```

Per i dettagli del pacchetto, consulta la pagina [Client di interfaccia di runtime AWS Lambda Java](https://mvnrepository.com/artifact/com.amazonaws/aws-lambda-java-runtime-interface-client) nel Maven Central Repository. È inoltre possibile esaminare il codice sorgente del client dell'interfaccia di runtime nel GitHub repository [AWS Lambda Java Support Libraries](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-runtime-interface-client).

L'esempio seguente dimostra come creare un'immagine di container per Java utilizzando un'[immagine Amazon Corretto](https://gallery.ecr.aws/amazoncorretto/amazoncorretto). Amazon Corretto è una distribuzione pronta per la produzione gratuita, con un ambiente multipiattaforma di Open Java Development Kit (OpenJDK). Il progetto Maven include il client di interfaccia di runtime come dipendenza.

### Prerequisiti
<a name="java-alt-prerequisites"></a>

Per completare le fasi riportate in questa sezione, è necessario:
+ Java (ad esempio, [Amazon Corretto](https://aws.amazon.com/corretto))
+ [Apache Maven](https://maven.apache.org/)
+ [AWS CLI versione 2](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)
+ [Docker](https://docs.docker.com/get-docker) (versione minima 25.0.0)
+ Il [plugin buildx](https://github.com/docker/buildx/blob/master/README.md) di Docker.

### Creazione di un'immagine da un'immagine di base alternativa
<a name="java-alt-create"></a>

1. Crea un progetto Maven. I parametri seguenti sono obbligatori:
   + **groupId**: il namespace completo del pacchetto dell'applicazione.
   + **artifactId**: il nome del progetto. Questo sarà il nome della directory per il progetto.

------
#### [ Linux/macOS ]

   ```
   mvn -B archetype:generate \
      -DarchetypeArtifactId=maven-archetype-quickstart \
      -DgroupId=example \
      -DartifactId=myapp \
      -DinteractiveMode=false
   ```

------
#### [ PowerShell ]

   ```
   mvn -B archetype:generate `
      -DarchetypeArtifactId=maven-archetype-quickstart `
      -DgroupId=example `
      -DartifactId=myapp `
      -DinteractiveMode=false
   ```

------

1. Apri la directory del progetto.

   ```
   cd myapp
   ```

1. Apri il file `pom.xml` e sostituisci il contenuto con quanto riportato di seguito. Questo file include [aws-lambda-java-runtime-interface-client](https://github.com/aws/aws-lambda-java-libs/tree/main/aws-lambda-java-runtime-interface-client) come dipendenza. In alternativa, è possibile installare il client di interfaccia di runtime nel Dockerfile. Tuttavia, l'approccio più semplice consiste nell'includere la libreria come dipendenza.

   ```
   <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <groupId>example</groupId>
     <artifactId>hello-lambda</artifactId>
     <packaging>jar</packaging>
     <version>1.0-SNAPSHOT</version>
     <name>hello-lambda</name>
     <url>http://maven.apache.org</url>
     <properties>
       <maven.compiler.source>1.8</maven.compiler.source>
       <maven.compiler.target>1.8</maven.compiler.target>
     </properties>
     <dependencies>
       <dependency>
         <groupId>com.amazonaws</groupId>
         <artifactId>aws-lambda-java-runtime-interface-client</artifactId>
         <version>2.3.2</version>
       </dependency>
     </dependencies>
     <build>
       <plugins>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-dependency-plugin</artifactId>
           <version>3.1.2</version>
           <executions>
             <execution>
               <id>copy-dependencies</id>
               <phase>package</phase>
               <goals>
                 <goal>copy-dependencies</goal>
               </goals>
             </execution>
           </executions>
         </plugin>
       </plugins>
     </build>
   </project>
   ```

1. Apri la directory `myapp/src/main/java/com/example/myapp` e cerca il file `App.java`. Questo è il codice per la funzione Lambda. Sostituisci il codice con il seguente.  
**Example gestore della funzione**  

   ```
   package example;
   
   public class App {
       public static String sayHello() {
           return "Hello world!";
       }
   }
   ```

1. Il comando `mvn -B archetype:generate` del passaggio 1 ha anche generato un test case fittizio nella directory `src/test`. Ai fini di questo tutorial, salta l'esecuzione dei test eliminando la directory `/test` generata interamente.

1. Torna alla directory principale del progetto e crea un nuovo Dockerfile. Il Dockerfile di esempio seguente utilizza un'[immagine Amazon Corretto](https://gallery.ecr.aws/amazoncorretto/amazoncorretto). Amazon Corretto è una distribuzione multi-piattaforma gratuita e pronta per la produzione di OpenJDK.
   + Imposta la proprietà `FROM` sull'URI dell'immagine di base.
   + Imposta l'`ENTRYPOINT` sul modulo su cui desideri che il container Docker venga eseguito all'avvio. In questo caso, il modulo è il client di interfaccia di runtime.
   + Imposta l'argomento `CMD` specificando il gestore della funzione Lambda.

   Nota che l'esempio Dockerfile non include un'[istruzione USER](https://docs.docker.com/reference/dockerfile/#user). Quando implementi un'immagine di container su Lambda, Lambda definisce automaticamente un utente Linux predefinito con autorizzazioni con privilegi minimi. Questo è diverso dal comportamento standard di Docker, che per impostazione predefinita è l'utente `root` quando non viene fornita alcuna istruzione `USER`.  
**Example Dockerfile**  

   ```
   FROM public.ecr.aws/amazoncorretto/amazoncorretto:21 as base
   
   # Configure the build environment
   FROM base as build
   RUN yum install -y maven
   WORKDIR /src
   
   # Cache and copy dependencies
   ADD pom.xml .
   RUN mvn dependency:go-offline dependency:copy-dependencies
   
   # Compile the function
   ADD . .
   RUN mvn package 
   
   # Copy the function artifact and dependencies onto a clean base
   FROM base
   WORKDIR /function
   
   COPY --from=build /src/target/dependency/*.jar ./
   COPY --from=build /src/target/*.jar ./
   
   # Set runtime interface client as default command for the container runtime
   ENTRYPOINT [ "/usr/bin/java", "-cp", "./*", "com.amazonaws.services.lambda.runtime.api.client.AWSLambda" ]
   # Pass the name of the function handler as an argument to the runtime
   CMD [ "example.App::sayHello" ]
   ```

1. Crea l'immagine Docker con il comando [docker build](https://docs.docker.com/engine/reference/commandline/build/). L'esempio seguente assegna un nome all'immagine `docker-image` e le assegna il [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) `test`. Per rendere l'immagine compatibile con Lambda, è necessario utilizzare l'`--provenance=false`opzione.

   ```
   docker buildx build --platform linux/amd64 --provenance=false -t docker-image:test .
   ```
**Nota**  
Il comando specifica l’opzione `--platform linux/amd64` per garantire che il container sia compatibile con l'ambiente di esecuzione di Lambda, indipendentemente dall'architettura della macchina di sviluppo. Se intendi creare una funzione Lambda utilizzando l'architettura del set di ARM64 istruzioni, assicurati di modificare il comando per utilizzare invece l'`--platform linux/arm64`opzione.

### (Facoltativo) Test dell'immagine in locale
<a name="java-alt-test"></a>

Usa il [simulatore dell'interfaccia di runtime](https://github.com/aws/aws-lambda-runtime-interface-emulator/) per testare localmente l'immagine. Puoi [creare l'emulatore nella tua immagine](https://github.com/aws/aws-lambda-runtime-interface-emulator/?tab=readme-ov-file#build-rie-into-your-base-image) o seguire la procedura riportata e installarlo sul tuo computer locale.

**Installazione ed esecuzione dell'emulatore di interfaccia di runtime sul computer locale**

1. Dalla directory del progetto, esegui il comando seguente per scaricare l'emulatore di interfaccia di runtime (architettura x86-64) GitHub e installarlo sul computer locale.

------
#### [ Linux/macOS ]

   ```
   mkdir -p ~/.aws-lambda-rie && \
       curl -Lo ~/.aws-lambda-rie/aws-lambda-rie https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie && \
       chmod +x ~/.aws-lambda-rie/aws-lambda-rie
   ```

   Per installare l'emulatore arm64, sostituisci l'URL del GitHub repository nel comando precedente con il seguente:

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------
#### [ PowerShell ]

   ```
   $dirPath = "$HOME\.aws-lambda-rie"
   if (-not (Test-Path $dirPath)) {
       New-Item -Path $dirPath -ItemType Directory
   }
         
   $downloadLink = "https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie"
   $destinationPath = "$HOME\.aws-lambda-rie\aws-lambda-rie"
   Invoke-WebRequest -Uri $downloadLink -OutFile $destinationPath
   ```

   Per installare l'emulatore arm64, sostituisci `$downloadLink` con quanto segue:

   ```
   https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie-arm64
   ```

------

1. Avvia l'immagine Docker con il comando **docker run**. Tenere presente quanto segue:
   + `docker-image` è il nome dell'immagine e `test` è il tag.
   + `/usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHello` è l'`ENTRYPOINT` seguito dal `CMD` del Dockerfile.

------
#### [ Linux/macOS ]

   ```
   docker run --platform linux/amd64 -d -v ~/.aws-lambda-rie:/aws-lambda -p 9000:8080 \
       --entrypoint /aws-lambda/aws-lambda-rie \
       docker-image:test \
           /usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHello
   ```

------
#### [ PowerShell ]

   ```
   docker run --platform linux/amd64 -d -v "$HOME\.aws-lambda-rie:/aws-lambda" -p 9000:8080 `
   --entrypoint /aws-lambda/aws-lambda-rie `
   docker-image:test `
       /usr/bin/java -cp './*' com.amazonaws.services.lambda.runtime.api.client.AWSLambda example.App::sayHello
   ```

------

   Questo comando esegue l'immagine come container e crea un endpoint locale in `localhost:9000/2015-03-31/functions/function/invocations`.
**Nota**  
Se hai creato l'immagine Docker per l'architettura del set di ARM64 istruzioni, assicurati di utilizzare l'`--platform linux/arm64`opzione invece di. `--platform linux/amd64`

1. Pubblica un evento nell'endpoint locale.

------
#### [ Linux/macOS ]

   Su MacOS o Linux, esegui il comando seguente `curl`:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
   ```

   Questo comando richiama la funzione con un evento vuoto e restituisce una risposta. Se stai utilizzando il tuo codice della funzione anziché quello di esempio, potresti voler richiamare la funzione con un payload JSON. Esempio:

   ```
   curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{"payload":"hello world!"}'
   ```

------
#### [ PowerShell ]

   In PowerShell, esegui il seguente `Invoke-WebRequest` comando:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{}' -ContentType "application/json"
   ```

   Questo comando richiama la funzione con un evento vuoto e restituisce una risposta. Se stai utilizzando il tuo codice della funzione anziché quello di esempio, potresti voler richiamare la funzione con un payload JSON. Esempio:

   ```
   Invoke-WebRequest -Uri "http://localhost:9000/2015-03-31/functions/function/invocations" -Method Post -Body '{"payload":"hello world!"}' -ContentType "application/json"
   ```

------

1. Ottieni l'ID del container.

   ```
   docker ps
   ```

1. Utilizza il comando [docker kill](https://docs.docker.com/engine/reference/commandline/kill/) per arrestare il container. In questo comando, sostituisci `3766c4ab331c` con l'ID del container del passaggio precedente.

   ```
   docker kill 3766c4ab331c
   ```

### Implementazione dell'immagine
<a name="java-alt-deploy"></a>

**Caricamento dell'immagine su Amazon ECR e creazione della funzione Lambda**

1. Esegui il [get-login-password](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/get-login-password.html)comando per autenticare la CLI Docker nel tuo registro Amazon ECR.
   + Imposta il `--region` valore nel Regione AWS punto in cui desideri creare il repository Amazon ECR.
   + Sostituiscilo `111122223333` con il tuo ID. Account AWS 

   ```
   aws ecr get-login-password --region us-east-1 | docker login --username AWS --password-stdin 111122223333.dkr.ecr.us-east-1.amazonaws.com
   ```

1. Crea un repository in Amazon ECR utilizzando il commando [create-repository](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ecr/create-repository.html).

   ```
   aws ecr create-repository --repository-name hello-world --region us-east-1 --image-scanning-configuration scanOnPush=true --image-tag-mutability MUTABLE
   ```
**Nota**  
Il repository Amazon ECR deve corrispondere alla funzione Lambda. Regione AWS 

   In caso di esito positivo, dovresti ottenere una risposta simile a questa:

   ```
   {
       "repository": {
           "repositoryArn": "arn:aws:ecr:us-east-1:111122223333:repository/hello-world",
           "registryId": "111122223333",
           "repositoryName": "hello-world",
           "repositoryUri": "111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world",
           "createdAt": "2023-03-09T10:39:01+00:00",
           "imageTagMutability": "MUTABLE",
           "imageScanningConfiguration": {
               "scanOnPush": true
           },
           "encryptionConfiguration": {
               "encryptionType": "AES256"
           }
       }
   }
   ```

1. Copia il `repositoryUri` dall'output del passaggio precedente.

1. Esegui il comando [docker tag](https://docs.docker.com/engine/reference/commandline/tag/) per etichettare l'immagine locale nel repository Amazon ECR come versione più recente. In questo comando:
   + `docker-image:test` è il nome e [tag](https://docs.docker.com/engine/reference/commandline/build/#tag) dell'immagine Docker. Si tratta del nome e del tag dell'immagine specificati nel comando `docker build`.
   + Sostituisci l’`<ECRrepositoryUri>` con l’`repositoryUri` copiato. Assicurati di includere `:latest` alla fine dell'URI.

   ```
   docker tag docker-image:test <ECRrepositoryUri>:latest
   ```

   Esempio:

   ```
   docker tag docker-image:test 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. Esegui il comando [docker push](https://docs.docker.com/engine/reference/commandline/push/) per implementare la tua immagine locale sul repository Amazon ECR. Assicurati di includere `:latest` alla fine dell'URI del repository.

   ```
   docker push 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest
   ```

1. [Crea un ruolo di esecuzione](lambda-intro-execution-role.md#permissions-executionrole-api) per la funzione, se non lo hai già fatto. Il nome della risorsa Amazon (ARN) del ruolo ti occorrerà nel passaggio successivo.

1. Creazione della funzione Lambda Per `ImageUri`, specifica l'URI del repository creato in precedenza. Assicurati di includere `:latest` alla fine dell'URI.

   ```
   aws lambda create-function \
     --function-name hello-world \
     --package-type Image \
     --code ImageUri=111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
     --role arn:aws:iam::111122223333:role/lambda-ex
   ```
**Nota**  
È possibile creare una funzione utilizzando un'immagine in un AWS account diverso, purché l'immagine si trovi nella stessa regione della funzione Lambda. Per ulteriori informazioni, consulta [Autorizzazioni multiaccount Amazon ECR](images-create.md#configuration-images-xaccount-permissions).

1. Richiama la funzione.

   ```
   aws lambda invoke --function-name hello-world response.json
   ```

   Dovresti ottenere una risposta simile a questa:

   ```
   {
     "ExecutedVersion": "$LATEST", 
     "StatusCode": 200
   }
   ```

1. Per vedere l'output della funzione, controlla il file `response.json`.

Per aggiornare il codice della funzione, devi creare nuovamente l'immagine, caricare la nuova immagine nell'archivio Amazon ECR e quindi utilizzare il [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html)comando per distribuire l'immagine nella funzione Lambda.

Lambda risolve il tag dell'immagine in un digest di immagine specifico. Ciò significa che se punti il tag immagine utilizzato per implementare la funzione su una nuova immagine in Amazon ECR, Lambda non aggiorna automaticamente la funzione per utilizzare la nuova immagine.

Per distribuire la nuova immagine nella stessa funzione Lambda, è necessario utilizzare [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html)il comando, anche se il tag dell'immagine in Amazon ECR rimane lo stesso. Nell'esempio seguente, l'opzione `--publish` crea una nuova versione della funzione utilizzando l'immagine del container aggiornata.

```
aws lambda update-function-code \
  --function-name hello-world \
  --image-uri 111122223333.dkr.ecr.us-east-1.amazonaws.com/hello-world:latest \
  --publish
```