

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Integrações de faturamento, medição e licenciamento de produtos de contêiner
<a name="container-products-billing-integration"></a>

AWS Marketplace se integra a outros Serviços da AWS para fornecer preços baseados em medição e contrato para seu produto de contêiner. Para produtos de contêiner com preços por uso, use o [AWS Marketplace Metering Service](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html) para verificar a autorização a usar seu produto e para medir o uso para faturamento. Para produtos baseados em contêineres com preços contratuais, você pode usar o AWS License Manager para associar licenças ao seu produto. As seções a seguir fornecem mais informações sobre medição por hora e personalizada AWS Marketplace Metering Service e preços de contratos com AWS License Manager.

**Topics**
+ [Medição horária e personalizada com AWS Marketplace Metering Service](#entitlement-and-metering-for-paid-products)
+ [Contrate preços com AWS License Manager](#container-products-contracts-license-manager)
+ [Configurar a medição de hora em hora com o Serviço de medição do AWS Marketplace](container-metering-registerusage.md)
+ [Configurar a medição personalizada para produtos de contêineres com o Serviço de medição do AWS Marketplace](container-metering-meterusage.md)
+ [Preços contratuais para produtos em contêineres com AWS License Manager](container-license-manager-integration.md)

## Medição horária e personalizada com AWS Marketplace Metering Service
<a name="entitlement-and-metering-for-paid-products"></a>

Use o [Serviço de medição do AWS Marketplace](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html) para verificar o direito de usar seu produto e para medir o uso para faturamento. Se você quiser definir suas próprias unidades de preço e medir esse uso para faturamento, integre usando a operação de [MeterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html)API. Se você quiser precificar seu produto com base no número de tarefas ou pods usados e AWS medir esse uso automaticamente, faça a integração usando a operação da [RegisterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_RegisterUsage.html)API. Para ambos os tipos de definição de preço, é possível adicionar um preço de contrato em longo prazo sem alterar a forma como você se integra ao AWS Marketplace Metering Service.

Quando você cria um novo produto de contêiner no Portal de gerenciamento do AWS Marketplace, fornecemos um conjunto de identificadores de produto (o código do produto e a chave pública) que são usados para integrar seu produto ao AWS Marketplace Metering Service.

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

A integração com o AWS Marketplace Metering Service permite que você verifique se o cliente que executa seu software pago está inscrito em seu produto AWS Marketplace, protegendo você contra o uso não autorizado na inicialização do contêiner. Para verificar a titularidade, use as operações de [RegisterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_RegisterUsage.html)API [MeterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html)ou de acordo com seu modelo de preços. Para modelos de definição de preço por hora e mensais fixos, use a operação de API `RegisterUsage`. Para modelos de definição de preço de medição personalizados, use a operação de API `MeterUsage`.

Se um comprador não tiver direito ao seu produto, essas operações de API retornarão a exceção `CustomerNotEntitledException`.

**nota**  
Se um comprador cancelar a assinatura do produto durante a execução, ele terá o direito de continuar a executá-lo. No entanto, ele não poderá iniciar contêineres adicionais para o produto.

### Diretrizes de integração
<a name="integration-guidelines"></a>

Ao criar e publicar os produtos de contêiner e usar as operações de API `MeterUsage` ou `RegisterUsage` para obter autorização e medição, tenha em mente as seguintes diretrizes.
+ Não configure AWS credenciais em seu software ou na imagem do contêiner Docker. AWS as credenciais do comprador são obtidas automaticamente em tempo de execução quando a imagem do contêiner está sendo executada em uma tarefa do Amazon ECS ou em um pod do Amazon EKS.
+  Para chamar as operações `MeterUsage` ou de `RegisterUsage` API do Amazon EKS, você deve [usar um AWS SDK compatível](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html). Para testar a integração do `MeterUsage` ou `RegisterUsage` ao Amazon EKS, é necessário executar um cluster do Amazon EKS em execução no Kubernetes 1.13.x ou posterior. O Kubernetes 1.13 é necessário para funções AWS Identity and Access Management (IAM) de suporte a pods. As funções do IAM são necessárias para que o pod em execução obtenha AWS as credenciais necessárias para invocar essas ações no Amazon EKS. 
+ É possível fazer uma implantação local, mas receberá uma exceção `PlatformNotSupportedException`. Essa exceção não ocorrerá quando você iniciar o contêiner em serviços de AWS contêiner (Amazon ECS, Amazon EKS e Fargate).

### Suportado Regiões da AWS
<a name="supported-regions-metering"></a>

Para obter uma lista de todos os AWS Marketplace compatíveis Regiões da AWS, consulte a [tabela de regiões](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/) no site da infraestrutura global.

#### Obtendo o Região da AWS para medição
<a name="metering-aws-region-configuration"></a>

Ao integrar seu contêiner para medição com a operação `MeterUsage` ou a `RegisterUsage` API, não configure o AWS SDK para usar uma operação específica. Região da AWS A região deve ser obtida dinamicamente em runtime. 

**Example**  
Por exemplo, um cliente executa uma tarefa do Amazon ECS ou um pod do Amazon EKS. A operação de API `RegisterUsage` é chamada em uma região diferente da região em que a tarefa do Amazon ECS ou o pod do Amazon EKS foi executado. Portanto, a operação de API `RegisterUsage` gera um erro `InvalidRegionException`.



AWS As linguagens do SDK não determinam o de `AWS_REGION` maneira consistente. Se o SDK não captar automaticamente a `AWS_REGION`, o software precisará ser escrito manualmente para determinar a `AWS_Region`. Por exemplo, o AWS SDK para Java usa automaticamente os [Metadados de instâncias do Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html) (especificamente, `ec2InstanceMetadata`) para obter a região quando variáveis de ambiente ou outras configurações não estiverem presentes. Nessa instância, chame somente `ec2InstanceMetadata` se a variável de ambiente `AWS_REGION` não estiver presente.

Para obter informações sobre como obter dinamicamente um Região da AWS at runtime, consulte o [Guia do desenvolvedor do AWS SDK](https://aws.amazon.com/tools) para sua linguagem de programação.

### Impedir a modificação da medição
<a name="prevent-metering-modification"></a>

Apresentar formas para os compradores modificarem ou substituírem chamadas para `RegisterUsage` ou `MeterUsage` poderá resultar em problemas indesejáveis de faturamento e pagamento. É altamente recomendável que você integre a lógica de medição e de autorização.

Ao projetar seu produto para evitar a modificação da medição, tenha em mente o seguinte:
+ Se os compradores puderem inserir novas camadas de imagem que contenham instruções `CMD` ou `ENTRYPOINT`, integre `RegisterUsage` ou `MeterUsage` diretamente no software que o comprador está executando por meio da imagem do contêiner. Caso contrário, as chamadas para `RegisterUsage` ou `MeterUsage` executadas por `CMD` ou `ENTRYPOINT` usando a imagem base provavelmente serão substituídas pelo comprador.
+ Recomendamos que você gerencie os códigos de AWS Marketplace produto que seu software usa como entrada `RegisterUsage` ou de uma `MeterUsage` forma que os compradores não possam modificar. *No entanto, se seu produto gerencia códigos de produto de uma forma que os clientes possam substituir AWS CloudFormation, como o gráfico do Helm ou o manifesto do Kubernetes, você deverá manter uma lista de códigos de produto confiáveis.* AWS Marketplace Isso é para garantir que o código do produto que seu software passa como entrada `RegisterUsage` ou `MeterUsage` seja válido.
+  Se algum dos códigos de produto confiáveis for de produtos gratuitos, garanta que eles não possam ser usados no lugar de um código do produto pago.

## Contrate preços com AWS License Manager
<a name="container-products-contracts-license-manager"></a>

Para produtos baseados em contêineres com preços contratuais, você costuma AWS License Manager associar licenças ao seu produto. 

AWS License Manager é uma ferramenta de gerenciamento de licenças que permite que seu aplicativo rastreie e atualize licenças (também conhecidas como direitos) que foram adquiridas por um cliente. Esta seção fornece informações sobre como integrar seu produto ao AWS License Manager. Depois que a integração for concluída, você poderá publicar sua lista de produtos no AWS Marketplace.

Para obter mais informações sobre AWS License Manager, consulte o [Guia AWS License Manager do usuário](https://docs.aws.amazon.com/license-manager/latest/userguide/license-manager.html) e a [AWS License Manager](https://docs.aws.amazon.com/cli/latest/reference/license-manager/index.html)seção da *Referência de AWS CLI comandos*.

**nota**  
Os clientes não podem executar novas instâncias do contêiner após o período de expiração do contrato. No entanto, durante a vigência do contrato, eles podem executar qualquer número de instâncias. Essas licenças não estão vinculadas a um nó ou uma instância específica. Qualquer software executado em qualquer contêiner em qualquer nó pode fazer o checkout da licença, desde que tenha as credenciais da AWS atribuídas.
**Criação de oferta privada**: os vendedores podem gerar ofertas privadas para os produtos usando a ferramenta de criação de ofertas privadas no Portal de gerenciamento do AWS Marketplace.
**Relatórios**: você pode configurar feeds de dados configurando um bucket do Amazon S3 na seção **Relatório** no Portal de gerenciamento do AWS Marketplace. Para obter mais informações, consulte [Relatórios de vendedores, feeds de dados e painéis em AWS Marketplace](reports-and-data-feed.md).

### Fluxo de trabalho de integração
<a name="container-LM-LM-workflow"></a>

As etapas a seguir mostram o fluxo de trabalho para integrar seu produto de contêiner ao AWS License Manager:

1. O vendedor cria um produto com AWS License Manager integração.

1. O vendedor lista o produto em AWS Marketplace.

1. O comprador encontra o produto AWS Marketplace e o compra.

1. Uma licença é enviada para a Conta da AWS do comprador.

1. O comprador usa o software executando a instância do Amazon EC2, a tarefa do Amazon ECS ou o software pod do Amazon EKS. O cliente implanta usando um perfil do IAM.

1. O software lê a licença na AWS License Manager conta do comprador, descobre os direitos adquiridos e provisiona os recursos adequadamente. 
**nota**  
O License Manager não faz nenhum rastreamento ou atualização; isso é feito pelo aplicativo do vendedor.

# Configurar a medição de hora em hora com o Serviço de medição do AWS Marketplace
<a name="container-metering-registerusage"></a>

**nota**  
 Para implantações do Amazon EKS, o software deve usar [perfis do IAM para contas de serviço (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) a fim de assinar a chamada de API para a operação da 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). Usando a [Identidade de Pods do EKS](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html), a função de nó ou as chaves de acesso de longo prazo não são compatíveis.  
Para implantações do Amazon ECS, o software deve usar o [perfil do IAM de tarefa do Amazon ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html) para assinar a chamada de API da operação da 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). O uso da função de nó ou das chaves de acesso de longo prazo não é compatível.

Se o produto de contêiner usar a definição de preço por tarefa ou pod por hora em vez de dimensões personalizadas de definição de preço por medição, você não precisará definir dimensões de medição personalizadas. Você pode usar o AWS Marketplace Metering Service para medição personalizada para produtos de contêineres no AWS Marketplace. As seções a seguir mostram como configurar a medição horária com o Serviço de medição do AWS Marketplace.

A operação de API `RegisterUsage` mede o uso do software por tarefa do Amazon Elastic Container Service (Amazon ECS) ou por pod do Amazon Elastic Kubernetes Service (Amazon EKS), por hora, com o uso proporcional ao segundo. Pelo menos 1 minuto de uso se aplica a tarefas ou pods que tenham curta duração. A medição contínua para uso do software é feita automaticamente pelo. AWS Marketplace Metering Control Plane O software não precisa realizar ações específicas de medição, exceto chamar `RegisterUsage` uma vez para medição do uso de software para iniciar.

`RegisterUsage` deve ser chamado imediatamente no momento de execução de um contêiner. Se você não registrar o contêiner nas primeiras 6 horas após a execução do contêiner, o Serviço de medição do AWS Marketplace não fornecerá nenhuma garantia de medição dos meses anteriores. No entanto, a medição continuará durante o mês atual até que o contêiner termine.

A AWS Marketplace Metering Control Plane continua cobrando dos clientes pela execução de tarefas do Amazon ECS e pods do Amazon EKS, independentemente do estado da assinatura do cliente. Isso elimina a necessidade de o software realizar verificações de direitos após a execução inicial bem-sucedida da tarefa ou do pod. 

Para obter mais informações sobre a integração AWS Marketplace Metering Service da API com produtos de contêineres com preços por hora, consulte o workshop [Integrar com medição horária](https://catalog.workshops.aws/mpseller/en-US/container/integrate-hourly) do *AWS Marketplace vendedor*. 

**Topics**
+ [Pré-requisitos de medição por hora](#hourly-metering-prereqs)
+ [Teste da integração para `RegisterUsage`](#testing-integration-for-registerusage)
+ [Tratar erros no `RegisterUsage`](#hourly-metering-entitlement-error-handling)
+ [Integrando seu produto de contêiner com o AWS Marketplace Metering Service usando o AWS SDK para Java](java-integration-example-registerusage.md)

## Pré-requisitos de medição por hora
<a name="hourly-metering-prereqs"></a>

Antes de publicar o produto, você deve fazer o seguinte:

1. Crie um novo produto de contêiner no Portal de gerenciamento do AWS Marketplace e anote o código do produto.

   Para obter mais informações, consulte [Visão geral: crie um produto em contêiner](container-product-getting-started.md#create-container-product).

1. Use uma função AWS Identity and Access Management (IAM) para a tarefa ou o pod que executa seu aplicativo com as permissões do IAM necessárias para chamar`RegisterUsage`. A política `AWSMarketplaceMeteringRegisterUsage` gerenciada pelo IAM tem essas permissões. Para obter mais informações sobre a política, consulte [ AWSMarketplaceMeteringFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSMarketplaceMeteringFullAccess.html)na *Referência de política AWS gerenciada*.

1. (Opcional) Se você quiser ver o registro, recomendamos que você habilite o AWS CloudTrail login na definição de tarefa ou pod.

1. Faça uma chamada de teste para a operação de API `RegisterUsage` com um registro para todas as dimensões de preço definidas.

## Teste da integração para `RegisterUsage`
<a name="testing-integration-for-registerusage"></a>

Use a operação `RegisterUsage` da API para testar sua integração antes de enviar sua imagem AWS Marketplace para publicação.

Chame `RegisterUsage` na imagem de contêiner executando o produto no Amazon ECS ou no Amazon EKS. Use a AWS conta que você está usando para publicar o produto AWS Marketplace. Sua integração de medição deve configurá-la dinamicamente Região da AWS, em vez de codificá-la. No entanto, ao testar, execute pelo menos uma tarefa do Amazon ECS ou pod do Amazon EKS com o contêiner pago na região Leste dos EUA (Norte da Virgínia). Ao fazer isso, a equipe de AWS Marketplace operações pode verificar seu trabalho com os registros dessa região.

**nota**  
Se o produto oferecer suporte ao Amazon ECS e ao Amazon EKS, você só precisará executar no Amazon EKS para que possamos validar sua integração.

Não é possível testar totalmente a integração até o produto ser publicado com todos os metadados e informações de definição de preço necessários. Se solicitado, a equipe de operações do AWS Marketplace catálogo pode verificar o recebimento de seus registros de medição.

## Tratar erros no `RegisterUsage`
<a name="hourly-metering-entitlement-error-handling"></a>

Se a imagem do contêiner se integrar ao AWS Marketplace Metering Service e receber uma exceção que não seja `ThrottlingException` na inicialização do contêiner, você deverá encerrar o contêiner para evitar o uso não autorizado.

As exceções diferentes de `ThrottlingException` são lançadas somente na chamada inicial para a operação de API `RegisterUsage`. As chamadas subsequentes da mesma tarefa do Amazon ECS ou pod do Amazon EKS não lançarão `CustomerNotSubscribedException`, mesmo se o cliente cancelar a assinatura com a tarefa ou o pod ainda em execução. Esses clientes ainda são cobrados pela execução de contêineres depois de cancelarem a assinatura e seu uso for rastreado.

A tabela a seguir descreve os erros que a operação de API `RegisterUsage` pode lançar. Cada linguagem de programação do AWS SDK tem um conjunto de diretrizes de tratamento de erros que você pode consultar para obter informações adicionais. 


|  **Erro**  |  **Descrição**  | 
| --- | --- | 
|  InternalServiceErrorException  |  RegisterUsage não está disponível.  | 
|  CustomerNotEntitledException  |  O cliente não tem uma assinatura válida para o produto.  | 
|  InvalidProductCodeException  |  O valor ProductCode passado como parte da solicitação não existe.  | 
|  InvalidPublicKeyException  |  O valor PublicKeyVersion passado como parte da solicitação não existe.  | 
|  PlatformNotSupportedException  |  AWS Marketplace não suporta o uso de medição da plataforma subjacente. Somente o Amazon ECS, o Amazon EKS e o Amazon EKS AWS Fargate são compatíveis.  | 
|  ThrottlingException  |  As chamadas para RegisterUsage são limitadas.  | 
|  InvalidRegionException  |  RegisterUsagedeve ser chamada da mesma forma em Região da AWS que a tarefa do Amazon ECS ou o pod do Amazon EKS foi lançado. Isso evita que um contêiner escolha uma região (por exemplo, withRegion(“us-east-1”)) ao chamar RegisterUsage.  | 

# Integrando seu produto de contêiner com o AWS Marketplace Metering Service usando o AWS SDK para Java
<a name="java-integration-example-registerusage"></a>

Você pode usar o AWS SDK para Java para se integrar ao AWS Marketplace Metering Service. A medição contínua para uso do software é feita automaticamente pelo. AWS Marketplace Metering Control Plane O software não precisa realizar ações específicas de medição, exceto chamar `RegisterUsage` uma vez para medição do uso de software para iniciar. Este tópico fornece um exemplo de implementação usando o AWS SDK para Java para integrar com a `RegisterUsage` ação do [AWS Marketplace Metering Service](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html). 

`RegisterUsage` deve ser chamado imediatamente no momento de execução de um contêiner. Se você não registrar o contêiner nas primeiras 6 horas após a execução do contêiner, o Serviço de medição do AWS Marketplace não fornecerá nenhuma garantia de medição dos meses anteriores. No entanto, a medição continuará durante o mês atual até que o contêiner termine.

Para obter o código-fonte completo, consulte [RegisterUsage Exemplo de Java](#registerusage-java-example). Muitas dessas etapas se aplicam independentemente da linguagem do AWS SDK. 



**Exemplos de etapa para a integração do Serviço de medição do AWS Marketplace**

1. Faça login no [Portal de gerenciamento do AWS Marketplace](https://aws.amazon.com/marketplace/management/tour).

1. Em **Assets (Ativos)**, selecione **Containers (Contêineres)** para começar a criar um produto de contêiner. A criação do produto gera o código para a integração do produto com a imagem de contêiner. Para obter mais informações sobre configuração de permissões do IAM, consulte [AWS Marketplace permissões da API de medição e titulação](iam-user-policy-for-aws-marketplace-actions.md).

1.  Faça download do [SDK do AWS Java](https://aws.amazon.com/sdk-for-java/) público. 
**Importante**  
 Para chamar a medição APIs do Amazon EKS, você deve [usar um AWS SDK compatível e executar em um](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html) cluster do Amazon EKS executando o Kubernetes 1.13 ou posterior. 

1.  (Opcional) Se você estiver se integrando à `RegisterUsage` ação e quiser realizar a verificação de assinatura digital, precisará configurar a biblioteca de verificação de [BouncyCastle](https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on)assinatura no caminho de classe do seu aplicativo.

   Se quiser usar JSON Web Token (JWT), você também deverá incluir bibliotecas [JWT Java](https://jwt.io/) no caminho de classe do aplicativo. O uso do JWT fornece uma abordagem mais simples para a verificação de assinaturas, mas não é obrigatório. Em vez disso, você pode usar o modo autônomo BouncyCastle . Se você usa o JWT ou BouncyCastle precisa usar um sistema de compilação como o Maven para incluir dependências transitivas do BouncyCastle ou do JWT no caminho de classe do seu aplicativo.

   ```
   // 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.  Chame `RegisterUsage` de cada imagem de contêiner paga na oferta do produto. `ProductCode` e `PublicKeyVersion` são parâmetros obrigatórios, e todas as outras entradas são opcionais. Esta é uma carga útil de exemplo para `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**  
É possível ver problemas transitórios na conexão com o Serviço de medição do AWS Marketplace. O AWS Marketplace recomenda fortemente a implementação de novas tentativas por até 30 minutos, com recuo exponencial, para evitar interrupções de curto prazo ou problemas de rede.

1.  `RegisterUsage` gera uma assinatura digital RSA-PSS usando SHA-256 que é possível usar para verificar a autenticidade da solicitação. A assinatura inclui os seguintes campos: `ProductCode`, `PublicKeyVersion` e `Nonce`. Para verificar a assinatura digital, você deve manter esses campos da solicitação. Este código é uma resposta de exemplo para uma chamada `RegisterUsage`. 

   ```
   {
   "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. Recompile uma nova versão da imagem de contêiner que inclua a chamada `RegisterUsage`, marque o contêiner e o envie para qualquer registro que seja compatível com o Amazon ECS ou o Amazon EKS, como o Amazon ECR ou o Amazon ECR Public. Se você estiver usando o Amazon ECR, verifique se a conta que executa a tarefa do Amazon ECS ou o pod do Amazon EKS tem permissões no repositório do Amazon ECR. Caso contrário, ocorrerá uma falha na inicialização.

1.  Crie um perfil do [IAM](https://aws.amazon.com/iam/) que conceda permissão para o contêiner chamar `RegisterUsage`, conforme definido no código a seguir. Forneça esse perfil do IAM no parâmetro [Função da tarefa](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_role_arn) da definição de tarefa do Amazon ECS ou de pod do Amazon EKS.

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

****  

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

------

1. Crie uma tarefa do Amazon ECS ou uma definição de pod do Amazon EKS que faça referência ao contêiner que se integrou AWS Marketplace e faça referência à função do IAM que você criou na etapa 7. Você deve habilitar o AWS CloudTrail registro na definição da tarefa se quiser ver o registro. 

1. Crie um cluster do Amazon ECS ou Amazon EKS para executar sua tarefa ou pod. Para obter mais informações sobre como criar um cluster do Amazon ECS, consulte [Criar um cluster](https://docs.aws.amazon.com/AmazonECS/latest/userguide/create_cluster.html) no *Guia do desenvolvedor do Amazon Elastic Container Service*. Para obter mais informações sobre como criar um cluster do Amazon EKS (usando o Kubernetes versão 1.1.3.x ou posterior), consulte [Criar um cluster do Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/create_cluster.html).

1. Configure o cluster Amazon ECS ou Amazon EKS e inicie a definição de tarefa do Amazon ECS ou o pod Amazon EKS que você criou, no us-east-1. Região da AWSÉ somente durante este processo de teste, antes de o produto estar ativo, que você precisa usar essa região.

1. Você pode começar a criar seu produto de contêiner assim que obtiver uma resposta válida de `RegisterUsage`. Se tiver dúvidas, entre em contato com a equipe de [Operações do vendedor do AWS Marketplace](https://aws.amazon.com/marketplace/management/contact-us/). 

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

O exemplo a seguir usa o AWS SDK para Java e AWS Marketplace Metering Service para chamar a `RegisterUsage` operação. A verificação de assinatura é opcional, mas se quiser executar a verificação de assinatura, você deverá incluir as bibliotecas de verificação de assinatura digital obrigatórias. Esse exemplo é apenas para fins de ilustração. 

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

# Configurar a medição personalizada para produtos de contêineres com o Serviço de medição do AWS Marketplace
<a name="container-metering-meterusage"></a>

**nota**  
 Para implantações do Amazon EKS, o software deve usar [perfis do IAM para contas de serviço (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) a fim de assinar a chamada de API para a operação da 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). Usando a [Identidade de Pods do EKS](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html), a função de nó ou as chaves de acesso de longo prazo não são compatíveis.  
Para implantações do Amazon ECS, o software deve usar o [perfil do IAM de tarefa do Amazon ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task-iam-roles.html) para assinar a chamada de API da operação da 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). O uso da função de nó ou das chaves de acesso de longo prazo não é compatível.  
Para implantações do Amazon Bedrock AgentCore Runtime, seu software deve usar a [função AgentCore de execução do Runtime](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-permissions.html#runtime-permissions-execution) para assinar a chamada de API para a operação da [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. As chaves de acesso de longo prazo não são compatíveis.

AWS Marketplace os produtos de contêiner podem ter medição personalizada em até 24 dimensões de preços diferentes por produto. Cada dimensão pode ter um preço de contrato em longo prazo associada a ela. Para habilitar a medição personalizada, integre seu produto de contêiner ao Serviço de medição do AWS Marketplace. Você pode definir suas próprias unidades de preço e medição personalizada para esse uso ou AWS para faturamento usando a operação da [https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html)API. As seções a seguir mostram como configurar a medição personalizada para seu produto de contêiner.

As dimensões de preço são definidas em dois locais, uma vez durante a criação do produto no Portal de gerenciamento do AWS Marketplace (portal do vendedor) e uma vez no software para realizar a operação de `MeterUsage`. Esse método de dois fatores garante que as ofertas subsequentes estejam funcionando conforme pretendido antes de ficarem disponíveis para o público.

Para configurar a medição personalizada, será necessário escolher a categoria de uso, o tipo de unidade e as dimensões de definição de preço. 
+ **Categoria de uso**: a categoria ajuda os compradores a entender o que é o produto e como usá-lo. 
+ **Tipo de unidade**: o tipo de unidade define a unidade de medida para faturamento. Por exemplo, largura de banda medida em GBps ou MBps, o número de hosts ou dados medidos em MB, GB ou TB.
+ **Dimensões de preços** — As dimensões de preços representam um recurso ou serviço para o qual você definiu um preço unitário (por exemplo, usuários, escaneamentosCPUs, v ou agentes implantados). As dimensões de preços são públicas. No entanto, você ainda pode definir ofertas privadas e Traga a sua própria licença (BYOL) para produtos públicos. Não envie a definição de preço nos registros de medição. Você mede a quantidade de unidades, e nós usamos isso com os preços definidos na criação do produto para calcular a fatura do comprador. 

  Se a definição de preço do produto não se adequar a nenhuma categoria predefinida ou a nenhum tipo de unidade, você poderá escolher a categoria genérica **Unidades**. Em seguida, use a descrição da dimensão para descrever qual é a unidade.

Se desejar, você pode distribuir o uso em alocações por propriedades rastreadas. As alocações são representadas como tags para o comprador. Essas tags permitem que o comprador visualize os custos divididos em uso por valores de tag. Por exemplo, se você cobrar pelo usuário e os usuários tiverem uma propriedade “Departamento”, será possível criar alocações de uso com tags que tenham uma chave de “Departamento” e uma alocação por valor. Isso não altera o preço, as dimensões ou o uso total que você relata, mas permite que seu cliente visualize os custos por categorias apropriadas ao seu produto.

Recomendamos que você envie um registro de medição a cada hora. No entanto, você também pode agregar o uso em períodos diários ou mensais. Se ocorrer uma interrupção, você poderá agregar o uso do software do comprador e enviá-lo nas próximas horas de medição. Não é possível enviar mais de um registro por hora.

*Para obter mais informações sobre a integração AWS Marketplace Metering Service da API para produtos de contêineres com preços de medição personalizados, consulte o laboratório de [integração com medição personalizada](https://catalog.workshops.aws/mpseller/en-US/container/integrate-custom) do workshop do AWS Marketplace vendedor.*

**Importante**  
A avaliação gratuita e o direito pré-pago são monitorados de hora em hora. Como resultado, enviar esses registros separadamente pode fazer com que o comprador seja cobrado a mais.

**Topics**
+ [Pré-requisitos de medição personalizada](#custom-metering-prereqs)
+ [Teste de integração de `MeterUsage` para ECS e EKS](#testing-meterusage-integration)
+ [Testando MeterUsage a integração para AgentCore](#testing-agentcore-metering)
+ [Tratar erros no `MeterUsage`](#custom-metering-entitlement-error-handling)
+ [(Opcional) Marcação medida pelo fornecedor](#container-vendor-metered-tagging)
+ [Exemplo de código](#container-meter-code-example)
+ [Integrando seu produto de contêiner usando medição personalizada com o e AWS Marketplace Metering Service AWS SDK para Java](java-integration-example-meterusage.md)

## Pré-requisitos de medição personalizada
<a name="custom-metering-prereqs"></a>

Antes de publicar o produto, você deve fazer o seguinte:

1. Crie um novo produto de contêiner no Portal de gerenciamento do AWS Marketplace e anote o código do produto.

1. Use uma função AWS Identity and Access Management (IAM) para a tarefa, o pod ou o endpoint AgentCore de tempo de execução que executa seu aplicativo com as permissões do IAM necessárias para chamar`MeterUsage`. A política `AWSMarketplaceMeteringRegisterUsage` gerenciada pelo IAM tem essas permissões. Para obter mais informações sobre a política, consulte [ AWSMarketplaceMeteringFullAccess](https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AWSMarketplaceMeteringFullAccess.html)na *Referência de política AWS gerenciada*.

1. (Opcional) Recomendamos que você ative o AWS CloudTrail login na definição de tarefa ou pod se quiser ver o registro.

1. Faça uma chamada de teste para a operação de API `MeterUsage` com um registro para todas as dimensões de preço definidas.

## Teste de integração de `MeterUsage` para ECS e EKS
<a name="testing-meterusage-integration"></a>

Use a `MeterUsage` operação para testar sua integração antes de enviar sua imagem AWS Marketplace para publicação.

Ligue a `MeterUsage` partir das imagens do contêiner executando seu produto no Amazon Elastic Container Service (Amazon ECS) ou no Amazon Elastic Kubernetes Service (Amazon EKS Conta da AWS ) com o que você usa para publicar o produto. AWS Marketplace Sua integração de medição deve configurá-la dinamicamente Região da AWS, em vez de codificá-la. No entanto, ao testar, inicie pelo menos uma tarefa do Amazon ECS ou pod do Amazon EKS contendo seu contêiner pago na região Leste dos EUA (Norte da Virgínia) para que a equipe de AWS Marketplace operações possa verificar seu trabalho com os registros dessa região.

**nota**  
Se o produto oferecer suporte ao Amazon ECS e ao Amazon EKS, você só precisará executar no Amazon EKS para que possamos validar sua integração.
Teste todas as dimensões antes de lançar seu produto ao público e depois de adicionar uma nova dimensão. Se você não enviar um registro de medição para cada dimensão associada a um produto de contêiner, isso resultará em um erro com a falha da solicitação.

Não é possível testar totalmente a integração até o produto ser publicado com todos os metadados e informações de definição de preço necessários. Se solicitado, a equipe de operações do AWS Marketplace catálogo pode verificar o recebimento de seus registros de medição.

## Testando MeterUsage a integração para AgentCore
<a name="testing-agentcore-metering"></a>

Use a `MeterUsage` operação para testar sua integração antes de enviar sua imagem AWS Marketplace para publicação.

Ligue a `MeterUsage` partir das imagens do contêiner executando seu produto no Amazon Bedrock AgentCore com a AWS conta que você usa para publicar o produto. AWS Marketplace Sua integração de medição deve definir dinamicamente a AWS região, em vez de codificá-la. No entanto, ao testar, inicie pelo menos um AgentCore agente do Amazon Bedrock contendo seu contêiner pago na região Leste dos EUA (Norte da Virgínia) para que a equipe de AWS Marketplace operações possa verificar seu trabalho com os registros dessa região. 

 Você não precisa agregar registros de uso por hora. Chame `MeterUsage` em cada invocação de atendente com o uso dessa invocação.

Você deve usar a versão mais recente do AWS SDK para seu idioma. Isso preenche automaticamente o parâmetro `ClientToken` com um valor gerado automaticamente para ajudar na idempotência. Versões anteriores do SDK que não preencherem esse campo não funcionarão para `MeterUsage` chamadas de dentro do Amazon Bedrock. AgentCore Por causa de um problema de rede, você deve reutilizar exatamente a mesma solicitação ao tentar novamente. Isso garante que as solicitações sejam tratadas com idempotência.

Devido às diferenças no comportamento esperado de medição entre o Amazon Bedrock AgentCore e outros produtos de contêiner, não recomendamos compartilhar a mesma imagem de contêiner para uso no Amazon Bedrock e AgentCore no Amazon ECS ou EKS.

## Tratar erros no `MeterUsage`
<a name="custom-metering-entitlement-error-handling"></a>

Chame `MeterUsage` que define o parâmetro `DryRun` como verdadeiro na startup de contêiner para validar se a integração da medição está funcionando. Se a imagem de contêiner se integrar à operação `MeterUsage` e receber uma exceção diferente de `ThrottlingException` na inicialização do contêiner, você deverá encerrar a imagem de contêiner para evitar uso não autorizado.

As exceções diferentes de `ThrottlingException` são lançadas somente na chamada inicial para `MeterUsage`. As chamadas subsequentes da mesma tarefa do Amazon ECS, pod ou endpoint do Amazon EKS AgentCore Runtime não são enviadas`CustomerNotSubscribedException`, mesmo que o cliente cancele a assinatura enquanto a tarefa ou o pod ainda estão em execução. Esses clientes continuarão sendo cobrados pela execução de contêineres depois de cancelarem a assinatura e o uso for rastreado.

Consulte [MeterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html)a *Referência da AWS Marketplace Metering Service API* para obter descrições detalhadas dos erros comuns de`MeterUsage`. Cada linguagem de programação do AWS SDK tem um conjunto de diretrizes de tratamento de erros que você pode consultar para obter informações adicionais. 

## (Opcional) Marcação medida pelo fornecedor
<a name="container-vendor-metered-tagging"></a>

A marcação medida pelo fornecedor ajuda os fornecedores independentes de software (ISVs) a fornecer ao comprador uma visão mais granular sobre o uso do software e pode ajudá-lo a realizar a alocação de custos.

**nota**  
A marcação medida pelo fornecedor não é suportada para solicitações de medição de produtos Amazon Bedrock. AgentCore 

Você tem diversas maneiras de identificar o uso do software do comprador. Uma é primeiro perguntar aos compradores o que eles querem ver na alocação de custos. Em seguida, você pode dividir o uso entre as propriedades rastreadas para a conta do comprador. Exemplos de propriedades incluem `AccountId`, `Business Unit`, `Cost Centers` e outros metadados relevantes para seu produto. Essas propriedades são expostas ao comprador como tags. Usando tags, os compradores podem ver seus custos divididos em uso pelos valores das tags em seu console de AWS faturamento ([https://console.aws.amazon.com/costmanagement/](https://console.aws.amazon.com/costmanagement/)). A marcação medida pelo fornecedor não altera o preço, as dimensões ou o uso total que você relata. Ela permite que o cliente visualize os custos por categorias apropriadas ao seu produto.

Em um caso de uso comum, um comprador assina seu produto com uma Conta da AWS. O comprador também tem vários usuários associados à mesma assinatura do produto. Você pode criar alocações de uso com tags que tenham uma chave de `AccountId` e, em seguida, alocar o uso para cada usuário. Nesse caso, os compradores podem ativar a tag `AccountId` no console do Billing and Cost Management e analisar o uso individual do usuário.

### Experiência do vendedor
<a name="container-vendor-metered-tag-seller"></a>

Os vendedores podem agregar os registros de medição dos recursos com o mesmo conjunto de tags em vez de agregar o uso de todos os recursos. Por exemplo, os vendedores podem construir o registro de medição que inclui buckets `UsageAllocations` diferentes. Cada bucket representa `UsageQuantity` para um conjunto de tags, como `AccountId` e `BusinessUnit`. 

No diagrama a seguir, o **Recurso 1** tem um conjunto exclusivo de tags `AccountId` e `BusinessUnit` e aparece no **Registro de medição** como uma única entrada. 

O **Recurso 2** e o **Recurso 3** têm a mesma tag `AccountId`, `2222`, e a mesma tag `BusinessUnit`, `Operations`. Como resultado, eles são combinados em uma única entrada `UsageAllocations` no **Registro de medição**.

![\[Diagrama que mostra como as tags de medição do fornecedor combinam os dados de uso. Três recursos (Recursos 1, 2 e 3) diferentes AccountIds e BusinessUnits consolidados em um único Registro de Medição, UsageAllocations agrupados por AccountId e BusinessUnit antes de serem enviados ao AWS Marketplace Metering Service.\]](http://docs.aws.amazon.com/pt_br/marketplace/latest/userguide/images/seller-vendor-meter-tag.png)


Os vendedores também podem combinar recursos sem tags em uma única `UsageAllocation` com a quantidade de uso alocada e enviá-los como uma das entradas em `UsageAllocations`.

Os limites incluem:
+ Número de tags: 5
+ Quantidade de `UsageAllocations` (cardinalidade): 2.500

As validações incluem:
+ Caracteres permitidos para a chave e o valor da tag — a-zA-Z 0-9\$1 -= . \$1:\$1 /@
+ Máximo de tags na lista `UsageAllocation`: 5
+ Duas `UsageAllocations` não podem ter as mesmas tags (ou seja, a mesma combinação de chaves e valores de tag). Se for esse o caso, elas devem usar a mesma `UsageAllocation`.
+ A soma de `AllocatedUsageQuantity` de `UsageAllocation` deve ser igual a `UsageQuantity`, que é o uso agregado.

### Experiência do comprador
<a name="container-vendor-metered-tag-buyer"></a>

A tabela a seguir mostra um exemplo da experiência do comprador depois que ele ativa as tags de fornecedor `AccountId` e `BusinessUnit`. 

Neste exemplo, o comprador pode ver o uso alocado no **Relatório de uso de custos**. As tags medidas pelo fornecedor usam o prefixo `“aws:marketplace:isv”`. Os compradores podem ativá-las no Billing and Cost Management, em **Tags de alocação de custos**, **Tags de alocação de custos geradas pela AWS**.

A primeira e a última linha do **Relatório de uso de custos** são relevantes para o que o vendedor envia ao Serviço de medição (conforme mostrado no exemplo [Experiência do vendedor](#container-vendor-metered-tag-seller)).


**Relatório de uso de custos (simplificado)**  

| ProductCode  | Comprador | UsageDimension | UsageQuantity | `aws:marketplace:isv:AccountId ` | `aws:marketplace:isv:BusinessUnit` | 
| --- | --- | --- | --- | --- | --- | 
| xyz | 111122223333 | Rede: por (GB) inspecionado  | 70 | 2222 | Operações | 
| xyz | 111122223333 | Rede: por (GB) inspecionado  | 30 | 3333 | Finanças | 
| xyz | 111122223333 | Rede: por (GB) inspecionado  | 20 | 4444 | IT | 
| xyz | 111122223333 | Rede: por (GB) inspecionado  | 20 | 5555 | Marketing | 
| xyz | 111122223333 | Rede: por (GB) inspecionado  | 30 | 1111 | Marketing | 

Para ver um exemplo de código, consulte [Exemplo de código `MeterUsage` com marcação de alocação de uso (opcional)](#container-meterusage-code-example).

## Exemplo de código
<a name="container-meter-code-example"></a>

O exemplo de código a seguir é fornecido para ajudá-lo a integrar seu produto de contêiner com o AWS Marketplace APIs necessário para publicar e manter seu produto.

### Exemplo de código `MeterUsage` com marcação de alocação de uso (opcional)
<a name="container-meterusage-code-example"></a>

O exemplo de código a seguir é relevante para produtos de contêiner com modelos de definição de preço de consumo. O exemplo do Python envia um registro de medição com as tags de alocação de uso apropriadas para AWS Marketplace cobrar taxas de seus clientes. 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. 
# AWS Marketplace can only accept records for up to an hour in the past. 
#
# productCode is supplied after the AWS Marketplace 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 
)
```

Para obter mais informações sobre`MeterUsage`, consulte [MeterUsage](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html)na *Referência AWS Marketplace Metering Service da API*.

### Exemplo de resposta
<a name="container-meterusage-code-response"></a>

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

# Integrando seu produto de contêiner usando medição personalizada com o e AWS Marketplace Metering Service AWS SDK para Java
<a name="java-integration-example-meterusage"></a>

AWS Marketplace os produtos de contêineres podem ter medição personalizada em até 24 dimensões de preços diferentes por produto. Para habilitar a medição personalizada, você pode integrar seu produto de contêiner ao Serviço de medição do AWS Marketplace. Você pode definir suas próprias unidades de preço e medição personalizada para esse uso para a AWS para faturamento usando a operação de API [https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html). O exemplo a seguir descreve uma implementação que usa o AWS SDK para Java para se integrar à operação do [Serviço `MeterUsage` de AWS Marketplace Medição](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html). 

Para obter detalhes completos, consulte [Exemplos de Java do `MeterUsage`](#meterusage-java-example). Muitas etapas a seguir se aplicam independentemente da linguagem. 

**Exemplo: integração do serviço AWS Marketplace de medição**

1. Faça login no [Portal de gerenciamento do AWS Marketplace](https://aws.amazon.com/marketplace/management/tour).

1. Em **Ativos**, selecione **Contêineres** para começar a criar um produto de contêiner. A criação do produto gera o código para a integração do produto com a imagem de contêiner. Para obter informações sobre a configuração de permissões AWS Identity and Access Management (IAM), consulte[AWS Marketplace permissões da API de medição e titulação](iam-user-policy-for-aws-marketplace-actions.md).

1.  Faça download do [SDK do AWS Java](https://aws.amazon.com/sdk-for-java/) público. 
**Importante**  
 Para chamar as operações de API de medição do Amazon Elastic Kubernetes Service (Amazon EKS), você deve [usar um SDK da AWS compatível](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html) e executar em um cluster do Amazon EKS executando o Kubernetes 1.13 ou posterior. 

1. Chame a operação `MeterUsage` da tarefa ou do pod uma vez por hora para o uso de cada dimensão. A operação de API aceita um registro de medição para uma combinação exclusiva de `Dimension`, `Resource` e `Hour`. O recurso é uma tarefa do Amazon Elastic Container Service (Amazon ECS) ou um pod do 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**  
É possível ver problemas transitórios na conexão com o. AWS Marketplace Metering Service AWS Marketplace recomenda fortemente a implementação de novas tentativas por até 30 minutos, com recuo exponencial, para evitar interrupções de curto prazo ou problemas de rede.

1. Recompile uma nova versão da imagem de contêiner que inclua a chamada `MeterUsage`, marque o contêiner e o envie para qualquer registro de Docker compatível com o Amazon ECS ou o Amazon EKS, como o Amazon Elastic Container Registry (Amazon ECR). Se você estiver usando o Amazon ECR, verifique se a conta que executa a tarefa do Amazon ECS ou o pod do Amazon EKS tem permissões no repositório do Amazon ECR. Caso contrário, haverá falha na operação.

1. Crie um perfil do [IAM](https://aws.amazon.com/iam/) que conceda permissão para o contêiner chamar `MeterUsage`, conforme definido no exemplo de código a seguir. Você deve fornecer essa função AWS Identity and Access Management (IAM) no parâmetro Task [Role da tarefa](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_role_arn) do Amazon ECS ou da definição de pod do Amazon EKS.

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

****  

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

------

1. Crie uma tarefa do Amazon ECS ou uma definição de pod do Amazon EKS que faça referência ao contêiner que se integrou AWS Marketplace e faça referência à função do IAM que você criou na etapa 6. Se você quiser ver o registro, habilite o AWS CloudTrail registro na definição da tarefa. 

1. Crie um cluster do Amazon ECS ou Amazon EKS para executar sua tarefa ou pod. Para obter mais informações sobre como criar um cluster do Amazon ECS, consulte [Criar um cluster](https://docs.aws.amazon.com/AmazonECS/latest/userguide/create_cluster.html) no *Guia do desenvolvedor do Amazon Elastic Container Service*. Para obter mais informações sobre como criar um cluster do Amazon EKS (usando o Kubernetes versão 1.1.3.x ou posterior), consulte [Criar um cluster do Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/create_cluster.html).

1. Configure o cluster Amazon ECS ou Amazon EKS e inicie a definição de tarefa do Amazon ECS ou o pod Amazon EKS que você criou na etapa 8, na região us-east-1. AWS É somente durante este processo de teste, antes de o produto estar ativo, que você precisa usar essa região.

1. Quando você recebe uma resposta válida de `MeterUsage` para cada uma das dimensões que estão sendo publicadas para o produto, é possível começar a criar o produto de contêiner. Se tiver dúvidas, entre em contato com a equipe de [Operações do vendedor do AWS Marketplace](https://aws.amazon.com/marketplace/management/contact-us/). 

## Exemplos de Java do `MeterUsage`
<a name="meterusage-java-example"></a>

Os exemplos de código a seguir usam o AWS Marketplace Metering Service AWS SDK para Java e o AWS Marketplace para chamar a `MeterUsage` operação.

O exemplo de código a seguir chama a operação `MeterUsage` sem nenhum `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);
    }
}
```

O exemplo de código a seguir chama a operação `MeterUsage` com `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();
    }
```

# Preços contratuais para produtos em contêineres com AWS License Manager
<a name="container-license-manager-integration"></a>

Para produtos baseados em contêineres com preços contratuais, você pode usar AWS License Manager para associar licenças ao seu produto. AWS License Manager é uma ferramenta de gerenciamento de licenças que permite que seu aplicativo rastreie e atualize licenças (também conhecidas como direitos) que foram adquiridas por um cliente. Esta seção fornece informações sobre como integrar seu produto com AWS License Manager o. Depois que a integração for concluída, você poderá publicar sua lista de produtos no AWS Marketplace.

Se você estiver integrando o License Manager a um AWS Marketplace produto for Containers Anywhere para Amazon EKS Anywhere, Amazon ECS Anywhere, Amazon Elastic Compute Cloud (Amazon EC2) ou infraestrutura local, siga as instruções em. [Integrando um AWS Marketplace para contêineres em qualquer lugar com o License Manager](container-anywhere-license-manager-integration.md)

Para obter mais informações sobre AWS License Manager, consulte o [Guia AWS License Manager do usuário](https://docs.aws.amazon.com/license-manager/latest/userguide/license-manager.html) e a [AWS License Manager](https://docs.aws.amazon.com/cli/latest/reference/license-manager/index.html)seção da *Referência de AWS CLI comandos*.

Para obter mais informações sobre a integração AWS License Manager com produtos de contêineres com preços contratuais, consulte o [workshop Integrar com pagamento antecipado](https://catalog.workshops.aws/mpseller/en-US/container/integrate-contract) do *AWS Marketplace vendedor*.

**Topics**
+ [Preços contratuais para produtos de contêiner](#container-contracts)
+ [Modelos de licença](#container-LM-license-models)
+ [AWS License Manager pré-requisitos de integração](#container-LM-prereqs)
+ [Integração de um produto de contêiner ao License Manager](#container-integrate-with-LM)
+ [Operações de API do License Manager](#container-LM-API-calls)
+ [Renovações e upgrades de licenças](#container-LM-lic-renew-upgrade)
+ [Integrando um AWS Marketplace para contêineres em qualquer lugar com o License Manager](container-anywhere-license-manager-integration.md)

## Preços contratuais para produtos de contêiner
<a name="container-contracts"></a>

Para produtos baseados em contêineres com preços contratuais, AWS Marketplace fature seus clientes antecipadamente ou de acordo com o cronograma de pagamento definido por você, com base no contrato entre você e seu cliente. A partir daí, eles estarão autorizados a usar os recursos. 

Para definir seu preço, escolha uma ou mais durações de contrato para oferecer aos clientes. Você pode inserir preços diferentes para cada duração de contrato. Suas opções são durações de 1 mês, 12 meses, 24 meses e 36 meses. Para ofertas privadas, você pode especificar uma duração personalizada em meses (até 60 meses). 

Escolha a categoria que melhor descreve a definição de preço do seu produto. A categoria de preços aparece para os clientes no AWS Marketplace site. **Você pode escolher entre **largura de banda** (GB/s, MB/s), **dados** (GB, MB, TB), **hosts**, **solicitações**, **níveis** ou usuários.** Se nenhuma das categorias predefinidas atender às suas necessidades, você poderá escolher a categoria mais genérica **Unidades**. 

A oferta permite que até 24 dimensões sejam adicionadas a ela.


**Exemplo: aplicação de armazenamento de dados**  

|   | Preço para 1 mês | Preço para 12 meses  | Preço para 24 meses  | Preço para 36 meses  | 
| --- | --- | --- | --- | --- | 
|  Dados não criptografados (GB)  |  1,50 USD/GB  |  16,00 USD/GB  |  30,00 USD/GB  |  60,00 USD/GB  | 
|  Dados criptografados (GB)  |  1,55 USD/GB  |  16,60 USD/GB  |  31,20 USD/GB  |  61,20 USD/GB  | 


**Exemplo: produto de monitoramento de log**  

|   | Preço para 1 mês | Preço para 12 meses  | Preço para 24 meses | Preço para 36 meses | 
| --- | --- | --- | --- | --- | 
|  Básico (10 hosts monitorados, 5 contêineres monitorados)  |  100 USD  |  1000 USD  | 2000 USD  | 4000 USD | 
|  Padrão (20 hosts monitorados, 10 contêineres monitorados)  |  200 USD  |  2000 USD  | 4000 USD  | \$18000 | 
|  Pro (40 hosts monitorados, 20 contêineres monitorados)  |  400 USD  |  4000 USD  | \$18000  | \$116.000 | 
|  Outros hosts monitorados por hora  | \$110  | 100 USD  |  200 USD | 400 USD | 
|  Outros contêineres monitorados por hora  | \$110  | 100 USD  |  200 USD | 400 USD | 

**nota**  
Os preços podem ser para as seguintes durações: um mês, 12 meses, 24 meses ou 36 meses. Você pode optar por oferecer uma ou mais dessas opções para o seu produto. As durações devem ser as mesmas em cada dimensão.   

**Example**  
Por exemplo, em um caso em que você tem `AdminUsers` dimensões `ReadOnlyUsers` e dimensões, se você oferece um preço anual para ReadOnlyUsers, você também deve oferecer um preço anual para`AdminUsers`.


### Renovações automáticas
<a name="ami-contracts-automatic-renewals"></a>

 Quando os clientes compram seu produto AWS Marketplace usando contratos de contêineres, eles podem concordar em renovar automaticamente os termos do contrato. Os clientes continuam pagando pelas autorizações a cada mês ou por um, dois ou três anos. 

Os clientes podem modificar as configurações de renovação a qualquer momento. Para obter mais informações, consulte [Modificação de um contrato existente](https://docs.aws.amazon.com/marketplace/latest/buyerguide/buyer-container-contracts.html#modify-existing-contract) no *Guia do comprador do AWS Marketplace *.

## Modelos de licença
<a name="container-LM-license-models"></a>

AWS Marketplace a integração com AWS License Manager suporta dois modelos de licença:
+ [Modelo de licença configurável](#container-LM-config-lic-model)
+ [Modelo de licença em nível](#container-LM-tiered-lic-model)

### Modelo de licença configurável
<a name="container-LM-config-lic-model"></a>

O modelo de licença configurável (também conhecido como modelo de licença quantificável) autoriza o comprador a uma quantidade específica de recursos após a aquisição da licença. 

Você define uma dimensão de preço e um preço unitário. Em seguida, o comprador pode escolher a quantidade de recursos que deseja comprar.

**Example da dimensão de preços e do preço unitário**  
Você pode definir uma dimensão de preço (como backup de dados) e um preço unitário (como USD 30/unidade).  
O comprador pode optar por comprar 5, 10 ou 20 unidades.   
Seu produto rastreia e mede o uso para medir a quantidade de recursos consumidos.

Com o modelo de configuração, os direitos são contados de uma destas duas maneiras:
+ [Licenças emitidas](#container-floating-lic)
+ [Licenças flutuantes](#container-floating-lic) 

#### Licença emitida
<a name="container-drawndown-lic"></a>

 A licença é extraída do conjunto de quantidades permitidas de licenças após o uso. Esse direito é verificado permanentemente e não pode ser devolvido ao pool de licenças.

**Example de processar uma quantidade limitada de dados**  
Um usuário tem o direito de processar 500 GB de dados. À medida que continuam processando os dados, a quantidade é extraída do pool de 500 GB até que todas as licenças de 500 GB sejam consumidas.

Para licenças emitidas, você pode usar a operação de API `CheckoutLicense` para verificar as unidades de licença (direitos) que são consumidas. 

**Example de backup no Amazon S3 para várias unidades/ano**  
Você tem um produto de armazenamento que permite fazer backup no Amazon Simple Storage Service de até 1.024 unidades de dados por um ano. Seu aplicativo pode ser executado usando várias instâncias do Amazon EC2. Seu aplicativo tem um mecanismo para rastrear e agregar dados. Seu software chama a operação de API `CheckoutLicense` com o ID do produto em cada backup ou em intervalos fixos para atualizar as quantidades consumidas.   
Neste exemplo, seu software chama a operação de API `CheckoutLicense` para verificar 10 unidades de dados. Quando a capacidade total atinge o limite de backup que o cliente comprou, a chamada da API falha.

**Solicitação**

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

**Resposta**

```
{"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"
}
```

#### Licenças flutuantes
<a name="container-floating-lic"></a>

 A licença é devolvida ao conjunto da quantidade permitida de licenças após o uso.

Para licenças flutuantes, o aplicativo verifica os direitos no conjunto de direitos usando a operação de API `CheckoutLicense` quando o recurso está sendo usado. A resposta da operação de API `CheckoutLicense` inclui um token de consumo de licença, que é um identificador exclusivo para o checkout. O token de consumo de licença pode ser usado para realizar ações adicionais nos direitos que são retirados, como devolvê-los ao conjunto de licenças ou estender a finalização da compra.

Para devolver o direito ao conjunto, use a operação de API `CheckInLicense` quando o recurso não estiver mais em uso.

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

Em caso de falha de verificação do direito (no caso de o aplicativo falhar), o direito volta para o conjunto automaticamente após 60 minutos. Se o recurso estiver em uso por mais de 60 minutos, é uma prática recomendada manter o direito retirado do conjunto usando a operação de API `ExtendLicenseConsumption` enquanto o recurso estiver sendo usado.

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

**Example do número de usuários a partir de um limite superior fixo**  
Um usuário tem direito a 500 usuários simultâneos no aplicativo. Conforme os usuários fazem login e se desconectam, eles são retirados e retornados ao conjunto de 500 usuários. No entanto, o aplicativo não pode retirar mais de 500 usuários do conjunto porque 500 usuários simultâneos é o limite máximo fixo.

Para direitos flutuantes, você pode usar a operação de API `CheckInLicense` para devolver as unidades de licença ao conjunto de direitos. 

**Example do número de usuários simultâneos por um ano**  
O preço do produto é baseado no número de usuários simultâneos. O cliente compra uma licença para 10 usuários por um ano. O cliente executa o software fornecendo permissões do AWS Identity and Access Management (IAM). Quando um usuário faz login, seu aplicativo chama a operação de API `CheckoutLicense` para reduzir a quantidade em 1. Quando o usuário se desconecta, o aplicativo retorna essa licença para o conjunto chamando a operação de API `CheckInLicense`. Se você não chamar `CheckInLicense`, o check-in da unidade de licença será feito automaticamente depois de 1 hora.

**nota**  
Na solicitação a seguir, `key-fingerprint` não é um valor reservado, mas o valor real da impressão digital com a qual todas as licenças serão publicadas.

**Solicitação**

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

**Resposta**

```
{
  "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"
}
```

### Modelo de licença em nível
<a name="container-LM-tiered-lic-model"></a>

O modelo de licença em nível dá ao comprador o direito a um nível específico de recursos do aplicativo após a aquisição da licença. 

Você cria níveis para seu produto, como Básico, Intermediário e Premium. Em seguida, o comprador seleciona um dos níveis predefinidos.

O aplicativo não precisa rastrear ou medir o uso do aplicativo.

Com o modelo de licença em nível, os direitos não são contados, mas significam um nível de serviço que foi adquirido pelo cliente. 

Se você quiser oferecer recursos agrupados, os níveis são preferíveis. 

**Example dos níveis Básico, Intermediário e Premium**  
Um cliente pode assinar um contrato para um dos três níveis possíveis do software: Básico, Intermediário ou Premium. Cada um desses níveis tem seu próprio preço. Seu software pode identificar o nível que o cliente assinou invocando a operação de API `CheckoutLicense` e especificando todos os níveis possíveis na solicitação.   
A resposta da solicitação contém o direito correspondente ao nível que o cliente adquiriu. Com base nessas informações, o software pode fornecer a experiência adequada ao cliente.

#### Solicitação
<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"
```

#### Resposta
<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 pré-requisitos de integração
<a name="container-LM-prereqs"></a>

Antes de publicar o produto, você deve fazer o seguinte:

1. Crie um novo produto de contêiner no Portal de gerenciamento do AWS Marketplace e anote o código do produto.

   Para obter mais informações, consulte [Visão geral: crie um produto em contêiner](container-product-getting-started.md#create-container-product).

1. Use um perfil do IAM para a tarefa ou o pod que está executando o aplicativo com as permissões do IAM necessárias para chamar as operações de API `CheckoutLicense`, `ExtendLicenseConsumption` e `CheckInLicense`.

   As permissões do IAM obrigatórias são detalhadas na política do 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. Faça uma chamada de teste para a operação de API `RegisterUsage` com um registro para todas as dimensões de preço definidas.

## Integração de um produto de contêiner ao License Manager
<a name="container-integrate-with-LM"></a>

**Para integrar seu produto baseado em contêiner ao License Manager**

1. Defina as permissões do IAM para chamar o License Manager. Para obter mais informações, consulte [AWS License Manager pré-requisitos de integração](#container-LM-prereqs).

1. Baixe o AWS SDK.
**nota**  
Não configure AWS credenciais em seu software. AWS as credenciais do comprador são obtidas automaticamente em tempo de execução quando seu contêiner está sendo executado em uma instância do Amazon EC2, tarefa do Amazon ECS ou pod do Amazon EKS.

1. Adicione verificações de licença ao seu produto.

   Seu produto pode chamar a operação de API da `CheckoutLicense` onde quer que a verificação da licença deva ser realizada. Para verificar a licença, seu produto deve saber:

   1. O emissor confiável da licença (AWS Marketplace)

   1. O SKU do produto (ID do produto) do aplicativo

   1. O direito de verificar este aplicativo

   As chamadas de API variam de acordo com o tipo de preço das licenças que você configura.

1. Publique sua lista de produtos em AWS Marketplace.

## Operações de API do License Manager
<a name="container-LM-API-calls"></a>

Para gerenciar as licenças armazenadas na conta do License Manager do cliente, seu software pode usar as seguintes chamadas de API:
+ `GetLicense`: uma API que o software pode consultar. Ela recupera o status de uma licença comprada (ou seja, expirada ou expirando em breve) e envia uma notificação de status ao cliente.
+ `CheckoutLicense`: descobre as licenças que o usuário comprou. Você também pode usar a operação de API `CheckoutLicense` para atualizar a quantidade de licenças quando o usuário tiver consumido alguma quantidade de licenças. Com `CheckoutLicense`, você pode continuar verificando as quantidades de licenças usadas pelo cliente. Quando o cliente esgota todas as licenças, essa chamada retorna um erro. Para obter informações sobre a cadência sugerida para execução de `CheckoutLicense`, consulte [Renovações e upgrades de licenças](#container-LM-lic-renew-upgrade).
+ `ExtendLicenseConsumption`: no caso de dimensões flutuantes, quando o software comprar uma licença, a licença retornará ao conjunto automaticamente após 60 minutos. Se você quiser estender o tempo em que a licença permanece verificada, use a operação de API `ExtendLicenseConsumption` para estender a licença por mais 60 minutos.
+ `CheckInLicense`: no caso de dimensões flutuantes, quando quiser devolver a licença ao conjunto de direitos, use a operação de API `CheckInLicense`.
+ API `ListReceivedLicenses`: lista as licenças compradas pelo comprador.

## Renovações e upgrades de licenças
<a name="container-LM-lic-renew-upgrade"></a>

Os clientes podem renovar ou atualizar as licenças no Portal de gerenciamento do AWS Marketplace. Depois de fazer uma compra adicional, AWS Marketplace gera uma nova versão da licença que reflete os novos direitos. Seu software lê os novos direitos usando as mesmas operações de API. Você não precisa fazer nada diferente em termos de integração do License Manager para lidar com renovações e atualizações.

Devido a renovações de licenças, upgrades, cancelamentos e assim por diante, recomendamos que seu produto chame a operação de API `CheckoutLicense` em um ritmo regular enquanto o produto estiver em uso. Ao usar a operação de API `CheckoutLicense` em um ritmo regular, o produto pode detectar alterações nos direitos, como atualizações e expiração.

Recomendamos que você realize a chamada de API `CheckoutLicense` a cada 15 minutos. 

# Integrando um AWS Marketplace para contêineres em qualquer lugar com o License Manager
<a name="container-anywhere-license-manager-integration"></a>

Como AWS Marketplace vendedor, você pode se integrar AWS License Manager a um produto AWS Marketplace for Containers Anywhere para Amazon EKS Anywhere, Amazon ECS Anywhere, Amazon EC2 ou infraestrutura local. As seções a seguir dão instruções para esta integração.

Para obter informações gerais sobre a integração do License Manager com AWS Marketplace, incluindo os modelos de licença disponíveis, consulte[Preços contratuais para produtos em contêineres com AWS License Manager](container-license-manager-integration.md). Para obter mais informações sobre a AWS License Manager, consulte o [Guia do usuário do AWS License Manager](https://docs.aws.amazon.com/license-manager/latest/userguide/license-manager.html) e a [Referência de comandos do AWS License Manager](https://docs.aws.amazon.com/cli/latest/reference/license-manager/index.html).

**Topics**
+ [Integrando um produto AWS Marketplace for Containers Anywhere com o License Manager](#containers-anywhere-integrate-with-LM)
+ [Teste da integração do License Manager localmente](#container-testing-LM-integration-locally)
+ [Teste da integração do License Manager no Amazon EKS](#container-testing-LM-integration-EKS)
+ [Direitos de licença flutuante no License Manager](#container-LM-floating-license)
+ [Práticas recomendadas para integração com o License Manager para implantações on-premises](#container-LM-best-practices-on-prem)
+ [`LicenseManagerCredentialsProvider`: implementação de Java](#container-license-manager-cred-provider-java)
+ [`LicenseManagerCredentialsProvider`: implementação do `Golang`](#container-license-manager-cred-provider-golang)

## Integrando um produto AWS Marketplace for Containers Anywhere com o License Manager
<a name="containers-anywhere-integrate-with-LM"></a>

Use as instruções a seguir para integrar seu produto AWS Marketplace for Containers Anywhere com AWS License Manager o.

**Para integrar seu produto AWS Marketplace for Containers Anywhere com o License Manager**

1. Abra um navegador da web e faça login no [Portal de gerenciamento do AWS Marketplace](https://aws.amazon.com/marketplace/management/).

1. Crie um ID para seu produto de contêiner realizando as etapas a seguir. Você usará esse ID na imagem do contêiner para verificações de licença em uma etapa posterior.

   1. Na barra de menus, expanda **Ativos** e selecione **Contêiner**.

   1. Insira um nome voltado ao cliente para o produto e selecione **Criar**. Você pode alterar esse nome depois.

   1. Anote o **ID do produto**. Você o usará ao criar ou atualizar os detalhes de preços do produto.
**dica**  
Se você perder o ID do produto, poderá encontrá-lo Portal de gerenciamento do AWS Marketplace escolhendo **Contêiner** no menu **Ativos**. A página **Contêineres** mostra uma lista de seus produtos com os produtos associados IDs.

1. Baixe o AWS SDK público mais recente e instale-o em seu aplicativo de contêiner. Você pode encontrar instruções de instalação para seu AWS SDK preferido em [Tools to Build on AWS](https://aws.amazon.com/tools/).
**nota**  
Para chamar as operações da API do License Manager do Amazon EKS Anywhere ou de um cluster Kubernetes que não seja fornecido pelo AWS, você deve usar um SDK compatível. AWS Para ver uma lista dos compatíveis AWS SDKs, consulte Como [usar um AWS SDK compatível](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html).

1. Crie um AWS License Manager cliente com um provedor de credenciais personalizado para que ele possa fornecer credenciais para o aplicativo de contêiner implantado no local e no AWS local. Para obter o código-fonte completo de um provedor de credenciais personalizado, `LicenseCredentialProvider`, consulte as seções a seguir:
   + [`LicenseManagerCredentialsProvider`: implementação de Java](#container-license-manager-cred-provider-java)
   + [`LicenseManagerCredentialsProvider`: implementação do `Golang`](#container-license-manager-cred-provider-golang)

    `LicenseCredentialsProvider`estende a cadeia de provedores de credenciais padrão do AWS SDK para uso local adicionando. `LicenseManagerTokenCredentialsProvider` Isso fornece credenciais usando tokens de identidade emitidos pelo License Manager OIDC em ambientes on-premises. Você deve incluir o código-fonte do `LicenseCredentialsProvider` no caminho de classe do seu aplicativo.
**nota**  
Estender o `DefaultCredentialsProvider` permite que o mesmo aplicativo de contêiner obtenha credenciais ao ser executado em AWS e quando executado em um ambiente local. Se o aplicativo de contêiner já usa uma cadeia de provedores de credenciais personalizada em vez do padrão, ele também pode ser estendido adicionando `LicenseManagerTokenCredentialsProvider` à cadeia personalizada.

   O trecho de código a seguir é um exemplo de criação de um AWS License Manager cliente usando Java.

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

1. Chame a operação de API `CheckoutLicense` usando o comando `aws license-manager checkout-license` de cada imagem de contêiner paga na oferta de produto. Isso verifica se o comprador tem o direito de usar uma licença para o aplicativo. Se o comprador tiver direito ao aplicativo, `CheckoutLicense` obterá êxito e devolverá os direitos solicitados e os valores. Se o comprador não tiver direito ao aplicativo, `CheckoutLicense` lançará uma exceção.

   Os parâmetros a seguir são necessários ao chamar a operação de API `CheckoutLicense`:
   + `CheckoutType`: os valores válidos são `PROVISIONAL` ou `PERPETUAL`:
     + Use `PERPETUAL` quando a quantidade de direitos retirados será esgotada do conjunto.

       Exemplo: o comprador tem o direito de processar 500 GB de dados. À medida que continua processando os dados, a quantidade é retirada e esgotada do conjunto de 500 GB.
     + Use `PROVISIONAL` para direitos de licença flutuante, em que os direitos são retirados do conjunto e devolvidos após o uso.

       Exemplo: o usuário tem direito a 500 usuários simultâneos no aplicativo. Conforme os usuários fazem login ou se desconectam, eles são retirados ou retornados ao conjunto de 500 usuários. Para saber mais sobre direitos de licença flutuante, consulte [Direitos de licença flutuante no License Manager](#container-LM-floating-license).
   + `ClientToken`: um identificador exclusivo e que diferencia maiúsculas e minúsculas. Recomendamos usar um UUID aleatório para cada solicitação exclusiva.
   + `Entitlements`: uma lista de direitos a serem verificados.
     + Para direitos de recursos, forneça as propriedades `Name` e `Unit` assim.

       ```
       {
         "Name": "<Entitlement_Name>",
         "Unit": "None"
       }
       ```
     + Para direitos contados, forneça as propriedades `Name`, `Unit` e `Count` assim.

       ```
       {
         "Name": "<Entitlement_Name>",
         "Unit": "<Entitlement_Unit>",
         "Value": <Desired_Count>
       }
       ```
   + `KeyFingerprint`: a impressão digital de chave para licenças emitidas pelo AWS Marketplace é `aws:294406891311:AWS/Marketplace:issuer-fingerprint`. O uso dessa impressão digital de chave garante que a licença seja emitida por AWS Marketplace e não por uma entidade não confiável.
   + `ProductSKU`— O ID do produto gerado Portal de gerenciamento do AWS Marketplace nas etapas anteriores.

   O snippet a seguir é um exemplo de uma chamada usando a operação de API `CheckoutLicense` usando a 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**  
Para verificar as licenças, os aplicativos de contêiner exigem acesso de saída à rede para usar o License Manager. Os aplicativos implantados on-premises podem ter acesso de saída lento ou não confiável à rede. Esses aplicativos devem incluir novas tentativas adequadas ao chamar o License Manager. Para obter mais informações, consulte [Práticas recomendadas para integração com o License Manager para implantações on-premises](#container-LM-best-practices-on-prem).

1. Chame a operação de API `CheckoutLicense` regularmente para identificar quaisquer alterações nas licenças dos clientes devido a renovações, atualizações ou cancelamentos feitos no AWS Marketplace. A cadência depende do aplicativo. Recomendamos verificar as licenças uma vez por dia para receber as alterações automaticamente sem a intervenção do comprador.

   Um aplicativo implantado on-premises pode ter acesso não confiável à rede de saída para verificar as licenças em um ritmo regular. Nesses casos, o aplicativo deve usar licenças em cache para obter resiliência suficiente. Para obter mais informações, consulte [Práticas recomendadas para integração com o License Manager para implantações on-premises](#container-LM-best-practices-on-prem).

1. Depois de integrar a chamada `CheckoutLicense` ao seu aplicativo de contêiner, crie uma nova versão da imagem de contêiner do Docker com as alterações.

1. Atualize o gráfico do Helm do seu aplicativo para aceitar um segredo do Kubernetes como entrada opcional que contém a configuração para acessar licenças usando o License Manager. APIs O segredo de configuração conterá um token de identidade emitido pelo License Manager e uma AWS Identity and Access Management função que será usada pelo provedor de credenciais personalizado descrito anteriormente para obter AWS credenciais para chamar o License Manager APIs quando o aplicativo de contêiner for implantado localmente. Além disso, adicione a Região da AWS como uma entrada com um valor padrão de`us-east-1`.

   Os compradores que implantam o aplicativo de contêiner localmente podem criar o segredo do Kubernetes por meio da experiência do AWS Marketplace comprador em produtos de contêiner. Forneça o nome do segredo do Kubernetes como entrada para o comando `helm install`. O segredo da configuração tem o seguinte 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. Atualize o modelo de implantação do aplicativo no gráfico do Helm para imagens de contêiner integradas AWS License Manager para incluir o seguinte:
   + Conta de serviço para pod: a conta de serviço é necessária para implantações do Helm no Amazon EKS. Ela é usada para obter permissões para chamar as operações de API do License Manager configurando perfis do IAM para a conta de serviço na imagem do contêiner. Para obter mais informações sobre perfis do IAM para contas de serviço, consulte [Perfis do IAM para contas de serviço](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html).
   + Acesso à licença para implantações on-premises: o segredo da configuração da licença é necessário para fornecer credenciais e permissões apropriadas para chamar as operações de API do License Manager para implantações do Helm em ambientes on-premises. Os compradores gerarão e fornecerão o segredo da licença à Helm a partir da experiência do AWS Marketplace comprador.

   O snippet de código a seguir é um exemplo de especificação de implantação com a conta de serviço, a configuração da licença e o segredo de extração da imagem.

   ```
   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**  
O segredo da configuração da licença é opcional. Os compradores usam o valor somente para implantações on-premises. Para AWS implantações, a especificação de implantação deve incluir uma conta de serviço para as imagens integradas do License Manager.

1. Teste a integração do License Manager localmente e no Amazon EKS realizando as etapas nas seguintes seções:

   1. [Teste da integração do License Manager localmente](#container-testing-LM-integration-locally)

   1. [Teste da integração do License Manager no Amazon EKS](#container-testing-LM-integration-EKS)

1. Depois de verificar com êxito a integração do License Manager no local AWS e no local, você pode criar sua lista de produtos de contêiner seguindo as etapas em[Visão geral: crie um produto em contêiner](container-product-getting-started.md#create-container-product).

## Teste da integração do License Manager localmente
<a name="container-testing-LM-integration-locally"></a>

Você pode usar o minikube ou qualquer outra configuração para testar a integração do License Manager em qualquer cluster Kubernetes localmente. Certifique-se de que o cluster Kubernetes tenha acesso de saída à Internet para chamar as operações de API do License Manager.

**Para testar uma integração do License Manager localmente**

1. Crie uma licença de teste em uma conta de vendedor de teste com os direitos desejados. Para configurar uma licença de teste, consulte [CreateLicense](https://docs.aws.amazon.com/license-manager/latest/APIReference/API_CreateLicense.html)a *Referência AWS License Manager da API*. Ou use o script a seguir para criar uma licença de teste e, em seguida, criar uma concessão de licença para uma conta de comprador de teste para consumir a licença. O script a seguir usa as credenciais da conta de vendedor de teste.

   ```
   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. Crie um segredo do Kubernetes com o token de licença e o perfil do IAM usando o formato do segredo definido anteriormente. Use a operação de API `CreateToken` do License Manager para gerar um token de licença. Em seguida, use a operação de API `CreateRole` do IAM para criar um perfil do IAM com permissões e uma política de confiança. Veja o exemplo no script seguinte. O script a seguir usa as credenciais da conta de comprador de teste.

   ```
   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. Configure qualquer cluster Kubernetes hospedado fora. AWS Use-o para testar se os aplicativos de contêiner podem se conectar à AWS License Manager API de outros ambientes AWS e se o provedor de credenciais personalizadas está bem integrado ao aplicativo.

1. Implante o token de licença e o perfil do IAM gerados anteriormente no cluster local do Kubernetes.

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

1. Implante seu aplicativo por meio do Helm com o nome do segredo como entrada e verifique se o aplicativo pode chamar as operações de API do License Manager para realizar verificações de direitos. Para alterações nas especificações do Helm e da implantação, consulte a Etapa 9 em [Integrando um produto AWS Marketplace for Containers Anywhere com o License Manager](#containers-anywhere-integrate-with-LM).

## Teste da integração do License Manager no Amazon EKS
<a name="container-testing-LM-integration-EKS"></a>

Você também pode testar a integração do License Manager no Amazon EKS. Teste para garantir que o aplicativo possa chamar as operações de API do License Manager sem o segredo da configuração da licença. Além disso, certifique-se de que a conta de serviço possa ser usada para configurar perfis do IAM para contas de serviço (IRSA) e fornecer credenciais relevantes para o aplicativo.

**Para testar a integração do License Manager no Amazon EKS**

1. Crie uma licença de teste em uma conta de vendedor de teste com os direitos desejados. Consulte a [referência CreateLicense da API](https://docs.aws.amazon.com/license-manager/latest/APIReference/API_CreateLicense.html) para configurar sua licença de teste ou use o script a seguir para criar uma e criar uma concessão de licença para uma conta de comprador de teste para consumir a licença. O script a seguir usa as credenciais da conta de vendedor de teste.

   ```
   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. Crie um cluster de teste do Amazon EKS com as configurações desejadas ou execute os seguintes comandos para usar uma configuração padrão.

   ```
   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. Crie uma conta de serviço para um cluster existente e associe-o a um perfil do IAM. O comando a seguir cria um perfil do IAM com a `AWSLicenseManagerConsumptionPolicy`. Em seguida, o comando o anexa à conta de serviço `test_sa` do cluster do Amazon EKS em que as imagens integradas do License Manager devem ser implantadas. Como resultado, a conta de serviço pode obter as credenciais apropriadas para chamar as operações de API do 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. Implante o aplicativo por meio do Helm na conta de serviço em que o perfil do IAM está associado no comando anterior. Verifique se o aplicativo pode chamar as operações de API do License Manager para realizar verificações de direitos.

## Direitos de licença flutuante no License Manager
<a name="container-LM-floating-license"></a>

Com licenças flutuantes, à medida que os usuários acessam o aplicativo, uma licença é retirada do conjunto de licenças disponíveis. À medida que os usuários se desconectam, as licenças são adicionadas novamente ao conjunto de licenças disponíveis.

Para licenças flutuantes, o aplicativo usa a operação de API `CheckoutLicense` para verificar os direitos do conjunto de direitos quando o recurso está sendo usado. A resposta da operação de API `CheckoutLicense` inclui um token de consumo de licença, que é um identificador exclusivo para o checkout. O token de consumo de licença pode realizar ações adicionais nos direitos que são retirados, como devolvê-los ao conjunto de licenças ou estender a finalização da compra.

Quando o recurso não está mais em uso, o aplicativo usa a operação de API `CheckInLicense` para verificar o direito de volta ao conjunto.

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

Se a devolução de uma licença ao conjunto falhar, por exemplo, se o aplicativo falhar durante a operação, o direito será devolvido ao conjunto automaticamente após 60 minutos. Por esse motivo, se o recurso estiver em uso por mais de 60 minutos, é uma prática recomendada manter o direito retirado do conjunto. Para fazer isso, use a operação de API `ExtendLicenseConsumption` enquanto o recurso estiver sendo usado.

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

## Práticas recomendadas para integração com o License Manager para implantações on-premises
<a name="container-LM-best-practices-on-prem"></a>

Implantações de aplicativos de contêiner em um ambiente on-premises podem encontrar acesso não confiável à rede de saída. Use as práticas recomendadas a seguir para aumentar a resiliência e evitar a interrupção do serviço para os compradores devido a possíveis problemas causados pela baixa conectividade com a Internet:
+ Nova **tentativa adequada** — Problemas transitórios de rede podem impedir que seu aplicativo se conecte a. AWS License Manager Implemente novas tentativas por até 30 minutos, com recuo exponencial. Isso pode ajudar a evitar interrupções de curto prazo ou problemas de rede.
+ **Evitar limites rígidos**: os aplicativos implantados em clusters conectados podem verificar regularmente as licenças para identificar quaisquer alterações devido a atualizações ou renovações. Com o acesso externo não confiável, o aplicativo pode não conseguir identificar essas alterações. Sempre que possível, o aplicativo deve evitar a interrupção do serviço aos compradores devido à incapacidade de verificar as licenças por meio do License Manager. Os aplicativos podem recorrer a uma experiência de teste gratuito ou de código aberto quando a licença expirar e não podem verificar se a licença é válida.
+ **Notificar os clientes**: ao usar uma licença em cache, quaisquer alterações na licença (incluindo renovações ou upgrades) não são refletidas automaticamente na workload em execução. Notifique os clientes (que eles devem permitir o acesso externo ao aplicativo novamente temporariamente para que o aplicativo possa atualizar a licença em cache). Por exemplo, notifique os clientes por meio do próprio aplicativo ou da documentação. Da mesma forma, ao recorrer a um conjunto inferior de funcionalidades, notifique os clientes que os direitos estão esgotados ou que a licença expirou. Em seguida, eles podem optar por atualizar ou renovar.

## `LicenseManagerCredentialsProvider`: implementação de Java
<a name="container-license-manager-cred-provider-java"></a>

`LicenseCredentialsProvider`estende a cadeia de provedores de credenciais padrão do AWS SDK para uso local adicionando. `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` fornece credenciais usando tokens de identidade emitidos pelo License Manager OIDC em ambientes on-premises. Você deve incluir o código-fonte do `LicenseCredentialsProvider` no caminho de classe do seu aplicativo.

```
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`: implementação do `Golang`
<a name="container-license-manager-cred-provider-golang"></a>

**`LicenseCredentialsProvider`**

`LicenseCredentialsProvider`estende a cadeia de provedores de credenciais padrão do AWS SDK para uso local adicionando. `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` fornece credenciais usando tokens de identidade emitidos pelo License Manager OIDC em ambientes on-premises. Você deve incluir o código-fonte do `LicenseCredentialsProvider` no caminho de classe do seu aplicativo.

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