如何在Java中通过Billing API区分GCP原生服务与Marketplace采购产品
区分GCP原生服务与Marketplace产品(Billing API实现)
核心判断逻辑基于Billing API返回的Service和Sku对象特征字段,以下是具体规则和Java实现代码:
判断规则
- 服务商标识:原生服务的
service.providerName固定为"Google",Marketplace产品的该字段为第三方厂商名称(如"Datadog"、"MongoDB Inc.") - 资源分类:Marketplace产品的
service.category.resourceFamily通常为"Marketplace" - SKU描述:部分Marketplace产品的SKU描述会包含
"Marketplace"关键词(可作为辅助判断)
Java代码示例
首先添加Maven依赖:
<dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-billing</artifactId> <version>3.21.0</version> <!-- 替换为最新版本 --> </dependency>
实现代码:
import com.google.cloud.billing.v1.BillingAccount; import com.google.cloud.billing.v1.BillingClient; import com.google.cloud.billing.v1.ListBillingAccountsRequest; import com.google.cloud.billing.v1.ProjectBillingInfo; import com.google.cloud.billing.v1.Sku; import com.google.cloud.billing.v1.ListSkusRequest; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class MarketplaceProductLister { public static void main(String[] args) throws IOException { // 初始化Billing客户端 try (BillingClient billingClient = BillingClient.create()) { // 获取所有账单账号 ListBillingAccountsRequest accountRequest = ListBillingAccountsRequest.newBuilder() .setPageSize(100) .build(); for (BillingAccount account : billingClient.listBillingAccounts(accountRequest).iterateAll()) { System.out.printf("=== 账单账号: %s ===%n", account.getName()); // 获取该账单账号关联的所有项目 for (ProjectBillingInfo projectInfo : billingClient.listProjectBillingInfo(account.getName()).iterateAll()) { String projectId = projectInfo.getProjectId(); System.out.printf("--- 项目: %s ---%n", projectId); // 获取该项目对应的Marketplace产品SKUs List<Sku> marketplaceSkus = getMarketplaceSkus(billingClient, account.getName()); if (marketplaceSkus.isEmpty()) { System.out.println("无Marketplace采购产品"); continue; } // 去重并输出产品列表 List<String> productNames = new ArrayList<>(); for (Sku sku : marketplaceSkus) { String product = String.format("%s (厂商: %s)", sku.getService().getDisplayName(), sku.getService().getProviderName()); if (!productNames.contains(product)) { productNames.add(product); } } System.out.println("Marketplace产品列表:"); productNames.forEach(name -> System.out.println("- " + name)); } } } } private static List<Sku> getMarketplaceSkus(BillingClient billingClient, String billingAccountName) { List<Sku> skus = new ArrayList<>(); ListSkusRequest skuRequest = ListSkusRequest.newBuilder() .setParent(billingAccountName) .setPageSize(1000) .build(); for (Sku sku : billingClient.listSkus(skuRequest).iterateAll()) { // 核心判断:服务商非Google,或资源分类为Marketplace boolean isMarketplace = !"Google".equals(sku.getService().getProviderName()) || "Marketplace".equals(sku.getService().getCategory().getResourceFamily()); if (isMarketplace) { skus.add(sku); } } return skus; } }
注意事项
- 运行代码的服务账号需要拥有
roles/billing.viewer角色,确保能访问账单和项目关联信息 - 若需精准关联单个项目,可结合Cloud Asset API获取项目ID列表,再通过
ProjectBillingInfo匹配对应账单账号 - 部分旧版Marketplace产品分类标识不明显,建议优先以
providerName作为判断依据
内容的提问来源于stack exchange,提问作者Demetrio Laganà
相关产品推荐
相关产品推荐

