From 2145cee790f5f0640b2d926af33558025700ec69 Mon Sep 17 00:00:00 2001 From: Yoshi Automation Bot Date: Wed, 16 Dec 2020 09:09:49 -0800 Subject: [PATCH] feat: Add support for "billingAccounts" as another parent resource name for recommendations and insights APIs. (#383) PiperOrigin-RevId: 347703845 Source-Author: Google APIs Source-Date: Tue Dec 15 15:22:41 2020 -0800 Source-Repo: googleapis/googleapis Source-Sha: 5256ab60f3d396a3d1bd393043776936b9651c5b Source-Link: https://github.com/googleapis/googleapis/commit/5256ab60f3d396a3d1bd393043776936b9651c5b --- .../recommender/v1/RecommenderClient.java | 12 ++ .../recommender/v1/RecommenderClientTest.java | 96 ++++++--- .../cloud/recommender/v1/InsightName.java | 180 +++++++++++++++-- .../cloud/recommender/v1/InsightProto.java | 45 +++-- .../cloud/recommender/v1/InsightTypeName.java | 152 +++++++++++++- .../recommender/v1/ListInsightsRequest.java | 14 ++ .../v1/ListInsightsRequestOrBuilder.java | 4 + .../v1/ListRecommendationsRequest.java | 14 ++ .../ListRecommendationsRequestOrBuilder.java | 4 + .../cloud/recommender/v1/Operation.java | 66 +++--- .../recommender/v1/OperationOrBuilder.java | 30 +-- .../recommender/v1/RecommendationName.java | 191 ++++++++++++++++-- .../v1/RecommendationOuterClass.java | 97 ++++----- .../cloud/recommender/v1/RecommenderName.java | 152 +++++++++++++- .../recommender/v1/RecommenderProto.java | 117 ++++++----- .../google/cloud/recommender/v1/insight.proto | 2 + .../cloud/recommender/v1/recommendation.proto | 8 +- .../recommender/v1/recommender_service.proto | 32 +++ synth.metadata | 8 +- 19 files changed, 976 insertions(+), 248 deletions(-) diff --git a/google-cloud-recommender/src/main/java/com/google/cloud/recommender/v1/RecommenderClient.java b/google-cloud-recommender/src/main/java/com/google/cloud/recommender/v1/RecommenderClient.java index 203b30a4..7ff0ab7c 100644 --- a/google-cloud-recommender/src/main/java/com/google/cloud/recommender/v1/RecommenderClient.java +++ b/google-cloud-recommender/src/main/java/com/google/cloud/recommender/v1/RecommenderClient.java @@ -153,6 +153,8 @@ public RecommenderStub getStub() { * formats: *

1. "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", *

LOCATION here refers to GCP Locations: https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ public final ListInsightsPagedResponse listInsights(InsightTypeName parent) { @@ -172,6 +174,8 @@ public final ListInsightsPagedResponse listInsights(InsightTypeName parent) { * formats: *

1. "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", *

LOCATION here refers to GCP Locations: https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ public final ListInsightsPagedResponse listInsights(String parent) { @@ -356,6 +360,8 @@ public final UnaryCallable markInsightAccep * formats: *

1. "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", *

LOCATION here refers to GCP Locations: https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ public final ListRecommendationsPagedResponse listRecommendations(RecommenderName parent) { @@ -375,6 +381,8 @@ public final ListRecommendationsPagedResponse listRecommendations(RecommenderNam * formats: *

1. "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", *

LOCATION here refers to GCP Locations: https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * @throws com.google.api.gax.rpc.ApiException if the remote call fails */ public final ListRecommendationsPagedResponse listRecommendations(String parent) { @@ -392,6 +400,8 @@ public final ListRecommendationsPagedResponse listRecommendations(String parent) * formats: *

1. "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", *

LOCATION here refers to GCP Locations: https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * @param filter Filter expression to restrict the recommendations returned. Supported filter * fields: state_info.state Eg: `state_info.state:"DISMISSED" or state_info.state:"FAILED" * @throws com.google.api.gax.rpc.ApiException if the remote call fails @@ -415,6 +425,8 @@ public final ListRecommendationsPagedResponse listRecommendations( * formats: *

1. "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", *

LOCATION here refers to GCP Locations: https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * @param filter Filter expression to restrict the recommendations returned. Supported filter * fields: state_info.state Eg: `state_info.state:"DISMISSED" or state_info.state:"FAILED" * @throws com.google.api.gax.rpc.ApiException if the remote call fails diff --git a/google-cloud-recommender/src/test/java/com/google/cloud/recommender/v1/RecommenderClientTest.java b/google-cloud-recommender/src/test/java/com/google/cloud/recommender/v1/RecommenderClientTest.java index 234482be..2ebd5629 100644 --- a/google-cloud-recommender/src/test/java/com/google/cloud/recommender/v1/RecommenderClientTest.java +++ b/google-cloud-recommender/src/test/java/com/google/cloud/recommender/v1/RecommenderClientTest.java @@ -95,7 +95,9 @@ public void listInsightsTest() throws Exception { .build(); mockRecommender.addResponse(expectedResponse); - InsightTypeName parent = InsightTypeName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]"); + InsightTypeName parent = + InsightTypeName.ofProjectLocationInsightTypeName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]"); ListInsightsPagedResponse pagedListResponse = client.listInsights(parent); @@ -121,7 +123,9 @@ public void listInsightsExceptionTest() throws Exception { mockRecommender.addException(exception); try { - InsightTypeName parent = InsightTypeName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]"); + InsightTypeName parent = + InsightTypeName.ofProjectLocationInsightTypeName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]"); client.listInsights(parent); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { @@ -178,7 +182,9 @@ public void getInsightTest() throws Exception { Insight expectedResponse = Insight.newBuilder() .setName( - InsightName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]").toString()) + InsightName.ofProjectLocationInsightTypeInsightName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]") + .toString()) .setDescription("description-1724546052") .addAllTargetResources(new ArrayList()) .setInsightSubtype("insightSubtype841535170") @@ -191,7 +197,9 @@ public void getInsightTest() throws Exception { .build(); mockRecommender.addResponse(expectedResponse); - InsightName name = InsightName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]"); + InsightName name = + InsightName.ofProjectLocationInsightTypeInsightName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]"); Insight actualResponse = client.getInsight(name); Assert.assertEquals(expectedResponse, actualResponse); @@ -213,7 +221,9 @@ public void getInsightExceptionTest() throws Exception { mockRecommender.addException(exception); try { - InsightName name = InsightName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]"); + InsightName name = + InsightName.ofProjectLocationInsightTypeInsightName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]"); client.getInsight(name); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { @@ -226,7 +236,9 @@ public void getInsightTest2() throws Exception { Insight expectedResponse = Insight.newBuilder() .setName( - InsightName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]").toString()) + InsightName.ofProjectLocationInsightTypeInsightName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]") + .toString()) .setDescription("description-1724546052") .addAllTargetResources(new ArrayList()) .setInsightSubtype("insightSubtype841535170") @@ -274,7 +286,9 @@ public void markInsightAcceptedTest() throws Exception { Insight expectedResponse = Insight.newBuilder() .setName( - InsightName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]").toString()) + InsightName.ofProjectLocationInsightTypeInsightName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]") + .toString()) .setDescription("description-1724546052") .addAllTargetResources(new ArrayList()) .setInsightSubtype("insightSubtype841535170") @@ -287,7 +301,9 @@ public void markInsightAcceptedTest() throws Exception { .build(); mockRecommender.addResponse(expectedResponse); - InsightName name = InsightName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]"); + InsightName name = + InsightName.ofProjectLocationInsightTypeInsightName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]"); Map stateMetadata = new HashMap<>(); String etag = "etag3123477"; @@ -313,7 +329,9 @@ public void markInsightAcceptedExceptionTest() throws Exception { mockRecommender.addException(exception); try { - InsightName name = InsightName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]"); + InsightName name = + InsightName.ofProjectLocationInsightTypeInsightName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]"); Map stateMetadata = new HashMap<>(); String etag = "etag3123477"; client.markInsightAccepted(name, stateMetadata, etag); @@ -328,7 +346,9 @@ public void markInsightAcceptedTest2() throws Exception { Insight expectedResponse = Insight.newBuilder() .setName( - InsightName.of("[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]").toString()) + InsightName.ofProjectLocationInsightTypeInsightName( + "[PROJECT]", "[LOCATION]", "[INSIGHT_TYPE]", "[INSIGHT]") + .toString()) .setDescription("description-1724546052") .addAllTargetResources(new ArrayList()) .setInsightSubtype("insightSubtype841535170") @@ -387,7 +407,9 @@ public void listRecommendationsTest() throws Exception { .build(); mockRecommender.addResponse(expectedResponse); - RecommenderName parent = RecommenderName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]"); + RecommenderName parent = + RecommenderName.ofProjectLocationRecommenderName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]"); ListRecommendationsPagedResponse pagedListResponse = client.listRecommendations(parent); @@ -413,7 +435,9 @@ public void listRecommendationsExceptionTest() throws Exception { mockRecommender.addException(exception); try { - RecommenderName parent = RecommenderName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]"); + RecommenderName parent = + RecommenderName.ofProjectLocationRecommenderName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]"); client.listRecommendations(parent); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { @@ -475,7 +499,9 @@ public void listRecommendationsTest3() throws Exception { .build(); mockRecommender.addResponse(expectedResponse); - RecommenderName parent = RecommenderName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]"); + RecommenderName parent = + RecommenderName.ofProjectLocationRecommenderName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]"); String filter = "filter-1274492040"; ListRecommendationsPagedResponse pagedListResponse = client.listRecommendations(parent, filter); @@ -503,7 +529,9 @@ public void listRecommendationsExceptionTest3() throws Exception { mockRecommender.addException(exception); try { - RecommenderName parent = RecommenderName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]"); + RecommenderName parent = + RecommenderName.ofProjectLocationRecommenderName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]"); String filter = "filter-1274492040"; client.listRecommendations(parent, filter); Assert.fail("No exception raised"); @@ -564,7 +592,7 @@ public void getRecommendationTest() throws Exception { Recommendation expectedResponse = Recommendation.newBuilder() .setName( - RecommendationName.of( + RecommendationName.ofProjectLocationRecommenderRecommendationName( "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") .toString()) .setDescription("description-1724546052") @@ -580,7 +608,8 @@ public void getRecommendationTest() throws Exception { mockRecommender.addResponse(expectedResponse); RecommendationName name = - RecommendationName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); + RecommendationName.ofProjectLocationRecommenderRecommendationName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); Recommendation actualResponse = client.getRecommendation(name); Assert.assertEquals(expectedResponse, actualResponse); @@ -603,7 +632,8 @@ public void getRecommendationExceptionTest() throws Exception { try { RecommendationName name = - RecommendationName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); + RecommendationName.ofProjectLocationRecommenderRecommendationName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); client.getRecommendation(name); Assert.fail("No exception raised"); } catch (InvalidArgumentException e) { @@ -616,7 +646,7 @@ public void getRecommendationTest2() throws Exception { Recommendation expectedResponse = Recommendation.newBuilder() .setName( - RecommendationName.of( + RecommendationName.ofProjectLocationRecommenderRecommendationName( "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") .toString()) .setDescription("description-1724546052") @@ -666,7 +696,7 @@ public void markRecommendationClaimedTest() throws Exception { Recommendation expectedResponse = Recommendation.newBuilder() .setName( - RecommendationName.of( + RecommendationName.ofProjectLocationRecommenderRecommendationName( "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") .toString()) .setDescription("description-1724546052") @@ -682,7 +712,8 @@ public void markRecommendationClaimedTest() throws Exception { mockRecommender.addResponse(expectedResponse); RecommendationName name = - RecommendationName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); + RecommendationName.ofProjectLocationRecommenderRecommendationName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); Map stateMetadata = new HashMap<>(); String etag = "etag3123477"; @@ -710,7 +741,8 @@ public void markRecommendationClaimedExceptionTest() throws Exception { try { RecommendationName name = - RecommendationName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); + RecommendationName.ofProjectLocationRecommenderRecommendationName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); Map stateMetadata = new HashMap<>(); String etag = "etag3123477"; client.markRecommendationClaimed(name, stateMetadata, etag); @@ -725,7 +757,7 @@ public void markRecommendationClaimedTest2() throws Exception { Recommendation expectedResponse = Recommendation.newBuilder() .setName( - RecommendationName.of( + RecommendationName.ofProjectLocationRecommenderRecommendationName( "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") .toString()) .setDescription("description-1724546052") @@ -782,7 +814,7 @@ public void markRecommendationSucceededTest() throws Exception { Recommendation expectedResponse = Recommendation.newBuilder() .setName( - RecommendationName.of( + RecommendationName.ofProjectLocationRecommenderRecommendationName( "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") .toString()) .setDescription("description-1724546052") @@ -798,7 +830,8 @@ public void markRecommendationSucceededTest() throws Exception { mockRecommender.addResponse(expectedResponse); RecommendationName name = - RecommendationName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); + RecommendationName.ofProjectLocationRecommenderRecommendationName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); Map stateMetadata = new HashMap<>(); String etag = "etag3123477"; @@ -826,7 +859,8 @@ public void markRecommendationSucceededExceptionTest() throws Exception { try { RecommendationName name = - RecommendationName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); + RecommendationName.ofProjectLocationRecommenderRecommendationName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); Map stateMetadata = new HashMap<>(); String etag = "etag3123477"; client.markRecommendationSucceeded(name, stateMetadata, etag); @@ -841,7 +875,7 @@ public void markRecommendationSucceededTest2() throws Exception { Recommendation expectedResponse = Recommendation.newBuilder() .setName( - RecommendationName.of( + RecommendationName.ofProjectLocationRecommenderRecommendationName( "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") .toString()) .setDescription("description-1724546052") @@ -898,7 +932,7 @@ public void markRecommendationFailedTest() throws Exception { Recommendation expectedResponse = Recommendation.newBuilder() .setName( - RecommendationName.of( + RecommendationName.ofProjectLocationRecommenderRecommendationName( "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") .toString()) .setDescription("description-1724546052") @@ -914,7 +948,8 @@ public void markRecommendationFailedTest() throws Exception { mockRecommender.addResponse(expectedResponse); RecommendationName name = - RecommendationName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); + RecommendationName.ofProjectLocationRecommenderRecommendationName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); Map stateMetadata = new HashMap<>(); String etag = "etag3123477"; @@ -942,7 +977,8 @@ public void markRecommendationFailedExceptionTest() throws Exception { try { RecommendationName name = - RecommendationName.of("[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); + RecommendationName.ofProjectLocationRecommenderRecommendationName( + "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]"); Map stateMetadata = new HashMap<>(); String etag = "etag3123477"; client.markRecommendationFailed(name, stateMetadata, etag); @@ -957,7 +993,7 @@ public void markRecommendationFailedTest2() throws Exception { Recommendation expectedResponse = Recommendation.newBuilder() .setName( - RecommendationName.of( + RecommendationName.ofProjectLocationRecommenderRecommendationName( "[PROJECT]", "[LOCATION]", "[RECOMMENDER]", "[RECOMMENDATION]") .toString()) .setDescription("description-1724546052") diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightName.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightName.java index 7ada74c3..65a11f30 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightName.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightName.java @@ -16,7 +16,9 @@ package com.google.cloud.recommender.v1; +import com.google.api.core.BetaApi; import com.google.api.pathtemplate.PathTemplate; +import com.google.api.pathtemplate.ValidationException; import com.google.api.resourcenames.ResourceName; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; @@ -32,11 +34,17 @@ public class InsightName implements ResourceName { private static final PathTemplate PROJECT_LOCATION_INSIGHT_TYPE_INSIGHT = PathTemplate.createWithoutUrlEncoding( "projects/{project}/locations/{location}/insightTypes/{insight_type}/insights/{insight}"); + private static final PathTemplate BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE_INSIGHT = + PathTemplate.createWithoutUrlEncoding( + "billingAccounts/{billing_account}/locations/{location}/insightTypes/{insight_type}/insights/{insight}"); private volatile Map fieldValuesMap; + private PathTemplate pathTemplate; + private String fixedValue; private final String project; private final String location; private final String insightType; private final String insight; + private final String billingAccount; @Deprecated protected InsightName() { @@ -44,6 +52,7 @@ protected InsightName() { location = null; insightType = null; insight = null; + billingAccount = null; } private InsightName(Builder builder) { @@ -51,6 +60,17 @@ private InsightName(Builder builder) { location = Preconditions.checkNotNull(builder.getLocation()); insightType = Preconditions.checkNotNull(builder.getInsightType()); insight = Preconditions.checkNotNull(builder.getInsight()); + billingAccount = null; + pathTemplate = PROJECT_LOCATION_INSIGHT_TYPE_INSIGHT; + } + + private InsightName(BillingAccountLocationInsightTypeInsightBuilder builder) { + billingAccount = Preconditions.checkNotNull(builder.getBillingAccount()); + location = Preconditions.checkNotNull(builder.getLocation()); + insightType = Preconditions.checkNotNull(builder.getInsightType()); + insight = Preconditions.checkNotNull(builder.getInsight()); + project = null; + pathTemplate = BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE_INSIGHT; } public String getProject() { @@ -69,10 +89,25 @@ public String getInsight() { return insight; } + public String getBillingAccount() { + return billingAccount; + } + public static Builder newBuilder() { return new Builder(); } + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static Builder newProjectLocationInsightTypeInsightBuilder() { + return new Builder(); + } + + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static BillingAccountLocationInsightTypeInsightBuilder + newBillingAccountLocationInsightTypeInsightBuilder() { + return new BillingAccountLocationInsightTypeInsightBuilder(); + } + public Builder toBuilder() { return new Builder(this); } @@ -87,6 +122,28 @@ public static InsightName of( .build(); } + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static InsightName ofProjectLocationInsightTypeInsightName( + String project, String location, String insightType, String insight) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setInsightType(insightType) + .setInsight(insight) + .build(); + } + + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static InsightName ofBillingAccountLocationInsightTypeInsightName( + String billingAccount, String location, String insightType, String insight) { + return newBillingAccountLocationInsightTypeInsightBuilder() + .setBillingAccount(billingAccount) + .setLocation(location) + .setInsightType(insightType) + .setInsight(insight) + .build(); + } + public static String format(String project, String location, String insightType, String insight) { return newBuilder() .setProject(project) @@ -97,18 +154,51 @@ public static String format(String project, String location, String insightType, .toString(); } + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatProjectLocationInsightTypeInsightName( + String project, String location, String insightType, String insight) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setInsightType(insightType) + .setInsight(insight) + .build() + .toString(); + } + + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatBillingAccountLocationInsightTypeInsightName( + String billingAccount, String location, String insightType, String insight) { + return newBillingAccountLocationInsightTypeInsightBuilder() + .setBillingAccount(billingAccount) + .setLocation(location) + .setInsightType(insightType) + .setInsight(insight) + .build() + .toString(); + } + public static InsightName parse(String formattedString) { if (formattedString.isEmpty()) { return null; } - Map matchMap = - PROJECT_LOCATION_INSIGHT_TYPE_INSIGHT.validatedMatch( - formattedString, "InsightName.parse: formattedString not in valid format"); - return of( - matchMap.get("project"), - matchMap.get("location"), - matchMap.get("insight_type"), - matchMap.get("insight")); + if (PROJECT_LOCATION_INSIGHT_TYPE_INSIGHT.matches(formattedString)) { + Map matchMap = PROJECT_LOCATION_INSIGHT_TYPE_INSIGHT.match(formattedString); + return ofProjectLocationInsightTypeInsightName( + matchMap.get("project"), + matchMap.get("location"), + matchMap.get("insight_type"), + matchMap.get("insight")); + } else if (BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE_INSIGHT.matches(formattedString)) { + Map matchMap = + BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE_INSIGHT.match(formattedString); + return ofBillingAccountLocationInsightTypeInsightName( + matchMap.get("billing_account"), + matchMap.get("location"), + matchMap.get("insight_type"), + matchMap.get("insight")); + } + throw new ValidationException("InsightName.parse: formattedString not in valid format"); } public static List parseList(List formattedStrings) { @@ -132,7 +222,8 @@ public static List toStringList(List values) { } public static boolean isParsableFrom(String formattedString) { - return PROJECT_LOCATION_INSIGHT_TYPE_INSIGHT.matches(formattedString); + return PROJECT_LOCATION_INSIGHT_TYPE_INSIGHT.matches(formattedString) + || BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE_INSIGHT.matches(formattedString); } @Override @@ -153,6 +244,9 @@ public Map getFieldValuesMap() { if (insight != null) { fieldMapBuilder.put("insight", insight); } + if (billingAccount != null) { + fieldMapBuilder.put("billing_account", billingAccount); + } fieldValuesMap = fieldMapBuilder.build(); } } @@ -166,8 +260,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return PROJECT_LOCATION_INSIGHT_TYPE_INSIGHT.instantiate( - "project", project, "location", location, "insight_type", insightType, "insight", insight); + return fixedValue != null ? fixedValue : pathTemplate.instantiate(getFieldValuesMap()); } @Override @@ -180,7 +273,8 @@ public boolean equals(Object o) { return Objects.equals(this.project, that.project) && Objects.equals(this.location, that.location) && Objects.equals(this.insightType, that.insightType) - && Objects.equals(this.insight, that.insight); + && Objects.equals(this.insight, that.insight) + && Objects.equals(this.billingAccount, that.billingAccount); } return false; } @@ -189,6 +283,8 @@ public boolean equals(Object o) { public int hashCode() { int h = 1; h *= 1000003; + h ^= Objects.hashCode(fixedValue); + h *= 1000003; h ^= Objects.hashCode(project); h *= 1000003; h ^= Objects.hashCode(location); @@ -196,6 +292,8 @@ public int hashCode() { h ^= Objects.hashCode(insightType); h *= 1000003; h ^= Objects.hashCode(insight); + h *= 1000003; + h ^= Objects.hashCode(billingAccount); return h; } @@ -248,6 +346,9 @@ public Builder setInsight(String insight) { } private Builder(InsightName insightName) { + Preconditions.checkArgument( + Objects.equals(insightName.pathTemplate, PROJECT_LOCATION_INSIGHT_TYPE_INSIGHT), + "toBuilder is only supported when InsightName has the pattern of projects/{project}/locations/{location}/insightTypes/{insight_type}/insights/{insight}"); project = insightName.project; location = insightName.location; insightType = insightName.insightType; @@ -258,4 +359,59 @@ public InsightName build() { return new InsightName(this); } } + + /** + * Builder for + * billingAccounts/{billing_account}/locations/{location}/insightTypes/{insight_type}/insights/{insight}. + */ + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static class BillingAccountLocationInsightTypeInsightBuilder { + private String billingAccount; + private String location; + private String insightType; + private String insight; + + protected BillingAccountLocationInsightTypeInsightBuilder() {} + + public String getBillingAccount() { + return billingAccount; + } + + public String getLocation() { + return location; + } + + public String getInsightType() { + return insightType; + } + + public String getInsight() { + return insight; + } + + public BillingAccountLocationInsightTypeInsightBuilder setBillingAccount( + String billingAccount) { + this.billingAccount = billingAccount; + return this; + } + + public BillingAccountLocationInsightTypeInsightBuilder setLocation(String location) { + this.location = location; + return this; + } + + public BillingAccountLocationInsightTypeInsightBuilder setInsightType(String insightType) { + this.insightType = insightType; + return this; + } + + public BillingAccountLocationInsightTypeInsightBuilder setInsight(String insight) { + this.insight = insight; + return this; + } + + public InsightName build() { + return new InsightName(this); + } + } } diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightProto.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightProto.java index e968b2b5..a3f8e262 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightProto.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightProto.java @@ -56,7 +56,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "oto\022\033google.cloud.recommender.v1\032\031google" + "/api/resource.proto\032\036google/protobuf/dur" + "ation.proto\032\034google/protobuf/struct.prot" - + "o\032\037google/protobuf/timestamp.proto\"\201\006\n\007I" + + "o\032\037google/protobuf/timestamp.proto\"\352\006\n\007I" + "nsight\022\014\n\004name\030\001 \001(\t\022\023\n\013description\030\002 \001(" + "\t\022\030\n\020target_resources\030\t \003(\t\022\027\n\017insight_s" + "ubtype\030\n \001(\t\022(\n\007content\030\003 \001(\0132\027.google.p" @@ -72,25 +72,30 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "eference\0321\n\027RecommendationReference\022\026\n\016r" + "ecommendation\030\001 \001(\t\"`\n\010Category\022\030\n\024CATEG" + "ORY_UNSPECIFIED\020\000\022\010\n\004COST\020\001\022\014\n\010SECURITY\020" - + "\002\022\017\n\013PERFORMANCE\020\003\022\021\n\rMANAGEABILITY\020\004:\177\352" - + "A|\n\"recommender.googleapis.com/Insight\022V" - + "projects/{project}/locations/{location}/" - + "insightTypes/{insight_type}/insights/{in" - + "sight}\"\257\002\n\020InsightStateInfo\022B\n\005state\030\001 \001" - + "(\01623.google.cloud.recommender.v1.Insight" - + "StateInfo.State\022X\n\016state_metadata\030\002 \003(\0132" - + "@.google.cloud.recommender.v1.InsightSta" - + "teInfo.StateMetadataEntry\0324\n\022StateMetada" - + "taEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"" - + "G\n\005State\022\025\n\021STATE_UNSPECIFIED\020\000\022\n\n\006ACTIV" - + "E\020\001\022\014\n\010ACCEPTED\020\002\022\r\n\tDISMISSED\020\003B\216\002\n\037com" - + ".google.cloud.recommender.v1B\014InsightPro" - + "toP\001ZFgoogle.golang.org/genproto/googlea" - + "pis/cloud/recommender/v1;recommender\242\002\004C" - + "REC\252\002\033Google.Cloud.Recommender.V1\352Am\n&re" - + "commender.googleapis.com/InsightType\022Cpr" - + "ojects/{project}/locations/{location}/in" - + "sightTypes/{insight_type}b\006proto3" + + "\002\022\017\n\013PERFORMANCE\020\003\022\021\n\rMANAGEABILITY\020\004:\347\001" + + "\352A\343\001\n\"recommender.googleapis.com/Insight" + + "\022Vprojects/{project}/locations/{location" + + "}/insightTypes/{insight_type}/insights/{" + + "insight}\022ebillingAccounts/{billing_accou" + + "nt}/locations/{location}/insightTypes/{i" + + "nsight_type}/insights/{insight}\"\257\002\n\020Insi" + + "ghtStateInfo\022B\n\005state\030\001 \001(\01623.google.clo" + + "ud.recommender.v1.InsightStateInfo.State" + + "\022X\n\016state_metadata\030\002 \003(\0132@.google.cloud." + + "recommender.v1.InsightStateInfo.StateMet" + + "adataEntry\0324\n\022StateMetadataEntry\022\013\n\003key\030" + + "\001 \001(\t\022\r\n\005value\030\002 \001(\t:\0028\001\"G\n\005State\022\025\n\021STA" + + "TE_UNSPECIFIED\020\000\022\n\n\006ACTIVE\020\001\022\014\n\010ACCEPTED" + + "\020\002\022\r\n\tDISMISSED\020\003B\343\002\n\037com.google.cloud.r" + + "ecommender.v1B\014InsightProtoP\001ZFgoogle.go" + + "lang.org/genproto/googleapis/cloud/recom" + + "mender/v1;recommender\242\002\004CREC\252\002\033Google.Cl" + + "oud.Recommender.V1\352A\301\001\n&recommender.goog" + + "leapis.com/InsightType\022Cprojects/{projec" + + "t}/locations/{location}/insightTypes/{in" + + "sight_type}\022RbillingAccounts/{billing_ac" + + "count}/locations/{location}/insightTypes" + + "/{insight_type}b\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightTypeName.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightTypeName.java index 0cc565f7..f680d1b6 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightTypeName.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/InsightTypeName.java @@ -16,7 +16,9 @@ package com.google.cloud.recommender.v1; +import com.google.api.core.BetaApi; import com.google.api.pathtemplate.PathTemplate; +import com.google.api.pathtemplate.ValidationException; import com.google.api.resourcenames.ResourceName; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; @@ -32,22 +34,39 @@ public class InsightTypeName implements ResourceName { private static final PathTemplate PROJECT_LOCATION_INSIGHT_TYPE = PathTemplate.createWithoutUrlEncoding( "projects/{project}/locations/{location}/insightTypes/{insight_type}"); + private static final PathTemplate BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE = + PathTemplate.createWithoutUrlEncoding( + "billingAccounts/{billing_account}/locations/{location}/insightTypes/{insight_type}"); private volatile Map fieldValuesMap; + private PathTemplate pathTemplate; + private String fixedValue; private final String project; private final String location; private final String insightType; + private final String billingAccount; @Deprecated protected InsightTypeName() { project = null; location = null; insightType = null; + billingAccount = null; } private InsightTypeName(Builder builder) { project = Preconditions.checkNotNull(builder.getProject()); location = Preconditions.checkNotNull(builder.getLocation()); insightType = Preconditions.checkNotNull(builder.getInsightType()); + billingAccount = null; + pathTemplate = PROJECT_LOCATION_INSIGHT_TYPE; + } + + private InsightTypeName(BillingAccountLocationInsightTypeBuilder builder) { + billingAccount = Preconditions.checkNotNull(builder.getBillingAccount()); + location = Preconditions.checkNotNull(builder.getLocation()); + insightType = Preconditions.checkNotNull(builder.getInsightType()); + project = null; + pathTemplate = BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE; } public String getProject() { @@ -62,10 +81,25 @@ public String getInsightType() { return insightType; } + public String getBillingAccount() { + return billingAccount; + } + public static Builder newBuilder() { return new Builder(); } + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static Builder newProjectLocationInsightTypeBuilder() { + return new Builder(); + } + + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static BillingAccountLocationInsightTypeBuilder + newBillingAccountLocationInsightTypeBuilder() { + return new BillingAccountLocationInsightTypeBuilder(); + } + public Builder toBuilder() { return new Builder(this); } @@ -78,6 +112,26 @@ public static InsightTypeName of(String project, String location, String insight .build(); } + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static InsightTypeName ofProjectLocationInsightTypeName( + String project, String location, String insightType) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setInsightType(insightType) + .build(); + } + + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static InsightTypeName ofBillingAccountLocationInsightTypeName( + String billingAccount, String location, String insightType) { + return newBillingAccountLocationInsightTypeBuilder() + .setBillingAccount(billingAccount) + .setLocation(location) + .setInsightType(insightType) + .build(); + } + public static String format(String project, String location, String insightType) { return newBuilder() .setProject(project) @@ -87,14 +141,42 @@ public static String format(String project, String location, String insightType) .toString(); } + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatProjectLocationInsightTypeName( + String project, String location, String insightType) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setInsightType(insightType) + .build() + .toString(); + } + + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatBillingAccountLocationInsightTypeName( + String billingAccount, String location, String insightType) { + return newBillingAccountLocationInsightTypeBuilder() + .setBillingAccount(billingAccount) + .setLocation(location) + .setInsightType(insightType) + .build() + .toString(); + } + public static InsightTypeName parse(String formattedString) { if (formattedString.isEmpty()) { return null; } - Map matchMap = - PROJECT_LOCATION_INSIGHT_TYPE.validatedMatch( - formattedString, "InsightTypeName.parse: formattedString not in valid format"); - return of(matchMap.get("project"), matchMap.get("location"), matchMap.get("insight_type")); + if (PROJECT_LOCATION_INSIGHT_TYPE.matches(formattedString)) { + Map matchMap = PROJECT_LOCATION_INSIGHT_TYPE.match(formattedString); + return ofProjectLocationInsightTypeName( + matchMap.get("project"), matchMap.get("location"), matchMap.get("insight_type")); + } else if (BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE.matches(formattedString)) { + Map matchMap = BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE.match(formattedString); + return ofBillingAccountLocationInsightTypeName( + matchMap.get("billing_account"), matchMap.get("location"), matchMap.get("insight_type")); + } + throw new ValidationException("InsightTypeName.parse: formattedString not in valid format"); } public static List parseList(List formattedStrings) { @@ -118,7 +200,8 @@ public static List toStringList(List values) { } public static boolean isParsableFrom(String formattedString) { - return PROJECT_LOCATION_INSIGHT_TYPE.matches(formattedString); + return PROJECT_LOCATION_INSIGHT_TYPE.matches(formattedString) + || BILLING_ACCOUNT_LOCATION_INSIGHT_TYPE.matches(formattedString); } @Override @@ -136,6 +219,9 @@ public Map getFieldValuesMap() { if (insightType != null) { fieldMapBuilder.put("insight_type", insightType); } + if (billingAccount != null) { + fieldMapBuilder.put("billing_account", billingAccount); + } fieldValuesMap = fieldMapBuilder.build(); } } @@ -149,8 +235,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return PROJECT_LOCATION_INSIGHT_TYPE.instantiate( - "project", project, "location", location, "insight_type", insightType); + return fixedValue != null ? fixedValue : pathTemplate.instantiate(getFieldValuesMap()); } @Override @@ -162,7 +247,8 @@ public boolean equals(Object o) { InsightTypeName that = ((InsightTypeName) o); return Objects.equals(this.project, that.project) && Objects.equals(this.location, that.location) - && Objects.equals(this.insightType, that.insightType); + && Objects.equals(this.insightType, that.insightType) + && Objects.equals(this.billingAccount, that.billingAccount); } return false; } @@ -171,11 +257,15 @@ public boolean equals(Object o) { public int hashCode() { int h = 1; h *= 1000003; + h ^= Objects.hashCode(fixedValue); + h *= 1000003; h ^= Objects.hashCode(project); h *= 1000003; h ^= Objects.hashCode(location); h *= 1000003; h ^= Objects.hashCode(insightType); + h *= 1000003; + h ^= Objects.hashCode(billingAccount); return h; } @@ -215,6 +305,9 @@ public Builder setInsightType(String insightType) { } private Builder(InsightTypeName insightTypeName) { + Preconditions.checkArgument( + Objects.equals(insightTypeName.pathTemplate, PROJECT_LOCATION_INSIGHT_TYPE), + "toBuilder is only supported when InsightTypeName has the pattern of projects/{project}/locations/{location}/insightTypes/{insight_type}"); project = insightTypeName.project; location = insightTypeName.location; insightType = insightTypeName.insightType; @@ -224,4 +317,47 @@ public InsightTypeName build() { return new InsightTypeName(this); } } + + /** + * Builder for billingAccounts/{billing_account}/locations/{location}/insightTypes/{insight_type}. + */ + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static class BillingAccountLocationInsightTypeBuilder { + private String billingAccount; + private String location; + private String insightType; + + protected BillingAccountLocationInsightTypeBuilder() {} + + public String getBillingAccount() { + return billingAccount; + } + + public String getLocation() { + return location; + } + + public String getInsightType() { + return insightType; + } + + public BillingAccountLocationInsightTypeBuilder setBillingAccount(String billingAccount) { + this.billingAccount = billingAccount; + return this; + } + + public BillingAccountLocationInsightTypeBuilder setLocation(String location) { + this.location = location; + return this; + } + + public BillingAccountLocationInsightTypeBuilder setInsightType(String insightType) { + this.insightType = insightType; + return this; + } + + public InsightTypeName build() { + return new InsightTypeName(this); + } + } } diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListInsightsRequest.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListInsightsRequest.java index a2d13487..5cd9ab5e 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListInsightsRequest.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListInsightsRequest.java @@ -144,6 +144,8 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * * * @@ -174,6 +176,8 @@ public java.lang.String getParent() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * * * @@ -699,6 +703,8 @@ public Builder mergeFrom( * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * * * @@ -728,6 +734,8 @@ public java.lang.String getParent() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * * * @@ -757,6 +765,8 @@ public com.google.protobuf.ByteString getParentBytes() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * * * @@ -785,6 +795,8 @@ public Builder setParent(java.lang.String value) { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * * * @@ -809,6 +821,8 @@ public Builder clearParent() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * * * diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListInsightsRequestOrBuilder.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListInsightsRequestOrBuilder.java index c503fc64..6dbbd62d 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListInsightsRequestOrBuilder.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListInsightsRequestOrBuilder.java @@ -33,6 +33,8 @@ public interface ListInsightsRequestOrBuilder * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * * * @@ -52,6 +54,8 @@ public interface ListInsightsRequestOrBuilder * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/insightTypes/[INSIGHT_TYPE_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * INSIGHT_TYPE_ID refers to supported insight types: + * https://cloud.google.com/recommender/docs/insights/insight-types.) * * * diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListRecommendationsRequest.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListRecommendationsRequest.java index 04a36e0c..1a00512a 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListRecommendationsRequest.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListRecommendationsRequest.java @@ -144,6 +144,8 @@ public static final com.google.protobuf.Descriptors.Descriptor getDescriptor() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * * * @@ -174,6 +176,8 @@ public java.lang.String getParent() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * * * @@ -700,6 +704,8 @@ public Builder mergeFrom( * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * * * @@ -729,6 +735,8 @@ public java.lang.String getParent() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * * * @@ -758,6 +766,8 @@ public com.google.protobuf.ByteString getParentBytes() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * * * @@ -786,6 +796,8 @@ public Builder setParent(java.lang.String value) { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * * * @@ -810,6 +822,8 @@ public Builder clearParent() { * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * * * diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListRecommendationsRequestOrBuilder.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListRecommendationsRequestOrBuilder.java index cef6c5bd..d59c706a 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListRecommendationsRequestOrBuilder.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/ListRecommendationsRequestOrBuilder.java @@ -33,6 +33,8 @@ public interface ListRecommendationsRequestOrBuilder * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * * * @@ -52,6 +54,8 @@ public interface ListRecommendationsRequestOrBuilder * "projects/[PROJECT_NUMBER]/locations/[LOCATION]/recommenders/[RECOMMENDER_ID]", * LOCATION here refers to GCP Locations: * https://cloud.google.com/about/locations/ + * RECOMMENDER_ID refers to supported recommenders: + * https://cloud.google.com/recommender/docs/recommenders. * * * diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/Operation.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/Operation.java index 5ea50a5d..642a9c94 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/Operation.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/Operation.java @@ -754,12 +754,12 @@ public int getPathFiltersCount() { * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -794,12 +794,12 @@ public java.util.Map getPathFilters * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -825,12 +825,12 @@ public java.util.Map getPathFilters * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -862,12 +862,12 @@ public com.google.protobuf.Value getPathFiltersOrDefault( * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -2755,12 +2755,12 @@ public int getPathFiltersCount() { * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -2795,12 +2795,12 @@ public java.util.Map getPathFilters * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -2826,12 +2826,12 @@ public java.util.Map getPathFilters * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -2863,12 +2863,12 @@ public com.google.protobuf.Value getPathFiltersOrDefault( * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -2907,12 +2907,12 @@ public Builder clearPathFilters() { * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -2946,12 +2946,12 @@ public java.util.Map getMutablePath * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -2983,12 +2983,12 @@ public Builder putPathFilters(java.lang.String key, com.google.protobuf.Value va * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/OperationOrBuilder.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/OperationOrBuilder.java index 7dfddb0c..446c7a1d 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/OperationOrBuilder.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/OperationOrBuilder.java @@ -288,12 +288,12 @@ public interface OperationOrBuilder * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -316,12 +316,12 @@ public interface OperationOrBuilder * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -347,12 +347,12 @@ public interface OperationOrBuilder * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -375,12 +375,12 @@ public interface OperationOrBuilder * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. @@ -404,12 +404,12 @@ com.google.protobuf.Value getPathFiltersOrDefault( * "/versions/*/targetSize/percent": 20 * } * * Example: { - * "/bindings/*/role": "roles/admin" + * "/bindings/*/role": "roles/owner" * "/bindings/*/condition" : null * } * * Example: { - * "/bindings/*/role": "roles/admin" - * "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + * "/bindings/*/role": "roles/owner" + * "/bindings/*/members/*" : ["x@example.com", "y@example.com"] * } * When both path_filters and path_value_matchers are set, an implicit AND * must be performed. diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommendationName.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommendationName.java index d206b5e1..fc4fe9ae 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommendationName.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommendationName.java @@ -16,7 +16,9 @@ package com.google.cloud.recommender.v1; +import com.google.api.core.BetaApi; import com.google.api.pathtemplate.PathTemplate; +import com.google.api.pathtemplate.ValidationException; import com.google.api.resourcenames.ResourceName; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; @@ -32,11 +34,17 @@ public class RecommendationName implements ResourceName { private static final PathTemplate PROJECT_LOCATION_RECOMMENDER_RECOMMENDATION = PathTemplate.createWithoutUrlEncoding( "projects/{project}/locations/{location}/recommenders/{recommender}/recommendations/{recommendation}"); + private static final PathTemplate BILLING_ACCOUNT_LOCATION_RECOMMENDER_RECOMMENDATION = + PathTemplate.createWithoutUrlEncoding( + "billingAccounts/{billing_account}/locations/{location}/recommenders/{recommender}/recommendations/{recommendation}"); private volatile Map fieldValuesMap; + private PathTemplate pathTemplate; + private String fixedValue; private final String project; private final String location; private final String recommender; private final String recommendation; + private final String billingAccount; @Deprecated protected RecommendationName() { @@ -44,6 +52,7 @@ protected RecommendationName() { location = null; recommender = null; recommendation = null; + billingAccount = null; } private RecommendationName(Builder builder) { @@ -51,6 +60,17 @@ private RecommendationName(Builder builder) { location = Preconditions.checkNotNull(builder.getLocation()); recommender = Preconditions.checkNotNull(builder.getRecommender()); recommendation = Preconditions.checkNotNull(builder.getRecommendation()); + billingAccount = null; + pathTemplate = PROJECT_LOCATION_RECOMMENDER_RECOMMENDATION; + } + + private RecommendationName(BillingAccountLocationRecommenderRecommendationBuilder builder) { + billingAccount = Preconditions.checkNotNull(builder.getBillingAccount()); + location = Preconditions.checkNotNull(builder.getLocation()); + recommender = Preconditions.checkNotNull(builder.getRecommender()); + recommendation = Preconditions.checkNotNull(builder.getRecommendation()); + project = null; + pathTemplate = BILLING_ACCOUNT_LOCATION_RECOMMENDER_RECOMMENDATION; } public String getProject() { @@ -69,10 +89,25 @@ public String getRecommendation() { return recommendation; } + public String getBillingAccount() { + return billingAccount; + } + public static Builder newBuilder() { return new Builder(); } + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static Builder newProjectLocationRecommenderRecommendationBuilder() { + return new Builder(); + } + + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static BillingAccountLocationRecommenderRecommendationBuilder + newBillingAccountLocationRecommenderRecommendationBuilder() { + return new BillingAccountLocationRecommenderRecommendationBuilder(); + } + public Builder toBuilder() { return new Builder(this); } @@ -87,6 +122,28 @@ public static RecommendationName of( .build(); } + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static RecommendationName ofProjectLocationRecommenderRecommendationName( + String project, String location, String recommender, String recommendation) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setRecommender(recommender) + .setRecommendation(recommendation) + .build(); + } + + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static RecommendationName ofBillingAccountLocationRecommenderRecommendationName( + String billingAccount, String location, String recommender, String recommendation) { + return newBillingAccountLocationRecommenderRecommendationBuilder() + .setBillingAccount(billingAccount) + .setLocation(location) + .setRecommender(recommender) + .setRecommendation(recommendation) + .build(); + } + public static String format( String project, String location, String recommender, String recommendation) { return newBuilder() @@ -98,18 +155,52 @@ public static String format( .toString(); } + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatProjectLocationRecommenderRecommendationName( + String project, String location, String recommender, String recommendation) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setRecommender(recommender) + .setRecommendation(recommendation) + .build() + .toString(); + } + + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatBillingAccountLocationRecommenderRecommendationName( + String billingAccount, String location, String recommender, String recommendation) { + return newBillingAccountLocationRecommenderRecommendationBuilder() + .setBillingAccount(billingAccount) + .setLocation(location) + .setRecommender(recommender) + .setRecommendation(recommendation) + .build() + .toString(); + } + public static RecommendationName parse(String formattedString) { if (formattedString.isEmpty()) { return null; } - Map matchMap = - PROJECT_LOCATION_RECOMMENDER_RECOMMENDATION.validatedMatch( - formattedString, "RecommendationName.parse: formattedString not in valid format"); - return of( - matchMap.get("project"), - matchMap.get("location"), - matchMap.get("recommender"), - matchMap.get("recommendation")); + if (PROJECT_LOCATION_RECOMMENDER_RECOMMENDATION.matches(formattedString)) { + Map matchMap = + PROJECT_LOCATION_RECOMMENDER_RECOMMENDATION.match(formattedString); + return ofProjectLocationRecommenderRecommendationName( + matchMap.get("project"), + matchMap.get("location"), + matchMap.get("recommender"), + matchMap.get("recommendation")); + } else if (BILLING_ACCOUNT_LOCATION_RECOMMENDER_RECOMMENDATION.matches(formattedString)) { + Map matchMap = + BILLING_ACCOUNT_LOCATION_RECOMMENDER_RECOMMENDATION.match(formattedString); + return ofBillingAccountLocationRecommenderRecommendationName( + matchMap.get("billing_account"), + matchMap.get("location"), + matchMap.get("recommender"), + matchMap.get("recommendation")); + } + throw new ValidationException("RecommendationName.parse: formattedString not in valid format"); } public static List parseList(List formattedStrings) { @@ -133,7 +224,8 @@ public static List toStringList(List values) { } public static boolean isParsableFrom(String formattedString) { - return PROJECT_LOCATION_RECOMMENDER_RECOMMENDATION.matches(formattedString); + return PROJECT_LOCATION_RECOMMENDER_RECOMMENDATION.matches(formattedString) + || BILLING_ACCOUNT_LOCATION_RECOMMENDER_RECOMMENDATION.matches(formattedString); } @Override @@ -154,6 +246,9 @@ public Map getFieldValuesMap() { if (recommendation != null) { fieldMapBuilder.put("recommendation", recommendation); } + if (billingAccount != null) { + fieldMapBuilder.put("billing_account", billingAccount); + } fieldValuesMap = fieldMapBuilder.build(); } } @@ -167,15 +262,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return PROJECT_LOCATION_RECOMMENDER_RECOMMENDATION.instantiate( - "project", - project, - "location", - location, - "recommender", - recommender, - "recommendation", - recommendation); + return fixedValue != null ? fixedValue : pathTemplate.instantiate(getFieldValuesMap()); } @Override @@ -188,7 +275,8 @@ public boolean equals(Object o) { return Objects.equals(this.project, that.project) && Objects.equals(this.location, that.location) && Objects.equals(this.recommender, that.recommender) - && Objects.equals(this.recommendation, that.recommendation); + && Objects.equals(this.recommendation, that.recommendation) + && Objects.equals(this.billingAccount, that.billingAccount); } return false; } @@ -197,6 +285,8 @@ public boolean equals(Object o) { public int hashCode() { int h = 1; h *= 1000003; + h ^= Objects.hashCode(fixedValue); + h *= 1000003; h ^= Objects.hashCode(project); h *= 1000003; h ^= Objects.hashCode(location); @@ -204,6 +294,8 @@ public int hashCode() { h ^= Objects.hashCode(recommender); h *= 1000003; h ^= Objects.hashCode(recommendation); + h *= 1000003; + h ^= Objects.hashCode(billingAccount); return h; } @@ -256,6 +348,10 @@ public Builder setRecommendation(String recommendation) { } private Builder(RecommendationName recommendationName) { + Preconditions.checkArgument( + Objects.equals( + recommendationName.pathTemplate, PROJECT_LOCATION_RECOMMENDER_RECOMMENDATION), + "toBuilder is only supported when RecommendationName has the pattern of projects/{project}/locations/{location}/recommenders/{recommender}/recommendations/{recommendation}"); project = recommendationName.project; location = recommendationName.location; recommender = recommendationName.recommender; @@ -266,4 +362,61 @@ public RecommendationName build() { return new RecommendationName(this); } } + + /** + * Builder for + * billingAccounts/{billing_account}/locations/{location}/recommenders/{recommender}/recommendations/{recommendation}. + */ + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static class BillingAccountLocationRecommenderRecommendationBuilder { + private String billingAccount; + private String location; + private String recommender; + private String recommendation; + + protected BillingAccountLocationRecommenderRecommendationBuilder() {} + + public String getBillingAccount() { + return billingAccount; + } + + public String getLocation() { + return location; + } + + public String getRecommender() { + return recommender; + } + + public String getRecommendation() { + return recommendation; + } + + public BillingAccountLocationRecommenderRecommendationBuilder setBillingAccount( + String billingAccount) { + this.billingAccount = billingAccount; + return this; + } + + public BillingAccountLocationRecommenderRecommendationBuilder setLocation(String location) { + this.location = location; + return this; + } + + public BillingAccountLocationRecommenderRecommendationBuilder setRecommender( + String recommender) { + this.recommender = recommender; + return this; + } + + public BillingAccountLocationRecommenderRecommendationBuilder setRecommendation( + String recommendation) { + this.recommendation = recommendation; + return this; + } + + public RecommendationName build() { + return new RecommendationName(this); + } + } } diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommendationOuterClass.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommendationOuterClass.java index 19787dba..38678ad4 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommendationOuterClass.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommendationOuterClass.java @@ -89,7 +89,7 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "\031google/api/resource.proto\032\036google/proto" + "buf/duration.proto\032\034google/protobuf/stru" + "ct.proto\032\037google/protobuf/timestamp.prot" - + "o\032\027google/type/money.proto\"\270\005\n\016Recommend" + + "o\032\027google/type/money.proto\"\254\006\n\016Recommend" + "ation\022\014\n\004name\030\001 \001(\t\022\023\n\013description\030\002 \001(\t" + "\022\033\n\023recommender_subtype\030\014 \001(\t\0225\n\021last_re" + "fresh_time\030\004 \001(\0132\032.google.protobuf.Times" @@ -103,54 +103,59 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "\030\013 \001(\t\022Y\n\023associated_insights\030\016 \003(\0132<.go" + "ogle.cloud.recommender.v1.Recommendation" + ".InsightReference\032#\n\020InsightReference\022\017\n" - + "\007insight\030\001 \001(\t:\224\001\352A\220\001\n)recommender.googl" + + "\007insight\030\001 \001(\t:\210\002\352A\204\002\n)recommender.googl" + "eapis.com/Recommendation\022cprojects/{proj" + "ect}/locations/{location}/recommenders/{" + "recommender}/recommendations/{recommenda" - + "tion}\"^\n\025RecommendationContent\022E\n\020operat" - + "ion_groups\030\002 \003(\0132+.google.cloud.recommen" - + "der.v1.OperationGroup\"L\n\016OperationGroup\022" - + ":\n\noperations\030\001 \003(\0132&.google.cloud.recom" - + "mender.v1.Operation\"\327\004\n\tOperation\022\016\n\006act" - + "ion\030\001 \001(\t\022\025\n\rresource_type\030\002 \001(\t\022\020\n\010reso" - + "urce\030\003 \001(\t\022\014\n\004path\030\004 \001(\t\022\027\n\017source_resou" - + "rce\030\005 \001(\t\022\023\n\013source_path\030\006 \001(\t\022\'\n\005value\030" - + "\007 \001(\0132\026.google.protobuf.ValueH\000\022B\n\rvalue" - + "_matcher\030\n \001(\0132).google.cloud.recommende" - + "r.v1.ValueMatcherH\000\022M\n\014path_filters\030\010 \003(" - + "\01327.google.cloud.recommender.v1.Operatio" - + "n.PathFiltersEntry\022Z\n\023path_value_matcher" - + "s\030\013 \003(\0132=.google.cloud.recommender.v1.Op" - + "eration.PathValueMatchersEntry\032J\n\020PathFi" - + "ltersEntry\022\013\n\003key\030\001 \001(\t\022%\n\005value\030\002 \001(\0132\026" - + ".google.protobuf.Value:\0028\001\032c\n\026PathValueM" - + "atchersEntry\022\013\n\003key\030\001 \001(\t\0228\n\005value\030\002 \001(\013" - + "2).google.cloud.recommender.v1.ValueMatc" - + "her:\0028\001B\014\n\npath_value\":\n\014ValueMatcher\022\031\n" - + "\017matches_pattern\030\001 \001(\tH\000B\017\n\rmatch_varian" - + "t\"_\n\016CostProjection\022 \n\004cost\030\001 \001(\0132\022.goog" - + "le.type.Money\022+\n\010duration\030\002 \001(\0132\031.google" - + ".protobuf.Duration\"\200\002\n\006Impact\022>\n\010categor" - + "y\030\001 \001(\0162,.google.cloud.recommender.v1.Im" - + "pact.Category\022F\n\017cost_projection\030d \001(\0132+" - + ".google.cloud.recommender.v1.CostProject" - + "ionH\000\"`\n\010Category\022\030\n\024CATEGORY_UNSPECIFIE" - + "D\020\000\022\010\n\004COST\020\001\022\014\n\010SECURITY\020\002\022\017\n\013PERFORMAN" - + "CE\020\003\022\021\n\rMANAGEABILITY\020\004B\014\n\nprojection\"\336\002" - + "\n\027RecommendationStateInfo\022I\n\005state\030\001 \001(\016" - + "2:.google.cloud.recommender.v1.Recommend" - + "ationStateInfo.State\022_\n\016state_metadata\030\002" - + " \003(\0132G.google.cloud.recommender.v1.Recom" - + "mendationStateInfo.StateMetadataEntry\0324\n" - + "\022StateMetadataEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005valu" - + "e\030\002 \001(\t:\0028\001\"a\n\005State\022\025\n\021STATE_UNSPECIFIE" - + "D\020\000\022\n\n\006ACTIVE\020\001\022\013\n\007CLAIMED\020\006\022\r\n\tSUCCEEDE" - + "D\020\003\022\n\n\006FAILED\020\004\022\r\n\tDISMISSED\020\005B\377\001\n\037com.g" - + "oogle.cloud.recommender.v1P\001ZFgoogle.gol" - + "ang.org/genproto/googleapis/cloud/recomm" - + "ender/v1;recommender\242\002\004CREC\252\002\033Google.Clo" - + "ud.Recommender.V1\352Al\n&recommender.google" - + "apis.com/Recommender\022Bprojects/{project}" + + "tion}\022rbillingAccounts/{billing_account}" + + "/locations/{location}/recommenders/{reco" + + "mmender}/recommendations/{recommendation" + + "}\"^\n\025RecommendationContent\022E\n\020operation_" + + "groups\030\002 \003(\0132+.google.cloud.recommender." + + "v1.OperationGroup\"L\n\016OperationGroup\022:\n\no" + + "perations\030\001 \003(\0132&.google.cloud.recommend" + + "er.v1.Operation\"\327\004\n\tOperation\022\016\n\006action\030" + + "\001 \001(\t\022\025\n\rresource_type\030\002 \001(\t\022\020\n\010resource" + + "\030\003 \001(\t\022\014\n\004path\030\004 \001(\t\022\027\n\017source_resource\030" + + "\005 \001(\t\022\023\n\013source_path\030\006 \001(\t\022\'\n\005value\030\007 \001(" + + "\0132\026.google.protobuf.ValueH\000\022B\n\rvalue_mat" + + "cher\030\n \001(\0132).google.cloud.recommender.v1" + + ".ValueMatcherH\000\022M\n\014path_filters\030\010 \003(\01327." + + "google.cloud.recommender.v1.Operation.Pa" + + "thFiltersEntry\022Z\n\023path_value_matchers\030\013 " + + "\003(\0132=.google.cloud.recommender.v1.Operat" + + "ion.PathValueMatchersEntry\032J\n\020PathFilter" + + "sEntry\022\013\n\003key\030\001 \001(\t\022%\n\005value\030\002 \001(\0132\026.goo" + + "gle.protobuf.Value:\0028\001\032c\n\026PathValueMatch" + + "ersEntry\022\013\n\003key\030\001 \001(\t\0228\n\005value\030\002 \001(\0132).g" + + "oogle.cloud.recommender.v1.ValueMatcher:" + + "\0028\001B\014\n\npath_value\":\n\014ValueMatcher\022\031\n\017mat" + + "ches_pattern\030\001 \001(\tH\000B\017\n\rmatch_variant\"_\n" + + "\016CostProjection\022 \n\004cost\030\001 \001(\0132\022.google.t" + + "ype.Money\022+\n\010duration\030\002 \001(\0132\031.google.pro" + + "tobuf.Duration\"\200\002\n\006Impact\022>\n\010category\030\001 " + + "\001(\0162,.google.cloud.recommender.v1.Impact" + + ".Category\022F\n\017cost_projection\030d \001(\0132+.goo" + + "gle.cloud.recommender.v1.CostProjectionH" + + "\000\"`\n\010Category\022\030\n\024CATEGORY_UNSPECIFIED\020\000\022" + + "\010\n\004COST\020\001\022\014\n\010SECURITY\020\002\022\017\n\013PERFORMANCE\020\003" + + "\022\021\n\rMANAGEABILITY\020\004B\014\n\nprojection\"\336\002\n\027Re" + + "commendationStateInfo\022I\n\005state\030\001 \001(\0162:.g" + + "oogle.cloud.recommender.v1.Recommendatio" + + "nStateInfo.State\022_\n\016state_metadata\030\002 \003(\013" + + "2G.google.cloud.recommender.v1.Recommend" + + "ationStateInfo.StateMetadataEntry\0324\n\022Sta" + + "teMetadataEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 " + + "\001(\t:\0028\001\"a\n\005State\022\025\n\021STATE_UNSPECIFIED\020\000\022" + + "\n\n\006ACTIVE\020\001\022\013\n\007CLAIMED\020\006\022\r\n\tSUCCEEDED\020\003\022" + + "\n\n\006FAILED\020\004\022\r\n\tDISMISSED\020\005B\323\002\n\037com.googl" + + "e.cloud.recommender.v1P\001ZFgoogle.golang." + + "org/genproto/googleapis/cloud/recommende" + + "r/v1;recommender\242\002\004CREC\252\002\033Google.Cloud.R" + + "ecommender.V1\352A\277\001\n&recommender.googleapi" + + "s.com/Recommender\022Bprojects/{project}/lo" + + "cations/{location}/recommenders/{recomme" + + "nder}\022QbillingAccounts/{billing_account}" + "/locations/{location}/recommenders/{reco" + "mmender}b\006proto3" }; diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommenderName.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommenderName.java index 7a8ae6cb..6a8aa565 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommenderName.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommenderName.java @@ -16,7 +16,9 @@ package com.google.cloud.recommender.v1; +import com.google.api.core.BetaApi; import com.google.api.pathtemplate.PathTemplate; +import com.google.api.pathtemplate.ValidationException; import com.google.api.resourcenames.ResourceName; import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; @@ -32,22 +34,39 @@ public class RecommenderName implements ResourceName { private static final PathTemplate PROJECT_LOCATION_RECOMMENDER = PathTemplate.createWithoutUrlEncoding( "projects/{project}/locations/{location}/recommenders/{recommender}"); + private static final PathTemplate BILLING_ACCOUNT_LOCATION_RECOMMENDER = + PathTemplate.createWithoutUrlEncoding( + "billingAccounts/{billing_account}/locations/{location}/recommenders/{recommender}"); private volatile Map fieldValuesMap; + private PathTemplate pathTemplate; + private String fixedValue; private final String project; private final String location; private final String recommender; + private final String billingAccount; @Deprecated protected RecommenderName() { project = null; location = null; recommender = null; + billingAccount = null; } private RecommenderName(Builder builder) { project = Preconditions.checkNotNull(builder.getProject()); location = Preconditions.checkNotNull(builder.getLocation()); recommender = Preconditions.checkNotNull(builder.getRecommender()); + billingAccount = null; + pathTemplate = PROJECT_LOCATION_RECOMMENDER; + } + + private RecommenderName(BillingAccountLocationRecommenderBuilder builder) { + billingAccount = Preconditions.checkNotNull(builder.getBillingAccount()); + location = Preconditions.checkNotNull(builder.getLocation()); + recommender = Preconditions.checkNotNull(builder.getRecommender()); + project = null; + pathTemplate = BILLING_ACCOUNT_LOCATION_RECOMMENDER; } public String getProject() { @@ -62,10 +81,25 @@ public String getRecommender() { return recommender; } + public String getBillingAccount() { + return billingAccount; + } + public static Builder newBuilder() { return new Builder(); } + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static Builder newProjectLocationRecommenderBuilder() { + return new Builder(); + } + + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static BillingAccountLocationRecommenderBuilder + newBillingAccountLocationRecommenderBuilder() { + return new BillingAccountLocationRecommenderBuilder(); + } + public Builder toBuilder() { return new Builder(this); } @@ -78,6 +112,26 @@ public static RecommenderName of(String project, String location, String recomme .build(); } + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static RecommenderName ofProjectLocationRecommenderName( + String project, String location, String recommender) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setRecommender(recommender) + .build(); + } + + @BetaApi("The static create methods are not stable yet and may be changed in the future.") + public static RecommenderName ofBillingAccountLocationRecommenderName( + String billingAccount, String location, String recommender) { + return newBillingAccountLocationRecommenderBuilder() + .setBillingAccount(billingAccount) + .setLocation(location) + .setRecommender(recommender) + .build(); + } + public static String format(String project, String location, String recommender) { return newBuilder() .setProject(project) @@ -87,14 +141,42 @@ public static String format(String project, String location, String recommender) .toString(); } + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatProjectLocationRecommenderName( + String project, String location, String recommender) { + return newBuilder() + .setProject(project) + .setLocation(location) + .setRecommender(recommender) + .build() + .toString(); + } + + @BetaApi("The static format methods are not stable yet and may be changed in the future.") + public static String formatBillingAccountLocationRecommenderName( + String billingAccount, String location, String recommender) { + return newBillingAccountLocationRecommenderBuilder() + .setBillingAccount(billingAccount) + .setLocation(location) + .setRecommender(recommender) + .build() + .toString(); + } + public static RecommenderName parse(String formattedString) { if (formattedString.isEmpty()) { return null; } - Map matchMap = - PROJECT_LOCATION_RECOMMENDER.validatedMatch( - formattedString, "RecommenderName.parse: formattedString not in valid format"); - return of(matchMap.get("project"), matchMap.get("location"), matchMap.get("recommender")); + if (PROJECT_LOCATION_RECOMMENDER.matches(formattedString)) { + Map matchMap = PROJECT_LOCATION_RECOMMENDER.match(formattedString); + return ofProjectLocationRecommenderName( + matchMap.get("project"), matchMap.get("location"), matchMap.get("recommender")); + } else if (BILLING_ACCOUNT_LOCATION_RECOMMENDER.matches(formattedString)) { + Map matchMap = BILLING_ACCOUNT_LOCATION_RECOMMENDER.match(formattedString); + return ofBillingAccountLocationRecommenderName( + matchMap.get("billing_account"), matchMap.get("location"), matchMap.get("recommender")); + } + throw new ValidationException("RecommenderName.parse: formattedString not in valid format"); } public static List parseList(List formattedStrings) { @@ -118,7 +200,8 @@ public static List toStringList(List values) { } public static boolean isParsableFrom(String formattedString) { - return PROJECT_LOCATION_RECOMMENDER.matches(formattedString); + return PROJECT_LOCATION_RECOMMENDER.matches(formattedString) + || BILLING_ACCOUNT_LOCATION_RECOMMENDER.matches(formattedString); } @Override @@ -136,6 +219,9 @@ public Map getFieldValuesMap() { if (recommender != null) { fieldMapBuilder.put("recommender", recommender); } + if (billingAccount != null) { + fieldMapBuilder.put("billing_account", billingAccount); + } fieldValuesMap = fieldMapBuilder.build(); } } @@ -149,8 +235,7 @@ public String getFieldValue(String fieldName) { @Override public String toString() { - return PROJECT_LOCATION_RECOMMENDER.instantiate( - "project", project, "location", location, "recommender", recommender); + return fixedValue != null ? fixedValue : pathTemplate.instantiate(getFieldValuesMap()); } @Override @@ -162,7 +247,8 @@ public boolean equals(Object o) { RecommenderName that = ((RecommenderName) o); return Objects.equals(this.project, that.project) && Objects.equals(this.location, that.location) - && Objects.equals(this.recommender, that.recommender); + && Objects.equals(this.recommender, that.recommender) + && Objects.equals(this.billingAccount, that.billingAccount); } return false; } @@ -171,11 +257,15 @@ public boolean equals(Object o) { public int hashCode() { int h = 1; h *= 1000003; + h ^= Objects.hashCode(fixedValue); + h *= 1000003; h ^= Objects.hashCode(project); h *= 1000003; h ^= Objects.hashCode(location); h *= 1000003; h ^= Objects.hashCode(recommender); + h *= 1000003; + h ^= Objects.hashCode(billingAccount); return h; } @@ -215,6 +305,9 @@ public Builder setRecommender(String recommender) { } private Builder(RecommenderName recommenderName) { + Preconditions.checkArgument( + Objects.equals(recommenderName.pathTemplate, PROJECT_LOCATION_RECOMMENDER), + "toBuilder is only supported when RecommenderName has the pattern of projects/{project}/locations/{location}/recommenders/{recommender}"); project = recommenderName.project; location = recommenderName.location; recommender = recommenderName.recommender; @@ -224,4 +317,47 @@ public RecommenderName build() { return new RecommenderName(this); } } + + /** + * Builder for billingAccounts/{billing_account}/locations/{location}/recommenders/{recommender}. + */ + @BetaApi("The per-pattern Builders are not stable yet and may be changed in the future.") + public static class BillingAccountLocationRecommenderBuilder { + private String billingAccount; + private String location; + private String recommender; + + protected BillingAccountLocationRecommenderBuilder() {} + + public String getBillingAccount() { + return billingAccount; + } + + public String getLocation() { + return location; + } + + public String getRecommender() { + return recommender; + } + + public BillingAccountLocationRecommenderBuilder setBillingAccount(String billingAccount) { + this.billingAccount = billingAccount; + return this; + } + + public BillingAccountLocationRecommenderBuilder setLocation(String location) { + this.location = location; + return this; + } + + public BillingAccountLocationRecommenderBuilder setRecommender(String recommender) { + this.recommender = recommender; + return this; + } + + public RecommenderName build() { + return new RecommenderName(this); + } + } } diff --git a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommenderProto.java b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommenderProto.java index aec50ea7..4efc666c 100644 --- a/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommenderProto.java +++ b/proto-google-cloud-recommender-v1/src/main/java/com/google/cloud/recommender/v1/RecommenderProto.java @@ -145,59 +145,76 @@ public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { + "1.MarkRecommendationFailedRequest.StateM" + "etadataEntry\022\021\n\004etag\030\003 \001(\tB\003\340A\002\0324\n\022State" + "MetadataEntry\022\013\n\003key\030\001 \001(\t\022\r\n\005value\030\002 \001(" - + "\t:\0028\0012\371\016\n\013Recommender\022\301\001\n\014ListInsights\0220" + + "\t:\0028\0012\232\024\n\013Recommender\022\211\002\n\014ListInsights\0220" + ".google.cloud.recommender.v1.ListInsight" + "sRequest\0321.google.cloud.recommender.v1.L" - + "istInsightsResponse\"L\202\323\344\223\002=\022;/v1/{parent" - + "=projects/*/locations/*/insightTypes/*}/" - + "insights\332A\006parent\022\256\001\n\nGetInsight\022..googl" - + "e.cloud.recommender.v1.GetInsightRequest" - + "\032$.google.cloud.recommender.v1.Insight\"J" - + "\202\323\344\223\002=\022;/v1/{name=projects/*/locations/*" - + "/insightTypes/*/insights/*}\332A\004name\022\344\001\n\023M" - + "arkInsightAccepted\0227.google.cloud.recomm" - + "ender.v1.MarkInsightAcceptedRequest\032$.go" - + "ogle.cloud.recommender.v1.Insight\"n\202\323\344\223\002" - + "M\"H/v1/{name=projects/*/locations/*/insi" - + "ghtTypes/*/insights/*}:markAccepted:\001*\332A" - + "\030name,state_metadata,etag\022\355\001\n\023ListRecomm" - + "endations\0227.google.cloud.recommender.v1." - + "ListRecommendationsRequest\0328.google.clou" - + "d.recommender.v1.ListRecommendationsResp" - + "onse\"c\202\323\344\223\002D\022B/v1/{parent=projects/*/loc" - + "ations/*/recommenders/*}/recommendations" - + "\332A\006parent\332A\rparent,filter\022\312\001\n\021GetRecomme" - + "ndation\0225.google.cloud.recommender.v1.Ge" - + "tRecommendationRequest\032+.google.cloud.re" - + "commender.v1.Recommendation\"Q\202\323\344\223\002D\022B/v1" - + "/{name=projects/*/locations/*/recommende" - + "rs/*/recommendations/*}\332A\004name\022\375\001\n\031MarkR" - + "ecommendationClaimed\022=.google.cloud.reco" - + "mmender.v1.MarkRecommendationClaimedRequ" - + "est\032+.google.cloud.recommender.v1.Recomm" - + "endation\"t\202\323\344\223\002S\"N/v1/{name=projects/*/l" + + "istInsightsResponse\"\223\001\202\323\344\223\002\203\001\022;/v1/{pare" + + "nt=projects/*/locations/*/insightTypes/*" + + "}/insightsZD\022B/v1/{parent=billingAccount" + + "s/*/locations/*/insightTypes/*}/insights" + + "\332A\006parent\022\366\001\n\nGetInsight\022..google.cloud." + + "recommender.v1.GetInsightRequest\032$.googl" + + "e.cloud.recommender.v1.Insight\"\221\001\202\323\344\223\002\203\001" + + "\022;/v1/{name=projects/*/locations/*/insig" + + "htTypes/*/insights/*}ZD\022B/v1/{name=billi" + + "ngAccounts/*/locations/*/insightTypes/*/" + + "insights/*}\332A\004name\022\274\002\n\023MarkInsightAccept" + + "ed\0227.google.cloud.recommender.v1.MarkIns" + + "ightAcceptedRequest\032$.google.cloud.recom" + + "mender.v1.Insight\"\305\001\202\323\344\223\002\243\001\"H/v1/{name=p" + + "rojects/*/locations/*/insightTypes/*/ins" + + "ights/*}:markAccepted:\001*ZT\"O/v1/{name=bi" + + "llingAccounts/*/locations/*/insightTypes" + + "/*/insights/*}:markAccepted:\001*\332A\030name,st" + + "ate_metadata,etag\022\274\002\n\023ListRecommendation" + + "s\0227.google.cloud.recommender.v1.ListReco" + + "mmendationsRequest\0328.google.cloud.recomm" + + "ender.v1.ListRecommendationsResponse\"\261\001\202" + + "\323\344\223\002\221\001\022B/v1/{parent=projects/*/locations" + + "/*/recommenders/*}/recommendationsZK\022I/v" + + "1/{parent=billingAccounts/*/locations/*/" + + "recommenders/*}/recommendations\332A\006parent" + + "\332A\rparent,filter\022\231\002\n\021GetRecommendation\0225" + + ".google.cloud.recommender.v1.GetRecommen" + + "dationRequest\032+.google.cloud.recommender" + + ".v1.Recommendation\"\237\001\202\323\344\223\002\221\001\022B/v1/{name=" + + "projects/*/locations/*/recommenders/*/re" + + "commendations/*}ZK\022I/v1/{name=billingAcc" + + "ounts/*/locations/*/recommenders/*/recom" + + "mendations/*}\332A\004name\022\333\002\n\031MarkRecommendat" + + "ionClaimed\022=.google.cloud.recommender.v1" + + ".MarkRecommendationClaimedRequest\032+.goog" + + "le.cloud.recommender.v1.Recommendation\"\321" + + "\001\202\323\344\223\002\257\001\"N/v1/{name=projects/*/locations" + + "/*/recommenders/*/recommendations/*}:mar" + + "kClaimed:\001*ZZ\"U/v1/{name=billingAccounts" + + "/*/locations/*/recommenders/*/recommenda" + + "tions/*}:markClaimed:\001*\332A\030name,state_met" + + "adata,etag\022\343\002\n\033MarkRecommendationSucceed" + + "ed\022?.google.cloud.recommender.v1.MarkRec" + + "ommendationSucceededRequest\032+.google.clo" + + "ud.recommender.v1.Recommendation\"\325\001\202\323\344\223\002" + + "\263\001\"P/v1/{name=projects/*/locations/*/rec" + + "ommenders/*/recommendations/*}:markSucce" + + "eded:\001*Z\\\"W/v1/{name=billingAccounts/*/l" + "ocations/*/recommenders/*/recommendation" - + "s/*}:markClaimed:\001*\332A\030name,state_metadat" - + "a,etag\022\203\002\n\033MarkRecommendationSucceeded\022?" - + ".google.cloud.recommender.v1.MarkRecomme" - + "ndationSucceededRequest\032+.google.cloud.r" - + "ecommender.v1.Recommendation\"v\202\323\344\223\002U\"P/v" - + "1/{name=projects/*/locations/*/recommend" - + "ers/*/recommendations/*}:markSucceeded:\001" - + "*\332A\030name,state_metadata,etag\022\372\001\n\030MarkRec" - + "ommendationFailed\022<.google.cloud.recomme" - + "nder.v1.MarkRecommendationFailedRequest\032" - + "+.google.cloud.recommender.v1.Recommenda" - + "tion\"s\202\323\344\223\002R\"M/v1/{name=projects/*/locat" - + "ions/*/recommenders/*/recommendations/*}" - + ":markFailed:\001*\332A\030name,state_metadata,eta" - + "g\032N\312A\032recommender.googleapis.com\322A.https" - + "://www.googleapis.com/auth/cloud-platfor" - + "mB\242\001\n\037com.google.cloud.recommender.v1B\020R" - + "ecommenderProtoP\001ZFgoogle.golang.org/gen" - + "proto/googleapis/cloud/recommender/v1;re" - + "commender\242\002\004CREC\252\002\033Google.Cloud.Recommen" - + "der.V1b\006proto3" + + "s/*}:markSucceeded:\001*\332A\030name,state_metad" + + "ata,etag\022\327\002\n\030MarkRecommendationFailed\022<." + + "google.cloud.recommender.v1.MarkRecommen" + + "dationFailedRequest\032+.google.cloud.recom" + + "mender.v1.Recommendation\"\317\001\202\323\344\223\002\255\001\"M/v1/" + + "{name=projects/*/locations/*/recommender" + + "s/*/recommendations/*}:markFailed:\001*ZY\"T" + + "/v1/{name=billingAccounts/*/locations/*/" + + "recommenders/*/recommendations/*}:markFa" + + "iled:\001*\332A\030name,state_metadata,etag\032N\312A\032r" + + "ecommender.googleapis.com\322A.https://www." + + "googleapis.com/auth/cloud-platformB\242\001\n\037c" + + "om.google.cloud.recommender.v1B\020Recommen" + + "derProtoP\001ZFgoogle.golang.org/genproto/g" + + "oogleapis/cloud/recommender/v1;recommend" + + "er\242\002\004CREC\252\002\033Google.Cloud.Recommender.V1b" + + "\006proto3" }; descriptor = com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( diff --git a/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/insight.proto b/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/insight.proto index 783a7147..3708c835 100644 --- a/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/insight.proto +++ b/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/insight.proto @@ -30,6 +30,7 @@ option objc_class_prefix = "CREC"; option (google.api.resource_definition) = { type: "recommender.googleapis.com/InsightType" pattern: "projects/{project}/locations/{location}/insightTypes/{insight_type}" + pattern: "billingAccounts/{billing_account}/locations/{location}/insightTypes/{insight_type}" }; // An insight along with the information used to derive the insight. The insight @@ -38,6 +39,7 @@ message Insight { option (google.api.resource) = { type: "recommender.googleapis.com/Insight" pattern: "projects/{project}/locations/{location}/insightTypes/{insight_type}/insights/{insight}" + pattern: "billingAccounts/{billing_account}/locations/{location}/insightTypes/{insight_type}/insights/{insight}" }; // Reference to an associated recommendation. diff --git a/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/recommendation.proto b/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/recommendation.proto index aa8321ee..42345d8e 100644 --- a/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/recommendation.proto +++ b/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/recommendation.proto @@ -30,6 +30,7 @@ option objc_class_prefix = "CREC"; option (google.api.resource_definition) = { type: "recommender.googleapis.com/Recommender" pattern: "projects/{project}/locations/{location}/recommenders/{recommender}" + pattern: "billingAccounts/{billing_account}/locations/{location}/recommenders/{recommender}" }; // A recommendation along with a suggested action. E.g., a rightsizing @@ -38,6 +39,7 @@ message Recommendation { option (google.api.resource) = { type: "recommender.googleapis.com/Recommendation" pattern: "projects/{project}/locations/{location}/recommenders/{recommender}/recommendations/{recommendation}" + pattern: "billingAccounts/{billing_account}/locations/{location}/recommenders/{recommender}/recommendations/{recommendation}" }; // Reference to an associated insight. @@ -170,12 +172,12 @@ message Operation { // "/versions/*/targetSize/percent": 20 // } // * Example: { - // "/bindings/*/role": "roles/admin" + // "/bindings/*/role": "roles/owner" // "/bindings/*/condition" : null // } // * Example: { - // "/bindings/*/role": "roles/admin" - // "/bindings/*/members/*" : ["x@google.com", "y@google.com"] + // "/bindings/*/role": "roles/owner" + // "/bindings/*/members/*" : ["x@example.com", "y@example.com"] // } // When both path_filters and path_value_matchers are set, an implicit AND // must be performed. diff --git a/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/recommender_service.proto b/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/recommender_service.proto index 4f24a050..3bd54f83 100644 --- a/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/recommender_service.proto +++ b/proto-google-cloud-recommender-v1/src/main/proto/google/cloud/recommender/v1/recommender_service.proto @@ -43,6 +43,9 @@ service Recommender { rpc ListInsights(ListInsightsRequest) returns (ListInsightsResponse) { option (google.api.http) = { get: "/v1/{parent=projects/*/locations/*/insightTypes/*}/insights" + additional_bindings { + get: "/v1/{parent=billingAccounts/*/locations/*/insightTypes/*}/insights" + } }; option (google.api.method_signature) = "parent"; } @@ -52,6 +55,9 @@ service Recommender { rpc GetInsight(GetInsightRequest) returns (Insight) { option (google.api.http) = { get: "/v1/{name=projects/*/locations/*/insightTypes/*/insights/*}" + additional_bindings { + get: "/v1/{name=billingAccounts/*/locations/*/insightTypes/*/insights/*}" + } }; option (google.api.method_signature) = "name"; } @@ -66,6 +72,10 @@ service Recommender { option (google.api.http) = { post: "/v1/{name=projects/*/locations/*/insightTypes/*/insights/*}:markAccepted" body: "*" + additional_bindings { + post: "/v1/{name=billingAccounts/*/locations/*/insightTypes/*/insights/*}:markAccepted" + body: "*" + } }; option (google.api.method_signature) = "name,state_metadata,etag"; } @@ -75,6 +85,9 @@ service Recommender { rpc ListRecommendations(ListRecommendationsRequest) returns (ListRecommendationsResponse) { option (google.api.http) = { get: "/v1/{parent=projects/*/locations/*/recommenders/*}/recommendations" + additional_bindings { + get: "/v1/{parent=billingAccounts/*/locations/*/recommenders/*}/recommendations" + } }; option (google.api.method_signature) = "parent"; option (google.api.method_signature) = "parent,filter"; @@ -85,6 +98,9 @@ service Recommender { rpc GetRecommendation(GetRecommendationRequest) returns (Recommendation) { option (google.api.http) = { get: "/v1/{name=projects/*/locations/*/recommenders/*/recommendations/*}" + additional_bindings { + get: "/v1/{name=billingAccounts/*/locations/*/recommenders/*/recommendations/*}" + } }; option (google.api.method_signature) = "name"; } @@ -103,6 +119,10 @@ service Recommender { option (google.api.http) = { post: "/v1/{name=projects/*/locations/*/recommenders/*/recommendations/*}:markClaimed" body: "*" + additional_bindings { + post: "/v1/{name=billingAccounts/*/locations/*/recommenders/*/recommendations/*}:markClaimed" + body: "*" + } }; option (google.api.method_signature) = "name,state_metadata,etag"; } @@ -122,6 +142,10 @@ service Recommender { option (google.api.http) = { post: "/v1/{name=projects/*/locations/*/recommenders/*/recommendations/*}:markSucceeded" body: "*" + additional_bindings { + post: "/v1/{name=billingAccounts/*/locations/*/recommenders/*/recommendations/*}:markSucceeded" + body: "*" + } }; option (google.api.method_signature) = "name,state_metadata,etag"; } @@ -141,6 +165,10 @@ service Recommender { option (google.api.http) = { post: "/v1/{name=projects/*/locations/*/recommenders/*/recommendations/*}:markFailed" body: "*" + additional_bindings { + post: "/v1/{name=billingAccounts/*/locations/*/recommenders/*/recommendations/*}:markFailed" + body: "*" + } }; option (google.api.method_signature) = "name,state_metadata,etag"; } @@ -156,6 +184,8 @@ message ListInsightsRequest { // // LOCATION here refers to GCP Locations: // https://cloud.google.com/about/locations/ + // INSIGHT_TYPE_ID refers to supported insight types: + // https://cloud.google.com/recommender/docs/insights/insight-types.) string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { @@ -229,6 +259,8 @@ message ListRecommendationsRequest { // // LOCATION here refers to GCP Locations: // https://cloud.google.com/about/locations/ + // RECOMMENDER_ID refers to supported recommenders: + // https://cloud.google.com/recommender/docs/recommenders. string parent = 1 [ (google.api.field_behavior) = REQUIRED, (google.api.resource_reference) = { diff --git a/synth.metadata b/synth.metadata index 0a99ea15..913b3f07 100644 --- a/synth.metadata +++ b/synth.metadata @@ -11,16 +11,16 @@ "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "e689e62a5540d4b98639f0e444a0edf5b2d94043", - "internalRef": "347651882" + "sha": "5256ab60f3d396a3d1bd393043776936b9651c5b", + "internalRef": "347703845" } }, { "git": { "name": "googleapis", "remote": "https://github.com/googleapis/googleapis.git", - "sha": "e689e62a5540d4b98639f0e444a0edf5b2d94043", - "internalRef": "347651882" + "sha": "5256ab60f3d396a3d1bd393043776936b9651c5b", + "internalRef": "347703845" } }, {