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á.
Integrando seu produto de contêiner com o AWS Marketplace Metering Service usando o AWS SDK for Java
Você pode usar o AWS SDK for 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. Seu software não precisa realizar nenhuma ação específica de medição, exceto chamar RegisterUsage
uma vez para que a medição do uso do software comece. Este tópico fornece um exemplo de implementação usando o AWS SDK for Java para integrar com a RegisterUsage
ação do AWS Marketplace Metering Service.
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 o lançamento do contêiner, o AWS Marketplace Metering Service 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. Muitas dessas etapas se aplicam independentemente do AWS SDK idioma.
Exemplos de etapas para a integração AWS do Marketplace Metering Service
-
Faça login no Portal de gerenciamento do AWS Marketplace
. -
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 informações sobre como definir IAM permissões, consulteAWS Marketplace permissões da API de medição e titulação.
-
Baixe o AWSJava
públicoSDK. Importante
Para chamar a medição APIs da AmazonEKS, você deve usar um cluster compatível AWS SDK e executá-lo em um EKS cluster da Amazon executando o Kubernetes 1.13 ou posterior.
-
(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 BouncyCastleassinatura no caminho de classe do seu aplicativo. Se quiser usar o JSON Web Token (JWT), você também deve incluir bibliotecas JWTJava
no classpath do seu aplicativo. JWTO uso fornece uma abordagem mais simples para a verificação de assinatura, mas não é obrigatório. Em vez disso, você pode usar o modo autônomo. BouncyCastle Se você usa JWT ou BouncyCastle, você precisa usar um sistema de compilação como o Maven para incluir dependências transitivas de BouncyCastle ou JWT no classpath 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>
-
Chame
RegisterUsage
de cada imagem de contêiner paga na oferta do produto.ProductCode
ePublicKeyVersion
são parâmetros obrigatórios, e todas as outras entradas são opcionais. Esta é uma carga útil de exemplo paraRegisterUsage
.{ "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 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.
-
RegisterUsage
gera uma assinatura PSS digital RSA - usando SHA -256 que você pode usar para verificar a autenticidade da solicitação. A assinatura inclui os seguintes campos:ProductCode
,PublicKeyVersion
eNonce
. Para verificar a assinatura digital, você deve manter esses campos da solicitação. Este código é uma resposta de exemplo para uma chamadaRegisterUsage
.{ "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..."
-
Reconstrua uma nova versão da imagem do contêiner que inclua a
RegisterUsage
chamada, marque o contêiner e envie-o para qualquer registro de contêiner compatível com a Amazon ECS ou a AmazonEKS, como Amazon ECR ou Amazon ECR Public. Se você estiver usando a AmazonECR, certifique-se de que a conta que está iniciando a ECS tarefa da Amazon ou o EKS pod da Amazon tenha permissões no ECR repositório da Amazon. Caso contrário, ocorrerá uma falha na inicialização. -
Crie uma IAM
função que conceda permissão para que seu contêiner chame RegisterUsage
, conforme definido no código a seguir. Você deve fornecer essa IAM função no parâmetro Task Role da definição de ECS tarefa da Amazon ou EKS pod da Amazon.{ "Version": "2012-10-17", "Statement": [ { "Action": [ "aws-marketplace:RegisterUsage" ], "Effect": "Allow", "Resource": "*" } ] }
-
Crie uma ECS tarefa da Amazon ou uma definição de EKS pod da Amazon que faça referência ao contêiner que se integrou AWS Marketplace e faça referência à IAM função que você criou na etapa 7. Você deve habilitar o AWS CloudTrail registro na definição da tarefa se quiser ver o registro.
-
Crie um EKS cluster Amazon ECS ou Amazon para executar sua tarefa ou pod. Para obter mais informações sobre a criação de um ECS cluster da Amazon, consulte Como criar um cluster no Guia do desenvolvedor do Amazon Elastic Container Service. Para obter mais informações sobre a criação de um EKS cluster da Amazon (usando o Kubernetes versão 1.1.3.x ou posterior), consulte Criação de um cluster da Amazon. EKS
-
Configure o EKS cluster da Amazon ECS ou da Amazon e inicie a definição de ECS tarefa da Amazon ou o EKS pod da Amazon 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.
-
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.
RegisterUsage Exemplo de Java
O exemplo a seguir usa o AWS SDK for 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 AWS Marketplace 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(); } } }