

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用自訂計量與 AWS Marketplace Metering Service 和 整合您的容器產品 適用於 Java 的 AWS SDK
<a name="java-integration-example-meterusage"></a>

AWS Marketplace 容器產品可以對每個產品最多 24 個不同的定價維度進行自訂計量。若要啟用自訂計量，您可以將容器產品與 AWS Marketplace Metering Service 整合。您可以使用 [https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/API_MeterUsage.html) API 操作，為該用量定義自己的定價單位和自訂計量到 AWS 進行計費。下列範例概述使用 適用於 Java 的 AWS SDK 與 [AWS Marketplace Metering Service](https://docs.aws.amazon.com/marketplacemetering/latest/APIReference/Welcome.html) `MeterUsage`操作整合的實作。

如需完整詳細資訊，請參閱 [`MeterUsage` Java 範例](#meterusage-java-example)。無論語言為何，都適用下列許多步驟。

**範例： AWS Marketplace Metering Service 整合**

1. 登入 [AWS Marketplace 管理入口網站](https://aws.amazon.com/marketplace/management/tour)。

1. 從**資產**中，選擇**容器**以開始建立新的容器產品。建立產品會產生產品的產品代碼，以與您的容器映像整合。如需設定 AWS Identity and Access Management (IAM) 許可的詳細資訊，請參閱 [AWS Marketplace 計量和權利 API 許可](iam-user-policy-for-aws-marketplace-actions.md)。

1.  下載公有 [AWS Java 開發套件](https://aws.amazon.com/sdk-for-java/)。
**重要**  
 若要從 Amazon Elastic Kubernetes Service (Amazon EKS) 呼叫計量 API 操作[，您必須使用支援的 AWS SDK](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts-minimum-sdk.html)，並在執行 Kubernetes 1.13 或更新版本的 Amazon EKS 叢集上執行。

1. 每個維度用量每小時從任務或 Pod 呼叫一次 `MeterUsage`操作。API 操作接受 `Dimension`、 `Resource`和 唯一組合的一個計量記錄`Hour`。資源可以是 Amazon Elastic Container Service (Amazon ECS) 任務或 Amazon EKS Pod。

   ```
   {
       "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.
   }
   ```
**注意**  
連接到 時，可能會看到暫時性問題 AWS Marketplace Metering Service。 AWS Marketplace 強烈建議在指數退避的情況下，實作重試長達 30 分鐘，以避免短期中斷或網路問題。

1. 重建容器映像的新版本，其中包含`MeterUsage`呼叫、標記容器，並將其推送至與 Amazon ECS 或 Amazon EKS 相容的任何 Docker 登錄檔，例如 Amazon Elastic Container Registry (Amazon ECR)。如果您使用的是 Amazon ECR，請確定啟動 Amazon ECS 任務或 Amazon EKS Pod 的帳戶具有 Amazon ECR 儲存庫的許可。否則，操作會失敗。

1. 建立 [IAM](https://aws.amazon.com/iam/) 角色，授予容器呼叫 的許可`MeterUsage`，如下列程式碼範例所定義。您必須在 Amazon ECS 任務或 Amazon EKS Pod 定義的[任務角色](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_role_arn)參數中提供此 AWS Identity and Access Management (IAM) 角色。

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

****  

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

------

1. 建立 Amazon ECS 任務或 Amazon EKS Pod 定義，參考與 整合的容器， AWS Marketplace 並參考您在步驟 6 中建立的 IAM 角色。如果您想要查看記錄，請在任務定義中啟用 AWS CloudTrail 記錄。

1. 建立 Amazon ECS 或 Amazon EKS 叢集來執行您的任務或 Pod。如需建立 Amazon ECS 叢集的詳細資訊，請參閱《*Amazon Elastic Container Service 開發人員指南*》中的[建立叢集](https://docs.aws.amazon.com/AmazonECS/latest/userguide/create_cluster.html)。如需建立 Amazon EKS 叢集 （使用 Kubernetes 1.1.3.x 版或更新版本） 的詳細資訊，請參閱[建立 Amazon EKS 叢集](https://docs.aws.amazon.com/eks/latest/userguide/create_cluster.html)。

1. 設定 Amazon ECS 或 Amazon EKS 叢集，並在 us-east-1 AWS Region 中啟動您在步驟 8 中建立的 Amazon ECS 任務定義或 Amazon EKS Pod。只有在此測試程序期間，在產品上線之前，您必須使用此區域。

1. 當您從 取得`MeterUsage`針對產品發佈的每個維度的有效回應時，您可以開始建立容器產品。如有疑問，請聯絡[AWS Marketplace 賣方營運](https://aws.amazon.com/marketplace/management/contact-us/)團隊。

## `MeterUsage` Java 範例
<a name="meterusage-java-example"></a>

下列程式碼範例使用 適用於 Java 的 AWS SDK 和 AWS Marketplace Metering Service 來呼叫 `MeterUsage`操作。

下列程式碼範例在沒有 的情況下呼叫 `MeterUsage`操作`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);
    }
}
```

下列程式碼範例使用 呼叫 `MeterUsage`操作`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();
    }
```