

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

# Creare e distribuiredi una UDF utilizzando Lambda
<a name="udf-creating-and-deploying"></a>

Per creare una funzione definita dall'utente personalizzata, crea una nuova classe Java estendendo la classe `UserDefinedFunctionHandler`. Il codice sorgente del [UserDefinedFunctionHandlerfile.java](https://github.com/awslabs/aws-athena-query-federation/blob/master/athena-federation-sdk/src/main/java/com/amazonaws/athena/connector/lambda/handlers/UserDefinedFunctionHandler.java) nell'SDK è disponibile nell'[archivio awslabs/aws-athena-query-federation/athena -federation-sdk, insieme GitHub a esempi di implementazioni UDF che puoi esaminare e modificare](https://github.com/awslabs/aws-athena-query-federation/tree/master/athena-federation-sdk) [per creare una UDF personalizzata](https://github.com/awslabs/aws-athena-query-federation/tree/master/athena-udfs).

La procedura in questa sezione illustra la scrittura e la creazione di un file Jar della funzione definita dall'utente personalizzata utilizzando [Apache Maven](https://maven.apache.org/index.html) dalla riga di comando e una distribuzione.

Procedere con i seguenti passaggi per creare una funzione definita dall’utente personalizzata per Athena utilizzando Maven

1. [Duplicazione dell'SDK e preparazione dell'ambiente di sviluppo](#udf-create-install-sdk-prep-environment)

1. [Creazione del progetto Maven](#create-maven-project)

1. [Aggiunta di dipendenze e plugin al progetto Maven](#udf-add-maven-dependencies)

1. [Scrivere codice Java per UDFs](#udf-write-java)

1. [Compilazione del file JAR](#udf-create-package-jar)

1. [Distribuisci il JAR in AWS Lambda](#udf-create-deploy)

## Duplicazione dell'SDK e preparazione dell'ambiente di sviluppo
<a name="udf-create-install-sdk-prep-environment"></a>

Prima di iniziare, assicurati che git sia installato sul tuo sistema utilizzando `sudo yum install git -y`.

**AWS Per installare il Query Federation SDK**
+ Immettere quanto segue nella riga di comando per clonare il repository SDK. Questo repository include l'SDK, esempi e una suite di connettori di origine dati. Per ulteriori informazioni sui connettori di origine dati, consulta [Utilizza Amazon Athena Federated Query](federated-queries.md).

  ```
  git clone https://github.com/awslabs/aws-athena-query-federation.git
  ```

**Per installare i prerequisiti per questa procedura**

Se state lavorando su una macchina di sviluppo su cui sono già installati Apache Maven AWS CLI, lo strumento di AWS Serverless Application Model compilazione e sviluppo, potete saltare questo passaggio.

1. Dalla radice della directory `aws-athena-query-federation` creata durante la clonazione, esegui lo script [prepare\$1dev\$1env.sh](https://github.com/awslabs/aws-athena-query-federation/blob/master/tools/prepare_dev_env.sh) che prepara l'ambiente di sviluppo.

1. Aggiorna la shell per generare nuove variabili create dal processo di installazione o riavvia la sessione del terminale.

   ```
   source ~/.profile
   ```
**Importante**  
Se salti questo passaggio, in seguito riceverai degli errori relativi all'impossibilità dello strumento AWS CLI o AWS SAM build di pubblicare la tua funzione Lambda.

## Creazione del progetto Maven
<a name="create-maven-project"></a>

Esegui il comando seguente per creare il progetto Maven. Sostituiscila *groupId* con l'ID univoco della tua organizzazione e *my-athena-udf* sostituiscila con il nome dell'applicazione. Per ulteriori informazioni, vedi [Come faccio a creare il mio primo progetto Maven](https://maven.apache.org/guides/getting-started/index.html#How_do_I_make_my_first_Maven_project)? nella documentazione di Apache Maven.

```
mvn -B archetype:generate \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DgroupId=groupId \
-DartifactId=my-athena-udfs
```

## Aggiunta di dipendenze e plugin al progetto Maven
<a name="udf-add-maven-dependencies"></a>

Aggiungi le seguenti configurazioni al file `pom.xml` del progetto Maven. Per un esempio, consultate il [file pom.xml](https://github.com/awslabs/aws-athena-query-federation/blob/master/athena-udfs/pom.xml) in. GitHub

```
<properties>
    <aws-athena-federation-sdk.version>2022.47.1</aws-athena-federation-sdk.version>
</properties>

<dependencies>
    <dependency>
        <groupId>com.amazonaws</groupId>
        <artifactId>aws-athena-federation-sdk</artifactId>
        <version>${aws-athena-federation-sdk.version}</version>
    </dependency>
</dependencies>
    
<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
            <version>3.2.1</version>
            <configuration>
                <createDependencyReducedPom>false</createDependencyReducedPom>
                <filters>
                    <filter>
                        <artifact>*:*</artifact>
                        <excludes>
                            <exclude>META-INF/*.SF</exclude>
                            <exclude>META-INF/*.DSA</exclude>
                            <exclude>META-INF/*.RSA</exclude>
                        </excludes>
                    </filter>
                </filters>
            </configuration>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals>
                        <goal>shade</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
```

## Scrivere codice Java per UDFs
<a name="udf-write-java"></a>

Crea una nuova classe estendendo [UserDefinedFunctionHandler.java.](https://github.com/awslabs/aws-athena-query-federation/blob/master/athena-federation-sdk/src/main/java/com/amazonaws/athena/connector/lambda/handlers/UserDefinedFunctionHandler.java) Scrivi i tuoi dati UDFs all'interno della classe.

Nell'esempio seguente, all'interno della classe vengono creati due metodi Java per UDFs `compress()` e `decompress()``MyUserDefinedFunctions`.

```
*package *com.mycompany.athena.udfs;

public class MyUserDefinedFunctions
        extends UserDefinedFunctionHandler
{
    private static final String SOURCE_TYPE = "MyCompany";

    public MyUserDefinedFunctions()
    {
        super(SOURCE_TYPE);
    }

    /**
     * Compresses a valid UTF-8 String using the zlib compression library.
     * Encodes bytes with Base64 encoding scheme.
     *
     * @param input the String to be compressed
     * @return the compressed String
     */
    public String compress(String input)
    {
        byte[] inputBytes = input.getBytes(StandardCharsets.UTF_8);

        // create compressor
        Deflater compressor = new Deflater();
        compressor.setInput(inputBytes);
        compressor.finish();

        // compress bytes to output stream
        byte[] buffer = new byte[4096];
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(inputBytes.length);
        while (!compressor.finished()) {
            int bytes = compressor.deflate(buffer);
            byteArrayOutputStream.write(buffer, 0, bytes);
        }

        try {
            byteArrayOutputStream.close();
        }
        catch (IOException e) {
            throw new RuntimeException("Failed to close ByteArrayOutputStream", e);
        }

        // return encoded string
        byte[] compressedBytes = byteArrayOutputStream.toByteArray();
        return Base64.getEncoder().encodeToString(compressedBytes);
    }

    /**
     * Decompresses a valid String that has been compressed using the zlib compression library.
     * Decodes bytes with Base64 decoding scheme.
     *
     * @param input the String to be decompressed
     * @return the decompressed String
     */
    public String decompress(String input)
    {
        byte[] inputBytes = Base64.getDecoder().decode((input));

        // create decompressor
        Inflater decompressor = new Inflater();
        decompressor.setInput(inputBytes, 0, inputBytes.length);

        // decompress bytes to output stream
        byte[] buffer = new byte[4096];
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(inputBytes.length);
        try {
            while (!decompressor.finished()) {
                int bytes = decompressor.inflate(buffer);
                if (bytes == 0 && decompressor.needsInput()) {
                    throw new DataFormatException("Input is truncated");
                }
                byteArrayOutputStream.write(buffer, 0, bytes);
            }
        }
        catch (DataFormatException e) {
            throw new RuntimeException("Failed to decompress string", e);
        }

        try {
            byteArrayOutputStream.close();
        }
        catch (IOException e) {
            throw new RuntimeException("Failed to close ByteArrayOutputStream", e);
        }

        // return decoded string
        byte[] decompressedBytes = byteArrayOutputStream.toByteArray();
        return new String(decompressedBytes, StandardCharsets.UTF_8);
    }
}
```

## Compilazione del file JAR
<a name="udf-create-package-jar"></a>

Esegui `mvn clean install` per compilare il progetto. Una volta completato con successo, viene creato un file JAR nella `target` cartella denominata del progetto`artifactId-version.jar`, dove si *artifactId* trova il nome fornito nel progetto Maven, ad esempio. `my-athena-udfs`

## Distribuisci il JAR in AWS Lambda
<a name="udf-create-deploy"></a>

Hai a disposizione due opzioni per distribuire il codice in Lambda:
+ Distribuisci utilizzando AWS Serverless Application Repository (consigliato)
+ Creazione di una funzione Lambda dal file JAR

### Opzione 1: eseguire la distribuzione su AWS Serverless Application Repository
<a name="udf-create-deploy-sar"></a>

Quando si distribuisce il file JAR su AWS Serverless Application Repository, si crea un file YAML AWS SAM modello che rappresenta l'architettura dell'applicazione. Quindi devi specificare questo file YAML e un bucket Amazon S3 in cui gli artefatti dell'applicazione vengono caricati e resi disponibili ad AWS Serverless Application Repository. Nella procedura riportata di seguito viene utilizzato lo script [publish.sh](https://github.com/awslabs/aws-athena-query-federation/blob/master/tools/publish.sh) che si trova nella directory `athena-query-federation/tools` dell'SDK di Athena Query Federation clonato in precedenza.

Per ulteriori informazioni e requisiti, consulta [Pubblicazione di applicazioni](https://docs.aws.amazon.com/serverlessrepo/latest/devguide/serverlessrepo-publishing-applications.html) nella *AWS Serverless Application Repository Developer Guide*, [concetti di AWS SAM template](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-basics.html) nella *AWS Serverless Application Model Developer Guide* e [Pubblicazione di applicazioni serverless utilizzando la AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-publishing-applications.html).

Nell'esempio seguente vengono illustrati i parametri in un file YAML. Aggiungi parametri simili al file YAML e salvalo nella directory del progetto. Vedi [athena-udf.yaml](https://github.com/awslabs/aws-athena-query-federation/blob/master/athena-udfs/athena-udfs.yaml) in per un esempio completo. GitHub 

```
Transform: 'AWS::Serverless-2016-10-31'
Metadata:
  'AWS::ServerlessRepo::Application':
    Name: MyApplicationName
    Description: 'The description I write for my application'
    Author: 'Author Name'
    Labels:
      - athena-federation
    SemanticVersion: 1.0.0
Parameters:
  LambdaFunctionName:
    Description: 'The name of the Lambda function that will contain your UDFs.'
    Type: String
  LambdaTimeout:
    Description: 'Maximum Lambda invocation runtime in seconds. (min 1 - 900 max)'
    Default: 900
    Type: Number
  LambdaMemory:
    Description: 'Lambda memory in MB (min 128 - 3008 max).'
    Default: 3008
    Type: Number
Resources:
  ConnectorConfig:
    Type: 'AWS::Serverless::Function'
    Properties:
      FunctionName: !Ref LambdaFunctionName
      Handler: "full.path.to.your.handler. For example, com.amazonaws.athena.connectors.udfs.MyUDFHandler"
      CodeUri: "Relative path to your JAR file. For example, ./target/athena-udfs-1.0.jar"
      Description: "My description of the UDFs that this Lambda function enables."
      Runtime: java8
      Timeout: !Ref LambdaTimeout
      MemorySize: !Ref LambdaMemory
```

Copia lo script `publish.sh` nella directory del progetto in cui è stato salvato il file YAML ed esegui il comando seguente:

```
./publish.sh MyS3Location MyYamlFile
```

Ad esempio, se la posizione del bucket è `s3://amzn-s3-demo-bucket/mysarapps/athenaudf` e il file YAML è stato salvato come `my-athena-udfs.yaml`:

```
./publish.sh amzn-s3-demo-bucket/mysarapps/athenaudf my-athena-udfs
```

**Come creare una funzione Lambda**

1. Apri la console Lambda all'indirizzo [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/), scegli **Crea funzione**, quindi scegli **Browse serverless app repository**

1. Scegliere **Private applications (Applicazioni private)**, trovare l'applicazione nell'elenco o cercarla usando le parole chiave e selezionarla.

1. Rivedere e fornire i dettagli dell'applicazione, quindi scegliere **Deploy (Distribuisci)**.

   Ora puoi usare i nomi dei metodi definiti nel file JAR della funzione Lambda come in UDFs Athena.

### Opzione 2: Creare direttamente una funzione Lambda
<a name="udf-create-deploy-lambda"></a>

Puoi anche creare una funzione Lambda direttamente utilizzando la console o. AWS CLI L'esempio seguente illustra l'utilizzo del comando CLI della `create-function` Lambda. 

```
aws lambda create-function \
 --function-name MyLambdaFunctionName \
 --runtime java8 \
 --role arn:aws:iam::1234567890123:role/my_lambda_role \
 --handler com.mycompany.athena.udfs.MyUserDefinedFunctions \
 --timeout 900 \
 --zip-file fileb://./target/my-athena-udfs-1.0-SNAPSHOT.jar
```