

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Buat dan terapkan UDF menggunakan Lambda
<a name="udf-creating-and-deploying"></a>

Untuk membuat UDF kustom, Anda membuat kelas Java baru dengan memperluas`UserDefinedFunctionHandler`kelas. Kode sumber untuk [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) di SDK tersedia GitHub di [repositori awslabs/aws-athena-query-federation/athena](https://github.com/awslabs/aws-athena-query-federation/tree/master/athena-federation-sdk) -federation-sdk, bersama dengan [contoh implementasi UDF yang dapat Anda periksa dan modifikasi untuk membuat UDF](https://github.com/awslabs/aws-athena-query-federation/tree/master/athena-udfs) khusus.

Langkah-langkah dalam bagian ini menunjukkan penulisan dan membangun file UDF Jar kustom menggunakan[Apache Maven](https://maven.apache.org/index.html)dari baris perintah dan menerapkan.

Lakukan langkah-langkah berikut untuk membuat UDF kustom untuk Athena menggunakan Maven

1. [Kloning SDK dan siapkan lingkungan pengembangan Anda](#udf-create-install-sdk-prep-environment)

1. [Buat proyek Maven Anda](#create-maven-project)

1. [Tambahkan dependensi dan plugin ke proyek Maven Anda](#udf-add-maven-dependencies)

1. [Tulis kode Java untuk UDFs](#udf-write-java)

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

1. [Menyebarkan JAR ke AWS Lambda](#udf-create-deploy)

## Kloning SDK dan siapkan lingkungan pengembangan Anda
<a name="udf-create-install-sdk-prep-environment"></a>

Sebelum memulai, pastikan bahwa git diinstal pada sistem Anda menggunakan`sudo yum install git -y`.

**Untuk menginstal SDK federasi AWS kueri**
+ Masukkan yang berikut pada baris perintah untuk mengkloning repositori SDK. Repositori ini mencakup SDK, contoh dan rangkaian konektor sumber data. Untuk informasi selengkapnya tentang konektor sumber data, lihat [Gunakan Kueri Federasi Amazon Athena](federated-queries.md).

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

**Untuk menginstal prasyarat untuk prosedur ini**

Jika Anda sedang mengerjakan mesin pengembangan yang sudah memiliki Apache Maven, the AWS CLI, dan alat AWS Serverless Application Model build yang diinstal, Anda dapat melewati langkah ini.

1. Dari akar`aws-athena-query-federation`direktori yang Anda buat saat Anda kloning, jalankan[prepare\$1dev\$1env.sh](https://github.com/awslabs/aws-athena-query-federation/blob/master/tools/prepare_dev_env.sh)yang mempersiapkan lingkungan pengembangan Anda.

1. Perbarui shell Anda untuk sumber variabel baru yang dibuat oleh proses instalasi atau restart sesi terminal Anda.

   ```
   source ~/.profile
   ```
**penting**  
Jika Anda melewati langkah ini, Anda akan mendapatkan kesalahan nanti tentang AWS CLI atau AWS SAM membangun alat yang tidak dapat mempublikasikan fungsi Lambda Anda.

## Buat proyek Maven Anda
<a name="create-maven-project"></a>

Jalankan perintah berikut untuk membuat proyek Maven Anda. Ganti *groupId* dengan ID unik organisasi Anda, dan ganti *my-athena-udf* dengan nama aplikasi Anda Untuk informasi selengkapnya, lihat [Bagaimana cara membuat proyek Maven pertama saya](https://maven.apache.org/guides/getting-started/index.html#How_do_I_make_my_first_Maven_project)? dalam dokumentasi Apache Maven.

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

## Tambahkan dependensi dan plugin ke proyek Maven Anda
<a name="udf-add-maven-dependencies"></a>

Tambahkan konfigurasi berikut ke file proyek Maven `pom.xml` Anda. Sebagai contoh, lihat file [pom.xml](https://github.com/awslabs/aws-athena-query-federation/blob/master/athena-udfs/pom.xml) di file 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>
```

## Tulis kode Java untuk UDFs
<a name="udf-write-java"></a>

Buat kelas baru dengan memperluas [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) Tulis Anda UDFs di dalam kelas.

Dalam contoh berikut, dua metode Java untuk UDFs, `compress()` dan`decompress()`, dibuat di dalam kelas`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);
    }
}
```

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

Jalankan`mvn clean install`untuk membangun proyek Anda. Setelah berhasil dibangun, file JAR dibuat di `target` folder proyek Anda bernama`artifactId-version.jar`, di mana nama *artifactId* yang Anda berikan dalam proyek Maven, misalnya,. `my-athena-udfs`

## Menyebarkan JAR ke AWS Lambda
<a name="udf-create-deploy"></a>

Anda memiliki dua pilihan untuk men-deploy kode Anda untuk Lambda:
+ Menyebarkan Menggunakan AWS Serverless Application Repository (Disarankan)
+ Buat Fungsi Lambda dari file JAR

### Opsi 1: Menyebarkan ke AWS Serverless Application Repository
<a name="udf-create-deploy-sar"></a>

Ketika Anda menyebarkan file JAR Anda ke AWS Serverless Application Repository, Anda membuat file YAMM AWS SAM template yang mewakili arsitektur aplikasi Anda. Anda kemudian menentukan file YAML ini dan bucket Amazon S3 tempat artifact untuk aplikasi Anda di-upload dan dibuat tersedia untuk AWS Serverless Application Repository. Prosedur di bawah ini menggunakan[publish.sh](https://github.com/awslabs/aws-athena-query-federation/blob/master/tools/publish.sh)skrip yang terletak di`athena-query-federation/tools`dari Athena Kueri Federation SDK yang Anda kloning sebelumnya.

Untuk informasi dan persyaratan selengkapnya, lihat [Menerbitkan aplikasi](https://docs.aws.amazon.com/serverlessrepo/latest/devguide/serverlessrepo-publishing-applications.html) di *Panduan AWS Serverless Application Repository Pengembang*, [konsep AWS SAM templat](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-basics.html) di *Panduan AWS Serverless Application Model Pengembang*, dan [Menerbitkan aplikasi tanpa server menggunakan CLI AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-template-publishing-applications.html).

Contoh berikut menunjukkan parameter dalam file YAML. Tambahkan parameter serupa ke file YAML dan simpan di direktori proyek Anda. Lihat [athena-udf.yaml](https://github.com/awslabs/aws-athena-query-federation/blob/master/athena-udfs/athena-udfs.yaml) untuk contoh lengkapnya. 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
```

Salin`publish.sh`script ke direktori proyek tempat Anda menyimpan file YAML Anda, dan jalankan perintah berikut:

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

Misalnya, jika lokasi bucket Anda`s3://amzn-s3-demo-bucket/mysarapps/athenaudf`dan file YAML Anda disimpan sebagai`my-athena-udfs.yaml`:

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

**Untuk membuat fungsi Lambda**

1. Buka konsol Lambda di [https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/), pilih **Create function**, lalu pilih **Browse serverless** app repository

1. Pilih**Aplikasi privat**, temukan aplikasi Anda dalam daftar, atau cari menggunakan kata-kata kunci, dan pilih.

1. Tinjau dan berikan detail aplikasi, lalu pilih**Terapkan.**

   Anda sekarang dapat menggunakan nama metode yang ditentukan dalam file JAR fungsi Lambda Anda seperti di UDFs Athena.

### Opsi 2: Buat fungsi Lambda secara langsung
<a name="udf-create-deploy-lambda"></a>

Anda juga dapat membuat fungsi Lambda secara langsung menggunakan konsol atau. AWS CLI Contoh berikut menunjukkan menggunakan Lambda`create-function`Perintah CLI. 

```
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
```