

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

# Integrazioni di fatturazione, misurazione e licenza dei prodotti container
<a name="container-products-billing-integration"></a>

Marketplace AWS si integra con altri prodotti Servizi AWS per fornire prezzi basati sulla misurazione e su contratto per il prodotto in container. Per i prodotti basati su container con prezzi di utilizzo, puoi utilizzare il sia per verificare l'autorizzazione all'uso del prodotto sia [AWS Marketplace Metering Service](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html)per misurare l'utilizzo per la fatturazione. Per i prodotti basati su container con prezzi contrattuali, puoi utilizzarli per associare le licenze al tuo prodotto. AWS License Manager Le sezioni seguenti forniscono ulteriori informazioni sulla misurazione oraria e personalizzata e sui prezzi contrattuali con AWS Marketplace Metering Service . AWS License Manager

**Topics**
+ [Misurazione oraria e personalizzata con AWS Marketplace Metering Service](#entitlement-and-metering-for-paid-products)
+ [Prezzi contrattuali con AWS License Manager](#container-products-contracts-license-manager)
+ [Configurazione della misurazione oraria con AWS Marketplace Metering Service](container-metering-registerusage.md)
+ [Configurazione di contatori personalizzati per prodotti container con AWS Marketplace Metering Service](container-metering-meterusage.md)
+ [Prezzi contrattuali per prodotti in container con AWS License Manager](container-license-manager-integration.md)

## Misurazione oraria e personalizzata con AWS Marketplace Metering Service
<a name="entitlement-and-metering-for-paid-products"></a>

[Per verificare il diritto all'uso del prodotto e per misurare l'utilizzo per la fatturazione, utilizza il servizio di misurazione.Marketplace AWS](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html) Se desideri definire le tue unità di prezzo e contabilizzarci l'utilizzo per la fatturazione, esegui l'integrazione utilizzando l'operazione API. [MeterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html) Se desideri stabilire il prezzo del tuo prodotto in base al numero di attività o di pod utilizzati e calcolare automaticamente AWS tale utilizzo, esegui l'integrazione utilizzando l'operazione [RegisterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_RegisterUsage.html)API. Per entrambi i tipi di prezzi, puoi aggiungere un prezzo contrattuale a lungo termine senza modificare la AWS Marketplace Metering Service modalità di integrazione con.

Quando crei un nuovo prodotto contenitore in Portale di gestione Marketplace AWS, forniamo una serie di identificatori del prodotto (il codice del prodotto e la chiave pubblica) che vengono utilizzati per integrare il prodotto con. AWS Marketplace Metering Service

### Entitlement
<a name="seller-container-entitlement"></a>

L'integrazione con ti AWS Marketplace Metering Service consente di verificare che il cliente che utilizza il tuo software a pagamento sia abbonato al tuo prodotto Marketplace AWS, proteggendoti dall'uso non autorizzato all'avvio del contenitore. Per verificare l'autorizzazione, utilizza le operazioni [MeterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html)o le [RegisterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_RegisterUsage.html)API, a seconda del modello di prezzo in uso. Per i modelli di prezzi mensili orari e fissi, utilizza il funzionamento dell'`RegisterUsage`API. Per i modelli di misurazione dei prezzi personalizzati, utilizza l'operazione `MeterUsage` API.

Se un acquirente non ha diritto al tuo prodotto, queste operazioni API restituiscono l'`CustomerNotEntitledException`eccezione.

**Nota**  
Se un acquirente annulla l'iscrizione al tuo prodotto mentre lo utilizza, ha il diritto di continuare a utilizzarlo. Tuttavia, non possono avviare contenitori aggiuntivi per il tuo prodotto.

### Linee guida di integrazione
<a name="integration-guidelines"></a>

Quando crei e pubblichi i tuoi prodotti container e utilizzi le `MeterUsage` nostre operazioni `RegisterUsage` API per l'autorizzazione e la misurazione, tieni a mente le seguenti linee guida:
+ Non configurare AWS le credenziali all'interno del software o nell'immagine del contenitore Docker. AWS le credenziali per l'acquirente vengono ottenute automaticamente in fase di esecuzione quando l'immagine del contenitore è in esecuzione all'interno di un'attività Amazon ECS o di un pod Amazon EKS.
+  Per chiamare le operazioni `MeterUsage` o `RegisterUsage` API da Amazon EKS, devi [utilizzare un AWS SDK supportato](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html). Per testare `MeterUsage` o `RegisterUsage` integrare Amazon EKS, devi eseguire un cluster Amazon EKS con Kubernetes 1.13.x o versione successiva. Kubernetes 1.13 è richiesto per i ruoli (IAM) per il supporto dei pod. AWS Identity and Access Management I ruoli IAM sono necessari affinché il pod in esecuzione ottenga le AWS credenziali necessarie per richiamare queste azioni su Amazon EKS. 
+ Puoi occuparti dello sviluppo locale, ma otterrai un'`PlatformNotSupportedException`eccezione. Questa eccezione non si verifica quando avvii il contenitore su servizi AWS container (Amazon ECS, Amazon EKS e Fargate).

### Supportato Regioni AWS
<a name="supported-regions-metering"></a>

Per un elenco di tutte le aree Marketplace AWS supportate Regioni AWS, consulta la [Tabella delle regioni](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/) sul sito Web di Global Infrastructure.

#### Ottenere la misura Regione AWS per la misurazione
<a name="metering-aws-region-configuration"></a>

Quando integri il contenitore per la misurazione con il funzionamento `MeterUsage` o l'`RegisterUsage`API, non configurate l' AWS SDK per utilizzarne uno specifico. Regione AWS La regione deve essere ottenuta dinamicamente in fase di esecuzione. 

**Example**  
Ad esempio, un cliente avvia un'attività Amazon ECS o un pod Amazon EKS. L'operazione `RegisterUsage` API viene chiamata in una regione diversa dalla regione in cui è stato lanciato il task Amazon ECS o il pod Amazon EKS. Pertanto, l'operazione `RegisterUsage` API genera un errore. `InvalidRegionException`



AWS I linguaggi SDK non li determinano `AWS_REGION` in modo coerente. Se il tuo SDK non rileva automaticamente il file`AWS_REGION`, il software deve essere scritto manualmente per determinare il. `AWS_Region` Ad esempio, utilizza AWS SDK per Java automaticamente i [metadati delle istanze Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) (in particolare`ec2InstanceMetadata`) per ottenere la regione quando non sono presenti variabili di ambiente o altre configurazioni. In questo caso, chiama solo `ec2InstanceMetadata` se la variabile di `AWS_REGION` ambiente non è presente.

Per informazioni su come ottenere dinamicamente un file Regione AWS in fase di esecuzione, consultate la [AWS SDK Developer Guide](https://aws.amazon.com/tools) per il linguaggio di programmazione in uso.

### Impedire la modifica dei contatori
<a name="prevent-metering-modification"></a>

L'introduzione di modi per consentire agli acquirenti di modificare o annullare le chiamate `RegisterUsage` o `MeterUsage` potrebbe comportare problemi indesiderati di fatturazione e pagamento. Ti consigliamo vivamente di integrare la logica di misurazione e di autorizzazione.

Quando progettate il vostro prodotto per evitare modifiche alla misurazione, tenete presente quanto segue:
+ Se gli acquirenti possono inserire nuovi livelli di immagine che contengono `CMD` o `ENTRYPOINT` istruzioni, `RegisterUsage` integrali direttamente `MeterUsage` nel software che l'acquirente sta eseguendo tramite l'immagine del contenitore. In caso contrario, le chiamate verso `RegisterUsage` `CMD` o `MeterUsage` eseguite tramite o `ENTRYPOINT` dall'immagine di base verranno probabilmente sostituite dall'acquirente.
+ Ti consigliamo di gestire i codici di Marketplace AWS prodotto utilizzati dal software come input `RegisterUsage` o `MeterUsage` in modo che gli acquirenti non possano modificarli. *Tuttavia, se il tuo prodotto gestisce i codici di prodotto in un modo che i clienti possono ignorare AWS CloudFormation, ad esempio Helm chart o Kubernetes manifest, devi mantenere un elenco di codici di prodotto affidabili.* Marketplace AWS Questo serve a garantire che il codice prodotto a cui il software trasmette come input o sia valido. `RegisterUsage` `MeterUsage`
+  Se uno dei tuoi codici prodotto affidabili riguarda prodotti gratuiti, assicurati che non possa essere utilizzato al posto di un codice prodotto a pagamento.

## Prezzi contrattuali con AWS License Manager
<a name="container-products-contracts-license-manager"></a>

Per i prodotti basati su container con prezzi contrattuali, è possibile associare le licenze AWS License Manager al prodotto. 

AWS License Manager è uno strumento di gestione delle licenze che consente all'applicazione di tenere traccia e aggiornare le licenze (note anche come autorizzazioni) acquistate da un cliente. Questa sezione fornisce informazioni su come integrare il prodotto con. AWS License Manager Una volta completata l'integrazione, puoi pubblicare la tua scheda di prodotto su Marketplace AWS.

Per ulteriori informazioni in merito AWS License Manager, consulta la [Guida per AWS License Manager l'utente](https://docs.aws.amazon.com/license-manager/latest/userguide/license-manager.html) e la [AWS License Manager](https://docs.aws.amazon.com/cli/latest/reference/license-manager/index.html)sezione *AWS CLI Command Reference*.

**Nota**  
I clienti non possono lanciare nuove istanze del contenitore dopo il periodo di scadenza del contratto. Tuttavia, durante la durata del contratto, possono avviare un numero qualsiasi di istanze. Queste licenze non sono legate a un nodo o a un'istanza specifici. Qualsiasi software in esecuzione su qualsiasi contenitore su qualsiasi nodo può effettuare il checkout della licenza purché disponga delle credenziali AWS assegnate.
**Creazione di offerte private**: i venditori possono generare offerte private per i prodotti utilizzando lo strumento di creazione di offerte private disponibile in. Portale di gestione Marketplace AWS
**Reporting**: puoi configurare i feed di dati configurando un bucket Amazon S3 nella sezione Report **del**. Portale di gestione Marketplace AWS Per ulteriori informazioni, consulta [Report, feed di dati e dashboard per i venditori in Marketplace AWS](reports-and-data-feed.md).

### Workflow di integrazione
<a name="container-LM-LM-workflow"></a>

I passaggi seguenti mostrano il flusso di lavoro per l'integrazione del prodotto contenitore con AWS License Manager:

1. Il venditore crea un prodotto con AWS License Manager integrazione.

1. Il venditore mette in vendita il prodotto su Marketplace AWS.

1. L'acquirente trova il prodotto Marketplace AWS e lo acquista.

1. Una licenza viene inviata all'acquirente nel suo Account AWS.

1. L'acquirente utilizza il software avviando l'istanza Amazon EC2, il task Amazon ECS o il software pod Amazon EKS. Il cliente esegue la distribuzione utilizzando un ruolo IAM.

1. Il software legge la licenza nell' AWS License Manager account dell'acquirente, scopre i diritti acquistati e fornisce le funzionalità di conseguenza. 
**Nota**  
License Manager non effettua alcun tracciamento o aggiornamento; questo viene fatto dall'applicazione del venditore.

# Configurazione della misurazione oraria con AWS Marketplace Metering Service
<a name="container-metering-registerusage"></a>

**Nota**  
 Per le implementazioni di Amazon EKS, il tuo software deve utilizzare [IAM roles for service accounts (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) per firmare la chiamata API per il funzionamento dell'[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. L'utilizzo di [EKS Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html), il ruolo del nodo o le chiavi di accesso a lungo termine non sono supportati.  
Per le distribuzioni di Amazon ECS, il tuo software deve utilizzare il ruolo [IAM dell'attività di Amazon ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html) per firmare la chiamata API per l'operazione 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) L'utilizzo del ruolo del nodo o delle chiavi di accesso a lungo termine non è supportato.

Se il prodotto in container utilizza prezzi orari per attività o per pod anziché dimensioni di prezzo personalizzate basate su misuratori, non è necessario definire dimensioni di misurazione personalizzate. Puoi utilizzare AWS Marketplace Metering Service per la misurazione oraria con prodotti container all'interno. Marketplace AWS Le seguenti sezioni mostrano come configurare la misurazione oraria con AWS Marketplace Metering Service.

Il funzionamento dell'`RegisterUsage`API misura l'utilizzo del software per attività Amazon Elastic Container Service (Amazon ECS) o per pod Amazon Elastic Kubernetes Service (Amazon EKS), all'ora, con un utilizzo proporzionale al secondo. Un minimo di 1 minuto di utilizzo si applica alle attività o ai pod di breve durata. La misurazione continua dell'uso del software viene gestita automaticamente da. Marketplace AWS Metering Control Plane Il software non è tenuto a eseguire alcuna azione specifica di misurazione, ad eccezione di `RegisterUsage` una chiamata una sola volta per iniziare la misurazione dell'utilizzo del software.

`RegisterUsage`deve essere chiamato immediatamente al momento del lancio di un container. Se non registri il container nelle prime 6 ore dal lancio del container, AWS Marketplace Metering Service non fornisce alcuna garanzia di misurazione per i mesi precedenti. Tuttavia, la misurazione continuerà per il mese in corso fino alla scadenza del container.

 Marketplace AWS Metering Control PlaneContinua a fatturare ai clienti l'esecuzione delle attività di Amazon ECS e dei pod Amazon EKS, indipendentemente dallo stato dell'abbonamento del cliente. In questo modo non è più necessario che il software esegua controlli di autorizzazione dopo l'avvio iniziale con successo dell'operazione o del pod. 

*Per ulteriori informazioni sull'integrazione dell' AWS Marketplace Metering Service API con i prodotti container con prezzi orari, consulta il laboratorio [Integrazione con misurazione oraria](https://catalog.workshops.aws/mpseller/en-US/container/integrate-hourly) del workshop dedicato ai venditori.Marketplace AWS * 

**Topics**
+ [Prerequisiti per la misurazione oraria](#hourly-metering-prereqs)
+ [Test dell'integrazione per `RegisterUsage`](#testing-integration-for-registerusage)
+ [Gestione degli errori per `RegisterUsage`](#hourly-metering-entitlement-error-handling)
+ [Integrazione del prodotto container con AWS Marketplace Metering Service utilizzando AWS SDK per Java](java-integration-example-registerusage.md)

## Prerequisiti per la misurazione oraria
<a name="hourly-metering-prereqs"></a>

Prima di pubblicare il prodotto, devi fare quanto segue:

1. Crea un nuovo prodotto contenitore in e prendi nota del relativo codice prodotto. Portale di gestione Marketplace AWS

   Per ulteriori informazioni, consulta [Panoramica: crea un prodotto contenitore](container-product-getting-started.md#create-container-product).

1. Utilizza un ruolo AWS Identity and Access Management (IAM) per l'attività o il pod che esegue l'applicazione con le autorizzazioni IAM necessarie per la chiamata`RegisterUsage`. La policy gestita da IAM `AWSMarketplaceMeteringRegisterUsage` dispone di queste autorizzazioni. Per ulteriori informazioni sulla policy, consulta [ AWSMarketplaceMeteringFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSMarketplaceMeteringFullAccess.html)il *AWS Managed Policy Reference.*

1. (Facoltativo) Se desideri visualizzare la registrazione, ti consigliamo di abilitare la AWS CloudTrail registrazione nella definizione dell'attività o del pod.

1. Effettua una chiamata di prova all'operazione `RegisterUsage` API con un record per tutte le dimensioni di prezzo che definisci.

## Test dell'integrazione per `RegisterUsage`
<a name="testing-integration-for-registerusage"></a>

Utilizza l'operazione `RegisterUsage` API per testare l'integrazione prima di inviare l'immagine Marketplace AWS per la pubblicazione.

Chiama `RegisterUsage` dall'immagine del contenitore eseguendo il prodotto su Amazon ECS o Amazon EKS. Usa l' AWS account che stai utilizzando per pubblicare l'offerta del prodotto. Marketplace AWS La tua integrazione di misurazione deve impostare dinamicamente il file Regione AWS, anziché codificarlo. Tuttavia, durante il test, avvia almeno un'attività Amazon ECS o un pod Amazon EKS contenente il container a pagamento nella regione Stati Uniti orientali (Virginia settentrionale). In questo modo, il team Marketplace AWS operativo può verificare il tuo lavoro con i log di quella regione.

**Nota**  
Se il tuo prodotto supporta sia Amazon ECS che Amazon EKS, devi solo avviarlo in Amazon EKS per consentirci di convalidare la tua integrazione.

Non puoi testare completamente l'integrazione finché il prodotto non viene pubblicato con tutti i metadati e le informazioni sui prezzi richiesti. Se richiesto, il team operativo del Marketplace AWS catalogo può verificare la ricezione dei dati di misurazione.

## Gestione degli errori per `RegisterUsage`
<a name="hourly-metering-entitlement-error-handling"></a>

Se l'immagine del contenitore si integra con AWS Marketplace Metering Service e riceve un'eccezione diversa `ThrottlingException` dall'avvio del contenitore, è necessario terminare il contenitore per impedirne l'uso non autorizzato.

Le eccezioni diverse da `ThrottlingException` vengono generate solo durante la chiamata iniziale all'operazione API. `RegisterUsage` Le chiamate successive dalla stessa attività Amazon ECS o dallo stesso pod Amazon EKS non vengono generate `CustomerNotSubscribedException` anche se il cliente annulla l'iscrizione mentre l'attività o il pod è ancora in esecuzione. A questi clienti viene comunque addebitato il costo per l'utilizzo dei container dopo l'annullamento dell'iscrizione e il loro utilizzo viene monitorato.

La tabella seguente descrive gli errori che l'operazione `RegisterUsage` API potrebbe generare. Ogni linguaggio di programmazione AWS SDK dispone di una serie di linee guida per la gestione degli errori a cui puoi fare riferimento per ulteriori informazioni. 


|  **Errore**  |  **Descrizione**  | 
| --- | --- | 
|  InternalServiceErrorException  |  RegisterUsagenon è disponibile.  | 
|  CustomerNotEntitledException  |  Il cliente non dispone di un abbonamento valido per il prodotto.  | 
|  InvalidProductCodeException  |  Il ProductCode valore passato come parte della richiesta non esiste.  | 
|  InvalidPublicKeyException  |  Il PublicKeyVersion valore passato come parte della richiesta non esiste.  | 
|  PlatformNotSupportedException  |  Marketplace AWS non supporta la misurazione dell'utilizzo dalla piattaforma sottostante. Sono supportati solo Amazon ECS, Amazon EKS e AWS Fargate .  | 
|  ThrottlingException  |  Le chiamate a RegisterUsage sono limitate.  | 
|  InvalidRegionException  |  RegisterUsagedeve essere chiamato nello stesso modo in Regione AWS cui è stato lanciato il task Amazon ECS o il pod Amazon EKS. Ciò impedisce a un contenitore di scegliere una regione (ad esempiowithRegion(“us-east-1”)) durante la chiamataRegisterUsage.  | 

# Integrazione del prodotto container con AWS Marketplace Metering Service utilizzando AWS SDK per Java
<a name="java-integration-example-registerusage"></a>

Puoi utilizzarlo AWS SDK per Java per l'integrazione con l'AWS Marketplace Metering Service. La misurazione continua dell'uso del software viene gestita automaticamente da. Marketplace AWS Metering Control Plane Il software non è tenuto a eseguire alcuna azione specifica di misurazione, ad eccezione di `RegisterUsage` una chiamata una sola volta per iniziare la misurazione dell'utilizzo del software. Questo argomento fornisce un esempio di implementazione che utilizza l'azione del servizio di [Marketplace AWS misurazione AWS SDK per Java](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html) per l'integrazione con l'azione. `RegisterUsage` 

`RegisterUsage`deve essere chiamato immediatamente al momento del lancio di un contenitore. Se non registri il container nelle prime 6 ore dal lancio del container, AWS Marketplace Metering Service non fornisce alcuna garanzia di misurazione per i mesi precedenti. Tuttavia, la misurazione continuerà per il mese in corso fino alla scadenza del container.

Per il codice sorgente completo, vedi[RegisterUsage Esempio di Java](#registerusage-java-example). Molti di questi passaggi si applicano indipendentemente dal linguaggio AWS SDK. 



**Esempi di passaggi per l'integrazione con AWS Marketplace Metering Service**

1. Accedi alla [Portale di gestione Marketplace AWS](https://aws.amazon.com/marketplace/management/tour).

1. Da **Assets** scegli **Containers** per iniziare a creare un nuovo prodotto container. La creazione del prodotto genera il codice prodotto per il prodotto da integrare con l'immagine del contenitore. Per informazioni sull'impostazione delle autorizzazioni IAM, consulta[Marketplace AWS autorizzazioni API di misurazione e autorizzazione](iam-user-policy-for-aws-marketplace-actions.md).

1.  Scarica l'[SDK AWS Java](https://aws.amazon.com/sdk-for-java/) pubblico. 
**Importante**  
 Per richiamare la misurazione APIs da Amazon EKS, devi [utilizzare un AWS SDK supportato ed eseguirlo su un](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html) cluster Amazon EKS che esegue Kubernetes 1.13 o versione successiva. 

1.  (Facoltativo) Se ti stai integrando con l'`RegisterUsage`azione e desideri eseguire la verifica della firma digitale, devi configurare la libreria di verifica delle firme nel classpath dell'applicazione [BouncyCastle](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on).

   Se desideri utilizzare JSON Web Token (JWT), devi includere anche le librerie [JWT Java](https://jwt.io/) nel classpath dell'applicazione. L'utilizzo di JWT offre un approccio più semplice alla verifica della firma, ma non è obbligatorio ed è possibile utilizzare invece la modalità standalone. BouncyCastle Sia che utilizzi JWT o BouncyCastle che sia necessario utilizzare un sistema di compilazione come Maven per includere dipendenze transitive di o JWT nel classpath dell'applicazione. 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.  Chiama `RegisterUsage` da ogni immagine di container a pagamento presente nella tua offerta di prodotti. `ProductCode`e `PublicKeyVersion` sono parametri obbligatori e tutti gli altri input sono opzionali. Di seguito è riportato un esempio di payload per. `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
   }
   ```
**Nota**  
È possibile riscontrare problemi transitori nella connessione all'AWS Marketplace Metering Service. Marketplace AWS consiglia vivamente di implementare nuovi tentativi per un massimo di 30 minuti, con interruzione esponenziale, per evitare interruzioni a breve termine o problemi di rete.

1.  `RegisterUsage`genera una firma digitale RSA-PSS utilizzando SHA-256 che è possibile utilizzare per verificare l'autenticità della richiesta. La firma include i seguenti campi:, e. `ProductCode` `PublicKeyVersion` `Nonce` Per verificare la firma digitale, è necessario conservare questi campi della richiesta. Il codice seguente è un esempio di risposta a una `RegisterUsage` chiamata. 

   ```
   {
   "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. Ricostruisci una nuova versione dell'immagine del contenitore che includa la `RegisterUsage` chiamata, tagga il contenitore e inviala a qualsiasi registro di container compatibile con Amazon ECS o Amazon EKS, come Amazon ECR o Amazon ECR Public. Se utilizzi Amazon ECR, assicurati che l'account che avvia l'attività Amazon ECS o il pod Amazon EKS disponga delle autorizzazioni per l'archivio Amazon ECR. In caso contrario, il lancio fallisce.

1.  Crea un ruolo [IAM](https://aws.amazon.com/iam/) che conceda l'autorizzazione alla chiamata del contenitore`RegisterUsage`, come definito nel codice seguente. È necessario fornire questo ruolo IAM nel parametro [Task Role](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_role_arn) della definizione del task Amazon ECS o del pod Amazon EKS.

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

****  

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

------

1. Crea un'attività Amazon ECS o una definizione del pod Amazon EKS che faccia riferimento al contenitore integrato Marketplace AWS e che faccia riferimento al ruolo IAM creato nella fase 7. È necessario abilitare AWS CloudTrail la registrazione nella definizione dell'attività se si desidera visualizzare la registrazione. 

1. Crea un cluster Amazon ECS o Amazon EKS per eseguire la tua attività o il tuo pod. Per ulteriori informazioni sulla creazione di un cluster Amazon ECS, consulta [Creating a Cluster](https://docs.aws.amazon.com/AmazonECS/latest/userguide/create_cluster.html) nella *Amazon Elastic Container Service Developer Guide*. [Per ulteriori informazioni sulla creazione di un cluster Amazon EKS (utilizzando Kubernetes versione 1.1.3.x o successiva), consulta Creazione di un cluster Amazon EKS.](https://docs.aws.amazon.com/eks/latest/userguide/create_cluster.html)

1. Configura il cluster Amazon ECS o Amazon EKS e avvia la definizione di attività Amazon ECS o il pod Amazon EKS che hai creato, in us-east-1. Regione AWSÈ solo durante questo processo di test, prima che il prodotto sia disponibile, che devi utilizzare questa regione.

1. Quando ricevi una risposta valida da`RegisterUsage`, puoi iniziare a creare il tuo prodotto contenitore. Per domande, contatta il team [Operativo Marketplace AWS del venditore](https://aws.amazon.com/marketplace/management/contact-us/). 

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

L'esempio seguente utilizza AWS SDK per Java and Marketplace AWS Metering Service per chiamare l'`RegisterUsage`operazione. La verifica della firma è facoltativa, ma se si desidera eseguire la verifica della firma, è necessario includere le librerie di verifica delle firme digitali richieste. Questo esempio è solo a scopo illustrativo. 

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

# Configurazione di contatori personalizzati per prodotti container con AWS Marketplace Metering Service
<a name="container-metering-meterusage"></a>

**Nota**  
 Per le implementazioni di Amazon EKS, il tuo software deve utilizzare [IAM roles for service accounts (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) per firmare la chiamata API per il funzionamento dell'[https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_MeterUsage.html](https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_MeterUsage.html)API. L'utilizzo di [EKS Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html), il ruolo del nodo o le chiavi di accesso a lungo termine non sono supportati.  
Per le distribuzioni di Amazon ECS, il tuo software deve utilizzare il ruolo [IAM dell'attività di Amazon ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html) per firmare la chiamata API per l'operazione API. [https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_MeterUsage.html](https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_MeterUsage.html) L'utilizzo del ruolo del nodo o delle chiavi di accesso a lungo termine non è supportato.  
Per le distribuzioni AgentCore di Amazon Bedrock Runtime, il tuo software deve utilizzare il [ruolo AgentCore di esecuzione Runtime](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-permissions.html#runtime-permissions-execution) per firmare la chiamata API per l'[https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_MeterUsage.html](https://docs.aws.amazon.com/marketplace/latest/APIReference/API_marketplace-metering_MeterUsage.html)operazione API. Le chiavi di accesso a lungo termine non sono supportate.

Marketplace AWS i prodotti container possono avere una misurazione personalizzata per un massimo di 24 diverse dimensioni di prezzo per prodotto. A ogni dimensione può essere associato un prezzo contrattuale a lungo termine. Per abilitare la misurazione personalizzata, integra il tuo prodotto container con AWS Marketplace Metering Service. Puoi definire le tue unità di prezzo e la misurazione personalizzata per tale utilizzo e per la fatturazione utilizzando AWS il funzionamento dell'API. [https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html) Le seguenti sezioni mostrano come configurare la misurazione personalizzata per il prodotto container.

Le dimensioni del prezzo sono definite in due posizioni, una volta durante la creazione del prodotto nel Portale di gestione Marketplace AWS (portale dei venditori) e una volta nel software per eseguire l'`MeterUsage`operazione. Questo metodo a due fattori garantisce che le offerte successive funzionino come previsto prima di essere rese disponibili al pubblico.

Per configurare la misurazione personalizzata, devi scegliere la categoria di utilizzo, il tipo di unità e le dimensioni del prezzo: 
+ **Categoria di utilizzo**: la categoria di utilizzo aiuta gli acquirenti a capire cos'è il tuo prodotto e come utilizzarlo. 
+ **Tipo di unità**: il tipo di unità definisce l'unità di misura per la fatturazione. Ad esempio, la larghezza di banda misurata in GBps o MBps, il numero di host o i dati misurati in MB, GB o TB.
+ **Dimensioni dei prezzi**: le dimensioni dei prezzi rappresentano una funzionalità o un servizio per cui hai impostato un prezzo unitario (ad esempio, utenti, scanCPUs, v o agenti distribuiti). Le dimensioni relative ai prezzi sono pubbliche. Tuttavia, puoi comunque definire offerte private e Bring Your Own License (BYOL) per prodotti pubblici. Non inserire i prezzi nei registri di misurazione. Tu misuri la quantità di unità e noi la utilizziamo insieme ai prezzi che hai definito durante la creazione del prodotto per calcolare la fattura dell'acquirente. 

  Se il prezzo del prodotto non corrisponde a nessuna delle categorie o dei tipi di unità predefiniti, puoi scegliere la categoria di **unità** generica. Quindi, utilizza la descrizione della dimensione per descrivere cos'è l'unità.

Facoltativamente, è possibile distribuire l'utilizzo in allocazioni in base alle proprietà monitorate. Le allocazioni vengono rappresentate come tag per l'acquirente. Questi tag consentono all'acquirente di visualizzare i costi suddivisi in base all'utilizzo in base ai valori dei tag. Ad esempio, se addebiti in base all'utente e gli utenti hanno la proprietà «Dipartimento», puoi creare allocazioni di utilizzo con tag con la chiave «Dipartimento» e un'allocazione per valore. Ciò non modifica il prezzo, le dimensioni o l'utilizzo totale riportato, ma consente al cliente di visualizzare i costi per categorie appropriate al prodotto.

Ti consigliamo di inviare un record di misurazione ogni ora. Tuttavia, puoi aggregare l'utilizzo anche su periodi giornalieri o mensili. In caso di interruzione, puoi aggregare l'utilizzo del software da parte degli acquirenti e inviarlo per la misurazione delle ore successive. Non puoi inviare più di un record all'ora.

*Per ulteriori informazioni sull'integrazione dell' AWS Marketplace Metering Service API per i prodotti container con prezzi di misurazione personalizzati, consulta il laboratorio [Integrazione con misurazione personalizzata](https://catalog.workshops.aws/mpseller/en-US/container/integrate-custom) del workshop per i Marketplace AWS venditori.*

**Importante**  
La prova gratuita e i diritti prepagati vengono monitorati su base oraria. Di conseguenza, l'invio separato di questi documenti potrebbe comportare un sovrapprezzo per l'acquirente.

**Topics**
+ [Prerequisiti per la misurazione personalizzata](#custom-metering-prereqs)
+ [Test `MeterUsage` dell'integrazione per ECS ed EKS](#testing-meterusage-integration)
+ [Test di MeterUsage integrazione per AgentCore](#testing-agentcore-metering)
+ [Gestione degli errori per `MeterUsage`](#custom-metering-entitlement-error-handling)
+ [(Facoltativo) Etichettatura in base al fornitore](#container-vendor-metered-tagging)
+ [Esempio di codice](#container-meter-code-example)
+ [Integrazione del prodotto container utilizzando la misurazione personalizzata con e AWS Marketplace Metering Service AWS SDK per Java](java-integration-example-meterusage.md)

## Prerequisiti per la misurazione personalizzata
<a name="custom-metering-prereqs"></a>

Prima di pubblicare il prodotto, devi fare quanto segue:

1. Crea un nuovo prodotto contenitore in e prendi nota del relativo codice prodotto. Portale di gestione Marketplace AWS

1. Utilizza un ruolo AWS Identity and Access Management (IAM) per l'endpoint task, pod o AgentCore Runtime che esegue l'applicazione con le autorizzazioni IAM necessarie per effettuare la chiamata. `MeterUsage` La policy gestita da IAM `AWSMarketplaceMeteringRegisterUsage` dispone di queste autorizzazioni. Per ulteriori informazioni sulla policy, consulta [ AWSMarketplaceMeteringFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSMarketplaceMeteringFullAccess.html)il *AWS Managed Policy Reference.*

1. (Facoltativo) Ti consigliamo di abilitare la AWS CloudTrail registrazione nella definizione dell'attività o del contenitore se desideri visualizzare la registrazione.

1. Effettua una chiamata di prova all'operazione `MeterUsage` API con un record per tutte le dimensioni di prezzo che definisci.

## Test `MeterUsage` dell'integrazione per ECS ed EKS
<a name="testing-meterusage-integration"></a>

Utilizza l'`MeterUsage`operazione per testare l'integrazione prima di inviare l'immagine Marketplace AWS per la pubblicazione.

`MeterUsage`Esegui la chiamata dalle immagini del contenitore eseguendo il prodotto su Amazon Elastic Container Service (Amazon ECS) o Amazon Elastic Kubernetes Service (Amazon EKS Account AWS ) con il codice su cui pubblichi il prodotto. Marketplace AWS La tua integrazione di misurazione deve impostare dinamicamente il file Regione AWS, anziché codificarlo. Tuttavia, durante il test, avvia almeno un'attività Amazon ECS o un pod Amazon EKS contenente il tuo container a pagamento nella regione degli Stati Uniti orientali (Virginia settentrionale) in modo che il team Marketplace AWS operativo possa verificare il tuo lavoro con i log di quella regione.

**Nota**  
Se il tuo prodotto supporta sia Amazon ECS che Amazon EKS, devi solo avviarlo in Amazon EKS per consentirci di convalidare la tua integrazione.
Testa ogni dimensione prima di lanciare il prodotto al pubblico e dopo aver aggiunto una nuova dimensione. Se non invii un record di misurazione per ogni dimensione associata a un prodotto contenitore, si verificherà un errore e la richiesta non andrà a buon fine.

Non puoi testare completamente l'integrazione finché il prodotto non sarà pubblicato con tutti i metadati e le informazioni sui prezzi richiesti. Se richiesto, il team operativo del Marketplace AWS catalogo può verificare la ricezione dei dati di misurazione.

## Test di MeterUsage integrazione per AgentCore
<a name="testing-agentcore-metering"></a>

Utilizza l'`MeterUsage`operazione per testare l'integrazione prima di inviare l'immagine Marketplace AWS per la pubblicazione.

Effettua una chiamata `MeterUsage` dalle immagini del contenitore eseguendo il prodotto su Amazon Bedrock AgentCore con l' AWS account su Marketplace AWS cui pubblichi il prodotto. La tua integrazione di misurazione deve impostare dinamicamente la AWS regione, anziché codificarla. Tuttavia, durante il test, avvia almeno un AgentCore agente Amazon Bedrock contenente il tuo container a pagamento nella regione Stati Uniti orientali (Virginia settentrionale) in modo che il team Marketplace AWS operativo possa verificare il tuo lavoro con i log di quella regione. 

 Non è necessario aggregare i record di utilizzo orario. `MeterUsage`Richiamate ogni chiamata di un agente con l'utilizzo di tale chiamata.

È necessario utilizzare l'ultima versione rilasciata dell' AWS SDK per la propria lingua. Questo compila automaticamente il `ClientToken` parametro con un valore generato automaticamente per favorire l'idempotenza. Le versioni precedenti dell'SDK che non compilano questo campo non funzioneranno per `MeterUsage` le chiamate dall'interno di Amazon Bedrock. AgentCore A causa di un problema di rete, devi riutilizzare esattamente la stessa richiesta quando riprovi. In questo modo si garantisce che le richieste vengano trattate in modo ideale.

A causa delle differenze nel comportamento di misurazione previsto tra Amazon Bedrock AgentCore e altri prodotti container, non è consigliabile condividere la stessa immagine del contenitore da utilizzare su Amazon Bedrock e AgentCore su Amazon ECS o EKS.

## Gestione degli errori per `MeterUsage`
<a name="custom-metering-entitlement-error-handling"></a>

Chiama l'`MeterUsage`impostazione del `DryRun` parametro su true all'avvio del contenitore per verificare che l'integrazione della misurazione funzioni. Se l'immagine del contenitore si integra con l'`MeterUsage`operazione e riceve un'eccezione diversa `ThrottlingException` dall'avvio del contenitore, è necessario chiudere il contenitore per impedirne l'uso non autorizzato.

Le eccezioni diverse da `ThrottlingException` vengono generate solo durante la chiamata iniziale a. `MeterUsage` Le chiamate successive dalla stessa attività Amazon ECS o dal pod Amazon EKS o dallo stesso endpoint AgentCore Runtime non vengono generate`CustomerNotSubscribedException`, anche se il cliente annulla l'iscrizione mentre l'attività o il pod è ancora in esecuzione. A questi clienti vengono comunque addebitati i costi per l'utilizzo dei container dopo l'annullamento dell'iscrizione e il loro utilizzo viene monitorato.

[MeterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html)Consulta l'*AWS Marketplace Metering Service API Reference* per le descrizioni dettagliate degli errori più comuni per. `MeterUsage` Ogni linguaggio di programmazione AWS SDK dispone di una serie di linee guida per la gestione degli errori a cui puoi fare riferimento per ulteriori informazioni. 

## (Facoltativo) Etichettatura in base al fornitore
<a name="container-vendor-metered-tagging"></a>

L'etichettatura basata sul fornitore aiuta i fornitori di software indipendenti (ISVs) a fornire all'acquirente informazioni più dettagliate sull'utilizzo del software e può aiutarlo a eseguire l'allocazione dei costi.

**Nota**  
L'etichettatura basata sul fornitore non è supportata per le richieste di misurazione per i prodotti Amazon Bedrock. AgentCore 

Esistono diversi modi per contrassegnare l'utilizzo del software da parte di un acquirente. Uno consiste nel chiedere innanzitutto agli acquirenti cosa vogliono vedere nella ripartizione dei costi. Quindi puoi suddividere l'utilizzo tra le proprietà monitorate per l'account dell'acquirente. Esempi di proprietà includono `AccountId` `Business Unit``Cost Centers`, e altri metadati pertinenti per il tuo prodotto. Queste proprietà vengono esposte all'acquirente come tag. Utilizzando i tag, gli acquirenti possono visualizzare i costi suddivisi in base all'utilizzo in base ai valori dei tag nella loro AWS Billing Console ([https://console.aws.amazon.com/costmanagement/](https://console.aws.amazon.com/costmanagement/)). I tag misurati in base al fornitore non modificano il prezzo, le dimensioni o l'utilizzo totale segnalato. Consente ai clienti di visualizzare i costi per categorie appropriate al prodotto.

In un caso d'uso comune, un acquirente sottoscrive un abbonamento al tuo prodotto utilizzando un Account AWS prodotto. L'acquirente ha inoltre numerosi utenti associati allo stesso abbonamento al prodotto. È possibile creare allocazioni di utilizzo con tag con una chiave di e `AccountId` quindi allocare l'utilizzo a ciascun utente. In questo caso, gli acquirenti possono attivare il `AccountId` tag nella console di Billing and Cost Management e analizzare l'utilizzo da parte dei singoli utenti.

### Esperienza del venditore
<a name="container-vendor-metered-tag-seller"></a>

I venditori possono aggregare i record di misurazione delle risorse con lo stesso set di tag anziché aggregare l'utilizzo di tutte le risorse. Ad esempio, i venditori possono creare il record di misurazione che include diversi bucket. `UsageAllocations` Ogni bucket rappresenta un set di tag, ad `UsageQuantity` esempio e. `AccountId` `BusinessUnit` 

Nel diagramma seguente, **Resource 1** ha un set unico di `BusinessUnit` tag `AccountId` e viene visualizzata nel **Metering Record** come una voce singola. 

La **risorsa 2** e la **risorsa 3** hanno entrambe lo stesso `AccountId` tag e lo stesso `BusinessUnit` tag. `2222` `Operations` Di conseguenza, vengono combinati in un'unica `UsageAllocations` voce nel **Metering Record**.

![\[Diagramma che mostra come i tag di misurazione dei fornitori combinano i dati di utilizzo. Tre risorse (Risorsa 1, 2 e 3) con dati diversi AccountIds BusinessUnits vengono consolidate in un unico record di misurazione, UsageAllocations raggruppate per AccountId e BusinessUnit prima di essere inviate al AWS Marketplace Metering Service.\]](http://docs.aws.amazon.com/it_it/marketplace/latest/userguide/images/seller-vendor-meter-tag.png)


I venditori possono anche combinare le risorse senza tag in un'unica risorsa `UsageAllocation` con la quantità di utilizzo assegnata e inviarla come una delle voci inserite. `UsageAllocations`

I limiti includono:
+ Numero di tag: 5
+ Dimensione di `UsageAllocations` (cardinalità): 2.500

Le convalide includono:
+ Caratteri consentiti per la chiave e il valore del tag: a-zA-Z 0-9\$1 -= . \$1:\$1 /@
+ Numero massimo di tag nell'`UsageAllocation`elenco: 5
+ Due non `UsageAllocations` possono avere gli stessi tag (ovvero la stessa combinazione di chiavi e valori dei tag). In tal caso, devono usare lo stesso`UsageAllocation`.
+ La somma `AllocatedUsageQuantity` di `UsageAllocation` deve essere uguale a`UsageQuantity`, che è l'utilizzo aggregato.

### Esperienza dell'acquirente
<a name="container-vendor-metered-tag-buyer"></a>

La tabella seguente mostra un esempio dell'esperienza dell'acquirente dopo che un acquirente ha attivato i tag `AccountId` e `BusinessUnit` fornitore. 

In questo esempio, l'acquirente può visualizzare l'utilizzo allocato nel proprio rapporto **sui costi** di utilizzo. I tag misurati dal fornitore utilizzano il prefisso. `“aws:marketplace:isv”` Gli acquirenti possono attivarli in Billing and Cost Management, **in Tag di allocazione dei costi AWS, tag di allocazione** **dei costi generati**.

La prima e l'ultima riga del **report sull'utilizzo dei costi** sono pertinenti a ciò che il venditore invia al servizio di misurazione (come mostrato nell'esempio). [Esperienza del venditore](#container-vendor-metered-tag-seller)


**Report sull'utilizzo dei costi (semplificato)**  

| ProductCode  | Acquirente | UsageDimension | UsageQuantity | `aws:marketplace:isv:AccountId ` | `aws:marketplace:isv:BusinessUnit` | 
| --- | --- | --- | --- | --- | --- | 
| xyz | 111122223333 | Rete: per (GB) ispezionata  | 70 | 2222 | Operazioni | 
| xyz | 111122223333 | Rete: per (GB) ispezionata  | 30 | 3333 | Ambito finanziario | 
| xyz | 111122223333 | Rete: per (GB) ispezionata  | 20 | 4444 | IT | 
| xyz | 111122223333 | Rete: per (GB) ispezionata  | 20 | 5555 | Marketing | 
| xyz | 111122223333 | Rete: per (GB) ispezionata  | 30 | 1111 | Marketing | 

Per un esempio di codice, consulta [`MeterUsage`esempio di codice con etichettatura per l'allocazione dell'utilizzo (opzionale)](#container-meterusage-code-example).

## Esempio di codice
<a name="container-meter-code-example"></a>

Il seguente esempio di codice viene fornito per aiutarvi a integrare il prodotto contenitore con quanto Marketplace AWS APIs necessario per la pubblicazione e la manutenzione del prodotto.

### `MeterUsage`esempio di codice con etichettatura per l'allocazione dell'utilizzo (opzionale)
<a name="container-meterusage-code-example"></a>

Il seguente esempio di codice è rilevante per i prodotti container con modelli di determinazione dei prezzi al consumo. L'esempio di Python invia un record di misurazione con i tag di allocazione dell'uso appropriati per addebitare le Marketplace AWS commissioni ai clienti. pay-as-you-go

```
# NOTE: Your application will need to aggregate usage for the 
#       customer for the hour and set the quantity as seen below. 
# Marketplace AWS can only accept records for up to an hour in the past. 
#
# productCode is supplied after the Marketplace AWS Ops team has 
# published the product to limited

# Import AWS Python SDK
import boto3
import time

usageRecord = [
    { 
        "AllocatedUsageQuantity": 2, 
        "Tags": 
            [ 
                { "Key": "BusinessUnit", "Value": "IT" },
                { "Key": "AccountId", "Value": "123456789" },
            ]

    },
    { 
        "AllocatedUsageQuantity": 1, 
        "Tags": 
            [ 
                { "Key": "BusinessUnit", "Value": "Finance" },
                { "Key": "AccountId", "Value": "987654321" },
            ]

    }
]

marketplaceClient = boto3.client("meteringmarketplace")

response = marketplaceClient.meter_usage(
    ProductCode="testProduct",
    Timestamp=int(time.time()),
    UsageDimension="Dimension1",
    UsageQuantity=3,
    DryRun=False,
    UsageAllocations=usageRecord 
)
```

*Per ulteriori informazioni in merito`MeterUsage`, consulta l'API [MeterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html)Reference.AWS Marketplace Metering Service *

### Esempio di risposta
<a name="container-meterusage-code-response"></a>

```
{ "MeteringRecordId": "string" }
```

# Integrazione del prodotto container utilizzando la misurazione personalizzata con e AWS Marketplace Metering Service AWS SDK per Java
<a name="java-integration-example-meterusage"></a>

Marketplace AWS i prodotti container possono avere una misurazione personalizzata per un massimo di 24 diverse dimensioni di prezzo per prodotto. Per abilitare la misurazione personalizzata, integri il tuo prodotto container con AWS Marketplace Metering Service. Puoi definire le tue unità di prezzo e la misurazione personalizzata per tale utilizzo e per la fatturazione utilizzando AWS il funzionamento dell'API. [https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html) L'esempio seguente delinea un'implementazione che utilizza il servizio di misurazione AWS SDK per Java per l'integrazione con il funzionamento del servizio di [Marketplace AWS misurazione](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html). `MeterUsage` 

Per tutti i dettagli completi, consultare [`MeterUsage`Esempi di Java](#meterusage-java-example). Molti dei passaggi seguenti si applicano indipendentemente dalla lingua. 

**Esempio: integrazione del servizio Marketplace AWS di misurazione**

1. Accedi alla [Portale di gestione Marketplace AWS](https://aws.amazon.com/marketplace/management/tour).

1. Da **Assets**, scegli **Containers** per iniziare a creare un nuovo prodotto container. La creazione del prodotto genera il codice prodotto per il prodotto da integrare con l'immagine del contenitore. Per informazioni sull'impostazione delle autorizzazioni AWS Identity and Access Management (IAM), consulta[Marketplace AWS autorizzazioni API di misurazione e autorizzazione](iam-user-policy-for-aws-marketplace-actions.md).

1.  Scarica l'[SDK AWS Java](https://aws.amazon.com/sdk-for-java/) pubblico. 
**Importante**  
 Per chiamare le operazioni dell'API di misurazione da Amazon Elastic Kubernetes Service (Amazon EKS)[, devi AWS utilizzare](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html) un SDK supportato ed eseguirlo su un cluster Amazon EKS che esegue Kubernetes 1.13 o versione successiva. 

1. Chiama l'`MeterUsage`operazione dal task o dal pod una volta all'ora per ogni utilizzo di dimensione. L'operazione API accetta un record di misurazione per una combinazione unica di `Dimension``Resource`, e`Hour`. La risorsa è un'attività Amazon Elastic Container Service (Amazon ECS) o un pod Amazon EKS.

   ```
   {
       "ProductCode" : "string", // (required)
       "UsageDimension" : "string", // (required)
       "UsageQuantity":  int, // (optional) Default is 0. Acceptable value from [0, 2147483647 (INT_MAX)]
       "Timestamp": Date, // (required) Timestamp in UTC. Value can be one hour in the past.
       "UsageAllocations": List<UsageAllocation> // (optional) UsageAllocations across 1 or more tags.
   }
   ```
**Nota**  
È possibile riscontrare problemi transitori nella connessione a. AWS Marketplace Metering Service Marketplace AWS consiglia vivamente di implementare nuovi tentativi per un massimo di 30 minuti, con backoff esponenziale, per evitare interruzioni a breve termine o problemi di rete.

1. Ricostruisci una nuova versione dell'immagine del contenitore che includa la `MeterUsage` chiamata, tagga il contenitore e inviala a qualsiasi registro Docker compatibile con Amazon ECS o Amazon EKS, come Amazon Elastic Container Registry (Amazon ECR). Se utilizzi Amazon ECR, assicurati che l'account che avvia l'attività Amazon ECS o il pod Amazon EKS disponga delle autorizzazioni per l'archivio Amazon ECR. In caso contrario, l'operazione non va a buon fine.

1. Crea un ruolo [IAM](https://aws.amazon.com/iam/) che conceda l'autorizzazione alla chiamata del contenitore`MeterUsage`, come definito nel seguente esempio di codice. È necessario fornire questo ruolo AWS Identity and Access Management (IAM) nel parametro [Task Role](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_role_arn) della definizione del task Amazon ECS o del pod Amazon EKS.

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

****  

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

------

1. Crea un'attività Amazon ECS o una definizione del pod Amazon EKS che faccia riferimento al contenitore integrato Marketplace AWS e che faccia riferimento al ruolo IAM creato nella fase 6. Se desideri visualizzare la registrazione, abilita la AWS CloudTrail registrazione nella definizione dell'attività. 

1. Crea un cluster Amazon ECS o Amazon EKS per eseguire la tua attività o il tuo pod. Per ulteriori informazioni sulla creazione di un cluster Amazon ECS, consulta [Creating a cluster](https://docs.aws.amazon.com/AmazonECS/latest/userguide/create_cluster.html) nella *Amazon Elastic Container Service Developer Guide*. [Per ulteriori informazioni sulla creazione di un cluster Amazon EKS (utilizzando Kubernetes versione 1.1.3.x o successiva), consulta Creazione di un cluster Amazon EKS.](https://docs.aws.amazon.com/eks/latest/userguide/create_cluster.html)

1. Configura il cluster Amazon ECS o Amazon EKS e avvia la definizione di attività Amazon ECS o il pod Amazon EKS che hai creato nella fase 8, nella regione us-east-1. AWS È solo durante questo processo di test, prima che il prodotto sia disponibile, che devi utilizzare questa regione.

1. Quando ricevi una risposta valida `MeterUsage` per ciascuna delle dimensioni pubblicate per il prodotto, puoi iniziare a creare il tuo prodotto contenitore. Per domande, contatta il team [operativo Marketplace AWS del venditore](https://aws.amazon.com/marketplace/management/contact-us/). 

## `MeterUsage`Esempi di Java
<a name="meterusage-java-example"></a>

I seguenti esempi di codice utilizzano AWS Marketplace Metering Service per chiamare l'`MeterUsage`operazione. AWS SDK per Java 

Il seguente esempio di codice chiama l'`MeterUsage`operazione senza alcuna`UsageAllocations`.

```
import com.amazonaws.services.marketplacemetering.AWSMarketplaceMetering;
import com.amazonaws.services.marketplacemetering.AWSMarketplaceMeteringClientBuilder;
import com.amazonaws.services.marketplacemetering.model.MeterUsageRequest;
import com.amazonaws.services.marketplacemetering.model.MeterUsageResult;

import java.util.Date;

public class MeterUsage {
    private static final String PRODUCT_CODE = ".......";
    private final AWSMarketplaceMetering awsMarketplaceMetering;

    public MeterUsage() {
        awsMarketplaceMetering = AWSMarketplaceMeteringClientBuilder.standard().build();
    }

    /**
     * Submits metering record for a FCP Dimension. The API accepts 1 metering record per dimension
     * for a given buyer's resource for a given timestamp hour. Ex. If a buyer is running 10 tasks,
     * the API will accepts 1 call to MeterUsage in an hour for a given dimension for each running task.
     *
     * @param dimension - FCP dimension name provided during the publishing of the product.
     * @param quantity - FCP dimension consumption value for the hour.
     * @param timestamp - Timestamp, in UTC, for which the usage is being reported.
     *                  Timestamp cant be more than 1 hour in the past.
     *                  Make sure the timestamp value is not before the start of the software usage.
     */
    public void callMeterUsage(String dimension, int quantity, Date timestamp) {
        MeterUsageRequest meterUsageRequest = new MeterUsageRequest()
                .withProductCode(PRODUCT_CODE)
                .withUsageDimension(dimension)
                .withUsageQuantity(quantity)
                .withTimestamp(timestamp);
        MeterUsageResult meterUsageResult = awsMarketplaceMetering.meterUsage(meterUsageRequest);
    }
}
```

Il seguente esempio di codice richiama l'`MeterUsage`operazione con`UsageAllocations`.

```
private static String callMeterUsageWithAllocationsByTag(AWSMarketplaceMetering marketplaceMetering) {
        // Tag Keys for the product
        String tagKey1 = "Key1";
        String tagKey2 = "Key2";
        String tagKey3 = "Key3";

        // 1st Usage Allocation bucket which has two Tags [{Key1, Key1Value1},{Key2, Key2Value1}]
        List<Tag> tagsForUsageAllocation1 = Arrays.asList(new Tag().withKey(tagKey1).withValue("Key1Value1"),
                new Tag().withKey(tagKey2).withValue("Key2Value1"));
        UsageAllocation usageAllocation1 = new UsageAllocation()
                .withTags(tagsForUsageAllocation1)
                .withAllocatedUsageQuantity(20);

        // 2nd Usage Allocation bucket which has two Tags [{Key1, Key1Value2},{Key2, Key2Value1}]
        List<Tag> tagsForUsageAllocation2 = Arrays.asList(new Tag().withKey(tagKey1).withValue("Key1Value2"),
                new Tag().withKey(tagKey2).withValue("Key2Value1"));
        UsageAllocation usageAllocation2 = new UsageAllocation()
                .withTags(tagsForUsageAllocation2)
                .withAllocatedUsageQuantity(20);

        // 3rd Usage Allocation bucket which has two Tags [{Key1, Key1Value2},{Key2, Key2Value2},{Key3, Key3Value1}]
        List<Tag> tagsForUsageAllocation3 = Arrays.asList(new Tag().withKey(tagKey1).withValue("Key1Value2"),
                new Tag().withKey(tagKey2).withValue("Key2Value2"),
                new Tag().withKey(tagKey3).withValue("Key3Value1"));
        UsageAllocation usageAllocation3 = new UsageAllocation()
                .withTags(tagsForUsageAllocation3)
                .withAllocatedUsageQuantity(15);

        // 4th Usage Allocation bucket with no tags
        UsageAllocation usageAllocation4 = new UsageAllocation()
                .withAllocatedUsageQuantity(15);

        List<UsageAllocation> usageAllocationList = Arrays.asList(usageAllocation1,
                usageAllocation2,
                usageAllocation3,
                usageAllocation4);

        MeterUsageRequest meterUsageRequest = new MeterUsageRequest()
                .withProductCode("TestProductCode")
                .withUsageDimension("Dimension1")
                .withTimestamp(new Date())
                //UsageQuantity value must match with sum of all AllocatedUsageQuantity
                .withUsageQuantity(70)
                .withUsageAllocations(usageAllocationList);

        MeterUsageResult meterUsageResult;
        try {
            meterUsageResult = marketplaceMetering.meterUsage(meterUsageRequest);
        } catch (Exception e) {
            // Log Error
            throw e;
        }

        return meterUsageResult.getMeteringRecordId();
    }
```

# Prezzi contrattuali per prodotti in container con AWS License Manager
<a name="container-license-manager-integration"></a>

Per i prodotti basati su container con prezzi contrattuali, puoi usarli AWS License Manager per associare le licenze al tuo prodotto. AWS License Manager è uno strumento di gestione delle licenze che consente all'applicazione di tenere traccia e aggiornare le licenze (note anche come autorizzazioni) acquistate da un cliente. Questa sezione fornisce informazioni su come integrare il prodotto con. AWS License Manager Una volta completata l'integrazione, puoi pubblicare la tua scheda di prodotto su Marketplace AWS.

Se stai integrando License Manager con un prodotto Marketplace AWS for Containers Anywhere per Amazon EKS Anywhere, Amazon ECS Anywhere, Amazon Elastic Compute Cloud (Amazon EC2) Elastic Compute Cloud (Amazon EC2) o un'infrastruttura locale, segui le istruzioni riportate in. [Integrazione di an Marketplace AWS for Containers Anywhere con License Manager](container-anywhere-license-manager-integration.md)

*Per ulteriori informazioni in merito AWS License Manager, consulta la [Guida per l'AWS License Manager utente e la [AWS License Manager](https://docs.aws.amazon.com/cli/latest/reference/license-manager/index.html)sezione del Command](https://docs.aws.amazon.com/license-manager/latest/userguide/license-manager.html) Reference.AWS CLI *

Per ulteriori informazioni sull'integrazione AWS License Manager con i prodotti container con prezzi contrattuali, consulta il laboratorio [Integrazione con pagamento anticipato](https://catalog.workshops.aws/mpseller/en-US/container/integrate-contract) del workshop per i *Marketplace AWS venditori*.

**Topics**
+ [Prezzi contrattuali per i prodotti in container](#container-contracts)
+ [Modelli di licenza](#container-LM-license-models)
+ [AWS License Manager prerequisiti di integrazione](#container-LM-prereqs)
+ [Integrazione di un prodotto contenitore con License Manager](#container-integrate-with-LM)
+ [Operazioni dell'API License Manager](#container-LM-API-calls)
+ [Rinnovi e aggiornamenti delle licenze](#container-LM-lic-renew-upgrade)
+ [Integrazione di an Marketplace AWS for Containers Anywhere con License Manager](container-anywhere-license-manager-integration.md)

## Prezzi contrattuali per i prodotti in container
<a name="container-contracts"></a>

Per i prodotti basati su container con prezzi contrattuali, Marketplace AWS fattura i clienti in anticipo o in base al piano di pagamento da te definito, in base al contratto tra te e il cliente. Dopo quel punto, hanno il diritto di utilizzare tali risorse. 

Per impostare i prezzi, scegli una o più durate contrattuali che offri ai clienti. Puoi inserire prezzi diversi per ogni durata del contratto. Le opzioni disponibili sono durate di 1 mese, 12 mesi, 24 mesi e 36 mesi. Per le offerte private, puoi specificare una durata personalizzata in mesi (fino a 60 mesi). 

Scegli la categoria che meglio descrive il prezzo del tuo prodotto. La categoria di prezzo viene visualizzata dai clienti sul Marketplace AWS sito web. **Puoi scegliere tra **larghezza di banda** (GB/s, MB/s), **dati** (GB, MB, TB), **host**, **richieste**, **livelli** o utenti.** **Se nessuna delle categorie predefinite soddisfa le tue esigenze, puoi scegliere la categoria più generica di Unità.** 

L'offerta consente di aggiungere fino a 24 dimensioni.


**Esempio: applicazione di archiviazione dati**  

|   | Prezzo per 1 mese | Prezzo per 12 mesi  | Prezzo per 24 mesi  | Prezzo per 36 mesi  | 
| --- | --- | --- | --- | --- | 
|  Dati non crittografati (GB)  |  1,50 USD/GB  |  \$116,00/GB  |  \$130,00/GB  |  \$160,00/GB  | 
|  Dati crittografati (GB)  |  1,55 USD/GB  |  \$116,60/GB  |  \$131,20/GB  |  \$161,20/GB  | 


**Esempio: prodotto per il monitoraggio dei log**  

|   | Prezzo per 1 mese | Prezzo per 12 mesi  | Prezzo per 24 mesi | Prezzo per 36 mesi | 
| --- | --- | --- | --- | --- | 
|  Base (10 host monitorati, 5 container monitorati)  |  \$1100  |  \$11000  | 2000 dollari  | 4000 dollari | 
|  Standard (20 host monitorati, 10 container monitorati)  |  \$1200  |  2000\$1  | 4000 dollari  | 8000 dollari | 
|  Pro (40 host monitorati, 20 container monitorati)  |  400 dollari  |  4000 dollari  | 8000 dollari  | 16.000\$1 | 
|  Host aggiuntivi monitorati ogni ora  | \$110  | \$1100  |  \$1200 | 400 dollari | 
|  Contenitori aggiuntivi monitorati ogni ora  | \$110  | \$1100  |  \$1200 | 400 dollari | 

**Nota**  
I prezzi possono essere per le seguenti durate: 1 mese, 12 mesi, 24 mesi o 36 mesi. Puoi scegliere di offrire una o più di queste opzioni per il tuo prodotto. Le durate devono essere le stesse in ogni dimensione.   

**Example**  
Ad esempio, nel caso in cui tu abbia `ReadOnlyUsers` delle `AdminUsers` dimensioni, se offri un prezzo annuale per ReadOnlyUsers, devi offrire anche un prezzo annuale per`AdminUsers`.


### Rinnovi automatici
<a name="ami-contracts-automatic-renewals"></a>

 Quando i clienti acquistano il prodotto Marketplace AWS utilizzando contratti relativi ai container, possono accettare di rinnovare automaticamente i termini del contratto. I clienti continuano a pagare i diritti ogni mese o per 1, 2 o 3 anni. 

I clienti possono modificare le impostazioni di rinnovo in qualsiasi momento. Per ulteriori informazioni, consulta [Modifica di un contratto esistente](https://docs.aws.amazon.com/marketplace/latest/buyerguide/buyer-container-contracts.html#modify-existing-contract) nella *Guida all'Marketplace AWS acquisto*.

## Modelli di licenza
<a name="container-LM-license-models"></a>

Marketplace AWS integrazione con AWS License Manager supporta due modelli di licenza:
+ [Modello di licenza configurabile](#container-LM-config-lic-model)
+ [Modello di licenza a più livelli](#container-LM-tiered-lic-model)

### Modello di licenza configurabile
<a name="container-LM-config-lic-model"></a>

Il modello di licenza configurabile (noto anche come modello di licenza quantificabile) dà diritto a un acquirente a una quantità specifica di risorse dopo che l'acquirente si è procurato una licenza. 

Hai impostato una dimensione di prezzo e un prezzo unitario. L'acquirente può quindi scegliere la quantità di risorse che desidera acquistare.

**Example della dimensione dei prezzi e del prezzo unitario**  
Puoi impostare una dimensione di prezzo (come il backup dei dati) e un prezzo unitario (ad esempio 30 USD per unità).  
L'acquirente può scegliere di acquistare 5, 10 o 20 unità.   
Il prodotto monitora e misura l'utilizzo per misurare la quantità di risorse consumate.

Con il modello di configurazione, i diritti vengono conteggiati in due modi:
+ [Licenze Drawdown](#container-floating-lic)
+ [Licenze fluttuanti](#container-floating-lic) 

#### Licenza Drawdown
<a name="container-drawndown-lic"></a>

 La licenza viene prelevata dal pool di licenze consentite al momento dell'uso. Tale autorizzazione viene verificata in modo permanente e non può essere restituita al pool di licenze.

**Example di elaborare una quantità limitata di dati**  
Un utente ha il diritto di elaborare 500 GB di dati. Man mano che continuano a elaborare i dati, la quantità viene prelevata dal pool di 500 GB fino a esaurire tutte le licenze da 500 GB.

Per le licenze drawdown, è possibile utilizzare l'operazione `CheckoutLicense` API per verificare le unità di licenza (diritti) utilizzate. 

**Example di backup su Amazon S3 per un certo numero di unità/anno**  
Disponi di un prodotto di storage che consente il backup su Amazon Simple Storage Service per un massimo di 1.024 unità di dati per un anno. L'applicazione può essere avviata utilizzando più istanze Amazon EC2. L'applicazione dispone di un meccanismo per tracciare e aggregare i dati. Il software richiama il funzionamento dell'`CheckoutLicense`API con l'ID del prodotto a ogni backup o a intervalli fissi per aggiornare le quantità consumate.   
In questo esempio, il software richiama l'operazione `CheckoutLicense` API per il check-out di 10 unità di dati. Quando la capacità totale raggiunge il limite di backup acquistato dal cliente, la chiamata API non riesce.

**Richiesta**

```
linux-machine ~]$ aws license-manager checkout-license\
--product-sku "2205b290-19e6-4c76-9eea-377d6bf7la47" \
--checkout-type "PERPETUAL" \
--key-fingerprint "aws:294406891311:AWS/Marketplace:issuer-fingerprint" \
--entitlements "Name=DataConsumption, Value=l0, Unit=Count" \
--client-token "AKIAIOSFODNN7EXAMPLE"
```

**Risposta**

```
{"CheckoutType": "PERPETUAL",
"EntitlementsAllowed": [{
"Name": "IntermediateTier",
"Units": "None"
}],
"Expiration": "2021-04-22Tl9:02:36",
"IssuedAt": "2021-04-22Tl8:02:36",
"LicenseArn": "arn:aws:license-manager::294406891311:license:l-16bf01b...",
"LicenseConsumptionToken": "AKIAIOSFODNN7EXAMPLE"
}
```

#### Licenze fluttuanti
<a name="container-floating-lic"></a>

 La licenza viene restituita al pool del numero consentito di licenze dopo l'uso.

Per le licenze flottanti, l'applicazione estrae i permessi dal pool di autorizzazioni utilizzando l'operazione `CheckoutLicense` API quando la risorsa viene utilizzata. La risposta dell'operazione `CheckoutLicense` API include un token di consumo della licenza che è un identificatore univoco per il checkout. Il token di utilizzo della licenza può essere utilizzato per eseguire azioni aggiuntive sui diritti oggetto di check-out, ad esempio inserirli nuovamente nella licenza o estendere il check-out.

Per ricontrollare i diritti nel pool, utilizza l'operazione `CheckInLicense` API quando la risorsa non è più in uso.

```
aws license-manager check-in-license --license-consumption-token "f1603b3c1f574b7284db84..."
```

In caso di mancato check-in dell'autorizzazione (nel caso in cui l'applicazione si sia bloccata), l'autorizzazione torna automaticamente nel pool dopo 60 minuti. Se la risorsa viene utilizzata per più di 60 minuti, è consigliabile mantenere l'autorizzazione esclusa dal pool utilizzando l'operazione `ExtendLicenseConsumption` API per tutto il tempo in cui la risorsa viene utilizzata.

```
aws license-manager extend-license-consumption --license-consumption-token "f1603b3c1f574b7284..."
```

**Example del numero di utenti a partire da un limite massimo fisso**  
Un utente ha diritto a 500 utenti simultanei sull'applicazione. Quando gli utenti accedono e si disconnettono, gli utenti vengono estratti e restituiti al pool di 500 utenti. Tuttavia, l'applicazione non può attirare più di 500 utenti dal pool perché 500 utenti simultanei è il limite massimo fisso.

Per le autorizzazioni fluttuanti, è possibile utilizzare l'operazione `CheckInLicense` API per restituire le unità di licenza al pool di autorizzazioni. 

**Example del numero di utenti simultanei per un anno**  
Il prezzo del prodotto è basato sul numero di utenti simultanei. Il cliente acquista una licenza per 10 utenti per un anno. Il cliente avvia il software fornendo le autorizzazioni AWS Identity and Access Management (IAM). Quando un utente effettua l'accesso, l'applicazione richiama l'operazione `CheckoutLicense` API per ridurre la quantità di 1. Quando l'utente si disconnette, l'applicazione restituisce la licenza al pool chiamando l'operazione `CheckInLicense` API. Se non chiami`CheckInLicense`, l'unità di licenza verrà automaticamente registrata dopo 1 ora.

**Nota**  
Nella richiesta seguente, `key-fingerprint` non è un valore segnaposto ma il valore effettivo dell'impronta digitale con cui verranno pubblicate tutte le licenze.

**Richiesta**

```
aws license-manager checkout-license\
--product-sku "2205b290-19e6-4c76-9eea-377d6bf7la47" \
--checkout-type "PROVISIONAL" \
--key-fingerprint "aws:294406891311:AWS/Marketplace:issuer-fingerprint" \
--entitlements "Name=ReadOnlyUSers, Value=l0, Unit=Count" \
--client-token "AKIAIOSFODNN7EXAMPLE"
```

**Risposta**

```
{
  "CheckoutType": "PROVISIONAL",
  "EntitlementsAllowed": [
    {
      "Name": "ReadOnlyUsers", 
      "Count": 10,
      "Units": "Count",
      "Value": "Enabled"
    }
},
  "Expiration": "2021-04-22Tl9:02: 36",
  "IssuedAt": "2021-04-22Tl8:02:36",
  "LicenseArn": "arn:aws:license-manager::294406891311:license:l-16bf01b...",
  "LicenseConsumptionToken": "AKIAIOSFODNN7EXAMPLE"
}
```

### Modello di licenza a più livelli
<a name="container-LM-tiered-lic-model"></a>

Il modello di licenza a più livelli dà diritto a un acquirente a un livello o livello specifico di funzionalità dell'applicazione dopo che l'acquirente ha acquistato una licenza. 

Puoi creare livelli per il tuo prodotto, come Basic, Intermediate e Premium. L'acquirente seleziona quindi uno dei livelli predefiniti.

L'applicazione non ha bisogno di tracciare o misurare l'utilizzo dell'applicazione.

Con il modello di licenza a più livelli, i diritti non vengono conteggiati, ma indicano invece un livello di servizio acquistato dal cliente. 

Se desideri offrire insieme funzionalità in bundle, sono preferibili i livelli. 

**Example dei livelli Basic, Intermediate e Premium**  
Un cliente può firmare un contratto per uno dei tre possibili livelli del software: Basic, Intermediate o Premium. Ciascuno di questi livelli ha i propri prezzi. Il software è in grado di identificare il livello a cui il cliente si è registrato richiamando l'operazione `CheckoutLicense` API e specificando tutti i livelli possibili nella richiesta.   
La risposta alla richiesta contiene l'autorizzazione corrispondente al livello acquistato dal cliente. Sulla base di queste informazioni, il software è in grado di fornire al cliente un'esperienza adeguata.

#### Richiesta
<a name="container-LM-tiered-request"></a>

```
linux-machine  ~]$ aws  license-manager   checkout-license\
--product-sku  "2205b290-19e6-4c76-9eea-377d6bf7la47"  \
--checkout-type  "PROVISIONAL"  \
--key-fingerprint  "aws:294406891311:AWS/Marketplace:issuer-fingerprint" \
--entitlements  "Name=BasicTier,  Unit=None"   "Name=IntermediateTier,  Unit=None"	\ "Name=PremiumTier, Unit=None"
```

#### Risposta
<a name="container-LM-tiered-response"></a>

```
{
  "CheckoutType": "PROVISIONAL",
  "EntitlementsAllowed": [
    {
      "Name": "IntermediateTier", 
      "Units": "None"
    }
},
  "Expiration": "2021-04-22Tl9:02:36",
  "IssuedAt": "2021-04-22Tl8:02:36",
  "LicenseArn": "arn:aws:license-manager::294406891311:license:l-16bf01b...",
  "LicenseConsumptionToken": "AKIAIOSFODNN7EXAMPLE"
}
```

## AWS License Manager prerequisiti di integrazione
<a name="container-LM-prereqs"></a>

Prima di pubblicare il prodotto, è necessario effettuare le seguenti operazioni:

1. Crea un nuovo prodotto contenitore in e prendi nota del relativo codice prodotto. Portale di gestione Marketplace AWS

   Per ulteriori informazioni, consulta [Panoramica: crea un prodotto contenitore](container-product-getting-started.md#create-container-product).

1. Utilizza un ruolo IAM per l'attività o il pod che esegue l'applicazione con le autorizzazioni IAM necessarie per chiamare `CheckoutLicense` le `ExtendLicenseConsumption` operazioni dell'`CheckInLicense`API e.

   Le autorizzazioni IAM richieste sono dettagliate nella seguente politica IAM.

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

****  

   ```
   {
      "Version":"2012-10-17",		 	 	 
      "Statement":[
         {
            "Sid":"VisualEditorO",
            "Effect":"Allow",
            "Action":[
               "license-manager:CheckoutLicense",
               "license-manager:GetLicense",
               "license-manager:CheckInLicense",
               "license-manager:ExtendLicenseConsumption",
               "license-manager:ListReceivedLicenses"
            ],
            "Resource":"*"
         }
      ]
   }
   ```

------

1. Effettua una chiamata di prova all'operazione `RegisterUsage` API con un record per tutte le dimensioni di prezzo che definisci.

## Integrazione di un prodotto contenitore con License Manager
<a name="container-integrate-with-LM"></a>

**Per integrare il prodotto basato su container con License Manager**

1. Imposta le autorizzazioni IAM per chiamare License Manager. Per ulteriori informazioni, consulta [AWS License Manager prerequisiti di integrazione](#container-LM-prereqs).

1. Scarica l' AWS SDK.
**Nota**  
Non configurate AWS le credenziali all'interno del vostro software. AWS le credenziali per l'acquirente vengono ottenute automaticamente in fase di esecuzione quando il container è in esecuzione all'interno di un'istanza Amazon EC2, un'attività Amazon ECS o un pod Amazon EKS.

1. Aggiungi controlli di licenza al tuo prodotto.

   Il prodotto può richiamare l'operatività dell'`CheckoutLicense`API ovunque debba essere eseguito il controllo della licenza. Per verificare la licenza, il prodotto deve sapere:

   1. L'emittente affidabile della licenza ()Marketplace AWS

   1. Lo SKU del prodotto (ID del prodotto) dell'applicazione

   1. Il diritto a verificare la presenza di questa applicazione

   Le chiamate API variano in base al tipo di licenze tariffarie configurate.

1. Pubblica la tua scheda di prodotti su. Marketplace AWS

## Operazioni dell'API License Manager
<a name="container-LM-API-calls"></a>

Per gestire le licenze archiviate nell'account License Manager del cliente, il software può utilizzare le seguenti operazioni API:
+ `GetLicense`— Un'API che il software può interrogare. Recupera lo stato di una licenza acquistata (ossia scaduta o in scadenza a breve) e invia una notifica di stato al cliente.
+ `CheckoutLicense`— Scopre le licenze acquistate dall'utente. È inoltre possibile utilizzare l'operazione `CheckoutLicense` API per aggiornare la quantità di licenze quando l'utente ha consumato una certa quantità di licenze. Con`CheckoutLicense`, puoi continuare a controllare le quantità di licenze utilizzate dal cliente. Quando il cliente esaurisce tutte le licenze, questa chiamata restituisce un errore. Per informazioni sulla cadenza di esecuzione consigliata, consulta. `CheckoutLicense` [Rinnovi e aggiornamenti delle licenze](#container-LM-lic-renew-upgrade)
+ `ExtendLicenseConsumption`— In caso di dimensioni variabili, quando il software rileva una licenza, la licenza tornerà automaticamente nel pool dopo 60 minuti. Se desideri prolungare il periodo di validità della licenza, utilizza l'operazione `ExtendLicenseConsumption` API per estendere la licenza per altri 60 minuti.
+ `CheckInLicense`— In caso di dimensioni mobili, quando desideri restituire la licenza al pool di autorizzazioni, utilizza l'`CheckInLicense`operazione API.
+ `ListReceivedLicenses`API: elenca le licenze acquistate dall'acquirente.

## Rinnovi e aggiornamenti delle licenze
<a name="container-LM-lic-renew-upgrade"></a>

I clienti possono rinnovare o aggiornare le proprie licenze su. Portale di gestione Marketplace AWS Dopo aver effettuato un acquisto aggiuntivo, Marketplace AWS genera una nuova versione della licenza che riflette i nuovi diritti. Il software legge le nuove autorizzazioni utilizzando le stesse operazioni API. Non è necessario fare nulla di diverso in termini di integrazione del License Manager per gestire i rinnovi e gli aggiornamenti.

A causa di rinnovi di licenza, upgrade, annullamenti e così via, consigliamo che il prodotto richiami l'operatività dell'`CheckoutLicense`API a cadenza regolare mentre il prodotto è in uso. Utilizzando il funzionamento dell'`CheckoutLicense`API a cadenza regolare, il prodotto è in grado di rilevare cambiamenti nelle autorizzazioni, ad esempio aggiornamenti e scadenze.

Ti consigliamo di eseguire la chiamata `CheckoutLicense` API ogni 15 minuti. 

# Integrazione di an Marketplace AWS for Containers Anywhere con License Manager
<a name="container-anywhere-license-manager-integration"></a>

In qualità di Marketplace AWS venditore, puoi effettuare l'integrazione AWS License Manager con un prodotto Marketplace AWS for Containers Anywhere per Amazon EKS Anywhere, Amazon ECS Anywhere, Amazon EC2 o un'infrastruttura locale. Le seguenti sezioni forniscono istruzioni per questa integrazione.

Per informazioni generali sull'integrazione di License Manager con Marketplace AWS, inclusi i modelli di licenza disponibili, vedere[Prezzi contrattuali per prodotti in container con AWS License Manager](container-license-manager-integration.md). Per ulteriori informazioni in merito AWS License Manager, consulta la [Guida per AWS License Manager l'utente](https://docs.aws.amazon.com/license-manager/latest/userguide/license-manager.html) e la [AWS License Manager](https://docs.aws.amazon.com/cli/latest/reference/license-manager/index.html)sezione del *AWS CLI Command Reference*.

**Topics**
+ [Integrazione di un prodotto Marketplace AWS for Containers Anywhere con License Manager](#containers-anywhere-integrate-with-LM)
+ [Test dell'integrazione con License Manager a livello locale](#container-testing-LM-integration-locally)
+ [Test dell'integrazione di License Manager su Amazon EKS](#container-testing-LM-integration-EKS)
+ [Diritti di licenza fluttuanti con License Manager](#container-LM-floating-license)
+ [Le migliori pratiche per l'integrazione con License Manager per le distribuzioni locali](#container-LM-best-practices-on-prem)
+ [`LicenseManagerCredentialsProvider`- Implementazione Java](#container-license-manager-cred-provider-java)
+ [`LicenseManagerCredentialsProvider`- implementazione `Golang`](#container-license-manager-cred-provider-golang)

## Integrazione di un prodotto Marketplace AWS for Containers Anywhere con License Manager
<a name="containers-anywhere-integrate-with-LM"></a>

Utilizza le seguenti istruzioni per integrare il tuo prodotto Marketplace AWS for Containers Anywhere con AWS License Manager.

**Per integrare il prodotto Marketplace AWS for Containers Anywhere con License Manager**

1. Apri un browser Web e accedi a [Portale di gestione Marketplace AWS](https://aws.amazon.com/marketplace/management/).

1. Crea un ID prodotto per il tuo prodotto contenitore eseguendo i seguenti passaggi. Utilizzerai questo ID nell'immagine del contenitore per i controlli della licenza in una fase successiva.

   1. Dalla barra dei menu, espandi **Risorse** e scegli **Contenitore**.

   1. **Inserisci un nome rivolto ai clienti per il tuo prodotto e scegli Crea.** Puoi modificare questo nome in un secondo momento.

   1. Prendi nota dell'**ID del prodotto**. Lo utilizzerai per creare o aggiornare i dettagli dei prezzi del prodotto.
**Suggerimento**  
Se perdi l'ID del prodotto, puoi trovarlo nel menu **Risorse Portale di gestione Marketplace AWS ** scegliendo **Contenitore**. La pagina **Contenitori** mostra un elenco dei tuoi prodotti con il prodotto associato IDs.

1. Scarica l' AWS SDK pubblico più recente e installalo nell'applicazione contenitore. Puoi trovare le istruzioni di installazione per il tuo AWS SDK preferito in [Tools to Build on AWS](https://aws.amazon.com/tools/).
**Nota**  
Per richiamare le operazioni dell'API License Manager da Amazon EKS Anywhere o da un cluster Kubernetes non fornito da AWS, devi utilizzare un SDK supportato. AWS Per visualizzare un elenco di quelli supportati AWS SDKs, consulta [Utilizzo](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html) di un SDK supportato. AWS 

1. Crea un AWS License Manager client con un provider di credenziali personalizzato in modo che possa fornire le credenziali all'applicazione contenitore distribuita sia in locale che in locale AWS . Per il codice sorgente completo per un provider di credenziali personalizzato`LicenseCredentialProvider`, consulta le seguenti sezioni:
   + [`LicenseManagerCredentialsProvider`- Implementazione Java](#container-license-manager-cred-provider-java)
   + [`LicenseManagerCredentialsProvider`- implementazione `Golang`](#container-license-manager-cred-provider-golang)

    `LicenseCredentialsProvider`estende la catena di provider di credenziali predefinita dell' AWS SDK per l'uso in locale aggiungendo. `LicenseManagerTokenCredentialsProvider` Ciò fornisce le credenziali utilizzando i token di identità emessi da License Manager OIDC in ambienti locali. È necessario includere il codice sorgente di nel classpath dell'applicazione`LicenseCredentialsProvider`.
**Nota**  
L'estensione `DefaultCredentialsProvider` consente alla stessa applicazione contenitore di ottenere le credenziali durante l'esecuzione in un ambiente locale AWS e durante l'esecuzione in un ambiente locale. Se l'applicazione contenitore utilizza già una catena di fornitori di credenziali personalizzata anziché quella predefinita, può anche essere estesa aggiungendola `LicenseManagerTokenCredentialsProvider` alla catena personalizzata.

   Il seguente frammento di codice è un esempio di creazione di un AWS License Manager client utilizzando Java.

   ```
   LicenseManagerClientBuilder clientBuilder = LicenseManagerClient.builder().credentialsProvider(LicenseCredentialsProvider.create());
   ```

1. Chiama l'operazione `CheckoutLicense` API utilizzando il `aws license-manager checkout-license` comando di ogni immagine di contenitore a pagamento nella tua offerta di prodotti. Ciò verifica che l'acquirente sia autorizzato a utilizzare una licenza per l'applicazione. Se l'acquirente ha diritto alla richiesta, `CheckoutLicense` ci riesce e restituisce i diritti richiesti e i relativi valori. Se l'acquirente non ha diritto alla richiesta, `CheckoutLicense` genera un'eccezione.

   I seguenti parametri sono necessari quando si chiama l'operazione `CheckoutLicense` API:
   + `CheckoutType`— I valori validi sono `PROVISIONAL` o`PERPETUAL`:
     + Da utilizzare `PERPETUAL` quando la quantità di diritti prelevati dal pool sarà esaurita.

       Esempio: l'acquirente ha il diritto di elaborare 500 GB di dati. Man mano che continuano a elaborare i dati, la quantità viene prelevata ed esaurita dal pool di 500 GB.
     + `PROVISIONAL`Utilizzatelo per le licenze flottanti, in cui le autorizzazioni vengono estratte dal pool e restituite dopo l'uso.

       Esempio: l'utente ha diritto a 500 utenti simultanei sull'applicazione. Quando gli utenti accedono o si disconnettono, gli utenti vengono estratti o restituiti al pool di 500 utenti. Per ulteriori informazioni sui diritti di licenza fluttuanti, consulta. [Diritti di licenza fluttuanti con License Manager](#container-LM-floating-license)
   + `ClientToken`— Un identificatore univoco con distinzione tra maiuscole e minuscole. Si consiglia di utilizzare un UUID casuale per ogni richiesta univoca.
   + `Entitlements`— Un elenco di diritti da verificare.
     + Per i diritti relativi alle funzionalità, fornite le proprietà `Name` and `Unit` come segue.

       ```
       {
         "Name": "<Entitlement_Name>",
         "Unit": "None"
       }
       ```
     + Per i diritti conteggiati, fornite le proprietà `Name``Unit`, e `Count` come segue.

       ```
       {
         "Name": "<Entitlement_Name>",
         "Unit": "<Entitlement_Unit>",
         "Value": <Desired_Count>
       }
       ```
   + `KeyFingerprint`— L'impronta digitale chiave per le licenze rilasciate da è. Marketplace AWS `aws:294406891311:AWS/Marketplace:issuer-fingerprint` L'utilizzo di questa chiave digitale garantisce che la licenza sia rilasciata da Marketplace AWS e non da un'entità inaffidabile.
   + `ProductSKU`— L'ID del prodotto generato Portale di gestione Marketplace AWS nei passaggi precedenti.

   Il seguente frammento è un esempio di chiamata che utilizza l'operazione `CheckoutLicense` API utilizzando il. AWS CLI

   ```
   aws license-manager checkout-license \
   --product-sku "2205b290-19e6-4c76-9eea-377d6bf71a47" \
   --checkout-type "PROVISIONAL" \
   --client-token "79464194dca9429698cc774587a603a1" \
   --entitlements "Name=AWS::Marketplace::Usage/Drawdown/DataConsumption, Value=10, Unit=Gigabytes" \
   --key-fingerprint "aws:294406891311:AWS/Marketplace:issuer-fingerprint"
   ```
**Nota**  
Per controllare le licenze, le applicazioni container richiedono l'accesso alla rete in uscita per utilizzare License Manager. Le applicazioni distribuite in locale potrebbero presentare un accesso alla rete in uscita inaffidabile o lento. Queste applicazioni devono includere tentativi adeguati quando si chiama License Manager. Per ulteriori informazioni, consulta [Le migliori pratiche per l'integrazione con License Manager per le distribuzioni locali](#container-LM-best-practices-on-prem).

1. Chiamate il servizio operativo dell'`CheckoutLicense`API a cadenza regolare per identificare eventuali modifiche alle licenze dei clienti dovute a rinnovi, upgrade o cancellazioni effettuate il. Marketplace AWS La cadenza dipende dall'applicazione. Ti consigliamo di controllare le licenze una volta al giorno per rilevare automaticamente le modifiche senza l'intervento dell'acquirente.

   Un'applicazione distribuita in locale potrebbe avere un accesso inaffidabile alla rete in uscita per controllare le licenze con cadenza regolare. In questi casi, l'applicazione deve utilizzare licenze memorizzate nella cache per una resilienza sufficiente. Per ulteriori informazioni, consulta [Le migliori pratiche per l'integrazione con License Manager per le distribuzioni locali](#container-LM-best-practices-on-prem).

1. Dopo aver integrato la `CheckoutLicense` chiamata con l'applicazione contenitore, crea una nuova versione dell'immagine del contenitore Docker con le modifiche.

1. Aggiorna la tabella Helm dell'applicazione per accettare un segreto Kubernetes come input opzionale che contiene la configurazione per accedere alle licenze tramite License Manager. APIs Il segreto di configurazione conterrà un token di identità rilasciato da License Manager e un AWS Identity and Access Management ruolo che verrà utilizzato dal provider di credenziali personalizzate descritto in precedenza per ottenere AWS le credenziali per chiamare License Manager APIs quando l'applicazione contenitore viene distribuita in locale. Inoltre, aggiungi Regione AWS come input con un valore predefinito di. `us-east-1`

   Gli acquirenti che implementano l'applicazione container in locale possono creare il segreto di Kubernetes attraverso l'esperienza Marketplace AWS dell'acquirente per i prodotti container. Fornisci il nome segreto di Kubernetes come input per il comando. `helm install` Il segreto di configurazione è configurato nel seguente formato.

   ```
   apiVersion: v1
   kind: Secret
   metadata:
     name: aws-marketplace-license-config
   type: Opaque
   stringData:
     license_token: <token_value> // License Manager issued JWT token
     iam_role: <role_arn> // AWS Identity and Access Management role to assume with license token
   ```

1. Aggiorna il modello di distribuzione dell'applicazione nel grafico Helm per le immagini dei contenitori integrate con AWS License Manager per includere quanto segue:
   + Account di servizio per pod: l'account di servizio è necessario per le distribuzioni Helm su Amazon EKS. Viene utilizzato per ottenere le autorizzazioni per chiamare le operazioni dell'API License Manager impostando i ruoli IAM per l'account di servizio sull'immagine del contenitore. Per ulteriori informazioni sui ruoli IAM per gli account di servizio, consulta [Ruoli IAM per gli account di servizio](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html).
   + Accesso alla licenza per le distribuzioni locali: il segreto di configurazione della licenza è necessario per fornire le credenziali e le autorizzazioni appropriate per chiamare le operazioni dell'API License Manager per le distribuzioni Helm in ambienti locali. Gli acquirenti genereranno e forniranno il segreto della licenza a Helm in base all'esperienza dell'acquirente. Marketplace AWS 

   Il seguente frammento di codice è un esempio di specifica di distribuzione con l'account del servizio, la configurazione della licenza e l'image pull secret.

   ```
   apiVersion: apps/v1
   kind: Deployment
   metadata:
     name: example-app
   spec:
     replicas: 1
     selector:
       matchLabels:
         app: example-app
     template:
       metadata:
         labels:
           app: example-app
   spec:
         // Service account for pod
         serviceAccountName: {{ .Values.serviceAccountName }}
         containers:
           - name: example-app
             image: example-app
             ports:
               - containerPort: 8001
   // Add the following conditional attributes
   {{ - if .Values.awsmp.licenseConfigSecretName }}
             //Mount the license volume to the container image
             volumeMounts:
               - name: awsmp-product-license
                 mountPath: "/var/run/secrets/product-license"
             //Add following environment variable to container for credential
   provider
             env:
               - name: AWS_WEB_IDENTITY_REFRESH_TOKEN_FILE
                 value: "/var/run/secrets/product-license/license_token"
               - name: AWS_ROLE_ARN
                   valueFrom:
                       secretKeyRef:
                       name: {{ .Values.aws.licenseConfigSecretName }}
                       key: iam_role
         //Mount the license secret as a volume to the pod
         volumes:
           - name: awsmp-product-license
             secret:
               secretName: {{ .Values.aws.licenseConfigSecretName }}
               optional: true
   {{ - end }}
   ```
**Nota**  
Il segreto di configurazione della licenza è facoltativo. Gli acquirenti utilizzano il valore solo per le distribuzioni locali. Per le AWS distribuzioni, le specifiche di distribuzione devono includere un account di servizio per le immagini integrate di License Manager.

1. Verifica l'integrazione del License Manager localmente e su Amazon EKS eseguendo i passaggi nelle seguenti sezioni:

   1. [Test dell'integrazione con License Manager a livello locale](#container-testing-LM-integration-locally)

   1. [Test dell'integrazione di License Manager su Amazon EKS](#container-testing-LM-integration-EKS)

1. Dopo aver verificato con successo l'integrazione di License Manager AWS sia in locale che in locale, puoi creare la tua lista di prodotti container seguendo la procedura riportata di seguito. [Panoramica: crea un prodotto contenitore](container-product-getting-started.md#create-container-product)

## Test dell'integrazione con License Manager a livello locale
<a name="container-testing-LM-integration-locally"></a>

Puoi utilizzare minikube o qualsiasi altra configurazione per testare l'integrazione del License Manager su qualsiasi cluster Kubernetes a livello locale. Assicurati che il cluster Kubernetes disponga dell'accesso a Internet in uscita per chiamare le operazioni dell'API License Manager.

**Per testare localmente un'integrazione di License Manager**

1. Crea una licenza di prova in un account venditore di prova con i diritti desiderati. Per configurare una licenza di prova, consulta la sezione *AWS License Manager API [CreateLicense](https://docs.aws.amazon.com/license-manager/latest/APIReference/API_CreateLicense.html)*Reference. In alternativa, utilizza lo script seguente per creare una licenza di prova e quindi creare una concessione di licenza a un account acquirente di prova per utilizzare la licenza. Lo script seguente utilizza le credenziali dell'account venditore di prova.

   ```
   read -p 'AWS Account for test buyer: ' TEST_BUYER_ACCOUNT_ID
   read -p 'License entitlements: ' ENTITLEMENTS
   
   # TEST_SELLER_ACCOUNT_ID="109876543210"
   # ENTITLEMENTS="{\"Name\": \"ByData\",\"MaxCount\": 1000,\"Overage\":true,\"Unit\": \"Gigabits\",\"AllowCheckIn\": true}"
   
   # Create License
   
   NOW=$(date +"%Y-%m-%dT00:00:00+00:00")
   
   PRODUCT_NAME="My awesome product"
   PRODUCT_SKU="c97b7825-44c4-4f42-b025-12baa4c171e0"
   
   LICENSE_BENEFICIARY=" arn:aws:iam::$TEST_BUYER_ACCOUNT_ID:root "
   LICENSE_ISSUER_NAME="test-seller"
   LICENSE_NAME="test-seller-license"
   
   CLIENT_TOKEN="b3920968-a94f-4547-af07-3dd232319367"
   CONSUMPTION_TTL=180
   CONSUMPTION_RENEW_TYPE="None"
   
   HOME_REGION="us-east-1"
   
   LICENSE_ARN=$(aws license-manager create-license --license-name "$LICENSE_NAME" --product-name "$PRODUCT_NAME" --product-sku "$PRODUCT_SKU" --issuer Name="$LICENSE_ISSUER_NAME" --home-region "$HOME_REGION" --validity Begin="$NOW" --entitlements "$ENTITLEMENTS" --beneficiary "$LICENSE_BENEFICIARY" --consumption-configuration RenewType="$CONSUMPTION_RENEW_TYPE",ProvisionalConfiguration={MaxTimeToLiveInMinutes=$CONSUMPTION_TTL} --client-token "$CLIENT_TOKEN" | jq -r ".LicenseArn" )
   
   echo "License arn: $LICENSE_ARN"
   
   # Create Grant
   
   GRANT_TOKEN="e9a14140-4fca-4219-8230-57511a6ea6"
   GRANT_NAME="test-grant"
   
   GRANT_ARN=$(aws license-manager create-grant --grant-name "$GRANT_NAME" --license-arn "$LICENSE_ARN" --principals "$LICENSE_BENEFICIARY" --home-region "$HOME_REGION" --client-token "$GRANT_TOKEN" --allowed-operations "CheckoutLicense" "CheckInLicense" "ExtendConsumptionLicense" "CreateToken" | jq -r ".GrantArn")
   
   echo "Grant arn: $GRANT_ARN"
   ```

1. Crea un segreto Kubernetes con il token di licenza e il ruolo IAM utilizzando il formato segreto definito in precedenza. Utilizza l'operazione `CreateToken` API License Manager per generare un token di licenza. Quindi, utilizza l'operazione `CreateRole` API IAM per creare un ruolo IAM con autorizzazioni e una policy di fiducia. Vedi l'esempio nello script seguente. Lo script seguente utilizza le credenziali dell'account acquirente di prova.

   ```
   read -p 'AWS Account for test license: ' TEST_ACCOUNT_ID
   read -p 'License Arn' LICENSE_ARN
   # Create IAM Role
   ROLE_NAME="AWSLicenseManagerConsumptionTestRole"
   ROLE_DESCRIPTION="Role to test AWS License Manager integration on-prem"
   ROLE_POLICY_ARN="arn:aws:iam::aws:policy/service-role/AWSLicenseManagerConsumptionPolicy"
   ROLE_TRUST_POLICY="{\"Version\": \"2012-10-17\",\"Statement\": [{ \"Effect\":\"Allow\", \"Principal\": { \"Federated\": \"openid-license-manager.amazonaws.com\" }, \"Action\": \"sts:AssumeRoleWithWebIdentity\",\"Condition\": { \"ForAnyValue:StringLike\": { \"openid-license-manager.amazonaws.com:amr\": \"aws:license-manager:token-issuer-account-id:${TEST_ACCOUNT_ID}\" }}}]}"
   ROLE_SESSION_DURATION=3600
   
   ROLE_ARN=$(aws iam create-role --role-name "$ROLE_NAME" --description "$ROLE_DESCRIPTION" --assume-role-policy-document "$ROLE_TRUST_POLICY" --max-session-duration $ROLE_SESSION_DURATION | jq ".Role" | jq -r ".Arn")
   
   aws iam attach-role-policy --role-name "$ROLE_NAME" --policy-arn "$ROLE_POLICY_ARN"
   
   echo "Role arn: $ROLE_ARN"
   
   # Create Token
   CLIENT_TOKEN="b3920968-a94f-4547-af07-3dd232319367"
   
   TOKEN=$(aws license-manager create-token --license-arn $LICENSE_ARN --role-arns $ROLE_ARN --client-token $CLIENT_TOKEN | jq '.Token')
   
   echo "License access token: $TOKEN"c
   ```

1. Configura qualsiasi cluster Kubernetes ospitato all'esterno. AWS Usalo per verificare che le applicazioni container possano connettersi all' AWS License Manager API da ambienti diversi AWS e che il provider di credenziali personalizzate sia ben integrato nell'applicazione.

1. Distribuisci il token di licenza e il ruolo IAM generati in precedenza nel cluster Kubernetes locale.

   ```
   kubectl create secret generic "awsmp-license-access-config" \
   --from-literal=license_token=${TOKEN} \
   --from-literal=iam_role=${ROLE_ARN}
   ```

1. Implementa la tua applicazione tramite Helm inserendo il nome segreto e verifica che l'applicazione possa richiamare le operazioni API di License Manager per eseguire i controlli di autorizzazione. Per le modifiche a Helm e alle specifiche di distribuzione, consulta la Fase 9 in. [Integrazione di un prodotto Marketplace AWS for Containers Anywhere con License Manager](#containers-anywhere-integrate-with-LM)

## Test dell'integrazione di License Manager su Amazon EKS
<a name="container-testing-LM-integration-EKS"></a>

Puoi anche testare l'integrazione di License Manager su Amazon EKS. Esegui un test per assicurarti che l'applicazione possa richiamare le operazioni API di License Manager senza il segreto di configurazione della licenza. Assicurati inoltre che l'account di servizio possa essere utilizzato per configurare IAM Roles for Service Accounts (IRSA) e fornire le credenziali pertinenti all'applicazione.

**Per testare un'integrazione di License Manager su Amazon EKS**

1. Crea una licenza di prova in un account venditore di prova con i diritti desiderati. Consulta il [riferimento all'CreateLicense API](https://docs.aws.amazon.com/license-manager/latest/APIReference/API_CreateLicense.html) per configurare la tua licenza di prova oppure usa lo script seguente per crearne una e concedere una licenza a un account acquirente di prova per utilizzare la licenza. Lo script seguente utilizza le credenziali dell'account venditore di prova.

   ```
   read -p 'AWS Account for test buyer: ' TEST_BUYER_ACCOUNT_ID
   read -p 'License entitlements: ' ENTITLEMENTS
   
   # TEST_SELLER_ACCOUNT_ID="109876543210"
   # ENTITLEMENTS="{\"Name\": \"ByData\",\"MaxCount\": 1000,\"Overage\": true,\"Unit\": \"Gigabits\",\"AllowCheckIn\": true}"
   
   # Create License
   
   NOW=$(date +"%Y-%m-%dT00:00:00+00:00")
   
   PRODUCT_NAME="My awesome product"
   PRODUCT_SKU="c97b7825-44c4-4f42-b025-12baa4c171e0"
   
   LICENSE_BENEFICIARY=" arn:aws:iam::$TEST_BUYER_ACCOUNT_ID:root "
   LICENSE_ISSUER_NAME="test-seller"
   LICENSE_NAME="test-seller-license"
   
   CLIENT_TOKEN="b3920968-a94f-4547-af07-3dd232319367"
   CONSUMPTION_TTL=180
   CONSUMPTION_RENEW_TYPE="None"
   
   HOME_REGION="us-east-1"
   
   LICENSE_ARN=$(aws license-manager create-license --license-name "$LICENSE_NAME" --product-name "$PRODUCT_NAME" --product-sku "$PRODUCT_SKU" --issuer Name="$LICENSE_ISSUER_NAME" --home-region "$HOME_REGION" --validity Begin="$NOW" --entitlements "$ENTITLEMENTS" --beneficiary "$LICENSE_BENEFICIARY" --consumption-configuration RenewType="$CONSUMPTION_RENEW_TYPE",ProvisionalConfiguration={MaxTimeToLiveInMinutes=$CONSUMPTION_TTL} --client-token "$CLIENT_TOKEN" | jq -r ".LicenseArn" )
   
   echo "License arn: $LICENSE_ARN"
   
   # Create Grant
   
   GRANT_TOKEN="e9a14140-4fca-4219-8230-57511a6ea6"
   GRANT_NAME="test-grant"
   
   GRANT_ARN=$(aws license-manager create-grant --grant-name "$GRANT_NAME" --license-arn "$LICENSE_ARN" --principals "$LICENSE_BENEFICIARY" --home-region "$HOME_REGION" --client-token "$GRANT_TOKEN" --allowed-operations "CheckoutLicense" "CheckInLicense" "ExtendConsumptionLicense" "CreateToken" | jq -r ".GrantArn")
   
   echo "Grant arn: $GRANT_ARN"
   ```

1. Crea un cluster Amazon EKS di prova delle configurazioni desiderate o esegui i seguenti comandi per utilizzare una configurazione predefinita.

   ```
   aws ec2 create-key-pair --region us-west-2 --key-name eks-key-pair
   ```

   ```
   eksctl create cluster \
   --name awsmp-eks-test-example \
   --region us-west-2 \
   --with-oidc \
   --ssh-access \
   --ssh-public-key eks-key-pair
   ```

1. Crea un account di servizio per un cluster esistente e associalo a un ruolo IAM. Il comando seguente crea un ruolo IAM con`AWSLicenseManagerConsumptionPolicy`. Quindi, il comando lo collega all'account di `test_sa` servizio del cluster Amazon EKS in cui devono essere distribuite le immagini integrate di License Manager. Di conseguenza, l'account del servizio può ottenere le credenziali appropriate per chiamare le operazioni API di License Manager.

   ```
   eksctl create iamserviceaccount \
   --name test_sa \
   --namespace test_namespace \
   --cluster awsmp-eks-test-example \
   --attach-policy-arn "arn:aws:iam::aws:policy/service-role/AWSLicenseManagerConsumptionPolicy" \
   --approve \
   --override-existing-serviceaccounts
   ```

1. Distribuisci l'applicazione tramite Helm nell'account di servizio in cui il ruolo IAM è associato al comando precedente. Verificate che l'applicazione sia in grado di richiamare le operazioni dell'API License Manager per eseguire i controlli delle autorizzazioni.

## Diritti di licenza fluttuanti con License Manager
<a name="container-LM-floating-license"></a>

Con le licenze fluttuanti, quando gli utenti accedono all'applicazione, viene estratta una licenza dal pool di licenze disponibili. Quando gli utenti si disconnettono, le licenze vengono aggiunte nuovamente al pool di licenze disponibili.

Per le licenze flottanti, l'applicazione utilizza l'operazione `CheckoutLicense` API per estrarre le autorizzazioni dal pool di autorizzazioni quando viene utilizzata la risorsa. La risposta dell'operazione `CheckoutLicense` API include un token di consumo della licenza che è un identificatore univoco per il checkout. Il token di utilizzo delle licenze può eseguire azioni aggiuntive sui diritti di accesso sottoposti a check-out, ad esempio archiviarli nuovamente nel pool di licenze o estendere il check-out.

Quando la risorsa non è più in uso, l'applicazione utilizza l'operazione `CheckInLicense` API per ricontrollare l'autorizzazione nel pool.

```
aws license-manager check-in-license \
--license-consumption-token "f1603b3c1f574b7284db84a9e771ee12"
```

Se il ripristino di una licenza nel pool non riesce, ad esempio, se l'applicazione si blocca durante l'operazione, l'autorizzazione viene ricontrollata automaticamente nel pool dopo 60 minuti. Per questo motivo, se la risorsa viene utilizzata per più di 60 minuti, è consigliabile mantenere l'autorizzazione selezionata dal pool. A tale scopo, utilizzate l'operazione `ExtendLicenseConsumption` API fintanto che la risorsa viene utilizzata.

```
aws license-manager extend-license-consumption \
--license-consumption-token "f1603b3c1f574b7284db84a9e771ee12"
```

## Le migliori pratiche per l'integrazione con License Manager per le distribuzioni locali
<a name="container-LM-best-practices-on-prem"></a>

Le implementazioni di applicazioni container in un ambiente locale potrebbero comportare un accesso inaffidabile alla rete in uscita. Utilizza le seguenti best practice per aggiungere resilienza ed evitare interruzioni del servizio agli acquirenti a causa di potenziali problemi causati da una scarsa connettività Internet:
+ **Riprova adeguata**: problemi transitori di rete possono impedire la connessione dell'applicazione. AWS License Manager Implementa nuovi tentativi per un massimo di 30 minuti, con backoff esponenziale. Questo può aiutare a evitare interruzioni a breve termine o problemi di rete.
+ **Evita i limiti rigidi**: le applicazioni distribuite in cluster connessi possono controllare regolarmente le licenze per identificare eventuali modifiche dovute ad aggiornamenti o rinnovi. Con un accesso in uscita inaffidabile, l'applicazione potrebbe non essere in grado di identificare tali modifiche. Ove possibile, l'applicazione dovrebbe evitare interruzioni del servizio agli acquirenti dovute all'impossibilità di controllare le licenze tramite License Manager. Le applicazioni possono ricorrere a una versione di prova gratuita o open source alla scadenza della licenza e non possono verificare se una licenza è valida.
+ **Informa i clienti**: quando si utilizza una licenza memorizzata nella cache, eventuali modifiche alla licenza (inclusi rinnovi o aggiornamenti) non si riflettono automaticamente sul carico di lavoro in esecuzione. Informa i tuoi clienti (che devono consentire nuovamente e temporaneamente l'accesso in uscita all'applicazione) in modo che l'applicazione possa aggiornare la licenza memorizzata nella cache. Ad esempio, informate i clienti tramite l'applicazione stessa o tramite la relativa documentazione. Analogamente, quando ricorri a una serie inferiore di funzionalità, comunica ai clienti che i loro diritti sono esauriti o che la licenza è scaduta. Quindi, possono scegliere di eseguire l'aggiornamento o il rinnovo.

## `LicenseManagerCredentialsProvider`- Implementazione Java
<a name="container-license-manager-cred-provider-java"></a>

`LicenseCredentialsProvider`estende la catena di provider di credenziali predefinita dell' AWS SDK per l'uso in locale aggiungendo. `LicenseManagerTokenCredentialsProvider` 

**`LicenseCredentialsProvider`**

```
package com.amazon.awsmp.license;

import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProviderChain;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.auth.credentials.internal.LazyAwsCredentialsProvider;
import software.amazon.awssdk.utils.SdkAutoCloseable;

public class LicenseCredentialsProvider implements AwsCredentialsProvider, SdkAutoCloseable {
    private static final LicenseCredentialsProvider CREDENTIALS_PROVIDER = new LicenseCredentialsProvider();
    private final LazyAwsCredentialsProvider providerChain;

    private LicenseCredentialsProvider() {
        this.providerChain = createChain();
    }

    public static LicenseCredentialsProvider create() {
        return CREDENTIALS_PROVIDER;
    }

    @Override
    public AwsCredentials resolveCredentials() {
        return this.providerChain.resolveCredentials();
    }

    @Override
    public void close() {
        this.providerChain.close();
    }

    private LazyAwsCredentialsProvider createChain() {
        return LazyAwsCredentialsProvider.create(() -> {
            AwsCredentialsProvider[] credentialsProviders = new AwsCredentialsProvider[]{
                    DefaultCredentialsProvider.create(),
                    LicenseManagerTokenCredentialsProvider.create()};

            return AwsCredentialsProviderChain.builder().reuseLastProviderEnabled(true)
                    .credentialsProviders(credentialsProviders).build();
        });
    }
}
```

**`LicenseManagerTokenCredentialsProvider`**

`LicenseManagerTokenCredentialsProvider`fornisce credenziali utilizzando token di identità emessi da License Manager OIDC in ambienti locali. È necessario includere il codice sorgente di nel percorso di classe dell'applicazione`LicenseCredentialsProvider`.

```
package com.amazon.awsmp.license;

import software.amazon.awssdk.auth.credentials.AnonymousCredentialsProvider;
import software.amazon.awssdk.auth.credentials.AwsCredentials;
import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider;
import software.amazon.awssdk.core.SdkSystemSetting;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.core.retry.RetryPolicyContext;
import software.amazon.awssdk.core.retry.conditions.OrRetryCondition;
import software.amazon.awssdk.core.retry.conditions.RetryCondition;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.regions.providers.DefaultAwsRegionProviderChain;
import software.amazon.awssdk.services.licensemanager.LicenseManagerClient;
import software.amazon.awssdk.services.licensemanager.model.GetAccessTokenRequest;
import software.amazon.awssdk.services.licensemanager.model.GetAccessTokenResponse;
import software.amazon.awssdk.services.sts.StsClient;
import software.amazon.awssdk.services.sts.auth.StsAssumeRoleWithWebIdentityCredentialsProvider;
import software.amazon.awssdk.services.sts.model.AssumeRoleWithWebIdentityRequest;
import software.amazon.awssdk.services.sts.model.IdpCommunicationErrorException;
import software.amazon.awssdk.utils.IoUtils;
import software.amazon.awssdk.utils.SdkAutoCloseable;
import software.amazon.awssdk.utils.StringUtils;
import software.amazon.awssdk.utils.SystemSetting;

import java.io.IOException;
import java.io.InputStream;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.function.Supplier;

public class LicenseManagerTokenCredentialsProvider implements AwsCredentialsProvider, SdkAutoCloseable {

    private final StsAssumeRoleWithWebIdentityCredentialsProvider credentialsProvider;
    private final RuntimeException loadException;

    private Path licenseAccessTokenFile;
    private String roleArn;
    private String roleSessionName;
    private StsClient stsClient;
    private LicenseManagerClient lmClient;

    public static LicenseManagerTokenCredentialsProvider create() {
        return new Builder().build();
    }

    @Override
    public AwsCredentials resolveCredentials() {
        if (this.loadException != null) {
            throw this.loadException;
        }
        return this.credentialsProvider.resolveCredentials();
    }

    @Override
    public void close() {
        IoUtils.closeQuietly(this.credentialsProvider, null);
        IoUtils.closeQuietly(this.stsClient, null);
        IoUtils.closeIfCloseable(this.lmClient, null);
    }

    private LicenseManagerTokenCredentialsProvider(Builder builder) {
        StsAssumeRoleWithWebIdentityCredentialsProvider credentialsProvider = null;
        RuntimeException loadException = null;

        try {
            this.licenseAccessTokenFile = Paths.get(StringUtils.trim(LicenseSystemSetting.AWS_WEB_IDENTITY_REFRESH_TOKEN_FILE.getStringValueOrThrow()));
            this.roleArn = SdkSystemSetting.AWS_ROLE_ARN.getStringValueOrThrow();
            this.roleSessionName = SdkSystemSetting.AWS_ROLE_SESSION_NAME.getStringValue().orElse("aws-sdk-java-" + System.currentTimeMillis());
            this.stsClient = builder.stsClient != null ? builder.stsClient : StsClientFactory.create();
            this.lmClient = builder.lmClient != null ? builder.lmClient : LicenseManagerClientFactory.create();

            AssumeRoleWithWebIdentityRequest request = AssumeRoleWithWebIdentityRequest.builder()
                    .roleArn(this.roleArn).roleSessionName(this.roleSessionName).build();

            Supplier<AssumeRoleWithWebIdentityRequest> supplier = new AssumeRoleRequestSupplier(request,
                    this.licenseAccessTokenFile, this.lmClient);

            credentialsProvider = StsAssumeRoleWithWebIdentityCredentialsProvider.builder()
                    .stsClient(this.stsClient).refreshRequest(supplier).build();
        } catch (RuntimeException ex) {
            loadException = ex;
        }

        this.credentialsProvider = credentialsProvider;
        this.loadException = loadException;
    }

    public static final class Builder {
        private Path licenseAccessTokenFile;
        private String roleArn;
        private String roleSessionName;
        private StsClient stsClient;
        private LicenseManagerClient lmClient;

        public LicenseManagerTokenCredentialsProvider build() {
            return new LicenseManagerTokenCredentialsProvider(this);
        }

        public LicenseManagerTokenCredentialsProvider.Builder licenseAccessTokenFile(Path licenseAccessTokenFile) {
            this.licenseAccessTokenFile = licenseAccessTokenFile;
            return this;
        }

        public LicenseManagerTokenCredentialsProvider.Builder roleArn(String roleArn) {
            this.roleArn = roleArn;
            return this;
        }

        public LicenseManagerTokenCredentialsProvider.Builder roleSessionName(String roleSessionName) {
            this.roleSessionName = roleSessionName;
            return this;
        }

        public LicenseManagerTokenCredentialsProvider.Builder stsClient(StsClient stsClient) {
            this.stsClient = stsClient;
            return this;
        }

        public LicenseManagerTokenCredentialsProvider.Builder lmClient(LicenseManagerClient lmClient) {
            this.lmClient = lmClient;
            return this;
        }
    }

    private static final class AssumeRoleRequestSupplier implements Supplier {
        private final LicenseManagerClient lmClient;
        private final AssumeRoleWithWebIdentityRequest request;
        private final Path webIdentityRefreshTokenFile;

        AssumeRoleRequestSupplier(final AssumeRoleWithWebIdentityRequest request,
                                                 final Path webIdentityRefreshTokenFile,
                                                 final LicenseManagerClient lmClient) {
            this.lmClient = lmClient;
            this.request = request;
            this.webIdentityRefreshTokenFile = webIdentityRefreshTokenFile;
        }

        public AssumeRoleWithWebIdentityRequest get() {
            return this.request.toBuilder()
                    .webIdentityToken(getIdentityToken())
                    .build();
        }

        private String getIdentityToken() {
            return refreshIdToken(readRefreshToken(this.webIdentityRefreshTokenFile));
        }

        private String readRefreshToken(Path file) {
            try (InputStream webIdentityRefreshTokenStream = Files.newInputStream(file)) {
                return IoUtils.toUtf8String(webIdentityRefreshTokenStream);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        private String refreshIdToken(String licenseRefreshToken) {
            final GetAccessTokenRequest request = GetAccessTokenRequest.builder()
                    .token(licenseRefreshToken)
                    .build();

            GetAccessTokenResponse response = this.lmClient.getAccessToken(request);
            return response.accessToken();
        }
    }

    private static final class LicenseManagerClientFactory {
        private static final Duration DEFAULT_API_TIMEOUT = Duration.ofSeconds(30);
        private static final Duration DEFAULT_API_ATTEMPT_TIMEOUT = Duration.ofSeconds(10);

        public static LicenseManagerClient create() {
            return getLicenseManagerClient();
        }

        private static LicenseManagerClient getLicenseManagerClient() {
            ClientOverrideConfiguration configuration = ClientOverrideConfiguration.builder()
                    .apiCallTimeout(DEFAULT_API_TIMEOUT)
                    .apiCallAttemptTimeout(DEFAULT_API_ATTEMPT_TIMEOUT)
                    .build();

            LicenseManagerClient client = LicenseManagerClient.builder()
                    .region(configureLicenseManagerRegion())
                    .credentialsProvider(AnonymousCredentialsProvider.create())
                    .overrideConfiguration(configuration).build();
            return client;
        }

        private static Region configureLicenseManagerRegion() {
            Region defaultRegion = Region.US_EAST_1;

            Region region;
            try {
                region = (new DefaultAwsRegionProviderChain()).getRegion();
            } catch (RuntimeException ex) {
                region = defaultRegion;
            }
            return region;
        }
    }

    private static final class StsClientFactory {
        private static final Duration DEFAULT_API_TIMEOUT = Duration.ofSeconds(30);
        private static final Duration DEFAULT_API_ATTEMPT_TIMEOUT = Duration.ofSeconds(10);

        public static StsClient create() {
            return getStsClient();
        }

        private static StsClient getStsClient() {
            OrRetryCondition retryCondition = OrRetryCondition.create(new StsRetryCondition(),
                    RetryCondition.defaultRetryCondition());

            ClientOverrideConfiguration configuration = ClientOverrideConfiguration.builder()
                    .apiCallTimeout(DEFAULT_API_TIMEOUT)
                    .apiCallAttemptTimeout(DEFAULT_API_ATTEMPT_TIMEOUT)
                    .retryPolicy(r -> r.retryCondition(retryCondition))
                    .build();

            return StsClient.builder()
                    .region(configureStsRegion())
                    .credentialsProvider(AnonymousCredentialsProvider.create())
                    .overrideConfiguration(configuration).build();
        }

        private static Region configureStsRegion() {
            Region defaultRegion = Region.US_EAST_1;
            Region stsRegion;
            try {
                stsRegion = (new DefaultAwsRegionProviderChain()).getRegion();
            } catch (RuntimeException ex) {
                stsRegion = defaultRegion;
            }
            return stsRegion;
        }

        private static final class StsRetryCondition implements RetryCondition {
            public boolean shouldRetry(RetryPolicyContext context) {
                return context.exception() instanceof IdpCommunicationErrorException;
            }
        }
    }

    private enum LicenseSystemSetting implements SystemSetting {
        AWS_WEB_IDENTITY_REFRESH_TOKEN_FILE("aws.webIdentityRefreshTokenFile");

        private String systemProperty;
        private String defaultValue = null;

        LicenseSystemSetting(String systemProperty) {
            this.systemProperty = systemProperty;
        }

        @Override
        public String property() {
            return this.systemProperty;
        }

        @Override
        public String environmentVariable() {
            return this.name();
        }

        @Override
        public String defaultValue() {
            return this.defaultValue;
        }
    }
}
```

## `LicenseManagerCredentialsProvider`- implementazione `Golang`
<a name="container-license-manager-cred-provider-golang"></a>

**`LicenseCredentialsProvider`**

`LicenseCredentialsProvider`estende la catena di provider di credenziali predefinita dell' AWS SDK per l'uso in locale aggiungendo. `LicenseManagerTokenCredentialsProvider` 

```
package lib

import (
	"context"
	"fmt"
	"sync"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
)

// LicenseCredentialsProvider is the custom credential provider that can retrieve valid temporary aws credentials
type LicenseCredentialsProvider struct {
	fallBackProvider   aws.CredentialsProvider
	mux                sync.RWMutex
	licenseCredentials aws.Credentials
	err                error
}

// NewLicenseCredentialsProvider method will create a LicenseCredentialProvider Object which contains valid temporary aws credentials
func NewLicenseCredentialsProvider() (*LicenseCredentialsProvider, error) {
	licenseCredentialProvider := &LicenseCredentialsProvider{}
	fallBackProvider, err := createCredentialProvider()
	if err != nil {
		return licenseCredentialProvider, fmt.Errorf("failed to create LicenseCredentialsProvider, %w", err)
	}
	licenseCredentialProvider.fallBackProvider = fallBackProvider
	return licenseCredentialProvider, nil
}

// Retrieve method will retrieve temporary aws credentials from the credential provider
func (l *LicenseCredentialsProvider) Retrieve(ctx context.Context) (aws.Credentials, error) {
	l.mux.RLock()
	defer l.mux.RUnlock()
	l.licenseCredentials, l.err = l.fallBackProvider.Retrieve(ctx)
	return l.licenseCredentials, l.err
}

func createCredentialProvider() (aws.CredentialsProvider, error) {
	// LoadDefaultConfig will examine all "default" credential providers
	ctx := context.TODO()
	cfg, err := config.LoadDefaultConfig(ctx)
	if err != nil {
		return nil, fmt.Errorf("failed to create FallBackProvider, %w", err)
	}

	var useFallbackProvider bool
	if cfg.Credentials != nil {
		if _, err := cfg.Credentials.Retrieve(ctx); err != nil {
			// If the "default" credentials provider cannot retrieve credentials, enable fallback to customCredentialsProvider.
			useFallbackProvider = true
		}
	} else {
		useFallbackProvider = true
	}

	if useFallbackProvider {
		customProvider, err := newLicenseManagerTokenCredentialsProvider()
		if err != nil {
			return cfg.Credentials, fmt.Errorf("failed to create fallBackProvider, %w", err)
		}
		// wrap up customProvider with CredentialsCache to enable caching
		cfg.Credentials = aws.NewCredentialsCache(customProvider)
	}
	return cfg.Credentials, nil
}
```

**`LicenseManagerTokenCredentialsProvider`**

`LicenseManagerTokenCredentialsProvider`fornisce credenziali utilizzando token di identità emessi da License Manager OIDC in ambienti locali. È necessario includere il codice sorgente di nel percorso di classe dell'applicazione`LicenseCredentialsProvider`.

```
package lib

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"sync"
	"time"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/config"
	"github.com/aws/aws-sdk-go-v2/service/sts"
)

const awsRefreshTokenFilePathEnvVar = "AWS_LICENSE_ACCESS_FILE"

// licenseManagerTokenCredentialsProvider defines and contains StsAssumeRoleWithWebIdentityProvider
type licenseManagerTokenCredentialsProvider struct {
	stsCredentialProvider *stsAssumeRoleWithWebIdentityProvider
	mux                   sync.RWMutex
	licenseCredentials    aws.Credentials
	err                   error
}

// Retrieve method will retrieve credentials from credential provider.
// Make this method public to make this provider satisfies CredentialProvider interface
func (a *licenseManagerTokenCredentialsProvider) Retrieve(ctx context.Context) (aws.Credentials, error) {
	a.mux.RLock()
	defer a.mux.RUnlock()
	a.licenseCredentials, a.err = a.stsCredentialProvider.Retrieve(ctx)
	return a.licenseCredentials, a.err
}

// newLicenseManagerTokenCredentialsProvider will create and return a LicenseManagerTokenCredentialsProvider Object which wraps up stsAssumeRoleWithWebIdentityProvider
func newLicenseManagerTokenCredentialsProvider() (*licenseManagerTokenCredentialsProvider, error) {
	// 1. Retrieve variables From yaml environment
	envConfig, err := config.NewEnvConfig()
	if err != nil {
		return &licenseManagerTokenCredentialsProvider{}, fmt.Errorf("failed to create LicenseManagerTokenCredentialsProvider, %w", err)
	}
	roleArn := envConfig.RoleARN
	var roleSessionName string
	if envConfig.RoleSessionName == "" {
		roleSessionName = fmt.Sprintf("aws-sdk-go-v2-%v", time.Now().UnixNano())
	} else {
		roleSessionName = envConfig.RoleSessionName
	}
	tokenFilePath := os.Getenv(awsRefreshTokenFilePathEnvVar)
	b, err := ioutil.ReadFile(tokenFilePath)
	if err != nil {
		return &licenseManagerTokenCredentialsProvider{}, fmt.Errorf("failed to create LicenseManagerTokenCredentialsProvider, %w", err)
	}
	refreshToken := aws.String(string(b))

	// 2. Create stsClient
	cfg, err := config.LoadDefaultConfig(context.TODO())
	if err != nil {
		return &licenseManagerTokenCredentialsProvider{}, fmt.Errorf("failed to create LicenseManagerTokenCredentialsProvider, %w", err)
	}
	stsClient := sts.NewFromConfig(cfg, func(o *sts.Options) {
		o.Region = configureStsClientRegion(cfg.Region)
		o.Credentials = aws.AnonymousCredentials{}
	})

	// 3. Configure StsAssumeRoleWithWebIdentityProvider
	stsCredentialProvider := newStsAssumeRoleWithWebIdentityProvider(stsClient, roleArn, roleSessionName, refreshToken)

	// 4. Build and return
	return &licenseManagerTokenCredentialsProvider{
		stsCredentialProvider: stsCredentialProvider,
	}, nil
}

func configureStsClientRegion(configRegion string) string {
	defaultRegion := "us-east-1"
	if configRegion == "" {
		return defaultRegion
	} else {
		return configRegion
	}
}
```