

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

# Mengkonfigurasi pengukuran per jam dengan AWS Marketplace Metering Service
<a name="container-metering-registerusage"></a>

**catatan**  
 Untuk penerapan Amazon EKS, perangkat lunak Anda harus menggunakan [peran IAM untuk akun layanan (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) untuk menandatangani panggilan API untuk operasi API. [https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_RegisterUsage.html](https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_RegisterUsage.html) Menggunakan [EKS Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html), peran node, atau kunci akses jangka panjang tidak didukung.  
Untuk penerapan Amazon ECS, perangkat lunak Anda harus menggunakan peran [IAM tugas Amazon ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html) untuk menandatangani panggilan API untuk operasi API. [https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_RegisterUsage.html](https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_RegisterUsage.html) Menggunakan peran node atau kunci akses jangka panjang tidak didukung.

Jika produk kontainer Anda menggunakan harga per jam per tugas atau per-pod alih-alih dimensi harga terukur khusus, Anda tidak perlu menentukan dimensi pengukuran khusus. Anda dapat menggunakan AWS Marketplace Metering Service untuk pengukuran per jam dengan produk kontainer. AWS Marketplace Bagian berikut menunjukkan cara mengonfigurasi pengukuran per jam dengan AWS Marketplace Metering Service.

Perangkat lunak pengukur operasi `RegisterUsage` API digunakan per tugas Amazon Elastic Container Service (Amazon ECS) atau per pod Amazon Elastic Kubernetes Service (Amazon EKS), per jam, dengan penggunaan prorata ke yang kedua. Penggunaan minimal 1 menit berlaku untuk tugas atau pod yang berumur pendek. Pengukuran berkelanjutan untuk penggunaan perangkat lunak secara otomatis ditangani oleh. AWS Marketplace Metering Control Plane Perangkat lunak Anda tidak diperlukan untuk melakukan tindakan khusus pengukuran apa pun kecuali menelepon `RegisterUsage` sekali untuk pengukuran penggunaan perangkat lunak untuk memulai.

`RegisterUsage`harus segera dipanggil pada saat meluncurkan wadah. Jika Anda tidak mendaftarkan kontainer dalam 6 jam pertama peluncuran kontainer, AWS Marketplace Metering Service tidak memberikan jaminan pengukuran apa pun untuk bulan-bulan sebelumnya. Namun, pengukuran akan berlanjut untuk bulan berjalan ke depan sampai wadah berakhir.

Mereka AWS Marketplace Metering Control Plane terus menagih pelanggan untuk menjalankan tugas Amazon ECS dan pod Amazon EKS, terlepas dari status langganan pelanggan. Ini menghilangkan kebutuhan perangkat lunak Anda untuk melakukan pemeriksaan hak setelah peluncuran tugas atau pod awal yang berhasil. 

*Untuk informasi selengkapnya tentang mengintegrasikan AWS Marketplace Metering Service API dengan produk kontainer dengan harga per jam, lihat lab [Integrasikan dengan pengukuran per jam](https://catalog.workshops.aws/mpseller/en-US/container/integrate-hourly) di bengkel penjual.AWS Marketplace * 

**Topics**
+ [Prasyarat pengukuran per jam](#hourly-metering-prereqs)
+ [Integrasi pengujian untuk `RegisterUsage`](#testing-integration-for-registerusage)
+ [Penanganan kesalahan untuk `RegisterUsage`](#hourly-metering-entitlement-error-handling)
+ [Mengintegrasikan produk container Anda dengan AWS Marketplace Metering Service menggunakan AWS SDK untuk Java](java-integration-example-registerusage.md)

## Prasyarat pengukuran per jam
<a name="hourly-metering-prereqs"></a>

Sebelum menerbitkan produk, Anda harus melakukan hal berikut:

1. Buat produk kontainer baru di Portal Manajemen AWS Marketplace, dan catat kode produknya.

   Untuk informasi selengkapnya, lihat [Ikhtisar: Buat produk kontainer](container-product-getting-started.md#create-container-product).

1. Gunakan peran AWS Identity and Access Management (IAM) untuk tugas atau pod yang menjalankan aplikasi Anda dengan izin IAM yang diperlukan untuk memanggil. `RegisterUsage` Kebijakan terkelola `AWSMarketplaceMeteringRegisterUsage` meliputi izin-izin ini. Untuk informasi selengkapnya tentang kebijakan, lihat [ AWSMarketplaceMeteringFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSMarketplaceMeteringFullAccess.html)di *Referensi Kebijakan AWS Terkelola*.

1. (Opsional) Jika Anda ingin melihat logging, kami sarankan Anda mengaktifkan AWS CloudTrail logging dalam tugas atau definisi pod.

1. Lakukan panggilan uji ke operasi `RegisterUsage` API dengan catatan untuk semua dimensi harga yang Anda tetapkan.

## Integrasi pengujian untuk `RegisterUsage`
<a name="testing-integration-for-registerusage"></a>

Gunakan operasi `RegisterUsage` API untuk menguji integrasi Anda sebelum mengirimkan gambar Anda AWS Marketplace untuk dipublikasikan.

Panggil `RegisterUsage` dari gambar kontainer dengan menjalankan produk Anda di Amazon ECS atau Amazon EKS. Gunakan AWS akun yang Anda gunakan untuk membuat daftar produk AWS Marketplace. Integrasi pengukuran Anda harus secara dinamis mengatur Wilayah AWS, bukan hardcoding itu. Namun, saat menguji, luncurkan setidaknya satu tugas Amazon ECS atau pod Amazon EKS yang berisi kontainer berbayar Anda di Wilayah AS Timur (Virginia Utara). Dengan melakukan ini, tim AWS Marketplace operasi dapat memverifikasi pekerjaan Anda dengan log di Wilayah tersebut.

**catatan**  
Jika produk Anda mendukung Amazon ECS dan Amazon EKS, Anda hanya perlu meluncurkan di Amazon EKS bagi kami untuk memvalidasi integrasi Anda.

Anda tidak dapat sepenuhnya menguji integrasi sampai produk Anda dipublikasikan dengan semua metadata dan informasi harga yang diperlukan. Jika diminta, tim operasi AWS Marketplace katalog dapat memverifikasi penerimaan catatan pengukuran Anda.

## Penanganan kesalahan untuk `RegisterUsage`
<a name="hourly-metering-entitlement-error-handling"></a>

Jika image container Anda terintegrasi dengan AWS Marketplace Metering Service dan menerima pengecualian selain `ThrottlingException` saat startup container, Anda harus menghentikan container untuk mencegah penggunaan yang tidak sah.

Pengecualian selain `ThrottlingException` dilemparkan hanya pada panggilan awal ke operasi `RegisterUsage` API. Panggilan berikutnya dari tugas Amazon ECS yang sama atau pod Amazon EKS tidak dibuang `CustomerNotSubscribedException` meskipun pelanggan berhenti berlangganan saat tugas atau pod masih berjalan. Pelanggan ini masih dikenakan biaya untuk menjalankan kontainer setelah mereka berhenti berlangganan, dan penggunaannya dilacak.

Tabel berikut menjelaskan kesalahan yang mungkin ditimbulkan oleh operasi `RegisterUsage` API. Setiap bahasa pemrograman AWS SDK memiliki seperangkat pedoman penanganan kesalahan yang dapat Anda rujuk untuk informasi tambahan. 


|  **Kesalahan**  |  **Deskripsi**  | 
| --- | --- | 
|  InternalServiceErrorException  |  RegisterUsagetidak tersedia.  | 
|  CustomerNotEntitledException  |  Pelanggan tidak memiliki langganan yang valid untuk produk tersebut.  | 
|  InvalidProductCodeException  |  ParameterProductCodenilai yang dilewatkan sebagai bagian dari permintaan tidak ada.  | 
|  InvalidPublicKeyException  |  ParameterPublicKeyVersionnilai yang dilewatkan sebagai bagian dari permintaan tidak ada.  | 
|  PlatformNotSupportedException  |  AWS Marketplace tidak mendukung penggunaan pengukuran dari platform yang mendasarinya. Hanya Amazon ECS, Amazon EKS, dan AWS Fargate yang didukung.  | 
|  ThrottlingException  |  Panggilan keRegisterUsagediperlambat.  | 
|  InvalidRegionException  |  RegisterUsageharus dipanggil sama Wilayah AWS dengan tugas Amazon ECS atau pod Amazon EKS diluncurkan. Hal ini mencegah kontainer dari memilih Wilayah (misalnya,withRegion(“us-east-1”)) saat memanggilRegisterUsage.  | 

# Mengintegrasikan produk container Anda dengan AWS Marketplace Metering Service menggunakan AWS SDK untuk Java
<a name="java-integration-example-registerusage"></a>

Anda dapat menggunakan AWS SDK untuk Java untuk berintegrasi dengan AWS Marketplace Metering Service. Pengukuran berkelanjutan untuk penggunaan perangkat lunak secara otomatis ditangani oleh. AWS Marketplace Metering Control Plane Perangkat lunak Anda tidak diperlukan untuk melakukan tindakan khusus pengukuran apa pun kecuali menelepon `RegisterUsage` sekali untuk pengukuran penggunaan perangkat lunak untuk memulai. Topik ini memberikan contoh implementasi menggunakan AWS SDK untuk Java untuk mengintegrasikan dengan `RegisterUsage` tindakan [Layanan AWS Marketplace Pengukuran](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html). 

`RegisterUsage`harus segera dipanggil pada saat meluncurkan wadah. Jika Anda tidak mendaftarkan kontainer dalam 6 jam pertama peluncuran kontainer, AWS Marketplace Metering Service tidak memberikan jaminan pengukuran apa pun untuk bulan-bulan sebelumnya. Namun, pengukuran akan berlanjut untuk bulan berjalan ke depan sampai wadah berakhir.

Untuk kode sumber lengkap, lihat[RegisterUsage Contoh Java](#registerusage-java-example). Banyak dari langkah-langkah ini berlaku terlepas dari bahasa AWS SDK. 



**Contoh langkah untuk integrasi AWS Marketplace Metering Service**

1. Masuk ke [Portal Manajemen AWS Marketplace](https://aws.amazon.com/marketplace/management/tour).

1. Dari**Aset**Pilih**Kontainer**untuk mulai membuat produk kontainer baru. Membuat produk menghasilkan kode produk untuk produk untuk mengintegrasikan dengan citra kontainer Anda. Untuk informasi tentang izin IAM yang diperlukan, lihat [AWS Marketplace izin API pengukuran dan hak](iam-user-policy-for-aws-marketplace-actions.md).

1.  Unduh [AWS Java SDK](https://aws.amazon.com/sdk-for-java/) publik. 
**penting**  
 Untuk memanggil metering APIs dari Amazon EKS, Anda harus [menggunakan AWS SDK yang didukung](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html) dan berjalan di klaster Amazon EKS yang menjalankan Kubernetes 1.13 atau yang lebih baru. 

1.  (Opsional) Jika Anda mengintegrasikan dengan `RegisterUsage` tindakan dan ingin melakukan verifikasi tanda tangan digital, Anda perlu mengonfigurasi pustaka verifikasi [BouncyCastle](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on)tanda tangan di classpath aplikasi Anda.

   Jika Anda ingin menggunakan JSON Web Token (JWT), Anda juga harus menyertakan[Java JWT](https://jwt.io/)perpustakaan di classpath aplikasi Anda. Menggunakan JWT memberikan pendekatan yang lebih sederhana untuk verifikasi tanda tangan tetapi tidak diperlukan, dan Anda dapat menggunakan mandiri sebagai BouncyCastle gantinya. Baik Anda menggunakan JWT atau BouncyCastle, Anda perlu menggunakan sistem build seperti Maven untuk menyertakan dependensi transitif atau JWT di classpath aplikasi Anda. BouncyCastle 

   ```
   // Required for signature verification using code sample
   <dependency>
       <groupId>org.bouncycastle</groupId>
       <artifactId>bcpkix-jdk15on</artifactId>
       <version>1.60</version>
   </dependency>
   
   // This one is only required for JWT
   <dependency>
       <groupId>com.nimbusds</groupId>
       <artifactId>nimbus-jose-jwt</artifactId>
       <version>6.0</version>
   </dependency>
   ```

1.  Panggilan`RegisterUsage`dari setiap citra kontainer berbayar dalam penawaran produk Anda.`ProductCode`dan`PublicKeyVersion`diperlukan parameter, dan semua input lainnya adalah opsional. Berikut ini adalah contoh muatan untuk`RegisterUsage`. 

   ```
   {
       "ProductCode" : "string", // (required)
       "PublicKeyVersion": 1,    // (required)
       "Nonce": "string",        // (optional) to scope down the registration
                                 //            to a specific running software
                                 //            instance and guard against
                                 //            replay attacks
   }
   ```
**catatan**  
Dimungkinkan untuk melihat masalah sementara dalam menghubungkan ke AWS Marketplace Metering Service. AWS Marketplace sangat merekomendasikan untuk menerapkan percobaan ulang hingga 30 menit, dengan mundur eksponensial, untuk menghindari pemadaman jangka pendek atau masalah jaringan.

1.  `RegisterUsage`menghasilkan tanda tangan digital RSA-PSS menggunakan SHA-256 yang dapat Anda gunakan untuk memverifikasi keaslian permintaan. Tanda tangan meliputi kolom-kolom berikut:`ProductCode`,`PublicKeyVersion`, dan`Nonce`. Untuk memverifikasi tanda tangan digital, Anda harus mempertahankan bidang ini dari permintaan. Kode berikut adalah contoh responss terhadap`RegisterUsage`Panggilan. 

   ```
   {
   "Signature": "<<JWT Token>>"
   }
   
   // Where the JWT Token is composed of 3 dot-separated, 
   // base-64 URL Encoded sections.
   // e.g. eyJhbGcVCJ9.eyJzdWIMzkwMjJ9.rrO9Qw0SXRWTe
   
   // Section 1: Header/Algorithm
   {
   "alg": "PS256",
   "typ": "JWT"
   }
   
   // Section 2: Payload
   {
   "ProductCode" : "string",
   "PublicKeyVersion": 1,
   "Nonce": "string",
   "iat": date // JWT issued at claim 
   }
   
   // Section 3: RSA-PSS SHA256 signature
   "rrO9Q4FEi3gweH3X4lrt2okf5zwIatUUwERlw016wTy_21Nv8S..."
   ```

1. Buat kembali versi baru gambar penampung Anda yang menyertakan `RegisterUsage` panggilan, beri tag penampung, dan dorong ke registri kontainer apa pun yang kompatibel dengan Amazon ECS atau Amazon EKS, seperti Amazon ECR atau Amazon ECR Public. Jika Anda menggunakan Amazon ECR, memastikan bahwa akun meluncurkan tugas Amazon ECS atau Amazon EKS pod memiliki izin pada repositori Amazon ECR. Jika tidak, peluncuran gagal.

1.  Buat[IAM](https://aws.amazon.com/iam/)peran yang memberikan izin untuk kontainer Anda untuk menelepon`RegisterUsage`, seperti yang didefinisikan dalam kode berikut. Anda harus menyediakan IAM role ini di parameter [Peran tugas](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_role_arn) Amazon ECS atau definisi pod Amazon EKS.

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Action": [
                   "aws-marketplace:RegisterUsage"
                   ],
                   "Effect": "Allow",
                   "Resource": "*"
           }
       ]
   }
   ```

------

1. Buat tugas Amazon ECS atau definisi pod Amazon EKS yang mereferensikan wadah yang telah terintegrasi AWS Marketplace dan mereferensikan peran IAM yang Anda buat di langkah 7. Anda harus mengaktifkan AWS CloudTrail logging dalam definisi tugas jika Anda ingin melihat logging. 

1. Buat Amazon ECS atau Amazon EKS cluster untuk melaksanakan tugas Anda atau pod. Untuk informasi selengkapnya tentang cara membuat Amazon ECS cluster, lihat[Membuat Gugus](https://docs.aws.amazon.com/AmazonECS/latest/userguide/create_cluster.html)di*Panduan Pengembang Layanan Elastic kontainer*. Untuk informasi selengkapnya tentang membuat cluster Amazon EKS (menggunakan Kubernetes versi 1.1.3.x atau yang lebih baru), lihat[Membuat klaster EKS Amazon](https://docs.aws.amazon.com/eks/latest/userguide/create_cluster.html).

1. Konfigurasikan cluster Amazon ECS atau Amazon EKS dan luncurkan definisi tugas Amazon ECS atau pod Amazon EKS yang Anda buat, di us-east-1. Wilayah AWS Hanya selama proses pengujian ini, sebelum produk ditayangkan, Anda harus menggunakan wilayah ini.

1. Saat Anda mendapatkan responss yang valid kembali dari`RegisterUsage`, Anda dapat mulai membuat produk kontainer Anda. Untuk pertanyaan, hubungi[AWS Marketplace Operasi Penjual](https://aws.amazon.com/marketplace/management/contact-us/)Tim. 

## RegisterUsage Contoh Java
<a name="registerusage-java-example"></a>

Contoh berikut menggunakan AWS SDK untuk Java dan AWS Marketplace Metering Service untuk memanggil `RegisterUsage` operasi. Verifikasi tanda tangan bersifat opsional, tetapi jika Anda ingin melakukan verifikasi tanda tangan, Anda harus menyertakan pustaka verifikasi tanda tangan digital yang diperlukan. Contoh ini hanya untuk tujuan ilustrasi. 

```
import com.amazonaws.auth.PEM;
import com.amazonaws.services.marketplacemetering.AWSMarketplaceMetering;
import com.amazonaws.services.marketplacemetering.AWSMarketplaceMeteringClientBuilder;
import com.amazonaws.services.marketplacemetering.model.RegisterUsageRequest;
import com.amazonaws.services.marketplacemetering.model.RegisterUsageResult;
import com.amazonaws.util.json.Jackson;
import com.fasterxml.jackson.databind.JsonNode;
import com.nimbusds.jose.JWSObject;
import com.nimbusds.jose.JWSVerifier;
import com.nimbusds.jose.crypto.RSASSAVerifier;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.interfaces.RSAPublicKey;
import java.util.Base64;
import java.util.Optional;
import java.util.UUID;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

/**
 * Class for making calls out to &MKT; Metering Service.
 */
class RegisterUsage {

    private static final String PRODUCT_CODE = ".......";

    private final AWSMarketplaceMetering registerUsageClient;
    private final SignatureVerifier signatureVerifier;
    private final int publicKeyVersion;

    public RegisterUsage(final SignatureVerifier signatureVerifier) {
        this.signatureVerifier = signatureVerifier;
        this.publicKeyVersion = PublicKeyProvider.PUBLIC_KEY_VERSION;
        this.registerUsageClient = AWSMarketplaceMeteringClientBuilder.standard().build();
    }

    /**
     * Shows how to call RegisterUsage client and verify digital signature.
     */
    public void callRegisterUsage() {
        RegisterUsageRequest request = new RegisterUsageRequest()
                .withProductCode(PRODUCT_CODE)
                .withPublicKeyVersion(publicKeyVersion)
                .withNonce(UUID.randomUUID().toString());

        // Execute call to RegisterUsage (only need to call once at container startup)
        RegisterUsageResult result = this.registerUsageClient.registerUsage(request);

        // Verify Digital Signature w/o JWT
        boolean isSignatureValid = this.signatureVerifier.verify(request, result);
        if (!isSignatureValid) {
            throw new RuntimeException("Revoke entitlement, digital signature invalid.");
        }
    }
}

/**
 * Signature verification class with both a JWT-library based verification
 * and a non-library based implementation.
 */
class SignatureVerifier {
    private static BouncyCastleProvider BC = new BouncyCastleProvider();

    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA/PSS";

    private final PublicKey publicKey;

    public SignatureVerifier(PublicKeyProvider publicKeyProvider) {
        this.publicKey = publicKeyProvider.getPublicKey().orElse(null);
        Security.addProvider(BC);
    }

    /**
     * Example signature verification using the NimbusJOSEJWT library to verify the JWT Token.
     *
     * @param request RegisterUsage Request.
     * @param result  RegisterUsage Result.
     * @return true if the token matches.
     */
    public boolean verifyUsingNimbusJOSEJWT(final RegisterUsageRequest request, final RegisterUsageResult result) {
        if (!getPublicKey().isPresent()) {
            return false;
        }

        try {
            JWSVerifier verifier = new RSASSAVerifier((RSAPublicKey) getPublicKey().get());
            JWSObject jwsObject = JWSObject.parse(result.getSignature());
            return jwsObject.verify(verifier) && validatePayload(jwsObject.getPayload().toString(), request, result);
        } catch (Exception e) {
            // log error
            return false;
        }
    }

    /**
     * Example signature verification without any JWT library support.
     *
     * @param request RegisterUsage Request.
     * @param result  RegisterUsage Result.
     * @return true if the token matches.
     */
    public boolean verify(final RegisterUsageRequest request, final RegisterUsageResult result) {
        if (!getPublicKey().isPresent()) {
            return false;
        }
        try {
            String[] jwtParts = result.getSignature().split("\\.");
            String header = jwtParts[0];
            String payload = jwtParts[1];
            String payloadSignature = jwtParts[2];

            Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM, BC);
            signature.initVerify(getPublicKey().get());
            signature.update(String.format("%s.%s", header, payload).getBytes(StandardCharsets.UTF_8));
            boolean verified = signature.verify(Base64.getUrlDecoder()
                    .decode(payloadSignature.getBytes(StandardCharsets.UTF_8)));

            String decodedPayload = new String(Base64.getUrlDecoder().decode(payload));
            return verified && validatePayload(decodedPayload, request, result);
        } catch (Exception e) {
            // log error
            return false;
        }
    }

    /**
     * Validate each value in the returned payload matches values originally
     * supplied in the request to RegisterUsage. TimeToLiveInMillis and
     * PublicKeyExpirationTimestamp will have the values in the payload compared
     * to values in the signature
     */
    private boolean validatePayload(final String payload, final RegisterUsageRequest request,
                                    final RegisterUsageResult result) {
        try {
            JsonNode payloadJson = Jackson.getObjectMapper().readTree(payload);
            boolean matches = payloadJson.get("productCode")
                    .asText()
                    .equals(request.getProductCode());
            matches = matches && payloadJson.get("nonce")
                    .asText()
                    .equals(request.getNonce());
            return matches = matches && payloadJson.get("publicKeyVersion")
                    .asText()
                    .equals(String.valueOf(request.getPublicKeyVersion()));

        } catch (Exception ex) {
            // log error
            return false;
        }
    }

    private Optional<PublicKey> getPublicKey() {
        return Optional.ofNullable(this.publicKey);
    }
}

/**
 * Public key provider taking advantage of the &AWS; PEM Utility.
 */
class PublicKeyProvider {
    // Replace with your public key. Ensure there are new-lines ("\n") in the
    // string after "-----BEGIN PUBLIC KEY-----\n" and before "\n-----END PUBLIC KEY-----".
    private static final String PUBLIC_KEY =
            "-----BEGIN PUBLIC KEY-----\n"
                    + "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDdlatRjRjogo3WojgGHFHYLugd\n"
                    + "UWAY9iR3fy4arWNA1KoS8kVw33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQs\n"
                    + "HUfQrSDv+MuSUMAe8jzKE4qW+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5D\n"
                    + "o2kQ+X5xK9cipRgEKwIDAQAB\n"
                    + "-----END PUBLIC KEY-----";

    public static final int PUBLIC_KEY_VERSION = 1;

    public Optional<PublicKey> getPublicKey() {
        try {
            return Optional.of(PEM.readPublicKey(new ByteArrayInputStream(
                    PUBLIC_KEY.getBytes(StandardCharsets.UTF_8))));
        } catch (Exception e) {
            // log error
            return Optional.empty();
        }
    }
}
```