Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions sdks/java/io/google-ads/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ dependencies {
implementation library.java.google_auth_library_oauth2_http
implementation library.java.protobuf_java
implementation library.java.protobuf_java_util
implementation "com.google.api-ads:google-ads:42.0.0"
implementation "com.google.api-ads:google-ads-stubs-v23:42.0.0"
implementation "com.google.api-ads:google-ads:47.0.0"
implementation "com.google.api-ads:google-ads-stubs-v25:47.0.0"
implementation library.java.joda_time
implementation library.java.vendored_guava_32_1_2_jre
testImplementation project(path: ":sdks:java:core", configuration: "shadowTest")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
* href="https://developers.google.com/google-ads/api/docs/start">Google Ads API</a> over supported
* versions of the Google Ads client libraries.
*
* @see GoogleAdsV23
* @see GoogleAdsV25
*/
public abstract class GoogleAdsIO<GoogleAdsRowT, SearchGoogleAdsStreamRequestT> {

Expand All @@ -45,8 +45,8 @@ public abstract class GoogleAdsIO<GoogleAdsRowT, SearchGoogleAdsStreamRequestT>
PTransform<PCollection<SearchGoogleAdsStreamRequestT>, PCollection<GoogleAdsRowT>>>
T readAll();

public static GoogleAdsV23 current() {
return GoogleAdsV23.INSTANCE;
public static GoogleAdsV25 current() {
return GoogleAdsV25.INSTANCE;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.v23.errors.GoogleAdsError;
import com.google.ads.googleads.v23.errors.GoogleAdsException;
import com.google.ads.googleads.v23.errors.GoogleAdsFailure;
import com.google.ads.googleads.v23.errors.InternalErrorEnum;
import com.google.ads.googleads.v23.errors.QuotaErrorEnum;
import com.google.ads.googleads.v23.services.GoogleAdsRow;
import com.google.ads.googleads.v23.services.GoogleAdsServiceClient;
import com.google.ads.googleads.v23.services.SearchGoogleAdsStreamRequest;
import com.google.ads.googleads.v23.services.SearchGoogleAdsStreamResponse;
import com.google.ads.googleads.v25.errors.GoogleAdsError;
import com.google.ads.googleads.v25.errors.GoogleAdsException;
import com.google.ads.googleads.v25.errors.GoogleAdsFailure;
import com.google.ads.googleads.v25.errors.InternalErrorEnum;
import com.google.ads.googleads.v25.errors.QuotaErrorEnum;
import com.google.ads.googleads.v25.services.GoogleAdsRow;
import com.google.ads.googleads.v25.services.GoogleAdsServiceClient;
import com.google.ads.googleads.v25.services.SearchGoogleAdsStreamRequest;
import com.google.ads.googleads.v25.services.SearchGoogleAdsStreamResponse;
import com.google.auto.value.AutoValue;
import com.google.protobuf.Message;
import com.google.protobuf.util.Durations;
Expand All @@ -57,7 +57,7 @@
import org.joda.time.Duration;

/**
* {@link GoogleAdsV23} provides an API to read Google Ads API v23 reports.
* {@link GoogleAdsV25} provides an API to read Google Ads API v25 reports.
*
* <p>No backward compatibility guaranteed. Do not use directly. Use {@link GoogleAdsIO#current()}
* to access GoogleAdsIO instead.
Expand All @@ -79,15 +79,15 @@
* --googleAdsDeveloperToken=your-developer-token
* </pre>
*
* <p>Use {@link GoogleAdsV23#read()} to read either a bounded or unbounded {@link PCollection} of
* <p>Use {@link GoogleAdsV25#read()} to read either a bounded or unbounded {@link PCollection} of
* {@link GoogleAdsRow} from a single <a
* href="https://developers.google.com/google-ads/api/docs/query/overview">Google Ads Query
* Language</a> query using {@link Read#withQuery(String)} and a {@link PCollection} of customer
* IDs. Alternatively, use {@link GoogleAdsV23#readAll()} to read either a bounded or unbounded
* IDs. Alternatively, use {@link GoogleAdsV25#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.
*
* <p>For example, using {@link GoogleAdsV23#read()}:
* <p>For example, using {@link GoogleAdsV25#read()}:
*
* <pre>{@code
* Pipeline p = Pipeline.create();
Expand All @@ -107,7 +107,7 @@
* p.run();
* }</pre>
*
* <p>Alternatively, using {@link GoogleAdsV23#readAll()} to execute requests from a {@link
* <p>Alternatively, using {@link GoogleAdsV25#readAll()} to execute requests from a {@link
* PCollection} of {@link SearchGoogleAdsStreamRequest}:
*
* <pre>{@code
Expand All @@ -132,7 +132,7 @@
*
* <h2>Client-side rate limiting</h2>
*
* On construction of a {@link GoogleAdsV23#read()} or {@link GoogleAdsV23#readAll()} transform a
* On construction of a {@link GoogleAdsV25#read()} or {@link GoogleAdsV25#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
Expand Down Expand Up @@ -161,21 +161,21 @@
* @see <a href="https://developers.google.com/google-ads/api/docs/best-practices/overview">Best
* Practices in the Google Ads documentation</a>
*/
public class GoogleAdsV23 extends GoogleAdsIO<GoogleAdsRow, SearchGoogleAdsStreamRequest> {
static final GoogleAdsV23 INSTANCE = new GoogleAdsV23();
public class GoogleAdsV25 extends GoogleAdsIO<GoogleAdsRow, SearchGoogleAdsStreamRequest> {
static final GoogleAdsV25 INSTANCE = new GoogleAdsV25();

private GoogleAdsV23() {}
private GoogleAdsV25() {}

@Override
public Read read() {
return new AutoValue_GoogleAdsV23_Read.Builder()
return new AutoValue_GoogleAdsV25_Read.Builder()
.setGoogleAdsClientFactory(DefaultGoogleAdsClientFactory.getInstance())
.build();
}

@Override
public ReadAll readAll() {
return new AutoValue_GoogleAdsV23_ReadAll.Builder()
return new AutoValue_GoogleAdsV25_ReadAll.Builder()
.setGoogleAdsClientFactory(DefaultGoogleAdsClientFactory.getInstance())
.build();
}
Expand Down Expand Up @@ -450,13 +450,13 @@ static class ReadAllFn extends DoFn<SearchGoogleAdsStreamRequest, GoogleAdsRow>

@VisibleForTesting static Sleeper sleeper = Sleeper.DEFAULT;

private final GoogleAdsV23.ReadAll spec;
private final GoogleAdsV25.ReadAll spec;

private transient @Nullable GoogleAdsClient googleAdsClient;
private transient @Nullable GoogleAdsServiceClient googleAdsServiceClient;
private transient @Nullable RateLimitPolicy<GoogleAdsError> rateLimitPolicy;

ReadAllFn(GoogleAdsV23.ReadAll spec) {
ReadAllFn(GoogleAdsV25.ReadAll spec) {
this.spec = spec;
}

Expand All @@ -470,7 +470,7 @@ public void setup(PipelineOptions options) {
.newGoogleAdsClient(
adsOptions, spec.getDeveloperToken(), null, spec.getLoginCustomerId());
final GoogleAdsServiceClient googleAdsServiceClient =
googleAdsClient.getVersion23().createGoogleAdsServiceClient();
googleAdsClient.getVersion25().createGoogleAdsServiceClient();
final RateLimitPolicy<GoogleAdsError> rateLimitPolicy =
checkStateNotNull(spec.getRateLimitPolicyFactory()).getRateLimitPolicy();

Expand Down Expand Up @@ -578,17 +578,17 @@ private Optional<GoogleAdsError> findFirstRetryableError(GoogleAdsFailure e) {
* 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.
*
* <p>This policy can be used to limit requests across all {@link GoogleAdsV23.Read} or {@link
* GoogleAdsV23.ReadAll} transforms by defining and using a {@link
* GoogleAdsV23.RateLimitPolicyFactory} which holds a shared static {@link
* GoogleAdsV23.SimpleRateLimitPolicy}. Note that the desired rate must be divided by the expected
* <p>This policy can be used to limit requests across all {@link GoogleAdsV25.Read} or {@link
* GoogleAdsV25.ReadAll} transforms by defining and using a {@link
* GoogleAdsV25.RateLimitPolicyFactory} which holds a shared static {@link
* GoogleAdsV25.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.
*
* <pre>{@code
* public class SimpleRateLimitPolicyFactory implements GoogleAdsIO.RateLimitPolicyFactory {
* private static final GoogleAdsIO.RateLimitPolicy POLICY =
* new GoogleAdsV23.SimpleRateLimitPolicy(1.0 / 1000.0);
* new GoogleAdsV25.SimpleRateLimitPolicy(1.0 / 1000.0);
*
* @Override
* public GoogleAdsIO.RateLimitPolicy getRateLimitPolicy() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
package org.apache.beam.sdk.io.googleads;

import com.google.ads.googleads.v23.errors.GoogleAdsError;
import com.google.ads.googleads.v25.errors.GoogleAdsError;
import com.google.protobuf.Message;
import org.checkerframework.checker.nullness.qual.Nullable;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.when;

import com.google.ads.googleads.v23.errors.AuthenticationErrorEnum.AuthenticationError;
import com.google.ads.googleads.v23.errors.ErrorCode;
import com.google.ads.googleads.v23.errors.ErrorDetails;
import com.google.ads.googleads.v23.errors.GoogleAdsError;
import com.google.ads.googleads.v23.errors.GoogleAdsException;
import com.google.ads.googleads.v23.errors.GoogleAdsFailure;
import com.google.ads.googleads.v23.errors.InternalErrorEnum.InternalError;
import com.google.ads.googleads.v23.errors.QuotaErrorDetails;
import com.google.ads.googleads.v23.errors.QuotaErrorEnum.QuotaError;
import com.google.ads.googleads.v23.services.GoogleAdsRow;
import com.google.ads.googleads.v23.services.SearchGoogleAdsStreamRequest;
import com.google.ads.googleads.v23.services.SearchGoogleAdsStreamResponse;
import com.google.ads.googleads.v25.errors.AuthenticationErrorEnum.AuthenticationError;
import com.google.ads.googleads.v25.errors.ErrorCode;
import com.google.ads.googleads.v25.errors.ErrorDetails;
import com.google.ads.googleads.v25.errors.GoogleAdsError;
import com.google.ads.googleads.v25.errors.GoogleAdsException;
import com.google.ads.googleads.v25.errors.GoogleAdsFailure;
import com.google.ads.googleads.v25.errors.InternalErrorEnum.InternalError;
import com.google.ads.googleads.v25.errors.QuotaErrorDetails;
import com.google.ads.googleads.v25.errors.QuotaErrorEnum.QuotaError;
import com.google.ads.googleads.v25.services.GoogleAdsRow;
import com.google.ads.googleads.v25.services.SearchGoogleAdsStreamRequest;
import com.google.ads.googleads.v25.services.SearchGoogleAdsStreamResponse;
import com.google.api.gax.grpc.GrpcStatusCode;
import com.google.api.gax.rpc.ApiException;
import com.google.protobuf.Duration;
Expand Down Expand Up @@ -294,15 +294,15 @@ public static class ExecutionTests {
public void init() {
GoogleAdsOptions options = pipeline.getOptions().as(GoogleAdsOptions.class);
options.setGoogleAdsCredentialFactoryClass(NoopCredentialFactory.class);
synchronized (GoogleAdsV23.ReadAll.ReadAllFn.class) {
GoogleAdsV23.ReadAll.ReadAllFn.sleeper = (long millis) -> {};
synchronized (GoogleAdsV25.ReadAll.ReadAllFn.class) {
GoogleAdsV25.ReadAll.ReadAllFn.sleeper = (long millis) -> {};
}
}

@Test
@Category(NeedsRunner.class)
public void testRead() {
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V23
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V25
.searchStreamCallable()
.call(any(SearchGoogleAdsStreamRequest.class))
.iterator())
Expand Down Expand Up @@ -331,7 +331,7 @@ public void testRead() {
@Test
@Category(NeedsRunner.class)
public void testReadWithFailureFromMaxRetriesExceeded() throws Exception {
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V23
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V25
.searchStreamCallable()
.call(any(SearchGoogleAdsStreamRequest.class)))
.thenThrow(
Expand Down Expand Up @@ -370,7 +370,7 @@ public void testReadWithFailureFromMaxRetriesExceeded() throws Exception {
@Test
@Category(NeedsRunner.class)
public void testReadWithFailureFromNonRetryableError() throws Exception {
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V23
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V25
.searchStreamCallable()
.call(any(SearchGoogleAdsStreamRequest.class)))
.thenThrow(
Expand Down Expand Up @@ -403,7 +403,7 @@ public void testReadWithFailureFromNonRetryableError() throws Exception {
pipeline::run);
Assert.assertEquals(IOException.class, exception.getCause().getClass());
Assert.assertEquals(
"com.google.ads.googleads.v23.errors.GoogleAdsException: errors {\n"
"com.google.ads.googleads.v25.errors.GoogleAdsException: errors {\n"
+ " error_code {\n"
+ " authentication_error: OAUTH_TOKEN_REVOKED\n"
+ " }\n"
Expand All @@ -414,7 +414,7 @@ public void testReadWithFailureFromNonRetryableError() throws Exception {
@Test
@Category(NeedsRunner.class)
public void testReadWithRecoveryFromInternalError() throws Exception {
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V23
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V25
.searchStreamCallable()
.call(any(SearchGoogleAdsStreamRequest.class))
.iterator())
Expand Down Expand Up @@ -465,7 +465,7 @@ public void testReadWithRecoveryFromInternalError() throws Exception {
@Test
@Category(NeedsRunner.class)
public void testReadWithRecoveryFromQuotaErrorWithRetryDelay() throws Exception {
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V23
when(MockGoogleAdsClientFactory.GOOGLE_ADS_SERVICE_STUB_V25
.searchStreamCallable()
.call(any(SearchGoogleAdsStreamRequest.class))
.iterator())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@
import static org.mockito.Mockito.withSettings;

import com.google.ads.googleads.lib.GoogleAdsClient;
import com.google.ads.googleads.v23.services.GoogleAdsServiceClient;
import com.google.ads.googleads.v23.services.stub.GoogleAdsServiceStub;
import com.google.ads.googleads.v25.services.GoogleAdsServiceClient;
import com.google.ads.googleads.v25.services.stub.GoogleAdsServiceStub;
import org.checkerframework.checker.nullness.qual.Nullable;

class MockGoogleAdsClientFactory implements GoogleAdsClientFactory {
static final GoogleAdsServiceStub GOOGLE_ADS_SERVICE_STUB_V23 =
static final GoogleAdsServiceStub GOOGLE_ADS_SERVICE_STUB_V25 =
mock(GoogleAdsServiceStub.class, withSettings().defaultAnswer(RETURNS_DEEP_STUBS));

@Override
Expand All @@ -39,8 +39,8 @@ public GoogleAdsClient newGoogleAdsClient(
@Nullable Long loginCustomerId) {
GoogleAdsClient mockGoogleAdsClient =
mock(GoogleAdsClient.class, withSettings().defaultAnswer(RETURNS_DEEP_STUBS));
when(mockGoogleAdsClient.getVersion23().createGoogleAdsServiceClient())
.thenReturn(GoogleAdsServiceClient.create(GOOGLE_ADS_SERVICE_STUB_V23));
when(mockGoogleAdsClient.getVersion25().createGoogleAdsServiceClient())
.thenReturn(GoogleAdsServiceClient.create(GOOGLE_ADS_SERVICE_STUB_V25));
return mockGoogleAdsClient;
}
}
Loading