

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

# Konfiguration der stündlichen Messung mit dem AWS Marketplace Metering Service
<a name="container-metering-registerusage"></a>

**Anmerkung**  
 Für Amazon EKS-Bereitstellungen muss Ihre Software [IAM-Rollen für Dienstkonten (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) verwenden, um den API-Aufruf für den [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)API-Vorgang zu signieren. Bei Verwendung von [EKS Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html) werden die Knotenrolle oder langfristige Zugriffsschlüssel nicht unterstützt.  
Für Amazon ECS-Bereitstellungen muss Ihre Software die [Amazon ECS-Aufgaben-IAM-Rolle](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html) verwenden, um den API-Aufruf für den [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)API-Vorgang zu signieren. Die Verwendung der Knotenrolle oder langfristige Zugriffsschlüssel werden nicht unterstützt.

Wenn Ihr Container-Produkt eine Preisgestaltung pro Stunde pro Aufgabe oder pro Pod anstelle von kundenspezifischen Preisdimensionen verwendet, müssen Sie keine benutzerdefinierten Bemessungsdimensionen definieren. Sie können den AWS Marketplace Metering Service für die stündliche Messung verwenden, in der Containerprodukte enthalten sind AWS Marketplace. In den folgenden Abschnitten erfahren Sie, wie Sie die stündliche Messung mit dem AWS Marketplace Metering Service konfigurieren.

Der `RegisterUsage` API-Betrieb misst die Softwarenutzung pro Amazon Elastic Container Service (Amazon ECS) -Aufgabe oder pro Amazon Elastic Kubernetes Service (Amazon EKS) -Pod pro Stunde, wobei die Nutzung auf die Sekunde aufgeteilt wird. Auf nur kurz ausgeführte Aufgaben oder Pods wird ein Minimum von 1 Minute angewendet. Die kontinuierliche Messung der Softwarenutzung erfolgt automatisch durch die. AWS Marketplace Metering Control Plane Ihre Software muss keine spezifischen Aktionen zur Erfassung der Softwarenutzung ausführen, es sei denn, Sie rufen `RegisterUsage` einmal auf, damit die Messung der Softwarenutzung beginnt.

`RegisterUsage`muss sofort beim Starten eines Containers aufgerufen werden. Wenn Sie den Container nicht in den ersten 6 Stunden nach dem Start des Containers registrieren, bietet der AWS Marketplace Metering Service keine Messgarantien für frühere Monate. Die Messung wird jedoch im laufenden Monat fortgesetzt, bis der Container endet.

The AWS Marketplace Metering Control Plane stellt Kunden weiterhin die Ausführung von Amazon ECS-Aufgaben und Amazon EKS-Pods in Rechnung, unabhängig vom Abonnementstatus des Kunden. Dadurch muss Ihre Software nach dem ersten erfolgreichen Start der Aufgabe oder des Pods keine Berechtigungsprüfungen mehr durchführen. 

Weitere Informationen zur Integration der AWS Marketplace Metering Service API mit Container-Produkten mit stündlicher Preisgestaltung finden Sie im Labor „[Integration mit stündlicher Messung](https://catalog.workshops.aws/mpseller/en-US/container/integrate-hourly)“ des *AWS Marketplace Verkäuferworkshops*. 

**Topics**
+ [Voraussetzungen für die Stundenmessung](#hourly-metering-prereqs)
+ [Testen Sie die Integration für `RegisterUsage`](#testing-integration-for-registerusage)
+ [Fehlerbehandlung für `RegisterUsage`](#hourly-metering-entitlement-error-handling)
+ [Integrieren Sie Ihr Container-Produkt mit dem AWS Marketplace Metering Service mithilfe der AWS SDK für Java](java-integration-example-registerusage.md)

## Voraussetzungen für die Stundenmessung
<a name="hourly-metering-prereqs"></a>

Bevor Sie das Produkt veröffentlichen, müssen Sie Folgendes tun:

1. Erstellen Sie in der AWS Marketplace Management Portal ein neues Containerprodukt und notieren Sie sich den zugehörigen Produktcode.

   Weitere Informationen finden Sie unter [Überblick: Erstellen Sie ein Container-Produkt](container-product-getting-started.md#create-container-product).

1. Verwenden Sie eine AWS Identity and Access Management (IAM-) Rolle für die Aufgabe oder den Pod, auf dem Ihre Anwendung ausgeführt wird, mit den für den Aufruf erforderlichen IAM-Berechtigungen. `RegisterUsage` Die von IAM verwaltete Richtlinie `AWSMarketplaceMeteringRegisterUsage` verfügt über diese Berechtigungen. Weitere Informationen zu der Richtlinie finden Sie [ AWSMarketplaceMeteringFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSMarketplaceMeteringFullAccess.html)in der *Referenz zu AWS verwalteten Richtlinien.*

1. (Optional) Wenn Sie die Protokollierung sehen möchten, empfehlen wir, die AWS CloudTrail Protokollierung in der Aufgaben- oder Pod-Definition zu aktivieren.

1. Führen Sie einen Testaufruf für den `RegisterUsage` API-Vorgang mit einem Datensatz für alle von Ihnen definierten Preisdimensionen durch.

## Testen Sie die Integration für `RegisterUsage`
<a name="testing-integration-for-registerusage"></a>

Verwenden Sie den `RegisterUsage` API-Vorgang, um Ihre Integration zu testen, bevor Sie Ihr Bild AWS Marketplace zur Veröffentlichung einreichen.

Rufen Sie `RegisterUsage` vom Container-Image aus auf, indem Sie Ihr Produkt auf Amazon ECS oder Amazon EKS ausführen. Verwenden Sie das AWS Konto, mit dem Sie das Produkt anbieten AWS Marketplace. Ihre Messintegration muss das dynamisch einstellen AWS-Region, anstatt es fest zu codieren. Starten Sie beim Testen jedoch mindestens eine Amazon ECS-Task oder einen Amazon EKS-Pod mit Ihrem bezahlten Container in der Region USA Ost (Nord-Virginia). Auf diese Weise kann das AWS Marketplace Betriebsteam Ihre Arbeit anhand der Protokolle in dieser Region überprüfen.

**Anmerkung**  
Wenn Ihr Produkt sowohl Amazon ECS als auch Amazon EKS unterstützt, müssen Sie es nur in Amazon EKS starten, damit wir Ihre Integration validieren können.

Sie können die Integration erst dann vollständig testen, wenn es mit allen erforderlichen Metadaten und Preisinformationen veröffentlicht wurde. Auf Anfrage kann das Team für den Betrieb des AWS Marketplace Katalogs den Eingang Ihrer Messdaten überprüfen.

## Fehlerbehandlung für `RegisterUsage`
<a name="hourly-metering-entitlement-error-handling"></a>

Wenn Ihr Container-Image in das integriert ist AWS Marketplace Metering Service und eine Ausnahme auftritt`ThrottlingException`, sollten Sie den Container beenden, um eine unbefugte Verwendung zu verhindern.

Andere Ausnahmen als `ThrottlingException` werden nur beim ersten Aufruf des `RegisterUsage` API-Vorgangs ausgelöst. Nachfolgende Aufrufe von derselben Amazon ECS-Task oder demselben Amazon EKS-Pod werden nicht ausgelöst, `CustomerNotSubscribedException` selbst wenn der Kunde sich abmeldet, während die Aufgabe oder der Pod noch ausgeführt wird. Diesen Kunden wird nach dem Abbestellen weiterhin der Betrieb von Containern in Rechnung gestellt, und ihre Nutzung wird nachverfolgt.

In der folgenden Tabelle werden die Fehler beschrieben, die durch den `RegisterUsage` API-Vorgang ausgelöst werden können. Für jede AWS SDK-Programmiersprache gibt es eine Reihe von Richtlinien zur Fehlerbehandlung, in denen Sie weitere Informationen finden können. 


|  **Fehler**  |  **Beschreibung**  | 
| --- | --- | 
|  InternalServiceErrorException  |  RegisterUsage ist nicht verfügbar.  | 
|  CustomerNotEntitledException  |  Der Kunde verfügt über kein gültiges Abonnement für das Produkt.  | 
|  InvalidProductCodeException  |  Der als Teil der Anforderung übergebene ProductCode-Wert ist nicht vorhanden.  | 
|  InvalidPublicKeyException  |  Der als Teil der Anforderung übergebene PublicKeyVersion-Wert ist nicht vorhanden.  | 
|  PlatformNotSupportedException  |  AWS Marketplace unterstützt nicht die Messung der Nutzung von der zugrunde liegenden Plattform aus. Nur Amazon ECS, Amazon EKS und E AWS Fargate werden unterstützt.  | 
|  ThrottlingException  |  Die Aufrufe von RegisterUsage werden gedrosselt.  | 
|  InvalidRegionException  |  RegisterUsagemuss in derselben Weise aufgerufen werden, in der AWS-Region die Amazon ECS-Task oder der Amazon EKS-Pod gestartet wurde. Damit wird verhindert, dass ein Container eine Region (beispielsweise withRegion(“us-east-1”)) auswählt, wenn RegisterUsage aufrufen wird.  | 

# Integrieren Sie Ihr Container-Produkt mit dem AWS Marketplace Metering Service mithilfe der AWS SDK für Java
<a name="java-integration-example-registerusage"></a>

Sie können den verwenden AWS SDK für Java , um ihn in den AWS Marketplace Metering Service zu integrieren. Die kontinuierliche Messung für die Softwarenutzung erfolgt automatisch durch den AWS Marketplace Metering Control Plane. Ihre Software muss keine spezifischen Aktionen zur Erfassung der Softwarenutzung ausführen, es sei denn, Sie rufen `RegisterUsage` einmal auf, damit die Messung der Softwarenutzung beginnt. Dieses Thema enthält eine Beispielimplementierung, bei der das AWS SDK für Java zur Integration in die `RegisterUsage` Aktion des [AWS Marketplace Messdienstes](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html) verwendet wird. 

`RegisterUsage`muss sofort beim Starten eines Containers aufgerufen werden. Wenn Sie den Container nicht in den ersten 6 Stunden nach dem Start des Containers registrieren, bietet der AWS Marketplace Metering Service keine Messgarantien für frühere Monate. Die Messung wird jedoch im laufenden Monat fortgesetzt, bis der Container endet.

Den vollständigen Quellcode finden Sie unter [RegisterUsage Java-Beispiel](#registerusage-java-example). Viele dieser Schritte gelten unabhängig von der AWS SDK-Sprache. 



**Beispielschritte für die Integration von AWS Marketplace Metering Service**

1. Melden Sie sich beim [AWS Marketplace Management Portal](https://aws.amazon.com/marketplace/management/tour) an.

1. Wählen Sie unter **Assets (Objekte)** die Option **Container**, um mit der Erstellung eines neuen Container-Produkts zu beginnen. Das Erstellen des Produkts generiert den Produkt-Code für das Produkt, das mit Ihrem Container-Abbild integriert werden soll. Informationen zum Einrichten von IAM-Berechtigungen finden Sie unter[AWS Marketplace Mess- und Berechtigungs-API-Berechtigungen](iam-user-policy-for-aws-marketplace-actions.md).

1.  Laden Sie das öffentliche [AWS Java-SDK](https://aws.amazon.com/sdk-for-java/) herunter. 
**Wichtig**  
 Um das Metering APIs von Amazon EKS aus aufzurufen, müssen Sie [ein unterstütztes AWS SDK verwenden](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html) und es auf einem Amazon EKS-Cluster mit Kubernetes 1.13 oder höher ausführen. 

1.  (Optional) Wenn Sie die `RegisterUsage` Aktion integrieren und eine Überprüfung der digitalen Signatur durchführen möchten, müssen Sie die Bibliothek für die [BouncyCastle](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on)Signaturverifizierung in Ihrem Anwendungs-Classpath konfigurieren.

   Wenn Sie ein JSON Web Token (JWT) verwenden möchten, muss Ihr Anwendungs-Klassenpfad auch [JWT Java](https://jwt.io/)-Bibliotheken enthalten. Die Verwendung von JWT bietet einen einfacheren Ansatz zur Signaturüberprüfung, ist jedoch nicht erforderlich. Sie können stattdessen eine eigenständige Version verwenden. BouncyCastle Unabhängig davon, ob Sie JWT oder verwenden BouncyCastle, müssen Sie ein Build-System wie Maven verwenden, um transitive Abhängigkeiten von BouncyCastle oder JWT in den Klassenpfad Ihrer Anwendung aufzunehmen.

   ```
   // 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.  Rufen Sie `RegisterUsage` von jedem kostenpflichtigen Container-Abbild in Ihrem Produktangebot auf. `ProductCode` und `PublicKeyVersion` sind erforderliche Parameter, alle anderen Eingaben sind optional. Es folgt ein Beispiel einer Nutzlast für `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
   }
   ```
**Anmerkung**  
Bei der Verbindung mit dem AWS Marketplace Metering Service können vorübergehende Probleme auftreten. AWS Marketplace empfiehlt dringend, Wiederholungsversuche für bis zu 30 Minuten mit exponentiellem Back-up durchzuführen, um kurzfristige Ausfälle oder Netzwerkprobleme zu vermeiden.

1.  `RegisterUsage` generiert eine digitale RSA-PSS-Signatur mit SHA-256, mit der Sie die Authentizität der Anforderung überprüfen können. Die Signatur enthält die folgenden Felder: `ProductCode`, `PublicKeyVersion` und `Nonce`. Um die digitale Signatur zu überprüfen, müssen Sie diese Felder aus der Anforderung beibehalten. Der folgende Code ist ein Beispiel für eine Antwort auf einen `RegisterUsage`-Aufruf. 

   ```
   {
   "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. Erstellen Sie eine neue Version Ihres Container-Images, die den `RegisterUsage` Call enthält, taggen Sie den Container und übertragen Sie ihn in eine beliebige Container-Registry, die mit Amazon ECS oder Amazon EKS kompatibel ist, wie Amazon ECR oder Amazon ECR Public. Wenn Sie Amazon ECR verwenden, stellen Sie sicher, dass das Konto, das die Amazon ECS-Aufgabe oder den Amazon EKS-Pod startet, über Berechtigungen für das Amazon ECR-Repository verfügt. Andernfalls schlägt der Start fehl.

1.  Erstellen Sie eine [IAM](https://aws.amazon.com/iam/)-Rolle, die Ihrem Container die Berechtigung zum Aufrufen von `RegisterUsage` erteilt, wie im folgenden Code definiert. Sie müssen diese IAM-Rolle im Parameter [Task Role](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_role_arn) der Amazon ECS-Aufgabe oder der Amazon EKS-Pod-Definition angeben.

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

****  

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

------

1. Erstellen Sie eine Amazon ECS-Aufgabe oder eine Amazon EKS-Pod-Definition, die auf den Container verweist, der in Schritt 7 integriert wurde, AWS Marketplace und auf die IAM-Rolle verweist, die Sie in Schritt 7 erstellt haben. Sie sollten die AWS CloudTrail Protokollierung in der Aufgabendefinition aktivieren, wenn Sie die Protokollierung sehen möchten. 

1. Erstellen Sie einen Amazon ECS- oder Amazon EKS-Cluster, um Ihre Aufgabe oder Ihren Pod auszuführen. Weitere Informationen zum Erstellen eines Amazon ECS-Clusters finden Sie unter [Creating a Cluster](https://docs.aws.amazon.com/AmazonECS/latest/userguide/create_cluster.html) im *Amazon Elastic Container Service Developer Guide*. Weitere Informationen zum Erstellen eines Amazon EKS-Clusters (mit Kubernetes Version 1.1.3.x oder höher) finden Sie unter [Erstellen eines](https://docs.aws.amazon.com/eks/latest/userguide/create_cluster.html) Amazon EKS-Clusters.

1. Konfigurieren Sie den Amazon ECS- oder Amazon EKS-Cluster und starten Sie die Amazon ECS-Aufgabendefinition oder den Amazon EKS-Pod, den Sie erstellt haben, im US-East-1 AWS-Region. Sie müssen diese Region nur während dieses Testprozesses, bevor das Produkt live geht, verwenden.

1. Wenn Sie eine gültige Antwort von `RegisterUsage` erhalten, können Sie mit der Erstellung Ihres Containerprodukts beginnen. Bei Fragen wenden Sie sich bitte an das [AWS Marketplace Seller Operations](https://aws.amazon.com/marketplace/management/contact-us/)-Team. 

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

Im folgenden Beispiel wird der AWS SDK für Java und AWS Marketplace Metering Service verwendet, um den `RegisterUsage` Vorgang aufzurufen. Die Signaturverifizierung ist optional. Wenn Sie die Signaturverifizierung aber durchführen möchten, müssen Sie die erforderlichen Bibliotheken für die Verifizierung von digitalen Signaturen einschließen. Dieses Beispiel dient lediglich der Veranschaulichung. 

```
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();
        }
    }
}
```