diff --git a/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy b/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy index addb7c50a28a..9e5ffa8a1c42 100644 --- a/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy +++ b/buildSrc/src/main/groovy/org/apache/beam/gradle/BeamModulePlugin.groovy @@ -604,7 +604,7 @@ class BeamModulePlugin implements Plugin { def errorprone_version = "2.10.0" // [bomupgrader] determined by: com.google.api:gax, consistent with: google_cloud_platform_libraries_bom def gax_version = "2.48.0" - def google_ads_version = "26.0.0" + def google_ads_version = "33.0.0" def google_clients_version = "2.0.0" def google_cloud_bigdataoss_version = "2.2.16" // [bomupgrader] determined by: com.google.cloud:google-cloud-spanner, consistent with: google_cloud_platform_libraries_bom @@ -731,7 +731,7 @@ class BeamModulePlugin implements Plugin { gax_grpc_test : "com.google.api:gax-grpc:$gax_version:testlib", // google_cloud_platform_libraries_bom sets version gax_httpjson : "com.google.api:gax-httpjson", // google_cloud_platform_libraries_bom sets version google_ads : "com.google.api-ads:google-ads:$google_ads_version", - google_ads_stubs_v14 : "com.google.api-ads:google-ads-stubs-v14:$google_ads_version", + google_ads_stubs : "com.google.api-ads:google-ads-stubs-v17:$google_ads_version", google_api_client : "com.google.api-client:google-api-client:$google_clients_version", // for the libraries using $google_clients_version below. google_api_client_gson : "com.google.api-client:google-api-client-gson:$google_clients_version", google_api_client_java6 : "com.google.api-client:google-api-client-java6:$google_clients_version", diff --git a/sdks/java/build-tools/src/main/resources/beam/checkstyle/suppressions.xml b/sdks/java/build-tools/src/main/resources/beam/checkstyle/suppressions.xml index 824aa9010780..01c997441479 100644 --- a/sdks/java/build-tools/src/main/resources/beam/checkstyle/suppressions.xml +++ b/sdks/java/build-tools/src/main/resources/beam/checkstyle/suppressions.xml @@ -62,8 +62,8 @@ - - + + diff --git a/sdks/java/io/google-ads/build.gradle b/sdks/java/io/google-ads/build.gradle index ebd8f917be96..037fcbf28a6a 100644 --- a/sdks/java/io/google-ads/build.gradle +++ b/sdks/java/io/google-ads/build.gradle @@ -32,7 +32,7 @@ dependencies { implementation library.java.protobuf_java implementation library.java.protobuf_java_util implementation library.java.google_ads - implementation library.java.google_ads_stubs_v14 + implementation library.java.google_ads_stubs implementation library.java.joda_time implementation library.java.vendored_guava_32_1_2_jre testImplementation project(path: ":sdks:java:core", configuration: "shadowTest") diff --git a/sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsIO.java b/sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsIO.java index de176a05e9be..c36e75667e7c 100644 --- a/sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsIO.java +++ b/sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsIO.java @@ -19,15 +19,15 @@ /** * {@link GoogleAdsIO} provides an API for reading from the Google Ads API over different + * href="https://developers.google.com/google-ads/api/docs/start">Google Ads API over supported * versions of the Google Ads client libraries. * - * @see GoogleAdsV14 + * @see GoogleAdsV17 */ public class GoogleAdsIO { private GoogleAdsIO() {} - public static GoogleAdsV14 v14() { - return GoogleAdsV14.INSTANCE; + public static GoogleAdsV17 v17() { + return GoogleAdsV17.INSTANCE; } } diff --git a/sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsV14.java b/sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsV17.java similarity index 89% rename from sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsV14.java rename to sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsV17.java index 46448e0110d9..df6c09b5f705 100644 --- a/sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsV14.java +++ b/sdks/java/io/google-ads/src/main/java/org/apache/beam/sdk/io/googleads/GoogleAdsV17.java @@ -22,15 +22,15 @@ import static org.apache.beam.vendor.guava.v32_1_2_jre.com.google.common.base.Preconditions.checkArgument; import com.google.ads.googleads.lib.GoogleAdsClient; -import com.google.ads.googleads.v14.errors.GoogleAdsError; -import com.google.ads.googleads.v14.errors.GoogleAdsException; -import com.google.ads.googleads.v14.errors.GoogleAdsFailure; -import com.google.ads.googleads.v14.errors.InternalErrorEnum; -import com.google.ads.googleads.v14.errors.QuotaErrorEnum; -import com.google.ads.googleads.v14.services.GoogleAdsRow; -import com.google.ads.googleads.v14.services.GoogleAdsServiceClient; -import com.google.ads.googleads.v14.services.SearchGoogleAdsStreamRequest; -import com.google.ads.googleads.v14.services.SearchGoogleAdsStreamResponse; +import com.google.ads.googleads.v17.errors.GoogleAdsError; +import com.google.ads.googleads.v17.errors.GoogleAdsException; +import com.google.ads.googleads.v17.errors.GoogleAdsFailure; +import com.google.ads.googleads.v17.errors.InternalErrorEnum; +import com.google.ads.googleads.v17.errors.QuotaErrorEnum; +import com.google.ads.googleads.v17.services.GoogleAdsRow; +import com.google.ads.googleads.v17.services.GoogleAdsServiceClient; +import com.google.ads.googleads.v17.services.SearchGoogleAdsStreamRequest; +import com.google.ads.googleads.v17.services.SearchGoogleAdsStreamResponse; import com.google.auto.value.AutoValue; import com.google.protobuf.Message; import com.google.protobuf.util.Durations; @@ -40,10 +40,6 @@ import java.util.concurrent.TimeUnit; import org.apache.beam.sdk.options.PipelineOptions; import org.apache.beam.sdk.transforms.DoFn; -import org.apache.beam.sdk.transforms.DoFn.ProcessContext; -import org.apache.beam.sdk.transforms.DoFn.ProcessElement; -import org.apache.beam.sdk.transforms.DoFn.Setup; -import org.apache.beam.sdk.transforms.DoFn.Teardown; import org.apache.beam.sdk.transforms.MapElements; import org.apache.beam.sdk.transforms.PTransform; import org.apache.beam.sdk.transforms.ParDo; @@ -62,7 +58,7 @@ import org.joda.time.Duration; /** - * {@link GoogleAdsV14} provides an API to read Google Ads API v14 reports. + * {@link GoogleAdsV17} provides an API to read Google Ads API v17 reports. * *

The Google Ads API does not use service account credentials in the same way as Google Cloud * Platform APIs do. Service account credentials are typically only used to delegate (using @@ -81,15 +77,15 @@ * --googleAdsDeveloperToken=your-developer-token * * - *

Use {@link GoogleAdsV14#read()} to read either a bounded or unbounded {@link PCollection} of + *

Use {@link GoogleAdsV17#read()} to read either a bounded or unbounded {@link PCollection} of * {@link GoogleAdsRow} from a single Google Ads Query * Language query using {@link Read#withQuery(String)} and a {@link PCollection} of customer - * IDs. Alternatively, use {@link GoogleAdsV14#readAll()} to read either a bounded or unbounded + * IDs. Alternatively, use {@link GoogleAdsV17#readAll()} to read either a bounded or unbounded * {@link PCollection} of {@link GoogleAdsRow} from a {@link PCollection} of {@link * SearchGoogleAdsStreamRequest} potentially containing many different queries. * - *

For example, using {@link GoogleAdsV14#read()}: + *

For example, using {@link GoogleAdsV17#read()}: * *

{@code
  * Pipeline p = Pipeline.create();
@@ -97,7 +93,7 @@
  *     p.apply(Create.of(Long.toString(1234567890L)));
  * PCollection rows =
  *     customerIds.apply(
- *         GoogleAdsIO.v14()
+ *         GoogleAdsIO.v17()
  *             .read()
  *             .withRateLimitPolicy(MY_RATE_LIMIT_POLICY)
  *             .withQuery(
@@ -109,7 +105,7 @@
  * p.run();
  * }
* - *

Alternatively, using {@link GoogleAdsV14#readAll()} to execute requests from a {@link + *

Alternatively, using {@link GoogleAdsV17#readAll()} to execute requests from a {@link * PCollection} of {@link SearchGoogleAdsStreamRequest}: * *

{@code
@@ -128,13 +124,13 @@
  *                             + "FROM campaign")
  *                     .build())));
  * PCollection rows =
- *     requests.apply(GoogleAdsIO.v14().readAll().withRateLimitPolicy(MY_RATE_LIMIT_POLICY));
+ *     requests.apply(GoogleAdsIO.v17().readAll().withRateLimitPolicy(MY_RATE_LIMIT_POLICY));
  * p.run();
  * }
* *

Client-side rate limiting

* - * On construction of a {@link GoogleAdsV14#read()} or {@link GoogleAdsV14#readAll()} transform a + * On construction of a {@link GoogleAdsV17#read()} or {@link GoogleAdsV17#readAll()} transform a * rate limiting policy must be specified to stay well under the assigned quota for the Google Ads * API. The Google Ads API enforces global rate limits from the developer token down to the customer * ID and depending on the access level of the developer token a limit on the total number of @@ -158,24 +154,24 @@ * Functionality and Rate * sheet & non-compliance fees in the Google Ads API documentation for more details. * - * @see GoogleAdsIO#v14() + * @see GoogleAdsIO#v17() * @see GoogleAdsOptions * @see Best * Practices in the Google Ads documentation */ -public class GoogleAdsV14 { - static final GoogleAdsV14 INSTANCE = new GoogleAdsV14(); +public class GoogleAdsV17 { + static final GoogleAdsV17 INSTANCE = new GoogleAdsV17(); - private GoogleAdsV14() {} + private GoogleAdsV17() {} public Read read() { - return new AutoValue_GoogleAdsV14_Read.Builder() + return new AutoValue_GoogleAdsV17_Read.Builder() .setGoogleAdsClientFactory(DefaultGoogleAdsClientFactory.getInstance()) .build(); } public ReadAll readAll() { - return new AutoValue_GoogleAdsV14_ReadAll.Builder() + return new AutoValue_GoogleAdsV17_ReadAll.Builder() .setGoogleAdsClientFactory(DefaultGoogleAdsClientFactory.getInstance()) .build(); } @@ -184,7 +180,7 @@ public ReadAll readAll() { * A {@link PTransform} that reads the results of a Google Ads query as {@link GoogleAdsRow} * objects. * - * @see GoogleAdsIO#v14() + * @see GoogleAdsIO#v17() * @see #readAll() */ @AutoValue @@ -329,7 +325,7 @@ public void populateDisplayData(DisplayData.Builder builder) { * A {@link PTransform} that reads the results of many {@link SearchGoogleAdsStreamRequest} * objects as {@link GoogleAdsRow} objects. * * - * @see GoogleAdsIO#v14() + * @see GoogleAdsIO#v17() * @see #readAll() */ @AutoValue @@ -447,13 +443,13 @@ static class ReadAllFn extends DoFn @VisibleForTesting static Sleeper sleeper = Sleeper.DEFAULT; - private final GoogleAdsV14.ReadAll spec; + private final GoogleAdsV17.ReadAll spec; private transient @Nullable GoogleAdsClient googleAdsClient; private transient @Nullable GoogleAdsServiceClient googleAdsServiceClient; private transient @Nullable RateLimitPolicy rateLimitPolicy; - ReadAllFn(GoogleAdsV14.ReadAll spec) { + ReadAllFn(GoogleAdsV17.ReadAll spec) { this.spec = spec; } @@ -467,7 +463,7 @@ public void setup(PipelineOptions options) { .newGoogleAdsClient( adsOptions, spec.getDeveloperToken(), null, spec.getLoginCustomerId()); final GoogleAdsServiceClient googleAdsServiceClient = - googleAdsClient.getVersion14().createGoogleAdsServiceClient(); + googleAdsClient.getVersion17().createGoogleAdsServiceClient(); final RateLimitPolicy rateLimitPolicy = checkStateNotNull(spec.getRateLimitPolicyFactory()).getRateLimitPolicy(); @@ -488,11 +484,11 @@ public void processElement(ProcessContext c) throws IOException, InterruptedExce GoogleAdsException lastException = null; SearchGoogleAdsStreamRequest request = c.element(); - String developerToken = googleAdsClient.getDeveloperToken(); + String token = googleAdsClient.getDeveloperToken(); String customerId = request.getCustomerId(); do { - rateLimitPolicy.onBeforeRequest(developerToken, customerId, request); + rateLimitPolicy.onBeforeRequest(token, customerId, request); try { for (SearchGoogleAdsStreamResponse response : @@ -501,14 +497,14 @@ public void processElement(ProcessContext c) throws IOException, InterruptedExce c.output(row); } } - rateLimitPolicy.onSuccess(developerToken, customerId, request); + rateLimitPolicy.onSuccess(token, customerId, request); return; } catch (GoogleAdsException e) { GoogleAdsError retryableError = findFirstRetryableError(e.getGoogleAdsFailure()) .orElseThrow(() -> new IOException(e)); - rateLimitPolicy.onError(developerToken, customerId, request, retryableError); + rateLimitPolicy.onError(token, customerId, request, retryableError); // If the error happens to carry a suggested retry delay, then use that instead. // Retry these errors without incrementing the retry count or backoff interval. @@ -594,7 +590,7 @@ public interface RateLimitPolicy { * @param request Any Google Ads API request. * @throws InterruptedException */ - void onBeforeRequest(String developerToken, String customerId, Message request) + void onBeforeRequest(@Nullable String developerToken, String customerId, Message request) throws InterruptedException; /** @@ -604,7 +600,7 @@ void onBeforeRequest(String developerToken, String customerId, Message request) * @param customerId The customer ID specified on the request. * @param request Any Google Ads API request. */ - void onSuccess(String developerToken, String customerId, Message request); + void onSuccess(@Nullable String developerToken, String customerId, Message request); /** * Called after a request fails with a retryable error. @@ -614,7 +610,8 @@ void onBeforeRequest(String developerToken, String customerId, Message request) * @param request Any Google Ads API request. * @param error A retryable error. */ - void onError(String developerToken, String customerId, Message request, GoogleAdsError error); + void onError( + @Nullable String developerToken, String customerId, Message request, GoogleAdsError error); } /** @@ -623,20 +620,20 @@ void onBeforeRequest(String developerToken, String customerId, Message request) * global (per pipeline or otherwise) rate limit to requests and should not be used in deployments * where the Google Ads API quota is shared between multiple applications. * - *

This policy can be used to limit requests across all {@link GoogleAdsV14.Read} or {@link - * GoogleAdsV14.ReadAll} transforms by defining and using a {@link - * GoogleAdsV14.RateLimitPolicyFactory} which holds a shared static {@link - * GoogleAdsV14.SimpleRateLimitPolicy}. Note that the desired rate must be divided by the expected + *

This policy can be used to limit requests across all {@link GoogleAdsV17.Read} or {@link + * GoogleAdsV17.ReadAll} transforms by defining and using a {@link + * GoogleAdsV17.RateLimitPolicyFactory} which holds a shared static {@link + * GoogleAdsV17.SimpleRateLimitPolicy}. Note that the desired rate must be divided by the expected * maximum number of workers for the pipeline, otherwise the pipeline may exceed the desired rate * after an upscaling event. * *

{@code
-   * public class SimpleRateLimitPolicyFactory implements GoogleAdsV14.RateLimitPolicyFactory {
-   *   private static final GoogleAdsV14.RateLimitPolicy POLICY =
-   *       new GoogleAdsV14.SimpleRateLimitPolicy(1.0 / 1000.0);
+   * public class SimpleRateLimitPolicyFactory implements GoogleAdsV17.RateLimitPolicyFactory {
+   *   private static final GoogleAdsV17.RateLimitPolicy POLICY =
+   *       new GoogleAdsV17.SimpleRateLimitPolicy(1.0 / 1000.0);
    *
    *   @Override
-   *   public GoogleAdsV14.RateLimitPolicy getRateLimitPolicy() {
+   *   public GoogleAdsV17.RateLimitPolicy getRateLimitPolicy() {
    *     return POLICY;
    *   }
    * }
@@ -654,16 +651,19 @@ public SimpleRateLimitPolicy(double permitsPerSecond, long warmupPeriod, TimeUni
     }
 
     @Override
-    public void onBeforeRequest(String developerToken, String customerId, Message request)
+    public void onBeforeRequest(@Nullable String developerToken, String customerId, Message request)
         throws InterruptedException {
       rateLimiter.acquire();
     }
 
     @Override
-    public void onSuccess(String developerToken, String customerId, Message request) {}
+    public void onSuccess(@Nullable String developerToken, String customerId, Message request) {}
 
     @Override
     public void onError(
-        String developerToken, String customerId, Message request, GoogleAdsError error) {}
+        @Nullable String developerToken,
+        String customerId,
+        Message request,
+        GoogleAdsError error) {}
   }
 }
diff --git a/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/DummyRateLimitPolicy.java b/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/DummyRateLimitPolicy.java
index c2d3b230c13c..b958f28f83b0 100644
--- a/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/DummyRateLimitPolicy.java
+++ b/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/DummyRateLimitPolicy.java
@@ -17,18 +17,19 @@
  */
 package org.apache.beam.sdk.io.googleads;
 
-import com.google.ads.googleads.v14.errors.GoogleAdsError;
+import com.google.ads.googleads.v17.errors.GoogleAdsError;
 import com.google.protobuf.Message;
+import org.checkerframework.checker.nullness.qual.Nullable;
 
-public class DummyRateLimitPolicy implements GoogleAdsV14.RateLimitPolicy {
+public class DummyRateLimitPolicy implements GoogleAdsV17.RateLimitPolicy {
   @Override
-  public void onBeforeRequest(String developerToken, String customerId, Message request)
+  public void onBeforeRequest(@Nullable String developerToken, String customerId, Message request)
       throws InterruptedException {}
 
   @Override
-  public void onSuccess(String developerToken, String customerId, Message request) {}
+  public void onSuccess(@Nullable String developerToken, String customerId, Message request) {}
 
   @Override
   public void onError(
-      String developerToken, String customerId, Message request, GoogleAdsError error) {}
+      @Nullable String developerToken, String customerId, Message request, GoogleAdsError error) {}
 }
diff --git a/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/GoogleAdsV14Test.java b/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/GoogleAdsV17Test.java
similarity index 90%
rename from sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/GoogleAdsV14Test.java
rename to sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/GoogleAdsV17Test.java
index efe1694691c3..f73ab10e0824 100644
--- a/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/GoogleAdsV14Test.java
+++ b/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/GoogleAdsV17Test.java
@@ -20,18 +20,18 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.when;
 
-import com.google.ads.googleads.v14.errors.AuthenticationErrorEnum.AuthenticationError;
-import com.google.ads.googleads.v14.errors.ErrorCode;
-import com.google.ads.googleads.v14.errors.ErrorDetails;
-import com.google.ads.googleads.v14.errors.GoogleAdsError;
-import com.google.ads.googleads.v14.errors.GoogleAdsException;
-import com.google.ads.googleads.v14.errors.GoogleAdsFailure;
-import com.google.ads.googleads.v14.errors.InternalErrorEnum.InternalError;
-import com.google.ads.googleads.v14.errors.QuotaErrorDetails;
-import com.google.ads.googleads.v14.errors.QuotaErrorEnum.QuotaError;
-import com.google.ads.googleads.v14.services.GoogleAdsRow;
-import com.google.ads.googleads.v14.services.SearchGoogleAdsStreamRequest;
-import com.google.ads.googleads.v14.services.SearchGoogleAdsStreamResponse;
+import com.google.ads.googleads.v17.errors.AuthenticationErrorEnum.AuthenticationError;
+import com.google.ads.googleads.v17.errors.ErrorCode;
+import com.google.ads.googleads.v17.errors.ErrorDetails;
+import com.google.ads.googleads.v17.errors.GoogleAdsError;
+import com.google.ads.googleads.v17.errors.GoogleAdsException;
+import com.google.ads.googleads.v17.errors.GoogleAdsFailure;
+import com.google.ads.googleads.v17.errors.InternalErrorEnum.InternalError;
+import com.google.ads.googleads.v17.errors.QuotaErrorDetails;
+import com.google.ads.googleads.v17.errors.QuotaErrorEnum.QuotaError;
+import com.google.ads.googleads.v17.services.GoogleAdsRow;
+import com.google.ads.googleads.v17.services.SearchGoogleAdsStreamRequest;
+import com.google.ads.googleads.v17.services.SearchGoogleAdsStreamResponse;
 import com.google.api.gax.grpc.GrpcStatusCode;
 import com.google.api.gax.rpc.ApiException;
 import com.google.protobuf.Duration;
@@ -41,7 +41,7 @@
 import org.apache.beam.sdk.Pipeline;
 import org.apache.beam.sdk.Pipeline.PipelineExecutionException;
 import org.apache.beam.sdk.extensions.gcp.auth.NoopCredentialFactory;
-import org.apache.beam.sdk.io.googleads.GoogleAdsV14.RateLimitPolicyFactory;
+import org.apache.beam.sdk.io.googleads.GoogleAdsV17.RateLimitPolicyFactory;
 import org.apache.beam.sdk.testing.NeedsRunner;
 import org.apache.beam.sdk.testing.PAssert;
 import org.apache.beam.sdk.testing.TestPipeline;
@@ -61,7 +61,7 @@
 import org.mockito.junit.MockitoJUnitRunner;
 
 @RunWith(Enclosed.class)
-public class GoogleAdsV14Test {
+public class GoogleAdsV17Test {
   static final RateLimitPolicyFactory TEST_POLICY_FACTORY = () -> new DummyRateLimitPolicy();
 
   @RunWith(JUnit4.class)
@@ -73,7 +73,7 @@ public void testReadAllExpandWithDeveloperTokenFromBuilder() {
       pipeline
           .apply(Create.empty(new TypeDescriptor() {}))
           .apply(
-              GoogleAdsIO.v14()
+              GoogleAdsIO.v17()
                   .readAll()
                   .withRateLimitPolicy(TEST_POLICY_FACTORY)
                   .withDeveloperToken("abc"));
@@ -84,7 +84,7 @@ public void testReadAllExpandWithDeveloperTokenFromOptions() {
       pipeline.getOptions().as(GoogleAdsOptions.class).setGoogleAdsDeveloperToken("abc");
       pipeline
           .apply(Create.empty(new TypeDescriptor() {}))
-          .apply(GoogleAdsIO.v14().readAll().withRateLimitPolicy(TEST_POLICY_FACTORY));
+          .apply(GoogleAdsIO.v17().readAll().withRateLimitPolicy(TEST_POLICY_FACTORY));
     }
 
     @Test
@@ -93,7 +93,7 @@ public void testReadAllExpandWithDeveloperTokenFromOptionsAndBuilder() {
       pipeline
           .apply(Create.empty(new TypeDescriptor() {}))
           .apply(
-              GoogleAdsIO.v14()
+              GoogleAdsIO.v17()
                   .readAll()
                   .withRateLimitPolicy(TEST_POLICY_FACTORY)
                   .withDeveloperToken(null));
@@ -107,7 +107,7 @@ public void testReadAllExpandWithoutDeveloperToken() throws Exception {
           () ->
               pipeline
                   .apply(Create.empty(new TypeDescriptor() {}))
-                  .apply(GoogleAdsIO.v14().readAll().withRateLimitPolicy(TEST_POLICY_FACTORY)));
+                  .apply(GoogleAdsIO.v17().readAll().withRateLimitPolicy(TEST_POLICY_FACTORY)));
     }
 
     @Test
@@ -118,7 +118,7 @@ public void testReadAllExpandWithoutRateLimitPolicy() throws Exception {
           () ->
               pipeline
                   .apply(Create.empty(new TypeDescriptor() {}))
-                  .apply(GoogleAdsIO.v14().readAll().withDeveloperToken("abc")));
+                  .apply(GoogleAdsIO.v17().readAll().withDeveloperToken("abc")));
     }
 
     @Test
@@ -130,7 +130,7 @@ public void testReadAllExpandWithoutValidGoogleAdsClientFactory() throws Excepti
               pipeline
                   .apply(Create.empty(new TypeDescriptor() {}))
                   .apply(
-                      GoogleAdsIO.v14()
+                      GoogleAdsIO.v17()
                           .readAll()
                           .withRateLimitPolicy(TEST_POLICY_FACTORY)
                           .withGoogleAdsClientFactory(null)));
@@ -144,7 +144,7 @@ public void testReadAllExpandWithoutValidRateLimitPolicy() throws Exception {
           () ->
               pipeline
                   .apply(Create.empty(new TypeDescriptor() {}))
-                  .apply(GoogleAdsIO.v14().readAll().withRateLimitPolicy(null)));
+                  .apply(GoogleAdsIO.v17().readAll().withRateLimitPolicy(null)));
     }
 
     @Test
@@ -152,7 +152,7 @@ public void testReadExpandWithDeveloperTokenFromBuilder() {
       pipeline
           .apply(Create.empty(TypeDescriptors.strings()))
           .apply(
-              GoogleAdsIO.v14()
+              GoogleAdsIO.v17()
                   .read()
                   .withRateLimitPolicy(TEST_POLICY_FACTORY)
                   .withDeveloperToken("abc")
@@ -161,7 +161,7 @@ public void testReadExpandWithDeveloperTokenFromBuilder() {
       pipeline
           .apply(Create.empty(TypeDescriptors.strings()))
           .apply(
-              GoogleAdsIO.v14().read().withRateLimitPolicy(TEST_POLICY_FACTORY).withQuery("GAQL"));
+              GoogleAdsIO.v17().read().withRateLimitPolicy(TEST_POLICY_FACTORY).withQuery("GAQL"));
     }
 
     @Test
@@ -170,7 +170,7 @@ public void testReadExpandWithDeveloperTokenFromOptions() {
       pipeline
           .apply(Create.empty(TypeDescriptors.strings()))
           .apply(
-              GoogleAdsIO.v14().read().withRateLimitPolicy(TEST_POLICY_FACTORY).withQuery("GAQL"));
+              GoogleAdsIO.v17().read().withRateLimitPolicy(TEST_POLICY_FACTORY).withQuery("GAQL"));
     }
 
     @Test
@@ -179,7 +179,7 @@ public void testReadExpandWithDeveloperTokenFromOptionsAndBuilder() {
       pipeline
           .apply(Create.empty(TypeDescriptors.strings()))
           .apply(
-              GoogleAdsIO.v14()
+              GoogleAdsIO.v17()
                   .read()
                   .withRateLimitPolicy(TEST_POLICY_FACTORY)
                   .withDeveloperToken(null)
@@ -195,7 +195,7 @@ public void testReadExpandWithoutDeveloperToken() throws Exception {
               pipeline
                   .apply(Create.empty(TypeDescriptors.strings()))
                   .apply(
-                      GoogleAdsIO.v14()
+                      GoogleAdsIO.v17()
                           .read()
                           .withRateLimitPolicy(TEST_POLICY_FACTORY)
                           .withQuery("GAQL")));
@@ -209,7 +209,7 @@ public void testReadExpandWithoutQuery() throws Exception {
           () ->
               pipeline
                   .apply(Create.empty(TypeDescriptors.strings()))
-                  .apply(GoogleAdsIO.v14().read().withRateLimitPolicy(TEST_POLICY_FACTORY)));
+                  .apply(GoogleAdsIO.v17().read().withRateLimitPolicy(TEST_POLICY_FACTORY)));
     }
 
     @Test
@@ -220,7 +220,7 @@ public void testReadExpandWithoutRateLimitPolicy() throws Exception {
           () ->
               pipeline
                   .apply(Create.empty(TypeDescriptors.strings()))
-                  .apply(GoogleAdsIO.v14().read().withDeveloperToken("abc").withQuery("GAQL")));
+                  .apply(GoogleAdsIO.v17().read().withDeveloperToken("abc").withQuery("GAQL")));
     }
 
     @Test
@@ -232,7 +232,7 @@ public void testReadExpandWithoutValidGoogleAdsClientFactory() throws Exception
               pipeline
                   .apply(Create.empty(TypeDescriptors.strings()))
                   .apply(
-                      GoogleAdsIO.v14()
+                      GoogleAdsIO.v17()
                           .read()
                           .withRateLimitPolicy(TEST_POLICY_FACTORY)
                           .withQuery("GAQL")
@@ -248,7 +248,7 @@ public void testReadExpandWithoutValidQuery() throws Exception {
               pipeline
                   .apply(Create.empty(TypeDescriptors.strings()))
                   .apply(
-                      GoogleAdsIO.v14()
+                      GoogleAdsIO.v17()
                           .read()
                           .withRateLimitPolicy(TEST_POLICY_FACTORY)
                           .withQuery(null)));
@@ -260,7 +260,7 @@ public void testReadExpandWithoutValidQuery() throws Exception {
               pipeline
                   .apply(Create.empty(TypeDescriptors.strings()))
                   .apply(
-                      GoogleAdsIO.v14()
+                      GoogleAdsIO.v17()
                           .read()
                           .withRateLimitPolicy(TEST_POLICY_FACTORY)
                           .withQuery("")));
@@ -274,7 +274,7 @@ public void testReadExpandWithoutValidRateLimitPolicy() throws Exception {
           () ->
               pipeline
                   .apply(Create.empty(TypeDescriptors.strings()))
-                  .apply(GoogleAdsIO.v14().read().withQuery("GAQL").withRateLimitPolicy(null)));
+                  .apply(GoogleAdsIO.v17().read().withQuery("GAQL").withRateLimitPolicy(null)));
     }
   }
 
@@ -286,15 +286,15 @@ public static class ExecutionTests {
     public void init() {
       GoogleAdsOptions options = pipeline.getOptions().as(GoogleAdsOptions.class);
       options.setGoogleAdsCredentialFactoryClass(NoopCredentialFactory.class);
-      synchronized (GoogleAdsV14.ReadAll.ReadAllFn.class) {
-        GoogleAdsV14.ReadAll.ReadAllFn.sleeper = (long millis) -> {};
+      synchronized (GoogleAdsV17.ReadAll.ReadAllFn.class) {
+        GoogleAdsV17.ReadAll.ReadAllFn.sleeper = (long millis) -> {};
       }
     }
 
     @Test
     @Category(NeedsRunner.class)
     public void testRead() {
-      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V14
+      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V17
               .searchStreamCallable()
               .call(any(SearchGoogleAdsStreamRequest.class))
               .iterator())
@@ -309,7 +309,7 @@ public void testRead() {
           pipeline
               .apply(Create.of("123"))
               .apply(
-                  GoogleAdsIO.v14()
+                  GoogleAdsIO.v17()
                       .read()
                       .withGoogleAdsClientFactory(new MockGoogleAdsClientFactory())
                       .withRateLimitPolicy(TEST_POLICY_FACTORY)
@@ -323,7 +323,7 @@ public void testRead() {
     @Test
     @Category(NeedsRunner.class)
     public void testReadWithFailureFromMaxRetriesExceeded() throws Exception {
-      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V14
+      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V17
               .searchStreamCallable()
               .call(any(SearchGoogleAdsStreamRequest.class)))
           .thenThrow(
@@ -341,7 +341,7 @@ public void testReadWithFailureFromMaxRetriesExceeded() throws Exception {
       pipeline
           .apply(Create.of("123"))
           .apply(
-              GoogleAdsIO.v14()
+              GoogleAdsIO.v17()
                   .read()
                   .withGoogleAdsClientFactory(new MockGoogleAdsClientFactory())
                   .withRateLimitPolicy(TEST_POLICY_FACTORY)
@@ -362,7 +362,7 @@ public void testReadWithFailureFromMaxRetriesExceeded() throws Exception {
     @Test
     @Category(NeedsRunner.class)
     public void testReadWithFailureFromNonRetryableError() throws Exception {
-      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V14
+      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V17
               .searchStreamCallable()
               .call(any(SearchGoogleAdsStreamRequest.class)))
           .thenThrow(
@@ -381,7 +381,7 @@ public void testReadWithFailureFromNonRetryableError() throws Exception {
       pipeline
           .apply(Create.of("123"))
           .apply(
-              GoogleAdsIO.v14()
+              GoogleAdsIO.v17()
                   .read()
                   .withGoogleAdsClientFactory(new MockGoogleAdsClientFactory())
                   .withRateLimitPolicy(TEST_POLICY_FACTORY)
@@ -395,7 +395,7 @@ public void testReadWithFailureFromNonRetryableError() throws Exception {
               pipeline::run);
       Assert.assertEquals(IOException.class, exception.getCause().getClass());
       Assert.assertEquals(
-          "com.google.ads.googleads.v14.errors.GoogleAdsException: errors {\n"
+          "com.google.ads.googleads.v17.errors.GoogleAdsException: errors {\n"
               + "  error_code {\n"
               + "    authentication_error: OAUTH_TOKEN_REVOKED\n"
               + "  }\n"
@@ -406,7 +406,7 @@ public void testReadWithFailureFromNonRetryableError() throws Exception {
     @Test
     @Category(NeedsRunner.class)
     public void testReadWithRecoveryFromInternalError() throws Exception {
-      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V14
+      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V17
               .searchStreamCallable()
               .call(any(SearchGoogleAdsStreamRequest.class))
               .iterator())
@@ -443,7 +443,7 @@ public void testReadWithRecoveryFromInternalError() throws Exception {
           pipeline
               .apply(Create.of("123"))
               .apply(
-                  GoogleAdsIO.v14()
+                  GoogleAdsIO.v17()
                       .read()
                       .withGoogleAdsClientFactory(new MockGoogleAdsClientFactory())
                       .withRateLimitPolicy(TEST_POLICY_FACTORY)
@@ -457,7 +457,7 @@ public void testReadWithRecoveryFromInternalError() throws Exception {
     @Test
     @Category(NeedsRunner.class)
     public void testReadWithRecoveryFromQuotaErrorWithRetryDelay() throws Exception {
-      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V14
+      when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V17
               .searchStreamCallable()
               .call(any(SearchGoogleAdsStreamRequest.class))
               .iterator())
@@ -505,7 +505,7 @@ public void testReadWithRecoveryFromQuotaErrorWithRetryDelay() throws Exception
           pipeline
               .apply(Create.of("123"))
               .apply(
-                  GoogleAdsIO.v14()
+                  GoogleAdsIO.v17()
                       .read()
                       .withGoogleAdsClientFactory(new MockGoogleAdsClientFactory())
                       .withRateLimitPolicy(TEST_POLICY_FACTORY)
diff --git a/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/MockGoogleAdsClientFactory.java b/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/MockGoogleAdsClientFactory.java
index 258b47763a4b..4ed1f87788f5 100644
--- a/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/MockGoogleAdsClientFactory.java
+++ b/sdks/java/io/google-ads/src/test/java/org/apache/beam/sdk/io/googleads/MockGoogleAdsClientFactory.java
@@ -23,12 +23,12 @@
 import static org.mockito.Mockito.withSettings;
 
 import com.google.ads.googleads.lib.GoogleAdsClient;
-import com.google.ads.googleads.v14.services.GoogleAdsServiceClient;
-import com.google.ads.googleads.v14.services.stub.GoogleAdsServiceStub;
+import com.google.ads.googleads.v17.services.GoogleAdsServiceClient;
+import com.google.ads.googleads.v17.services.stub.GoogleAdsServiceStub;
 import org.checkerframework.checker.nullness.qual.Nullable;
 
 class MockGoogleAdsClientFactory implements GoogleAdsClientFactory {
-  static final GoogleAdsServiceStub GOOGLE_ADS_SERVICE_STUB_V14 =
+  static final GoogleAdsServiceStub GOOGLE_ADS_SERVICE_STUB_V17 =
       mock(GoogleAdsServiceStub.class, withSettings().defaultAnswer(RETURNS_DEEP_STUBS));
 
   @Override
@@ -39,8 +39,8 @@ public GoogleAdsClient newGoogleAdsClient(
       @Nullable Long loginCustomerId) {
     GoogleAdsClient mockGoogleAdsClient =
         mock(GoogleAdsClient.class, withSettings().defaultAnswer(RETURNS_DEEP_STUBS));
-    when(mockGoogleAdsClient.getVersion14().createGoogleAdsServiceClient())
-        .thenReturn(GoogleAdsServiceClient.create(GOOGLE_ADS_SERVICE_STUB_V14));
+    when(mockGoogleAdsClient.getVersion17().createGoogleAdsServiceClient())
+        .thenReturn(GoogleAdsServiceClient.create(GOOGLE_ADS_SERVICE_STUB_V17));
     return mockGoogleAdsClient;
   }
 }