() {
- @Override
- public void onSuccess(IntermediateCredentials result) {
- RefreshTask.this.set(result);
- }
-
- @Override
- public void onFailure(@Nullable Throwable t) {
- RefreshTask.this.setException(
- t != null ? t : new IOException("Refresh failed with null Throwable."));
+ RefreshTask.this.setException(cause != null ? cause : e);
+ } catch (Throwable t) {
+ RefreshTask.this.setException(t);
}
},
MoreExecutors.directExecutor());
diff --git a/google-auth-library-java/cab-token-generator/javatests/com/google/auth/credentialaccessboundary/ClientSideCredentialAccessBoundaryFactoryTest.java b/google-auth-library-java/cab-token-generator/javatests/com/google/auth/credentialaccessboundary/ClientSideCredentialAccessBoundaryFactoryTest.java
index a1714a9ba92f..bfe9077c990f 100644
--- a/google-auth-library-java/cab-token-generator/javatests/com/google/auth/credentialaccessboundary/ClientSideCredentialAccessBoundaryFactoryTest.java
+++ b/google-auth-library-java/cab-token-generator/javatests/com/google/auth/credentialaccessboundary/ClientSideCredentialAccessBoundaryFactoryTest.java
@@ -988,4 +988,59 @@ void generateToken_withMalformSessionKey_failure() throws Exception {
assertThrows(GeneralSecurityException.class, () -> factory.generateToken(accessBoundary));
}
+
+ @Test
+ void generateToken_freshInstance_concurrent_noNpe() throws Exception {
+ for (int run = 0; run < 10; run++) { // Run 10 times in a single test instance to save time
+ GoogleCredentials sourceCredentials =
+ getServiceAccountSourceCredentials(mockTokenServerTransportFactory);
+ ClientSideCredentialAccessBoundaryFactory factory =
+ ClientSideCredentialAccessBoundaryFactory.newBuilder()
+ .setSourceCredential(sourceCredentials)
+ .setHttpTransportFactory(mockStsTransportFactory)
+ .build();
+
+ CredentialAccessBoundary.Builder cabBuilder = CredentialAccessBoundary.newBuilder();
+ CredentialAccessBoundary accessBoundary =
+ cabBuilder
+ .addRule(
+ CredentialAccessBoundary.AccessBoundaryRule.newBuilder()
+ .setAvailableResource("resource")
+ .setAvailablePermissions(ImmutableList.of("role"))
+ .build())
+ .build();
+
+ int numThreads = 5;
+ CountDownLatch latch = new CountDownLatch(numThreads);
+ java.util.concurrent.atomic.AtomicInteger npeCount =
+ new java.util.concurrent.atomic.AtomicInteger();
+ java.util.concurrent.ExecutorService executor =
+ java.util.concurrent.Executors.newFixedThreadPool(numThreads);
+
+ try {
+ for (int i = 0; i < numThreads; i++) {
+ executor.submit(
+ () -> {
+ try {
+ latch.countDown();
+ latch.await();
+ factory.generateToken(accessBoundary);
+ } catch (NullPointerException e) {
+ npeCount.incrementAndGet();
+ } catch (Exception e) {
+ // Ignore other exceptions for the sake of the race reproduction
+ }
+ });
+ }
+ } finally {
+ executor.shutdown();
+ executor.awaitTermination(5, java.util.concurrent.TimeUnit.SECONDS);
+ }
+
+ org.junit.jupiter.api.Assertions.assertEquals(
+ 0,
+ npeCount.get(),
+ "Expected zero NullPointerExceptions due to the race condition, but some were thrown.");
+ }
+ }
}
diff --git a/google-auth-library-java/cab-token-generator/pom.xml b/google-auth-library-java/cab-token-generator/pom.xml
index 32a61919d1f3..f14748eeb066 100644
--- a/google-auth-library-java/cab-token-generator/pom.xml
+++ b/google-auth-library-java/cab-token-generator/pom.xml
@@ -6,7 +6,7 @@
com.google.auth
google-auth-library-parent
- 1.45.0
+ 1.46.0
google-auth-library-cab-token-generator
diff --git a/google-auth-library-java/credentials/pom.xml b/google-auth-library-java/credentials/pom.xml
index 5dd5795bd184..62cff4c16bb8 100644
--- a/google-auth-library-java/credentials/pom.xml
+++ b/google-auth-library-java/credentials/pom.xml
@@ -4,7 +4,7 @@
com.google.auth
google-auth-library-parent
- 1.45.0
+ 1.46.0
../pom.xml
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/mtls/MtlsUtils.java b/google-auth-library-java/oauth2_http/java/com/google/auth/mtls/MtlsUtils.java
new file mode 100644
index 000000000000..0d34cf271986
--- /dev/null
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/mtls/MtlsUtils.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.google.auth.mtls;
+
+import com.google.api.core.InternalApi;
+import com.google.auth.oauth2.EnvironmentProvider;
+import com.google.auth.oauth2.PropertyProvider;
+import com.google.common.base.Strings;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Locale;
+
+/**
+ * Utility class for mTLS related operations.
+ *
+ * For internal use only.
+ */
+@InternalApi
+public class MtlsUtils {
+ static final String CERTIFICATE_CONFIGURATION_ENV_VARIABLE = "GOOGLE_API_CERTIFICATE_CONFIG";
+ static final String WELL_KNOWN_CERTIFICATE_CONFIG_FILE = "certificate_config.json";
+ static final String CLOUDSDK_CONFIG_DIRECTORY = "gcloud";
+
+ private MtlsUtils() {
+ // Prevent instantiation for Utility class
+ }
+
+ /**
+ * Returns the path to the client certificate file specified by the loaded workload certificate
+ * configuration.
+ *
+ * @return The path to the certificate file.
+ * @throws IOException if the certificate configuration cannot be found or loaded.
+ */
+ public static String getCertificatePath(
+ EnvironmentProvider envProvider, PropertyProvider propProvider, String certConfigPathOverride)
+ throws IOException {
+ String certPath =
+ getWorkloadCertificateConfiguration(envProvider, propProvider, certConfigPathOverride)
+ .getCertPath();
+ if (Strings.isNullOrEmpty(certPath)) {
+ throw new CertificateSourceUnavailableException(
+ "Certificate configuration loaded successfully, but does not contain a 'certificate_file' path.");
+ }
+ return certPath;
+ }
+
+ /**
+ * Resolves and loads the workload certificate configuration.
+ *
+ *
The configuration file is resolved in the following order of precedence: 1. The provided
+ * certConfigPathOverride (if not null). 2. The path specified by the
+ * GOOGLE_API_CERTIFICATE_CONFIG environment variable. 3. The well-known certificate configuration
+ * file in the gcloud config directory.
+ *
+ * @param envProvider the environment provider to use for resolving environment variables
+ * @param propProvider the property provider to use for resolving system properties
+ * @param certConfigPathOverride optional override path for the configuration file
+ * @return the loaded WorkloadCertificateConfiguration
+ * @throws IOException if the configuration file cannot be found, read, or parsed
+ */
+ static WorkloadCertificateConfiguration getWorkloadCertificateConfiguration(
+ EnvironmentProvider envProvider, PropertyProvider propProvider, String certConfigPathOverride)
+ throws IOException {
+ File certConfig;
+ if (certConfigPathOverride != null) {
+ certConfig = new File(certConfigPathOverride);
+ } else {
+ String envCredentialsPath = envProvider.getEnv(CERTIFICATE_CONFIGURATION_ENV_VARIABLE);
+ if (!Strings.isNullOrEmpty(envCredentialsPath)) {
+ certConfig = new File(envCredentialsPath);
+ } else {
+ certConfig = getWellKnownCertificateConfigFile(envProvider, propProvider);
+ }
+ }
+
+ if (!certConfig.isFile()) {
+ throw new CertificateSourceUnavailableException(
+ "Certificate configuration file does not exist or is not a file: "
+ + certConfig.getAbsolutePath());
+ }
+ try (InputStream certConfigStream = new FileInputStream(certConfig)) {
+ return WorkloadCertificateConfiguration.fromCertificateConfigurationStream(certConfigStream);
+ }
+ }
+
+ private static File getWellKnownCertificateConfigFile(
+ EnvironmentProvider envProvider, PropertyProvider propProvider) throws IOException {
+ File cloudConfigPath;
+ String envPath = envProvider.getEnv("CLOUDSDK_CONFIG");
+ if (envPath != null) {
+ cloudConfigPath = new File(envPath);
+ } else {
+ String osName = propProvider.getProperty("os.name", "").toLowerCase(Locale.US);
+ if (osName.indexOf("windows") >= 0) {
+ String appData = envProvider.getEnv("APPDATA");
+ if (Strings.isNullOrEmpty(appData)) {
+ throw new CertificateSourceUnavailableException(
+ "APPDATA environment variable is not set on Windows.");
+ }
+ File appDataPath = new File(appData);
+ cloudConfigPath = new File(appDataPath, CLOUDSDK_CONFIG_DIRECTORY);
+ } else {
+ File configPath = new File(propProvider.getProperty("user.home", ""), ".config");
+ cloudConfigPath = new File(configPath, CLOUDSDK_CONFIG_DIRECTORY);
+ }
+ }
+ return new File(cloudConfigPath, WELL_KNOWN_CERTIFICATE_CONFIG_FILE);
+ }
+}
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/mtls/X509Provider.java b/google-auth-library-java/oauth2_http/java/com/google/auth/mtls/X509Provider.java
index 7ff490f0f147..4127b1492460 100644
--- a/google-auth-library-java/oauth2_http/java/com/google/auth/mtls/X509Provider.java
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/mtls/X509Provider.java
@@ -31,15 +31,17 @@
package com.google.auth.mtls;
import com.google.api.client.util.SecurityUtils;
-import com.google.common.base.Strings;
+import com.google.api.core.InternalApi;
+import com.google.auth.oauth2.EnvironmentProvider;
+import com.google.auth.oauth2.PropertyProvider;
+import com.google.auth.oauth2.SystemEnvironmentProvider;
+import com.google.auth.oauth2.SystemPropertyProvider;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.SequenceInputStream;
import java.security.KeyStore;
-import java.util.Locale;
/**
* This class implements {@link MtlsProvider} for the Google Auth library transport layer via {@link
@@ -47,11 +49,10 @@
* libraries, and the public facing methods may be changed without notice, and have no guarantee of
* backwards compatibility.
*/
+@InternalApi
public class X509Provider implements MtlsProvider {
- static final String CERTIFICATE_CONFIGURATION_ENV_VARIABLE = "GOOGLE_API_CERTIFICATE_CONFIG";
- static final String WELL_KNOWN_CERTIFICATE_CONFIG_FILE = "certificate_config.json";
- static final String CLOUDSDK_CONFIG_DIRECTORY = "gcloud";
-
+ private final EnvironmentProvider envProvider;
+ private final PropertyProvider propProvider;
private final String certConfigPathOverride;
/**
@@ -59,12 +60,32 @@ public class X509Provider implements MtlsProvider {
* normal checks for the well known certificate configuration file path and environment variable.
* This is meant for internal Google Cloud usage and behavior may be changed without warning.
*
+ * @param envProvider environment provider used for environment variables
+ * @param propProvider property provider used for system properties
* @param certConfigPathOverride the path to read the certificate configuration from.
*/
- public X509Provider(String certConfigPathOverride) {
+ @InternalApi
+ public X509Provider(
+ EnvironmentProvider envProvider,
+ PropertyProvider propProvider,
+ String certConfigPathOverride) {
+ this.envProvider = envProvider;
+ this.propProvider = propProvider;
this.certConfigPathOverride = certConfigPathOverride;
}
+ /**
+ * Creates an X509 provider with an override path for the certificate configuration.
+ *
+ * @param certConfigPathOverride the path to read the certificate configuration from.
+ */
+ public X509Provider(String certConfigPathOverride) {
+ this(
+ SystemEnvironmentProvider.getInstance(),
+ SystemPropertyProvider.getInstance(),
+ certConfigPathOverride);
+ }
+
/**
* Creates a new X.509 provider that will check the environment variable path and the well known
* Gcloud certificate configuration location. This is meant for internal Google Cloud usage and
@@ -74,29 +95,6 @@ public X509Provider() {
this(null);
}
- /**
- * Returns the path to the client certificate file specified by the loaded workload certificate
- * configuration.
- *
- *
If the configuration has not been loaded yet (e.g., if {@link #getKeyStore()} has not been
- * called), this method will attempt to load it first by searching the override path, environment
- * variable, and well-known locations.
- *
- * @return The path to the certificate file.
- * @throws IOException if the certificate configuration cannot be found or loaded, or if the
- * configuration file does not specify a certificate path.
- * @throws CertificateSourceUnavailableException if the configuration file is not found.
- */
- public String getCertificatePath() throws IOException {
- String certPath = getWorkloadCertificateConfiguration().getCertPath();
- if (Strings.isNullOrEmpty(certPath)) {
- // Ensure the loaded configuration actually contains the required path.
- throw new CertificateSourceUnavailableException(
- "Certificate configuration loaded successfully, but does not contain a 'certificate_file' path.");
- }
- return certPath;
- }
-
/**
* Finds the certificate configuration file, then builds a Keystore using the X.509 certificate
* and private key pointed to by the configuration. This will check the following locations in
@@ -115,12 +113,14 @@ public String getCertificatePath() throws IOException {
*/
@Override
public KeyStore getKeyStore() throws CertificateSourceUnavailableException, IOException {
- WorkloadCertificateConfiguration workloadCertConfig = getWorkloadCertificateConfiguration();
+ WorkloadCertificateConfiguration workloadCertConfig =
+ MtlsUtils.getWorkloadCertificateConfiguration(
+ envProvider, propProvider, certConfigPathOverride);
// Read the certificate and private key file paths into streams.
- try (InputStream certStream = createInputStream(new File(workloadCertConfig.getCertPath()));
+ try (InputStream certStream = new FileInputStream(new File(workloadCertConfig.getCertPath()));
InputStream privateKeyStream =
- createInputStream(new File(workloadCertConfig.getPrivateKeyPath()));
+ new FileInputStream(new File(workloadCertConfig.getPrivateKeyPath()));
SequenceInputStream certAndPrivateKeyStream =
new SequenceInputStream(certStream, privateKeyStream)) {
@@ -149,74 +149,4 @@ public boolean isAvailable() throws IOException {
}
return true;
}
-
- private WorkloadCertificateConfiguration getWorkloadCertificateConfiguration()
- throws IOException {
- File certConfig;
- if (this.certConfigPathOverride != null) {
- certConfig = new File(certConfigPathOverride);
- } else {
- String envCredentialsPath = getEnv(CERTIFICATE_CONFIGURATION_ENV_VARIABLE);
- if (!Strings.isNullOrEmpty(envCredentialsPath)) {
- certConfig = new File(envCredentialsPath);
- } else {
- certConfig = getWellKnownCertificateConfigFile();
- }
- }
- InputStream certConfigStream = null;
- try {
- if (!isFile(certConfig)) {
- // Path will be put in the message from the catch block below
- throw new CertificateSourceUnavailableException("File does not exist.");
- }
- certConfigStream = createInputStream(certConfig);
- return WorkloadCertificateConfiguration.fromCertificateConfigurationStream(certConfigStream);
- } finally {
- if (certConfigStream != null) {
- certConfigStream.close();
- }
- }
- }
-
- /*
- * Start of methods to allow overriding in the test code to isolate from the environment.
- */
- boolean isFile(File file) {
- return file.isFile();
- }
-
- InputStream createInputStream(File file) throws FileNotFoundException {
- return new FileInputStream(file);
- }
-
- String getEnv(String name) {
- return System.getenv(name);
- }
-
- String getOsName() {
- return getProperty("os.name", "").toLowerCase(Locale.US);
- }
-
- String getProperty(String property, String def) {
- return System.getProperty(property, def);
- }
-
- /*
- * End of methods to allow overriding in the test code to isolate from the environment.
- */
-
- private File getWellKnownCertificateConfigFile() {
- File cloudConfigPath;
- String envPath = getEnv("CLOUDSDK_CONFIG");
- if (envPath != null) {
- cloudConfigPath = new File(envPath);
- } else if (getOsName().indexOf("windows") >= 0) {
- File appDataPath = new File(getEnv("APPDATA"));
- cloudConfigPath = new File(appDataPath, CLOUDSDK_CONFIG_DIRECTORY);
- } else {
- File configPath = new File(getProperty("user.home", ""), ".config");
- cloudConfigPath = new File(configPath, CLOUDSDK_CONFIG_DIRECTORY);
- }
- return new File(cloudConfigPath, WELL_KNOWN_CERTIFICATE_CONFIG_FILE);
- }
}
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java
index 3085765317b7..bb943fcdf3b2 100644
--- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/AwsCredentials.java
@@ -196,11 +196,6 @@ String getRegionalCredentialVerificationUrl() {
return this.regionalCredentialVerificationUrl;
}
- @VisibleForTesting
- String getEnv(String name) {
- return System.getenv(name);
- }
-
@VisibleForTesting
AwsSecurityCredentialsSupplier getAwsSecurityCredentialsSupplier() {
return this.awsSecurityCredentialsSupplier;
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/EnvironmentProvider.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/EnvironmentProvider.java
index 5c77ecc65764..26373f4cd729 100644
--- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/EnvironmentProvider.java
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/EnvironmentProvider.java
@@ -1,6 +1,43 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
package com.google.auth.oauth2;
-/** Interface for an environment provider. */
-interface EnvironmentProvider {
+import com.google.api.core.InternalApi;
+
+/**
+ * Interface for an environment provider.
+ *
+ *
For internal use only.
+ */
+@InternalApi
+public interface EnvironmentProvider {
String getEnv(String name);
}
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java
index 7f9f0c20774b..e92c64bed90e 100644
--- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java
@@ -97,6 +97,7 @@ public abstract class ExternalAccountCredentials extends GoogleCredentials {
@Nullable protected ImpersonatedCredentials impersonatedCredentials;
private EnvironmentProvider environmentProvider;
+ private PropertyProvider propertyProvider;
private int connectTimeout;
private int readTimeout;
@@ -205,6 +206,7 @@ protected ExternalAccountCredentials(
: scopes;
this.environmentProvider =
environmentProvider == null ? SystemEnvironmentProvider.getInstance() : environmentProvider;
+ this.propertyProvider = SystemPropertyProvider.getInstance();
this.workforcePoolUserProject = null;
this.serviceAccountImpersonationOptions =
new ServiceAccountImpersonationOptions(new HashMap());
@@ -253,6 +255,10 @@ protected ExternalAccountCredentials(ExternalAccountCredentials.Builder builder)
builder.environmentProvider == null
? SystemEnvironmentProvider.getInstance()
: builder.environmentProvider;
+ this.propertyProvider =
+ builder.propertyProvider == null
+ ? SystemPropertyProvider.getInstance()
+ : builder.propertyProvider;
this.serviceAccountImpersonationOptions =
builder.serviceAccountImpersonationOptions == null
? new ServiceAccountImpersonationOptions(new HashMap())
@@ -657,6 +663,10 @@ EnvironmentProvider getEnvironmentProvider() {
return environmentProvider;
}
+ PropertyProvider getPropertyProvider() {
+ return propertyProvider;
+ }
+
/**
* @return whether the current configuration is for Workforce Pools (which enable 3p user
* identities, rather than workloads)
@@ -772,6 +782,7 @@ public abstract static class Builder extends GoogleCredentials.Builder {
protected String tokenInfoUrl;
protected CredentialSource credentialSource;
protected EnvironmentProvider environmentProvider;
+ protected PropertyProvider propertyProvider;
protected HttpTransportFactory transportFactory;
@Nullable protected String serviceAccountImpersonationUrl;
@@ -806,6 +817,7 @@ protected Builder(ExternalAccountCredentials credentials) {
this.clientSecret = credentials.clientSecret;
this.scopes = credentials.scopes;
this.environmentProvider = credentials.environmentProvider;
+ this.propertyProvider = credentials.propertyProvider;
this.workforcePoolUserProject = credentials.workforcePoolUserProject;
this.serviceAccountImpersonationOptions = credentials.serviceAccountImpersonationOptions;
this.metricsHandler = credentials.metricsHandler;
@@ -1029,6 +1041,18 @@ Builder setEnvironmentProvider(EnvironmentProvider environmentProvider) {
return this;
}
+ /**
+ * Sets the optional Property Provider.
+ *
+ * @param propertyProvider the {@code PropertyProvider} to set
+ * @return this {@code Builder} object
+ */
+ @CanIgnoreReturnValue
+ Builder setPropertyProvider(PropertyProvider propertyProvider) {
+ this.propertyProvider = propertyProvider;
+ return this;
+ }
+
@Override
public abstract ExternalAccountCredentials build();
}
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GdchCredentials.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GdchCredentials.java
index a71a8c39029e..e8b81c71c35d 100644
--- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GdchCredentials.java
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/GdchCredentials.java
@@ -37,18 +37,25 @@
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.HttpResponseException;
import com.google.api.client.http.HttpTransport;
-import com.google.api.client.http.UrlEncodedContent;
import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.client.http.json.JsonHttpContent;
import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonObjectParser;
+import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.json.webtoken.JsonWebSignature;
import com.google.api.client.json.webtoken.JsonWebToken;
+import com.google.api.client.util.Clock;
import com.google.api.client.util.GenericData;
+import com.google.api.client.util.PemReader;
+import com.google.api.client.util.SecurityUtils;
+import com.google.api.client.util.StringUtils;
+import com.google.api.core.ObsoleteApi;
import com.google.auth.http.HttpTransportFactory;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.File;
import java.io.FileInputStream;
@@ -56,10 +63,19 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
+import java.security.AlgorithmParameters;
import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
import java.security.PrivateKey;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPrivateKeySpec;
+import java.util.Base64;
import java.util.Date;
import java.util.Map;
import java.util.Objects;
@@ -67,8 +83,23 @@
public class GdchCredentials extends GoogleCredentials {
private static final LoggerProvider LOGGER_PROVIDER =
LoggerProvider.forClazz(GdchCredentials.class);
- static final String SUPPORTED_FORMAT_VERSION = "1";
private static final String PARSE_ERROR_PREFIX = "Error parsing token refresh response. ";
+
+ /**
+ * The expected format version for GDCH credential profiles. Version "1" indicates the initial and
+ * currently supported JSON format for these credentials. See go/gdch-python-auth-lib for more
+ * info.
+ */
+ @VisibleForTesting static final String SUPPORTED_JSON_FORMAT_VERSION = "1";
+
+ // Custom URN used by GDCH to identify service account tokens in token exchange requests.
+ // See go/gdch-python-auth-lib for more information.
+ private static final String SERVICE_ACCOUNT_TOKEN_TYPE =
+ "urn:k8s:params:oauth:token-type:serviceaccount";
+
+ private static final String PRIVATE_KEY_PEM_TITLE = "PRIVATE KEY";
+ private static final String EC_PRIVATE_KEY_PEM_TITLE = "EC PRIVATE KEY";
+
private static final int DEFAULT_LIFETIME_IN_SECONDS = 3600;
private final PrivateKey privateKey;
@@ -76,7 +107,7 @@ public class GdchCredentials extends GoogleCredentials {
private final String projectId;
private final String serviceIdentityName;
private final URI tokenServerUri;
- private final URI apiAudience;
+ private final String apiAudience;
private final int lifetime;
private final String transportFactoryClassName;
private final String caCertPath;
@@ -181,15 +212,15 @@ static GdchCredentials fromJson(Map json, HttpTransportFactory t
String formatVersion = validateField((String) json.get("format_version"), "format_version");
String projectId = validateField((String) json.get("project"), "project");
String privateKeyId = validateField((String) json.get("private_key_id"), "private_key_id");
- String privateKeyPkcs8 = validateField((String) json.get("private_key"), "private_key");
+ String privateKeyPem = validateField((String) json.get("private_key"), "private_key");
String serviceIdentityName = validateField((String) json.get("name"), "name");
String tokenServerUriStringFromCreds =
validateField((String) json.get("token_uri"), "token_uri");
String caCertPath = (String) json.get("ca_cert_path");
- if (!SUPPORTED_FORMAT_VERSION.equals(formatVersion)) {
+ if (!SUPPORTED_JSON_FORMAT_VERSION.equals(formatVersion)) {
throw new IOException(
- String.format("Only format version %s is supported.", SUPPORTED_FORMAT_VERSION));
+ String.format("Only format version %s is supported.", SUPPORTED_JSON_FORMAT_VERSION));
}
URI tokenServerUriFromCreds = null;
@@ -208,32 +239,71 @@ static GdchCredentials fromJson(Map json, HttpTransportFactory t
.setCaCertPath(caCertPath)
.setHttpTransportFactory(transportFactory);
- return fromPkcs8(privateKeyPkcs8, builder);
+ return fromPem(privateKeyPem, builder);
}
/**
- * Internal constructor.
+ * Reads a private key from a PEM encoded string, supporting both PKCS#8 and SEC1 formats.
*
- * @param privateKeyPkcs8 RSA private key object for the service account in PKCS#8 format.
+ * If the key is labeled with "PRIVATE KEY", it is parsed as PKCS#8 as per RFC 7468 Section 10.
+ * If it is labeled with "EC PRIVATE KEY", it is parsed as SEC1 as per RFC 5915 Section 3.
+ *
+ * @see RFC 7468 Section 10
+ * @see RFC 5915 Section 3
+ * @param privateKeyPem EC private key object for the service account in PEM format (PKCS#8 or
+ * SEC1).
* @param builder A builder for GdchCredentials.
* @return an instance of GdchCredentials.
*/
- static GdchCredentials fromPkcs8(String privateKeyPkcs8, GdchCredentials.Builder builder)
+ static GdchCredentials fromPem(String privateKeyPem, GdchCredentials.Builder builder)
throws IOException {
- PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(privateKeyPkcs8);
+ Reader reader = new StringReader(privateKeyPem);
+ // Read the first section regardless of title
+ PemReader.Section section = PemReader.readFirstSectionAndClose(reader);
+
+ if (section == null) {
+ throw new GoogleAuthException(false, 0, "Invalid key data: no PEM section found.", null);
+ }
+
+ String title = section.getTitle();
+ PrivateKey privateKey;
+
+ if (PRIVATE_KEY_PEM_TITLE.equals(title)) {
+ privateKey = OAuth2Utils.privateKeyFromPkcs8(privateKeyPem, OAuth2Utils.Pkcs8Algorithm.EC);
+ } else if (EC_PRIVATE_KEY_PEM_TITLE.equals(title)) {
+ privateKey = privateKeyFromSec1(section.getBase64DecodedBytes());
+ } else {
+ throw new GoogleAuthException(false, 0, "Unsupported key type: " + title, null);
+ }
+
builder.setPrivateKey(privateKey);
return new GdchCredentials(builder);
}
/**
- * Create a copy of GDCH credentials with the specified audience.
+ * This method is obsolete. Please use {@link #createWithGdchAudience(String)}} instead. Create a
+ * copy of GDCH credentials with the specified audience.
*
* @param apiAudience The intended audience for GDCH credentials.
*/
- public GdchCredentials createWithGdchAudience(URI apiAudience) throws IOException {
+ @ObsoleteApi("Use createWithGdchAudience(String) instead.")
+ public GdchCredentials createWithGdchAudience(URI apiAudience) {
Preconditions.checkNotNull(
apiAudience, "Audience are not configured for GDCH service account credentials.");
+ return this.toBuilder().setGdchAudience(apiAudience.toString()).build();
+ }
+
+ /**
+ * Create a copy of GDCH credentials with the specified audience.
+ *
+ * @param apiAudience The intended audience for GDCH credentials.
+ */
+ public GdchCredentials createWithGdchAudience(String apiAudience) {
+ if (Strings.isNullOrEmpty(apiAudience)) {
+ throw new IllegalArgumentException(
+ "Audience cannot be null or empty for GDCH service account credentials.");
+ }
return this.toBuilder().setGdchAudience(apiAudience).build();
}
@@ -248,17 +318,22 @@ public GdchCredentials createWithGdchAudience(URI apiAudience) throws IOExceptio
public AccessToken refreshAccessToken() throws IOException {
Preconditions.checkNotNull(
this.apiAudience,
- "Audience are not configured for GDCH service account. Specify the "
- + "audience by calling createWithGDCHAudience.");
+ "Audience cannot be null or empty for GDCH service account credentials. "
+ + "Specify the audience by calling createWithGdchAudience.");
- JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY;
- long currentTime = clock.currentTimeMillis();
- String assertion = createAssertion(jsonFactory, currentTime, getApiAudience());
+ JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
+
+ long currentTime = Clock.SYSTEM.currentTimeMillis();
+ String assertion = createAssertion(jsonFactory, currentTime);
GenericData tokenRequest = new GenericData();
+ tokenRequest.set("audience", apiAudience);
tokenRequest.set("grant_type", OAuth2Utils.TOKEN_TYPE_TOKEN_EXCHANGE);
- tokenRequest.set("assertion", assertion);
- UrlEncodedContent content = new UrlEncodedContent(tokenRequest);
+ tokenRequest.set("requested_token_type", OAuth2Utils.TOKEN_TYPE_ACCESS_TOKEN);
+ tokenRequest.set("subject_token", assertion);
+ tokenRequest.set("subject_token_type", SERVICE_ACCOUNT_TOKEN_TYPE);
+
+ JsonHttpContent content = new JsonHttpContent(jsonFactory, tokenRequest);
HttpRequestFactory requestFactory = transportFactory.create().createRequestFactory();
HttpRequest request = requestFactory.buildPostRequest(new GenericUrl(tokenServerUri), content);
@@ -280,8 +355,8 @@ public AccessToken refreshAccessToken() throws IOException {
String message = String.format(errorTemplate, re.getMessage(), getServiceIdentityName());
throw GoogleAuthException.createWithTokenEndpointResponseException(re, message);
} catch (IOException e) {
- throw GoogleAuthException.createWithTokenEndpointIOException(
- e, String.format(errorTemplate, e.getMessage(), getServiceIdentityName()));
+ String message = String.format(errorTemplate, e.getMessage(), getServiceIdentityName());
+ throw GoogleAuthException.createWithTokenEndpointIOException(e, message);
}
GenericData responseData = response.parseAs(GenericData.class);
@@ -302,10 +377,9 @@ public AccessToken refreshAccessToken() throws IOException {
* (tokenServerUri), not for API call. It uses the serviceIdentityName as the `iss` and `sub`
* claim, and the tokenServerUri as the `aud` claim. The JWT is signed with the privateKey.
*/
- String createAssertion(JsonFactory jsonFactory, long currentTime, URI apiAudience)
- throws IOException {
+ String createAssertion(JsonFactory jsonFactory, long currentTime) throws IOException {
JsonWebSignature.Header header = new JsonWebSignature.Header();
- header.setAlgorithm("RS256");
+ header.setAlgorithm("ES256");
header.setType("JWT");
header.setKeyId(privateKeyId);
@@ -314,15 +388,14 @@ String createAssertion(JsonFactory jsonFactory, long currentTime, URI apiAudienc
payload.setSubject(getIssuerSubjectValue(projectId, serviceIdentityName));
payload.setIssuedAtTimeSeconds(currentTime / 1000);
payload.setExpirationTimeSeconds(currentTime / 1000 + this.lifetime);
- payload.setAudience(getTokenServerUri().toString());
+ payload.setAudience(tokenServerUri.toString());
String assertion;
try {
- payload.set("api_audience", apiAudience.toString());
- assertion = JsonWebSignature.signUsingRsaSha256(privateKey, jsonFactory, header, payload);
+ assertion = signUsingEsSha256(privateKey, jsonFactory, header, payload);
} catch (GeneralSecurityException e) {
- throw new IOException(
- "Error signing service account access token request with private key.", e);
+ throw new GoogleAuthException(
+ false, 0, "Error signing service account access token request with private key.", e);
}
return assertion;
@@ -363,10 +436,35 @@ public final URI getTokenServerUri() {
return tokenServerUri;
}
- public final URI getApiAudience() {
+ /**
+ * Returns the underlying audience string set for this credentials object.
+ *
+ * @return the audience string, or null if no audience has been set.
+ */
+ public final String getGdchAudience() {
return apiAudience;
}
+ /**
+ * NOTE: This method is obsolete, please use {@link #getGdchAudience()} instead. Returns a URI
+ * representation of the underlying audience string set for this credentials object. This method
+ * may fail if the underlying audience string does not conform to a URI format.
+ *
+ * @return a URI object representing the audience of the credentials, or null if no audience has
+ * been set or if the audience string is not a valid URI.
+ */
+ @ObsoleteApi("Use getGdchAudience() instead.")
+ public final URI getApiAudience() {
+ if (Strings.isNullOrEmpty(apiAudience)) {
+ return null;
+ }
+ try {
+ return new URI(apiAudience);
+ } catch (URISyntaxException e) {
+ return null;
+ }
+ }
+
public final HttpTransportFactory getTransportFactory() {
return transportFactory;
}
@@ -446,7 +544,7 @@ public static class Builder extends GoogleCredentials.Builder {
private PrivateKey privateKey;
private String serviceIdentityName;
private URI tokenServerUri;
- private URI apiAudience;
+ private String apiAudience;
private HttpTransportFactory transportFactory;
private String caCertPath;
private int lifetime = DEFAULT_LIFETIME_IN_SECONDS;
@@ -506,8 +604,19 @@ public Builder setCaCertPath(String caCertPath) {
return this;
}
+ /**
+ * Sets the intended audience for GDCH credentials.
+ *
+ * @param apiAudience The audience string. Cannot be null or empty.
+ * @return this builder.
+ * @throws IllegalArgumentException if the audience is null or empty.
+ */
@CanIgnoreReturnValue
- public Builder setGdchAudience(URI apiAudience) {
+ public Builder setGdchAudience(String apiAudience) {
+ if (Strings.isNullOrEmpty(apiAudience)) {
+ throw new IllegalArgumentException(
+ "Audience cannot be null or empty for GDCH service account credentials.");
+ }
this.apiAudience = apiAudience;
return this;
}
@@ -563,13 +672,16 @@ private static String validateField(String field, String fieldName) throws IOExc
/*
* Internal HttpTransportFactory for GDCH credentials.
*
- *
GDCH authentication server could use a self-signed certificate, thus the client could
+ *
GDCH authentication server could use a self-signed certificate, thus the
+ * client could
* provide the CA certificate path through the `ca_cert_path` in GDCH JSON file.
*
- *
The TransportFactoryForGdch subclass would read the certificate and create a trust store,
+ *
The TransportFactoryForGdch subclass would read the certificate and
+ * create a trust store,
* then use the trust store to create a transport.
*
- *
If the GDCH authentication server uses well known CA certificate, then a regular transport
+ *
If the GDCH authentication server uses well known CA certificate, then a
+ * regular transport
* would be set.
*/
static class TransportFactoryForGdch implements HttpTransportFactory {
@@ -604,4 +716,231 @@ private void setTransport(String caCertPath) throws IOException {
}
}
}
+
+ /**
+ * Signs the JWS header and payload using the ES256 algorithm (ECDSA with SHA-256).
+ *
+ *
The ES256 algorithm is defined in RFC 7518 Section 3.4. This method
+ * follows the JWS Compact Serialization format described in RFC 7515 Section 3.1.
+ *
+ *
Unlike RSA signatures, ECDSA signatures produced by the Java Cryptography Architecture (JCA)
+ * are DER-encoded. This method transcodes the DER-encoded signature into the concatenated R|S
+ * format required by the JWS standard, as specified in RFC 7515 Appendix A.3.
+ *
+ * @param privateKey The Elliptic Curve private key used for signing.
+ * @param jsonFactory The JSON factory to serialize header and payload.
+ * @param header The JWS header (e.g., containing "alg": "ES256").
+ * @param payload The JWS payload containing claims like "iss", "sub", and "aud".
+ * @return A complete, signed JWS string in the format {@code [header].[payload].[signature]}.
+ * @throws GeneralSecurityException If signing fails due to cryptographic errors.
+ * @throws IOException If serialization or transcoding fails.
+ */
+ @VisibleForTesting
+ static String signUsingEsSha256(
+ PrivateKey privateKey,
+ JsonFactory jsonFactory,
+ JsonWebSignature.Header header,
+ JsonWebToken.Payload payload)
+ throws GeneralSecurityException, GoogleAuthException {
+
+ try {
+ // 1. Construct the JWS Signing Input: Base64URL(UTF8(Header)) + '.' +
+ // Base64URL(UTF8(Payload))
+ String content =
+ Base64.getUrlEncoder().withoutPadding().encodeToString(jsonFactory.toByteArray(header))
+ + "."
+ + Base64.getUrlEncoder()
+ .withoutPadding()
+ .encodeToString(jsonFactory.toByteArray(payload));
+ byte[] contentBytes = StringUtils.getBytesUtf8(content);
+
+ // 2. Create the digital signature using SHA256withECDSA.
+ byte[] signature =
+ SecurityUtils.sign(SecurityUtils.getEs256SignatureAlgorithm(), privateKey, contentBytes);
+
+ // 3. Transcode the signature from DER to Concatenated R|S.
+ byte[] jwsSignature = transcodeDerToConcat(signature, 64);
+
+ // 4. Return final JWS: [Signing Input] + '.' + Base64URL(Signature)
+ return content + "." + Base64.getUrlEncoder().withoutPadding().encodeToString(jwsSignature);
+ } catch (IOException e) {
+ throw new GoogleAuthException(false, 0, "Error serializing or transcoding JWT.", e);
+ }
+ }
+
+ /**
+ * Transcodes a DER-encoded ECDSA signature into the concatenated R|S format.
+ *
+ *
DER format (ASN.1): {@code SEQUENCE { r INTEGER, s INTEGER }}
+ *
+ *
Concatenated format: {@code r | s} (where {@code |} is concatenation).
+ *
+ * @param derSignature The raw bytes of the DER-encoded signature.
+ * @param outputLength The total expected length of the concatenated signature (64 bytes for
+ * ES256).
+ * @return The signature in concatenated R|S format.
+ * @throws IOException If the DER format is invalid.
+ */
+ @VisibleForTesting
+ static byte[] transcodeDerToConcat(byte[] derSignature, int outputLength)
+ throws GoogleAuthException {
+ // Validate basic ASN.1 DER structure (0x30 = SEQUENCE)
+ if (derSignature.length < 8 || derSignature[0] != 0x30) {
+ throw new GoogleAuthException(false, 0, "Invalid DER signature format.", null);
+ }
+
+ int offset = 2;
+ int seqLength = derSignature[1] & 0xFF;
+ // Handle long-form length encoding for the sequence
+ if (seqLength == 0x81) {
+ offset = 3;
+ seqLength = derSignature[2] & 0xFF;
+ }
+
+ if (derSignature.length - offset != seqLength) {
+ throw new GoogleAuthException(false, 0, "Invalid DER signature length.", null);
+ }
+
+ // Parse Integer R (0x02 = INTEGER)
+ if (derSignature[offset++] != 0x02) {
+ throw new GoogleAuthException(false, 0, "Expected INTEGER for R.", null);
+ }
+ int rLength = derSignature[offset++];
+ // Skip leading zero byte if it exists (DER integers are signed; zero is added to stay positive)
+ if (derSignature[offset] == 0x00 && rLength > 1 && (derSignature[offset + 1] & 0x80) != 0) {
+ offset++;
+ rLength--;
+ }
+ byte[] r = new byte[rLength];
+ System.arraycopy(derSignature, offset, r, 0, rLength);
+ offset += rLength;
+
+ // Parse Integer S
+ if (derSignature[offset++] != 0x02) {
+ throw new GoogleAuthException(false, 0, "Expected INTEGER for S.", null);
+ }
+ int sLength = derSignature[offset++];
+ if (derSignature[offset] == 0x00 && sLength > 1 && (derSignature[offset + 1] & 0x80) != 0) {
+ offset++;
+ sLength--;
+ }
+ byte[] s = new byte[sLength];
+ System.arraycopy(derSignature, offset, s, 0, sLength);
+
+ // Concatenate r and s into fixed-length segments (32 bytes each for ES256)
+ int keySizeBytes = outputLength / 2;
+ if (r.length > keySizeBytes || s.length > keySizeBytes) {
+ throw new GoogleAuthException(
+ false,
+ 0,
+ String.format(
+ "Invalid R or S length. R: %d, S: %d, Expected: %d",
+ r.length, s.length, keySizeBytes),
+ null);
+ }
+
+ byte[] result = new byte[outputLength];
+ System.arraycopy(r, 0, result, keySizeBytes - r.length, r.length);
+ System.arraycopy(s, 0, result, outputLength - s.length, s.length);
+
+ return result;
+ }
+
+ /**
+ * Parses an EC private key in SEC1 format using fixed prefix verification.
+ *
+ *
This function assumes that standard SEC1 keys for P-256 generated by OpenSSL have a known,
+ * stable structure of bytes at the beginning. This "fingerprint" allows us to verify the format
+ * without complete ASN.1 parsing. If the fingerprint matches, we can safely extract the private
+ * key value using fixed offsets.
+ *
+ * @param bytes The raw bytes of the SEC1 key.
+ * @return The PrivateKey object.
+ * @throws GoogleAuthException If parsing fails or the key format is unsupported.
+ */
+ private static PrivateKey privateKeyFromSec1(byte[] bytes) throws IOException {
+ if (!hasStandardSec1P256Prefix(bytes)) {
+ throw new GoogleAuthException(
+ false, 0, "Unsupported SEC1 key format: standard prefix not found.", null);
+ }
+ BigInteger s = extractPrivateKeyValue(bytes);
+ return createEcPrivateKey(s);
+ }
+
+ /**
+ * Verifies if the bytes start with the standard SEC1 P-256 prefix.
+ *
+ *
The prefix is derived from the standard DER encoding of the ECPrivateKey structure defined
+ * in RFC 5915 Section 3. For P-256 with named curve parameters and public key included, the
+ * prefix is stable: [0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20]
+ *
+ * @see RFC 5915 Section 3
+ * @param bytes The raw bytes of the key.
+ * @return true if the prefix matches.
+ */
+ private static boolean hasStandardSec1P256Prefix(byte[] bytes) {
+ if (bytes.length < 7) return false;
+ return bytes[0] == 0x30 // Sequence
+ && bytes[1] == 0x77 // Length
+ && bytes[2] == 0x02 // Integer
+ && bytes[3] == 0x01 // Length
+ && bytes[4] == 0x01 // Version
+ && bytes[5] == 0x04 // Octet String
+ && bytes[6] == 0x20; // Length 32
+ }
+
+ /**
+ * Extracts the private key value 's' from the SEC1 bytes using fixed offset.
+ *
+ *
Assumes the prefix has already been verified by {@link #hasStandardSec1P256Prefix(byte[])}.
+ *
+ * @param bytes The raw bytes of the key.
+ * @return The BigInteger value of 's'.
+ */
+ private static BigInteger extractPrivateKeyValue(byte[] bytes) {
+ // P-256 private key size is 32 bytes as per RFC 5915 Section 3.
+ byte[] sBytes = new byte[32];
+ // Copy 32 bytes starting at offset 7 (after the 7-byte metadata prefix verified by
+ // hasStandardSec1P256Prefix).
+ System.arraycopy(bytes, 7, sBytes, 0, 32);
+ // Use signum 1 to ensure the byte array is interpreted as a positive integer.
+ return new BigInteger(1, sBytes);
+ }
+
+ /**
+ * Creates an EC PrivateKey from the private key value 's' using P-256 parameters.
+ *
+ *
Algorithm steps: 1. Get an instance of AlgorithmParameters for "EC". 2. Initialize it with
+ * secp256r1 curve spec (requirement as per GDCH supported curve). 3. Extract ECParameterSpec from
+ * parameters. 4. Create ECPrivateKeySpec with the extracted private key value and parameters. 5.
+ * Generate PrivateKey using KeyFactory.
+ *
+ * @param s The private key value.
+ * @return The PrivateKey object.
+ * @throws GoogleAuthException If key creation fails.
+ */
+ private static PrivateKey createEcPrivateKey(BigInteger s) throws IOException {
+ try {
+ AlgorithmParameters params = AlgorithmParameters.getInstance("EC");
+
+ params.init(new ECGenParameterSpec("secp256r1"));
+
+ ECParameterSpec ecParams = params.getParameterSpec(ECParameterSpec.class);
+
+ ECPrivateKeySpec keySpec = new ECPrivateKeySpec(s, ecParams);
+
+ KeyFactory keyFactory = KeyFactory.getInstance("EC");
+
+ return keyFactory.generatePrivate(keySpec);
+ } catch (GeneralSecurityException e) {
+ throw new GoogleAuthException(
+ false,
+ 0,
+ "Failed to create EC Private Key for GDCH. Please ensure the private key data is valid and represents a P-256 private key.",
+ e);
+ }
+ }
}
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java
index ee5df1466c36..0ff9da853e2d 100644
--- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/IdentityPoolCredentials.java
@@ -33,6 +33,7 @@
import com.google.auth.http.HttpTransportFactory;
import com.google.auth.mtls.MtlsHttpTransportFactory;
+import com.google.auth.mtls.MtlsUtils;
import com.google.auth.mtls.X509Provider;
import com.google.auth.oauth2.IdentityPoolCredentialSource.IdentityPoolCredentialSourceType;
import com.google.common.annotations.VisibleForTesting;
@@ -166,28 +167,37 @@ private IdentityPoolSubjectTokenSupplier createCertificateSubjectTokenSupplier(
this.transportFactory = new MtlsHttpTransportFactory(mtlsKeyStore);
// Initialize the subject token supplier with the certificate path.
- credentialSource.setCredentialLocation(x509Provider.getCertificatePath());
+ String explicitCertConfigPath = getExplicitCertConfigPath(credentialSource);
+ credentialSource.setCredentialLocation(
+ MtlsUtils.getCertificatePath(
+ getEnvironmentProvider(), getPropertyProvider(), explicitCertConfigPath));
return new CertificateIdentityPoolSubjectTokenSupplier(credentialSource);
}
private X509Provider getX509Provider(
Builder builder, IdentityPoolCredentialSource credentialSource) {
- final IdentityPoolCredentialSource.CertificateConfig certConfig =
- credentialSource.getCertificateConfig();
-
// Use the provided X509Provider if available, otherwise initialize a default one.
X509Provider x509Provider = builder.x509Provider;
if (x509Provider == null) {
// Determine the certificate path based on the configuration.
- String explicitCertConfigPath =
- certConfig.useDefaultCertificateConfig()
- ? null
- : certConfig.getCertificateConfigLocation();
- x509Provider = new X509Provider(explicitCertConfigPath);
+ String explicitCertConfigPath = getExplicitCertConfigPath(credentialSource);
+ x509Provider =
+ new X509Provider(getEnvironmentProvider(), getPropertyProvider(), explicitCertConfigPath);
}
return x509Provider;
}
+ private static String getExplicitCertConfigPath(IdentityPoolCredentialSource credentialSource) {
+ IdentityPoolCredentialSource.CertificateConfig certConfig =
+ credentialSource.getCertificateConfig();
+ if (certConfig == null) {
+ return null;
+ }
+ return certConfig.useDefaultCertificateConfig()
+ ? null
+ : certConfig.getCertificateConfigLocation();
+ }
+
public static class Builder extends ExternalAccountCredentials.Builder {
private IdentityPoolSubjectTokenSupplier subjectTokenSupplier;
@@ -212,6 +222,7 @@ public static class Builder extends ExternalAccountCredentials.Builder {
* @return this {@code Builder} object
*/
@CanIgnoreReturnValue
+ @VisibleForTesting
Builder setX509Provider(X509Provider x509Provider) {
this.x509Provider = x509Provider;
return this;
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
index b4a933963fe8..e17714c3eee8 100644
--- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Credentials.java
@@ -86,7 +86,7 @@ public class OAuth2Credentials extends Credentials {
// Change listeners are not serialized
private transient List changeListeners;
// Until we expose this to the users it can remain transient and non-serializable
- @VisibleForTesting transient Clock clock = Clock.SYSTEM;
+ transient Clock clock = Clock.SYSTEM;
/**
* Returns the credentials instance from the given access token.
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java
index 7efec082fe16..643c3dc7dc65 100644
--- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/OAuth2Utils.java
@@ -40,7 +40,6 @@
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.PemReader;
import com.google.api.client.util.PemReader.Section;
-import com.google.api.client.util.SecurityUtils;
import com.google.api.core.InternalApi;
import com.google.auth.http.AuthHttpConstants;
import com.google.auth.http.HttpTransportFactory;
@@ -82,6 +81,11 @@
@InternalApi
public class OAuth2Utils {
+ enum Pkcs8Algorithm {
+ RSA,
+ EC
+ }
+
static final String SIGNATURE_ALGORITHM = "SHA256withRSA";
public static final String TOKEN_TYPE_ACCESS_TOKEN =
@@ -269,6 +273,24 @@ static Map validateMap(Map map, String key, Stri
* key creation.
*/
public static PrivateKey privateKeyFromPkcs8(String privateKeyPkcs8) throws IOException {
+ return privateKeyFromPkcs8(privateKeyPkcs8, Pkcs8Algorithm.RSA);
+ }
+
+ /**
+ * Reads a private key from a PKCS#8 encoded string.
+ *
+ * If the key is labeled with "-----BEGIN PRIVATE KEY-----", it is parsed as PKCS#8 as per RFC
+ * 7468 Section 10.
+ *
+ * @see RFC 7468 Section 10
+ * @param privateKeyPkcs8 base64 encoded private key string
+ * @param algorithm expected algorithm of the private key
+ * @return the private key.
+ * @throws IOException if the private key data is invalid or if an unexpected exception occurs
+ * during key creation.
+ */
+ public static PrivateKey privateKeyFromPkcs8(String privateKeyPkcs8, Pkcs8Algorithm algorithm)
+ throws IOException {
Reader reader = new StringReader(privateKeyPkcs8);
Section section = PemReader.readFirstSectionAndClose(reader, "PRIVATE KEY");
if (section == null) {
@@ -278,7 +300,7 @@ public static PrivateKey privateKeyFromPkcs8(String privateKeyPkcs8) throws IOEx
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
Exception unexpectedException;
try {
- KeyFactory keyFactory = SecurityUtils.getRsaKeyFactory();
+ KeyFactory keyFactory = KeyFactory.getInstance(algorithm.toString());
return keyFactory.generatePrivate(keySpec);
} catch (NoSuchAlgorithmException | InvalidKeySpecException exception) {
unexpectedException = exception;
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/PropertyProvider.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/PropertyProvider.java
new file mode 100644
index 000000000000..93343c84ebab
--- /dev/null
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/PropertyProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.google.auth.oauth2;
+
+import com.google.api.core.InternalApi;
+
+/**
+ * Interface for a system property provider.
+ *
+ *
For internal use only.
+ */
+@InternalApi
+public interface PropertyProvider {
+ String getProperty(String property, String def);
+}
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/SystemEnvironmentProvider.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/SystemEnvironmentProvider.java
index a2970772135a..a58285831598 100644
--- a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/SystemEnvironmentProvider.java
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/SystemEnvironmentProvider.java
@@ -1,9 +1,45 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
package com.google.auth.oauth2;
+import com.google.api.core.InternalApi;
import java.io.Serializable;
-/** Represents the default system environment provider. */
-class SystemEnvironmentProvider implements EnvironmentProvider, Serializable {
+/**
+ * Represents the default system environment provider.
+ *
+ *
For internal use only.
+ */
+@InternalApi
+public class SystemEnvironmentProvider implements EnvironmentProvider, Serializable {
static final SystemEnvironmentProvider INSTANCE = new SystemEnvironmentProvider();
private static final long serialVersionUID = -4698164985883575244L;
diff --git a/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/SystemPropertyProvider.java b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/SystemPropertyProvider.java
new file mode 100644
index 000000000000..6c2042329be8
--- /dev/null
+++ b/google-auth-library-java/oauth2_http/java/com/google/auth/oauth2/SystemPropertyProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.google.auth.oauth2;
+
+import com.google.api.core.InternalApi;
+import java.io.Serializable;
+
+/**
+ * Represents the default system property provider.
+ *
+ *
For internal use only.
+ */
+@InternalApi
+public class SystemPropertyProvider implements PropertyProvider, Serializable {
+ public static final SystemPropertyProvider INSTANCE = new SystemPropertyProvider();
+ private static final long serialVersionUID = 1L;
+
+ private SystemPropertyProvider() {}
+
+ @Override
+ public String getProperty(String property, String def) {
+ return System.getProperty(property, def);
+ }
+
+ public static SystemPropertyProvider getInstance() {
+ return INSTANCE;
+ }
+}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/TestUtils.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/TestUtils.java
index d794ba18486d..91b648992848 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/TestUtils.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/TestUtils.java
@@ -46,9 +46,9 @@
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
-import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URLDecoder;
+import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
@@ -90,17 +90,20 @@ private static boolean hasBearerToken(Map> metadata, String
public static InputStream jsonToInputStream(GenericJson json) throws IOException {
json.setFactory(JSON_FACTORY);
String text = json.toPrettyString();
- return new ByteArrayInputStream(text.getBytes("UTF-8"));
+ return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
}
public static InputStream stringToInputStream(String text) {
- try {
- return new ByteArrayInputStream(text.getBytes("UTF-8"));
- } catch (UnsupportedEncodingException e) {
- throw new RuntimeException("Unexpected encoding exception", e);
- }
+ return new ByteArrayInputStream(text.getBytes(StandardCharsets.UTF_8));
}
+ /**
+ * Parses a URI query string into a map of key-value pairs.
+ *
+ * @param query The URI query string (e.g., "key1=val1&key2=val2").
+ * @return A map of decoded keys to decoded values.
+ * @throws IOException If the query string is malformed.
+ */
public static Map parseQuery(String query) throws IOException {
Map map = new HashMap<>();
Iterable entries = Splitter.on('&').split(query);
@@ -116,6 +119,23 @@ public static Map parseQuery(String query) throws IOException {
return map;
}
+ /**
+ * Parses a JSON string into a map of key-value pairs.
+ *
+ * @param content The JSON string representation of a flat object.
+ * @return A map of keys to string representations of their values.
+ * @throws IOException If the JSON is malformed.
+ */
+ public static Map parseJson(String content) throws IOException {
+ GenericJson json = JSON_FACTORY.fromString(content, GenericJson.class);
+ Map map = new HashMap<>();
+ for (Map.Entry entry : json.entrySet()) {
+ Object value = entry.getValue();
+ map.put(entry.getKey(), value == null ? null : value.toString());
+ }
+ return map;
+ }
+
public static String errorJson(String message) throws IOException {
GenericJson errorResponse = new GenericJson();
errorResponse.setFactory(JSON_FACTORY);
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/http/HttpCredentialsAdapterTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/http/HttpCredentialsAdapterTest.java
index 10d2141fd7b3..666be521e9ed 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/http/HttpCredentialsAdapterTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/http/HttpCredentialsAdapterTest.java
@@ -79,7 +79,7 @@ void initialize_populatesOAuth2Credentials() throws IOException {
HttpHeaders requestHeaders = request.getHeaders();
String authorizationHeader = requestHeaders.getAuthorization();
- assertEquals(authorizationHeader, expectedAuthorization);
+ assertEquals(expectedAuthorization, authorizationHeader);
}
@Test
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/MtlsUtilsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/MtlsUtilsTest.java
new file mode 100644
index 000000000000..f3fdf05a4c32
--- /dev/null
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/MtlsUtilsTest.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2026, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.google.auth.mtls;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.google.auth.oauth2.EnvironmentProvider;
+import com.google.auth.oauth2.PropertyProvider;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.io.TempDir;
+
+class MtlsUtilsTest {
+
+ @TempDir Path tempDir;
+
+ @Test
+ void getCertificatePath_succeeds() throws IOException {
+ Path configFile = tempDir.resolve("config.json");
+ Files.write(
+ configFile,
+ "{\"cert_configs\":{\"workload\":{\"cert_path\":\"cert.pem\",\"key_path\":\"key.pem\"}}}"
+ .getBytes());
+
+ EnvironmentProvider envProvider =
+ new EnvironmentProvider() {
+ @Override
+ public String getEnv(String name) {
+ return null;
+ }
+ };
+ PropertyProvider propProvider =
+ new PropertyProvider() {
+ @Override
+ public String getProperty(String name, String def) {
+ return def;
+ }
+ };
+
+ String certPath =
+ MtlsUtils.getCertificatePath(envProvider, propProvider, configFile.toString());
+
+ assertEquals("cert.pem", certPath);
+ }
+
+ @Test
+ void getCertificatePath_missingCertPath_throws() throws IOException {
+ Path configFile = tempDir.resolve("config.json");
+ Files.write(
+ configFile, "{\"cert_configs\":{\"workload\":{\"key_path\":\"key.pem\"}}}".getBytes());
+
+ EnvironmentProvider envProvider =
+ new EnvironmentProvider() {
+ @Override
+ public String getEnv(String name) {
+ return null;
+ }
+ };
+ PropertyProvider propProvider =
+ new PropertyProvider() {
+ @Override
+ public String getProperty(String name, String def) {
+ return def;
+ }
+ };
+
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> MtlsUtils.getCertificatePath(envProvider, propProvider, configFile.toString()));
+ }
+
+ @Test
+ void getWorkloadCertificateConfiguration_overridePath() throws IOException {
+ Path configFile = tempDir.resolve("custom_config.json");
+ Files.write(
+ configFile,
+ "{\"cert_configs\":{\"workload\":{\"cert_path\":\"cert.pem\",\"key_path\":\"key.pem\"}}}"
+ .getBytes());
+
+ EnvironmentProvider envProvider =
+ new EnvironmentProvider() {
+ @Override
+ public String getEnv(String name) {
+ return null;
+ }
+ };
+ PropertyProvider propProvider =
+ new PropertyProvider() {
+ @Override
+ public String getProperty(String name, String def) {
+ return def;
+ }
+ };
+
+ WorkloadCertificateConfiguration config =
+ MtlsUtils.getWorkloadCertificateConfiguration(
+ envProvider, propProvider, configFile.toString());
+
+ assertNotNull(config);
+ assertEquals("cert.pem", config.getCertPath());
+ assertEquals("key.pem", config.getPrivateKeyPath());
+ }
+
+ @Test
+ void getWorkloadCertificateConfiguration_envVar() throws IOException {
+ Path configFile = tempDir.resolve("env_config.json");
+ Files.write(
+ configFile,
+ "{\"cert_configs\":{\"workload\":{\"cert_path\":\"cert.pem\",\"key_path\":\"key.pem\"}}}"
+ .getBytes());
+
+ EnvironmentProvider envProvider =
+ new EnvironmentProvider() {
+ @Override
+ public String getEnv(String name) {
+ return "GOOGLE_API_CERTIFICATE_CONFIG".equals(name) ? configFile.toString() : null;
+ }
+ };
+ PropertyProvider propProvider =
+ new PropertyProvider() {
+ @Override
+ public String getProperty(String name, String def) {
+ return def;
+ }
+ };
+
+ WorkloadCertificateConfiguration config =
+ MtlsUtils.getWorkloadCertificateConfiguration(envProvider, propProvider, null);
+
+ assertNotNull(config);
+ assertEquals("cert.pem", config.getCertPath());
+ }
+
+ @Test
+ void getWellKnownCertificateConfigFile_windows() throws IOException {
+ EnvironmentProvider envProvider =
+ new EnvironmentProvider() {
+ @Override
+ public String getEnv(String name) {
+ return "APPDATA".equals(name) ? tempDir.toString() : null;
+ }
+ };
+ PropertyProvider propProvider =
+ new PropertyProvider() {
+ @Override
+ public String getProperty(String name, String def) {
+ return "os.name".equals(name) ? "Windows 10" : def;
+ }
+ };
+
+ CertificateSourceUnavailableException exception =
+ assertThrows(
+ CertificateSourceUnavailableException.class,
+ () -> MtlsUtils.getWorkloadCertificateConfiguration(envProvider, propProvider, null));
+
+ String expectedPath =
+ new File(tempDir.toFile(), "gcloud/certificate_config.json").getAbsolutePath();
+ assertTrue(exception.getMessage().contains(expectedPath));
+ }
+
+ @Test
+ void getWellKnownCertificateConfigFile_linux() throws IOException {
+ EnvironmentProvider envProvider =
+ new EnvironmentProvider() {
+ @Override
+ public String getEnv(String name) {
+ return null;
+ }
+ };
+ PropertyProvider propProvider =
+ new PropertyProvider() {
+ @Override
+ public String getProperty(String name, String def) {
+ if ("os.name".equals(name)) return "Linux";
+ if ("user.home".equals(name)) return tempDir.toString();
+ return def;
+ }
+ };
+
+ CertificateSourceUnavailableException exception =
+ assertThrows(
+ CertificateSourceUnavailableException.class,
+ () -> MtlsUtils.getWorkloadCertificateConfiguration(envProvider, propProvider, null));
+
+ String expectedPath =
+ new File(tempDir.toFile(), ".config/gcloud/certificate_config.json").getAbsolutePath();
+ assertTrue(exception.getMessage().contains(expectedPath));
+ }
+
+ @Test
+ void getWellKnownCertificateConfigFile_windows_missingAppData_throws() {
+ EnvironmentProvider envProvider =
+ new EnvironmentProvider() {
+ @Override
+ public String getEnv(String name) {
+ return null;
+ }
+ };
+ PropertyProvider propProvider =
+ new PropertyProvider() {
+ @Override
+ public String getProperty(String name, String def) {
+ return "os.name".equals(name) ? "Windows 10" : def;
+ }
+ };
+
+ CertificateSourceUnavailableException exception =
+ assertThrows(
+ CertificateSourceUnavailableException.class,
+ () -> MtlsUtils.getWorkloadCertificateConfiguration(envProvider, propProvider, null));
+
+ assertEquals("APPDATA environment variable is not set on Windows.", exception.getMessage());
+ }
+}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/SecureConnectProviderTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/SecureConnectProviderTest.java
index 7e962014ae25..fab805fa9520 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/SecureConnectProviderTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/SecureConnectProviderTest.java
@@ -38,7 +38,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.security.GeneralSecurityException;
import java.util.List;
import org.junit.jupiter.api.Test;
@@ -70,7 +69,7 @@ public InputStream getErrorStream() {
}
@Override
- public int waitFor() throws InterruptedException {
+ public int waitFor() {
return 0;
}
@@ -83,7 +82,9 @@ public int exitValue() {
}
@Override
- public void destroy() {}
+ public void destroy() {
+ // Nothing was initialized and nothing needs to be destroyed
+ }
}
static class TestProcessProvider implements SecureConnectProvider.ProcessProvider {
@@ -102,19 +103,22 @@ public Process createProcess(InputStream metadata) throws IOException {
@Test
void testGetKeyStoreNonZeroExitCode() {
- InputStream metadata =
+ try (InputStream metadata =
this.getClass()
.getClassLoader()
- .getResourceAsStream("com/google/api/gax/rpc/mtls/mtlsCertAndKey.pem");
- IOException actual =
- assertThrows(
- IOException.class,
- () -> SecureConnectProvider.getKeyStore(metadata, new TestProcessProvider(1)));
- assertTrue(
- actual
- .getMessage()
- .contains("SecureConnect: Cert provider command failed with exit code: 1"),
- "expected to fail with nonzero exit code");
+ .getResourceAsStream("com/google/api/gax/rpc/mtls/mtlsCertAndKey.pem")) {
+ IOException actual =
+ assertThrows(
+ IOException.class,
+ () -> SecureConnectProvider.getKeyStore(metadata, new TestProcessProvider(1)));
+ assertTrue(
+ actual
+ .getMessage()
+ .contains("SecureConnect: Cert provider command failed with exit code: 1"),
+ "expected to fail with nonzero exit code");
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
}
@Test
@@ -147,8 +151,7 @@ void testRunCertificateProviderCommandTimeout() {
}
@Test
- void testGetKeyStore_FileNotFoundException()
- throws IOException, GeneralSecurityException, InterruptedException {
+ void testGetKeyStore_FileNotFoundException() {
SecureConnectProvider provider =
new SecureConnectProvider(new TestProcessProvider(0), "/invalid/metadata/path.json");
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/WorkloadCertificateConfigurationTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/WorkloadCertificateConfigurationTest.java
index bd17436c16ee..8d74f7978ce9 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/WorkloadCertificateConfigurationTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/WorkloadCertificateConfigurationTest.java
@@ -58,71 +58,77 @@ void workloadCertificateConfig_fromStream_Succeeds() throws IOException {
void workloadCertificateConfig_fromStreamMissingCertPath_Fails() throws IOException {
String certPath = "";
String privateKeyPath = "key.crt";
- InputStream configStream = writeWorkloadCertificateConfigStream(certPath, privateKeyPath);
-
- IllegalArgumentException exception =
- assertThrows(
- IllegalArgumentException.class,
- () ->
- WorkloadCertificateConfiguration.fromCertificateConfigurationStream(configStream));
- assertTrue(
- exception
- .getMessage()
- .contains(
- "The cert_path field must be provided in the workload certificate configuration."));
+ try (InputStream configStream =
+ writeWorkloadCertificateConfigStream(certPath, privateKeyPath)) {
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ WorkloadCertificateConfiguration.fromCertificateConfigurationStream(
+ configStream));
+ assertTrue(
+ exception
+ .getMessage()
+ .contains(
+ "The cert_path field must be provided in the workload certificate configuration."));
+ }
}
@Test
void workloadCertificateConfig_fromStreamMissingPrivateKeyPath_Fails() throws IOException {
String certPath = "cert.crt";
String privateKeyPath = "";
- InputStream configStream = writeWorkloadCertificateConfigStream(certPath, privateKeyPath);
-
- IllegalArgumentException exception =
- assertThrows(
- IllegalArgumentException.class,
- () ->
- WorkloadCertificateConfiguration.fromCertificateConfigurationStream(configStream));
- assertTrue(
- exception
- .getMessage()
- .contains(
- "The key_path field must be provided in the workload certificate configuration."));
+ try (InputStream configStream =
+ writeWorkloadCertificateConfigStream(certPath, privateKeyPath)) {
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ WorkloadCertificateConfiguration.fromCertificateConfigurationStream(
+ configStream));
+ assertTrue(
+ exception
+ .getMessage()
+ .contains(
+ "The key_path field must be provided in the workload certificate configuration."));
+ }
}
@Test
void workloadCertificateConfig_fromStreamMissingWorkload_Fails() throws IOException {
GenericJson json = new GenericJson();
json.put("cert_configs", new GenericJson());
- InputStream configStream = TestUtils.jsonToInputStream(json);
-
- CertificateSourceUnavailableException exception =
- assertThrows(
- CertificateSourceUnavailableException.class,
- () ->
- WorkloadCertificateConfiguration.fromCertificateConfigurationStream(configStream));
- assertTrue(
- exception
- .getMessage()
- .contains(
- "A workload certificate configuration must be provided in the cert_configs object."));
+ try (InputStream configStream = TestUtils.jsonToInputStream(json)) {
+ CertificateSourceUnavailableException exception =
+ assertThrows(
+ CertificateSourceUnavailableException.class,
+ () ->
+ WorkloadCertificateConfiguration.fromCertificateConfigurationStream(
+ configStream));
+ assertTrue(
+ exception
+ .getMessage()
+ .contains(
+ "A workload certificate configuration must be provided in the cert_configs object."));
+ }
}
@Test
void workloadCertificateConfig_fromStreamMissingCertConfig_Fails() throws IOException {
GenericJson json = new GenericJson();
- InputStream configStream = TestUtils.jsonToInputStream(json);
-
- IllegalArgumentException exception =
- assertThrows(
- IllegalArgumentException.class,
- () ->
- WorkloadCertificateConfiguration.fromCertificateConfigurationStream(configStream));
- assertTrue(
- exception
- .getMessage()
- .contains(
- "The cert_configs object must be provided in the certificate configuration file."));
+ try (InputStream configStream = TestUtils.jsonToInputStream(json)) {
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ () ->
+ WorkloadCertificateConfiguration.fromCertificateConfigurationStream(
+ configStream));
+ assertTrue(
+ exception
+ .getMessage()
+ .contains(
+ "The cert_configs object must be provided in the certificate configuration file."));
+ }
}
static InputStream writeWorkloadCertificateConfigStream(String certPath, String privateKeyPath)
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/X509ProviderTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/X509ProviderTest.java
index 7f3927654f80..5ddd1a169d29 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/X509ProviderTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/mtls/X509ProviderTest.java
@@ -36,73 +36,44 @@
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import java.io.ByteArrayInputStream;
+import com.google.auth.oauth2.SystemPropertyProvider;
+import com.google.auth.oauth2.TestEnvironmentProvider;
+import com.google.auth.oauth2.TestPropertyProvider;
import java.io.File;
-import java.io.FileNotFoundException;
+import java.io.FileInputStream;
import java.io.IOException;
-import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
-import java.util.HashMap;
-import java.util.Map;
import org.junit.jupiter.api.Test;
class X509ProviderTest {
- private static final String TEST_CERT =
- "-----BEGIN CERTIFICATE-----\n"
- + "MIICGzCCAYSgAwIBAgIIWrt6xtmHPs4wDQYJKoZIhvcNAQEFBQAwMzExMC8GA1UE\n"
- + "AxMoMTAwOTEyMDcyNjg3OC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbTAeFw0x\n"
- + "MjEyMDExNjEwNDRaFw0yMjExMjkxNjEwNDRaMDMxMTAvBgNVBAMTKDEwMDkxMjA3\n"
- + "MjY4NzguYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20wgZ8wDQYJKoZIhvcNAQEB\n"
- + "BQADgY0AMIGJAoGBAL1SdY8jTUVU7O4/XrZLYTw0ON1lV6MQRGajFDFCqD2Fd9tQ\n"
- + "GLW8Iftx9wfXe1zuaehJSgLcyCxazfyJoN3RiONBihBqWY6d3lQKqkgsRTNZkdFJ\n"
- + "Wdzl/6CxhK9sojh2p0r3tydtv9iwq5fuuWIvtODtT98EgphhncQAqkKoF3zVAgMB\n"
- + "AAGjODA2MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQM\n"
- + "MAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4GBAD8XQEqzGePa9VrvtEGpf+R4\n"
- + "fkxKbcYAzqYq202nKu0kfjhIYkYSBj6gi348YaxE64yu60TVl42l5HThmswUheW4\n"
- + "uQIaq36JvwvsDP5Zoj5BgiNSnDAFQp+jJFBRUA5vooJKgKgMDf/r/DCOsbO6VJF1\n"
- + "kWwa9n19NFiV0z3m6isj\n"
- + "-----END CERTIFICATE-----\n";
-
- private static final String TEST_PRIVATE_KEY =
- "-----BEGIN PRIVATE KEY-----\n"
- + "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAL1SdY8jTUVU7O4/\n"
- + "XrZLYTw0ON1lV6MQRGajFDFCqD2Fd9tQGLW8Iftx9wfXe1zuaehJSgLcyCxazfyJ\n"
- + "oN3RiONBihBqWY6d3lQKqkgsRTNZkdFJWdzl/6CxhK9sojh2p0r3tydtv9iwq5fu\n"
- + "uWIvtODtT98EgphhncQAqkKoF3zVAgMBAAECgYB51B9cXe4yiGTzJ4pOKpHGySAy\n"
- + "sC1F/IjXt2eeD3PuKv4m/hL4l7kScpLx0+NJuQ4j8U2UK/kQOdrGANapB1ZbMZAK\n"
- + "/q0xmIUzdNIDiGSoTXGN2mEfdsEpQ/Xiv0lyhYBBPC/K4sYIpHccnhSRQUZlWLLY\n"
- + "lE5cFNKC9b7226mNvQJBAPt0hfCNIN0kUYOA9jdLtx7CE4ySGMPf5KPBuzPd8ty1\n"
- + "fxaFm9PB7B76VZQYmHcWy8rT5XjoLJHrmGW1ZvP+iDsCQQDAvnKoarPOGb5iJfkq\n"
- + "RrA4flf1TOlf+1+uqIOJ94959jkkJeb0gv/TshDnm6/bWn+1kJylQaKygCizwPwB\n"
- + "Z84vAkA0Duur4YvsPJijoQ9YY1SGCagCcjyuUKwFOxaGpmyhRPIKt56LOJqpzyno\n"
- + "fy8ReKa4VyYq4eZYT249oFCwMwIBAkAROPNF2UL3x5UbcAkznd1hLujtIlI4IV4L\n"
- + "XUNjsJtBap7we/KHJq11XRPlniO4lf2TW7iji5neGVWJulTKS1xBAkAerktk4Hsw\n"
- + "ErUaUG1s/d+Sgc8e/KMeBElV+NxGhcWEeZtfHMn/6VOlbzY82JyvC9OKC80A5CAE\n"
- + "VUV6b25kqrcu\n"
- + "-----END PRIVATE KEY-----";
+ private static final String TEST_CERT_PATH = "testresources/mtls/test_cert.pem";
+ private static final String TEST_CONFIG_PATH = "testresources/mtls/certificate_config.json";
@Test
void x509Provider_fileDoesntExist_throws() {
String certConfigPath = "badfile.txt";
- X509Provider testProvider = new TestX509Provider(certConfigPath);
- String expectedErrorMessage = "File does not exist.";
-
+ X509Provider testProvider = new X509Provider(certConfigPath);
+ String expectedErrorMessage =
+ "Certificate configuration file does not exist or is not a file: "
+ + new File(certConfigPath).getAbsolutePath();
CertificateSourceUnavailableException exception =
assertThrows(CertificateSourceUnavailableException.class, testProvider::getKeyStore);
- assertTrue(exception.getMessage().contains(expectedErrorMessage));
+ assertEquals(expectedErrorMessage, exception.getMessage());
}
@Test
- void x509Provider_emptyFile_throws() {
- String certConfigPath = "certConfig.txt";
- InputStream certConfigStream = new ByteArrayInputStream("".getBytes());
- TestX509Provider testProvider = new TestX509Provider(certConfigPath);
- testProvider.addFile(certConfigPath, certConfigStream);
+ void x509Provider_emptyFile_throws() throws IOException {
+ Path emptyConfig = Files.createTempFile("emptyConfig", ".txt");
+ emptyConfig.toFile().deleteOnExit();
+
+ X509Provider testProvider = new X509Provider(emptyConfig.toString());
String expectedErrorMessage = "no JSON input found";
IllegalArgumentException exception =
@@ -112,21 +83,13 @@ void x509Provider_emptyFile_throws() {
@Test
void x509Provider_succeeds() throws IOException, KeyStoreException, CertificateException {
- String certConfigPath = "certConfig.txt";
- String certPath = "cert.crt";
- String keyPath = "key.crt";
- InputStream certConfigStream =
- WorkloadCertificateConfigurationTest.writeWorkloadCertificateConfigStream(
- certPath, keyPath);
-
- TestX509Provider testProvider = new TestX509Provider(certConfigPath);
- testProvider.addFile(certConfigPath, certConfigStream);
- testProvider.addFile(certPath, new ByteArrayInputStream(TEST_CERT.getBytes()));
- testProvider.addFile(keyPath, new ByteArrayInputStream(TEST_PRIVATE_KEY.getBytes()));
+ X509Provider testProvider = new X509Provider(TEST_CONFIG_PATH);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
- Certificate expectedCert =
- cf.generateCertificate(new ByteArrayInputStream(TEST_CERT.getBytes()));
+ Certificate expectedCert;
+ try (FileInputStream fis = new FileInputStream(new File(TEST_CERT_PATH))) {
+ expectedCert = cf.generateCertificate(fis);
+ }
// Assert that the store has the expected certificate and only the expected certificate.
KeyStore store = testProvider.getKeyStore();
@@ -137,22 +100,17 @@ void x509Provider_succeeds() throws IOException, KeyStoreException, CertificateE
@Test
void x509Provider_succeeds_withEnvVariable()
throws IOException, KeyStoreException, CertificateException {
- String certConfigPath = "certConfig.txt";
- String certPath = "cert.crt";
- String keyPath = "key.crt";
- InputStream certConfigStream =
- WorkloadCertificateConfigurationTest.writeWorkloadCertificateConfigStream(
- certPath, keyPath);
-
- TestX509Provider testProvider = new TestX509Provider();
- testProvider.setEnv("GOOGLE_API_CERTIFICATE_CONFIG", certConfigPath);
- testProvider.addFile(certConfigPath, certConfigStream);
- testProvider.addFile(certPath, new ByteArrayInputStream(TEST_CERT.getBytes()));
- testProvider.addFile(keyPath, new ByteArrayInputStream(TEST_PRIVATE_KEY.getBytes()));
+ TestEnvironmentProvider envProvider = new TestEnvironmentProvider();
+ envProvider.setEnv("GOOGLE_API_CERTIFICATE_CONFIG", TEST_CONFIG_PATH);
+
+ X509Provider testProvider =
+ new X509Provider(envProvider, SystemPropertyProvider.getInstance(), null);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
- Certificate expectedCert =
- cf.generateCertificate(new ByteArrayInputStream(TEST_CERT.getBytes()));
+ Certificate expectedCert;
+ try (FileInputStream fis = new FileInputStream(new File(TEST_CERT_PATH))) {
+ expectedCert = cf.generateCertificate(fis);
+ }
// Assert that the store has the expected certificate and only the expected certificate.
KeyStore store = testProvider.getKeyStore();
@@ -163,22 +121,17 @@ void x509Provider_succeeds_withEnvVariable()
@Test
void x509Provider_succeeds_withWellKnownPath()
throws IOException, KeyStoreException, CertificateException {
- String certConfigPath = "certConfig.txt";
- String certPath = "cert.crt";
- String keyPath = "key.crt";
- InputStream certConfigStream =
- WorkloadCertificateConfigurationTest.writeWorkloadCertificateConfigStream(
- certPath, keyPath);
-
- TestX509Provider testProvider = new TestX509Provider();
- testProvider.setEnv("GOOGLE_API_CERTIFICATE_CONFIG", certConfigPath);
- testProvider.addFile(certConfigPath, certConfigStream);
- testProvider.addFile(certPath, new ByteArrayInputStream(TEST_CERT.getBytes()));
- testProvider.addFile(keyPath, new ByteArrayInputStream(TEST_PRIVATE_KEY.getBytes()));
+ TestEnvironmentProvider envProvider = new TestEnvironmentProvider();
+ envProvider.setEnv("CLOUDSDK_CONFIG", "testresources/mtls/");
+
+ X509Provider testProvider =
+ new X509Provider(envProvider, SystemPropertyProvider.getInstance(), null);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
- Certificate expectedCert =
- cf.generateCertificate(new ByteArrayInputStream(TEST_CERT.getBytes()));
+ Certificate expectedCert;
+ try (FileInputStream fis = new FileInputStream(new File(TEST_CERT_PATH))) {
+ expectedCert = cf.generateCertificate(fis);
+ }
// Assert that the store has the expected certificate and only the expected certificate.
KeyStore store = testProvider.getKeyStore();
@@ -186,53 +139,73 @@ void x509Provider_succeeds_withWellKnownPath()
assertNotNull(store.getCertificateAlias(expectedCert));
}
- static class TestX509Provider extends X509Provider {
- private final Map files;
- private final Map variables;
- private final Map properties;
+ @Test
+ void x509Provider_succeeds_withWindowsPath()
+ throws IOException, KeyStoreException, CertificateException {
+ Path windowsTempDir = Files.createTempDirectory("windowsTempDir");
+ windowsTempDir.toFile().deleteOnExit();
+ Path gcloudDir = windowsTempDir.resolve("gcloud");
+ Files.createDirectory(gcloudDir);
+ Path configPath = gcloudDir.resolve("certificate_config.json");
- TestX509Provider() {
- this(null);
- }
+ // Copy the valid config to this new temp location
+ Files.copy(new File(TEST_CONFIG_PATH).toPath(), configPath);
- TestX509Provider(String filePathOverride) {
- super(filePathOverride);
- this.files = new HashMap<>();
- this.variables = new HashMap<>();
- this.properties = new HashMap<>();
- }
+ TestEnvironmentProvider envProvider = new TestEnvironmentProvider();
+ envProvider.setEnv("APPDATA", windowsTempDir.toString());
- void addFile(String file, InputStream stream) {
- files.put(file, stream);
- }
+ TestPropertyProvider propProvider = new TestPropertyProvider();
+ propProvider.setProperty("os.name", "Windows 10");
- @Override
- String getEnv(String name) {
- return variables.get(name);
- }
+ X509Provider testProvider = new X509Provider(envProvider, propProvider, null);
- void setEnv(String name, String value) {
- variables.put(name, value);
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ Certificate expectedCert;
+ try (FileInputStream fis = new FileInputStream(new File(TEST_CERT_PATH))) {
+ expectedCert = cf.generateCertificate(fis);
}
- @Override
- String getProperty(String property, String def) {
- String value = properties.get(property);
- return value == null ? def : value;
- }
+ KeyStore store = testProvider.getKeyStore();
+ assertEquals(1, store.size());
+ assertNotNull(store.getCertificateAlias(expectedCert));
+ }
- @Override
- boolean isFile(File file) {
- return files.containsKey(file.getPath());
- }
+ @Test
+ void x509Provider_certFileDoesntExist_throws() throws IOException {
+ Path tempConfig = Files.createTempFile("config", ".json");
+ tempConfig.toFile().deleteOnExit();
+ Path nonExistentCert = tempConfig.getParent().resolve("non_existent_cert.pem");
- @Override
- InputStream createInputStream(File file) throws FileNotFoundException {
- InputStream stream = files.get(file.getPath());
- if (stream == null) {
- throw new FileNotFoundException(file.getPath());
- }
- return stream;
- }
+ Files.write(
+ tempConfig,
+ ("{\"cert_configs\":{\"workload\":{\"cert_path\":\""
+ + nonExistentCert.toString()
+ + "\",\"key_path\":\"key.pem\"}}}")
+ .getBytes());
+
+ X509Provider testProvider = new X509Provider(tempConfig.toString());
+
+ assertThrows(IOException.class, testProvider::getKeyStore);
+ }
+
+ @Test
+ void x509Provider_malformedCert_throws() throws IOException {
+ Path tempConfig = Files.createTempFile("config", ".json");
+ tempConfig.toFile().deleteOnExit();
+ Path malformedCert = Files.createTempFile("badcert", ".pem");
+ malformedCert.toFile().deleteOnExit();
+
+ Files.write(malformedCert, "This is not a valid certificate".getBytes());
+
+ Files.write(
+ tempConfig,
+ ("{\"cert_configs\":{\"workload\":{\"cert_path\":\""
+ + malformedCert.toString()
+ + "\",\"key_path\":\"key.pem\"}}}")
+ .getBytes());
+
+ X509Provider testProvider = new X509Provider(tempConfig.toString());
+
+ assertThrows(Exception.class, testProvider::getKeyStore);
}
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AccessTokenTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AccessTokenTest.java
index d93e2c98f53e..f9ebaa2bb94c 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AccessTokenTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AccessTokenTest.java
@@ -32,14 +32,14 @@
package com.google.auth.oauth2;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotSame;
import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Date;
import java.util.List;
import org.junit.jupiter.api.Test;
@@ -92,7 +92,7 @@ void builder() {
.setTokenValue(TOKEN)
.setScopes("dummy")
.build();
- assertEquals(Arrays.asList("dummy"), accessToken.getScopes());
+ assertEquals(Collections.singletonList("dummy"), accessToken.getScopes());
// empty scope
accessToken =
@@ -105,7 +105,7 @@ void builder() {
}
@Test
- void equals_true() throws IOException {
+ void equals_true() {
AccessToken accessToken =
AccessToken.newBuilder()
.setExpirationTime(EXPIRATION_DATE)
@@ -121,12 +121,12 @@ void equals_true() throws IOException {
.setScopes(SCOPES)
.build();
- assertTrue(accessToken.equals(otherAccessToken));
- assertTrue(otherAccessToken.equals(accessToken));
+ assertEquals(accessToken, otherAccessToken);
+ assertEquals(otherAccessToken, accessToken);
}
@Test
- void equals_false_scopes() throws IOException {
+ void equals_false_scopes() {
AccessToken accessToken =
AccessToken.newBuilder()
.setExpirationTime(EXPIRATION_DATE)
@@ -138,15 +138,15 @@ void equals_false_scopes() throws IOException {
AccessToken.newBuilder()
.setExpirationTime(EXPIRATION_DATE)
.setTokenValue(TOKEN)
- .setScopes(Arrays.asList("scope1"))
+ .setScopes(Collections.singletonList("scope1"))
.build();
- assertFalse(accessToken.equals(otherAccessToken));
- assertFalse(otherAccessToken.equals(accessToken));
+ assertNotEquals(accessToken, otherAccessToken);
+ assertNotEquals(otherAccessToken, accessToken);
}
@Test
- void equals_false_token() throws IOException {
+ void equals_false_token() {
AccessToken accessToken =
AccessToken.newBuilder()
.setExpirationTime(EXPIRATION_DATE)
@@ -161,12 +161,12 @@ void equals_false_token() throws IOException {
.setScopes(SCOPES)
.build();
- assertFalse(accessToken.equals(otherAccessToken));
- assertFalse(otherAccessToken.equals(accessToken));
+ assertNotEquals(accessToken, otherAccessToken);
+ assertNotEquals(otherAccessToken, accessToken);
}
@Test
- void equals_false_expirationDate() throws IOException {
+ void equals_false_expirationDate() {
AccessToken accessToken =
AccessToken.newBuilder()
.setExpirationTime(EXPIRATION_DATE)
@@ -181,8 +181,8 @@ void equals_false_expirationDate() throws IOException {
.setScopes(SCOPES)
.build();
- assertFalse(accessToken.equals(otherAccessToken));
- assertFalse(otherAccessToken.equals(accessToken));
+ assertNotEquals(accessToken, otherAccessToken);
+ assertNotEquals(otherAccessToken, accessToken);
}
@Test
@@ -201,7 +201,7 @@ void toString_containsFields() {
}
@Test
- void hashCode_equals() throws IOException {
+ void hashCode_equals() {
AccessToken accessToken =
AccessToken.newBuilder()
.setExpirationTime(EXPIRATION_DATE)
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AppEngineCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AppEngineCredentialsTest.java
index 43139e2bed2b..eb885d184c17 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AppEngineCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AppEngineCredentialsTest.java
@@ -37,8 +37,8 @@
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.common.collect.ImmutableMap;
import java.io.IOException;
@@ -77,18 +77,15 @@ void constructor_usesAppIdentityService() throws IOException {
@Test
void constructor_noAppEngineRuntime_throwsHelpfulLoadError() {
- try {
- new TestAppEngineCredentialsNoSdk();
- fail("Credential expected to fail to load if credential class not present.");
- } catch (IOException e) {
- String message = e.getMessage();
- assertTrue(message.contains("Check that the App Engine SDK is deployed."));
- assertInstanceOf(ClassNotFoundException.class, e.getCause());
- assertTrue(
- e.getCause()
- .getMessage()
- .contains(AppEngineCredentials.APP_IDENTITY_SERVICE_FACTORY_CLASS));
- }
+ IOException exception = assertThrows(IOException.class, TestAppEngineCredentialsNoSdk::new);
+ String message = exception.getMessage();
+ assertTrue(message.contains("Check that the App Engine SDK is deployed."));
+ assertInstanceOf(ClassNotFoundException.class, exception.getCause());
+ assertTrue(
+ exception
+ .getCause()
+ .getMessage()
+ .contains(AppEngineCredentials.APP_IDENTITY_SERVICE_FACTORY_CLASS));
}
@Test
@@ -115,12 +112,7 @@ void sign_sameAs() throws IOException {
void createScoped_clonesWithScopes() throws IOException {
TestAppEngineCredentials credentials = new TestAppEngineCredentials(null);
assertTrue(credentials.createScopedRequired());
- try {
- credentials.refreshAccessToken();
- fail("Should not be able to use credential without scopes.");
- } catch (Exception expected) {
- // Expected
- }
+ assertThrows(IOException.class, credentials::refreshAccessToken);
GoogleCredentials scopedCredentials = credentials.createScoped(SCOPES);
assertNotSame(credentials, scopedCredentials);
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AwsCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AwsCredentialsTest.java
index 4764d27ec38f..e401ae853771 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AwsCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AwsCredentialsTest.java
@@ -32,12 +32,13 @@
package com.google.auth.oauth2;
import static com.google.auth.Credentials.GOOGLE_DEFAULT_UNIVERSE;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonParser;
@@ -55,7 +56,6 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
-import java.util.function.Supplier;
import org.junit.jupiter.api.Test;
/** Tests for {@link AwsCredentials}. */
@@ -86,7 +86,6 @@ class AwsCredentialsTest extends BaseSerializationTest {
}
};
- private static final Map EMPTY_METADATA_HEADERS = Collections.emptyMap();
private static final Map EMPTY_STRING_HEADERS = Collections.emptyMap();
private static final AwsCredentialSource AWS_CREDENTIAL_SOURCE =
@@ -110,13 +109,13 @@ class AwsCredentialsTest extends BaseSerializationTest {
@Test
void test_awsCredentialSource() {
- String keys[] = {"region_url", "url", "imdsv2_session_token_url"};
+ String[] keys = {"region_url", "url", "imdsv2_session_token_url"};
for (String key : keys) {
Map credentialSourceWithInvalidUrl = buildAwsIpv6CredentialSourceMap();
credentialSourceWithInvalidUrl.put(key, "https://badhost.com/fake");
// Should succeed as no validation is done.
- new AwsCredentialSource(credentialSourceWithInvalidUrl);
+ assertDoesNotThrow(() -> new AwsCredentialSource(credentialSourceWithInvalidUrl));
}
}
@@ -190,7 +189,7 @@ void refreshAccessToken_withServiceAccountImpersonationOptions() throws IOExcept
.setServiceAccountImpersonationUrl(
transportFactory.transport.getServiceAccountImpersonationUrl())
.setServiceAccountImpersonationOptions(
- ExternalAccountCredentialsTest.buildServiceAccountImpersonationOptions(2800))
+ ExternalAccountCredentialsTest.buildServiceAccountImpersonationOptions())
.build();
AccessToken accessToken = awsCredential.refreshAccessToken();
@@ -199,17 +198,17 @@ void refreshAccessToken_withServiceAccountImpersonationOptions() throws IOExcept
transportFactory.transport.getServiceAccountAccessToken(), accessToken.getTokenValue());
// Validate that default lifetime was set correctly on the request.
- GenericJson query =
- OAuth2Utils.JSON_FACTORY
- .createJsonParser(transportFactory.transport.getLastRequest().getContentAsString())
- .parseAndClose(GenericJson.class);
-
- assertEquals("2800s", query.get("lifetime"));
-
- // Validate metrics header is set correctly on the sts request.
- Map> headers =
- transportFactory.transport.getRequests().get(6).getHeaders();
- ExternalAccountCredentialsTest.validateMetricsHeader(headers, "aws", true, true);
+ try (JsonParser jsonParser =
+ OAuth2Utils.JSON_FACTORY.createJsonParser(
+ transportFactory.transport.getLastRequest().getContentAsString())) {
+ GenericJson query = jsonParser.parseAndClose(GenericJson.class);
+ assertEquals("2800s", query.get("lifetime"));
+
+ // Validate metrics header is set correctly on the sts request.
+ Map> headers =
+ transportFactory.transport.getRequests().get(6).getHeaders();
+ ExternalAccountCredentialsTest.validateMetricsHeader(headers, "aws", true, true);
+ }
}
@Test
@@ -485,12 +484,8 @@ void retrieveSubjectToken_noRegion_expectThrows() {
.setCredentialSource(buildAwsCredentialSource(transportFactory))
.build();
- try {
- awsCredential.retrieveSubjectToken();
- fail("Should not be able to use credential without exception.");
- } catch (IOException exception) {
- assertEquals("Failed to retrieve AWS region.", exception.getMessage());
- }
+ IOException exception = assertThrows(IOException.class, awsCredential::retrieveSubjectToken);
+ assertEquals("Failed to retrieve AWS region.", exception.getMessage());
List requests = transportFactory.transport.getRequests();
assertEquals(1, requests.size());
@@ -514,12 +509,8 @@ void retrieveSubjectToken_noRole_expectThrows() {
.setCredentialSource(buildAwsCredentialSource(transportFactory))
.build();
- try {
- awsCredential.retrieveSubjectToken();
- fail("Should not be able to use credential without exception.");
- } catch (IOException exception) {
- assertEquals("Failed to retrieve AWS IAM role.", exception.getMessage());
- }
+ IOException exception = assertThrows(IOException.class, awsCredential::retrieveSubjectToken);
+ assertEquals("Failed to retrieve AWS IAM role.", exception.getMessage());
List requests = transportFactory.transport.getRequests();
assertEquals(2, requests.size());
@@ -546,12 +537,8 @@ void retrieveSubjectToken_noCredentials_expectThrows() {
.setCredentialSource(buildAwsCredentialSource(transportFactory))
.build();
- try {
- awsCredential.retrieveSubjectToken();
- fail("Should not be able to use credential without exception.");
- } catch (IOException exception) {
- assertEquals("Failed to retrieve AWS credentials.", exception.getMessage());
- }
+ IOException exception = assertThrows(IOException.class, awsCredential::retrieveSubjectToken);
+ assertEquals("Failed to retrieve AWS credentials.", exception.getMessage());
List requests = transportFactory.transport.getRequests();
assertEquals(3, requests.size());
@@ -581,15 +568,11 @@ void retrieveSubjectToken_noRegionUrlProvided() {
.setCredentialSource(new AwsCredentialSource(credentialSource))
.build();
- try {
- awsCredential.retrieveSubjectToken();
- fail("Should not be able to use credential without exception.");
- } catch (IOException exception) {
- assertEquals(
- "Unable to determine the AWS region. The credential source does not "
- + "contain the region URL.",
- exception.getMessage());
- }
+ IOException exception = assertThrows(IOException.class, awsCredential::retrieveSubjectToken);
+ assertEquals(
+ "Unable to determine the AWS region. The credential source does not "
+ + "contain the region URL.",
+ exception.getMessage());
// No requests because the credential source does not contain region URL.
List requests = transportFactory.transport.getRequests();
@@ -679,7 +662,7 @@ void retrieveSubjectToken_withProgrammaticRefreshSessionToken() throws IOExcepti
}
@Test
- void retrieveSubjectToken_passesContext() throws IOException {
+ void retrieveSubjectToken_passesContext() {
MockExternalAccountCredentialsTransportFactory transportFactory =
new MockExternalAccountCredentialsTransportFactory();
@@ -705,11 +688,11 @@ void retrieveSubjectToken_passesContext() throws IOException {
.setSubjectTokenType("subjectTokenType")
.build();
- awsCredential.retrieveSubjectToken();
+ assertDoesNotThrow(awsCredential::retrieveSubjectToken);
}
@Test
- void retrieveSubjectToken_withProgrammaticRefreshThrowsError() throws IOException {
+ void retrieveSubjectToken_withProgrammaticRefreshThrowsError() {
MockExternalAccountCredentialsTransportFactory transportFactory =
new MockExternalAccountCredentialsTransportFactory();
@@ -727,12 +710,8 @@ void retrieveSubjectToken_withProgrammaticRefreshThrowsError() throws IOExceptio
.setSubjectTokenType("subjectTokenType")
.build();
- try {
- String subjectToken = URLDecoder.decode(awsCredential.retrieveSubjectToken(), "UTF-8");
- fail("retrieveSubjectToken should not succeed");
- } catch (IOException e) {
- assertEquals("test", e.getMessage());
- }
+ IOException exception = assertThrows(IOException.class, awsCredential::retrieveSubjectToken);
+ assertEquals("test", exception.getMessage());
}
@Test
@@ -853,14 +832,13 @@ void getAwsSecurityCredentials_fromMetadataServer_noUrlProvided() {
.setCredentialSource(new AwsCredentialSource(credentialSource))
.build();
- try {
- awsCredential.getAwsSecurityCredentialsSupplier().getCredentials(emptyContext);
- fail("Should not be able to use credential without exception.");
- } catch (IOException exception) {
- assertEquals(
- "Unable to determine the AWS IAM role name. The credential source does not contain the url field.",
- exception.getMessage());
- }
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () -> awsCredential.getAwsSecurityCredentialsSupplier().getCredentials(emptyContext));
+ assertEquals(
+ "Unable to determine the AWS IAM role name. The credential source does not contain the url field.",
+ exception.getMessage());
// No requests because url field is not present in credential source.
List requests = transportFactory.transport.getRequests();
@@ -946,7 +924,7 @@ void getAwsRegion_metadataServer() throws IOException {
}
@Test
- void createdScoped_clonedCredentialWithAddedScopes() throws IOException {
+ void createdScoped_clonedCredentialWithAddedScopes() {
AwsCredentials credentials =
AwsCredentials.newBuilder(AWS_CREDENTIAL)
.setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
@@ -982,12 +960,10 @@ void credentialSource_invalidAwsEnvironmentId() {
credentialSource.put("regional_cred_verification_url", GET_CALLER_IDENTITY_URL);
credentialSource.put("environment_id", "azure1");
- try {
- new AwsCredentialSource(credentialSource);
- fail("Exception should be thrown.");
- } catch (IllegalArgumentException e) {
- assertEquals("Invalid AWS environment ID.", e.getMessage());
- }
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class, () -> new AwsCredentialSource(credentialSource));
+ assertEquals("Invalid AWS environment ID.", exception.getMessage());
}
@Test
@@ -997,31 +973,27 @@ void credentialSource_invalidAwsEnvironmentVersion() {
credentialSource.put("regional_cred_verification_url", GET_CALLER_IDENTITY_URL);
credentialSource.put("environment_id", "aws" + environmentVersion);
- try {
- new AwsCredentialSource(credentialSource);
- fail("Exception should be thrown.");
- } catch (IllegalArgumentException e) {
- assertEquals(
- String.format(
- "AWS version %s is not supported in the current build.", environmentVersion),
- e.getMessage());
- }
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class, () -> new AwsCredentialSource(credentialSource));
+ assertEquals(
+ String.format("AWS version %s is not supported in the current build.", environmentVersion),
+ exception.getMessage());
}
@Test
void credentialSource_missingRegionalCredVerificationUrl() {
- try {
- new AwsCredentialSource(new HashMap());
- fail("Exception should be thrown.");
- } catch (IllegalArgumentException e) {
- assertEquals(
- "A regional_cred_verification_url representing the GetCallerIdentity action URL must be specified.",
- e.getMessage());
- }
+ HashMap credentialSourceMap = new HashMap<>();
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class, () -> new AwsCredentialSource(credentialSourceMap));
+ assertEquals(
+ "A regional_cred_verification_url representing the GetCallerIdentity action URL must be specified.",
+ exception.getMessage());
}
@Test
- void builder_allFields() throws IOException {
+ void builder_allFields() {
List scopes = Arrays.asList("scope1", "scope2");
AwsCredentials credentials =
@@ -1057,7 +1029,7 @@ void builder_allFields() throws IOException {
}
@Test
- void builder_missingUniverseDomain_defaults() throws IOException {
+ void builder_missingUniverseDomain_defaults() {
List scopes = Arrays.asList("scope1", "scope2");
AwsCredentials credentials =
@@ -1094,7 +1066,7 @@ void builder_missingUniverseDomain_defaults() throws IOException {
}
@Test
- void newBuilder_allFields() throws IOException {
+ void newBuilder_allFields() {
List scopes = Arrays.asList("scope1", "scope2");
AwsCredentials credentials =
@@ -1132,7 +1104,7 @@ void newBuilder_allFields() throws IOException {
}
@Test
- void newBuilder_noUniverseDomain_defaults() throws IOException {
+ void newBuilder_noUniverseDomain_defaults() {
List scopes = Arrays.asList("scope1", "scope2");
AwsCredentials credentials =
@@ -1169,7 +1141,7 @@ void newBuilder_noUniverseDomain_defaults() throws IOException {
}
@Test
- void builder_defaultRegionalCredentialVerificationUrlOverride() throws IOException {
+ void builder_defaultRegionalCredentialVerificationUrlOverride() {
List scopes = Arrays.asList("scope1", "scope2");
AwsSecurityCredentialsSupplier supplier =
@@ -1197,63 +1169,55 @@ void builder_defaultRegionalCredentialVerificationUrlOverride() throws IOExcepti
}
@Test
- void builder_supplierAndCredSourceThrows() throws IOException {
+ void builder_supplierAndCredSourceThrows() {
List scopes = Arrays.asList("scope1", "scope2");
AwsSecurityCredentialsSupplier supplier =
new TestAwsSecurityCredentialsSupplier("region", null, null, null);
- try {
- AwsCredentials credentials =
- AwsCredentials.newBuilder()
- .setAwsSecurityCredentialsSupplier(supplier)
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setAudience("audience")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .setTokenInfoUrl("tokenInfoUrl")
- .setCredentialSource(AWS_CREDENTIAL_SOURCE)
- .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
- .setQuotaProjectId("quotaProjectId")
- .setClientId("clientId")
- .setClientSecret("clientSecret")
- .setScopes(scopes)
- .build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- "AwsCredentials cannot have both an awsSecurityCredentialsSupplier and a credentialSource.",
- exception.getMessage());
- }
+ AwsCredentials.Builder builder =
+ AwsCredentials.newBuilder()
+ .setAwsSecurityCredentialsSupplier(supplier)
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setAudience("audience")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL)
+ .setTokenInfoUrl("tokenInfoUrl")
+ .setCredentialSource(AWS_CREDENTIAL_SOURCE)
+ .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
+ .setQuotaProjectId("quotaProjectId")
+ .setClientId("clientId")
+ .setClientSecret("clientSecret")
+ .setScopes(scopes);
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals(
+ "AwsCredentials cannot have both an awsSecurityCredentialsSupplier and a credentialSource.",
+ exception.getMessage());
}
@Test
- void builder_noSupplieOrCredSourceThrows() throws IOException {
+ void builder_noSupplieOrCredSourceThrows() {
List scopes = Arrays.asList("scope1", "scope2");
- Supplier testSupplier = () -> null;
-
- try {
- AwsCredentials credentials =
- AwsCredentials.newBuilder()
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setAudience("audience")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .setTokenInfoUrl("tokenInfoUrl")
- .setTokenInfoUrl("tokenInfoUrl")
- .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
- .setQuotaProjectId("quotaProjectId")
- .setClientId("clientId")
- .setClientSecret("clientSecret")
- .setScopes(scopes)
- .build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- "An awsSecurityCredentialsSupplier or a credentialSource must be provided.",
- exception.getMessage());
- }
+ AwsCredentials.Builder builder =
+ AwsCredentials.newBuilder()
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setAudience("audience")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL)
+ .setTokenInfoUrl("tokenInfoUrl")
+ .setTokenInfoUrl("tokenInfoUrl")
+ .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
+ .setQuotaProjectId("quotaProjectId")
+ .setClientId("clientId")
+ .setClientSecret("clientSecret")
+ .setScopes(scopes);
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals(
+ "An awsSecurityCredentialsSupplier or a credentialSource must be provided.",
+ exception.getMessage());
}
@Test
@@ -1281,7 +1245,7 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(testCredentials, deserializedCredentials);
assertEquals(testCredentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(testCredentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
}
private static void ValidateRequest(
@@ -1353,12 +1317,12 @@ static InputStream writeAwsCredentialsStream(String stsUrl, String regionUrl, St
return TestUtils.jsonToInputStream(json);
}
- class TestAwsSecurityCredentialsSupplier implements AwsSecurityCredentialsSupplier {
+ static class TestAwsSecurityCredentialsSupplier implements AwsSecurityCredentialsSupplier {
- private String region;
- private AwsSecurityCredentials credentials;
- private IOException credentialException;
- private ExternalAccountSupplierContext expectedContext;
+ private final String region;
+ private final AwsSecurityCredentials credentials;
+ private final IOException credentialException;
+ private final ExternalAccountSupplierContext expectedContext;
TestAwsSecurityCredentialsSupplier(
String region,
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AwsRequestSignerTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AwsRequestSignerTest.java
index a1125edef760..750390aeaec2 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AwsRequestSignerTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/AwsRequestSignerTest.java
@@ -49,8 +49,9 @@
/**
* Tests for {@link AwsRequestSigner}.
*
- * Examples of sigv4 signed requests:
- * https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html
+ *
Examples
+ * of sigv4 signed requests
*/
class AwsRequestSignerTest {
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CertificateIdentityPoolSubjectTokenSupplierTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CertificateIdentityPoolSubjectTokenSupplierTest.java
index 9ff8f7f5f9f6..dfb81281db53 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CertificateIdentityPoolSubjectTokenSupplierTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CertificateIdentityPoolSubjectTokenSupplierTest.java
@@ -32,6 +32,7 @@
package com.google.auth.oauth2;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -254,8 +255,9 @@ void getSubjectToken_trustChainWrongOrder_throwsIllegalArgumentException() {
Throwable cause = exception.getCause();
assertNotNull(cause, "Exception cause should not be null");
- assertTrue(
- cause instanceof IllegalArgumentException,
+ assertInstanceOf(
+ IllegalArgumentException.class,
+ cause,
"Exception cause should be an IllegalArgumentException");
assertEquals(expectedRootErrorMessage, cause.getMessage());
}
@@ -301,7 +303,7 @@ void getSubjectToken_trustChainFileNotFound_throwsIOException() {
assertThrows(IOException.class, () -> supplier.getSubjectToken(mockContext));
// Check that the cause is NoSuchFileException from readTrustChain.
- assertTrue(exception.getCause() instanceof NoSuchFileException);
+ assertInstanceOf(NoSuchFileException.class, exception.getCause());
// Check the outer exception message added in getSubjectToken.
assertEquals("Trust chain file not found: " + nonExistentPath, exception.getMessage());
@@ -328,7 +330,7 @@ void getSubjectToken_trustChainInvalidFormat_throwsIOException() throws Exceptio
exception.getMessage());
// Check that the cause is CertificateException from readTrustChain
- assertTrue(exception.getCause() instanceof CertificateException);
+ assertInstanceOf(CertificateException.class, exception.getCause());
// Verify the cause's message specifically points to the trust chain parsing failure
// and includes the path of the invalid trust chain file.
@@ -357,8 +359,8 @@ void getSubjectToken_leafCertFileNotFound_throwsIOException() {
// Check that the cause is the original NoSuchFileException.
assertNotNull(exception.getCause(), "Exception should have a cause");
- assertTrue(
- exception.getCause() instanceof NoSuchFileException, "Cause should be NoSuchFileException");
+ assertInstanceOf(
+ NoSuchFileException.class, exception.getCause(), "Cause should be NoSuchFileException");
// Check the message of the cause (which is the path) in a platform-agnostic way.
Path expectedCausePath = Paths.get(nonExistentPath);
@@ -385,7 +387,7 @@ void getSubjectToken_leafCertInvalidFormat_throwsIOException() throws Exception
// Check that the cause is CertificateException from parseCertificate (via
// loadLeafCertificate)
- assertTrue(exception.getCause() instanceof CertificateException);
+ assertInstanceOf(CertificateException.class, exception.getCause());
assertEquals("Failed to parse X.509 certificate data.", exception.getCause().getMessage());
// Check the outer exception message
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ClientIdTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ClientIdTest.java
index c002cf7e4fe5..eaceca0eaf3a 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ClientIdTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ClientIdTest.java
@@ -31,6 +31,7 @@
package com.google.auth.oauth2;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
@@ -57,9 +58,8 @@ void constructor() {
@Test
void constructor_nullClientId_throws() {
- assertThrows(
- NullPointerException.class,
- () -> ClientId.newBuilder().setClientSecret(CLIENT_SECRET).build());
+ ClientId.Builder builder = ClientId.newBuilder().setClientSecret(CLIENT_SECRET);
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
@@ -100,21 +100,21 @@ void fromJson_installedNoSecret() throws IOException {
}
@Test
- void fromJson_invalidType_throws() throws IOException {
+ void fromJson_invalidType_throws() {
GenericJson json = writeClientIdJson("invalid", CLIENT_ID, null);
assertThrows(IOException.class, () -> ClientId.fromJson(json));
}
@Test
- void fromJson_noClientId_throws() throws IOException {
+ void fromJson_noClientId_throws() {
GenericJson json = writeClientIdJson("web", null, null);
assertThrows(IOException.class, () -> ClientId.fromJson(json));
}
@Test
- void fromJson_zeroLengthClientId_throws() throws IOException {
+ void fromJson_zeroLengthClientId_throws() {
GenericJson json = writeClientIdJson("web", "", null);
assertThrows(IOException.class, () -> ClientId.fromJson(json));
@@ -129,7 +129,7 @@ void fromResource() throws IOException {
}
@Test
- void fromResource_badResource() throws IOException {
+ void fromResource_badResource() {
assertThrows(
NullPointerException.class,
() -> ClientId.fromResource(ClientIdTest.class, "invalid.json"));
@@ -168,9 +168,9 @@ void fromStream_invalidJson_doesNotThrow() throws IOException {
+ CLIENT_SECRET
+ "\""
+ "}"; // No closing brace
- InputStream stream = TestUtils.stringToInputStream(invalidJson);
-
- ClientId.fromStream(stream);
+ try (InputStream stream = TestUtils.stringToInputStream(invalidJson)) {
+ assertDoesNotThrow(() -> ClientId.fromStream(stream));
+ }
}
private GenericJson writeClientIdJson(String type, String clientId, String clientSecret) {
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CloudShellCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CloudShellCredentialsTest.java
index 2f0dde620679..21abe335f3f5 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CloudShellCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CloudShellCredentialsTest.java
@@ -32,9 +32,8 @@
package com.google.auth.oauth2;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.assertTrue;
import com.google.api.client.util.Clock;
import java.io.BufferedReader;
@@ -50,63 +49,57 @@ class CloudShellCredentialsTest extends BaseSerializationTest {
@Test
void refreshAccessToken() throws IOException {
- final ServerSocket authSocket = new ServerSocket(0);
- try {
+ try (ServerSocket authSocket = new ServerSocket(0)) {
Runnable serverTask =
- new Runnable() {
- @Override
- public void run() {
- try {
- Socket clientSocket = authSocket.accept();
- BufferedReader input =
- new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
- String lines = input.readLine();
- lines += '\n' + input.readLine();
- assertEquals(lines, CloudShellCredentials.GET_AUTH_TOKEN_REQUEST);
-
- PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
- out.println("32\n[\"email\", \"project-id\", \"token\"]");
- } catch (Exception reThrown) {
- throw new RuntimeException(reThrown);
- }
+ () -> {
+ try {
+ Socket clientSocket = authSocket.accept();
+ BufferedReader input =
+ new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
+ String lines = input.readLine();
+ lines += '\n' + input.readLine();
+ assertEquals(CloudShellCredentials.GET_AUTH_TOKEN_REQUEST, lines);
+
+ PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);
+ out.println("32\n[\"email\", \"project-id\", \"token\"]");
+ } catch (Exception reThrown) {
+ throw new RuntimeException(reThrown);
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
- GoogleCredentials creds =
+ GoogleCredentials credentials =
CloudShellCredentials.newBuilder().setAuthPort(authSocket.getLocalPort()).build();
- assertEquals("token", creds.refreshAccessToken().getTokenValue());
- } finally {
- authSocket.close();
+ assertEquals("token", credentials.refreshAccessToken().getTokenValue());
}
}
@Test
- void equals_true() throws IOException {
+ void equals_true() {
GoogleCredentials credentials = CloudShellCredentials.newBuilder().setAuthPort(42).build();
GoogleCredentials otherCredentials = CloudShellCredentials.newBuilder().setAuthPort(42).build();
- assertTrue(credentials.equals(otherCredentials));
- assertTrue(otherCredentials.equals(credentials));
+ assertEquals(credentials, otherCredentials);
+ assertEquals(otherCredentials, credentials);
}
@Test
- void equals_false_authPort() throws IOException {
+ void equals_false_authPort() {
GoogleCredentials credentials = CloudShellCredentials.newBuilder().setAuthPort(42).build();
GoogleCredentials otherCredentials = CloudShellCredentials.newBuilder().setAuthPort(43).build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
- void toString_containsFields() throws IOException {
+ void toString_containsFields() {
String expectedToString = String.format("CloudShellCredentials{authPort=%d}", 42);
GoogleCredentials credentials = CloudShellCredentials.newBuilder().setAuthPort(42).build();
assertEquals(expectedToString, credentials.toString());
}
@Test
- void hashCode_equals() throws IOException {
+ void hashCode_equals() {
GoogleCredentials credentials = CloudShellCredentials.newBuilder().setAuthPort(42).build();
GoogleCredentials otherCredentials = CloudShellCredentials.newBuilder().setAuthPort(42).build();
assertEquals(credentials.hashCode(), otherCredentials.hashCode());
@@ -119,7 +112,7 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
}
@Test
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java
index 2f9b4b7e2836..82240171d9af 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java
@@ -36,12 +36,13 @@
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.client.http.HttpTransport;
@@ -151,7 +152,7 @@ void buildTokenUrlWithScopes_empty_scopes() {
@Test
void buildTokenUrlWithScopes_single_scope() {
ComputeEngineCredentials credentials =
- ComputeEngineCredentials.newBuilder().setScopes(Arrays.asList("foo")).build();
+ ComputeEngineCredentials.newBuilder().setScopes(Collections.singletonList("foo")).build();
String tokenUrlWithScopes = credentials.createTokenUrlWithScopes();
Collection scopes = credentials.getScopes();
@@ -295,11 +296,11 @@ void buildTokenUrlHardDirectPathBound_alts_transport() {
}
@Test
- void buildScoped_scopesPresent() throws IOException {
+ void buildScoped_scopesPresent() {
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setScopes(null).build();
ComputeEngineCredentials scopedCredentials =
- (ComputeEngineCredentials) credentials.createScoped(Arrays.asList("foo"));
+ (ComputeEngineCredentials) credentials.createScoped(Collections.singletonList("foo"));
Collection scopes = scopedCredentials.getScopes();
assertEquals(1, scopes.size());
@@ -307,11 +308,11 @@ void buildScoped_scopesPresent() throws IOException {
}
@Test
- void buildScoped_correctMargins() throws IOException {
+ void buildScoped_correctMargins() {
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setScopes(null).build();
ComputeEngineCredentials scopedCredentials =
- (ComputeEngineCredentials) credentials.createScoped(Arrays.asList("foo"));
+ (ComputeEngineCredentials) credentials.createScoped(Collections.singletonList("foo"));
assertEquals(
ComputeEngineCredentials.COMPUTE_EXPIRATION_MARGIN,
@@ -328,7 +329,7 @@ void buildScoped_explicitUniverse() throws IOException {
.setUniverseDomain("some-universe")
.build();
ComputeEngineCredentials scopedCredentials =
- (ComputeEngineCredentials) credentials.createScoped(Arrays.asList("foo"));
+ (ComputeEngineCredentials) credentials.createScoped(Collections.singletonList("foo"));
assertEquals("some-universe", scopedCredentials.getUniverseDomain());
assertTrue(scopedCredentials.isExplicitUniverseDomain());
@@ -337,7 +338,7 @@ void buildScoped_explicitUniverse() throws IOException {
@Test
void createScoped_defaultScopes() {
GoogleCredentials credentials =
- ComputeEngineCredentials.create().createScoped(null, Arrays.asList("foo"));
+ ComputeEngineCredentials.create().createScoped(null, Collections.singletonList("foo"));
Collection scopes = ((ComputeEngineCredentials) credentials).getScopes();
assertEquals(1, scopes.size());
@@ -345,14 +346,14 @@ void createScoped_defaultScopes() {
}
@Test
- void buildScoped_quotaProjectId() throws IOException {
+ void buildScoped_quotaProjectId() {
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder()
.setScopes(null)
.setQuotaProjectId("some-project-id")
.build();
ComputeEngineCredentials scopedCredentials =
- (ComputeEngineCredentials) credentials.createScoped(Arrays.asList("foo"));
+ (ComputeEngineCredentials) credentials.createScoped(Collections.singletonList("foo"));
assertEquals("some-project-id", scopedCredentials.getQuotaProjectId());
}
@@ -365,7 +366,7 @@ void buildDefaultScoped_explicitUniverse() throws IOException {
.setUniverseDomain("some-universe")
.build();
ComputeEngineCredentials scopedCredentials =
- (ComputeEngineCredentials) credentials.createScoped(null, Arrays.asList("foo"));
+ (ComputeEngineCredentials) credentials.createScoped(null, Collections.singletonList("foo"));
assertEquals("some-universe", scopedCredentials.getUniverseDomain());
assertTrue(scopedCredentials.isExplicitUniverseDomain());
@@ -374,7 +375,7 @@ void buildDefaultScoped_explicitUniverse() throws IOException {
@Test
void create_scoped_correctMargins() {
GoogleCredentials credentials =
- ComputeEngineCredentials.create().createScoped(null, Arrays.asList("foo"));
+ ComputeEngineCredentials.create().createScoped(null, Collections.singletonList("foo"));
assertEquals(
ComputeEngineCredentials.COMPUTE_EXPIRATION_MARGIN, credentials.getExpirationMargin());
@@ -425,15 +426,12 @@ void getRequestMetadata_missingServiceAccount_throws() {
transportFactory.transport.setServiceAccountEmail("SA_CLIENT_EMAIL");
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build();
- try {
- credentials.getRequestMetadata(CALL_URI);
- fail("Expected error refreshing token.");
- } catch (IOException expected) {
- String message = expected.getMessage();
- assertTrue(message.contains(Integer.toString(HttpStatusCodes.STATUS_CODE_NOT_FOUND)));
- // Message should mention scopes are missing on the VM.
- assertTrue(message.contains("scope"));
- }
+ IOException exception =
+ assertThrows(IOException.class, () -> credentials.getRequestMetadata(CALL_URI));
+ String message = exception.getMessage();
+ assertTrue(message.contains(Integer.toString(HttpStatusCodes.STATUS_CODE_NOT_FOUND)));
+ // Message should mention scopes are missing on the VM.
+ assertTrue(message.contains("scope"));
}
@Test
@@ -443,14 +441,11 @@ void getRequestMetadata_serverError_throws() {
transportFactory.transport.setServiceAccountEmail("SA_CLIENT_EMAIL");
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build();
- try {
- credentials.getRequestMetadata(CALL_URI);
- fail("Expected error refreshing token.");
- } catch (IOException expected) {
- String message = expected.getMessage();
- assertTrue(message.contains(Integer.toString(HttpStatusCodes.STATUS_CODE_SERVER_ERROR)));
- assertTrue(message.contains("Unexpected"));
- }
+ IOException exception =
+ assertThrows(IOException.class, () -> credentials.getRequestMetadata(CALL_URI));
+ String message = exception.getMessage();
+ assertTrue(message.contains(Integer.toString(HttpStatusCodes.STATUS_CODE_SERVER_ERROR)));
+ assertTrue(message.contains("Unexpected"));
}
@Test
@@ -464,19 +459,19 @@ void equals_true() throws IOException {
ComputeEngineCredentials otherCredentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build();
assertEquals(Credentials.GOOGLE_DEFAULT_UNIVERSE, otherCredentials.getUniverseDomain());
- assertFalse(explicitUniverseCredentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(explicitUniverseCredentials));
+ assertNotEquals(explicitUniverseCredentials, otherCredentials);
+ assertNotEquals(otherCredentials, explicitUniverseCredentials);
ComputeEngineCredentials otherExplicitUniverseCredentials =
ComputeEngineCredentials.newBuilder()
.setUniverseDomain(Credentials.GOOGLE_DEFAULT_UNIVERSE)
.setHttpTransportFactory(transportFactory)
.build();
- assertTrue(explicitUniverseCredentials.equals(otherExplicitUniverseCredentials));
- assertTrue(otherExplicitUniverseCredentials.equals(explicitUniverseCredentials));
+ assertEquals(explicitUniverseCredentials, otherExplicitUniverseCredentials);
+ assertEquals(otherExplicitUniverseCredentials, explicitUniverseCredentials);
}
@Test
- void equals_false_transportFactory() throws IOException {
+ void equals_false_transportFactory() {
MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
MockMetadataServerTransportFactory serverTransportFactory =
new MockMetadataServerTransportFactory();
@@ -486,12 +481,12 @@ void equals_false_transportFactory() throws IOException {
.build();
ComputeEngineCredentials otherCredentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(httpTransportFactory).build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
- void toString_explicit_containsFields() throws IOException {
+ void toString_explicit_containsFields() {
MockMetadataServerTransportFactory serverTransportFactory =
new MockMetadataServerTransportFactory();
String expectedToString =
@@ -513,7 +508,7 @@ void toString_explicit_containsFields() throws IOException {
}
@Test
- void hashCode_equals() throws IOException {
+ void hashCode_equals() {
MockMetadataServerTransportFactory serverTransportFactory =
new MockMetadataServerTransportFactory();
ComputeEngineCredentials credentials =
@@ -552,17 +547,17 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
credentials = ComputeEngineCredentials.newBuilder().build();
deserializedCredentials = serializeAndDeserialize(credentials);
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
}
@Test
- void getAccount_sameAs() throws IOException {
+ void getAccount_sameAs() {
MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
String defaultAccountEmail = "mail@mail.com";
@@ -603,14 +598,10 @@ public LowLevelHttpResponse execute() throws IOException {
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build();
- try {
- credentials.getAccount();
- fail("Fetching default service account should have failed");
- } catch (RuntimeException e) {
- assertEquals("Failed to get service account", e.getMessage());
- assertNotNull(e.getCause());
- assertTrue(e.getCause().getMessage().contains("404"));
- }
+ RuntimeException exception = assertThrows(RuntimeException.class, credentials::getAccount);
+ assertEquals("Failed to get service account", exception.getMessage());
+ assertNotNull(exception.getCause());
+ assertTrue(exception.getCause().getMessage().contains("404"));
}
@Test
@@ -638,14 +629,10 @@ public LowLevelHttpResponse execute() throws IOException {
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build();
- try {
- credentials.getAccount();
- fail("Fetching default service account should have failed");
- } catch (RuntimeException e) {
- assertEquals("Failed to get service account", e.getMessage());
- assertNotNull(e.getCause());
- assertTrue(e.getCause().getMessage().contains("Empty content"));
- }
+ RuntimeException exception = assertThrows(RuntimeException.class, credentials::getAccount);
+ assertEquals("Failed to get service account", exception.getMessage());
+ assertNotNull(exception.getCause());
+ assertTrue(exception.getCause().getMessage().contains("Empty content"));
}
@Test
@@ -793,9 +780,9 @@ public LowLevelHttpResponse execute() throws IOException {
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build();
- IOException exception = assertThrows(IOException.class, () -> credentials.refreshAccessToken());
+ IOException exception = assertThrows(IOException.class, credentials::refreshAccessToken);
assertTrue(exception.getCause().getMessage().contains("503"));
- assertTrue(exception instanceof GoogleAuthException);
+ assertInstanceOf(GoogleAuthException.class, exception);
assertTrue(((GoogleAuthException) exception).isRetryable());
}
@@ -803,7 +790,7 @@ public LowLevelHttpResponse execute() throws IOException {
void refresh_non503_ioexception_throws() {
MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
final Queue responseSequence = new ArrayDeque<>();
- IntStream.rangeClosed(400, 600).forEach(i -> responseSequence.add(i));
+ IntStream.rangeClosed(400, 600).forEach(responseSequence::add);
while (!responseSequence.isEmpty()) {
if (responseSequence.peek() == 503) {
@@ -829,8 +816,7 @@ public LowLevelHttpResponse execute() throws IOException {
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build();
- IOException exception =
- assertThrows(IOException.class, () -> credentials.refreshAccessToken());
+ IOException exception = assertThrows(IOException.class, credentials::refreshAccessToken);
assertFalse(exception instanceof GoogleAuthException);
}
}
@@ -859,7 +845,7 @@ public LowLevelHttpResponse execute() throws IOException {
String universeDomain = credentials.getUniverseDomain();
assertEquals("some-universe.xyz", universeDomain);
- assertEquals(false, credentials.isExplicitUniverseDomain());
+ assertFalse(credentials.isExplicitUniverseDomain());
}
@Test
@@ -886,7 +872,7 @@ public LowLevelHttpResponse execute() throws IOException {
String universeDomain = credentials.getUniverseDomain();
assertEquals(Credentials.GOOGLE_DEFAULT_UNIVERSE, universeDomain);
- assertEquals(false, credentials.isExplicitUniverseDomain());
+ assertFalse(credentials.isExplicitUniverseDomain());
}
@Test
@@ -913,7 +899,7 @@ public LowLevelHttpResponse execute() throws IOException {
String universeDomain = credentials.getUniverseDomain();
assertEquals(Credentials.GOOGLE_DEFAULT_UNIVERSE, universeDomain);
- assertEquals(false, credentials.isExplicitUniverseDomain());
+ assertFalse(credentials.isExplicitUniverseDomain());
}
@Test
@@ -929,7 +915,7 @@ void getUniverseDomain_explicitSet_NoMdsCall() throws IOException {
String universeDomain = credentials.getUniverseDomain();
assertEquals("explicit.universe", universeDomain);
- assertEquals(true, credentials.isExplicitUniverseDomain());
+ assertTrue(credentials.isExplicitUniverseDomain());
assertEquals(0, transportFactory.transport.getRequestCount());
}
@@ -946,14 +932,13 @@ void getUniverseDomain_explicitGduSet_NoMdsCall() throws IOException {
String universeDomain = credentials.getUniverseDomain();
assertEquals(Credentials.GOOGLE_DEFAULT_UNIVERSE, universeDomain);
- assertEquals(true, credentials.isExplicitUniverseDomain());
+ assertTrue(credentials.isExplicitUniverseDomain());
assertEquals(0, transportFactory.transport.getRequestCount());
}
@Test
- void getUniverseDomain_fromMetadata_non404error_throws() throws IOException {
+ void getUniverseDomain_fromMetadata_non404error_throws() {
MockMetadataServerTransportFactory transportFactory = new MockMetadataServerTransportFactory();
- MockMetadataServerTransport transport = transportFactory.transport;
ComputeEngineCredentials credentials =
ComputeEngineCredentials.newBuilder().setHttpTransportFactory(transportFactory).build();
@@ -963,13 +948,10 @@ void getUniverseDomain_fromMetadata_non404error_throws() throws IOException {
if (status == 404) {
continue;
}
- try {
- transportFactory.transport.setStatusCode(status);
- credentials.getUniverseDomain();
- fail("Should not be able to use credential without exception.");
- } catch (GoogleAuthException ex) {
- assertTrue(ex.isRetryable());
- }
+ transportFactory.transport.setStatusCode(status);
+ GoogleAuthException ex =
+ assertThrows(GoogleAuthException.class, credentials::getUniverseDomain);
+ assertTrue(ex.isRetryable());
}
}
@@ -985,7 +967,7 @@ public LowLevelHttpRequest buildRequest(String method, String url) throws IOExce
if (isSignRequestUrl(url)) {
return new MockLowLevelHttpRequest(url) {
@Override
- public LowLevelHttpResponse execute() throws IOException {
+ public LowLevelHttpResponse execute() {
return new MockLowLevelHttpResponse()
.setStatusCode(HttpStatusCodes.STATUS_CODE_OK);
}
@@ -1061,7 +1043,7 @@ void idTokenWithAudience_full() throws IOException {
IdTokenCredentials.newBuilder()
.setIdTokenProvider(credentials)
.setTargetAudience(targetAudience)
- .setOptions(Arrays.asList(IdTokenProvider.Option.FORMAT_FULL))
+ .setOptions(Collections.singletonList(IdTokenProvider.Option.FORMAT_FULL))
.build();
tokenCredential.refresh();
Payload p = tokenCredential.getIdToken().getJsonWebSignature().getPayload();
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CredentialAccessBoundaryTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CredentialAccessBoundaryTest.java
index 0dee7011e4ee..04abd3d9d23c 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CredentialAccessBoundaryTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/CredentialAccessBoundaryTest.java
@@ -33,7 +33,7 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.auth.oauth2.CredentialAccessBoundary.AccessBoundaryRule;
import com.google.auth.oauth2.CredentialAccessBoundary.AccessBoundaryRule.AvailabilityCondition;
@@ -90,22 +90,17 @@ void credentialAccessBoundary() {
@Test
void credentialAccessBoundary_nullRules_throws() {
- try {
- CredentialAccessBoundary.newBuilder().build();
- fail("Should fail.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ CredentialAccessBoundary.Builder builder = CredentialAccessBoundary.newBuilder();
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void credentialAccessBoundary_withoutRules_throws() {
- try {
- CredentialAccessBoundary.newBuilder().setRules(new ArrayList()).build();
- fail("Should fail.");
- } catch (IllegalArgumentException e) {
- assertEquals("At least one access boundary rule must be provided.", e.getMessage());
- }
+ CredentialAccessBoundary.Builder builder =
+ CredentialAccessBoundary.newBuilder().setRules(new ArrayList<>());
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals("At least one access boundary rule must be provided.", exception.getMessage());
}
@Test
@@ -121,12 +116,10 @@ void credentialAccessBoundary_ruleCountExceeded_throws() {
builder.addRule(rule);
}
- try {
- builder.build();
- fail("Should fail.");
- } catch (IllegalArgumentException e) {
- assertEquals("The provided list has more than 10 access boundary rules.", e.getMessage());
- }
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals(
+ "The provided list has more than 10 access boundary rules.", exception.getMessage());
}
@Test
@@ -204,74 +197,58 @@ void accessBoundaryRule_requiredFields() {
@Test
void accessBoundaryRule_withEmptyAvailableResource_throws() {
- try {
- AccessBoundaryRule.newBuilder()
- .setAvailableResource("")
- .addAvailablePermission("permission")
- .build();
- fail("Should fail.");
- } catch (IllegalArgumentException e) {
- assertEquals("The provided availableResource is empty.", e.getMessage());
- }
+ AccessBoundaryRule.Builder builder =
+ AccessBoundaryRule.newBuilder()
+ .setAvailableResource("")
+ .addAvailablePermission("permission");
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals("The provided availableResource is empty.", exception.getMessage());
}
@Test
void accessBoundaryRule_withoutAvailableResource_throws() {
- try {
- AccessBoundaryRule.newBuilder().addAvailablePermission("permission").build();
- fail("Should fail.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ AccessBoundaryRule.Builder builder =
+ AccessBoundaryRule.newBuilder().addAvailablePermission("permission");
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void accessBoundaryRule_withoutAvailablePermissions_throws() {
- try {
- AccessBoundaryRule.newBuilder().setAvailableResource("resource").build();
- fail("Should fail.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ AccessBoundaryRule.Builder builder =
+ AccessBoundaryRule.newBuilder().setAvailableResource("resource");
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void accessBoundaryRule_withEmptyAvailablePermissions_throws() {
- try {
- AccessBoundaryRule.newBuilder()
- .setAvailableResource("resource")
- .setAvailablePermissions(new ArrayList())
- .build();
- fail("Should fail.");
- } catch (IllegalArgumentException e) {
- assertEquals("The list of provided availablePermissions is empty.", e.getMessage());
- }
+ AccessBoundaryRule.Builder builder =
+ AccessBoundaryRule.newBuilder()
+ .setAvailableResource("resource")
+ .setAvailablePermissions(new ArrayList<>());
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals("The list of provided availablePermissions is empty.", exception.getMessage());
}
@Test
void accessBoundaryRule_withNullAvailablePermissions_throws() {
- try {
- AccessBoundaryRule.newBuilder()
- .setAvailableResource("resource")
- .addAvailablePermission(null)
- .build();
- fail("Should fail.");
- } catch (IllegalArgumentException e) {
- assertEquals("One of the provided available permissions is null.", e.getMessage());
- }
+ AccessBoundaryRule.Builder builder =
+ AccessBoundaryRule.newBuilder()
+ .setAvailableResource("resource")
+ .addAvailablePermission(null);
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals("One of the provided available permissions is null.", exception.getMessage());
}
@Test
void accessBoundaryRule_withEmptyAvailablePermission_throws() {
- try {
- AccessBoundaryRule.newBuilder()
- .setAvailableResource("resource")
- .addAvailablePermission("")
- .build();
- fail("Should fail.");
- } catch (IllegalArgumentException e) {
- assertEquals("One of the provided available permissions is empty.", e.getMessage());
- }
+ AccessBoundaryRule.Builder builder =
+ AccessBoundaryRule.newBuilder().setAvailableResource("resource").addAvailablePermission("");
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals("One of the provided available permissions is empty.", exception.getMessage());
}
@Test
@@ -300,21 +277,15 @@ void availabilityCondition_expressionOnly() {
@Test
void availabilityCondition_nullExpression_throws() {
- try {
- AvailabilityCondition.newBuilder().setExpression(null).build();
- fail("Should fail.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ AvailabilityCondition.Builder builder = AvailabilityCondition.newBuilder().setExpression(null);
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void availabilityCondition_emptyExpression_throws() {
- try {
- AvailabilityCondition.newBuilder().setExpression("").build();
- fail("Should fail.");
- } catch (IllegalArgumentException e) {
- assertEquals("The provided expression is empty.", e.getMessage());
- }
+ AvailabilityCondition.Builder builder = AvailabilityCondition.newBuilder().setExpression("");
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals("The provided expression is empty.", exception.getMessage());
}
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java
index 1852629ee6cb..d0447871b01a 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultCredentialsProviderTest.java
@@ -33,11 +33,13 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.LowLevelHttpRequest;
@@ -83,7 +85,7 @@ class DefaultCredentialsProviderTest {
private static final String SA_PRIVATE_KEY_ID = "d84a4fefcf50791d4a90f2d7af17469d6282df9d";
private static final String SA_PRIVATE_KEY_PKCS8 =
ServiceAccountCredentialsTest.PRIVATE_KEY_PKCS8;
- private static final String GDCH_SA_FORMAT_VERSION = GdchCredentials.SUPPORTED_FORMAT_VERSION;
+
private static final String GDCH_SA_PROJECT_ID = "gdch-service-account-project-id";
private static final String GDCH_SA_PRIVATE_KEY_ID = "d84a4fefcf50791d4a90f2d7af17469d6282df9d";
private static final String GDCH_SA_PRIVATE_KEY_PKC8 = GdchCredentialsTest.PRIVATE_KEY_PKCS8;
@@ -94,7 +96,7 @@ class DefaultCredentialsProviderTest {
private static final String GDCH_SA_CA_CERT_FILE_NAME = "cert.pem";
private static final String GDCH_SA_CA_CERT_PATH =
GdchCredentialsTest.class.getClassLoader().getResource(GDCH_SA_CA_CERT_FILE_NAME).getPath();
- private static final URI GDCH_SA_API_AUDIENCE = URI.create("https://gdch-api-audience");
+ private static final String GDCH_SA_API_AUDIENCE = "https://gdch-api-audience";
private static final Collection SCOPES = Collections.singletonList("dummy.scope");
private static final URI CALL_URI = URI.create("http://googleapis.com/testapi/v1/foo");
private static final String QUOTA_PROJECT = "sample-quota-project-id";
@@ -107,28 +109,22 @@ void getDefaultCredentials_noCredentials_throws() {
MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("No credential expected.");
- } catch (IOException e) {
- String message = e.getMessage();
- assertTrue(message.equals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS));
- }
+ IOException e =
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
+ String message = e.getMessage();
+ assertEquals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS, message);
}
@Test
void getDefaultCredentials_noCredentialsSandbox_throwsNonSecurity() {
MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- testProvider.setFileSandbox(true);
-
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("No credential expected.");
- } catch (IOException e) {
- String message = e.getMessage();
- assertTrue(message.equals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS));
- }
+ testProvider.setFileSandbox();
+
+ IOException e =
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
+ String message = e.getMessage();
+ assertEquals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS, message);
}
@Test
@@ -138,18 +134,15 @@ void getDefaultCredentials_envValidSandbox_throwsNonSecurity() throws Exception
UserCredentialsTest.writeUserStream(
USER_CLIENT_ID, USER_CLIENT_SECRET, REFRESH_TOKEN, QUOTA_PROJECT);
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- testProvider.setFileSandbox(true);
+ testProvider.setFileSandbox();
String userPath = tempFilePath("user.json");
testProvider.addFile(userPath, userStream);
testProvider.setEnv(DefaultCredentialsProvider.CREDENTIAL_ENV_VAR, userPath);
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("No credential expected.");
- } catch (IOException e) {
- String message = e.getMessage();
- assertTrue(message.equals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS));
- }
+ IOException e =
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
+ String message = e.getMessage();
+ assertEquals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS, message);
}
@Test
@@ -158,70 +151,47 @@ void getDefaultCredentials_noCredentials_singleGceTestRequest() {
new MockRequestCountingTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("No credential expected.");
- } catch (IOException expected) {
- String message = expected.getMessage();
- assertTrue(message.equals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS));
- }
+ IOException expected =
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
+ String message = expected.getMessage();
+ assertEquals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS, message);
assertEquals(
- transportFactory.transport.getRequestCount(),
- ComputeEngineCredentials.MAX_COMPUTE_PING_TRIES);
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("No credential expected.");
- } catch (IOException expected) {
- // Expected
- }
+ ComputeEngineCredentials.MAX_COMPUTE_PING_TRIES,
+ transportFactory.transport.getRequestCount());
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
assertEquals(
- transportFactory.transport.getRequestCount(),
- ComputeEngineCredentials.MAX_COMPUTE_PING_TRIES);
+ ComputeEngineCredentials.MAX_COMPUTE_PING_TRIES,
+ transportFactory.transport.getRequestCount());
}
@Test
- void getDefaultCredentials_noCredentials_linuxNotGce() throws IOException {
- TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- testProvider.setProperty("os.name", "Linux");
- String productFilePath = SMBIOS_PATH_LINUX;
- InputStream productStream = new ByteArrayInputStream("test".getBytes());
- testProvider.addFile(productFilePath, productStream);
-
- assertFalse(ComputeEngineCredentials.checkStaticGceDetection(testProvider));
+ void getDefaultCredentials_noCredentials_linuxNotGce() {
+ checkStaticGceDetection("linux", "test", false);
}
@Test
- void getDefaultCredentials_static_linux() throws IOException {
- TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- testProvider.setProperty("os.name", "Linux");
- String productFilePath = SMBIOS_PATH_LINUX;
- File productFile = new File(productFilePath);
- InputStream productStream = new ByteArrayInputStream("Googlekdjsfhg".getBytes());
- testProvider.addFile(productFile.getAbsolutePath(), productStream);
-
- assertTrue(ComputeEngineCredentials.checkStaticGceDetection(testProvider));
+ void getDefaultCredentials_static_linux() {
+ checkStaticGceDetection("linux", "Googlekdjsfhg", true);
}
@Test
- void getDefaultCredentials_static_windows_configuredAsLinux_notGce() throws IOException {
- TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- testProvider.setProperty("os.name", "windows");
- String productFilePath = SMBIOS_PATH_LINUX;
- InputStream productStream = new ByteArrayInputStream("Googlekdjsfhg".getBytes());
- testProvider.addFile(productFilePath, productStream);
-
- assertFalse(ComputeEngineCredentials.checkStaticGceDetection(testProvider));
+ void getDefaultCredentials_static_windows_configuredAsLinux_notGce() {
+ checkStaticGceDetection("windows", "Googlekdjsfhg", false);
}
@Test
- void getDefaultCredentials_static_unsupportedPlatform_notGce() throws IOException {
+ void getDefaultCredentials_static_unsupportedPlatform_notGce() {
+ checkStaticGceDetection("macos", "Googlekdjsfhg", false);
+ }
+
+ private void checkStaticGceDetection(String osName, String productContent, boolean expected) {
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- testProvider.setProperty("os.name", "macos");
+ testProvider.setProperty("os.name", osName);
String productFilePath = SMBIOS_PATH_LINUX;
- InputStream productStream = new ByteArrayInputStream("Googlekdjsfhg".getBytes());
+ InputStream productStream = new ByteArrayInputStream(productContent.getBytes());
testProvider.addFile(productFilePath, productStream);
- assertFalse(ComputeEngineCredentials.checkStaticGceDetection(testProvider));
+ assertEquals(expected, ComputeEngineCredentials.checkStaticGceDetection(testProvider));
}
@Test
@@ -253,49 +223,40 @@ void getDefaultCredentials_caches() throws IOException {
void getDefaultCredentials_appEngineClassWithoutRuntime_NotFoundError() {
MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- testProvider.addType(
- DefaultCredentialsProvider.APP_ENGINE_SIGNAL_CLASS, MockOffAppEngineSystemProperty.class);
+ testProvider.addType(MockOffAppEngineSystemProperty.class);
testProvider.setProperty("isOnGAEStandard7", "true");
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("No credential expected when not on App Engine.");
- } catch (IOException e) {
- String message = e.getMessage();
- assertTrue(message.equals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS));
- }
+ IOException e =
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
+ String message = e.getMessage();
+ assertEquals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS, message);
}
@Test
void getDefaultCredentials_appEngineRuntimeWithoutClass_throwsHelpfulLoadError() {
MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- testProvider.addType(
- DefaultCredentialsProvider.APP_ENGINE_SIGNAL_CLASS, MockAppEngineSystemProperty.class);
+ testProvider.addType(MockAppEngineSystemProperty.class);
testProvider.setProperty("isOnGAEStandard7", "true");
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("Credential expected to fail to load if credential class not present.");
- } catch (IOException e) {
- String message = e.getMessage();
- assertFalse(message.equals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS));
- assertTrue(message.contains("Check that the App Engine SDK is deployed."));
- }
+ IOException e =
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
+ String message = e.getMessage();
+ assertNotEquals(DefaultCredentialsProvider.CLOUDSDK_MISSING_CREDENTIALS, message);
+ assertTrue(message.contains("Check that the App Engine SDK is deployed."));
}
@Test
void getDefaultCredentials_appEngineSkipWorks_retrievesCloudShellCredential() throws IOException {
MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
- testProvider.addType(
- DefaultCredentialsProvider.APP_ENGINE_SIGNAL_CLASS, MockOffAppEngineSystemProperty.class);
+ testProvider.addType(MockOffAppEngineSystemProperty.class);
testProvider.setEnv(DefaultCredentialsProvider.CLOUD_SHELL_ENV_VAR, "9090");
testProvider.setEnv(DefaultCredentialsProvider.SKIP_APP_ENGINE_ENV_VAR, "true");
testProvider.setProperty("isOnGAEStanadard7", "true");
GoogleCredentials credentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(credentials);
- assertTrue(credentials instanceof CloudShellCredentials);
+ assertInstanceOf(CloudShellCredentials.class, credentials);
}
@Test
@@ -319,8 +280,8 @@ void getDefaultCredentials_cloudshell() throws IOException {
GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
- assertTrue(defaultCredentials instanceof CloudShellCredentials);
- assertEquals(((CloudShellCredentials) defaultCredentials).getAuthPort(), 4);
+ assertInstanceOf(CloudShellCredentials.class, defaultCredentials);
+ assertEquals(4, ((CloudShellCredentials) defaultCredentials).getAuthPort());
}
@Test
@@ -331,8 +292,8 @@ void getDefaultCredentials_cloudshell_withComputCredentialsPresent() throws IOEx
GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
- assertTrue(defaultCredentials instanceof CloudShellCredentials);
- assertEquals(((CloudShellCredentials) defaultCredentials).getAuthPort(), 4);
+ assertInstanceOf(CloudShellCredentials.class, defaultCredentials);
+ assertEquals(4, ((CloudShellCredentials) defaultCredentials).getAuthPort());
}
@Test
@@ -342,14 +303,11 @@ void getDefaultCredentials_envMissingFile_throws() {
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.setEnv(DefaultCredentialsProvider.CREDENTIAL_ENV_VAR, invalidPath);
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("Non existent credential should throw exception");
- } catch (IOException e) {
- String message = e.getMessage();
- assertTrue(message.contains(DefaultCredentialsProvider.CREDENTIAL_ENV_VAR));
- assertTrue(message.contains(invalidPath));
- }
+ IOException e =
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
+ String message = e.getMessage();
+ assertTrue(message.contains(DefaultCredentialsProvider.CREDENTIAL_ENV_VAR));
+ assertTrue(message.contains(invalidPath));
}
@Test
@@ -382,7 +340,7 @@ void getDefaultCredentials_envUser_providesToken() throws IOException {
testProvider.addFile(userPath, userStream);
testProvider.setEnv(DefaultCredentialsProvider.CREDENTIAL_ENV_VAR, userPath);
- testUserProvidesToken(testProvider, USER_CLIENT_ID, USER_CLIENT_SECRET, REFRESH_TOKEN);
+ testUserProvidesToken(testProvider, USER_CLIENT_ID);
}
@Test
@@ -390,7 +348,7 @@ void getDefaultCredentials_GdchServiceAccount() throws IOException {
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
- GDCH_SA_FORMAT_VERSION,
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION,
GDCH_SA_PROJECT_ID,
GDCH_SA_PRIVATE_KEY_ID,
GDCH_SA_PRIVATE_KEY_PKC8,
@@ -405,7 +363,7 @@ void getDefaultCredentials_GdchServiceAccount() throws IOException {
GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(defaultCredentials);
- assertTrue(defaultCredentials instanceof GdchCredentials);
+ assertInstanceOf(GdchCredentials.class, defaultCredentials);
assertEquals(GDCH_SA_PROJECT_ID, defaultCredentials.getProjectId());
assertEquals(
GDCH_SA_SERVICE_IDENTITY_NAME,
@@ -418,7 +376,7 @@ void getDefaultCredentials_GdchServiceAccount() throws IOException {
defaultCredentials =
((GdchCredentials) defaultCredentials).createWithGdchAudience(GDCH_SA_API_AUDIENCE);
assertNotNull(defaultCredentials);
- assertTrue(defaultCredentials instanceof GdchCredentials);
+ assertInstanceOf(GdchCredentials.class, defaultCredentials);
assertEquals(GDCH_SA_PROJECT_ID, defaultCredentials.getProjectId());
assertEquals(
GDCH_SA_SERVICE_IDENTITY_NAME,
@@ -451,7 +409,7 @@ void getDefaultCredentials_quota_project() throws IOException {
credentials = credentials.toBuilder().setQuotaProjectId(QUOTA_PROJECT_EXPLICIT).build();
assertEquals(QUOTA_PROJECT_EXPLICIT, credentials.getQuotaProjectId());
- testUserProvidesToken(testProvider, USER_CLIENT_ID, USER_CLIENT_SECRET, REFRESH_TOKEN);
+ testUserProvidesToken(testProvider, USER_CLIENT_ID);
}
@Test
@@ -463,7 +421,7 @@ void getDefaultCredentials_compute_quotaProject() throws IOException {
GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
- assertTrue(defaultCredentials instanceof ComputeEngineCredentials);
+ assertInstanceOf(ComputeEngineCredentials.class, defaultCredentials);
assertEquals(QUOTA_PROJECT_FROM_ENVIRONMENT, defaultCredentials.getQuotaProjectId());
// verify metrics header
@@ -482,44 +440,33 @@ void getDefaultCredentials_cloudshell_quotaProject() throws IOException {
GoogleCredentials defaultCredentials = testProvider.getDefaultCredentials(transportFactory);
- assertTrue(defaultCredentials instanceof CloudShellCredentials);
+ assertInstanceOf(CloudShellCredentials.class, defaultCredentials);
assertEquals(QUOTA_PROJECT_FROM_ENVIRONMENT, defaultCredentials.getQuotaProjectId());
}
@Test
- void getDefaultCredentials_envNoGceCheck_noGceRequest() throws IOException {
+ void getDefaultCredentials_envNoGceCheck_noGceRequest() {
MockRequestCountingTransportFactory transportFactory =
new MockRequestCountingTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.setEnv(DefaultCredentialsProvider.NO_GCE_CHECK_ENV_VAR, "true");
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("No credential expected.");
- } catch (IOException expected) {
- // Expected
- }
- assertEquals(transportFactory.transport.getRequestCount(), 0);
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
+ assertEquals(0, transportFactory.transport.getRequestCount());
}
@Test
- void getDefaultCredentials_linuxSetup_envNoGceCheck_noGce() throws IOException {
+ void getDefaultCredentials_linuxSetup_envNoGceCheck_noGce() {
MockRequestCountingTransportFactory transportFactory =
new MockRequestCountingTransportFactory();
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.setEnv(DefaultCredentialsProvider.NO_GCE_CHECK_ENV_VAR, "true");
testProvider.setProperty("os.name", "Linux");
- String productFilePath = SMBIOS_PATH_LINUX;
- File productFile = new File(productFilePath);
+ File productFile = new File(SMBIOS_PATH_LINUX);
InputStream productStream = new ByteArrayInputStream("Googlekdjsfhg".getBytes());
testProvider.addFile(productFile.getAbsolutePath(), productStream);
- try {
- testProvider.getDefaultCredentials(transportFactory);
- fail("No credential expected.");
- } catch (IOException expected) {
- // Expected
- }
- assertEquals(transportFactory.transport.getRequestCount(), 0);
+ assertThrows(IOException.class, () -> testProvider.getDefaultCredentials(transportFactory));
+ assertEquals(0, transportFactory.transport.getRequestCount());
}
@Test
@@ -527,7 +474,7 @@ void getDefaultCredentials_envGceMetadataHost_setsMetadataServerUrl() {
String testUrl = "192.0.2.0";
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.setEnv(DefaultCredentialsProvider.GCE_METADATA_HOST_ENV_VAR, testUrl);
- assertEquals(ComputeEngineCredentials.getMetadataServerUrl(testProvider), "http://" + testUrl);
+ assertEquals("http://" + testUrl, ComputeEngineCredentials.getMetadataServerUrl(testProvider));
}
@Test
@@ -536,8 +483,8 @@ void getDefaultCredentials_envGceMetadataHost_setsTokenServerUrl() {
TestDefaultCredentialsProvider testProvider = new TestDefaultCredentialsProvider();
testProvider.setEnv(DefaultCredentialsProvider.GCE_METADATA_HOST_ENV_VAR, testUrl);
assertEquals(
- ComputeEngineCredentials.getTokenServerEncodedUrl(testProvider),
- "http://" + testUrl + "/computeMetadata/v1/instance/service-accounts/default/token");
+ "http://" + testUrl + "/computeMetadata/v1/instance/service-accounts/default/token",
+ ComputeEngineCredentials.getTokenServerEncodedUrl(testProvider));
}
@Test
@@ -552,7 +499,7 @@ void getDefaultCredentials_wellKnownFileEnv_providesToken() throws IOException {
testProvider.setEnv("CLOUDSDK_CONFIG", cloudConfigDir.getAbsolutePath());
testProvider.addFile(wellKnownFile.getAbsolutePath(), userStream);
- testUserProvidesToken(testProvider, USER_CLIENT_ID, USER_CLIENT_SECRET, REFRESH_TOKEN);
+ testUserProvidesToken(testProvider, USER_CLIENT_ID);
}
@Test
@@ -570,7 +517,7 @@ void getDefaultCredentials_wellKnownFileNonWindows_providesToken() throws IOExce
testProvider.setProperty("user.home", homeDir.getAbsolutePath());
testProvider.addFile(wellKnownFile.getAbsolutePath(), userStream);
- testUserProvidesToken(testProvider, USER_CLIENT_ID, USER_CLIENT_SECRET, REFRESH_TOKEN);
+ testUserProvidesToken(testProvider, USER_CLIENT_ID);
}
@Test
@@ -587,7 +534,7 @@ void getDefaultCredentials_wellKnownFileWindows_providesToken() throws IOExcepti
testProvider.setEnv("APPDATA", homeDir.getAbsolutePath());
testProvider.addFile(wellKnownFile.getAbsolutePath(), userStream);
- testUserProvidesToken(testProvider, USER_CLIENT_ID, USER_CLIENT_SECRET, REFRESH_TOKEN);
+ testUserProvidesToken(testProvider, USER_CLIENT_ID);
}
@Test
@@ -629,12 +576,12 @@ private String tempFilePath(String filename) {
return Paths.get(System.getProperty("java.io.tmpdir"), filename).toString();
}
- private class LogHandler extends Handler {
+ private static class LogHandler extends Handler {
LogRecord lastRecord;
@Override
- public void publish(LogRecord record) {
- lastRecord = record;
+ public void publish(LogRecord logRecord) {
+ this.lastRecord = logRecord;
}
public LogRecord getRecord() {
@@ -642,10 +589,14 @@ public LogRecord getRecord() {
}
@Override
- public void close() {}
+ public void close() {
+ // Test implementation. Nothing to close
+ }
@Override
- public void flush() {}
+ public void flush() {
+ // Test implementation. Nothing to flush
+ }
}
@Test
@@ -653,8 +604,7 @@ void getDefaultCredentials_wellKnownFile_logsGcloudWarning() throws IOException
LogRecord message = getCredentialsAndReturnLogMessage(false, true);
assertNotNull(message);
assertEquals(Level.WARNING, message.getLevel());
- assertTrue(
- message.getMessage().equals(DefaultCredentialsProvider.CLOUDSDK_CREDENTIALS_WARNING));
+ assertEquals(DefaultCredentialsProvider.CLOUDSDK_CREDENTIALS_WARNING, message.getMessage());
}
@Test
@@ -690,13 +640,12 @@ private LogRecord getCredentialsAndReturnLogMessage(boolean suppressWarning, boo
testProvider.setProperty("os.name", "linux");
testProvider.setProperty("user.home", homeDir.getAbsolutePath());
if (isGce) {
- String productFilePath = SMBIOS_PATH_LINUX;
- File productFile = new File(productFilePath);
+ File productFile = new File(SMBIOS_PATH_LINUX);
InputStream productStream = new ByteArrayInputStream("Googlekdjsfhg".getBytes());
testProvider.addFile(productFile.getAbsolutePath(), productStream);
}
testProvider.addFile(wellKnownFile.getAbsolutePath(), userStream);
- testUserProvidesToken(testProvider, GCLOUDSDK_CLIENT_ID, USER_CLIENT_SECRET, REFRESH_TOKEN);
+ testUserProvidesToken(testProvider, GCLOUDSDK_CLIENT_ID);
return handler.getRecord();
}
@@ -704,15 +653,13 @@ private static File getTempDirectory() {
return new File(System.getProperty("java.io.tmpdir"));
}
- private void testUserProvidesToken(
- TestDefaultCredentialsProvider testProvider,
- String clientId,
- String clientSecret,
- String refreshToken)
+ private void testUserProvidesToken(TestDefaultCredentialsProvider testProvider, String clientId)
throws IOException {
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
- transportFactory.transport.addClient(clientId, clientSecret);
- transportFactory.transport.addRefreshToken(refreshToken, ACCESS_TOKEN);
+ transportFactory.transport.addClient(
+ clientId, DefaultCredentialsProviderTest.USER_CLIENT_SECRET);
+ transportFactory.transport.addRefreshToken(
+ DefaultCredentialsProviderTest.REFRESH_TOKEN, ACCESS_TOKEN);
testUserProvidesToken(testProvider, transportFactory, ACCESS_TOKEN);
}
@@ -755,7 +702,7 @@ void getDefaultCredentials_envVarSet_serviceAccountCredentials_correctCredential
GoogleCredentials credentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(credentials);
- assertTrue(credentials instanceof ServiceAccountCredentials);
+ assertInstanceOf(ServiceAccountCredentials.class, credentials);
Map credentialInfo = credentials.getCredentialInfo();
assertEquals(
String.format(
@@ -780,7 +727,7 @@ void getDefaultCredentials_envVarSet_userCredential_correctCredentialInfo() thro
GoogleCredentials credentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(credentials);
- assertTrue(credentials instanceof UserCredentials);
+ assertInstanceOf(UserCredentials.class, credentials);
Map credentialInfo = credentials.getCredentialInfo();
assertEquals(
String.format(
@@ -808,7 +755,7 @@ void getDefaultCredentials_wellKnownFile_userCredential_correctCredentialInfo()
GoogleCredentials credentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(credentials);
- assertTrue(credentials instanceof UserCredentials);
+ assertInstanceOf(UserCredentials.class, credentials);
Map credentialInfo = credentials.getCredentialInfo();
assertEquals(
String.format("Well Known File at %s", wellKnownFile.getCanonicalPath()),
@@ -827,7 +774,7 @@ void getDefaultCredentials_computeEngineCredentials_defaultMDSUrl_correctCredent
GoogleCredentials credentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(credentials);
- assertTrue(credentials instanceof ComputeEngineCredentials);
+ assertInstanceOf(ComputeEngineCredentials.class, credentials);
Map credentialInfo = credentials.getCredentialInfo();
assertEquals(
String.format(
@@ -849,7 +796,7 @@ void getDefaultCredentials_computeEngineCredentials_customMDSUrl_correctCredenti
GoogleCredentials credentials = testProvider.getDefaultCredentials(transportFactory);
assertNotNull(credentials);
- assertTrue(credentials instanceof ComputeEngineCredentials);
+ assertInstanceOf(ComputeEngineCredentials.class, credentials);
Map credentialInfo = credentials.getCredentialInfo();
assertEquals(
String.format("Metadata Server URL set to http://%s", gceMetadataHost),
@@ -868,7 +815,7 @@ private static class MockAppEngineSystemProperty {
@SuppressWarnings("unused")
public static final MockEnvironment environment =
- new MockEnvironment(MockEnvironmentEnum.Production);
+ new MockEnvironment(MockEnvironmentEnum.PRODUCTION);
}
private static class MockOffAppEngineSystemProperty {
@@ -878,13 +825,13 @@ private static class MockOffAppEngineSystemProperty {
}
private enum MockEnvironmentEnum {
- Production,
- Development;
+ PRODUCTION,
+ DEVELOPMENT;
}
public static class MockEnvironment {
- private MockEnvironmentEnum innerValue;
+ private final MockEnvironmentEnum innerValue;
MockEnvironment(MockEnvironmentEnum value) {
this.innerValue = value;
@@ -934,8 +881,8 @@ void addFile(String file, InputStream stream) {
files.put(file, stream);
}
- void addType(String className, Class> type) {
- types.put(className, type);
+ void addType(Class> type) {
+ types.put(DefaultCredentialsProvider.APP_ENGINE_SIGNAL_CLASS, type);
}
@Override
@@ -991,8 +938,8 @@ InputStream readStream(File file) throws FileNotFoundException {
return stream;
}
- void setFileSandbox(boolean fileSandbox) {
- this.fileSandbox = fileSandbox;
+ void setFileSandbox() {
+ this.fileSandbox = true;
}
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultPKCEProviderTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultPKCEProviderTest.java
index 114e27298b3f..34e9be380841 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultPKCEProviderTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DefaultPKCEProviderTest.java
@@ -54,11 +54,11 @@ void testPkceExpected() throws NoSuchAlgorithmException {
String expectedCodeChallengeMethod = "S256";
assertEquals(pkce.getCodeChallenge(), expectedCodeChallenge);
- assertEquals(pkce.getCodeChallengeMethod(), expectedCodeChallengeMethod);
+ assertEquals(expectedCodeChallengeMethod, pkce.getCodeChallengeMethod());
}
@Test
- void testNoBase64Padding() throws NoSuchAlgorithmException {
+ void testNoBase64Padding() {
PKCEProvider pkce = new DefaultPKCEProvider();
assertFalse(pkce.getCodeChallenge().endsWith("="));
assertFalse(pkce.getCodeChallenge().contains("="));
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DownscopedCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DownscopedCredentialsTest.java
index 31c4e776e3f8..34a52b4154fb 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DownscopedCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/DownscopedCredentialsTest.java
@@ -35,7 +35,7 @@
import static com.google.auth.oauth2.OAuth2Utils.TOKEN_EXCHANGE_URL_FORMAT;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.api.client.http.HttpTransport;
import com.google.auth.TestUtils;
@@ -188,38 +188,25 @@ void refreshAccessToken_cantRefreshSourceCredentials_throws() throws IOException
.setHttpTransportFactory(transportFactory)
.build();
- try {
- downscopedCredentials.refreshAccessToken();
- fail("Should fail as the source credential should not be able to be refreshed.");
- } catch (IOException e) {
- assertEquals("Unable to refresh the provided source credential.", e.getMessage());
- }
+ IOException e = assertThrows(IOException.class, downscopedCredentials::refreshAccessToken);
+ assertEquals("Unable to refresh the provided source credential.", e.getMessage());
}
@Test
void builder_noSourceCredential_throws() {
- try {
- DownscopedCredentials.newBuilder()
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setCredentialAccessBoundary(CREDENTIAL_ACCESS_BOUNDARY)
- .build();
- fail("Should fail as the source credential is null.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ DownscopedCredentials.Builder builder =
+ DownscopedCredentials.newBuilder()
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY);
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void builder_noCredentialAccessBoundary_throws() throws IOException {
- try {
- DownscopedCredentials.newBuilder()
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setSourceCredential(getServiceAccountSourceCredentials(/* canRefresh= */ true))
- .build();
- fail("Should fail as no access boundary was provided.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ DownscopedCredentials.Builder builder =
+ DownscopedCredentials.newBuilder()
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setSourceCredential(getServiceAccountSourceCredentials(/* canRefresh= */ true));
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
@@ -263,37 +250,31 @@ void builder_universeDomainMismatch_throws() throws IOException {
GoogleCredentials sourceCredentials =
getServiceAccountSourceCredentials(/* canRefresh= */ true);
- try {
- DownscopedCredentials.newBuilder()
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setSourceCredential(sourceCredentials)
- .setCredentialAccessBoundary(CREDENTIAL_ACCESS_BOUNDARY)
- .setUniverseDomain("differentUniverseDomain")
- .build();
- fail("Should fail with universe domain mismatch.");
- } catch (IllegalArgumentException e) {
- assertEquals(
- "The downscoped credential's universe domain must be the same as the source credential.",
- e.getMessage());
- }
+ DownscopedCredentials.Builder builder =
+ DownscopedCredentials.newBuilder()
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setSourceCredential(sourceCredentials)
+ .setCredentialAccessBoundary(CREDENTIAL_ACCESS_BOUNDARY)
+ .setUniverseDomain("differentUniverseDomain");
+ IllegalArgumentException e = assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals(
+ "The downscoped credential's universe domain must be the same as the source credential.",
+ e.getMessage());
}
@Test
- void builder_sourceUniverseDomainUnavailable_throws() throws IOException {
+ void builder_sourceUniverseDomainUnavailable_throws() {
GoogleCredentials sourceCredentials = new MockSourceCredentialWithoutUniverseDomain();
- try {
- DownscopedCredentials.newBuilder()
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setSourceCredential(sourceCredentials)
- .setCredentialAccessBoundary(CREDENTIAL_ACCESS_BOUNDARY)
- .build();
- fail("Should fail to retrieve source credential universe domain.");
- } catch (IllegalStateException e) {
- assertEquals(
- "Error occurred when attempting to retrieve source credential universe domain.",
- e.getMessage());
- }
+ DownscopedCredentials.Builder builder =
+ DownscopedCredentials.newBuilder()
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setSourceCredential(sourceCredentials)
+ .setCredentialAccessBoundary(CREDENTIAL_ACCESS_BOUNDARY);
+ IllegalStateException e = assertThrows(IllegalStateException.class, builder::build);
+ assertEquals(
+ "Error occurred when attempting to retrieve source credential universe domain.",
+ e.getMessage());
}
private static GoogleCredentials getServiceAccountSourceCredentials(boolean canRefresh)
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExecutableResponseTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExecutableResponseTest.java
index da7ea8cc6e5b..d9923e968a16 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExecutableResponseTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExecutableResponseTest.java
@@ -34,8 +34,8 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.json.GenericJson;
import java.io.IOException;
@@ -128,129 +128,107 @@ void constructor_validErrorResponse() throws IOException {
}
@Test
- void constructor_errorResponseMissingCode_throws() throws IOException {
+ void constructor_errorResponseMissingCode_throws() {
GenericJson jsonResponse = buildErrorResponse();
Object[] values = new Object[] {null, ""};
for (Object value : values) {
jsonResponse.put("code", value);
- try {
- new ExecutableResponse(jsonResponse);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException exception) {
- assertEquals(
- "Error code INVALID_EXECUTABLE_RESPONSE: The executable response must contain "
- + "`error` and `message` fields when unsuccessful.",
- exception.getMessage());
- }
+ PluggableAuthException exception =
+ assertThrows(PluggableAuthException.class, () -> new ExecutableResponse(jsonResponse));
+ assertEquals(
+ "Error code INVALID_EXECUTABLE_RESPONSE: The executable response must contain "
+ + "`error` and `message` fields when unsuccessful.",
+ exception.getMessage());
}
}
@Test
- void constructor_errorResponseMissingMessage_throws() throws IOException {
+ void constructor_errorResponseMissingMessage_throws() {
GenericJson jsonResponse = buildErrorResponse();
Object[] values = new Object[] {null, ""};
for (Object value : values) {
jsonResponse.put("message", value);
- try {
- new ExecutableResponse(jsonResponse);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException exception) {
- assertEquals(
- "Error code INVALID_EXECUTABLE_RESPONSE: The executable response must contain "
- + "`error` and `message` fields when unsuccessful.",
- exception.getMessage());
- }
+ PluggableAuthException exception =
+ assertThrows(PluggableAuthException.class, () -> new ExecutableResponse(jsonResponse));
+ assertEquals(
+ "Error code INVALID_EXECUTABLE_RESPONSE: The executable response must contain "
+ + "`error` and `message` fields when unsuccessful.",
+ exception.getMessage());
}
}
@Test
- void constructor_successResponseMissingVersionField_throws() throws IOException {
+ void constructor_successResponseMissingVersionField_throws() {
GenericJson jsonResponse = buildOidcResponse();
jsonResponse.remove("version");
- try {
- new ExecutableResponse(jsonResponse);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException exception) {
- assertEquals(
- "Error code INVALID_EXECUTABLE_RESPONSE: The executable response is missing the "
- + "`version` field.",
- exception.getMessage());
- }
+ PluggableAuthException exception =
+ assertThrows(PluggableAuthException.class, () -> new ExecutableResponse(jsonResponse));
+ assertEquals(
+ "Error code INVALID_EXECUTABLE_RESPONSE: The executable response is missing the "
+ + "`version` field.",
+ exception.getMessage());
}
@Test
- void constructor_successResponseMissingSuccessField_throws() throws Exception {
+ void constructor_successResponseMissingSuccessField_throws() {
GenericJson jsonResponse = buildOidcResponse();
jsonResponse.remove("success");
- try {
- new ExecutableResponse(jsonResponse);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException exception) {
- assertEquals(
- "Error code INVALID_EXECUTABLE_RESPONSE: The executable response is missing the "
- + "`success` field.",
- exception.getMessage());
- }
+ PluggableAuthException exception =
+ assertThrows(PluggableAuthException.class, () -> new ExecutableResponse(jsonResponse));
+ assertEquals(
+ "Error code INVALID_EXECUTABLE_RESPONSE: The executable response is missing the "
+ + "`success` field.",
+ exception.getMessage());
}
@Test
- void constructor_successResponseMissingTokenTypeField_throws() throws IOException {
+ void constructor_successResponseMissingTokenTypeField_throws() {
GenericJson jsonResponse = buildOidcResponse();
jsonResponse.remove("token_type");
- try {
- new ExecutableResponse(jsonResponse);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException exception) {
- assertEquals(
- "Error code INVALID_EXECUTABLE_RESPONSE: The executable response is missing the "
- + "`token_type` field.",
- exception.getMessage());
- }
+ PluggableAuthException exception =
+ assertThrows(PluggableAuthException.class, () -> new ExecutableResponse(jsonResponse));
+ assertEquals(
+ "Error code INVALID_EXECUTABLE_RESPONSE: The executable response is missing the "
+ + "`token_type` field.",
+ exception.getMessage());
}
@Test
- void constructor_samlResponseMissingSubjectToken_throws() throws IOException {
+ void constructor_samlResponseMissingSubjectToken_throws() {
GenericJson jsonResponse = buildSamlResponse();
Object[] values = new Object[] {null, ""};
for (Object value : values) {
jsonResponse.put("saml_response", value);
-
- try {
- new ExecutableResponse(jsonResponse);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException exception) {
- assertEquals(
- "Error code INVALID_EXECUTABLE_RESPONSE: The executable response does not "
- + "contain a valid token.",
- exception.getMessage());
- }
+ PluggableAuthException exception =
+ assertThrows(PluggableAuthException.class, () -> new ExecutableResponse(jsonResponse));
+ assertEquals(
+ "Error code INVALID_EXECUTABLE_RESPONSE: The executable response does not "
+ + "contain a valid token.",
+ exception.getMessage());
}
}
@Test
- void constructor_oidcResponseMissingSubjectToken_throws() throws IOException {
+ void constructor_oidcResponseMissingSubjectToken_throws() {
GenericJson jsonResponse = buildOidcResponse();
Object[] values = new Object[] {null, ""};
for (Object value : values) {
jsonResponse.put("id_token", value);
- try {
- new ExecutableResponse(jsonResponse);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException exception) {
- assertEquals(
- "Error code INVALID_EXECUTABLE_RESPONSE: The executable response does not "
- + "contain a valid token.",
- exception.getMessage());
- }
+ PluggableAuthException exception =
+ assertThrows(PluggableAuthException.class, () -> new ExecutableResponse(jsonResponse));
+ assertEquals(
+ "Error code INVALID_EXECUTABLE_RESPONSE: The executable response does not "
+ + "contain a valid token.",
+ exception.getMessage());
}
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentialsTest.java
index 4913e5aec53e..78bb6811953e 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExternalAccountAuthorizedUserCredentialsTest.java
@@ -39,7 +39,6 @@
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.GenericJson;
@@ -51,12 +50,12 @@
import com.google.auth.oauth2.GoogleCredentials.GoogleCredentialsInfo;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
-import com.google.common.io.BaseEncoding;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
+import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
@@ -84,8 +83,8 @@ class ExternalAccountAuthorizedUserCredentialsTest extends BaseSerializationTest
private static final String BASIC_AUTH =
String.format(
"Basic %s",
- BaseEncoding.base64()
- .encode(
+ Base64.getEncoder()
+ .encodeToString(
String.format("%s:%s", CLIENT_ID, CLIENT_SECRET)
.getBytes(StandardCharsets.UTF_8)));
@@ -246,70 +245,59 @@ void builder_accessTokenWithMissingRefreshFields() {
@Test
void builder_accessAndRefreshTokenNull_throws() {
- try {
- ExternalAccountAuthorizedUserCredentials.newBuilder().build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
- assertEquals(
- "ExternalAccountAuthorizedUserCredentials must be initialized with "
- + "an access token or fields to enable refresh: "
- + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
- exception.getMessage());
- }
+ ExternalAccountAuthorizedUserCredentials.Builder builder =
+ ExternalAccountAuthorizedUserCredentials.newBuilder();
+ IllegalStateException exception = assertThrows(IllegalStateException.class, builder::build);
+ assertEquals(
+ "ExternalAccountAuthorizedUserCredentials must be initialized with "
+ + "an access token or fields to enable refresh: "
+ + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
+ exception.getMessage());
}
@Test
void builder_missingTokenUrl_throws() {
- try {
- ExternalAccountAuthorizedUserCredentials.newBuilder()
- .setRefreshToken(REFRESH_TOKEN)
- .setClientId(CLIENT_ID)
- .setClientSecret(CLIENT_SECRET)
- .build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
- assertEquals(
- "ExternalAccountAuthorizedUserCredentials must be initialized with "
- + "an access token or fields to enable refresh: "
- + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
- exception.getMessage());
- }
+ ExternalAccountAuthorizedUserCredentials.Builder builder =
+ ExternalAccountAuthorizedUserCredentials.newBuilder()
+ .setRefreshToken(REFRESH_TOKEN)
+ .setClientId(CLIENT_ID)
+ .setClientSecret(CLIENT_SECRET);
+ IllegalStateException exception = assertThrows(IllegalStateException.class, builder::build);
+ assertEquals(
+ "ExternalAccountAuthorizedUserCredentials must be initialized with "
+ + "an access token or fields to enable refresh: "
+ + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
+ exception.getMessage());
}
@Test
void builder_missingClientId_throws() {
- try {
- ExternalAccountAuthorizedUserCredentials.newBuilder()
- .setRefreshToken(REFRESH_TOKEN)
- .setTokenUrl(TOKEN_URL)
- .setClientSecret(CLIENT_SECRET)
- .build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
- assertEquals(
- "ExternalAccountAuthorizedUserCredentials must be initialized with "
- + "an access token or fields to enable refresh: "
- + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
- exception.getMessage());
- }
+ ExternalAccountAuthorizedUserCredentials.Builder builder =
+ ExternalAccountAuthorizedUserCredentials.newBuilder()
+ .setRefreshToken(REFRESH_TOKEN)
+ .setTokenUrl(TOKEN_URL)
+ .setClientSecret(CLIENT_SECRET);
+ IllegalStateException exception = assertThrows(IllegalStateException.class, builder::build);
+ assertEquals(
+ "ExternalAccountAuthorizedUserCredentials must be initialized with "
+ + "an access token or fields to enable refresh: "
+ + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
+ exception.getMessage());
}
@Test
void builder_missingClientSecret_throws() {
- try {
- ExternalAccountAuthorizedUserCredentials.newBuilder()
- .setRefreshToken(REFRESH_TOKEN)
- .setTokenUrl(TOKEN_URL)
- .setClientId(CLIENT_ID)
- .build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
- assertEquals(
- "ExternalAccountAuthorizedUserCredentials must be initialized with "
- + "an access token or fields to enable refresh: "
- + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
- exception.getMessage());
- }
+ ExternalAccountAuthorizedUserCredentials.Builder builder =
+ ExternalAccountAuthorizedUserCredentials.newBuilder()
+ .setRefreshToken(REFRESH_TOKEN)
+ .setTokenUrl(TOKEN_URL)
+ .setClientId(CLIENT_ID);
+ IllegalStateException exception = assertThrows(IllegalStateException.class, builder::build);
+ assertEquals(
+ "ExternalAccountAuthorizedUserCredentials must be initialized with "
+ + "an access token or fields to enable refresh: "
+ + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
+ exception.getMessage());
}
@Test
@@ -421,84 +409,89 @@ void fromJson_minimumRequiredFieldsForRefresh() throws IOException {
}
@Test
- void fromJson_accessTokenOnly_notSupported() throws IOException {
+ void fromJson_accessTokenOnly_notSupported() {
GenericJson json = new GenericJson();
json.put("access_token", ACCESS_TOKEN);
- try {
- ExternalAccountAuthorizedUserCredentials.fromJson(json, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
- assertEquals(
- "ExternalAccountAuthorizedUserCredentials must be initialized with "
- + "an access token or fields to enable refresh: "
- + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
- exception.getMessage());
- }
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () ->
+ ExternalAccountAuthorizedUserCredentials.fromJson(
+ json, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
+ assertEquals(
+ "ExternalAccountAuthorizedUserCredentials must be initialized with "
+ + "an access token or fields to enable refresh: "
+ + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
+ exception.getMessage());
}
@Test
- void fromJson_missingRefreshToken_throws() throws IOException {
- try {
- GenericJson json = buildJsonCredentials();
- json.remove("refresh_token");
- ExternalAccountAuthorizedUserCredentials.fromJson(json, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
- assertEquals(
- "ExternalAccountAuthorizedUserCredentials must be initialized with "
- + "an access token or fields to enable refresh: "
- + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
- exception.getMessage());
- }
+ void fromJson_missingRefreshToken_throws() {
+ GenericJson json = buildJsonCredentials();
+ json.remove("refresh_token");
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () ->
+ ExternalAccountAuthorizedUserCredentials.fromJson(
+ json, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
+ assertEquals(
+ "ExternalAccountAuthorizedUserCredentials must be initialized with "
+ + "an access token or fields to enable refresh: "
+ + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
+ exception.getMessage());
}
@Test
- void fromJson_missingTokenUrl_throws() throws IOException {
- try {
- GenericJson json = buildJsonCredentials();
- json.remove("token_url");
- ExternalAccountAuthorizedUserCredentials.fromJson(json, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
- assertEquals(
- "ExternalAccountAuthorizedUserCredentials must be initialized with "
- + "an access token or fields to enable refresh: "
- + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
- exception.getMessage());
- }
+ void fromJson_missingTokenUrl_throws() {
+ GenericJson json = buildJsonCredentials();
+ json.remove("token_url");
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () ->
+ ExternalAccountAuthorizedUserCredentials.fromJson(
+ json, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
+ assertEquals(
+ "ExternalAccountAuthorizedUserCredentials must be initialized with "
+ + "an access token or fields to enable refresh: "
+ + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
+ exception.getMessage());
}
@Test
- void fromJson_missingClientId_throws() throws IOException {
- try {
- GenericJson json = buildJsonCredentials();
- json.remove("client_id");
- ExternalAccountAuthorizedUserCredentials.fromJson(json, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
- assertEquals(
- "ExternalAccountAuthorizedUserCredentials must be initialized with "
- + "an access token or fields to enable refresh: "
- + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
- exception.getMessage());
- }
+ void fromJson_missingClientId_throws() {
+ GenericJson json = buildJsonCredentials();
+ json.remove("client_id");
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () ->
+ ExternalAccountAuthorizedUserCredentials.fromJson(
+ json, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
+ assertEquals(
+ "ExternalAccountAuthorizedUserCredentials must be initialized with "
+ + "an access token or fields to enable refresh: "
+ + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
+ exception.getMessage());
}
@Test
- void fromJson_missingClientSecret_throws() throws IOException {
- try {
- GenericJson json = buildJsonCredentials();
- json.remove("client_secret");
- ExternalAccountAuthorizedUserCredentials.fromJson(json, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
- assertEquals(
- "ExternalAccountAuthorizedUserCredentials must be initialized with "
- + "an access token or fields to enable refresh: "
- + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
- exception.getMessage());
- }
+ void fromJson_missingClientSecret_throws() {
+ GenericJson json = buildJsonCredentials();
+ json.remove("client_secret");
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () ->
+ ExternalAccountAuthorizedUserCredentials.fromJson(
+ json, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
+ assertEquals(
+ "ExternalAccountAuthorizedUserCredentials must be initialized with "
+ + "an access token or fields to enable refresh: "
+ + "('refresh_token', 'token_url', 'client_id', 'client_secret').",
+ exception.getMessage());
}
@Test
@@ -567,10 +560,11 @@ void fromStream_accessTokenOnly_notSupported() throws IOException {
json.put("access_token", ACCESS_TOKEN);
json.put(
"type", GoogleCredentialsInfo.EXTERNAL_ACCOUNT_AUTHORIZED_USER_CREDENTIALS.getFileType());
- try {
- ExternalAccountAuthorizedUserCredentials.fromStream(TestUtils.jsonToInputStream(json));
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
+ try (InputStream credentialsStream = TestUtils.jsonToInputStream(json)) {
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () -> ExternalAccountAuthorizedUserCredentials.fromStream(credentialsStream));
assertEquals(
"ExternalAccountAuthorizedUserCredentials must be initialized with "
+ "an access token or fields to enable refresh: "
@@ -581,12 +575,13 @@ void fromStream_accessTokenOnly_notSupported() throws IOException {
@Test
void fromStream_missingRefreshToken_throws() throws IOException {
- try {
- GenericJson json = buildJsonCredentials();
- json.remove("refresh_token");
- ExternalAccountAuthorizedUserCredentials.fromStream(TestUtils.jsonToInputStream(json));
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
+ GenericJson json = buildJsonCredentials();
+ json.remove("refresh_token");
+ try (InputStream credentialsStream = TestUtils.jsonToInputStream(json)) {
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () -> ExternalAccountAuthorizedUserCredentials.fromStream(credentialsStream));
assertEquals(
"ExternalAccountAuthorizedUserCredentials must be initialized with "
+ "an access token or fields to enable refresh: "
@@ -597,12 +592,13 @@ void fromStream_missingRefreshToken_throws() throws IOException {
@Test
void fromStream_missingTokenUrl_throws() throws IOException {
- try {
- GenericJson json = buildJsonCredentials();
- json.remove("token_url");
- ExternalAccountAuthorizedUserCredentials.fromStream(TestUtils.jsonToInputStream(json));
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
+ GenericJson json = buildJsonCredentials();
+ json.remove("token_url");
+ try (InputStream credentialsStream = TestUtils.jsonToInputStream(json)) {
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () -> ExternalAccountAuthorizedUserCredentials.fromStream(credentialsStream));
assertEquals(
"ExternalAccountAuthorizedUserCredentials must be initialized with "
+ "an access token or fields to enable refresh: "
@@ -613,12 +609,13 @@ void fromStream_missingTokenUrl_throws() throws IOException {
@Test
void fromStream_missingClientId_throws() throws IOException {
- try {
- GenericJson json = buildJsonCredentials();
- json.remove("client_id");
- ExternalAccountAuthorizedUserCredentials.fromStream(TestUtils.jsonToInputStream(json));
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
+ GenericJson json = buildJsonCredentials();
+ json.remove("client_id");
+ try (InputStream credentialsStream = TestUtils.jsonToInputStream(json)) {
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () -> ExternalAccountAuthorizedUserCredentials.fromStream(credentialsStream));
assertEquals(
"ExternalAccountAuthorizedUserCredentials must be initialized with "
+ "an access token or fields to enable refresh: "
@@ -629,12 +626,13 @@ void fromStream_missingClientId_throws() throws IOException {
@Test
void fromStream_missingClientSecret_throws() throws IOException {
- try {
- GenericJson json = buildJsonCredentials();
- json.remove("client_secret");
- ExternalAccountAuthorizedUserCredentials.fromStream(TestUtils.jsonToInputStream(json));
- fail("Should not be able to continue without exception.");
- } catch (IllegalStateException exception) {
+ GenericJson json = buildJsonCredentials();
+ json.remove("client_secret");
+ try (InputStream credentialsStream = TestUtils.jsonToInputStream(json)) {
+ IllegalStateException exception =
+ assertThrows(
+ IllegalStateException.class,
+ () -> ExternalAccountAuthorizedUserCredentials.fromStream(credentialsStream));
assertEquals(
"ExternalAccountAuthorizedUserCredentials must be initialized with "
+ "an access token or fields to enable refresh: "
@@ -664,12 +662,13 @@ void fromStream_missingUniverseDomain_defaults() throws IOException {
@Test
void fromStream_invalidInputStream_throws() throws IOException {
- try {
- GenericJson json = buildJsonCredentials();
- json.put("audience", new HashMap<>());
- ExternalAccountAuthorizedUserCredentials.fromStream(TestUtils.jsonToInputStream(json));
- fail("Should not be able to continue without exception.");
- } catch (CredentialFormatException e) {
+ GenericJson json = buildJsonCredentials();
+ json.put("audience", new HashMap<>());
+ try (InputStream credentialsStream = TestUtils.jsonToInputStream(json)) {
+ CredentialFormatException e =
+ assertThrows(
+ CredentialFormatException.class,
+ () -> ExternalAccountAuthorizedUserCredentials.fromStream(credentialsStream));
assertEquals("Invalid input stream provided.", e.getMessage());
}
}
@@ -720,8 +719,8 @@ void getRequestMetadata_withQuotaProjectId() throws IOException {
assertTrue(metadata.containsKey(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY));
assertEquals(
- metadata.get(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY),
- Collections.singletonList(QUOTA_PROJECT));
+ Collections.singletonList(QUOTA_PROJECT),
+ metadata.get(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY));
validateAuthHeader(transportFactory.transport.getRequest());
}
@@ -775,13 +774,9 @@ void refreshAccessToken_genericAuthError_throws() throws IOException {
ExternalAccountAuthorizedUserCredentials credentials =
ExternalAccountAuthorizedUserCredentials.fromJson(buildJsonCredentials(), transportFactory);
- try {
- credentials.refreshAccessToken();
- fail("");
- } catch (OAuthException e) {
- assertEquals("invalid_request", e.getErrorCode());
- assertEquals("Invalid request.", e.getErrorDescription());
- }
+ OAuthException e = assertThrows(OAuthException.class, credentials::refreshAccessToken);
+ assertEquals("invalid_request", e.getErrorCode());
+ assertEquals("Invalid request.", e.getErrorDescription());
}
@Test
@@ -791,11 +786,11 @@ void refreshAccessToken_genericIOError_throws() throws IOException {
ExternalAccountAuthorizedUserCredentials credentials =
ExternalAccountAuthorizedUserCredentials.fromJson(buildJsonCredentials(), transportFactory);
- assertThrows(IOException.class, () -> credentials.refreshAccessToken());
+ assertThrows(IOException.class, credentials::refreshAccessToken);
}
@Test
- void refreshAccessToken_missingRefreshFields_throws() throws IOException {
+ void refreshAccessToken_missingRefreshFields_throws() {
ExternalAccountAuthorizedUserCredentials credentials =
ExternalAccountAuthorizedUserCredentials.newBuilder()
.setClientId(CLIENT_ID)
@@ -805,7 +800,7 @@ void refreshAccessToken_missingRefreshFields_throws() throws IOException {
.setHttpTransportFactory(transportFactory)
.build();
- assertThrows(IllegalStateException.class, () -> credentials.refreshAccessToken());
+ assertThrows(IllegalStateException.class, credentials::refreshAccessToken);
}
@Test
@@ -1238,7 +1233,7 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
}
static GenericJson buildJsonCredentials() {
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExternalAccountCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExternalAccountCredentialsTest.java
index d45979cfb985..1338c0d68fe9 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExternalAccountCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ExternalAccountCredentialsTest.java
@@ -32,15 +32,18 @@
package com.google.auth.oauth2;
import static com.google.auth.oauth2.MockExternalAccountCredentialsTransport.SERVICE_ACCOUNT_IMPERSONATION_URL;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.GenericJson;
+import com.google.api.client.json.JsonParser;
import com.google.api.client.util.Clock;
import com.google.auth.TestUtils;
import com.google.auth.http.HttpTransportFactory;
@@ -97,7 +100,7 @@ void fromStream_identityPoolCredentials() throws IOException {
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromStream(TestUtils.jsonToInputStream(json));
- assertTrue(credential instanceof IdentityPoolCredentials);
+ assertInstanceOf(IdentityPoolCredentials.class, credential);
}
@Test
@@ -107,7 +110,7 @@ void fromStream_awsCredentials() throws IOException {
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromStream(TestUtils.jsonToInputStream(json));
- assertTrue(credential instanceof AwsCredentials);
+ assertInstanceOf(AwsCredentials.class, credential);
}
@Test
@@ -117,32 +120,29 @@ void fromStream_pluggableAuthCredentials() throws IOException {
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromStream(TestUtils.jsonToInputStream(json));
- assertTrue(credential instanceof PluggableAuthCredentials);
+ assertInstanceOf(PluggableAuthCredentials.class, credential);
}
@Test
- void fromStream_invalidStream_throws() throws IOException {
+ void fromStream_invalidStream_throws() {
GenericJson json = buildJsonAwsCredential();
json.put("audience", new HashMap<>());
- try {
- ExternalAccountCredentials.fromStream(TestUtils.jsonToInputStream(json));
- fail("Should fail.");
- } catch (CredentialFormatException e) {
- assertEquals("An invalid input stream was provided.", e.getMessage());
- }
+ CredentialFormatException e =
+ assertThrows(
+ CredentialFormatException.class,
+ () -> ExternalAccountCredentials.fromStream(TestUtils.jsonToInputStream(json)));
+ assertEquals("An invalid input stream was provided.", e.getMessage());
}
@Test
- void fromStream_nullTransport_throws() throws IOException {
- try {
- ExternalAccountCredentials.fromStream(
- new ByteArrayInputStream("foo".getBytes()), /* transportFactory= */ null);
- fail("NullPointerException should be thrown.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ void fromStream_nullTransport_throws() {
+ ByteArrayInputStream credentialsStream = new ByteArrayInputStream("foo".getBytes());
+ assertThrows(
+ NullPointerException.class,
+ () ->
+ ExternalAccountCredentials.fromStream(credentialsStream, /* transportFactory= */ null));
}
@Test
@@ -164,36 +164,32 @@ void fromStream_nullOptionalField() throws IOException {
}
@Test
- void fromStream_nullStream_throws() throws IOException {
- try {
- ExternalAccountCredentials.fromStream(
- /* credentialsStream= */ null, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- fail("NullPointerException should be thrown.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ void fromStream_nullStream_throws() {
+ assertThrows(
+ NullPointerException.class,
+ () ->
+ ExternalAccountCredentials.fromStream(
+ /* credentialsStream= */ null, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
}
@Test
- void fromStream_invalidWorkloadAudience_throws() throws IOException {
- try {
- GenericJson json = buildJsonIdentityPoolWorkforceCredential();
- json.put("audience", "invalidAudience");
- ExternalAccountCredentials credential =
- ExternalAccountCredentials.fromStream(TestUtils.jsonToInputStream(json));
- fail("CredentialFormatException should be thrown.");
- } catch (CredentialFormatException e) {
- assertEquals("An invalid input stream was provided.", e.getMessage());
- }
+ void fromStream_invalidWorkloadAudience_throws() {
+ GenericJson json = buildJsonIdentityPoolWorkforceCredential();
+ json.put("audience", "invalidAudience");
+ CredentialFormatException e =
+ assertThrows(
+ CredentialFormatException.class,
+ () -> ExternalAccountCredentials.fromStream(TestUtils.jsonToInputStream(json)));
+ assertEquals("An invalid input stream was provided.", e.getMessage());
}
@Test
- void fromJson_identityPoolCredentialsWorkload() throws IOException {
+ void fromJson_identityPoolCredentialsWorkload() {
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(
buildJsonIdentityPoolCredential(), OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof IdentityPoolCredentials);
+ assertInstanceOf(IdentityPoolCredentials.class, credential);
assertEquals(
"//iam.googleapis.com/projects/123/locations/global/workloadIdentityPools/pool/providers/provider",
credential.getAudience());
@@ -205,12 +201,12 @@ void fromJson_identityPoolCredentialsWorkload() throws IOException {
}
@Test
- void fromJson_identityPoolCredentialsWorkforce() throws IOException {
+ void fromJson_identityPoolCredentialsWorkforce() {
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(
buildJsonIdentityPoolWorkforceCredential(), OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof IdentityPoolCredentials);
+ assertInstanceOf(IdentityPoolCredentials.class, credential);
assertEquals(
"//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider",
credential.getAudience());
@@ -223,16 +219,16 @@ void fromJson_identityPoolCredentialsWorkforce() throws IOException {
}
@Test
- void fromJson_identityPoolCredentialsWithServiceAccountImpersonationOptions() throws IOException {
+ void fromJson_identityPoolCredentialsWithServiceAccountImpersonationOptions() {
GenericJson identityPoolCredentialJson = buildJsonIdentityPoolCredential();
identityPoolCredentialJson.set(
- "service_account_impersonation", buildServiceAccountImpersonationOptions(2800));
+ "service_account_impersonation", buildServiceAccountImpersonationOptions());
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(
identityPoolCredentialJson, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof IdentityPoolCredentials);
+ assertInstanceOf(IdentityPoolCredentials.class, credential);
assertEquals(
"//iam.googleapis.com/projects/123/locations/global/workloadIdentityPools/pool/providers/provider",
credential.getAudience());
@@ -245,7 +241,7 @@ void fromJson_identityPoolCredentialsWithServiceAccountImpersonationOptions() th
}
@Test
- void fromJson_identityPoolCredentialsWithUniverseDomain() throws IOException {
+ void fromJson_identityPoolCredentialsWithUniverseDomain() {
GenericJson identityPoolCredentialJson = buildJsonIdentityPoolCredential();
identityPoolCredentialJson.set("universe_domain", "universeDomain");
@@ -253,7 +249,7 @@ void fromJson_identityPoolCredentialsWithUniverseDomain() throws IOException {
ExternalAccountCredentials.fromJson(
identityPoolCredentialJson, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof IdentityPoolCredentials);
+ assertInstanceOf(IdentityPoolCredentials.class, credential);
assertNotNull(credential.getCredentialSource());
assertEquals(
"//iam.googleapis.com/projects/123/locations/global/workloadIdentityPools/pool/providers/provider",
@@ -265,12 +261,12 @@ void fromJson_identityPoolCredentialsWithUniverseDomain() throws IOException {
}
@Test
- void fromJson_awsCredentials() throws IOException {
+ void fromJson_awsCredentials() {
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(
buildJsonAwsCredential(), OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof AwsCredentials);
+ assertInstanceOf(AwsCredentials.class, credential);
assertEquals("audience", credential.getAudience());
assertEquals("subjectTokenType", credential.getSubjectTokenType());
assertEquals(STS_URL, credential.getTokenUrl());
@@ -280,15 +276,15 @@ void fromJson_awsCredentials() throws IOException {
}
@Test
- void fromJson_awsCredentialsWithServiceAccountImpersonationOptions() throws IOException {
+ void fromJson_awsCredentialsWithServiceAccountImpersonationOptions() {
GenericJson awsCredentialJson = buildJsonAwsCredential();
awsCredentialJson.set(
- "service_account_impersonation", buildServiceAccountImpersonationOptions(2800));
+ "service_account_impersonation", buildServiceAccountImpersonationOptions());
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(awsCredentialJson, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof AwsCredentials);
+ assertInstanceOf(AwsCredentials.class, credential);
assertEquals("audience", credential.getAudience());
assertEquals("subjectTokenType", credential.getSubjectTokenType());
assertEquals(STS_URL, credential.getTokenUrl());
@@ -299,14 +295,14 @@ void fromJson_awsCredentialsWithServiceAccountImpersonationOptions() throws IOEx
}
@Test
- void fromJson_awsCredentialsWithUniverseDomain() throws IOException {
+ void fromJson_awsCredentialsWithUniverseDomain() {
GenericJson awsCredentialJson = buildJsonAwsCredential();
awsCredentialJson.set("universe_domain", "universeDomain");
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(awsCredentialJson, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof AwsCredentials);
+ assertInstanceOf(AwsCredentials.class, credential);
assertEquals("audience", credential.getAudience());
assertEquals("subjectTokenType", credential.getSubjectTokenType());
assertEquals(STS_URL, credential.getTokenUrl());
@@ -316,12 +312,12 @@ void fromJson_awsCredentialsWithUniverseDomain() throws IOException {
}
@Test
- void fromJson_pluggableAuthCredentials() throws IOException {
+ void fromJson_pluggableAuthCredentials() {
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(
buildJsonPluggableAuthCredential(), OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof PluggableAuthCredentials);
+ assertInstanceOf(PluggableAuthCredentials.class, credential);
assertEquals("audience", credential.getAudience());
assertEquals("subjectTokenType", credential.getSubjectTokenType());
assertEquals(STS_URL, credential.getTokenUrl());
@@ -337,12 +333,12 @@ void fromJson_pluggableAuthCredentials() throws IOException {
}
@Test
- void fromJson_pluggableAuthCredentialsWorkforce() throws IOException {
+ void fromJson_pluggableAuthCredentialsWorkforce() {
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(
buildJsonPluggableAuthWorkforceCredential(), OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof PluggableAuthCredentials);
+ assertInstanceOf(PluggableAuthCredentials.class, credential);
assertEquals(
"//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider",
credential.getAudience());
@@ -363,7 +359,7 @@ void fromJson_pluggableAuthCredentialsWorkforce() throws IOException {
@Test
@SuppressWarnings("unchecked")
- void fromJson_pluggableAuthCredentials_allExecutableOptionsSet() throws IOException {
+ void fromJson_pluggableAuthCredentials_allExecutableOptionsSet() {
GenericJson json = buildJsonPluggableAuthCredential();
Map credentialSourceMap = (Map) json.get("credential_source");
// Add optional params to the executable config (timeout, output file path).
@@ -375,7 +371,7 @@ void fromJson_pluggableAuthCredentials_allExecutableOptionsSet() throws IOExcept
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(json, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof PluggableAuthCredentials);
+ assertInstanceOf(PluggableAuthCredentials.class, credential);
assertEquals("audience", credential.getAudience());
assertEquals("subjectTokenType", credential.getSubjectTokenType());
assertEquals(STS_URL, credential.getTokenUrl());
@@ -391,17 +387,16 @@ void fromJson_pluggableAuthCredentials_allExecutableOptionsSet() throws IOExcept
}
@Test
- void fromJson_pluggableAuthCredentialsWithServiceAccountImpersonationOptions()
- throws IOException {
+ void fromJson_pluggableAuthCredentialsWithServiceAccountImpersonationOptions() {
GenericJson pluggableAuthCredentialJson = buildJsonPluggableAuthCredential();
pluggableAuthCredentialJson.set(
- "service_account_impersonation", buildServiceAccountImpersonationOptions(2800));
+ "service_account_impersonation", buildServiceAccountImpersonationOptions());
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(
pluggableAuthCredentialJson, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof PluggableAuthCredentials);
+ assertInstanceOf(PluggableAuthCredentials.class, credential);
assertEquals("audience", credential.getAudience());
assertEquals("subjectTokenType", credential.getSubjectTokenType());
assertEquals(STS_URL, credential.getTokenUrl());
@@ -419,7 +414,7 @@ void fromJson_pluggableAuthCredentialsWithServiceAccountImpersonationOptions()
@Test
@SuppressWarnings("unchecked")
- void fromJson_pluggableAuthCredentials_withUniverseDomain() throws IOException {
+ void fromJson_pluggableAuthCredentials_withUniverseDomain() {
GenericJson json = buildJsonPluggableAuthCredential();
json.set("universe_domain", "universeDomain");
@@ -433,7 +428,7 @@ void fromJson_pluggableAuthCredentials_withUniverseDomain() throws IOException {
ExternalAccountCredentials credential =
ExternalAccountCredentials.fromJson(json, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof PluggableAuthCredentials);
+ assertInstanceOf(PluggableAuthCredentials.class, credential);
assertEquals("audience", credential.getAudience());
assertEquals("subjectTokenType", credential.getSubjectTokenType());
assertEquals(STS_URL, credential.getTokenUrl());
@@ -449,7 +444,7 @@ void fromJson_pluggableAuthCredentials_withUniverseDomain() throws IOException {
}
@Test
- void fromJson_pluggableAuthCredentialsWithUniverseDomain() throws IOException {
+ void fromJson_pluggableAuthCredentialsWithUniverseDomain() {
GenericJson pluggableAuthCredentialJson = buildJsonPluggableAuthCredential();
pluggableAuthCredentialJson.set("universe_domain", "universeDomain");
@@ -457,7 +452,7 @@ void fromJson_pluggableAuthCredentialsWithUniverseDomain() throws IOException {
ExternalAccountCredentials.fromJson(
pluggableAuthCredentialJson, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- assertTrue(credential instanceof PluggableAuthCredentials);
+ assertInstanceOf(PluggableAuthCredentials.class, credential);
assertEquals("audience", credential.getAudience());
assertEquals("subjectTokenType", credential.getSubjectTokenType());
assertEquals(STS_URL, credential.getTokenUrl());
@@ -473,31 +468,26 @@ void fromJson_pluggableAuthCredentialsWithUniverseDomain() throws IOException {
}
@Test
- void fromJson_nullJson_throws() throws IOException {
- try {
- ExternalAccountCredentials.fromJson(/* json= */ null, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- fail("Exception should be thrown.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ void fromJson_nullJson_throws() {
+ assertThrows(
+ NullPointerException.class,
+ () ->
+ ExternalAccountCredentials.fromJson(
+ /* json= */ null, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
}
@Test
- void fromJson_nullTransport_throws() throws IOException {
- try {
- ExternalAccountCredentials.fromJson(
- new HashMap(), /* transportFactory= */ null);
- fail("Exception should be thrown.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ void fromJson_nullTransport_throws() {
+ HashMap json = new HashMap<>();
+ assertThrows(NullPointerException.class, () -> ExternalAccountCredentials.fromJson(json, null));
}
@Test
- void fromJson_invalidWorkforceAudiences_throws() throws IOException {
+ void fromJson_invalidWorkforceAudiences_throws() {
List invalidAudiences =
Arrays.asList(
- "//iam.googleapis.com/locations/global/workloadIdentityPools/pool/providers/provider",
+ "",
+ "//iam.googleapis.com/projects/x23/locations/global/workloadIdentityPools/pool/providers/provider",
"//iam.googleapis.com/locations/global/workforcepools/pool/providers/provider",
"//iam.googleapis.com/locations/global/workforcePools/providers/provider",
"//iam.googleapis.com/locations/global/workforcePools/providers",
@@ -507,23 +497,25 @@ void fromJson_invalidWorkforceAudiences_throws() throws IOException {
"//iam.googleapis.com/locations/global/workforce/providers");
for (String audience : invalidAudiences) {
- try {
- GenericJson json = buildJsonIdentityPoolCredential();
- json.put("audience", audience);
- json.put("workforce_pool_user_project", "userProject");
-
- ExternalAccountCredentials.fromJson(json, OAuth2Utils.HTTP_TRANSPORT_FACTORY);
- fail("Exception should be thrown.");
- } catch (IllegalArgumentException e) {
- assertEquals(
- "The workforce_pool_user_project parameter should only be provided for a Workforce Pool configuration.",
- e.getMessage());
- }
+ GenericJson json = buildJsonIdentityPoolCredential();
+ json.put("audience", audience);
+ json.put("workforce_pool_user_project", "userProject");
+
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ (org.junit.jupiter.api.function.Executable)
+ () ->
+ ExternalAccountCredentials.fromJson(
+ json, OAuth2Utils.HTTP_TRANSPORT_FACTORY));
+ assertEquals(
+ "The workforce_pool_user_project parameter should only be provided for a Workforce Pool configuration.",
+ e.getMessage());
}
}
@Test
- void constructor_builder() throws IOException {
+ void constructor_builder() {
HashMap credentialSource = new HashMap<>();
credentialSource.put("file", "file");
@@ -617,37 +609,37 @@ void constructor_builder_subjectTokenTypeEnum() {
@Test
void constructor_builder_invalidTokenUrl() {
- try {
- ExternalAccountCredentials.Builder builder =
- TestExternalAccountCredentials.newBuilder()
- .setHttpTransportFactory(transportFactory)
- .setAudience("audience")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl("tokenUrl")
- .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP));
- new TestExternalAccountCredentials(builder);
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals("The provided token URL is invalid.", exception.getMessage());
- }
+ ExternalAccountCredentials.Builder builder =
+ TestExternalAccountCredentials.newBuilder()
+ .setHttpTransportFactory(transportFactory)
+ .setAudience("audience")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl("tokenUrl")
+ .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP));
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ (org.junit.jupiter.api.function.Executable)
+ () -> new TestExternalAccountCredentials(builder));
+ assertEquals("The provided token URL is invalid.", exception.getMessage());
}
@Test
void constructor_builder_invalidServiceAccountImpersonationUrl() {
- try {
- ExternalAccountCredentials.Builder builder =
- TestExternalAccountCredentials.newBuilder()
- .setHttpTransportFactory(transportFactory)
- .setAudience("audience")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl("tokenUrl")
- .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP))
- .setServiceAccountImpersonationUrl("serviceAccountImpersonationUrl");
- new TestExternalAccountCredentials(builder);
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals("The provided token URL is invalid.", exception.getMessage());
- }
+ ExternalAccountCredentials.Builder builder =
+ TestExternalAccountCredentials.newBuilder()
+ .setHttpTransportFactory(transportFactory)
+ .setAudience("audience")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl("tokenUrl")
+ .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP))
+ .setServiceAccountImpersonationUrl("serviceAccountImpersonationUrl");
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ (org.junit.jupiter.api.function.Executable)
+ () -> new TestExternalAccountCredentials(builder));
+ assertEquals("The provided token URL is invalid.", exception.getMessage());
}
@Test
@@ -667,21 +659,22 @@ void constructor_builderWithInvalidWorkforceAudiences_throws() {
HashMap credentialSource = new HashMap<>();
credentialSource.put("file", "file");
for (String audience : invalidAudiences) {
- try {
- TestExternalAccountCredentials.newBuilder()
- .setWorkforcePoolUserProject("workforcePoolUserProject")
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setAudience(audience)
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .setCredentialSource(new TestCredentialSource(credentialSource))
- .build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- "The workforce_pool_user_project parameter should only be provided for a Workforce Pool configuration.",
- exception.getMessage());
- }
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ (org.junit.jupiter.api.function.Executable)
+ () ->
+ TestExternalAccountCredentials.newBuilder()
+ .setWorkforcePoolUserProject("workforcePoolUserProject")
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setAudience(audience)
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL)
+ .setCredentialSource(new TestCredentialSource(credentialSource))
+ .build());
+ assertEquals(
+ "The workforce_pool_user_project parameter should only be provided for a Workforce Pool configuration.",
+ exception.getMessage());
}
}
@@ -690,14 +683,16 @@ void constructor_builderWithEmptyWorkforceUserProjectAndWorkforceAudience() {
HashMap credentialSource = new HashMap<>();
credentialSource.put("file", "file");
// No exception should be thrown.
- TestExternalAccountCredentials.newBuilder()
- .setWorkforcePoolUserProject("")
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setAudience("//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .setCredentialSource(new TestCredentialSource(credentialSource))
- .build();
+ ExternalAccountCredentials.Builder builder =
+ TestExternalAccountCredentials.newBuilder()
+ .setWorkforcePoolUserProject("")
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setAudience(
+ "//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL)
+ .setCredentialSource(new TestCredentialSource(credentialSource));
+ assertDoesNotThrow(builder::build);
}
@Test
@@ -705,31 +700,32 @@ void constructor_builder_invalidTokenLifetime_throws() {
Map invalidOptionsMap = new HashMap();
invalidOptionsMap.put("token_lifetime_seconds", "thisIsAString");
- try {
- IdentityPoolCredentials.newBuilder()
- .setHttpTransportFactory(transportFactory)
- .setAudience(
- "//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .setTokenInfoUrl("https://tokeninfo.com")
- .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
- .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP))
- .setScopes(Arrays.asList("scope1", "scope2"))
- .setQuotaProjectId("projectId")
- .setClientId("clientId")
- .setClientSecret("clientSecret")
- .setWorkforcePoolUserProject("workforcePoolUserProject")
- .setUniverseDomain("universeDomain")
- .setServiceAccountImpersonationOptions(invalidOptionsMap)
- .build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- "Value of \"token_lifetime_seconds\" field could not be parsed into an integer.",
- exception.getMessage());
- assertEquals(NumberFormatException.class, exception.getCause().getClass());
- }
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ (org.junit.jupiter.api.function.Executable)
+ () ->
+ IdentityPoolCredentials.newBuilder()
+ .setHttpTransportFactory(transportFactory)
+ .setAudience(
+ "//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL)
+ .setTokenInfoUrl("https://tokeninfo.com")
+ .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
+ .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP))
+ .setScopes(Arrays.asList("scope1", "scope2"))
+ .setQuotaProjectId("projectId")
+ .setClientId("clientId")
+ .setClientSecret("clientSecret")
+ .setWorkforcePoolUserProject("workforcePoolUserProject")
+ .setUniverseDomain("universeDomain")
+ .setServiceAccountImpersonationOptions(invalidOptionsMap)
+ .build());
+ assertEquals(
+ "Value of \"token_lifetime_seconds\" field could not be parsed into an integer.",
+ exception.getMessage());
+ assertEquals(NumberFormatException.class, exception.getCause().getClass());
}
@Test
@@ -789,7 +785,7 @@ void constructor_builder_bigDecimalTokenLifetime() {
@Test
void constructor_builder_integerTokenLifetime() {
Map optionsMap = new HashMap();
- optionsMap.put("token_lifetime_seconds", Integer.valueOf(2800));
+ optionsMap.put("token_lifetime_seconds", 2800);
ExternalAccountCredentials credentials =
IdentityPoolCredentials.newBuilder()
@@ -818,59 +814,61 @@ void constructor_builder_lowTokenLifetime_throws() {
Map optionsMap = new HashMap();
optionsMap.put("token_lifetime_seconds", 599);
- try {
- IdentityPoolCredentials.newBuilder()
- .setHttpTransportFactory(transportFactory)
- .setAudience(
- "//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .setTokenInfoUrl("https://tokeninfo.com")
- .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
- .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP))
- .setScopes(Arrays.asList("scope1", "scope2"))
- .setQuotaProjectId("projectId")
- .setClientId("clientId")
- .setClientSecret("clientSecret")
- .setWorkforcePoolUserProject("workforcePoolUserProject")
- .setUniverseDomain("universeDomain")
- .setServiceAccountImpersonationOptions(optionsMap)
- .build();
- } catch (IllegalArgumentException e) {
- assertEquals(
- "The \"token_lifetime_seconds\" field must be between 600 and 43200 seconds.",
- e.getMessage());
- }
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ (org.junit.jupiter.api.function.Executable)
+ () ->
+ IdentityPoolCredentials.newBuilder()
+ .setHttpTransportFactory(transportFactory)
+ .setAudience(
+ "//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL)
+ .setTokenInfoUrl("https://tokeninfo.com")
+ .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
+ .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP))
+ .setScopes(Arrays.asList("scope1", "scope2"))
+ .setQuotaProjectId("projectId")
+ .setClientId("clientId")
+ .setClientSecret("clientSecret")
+ .setWorkforcePoolUserProject("workforcePoolUserProject")
+ .setUniverseDomain("universeDomain")
+ .setServiceAccountImpersonationOptions(optionsMap)
+ .build());
+ assertEquals(
+ "The \"token_lifetime_seconds\" field must be between 600 and 43200 seconds.",
+ e.getMessage());
}
@Test
void constructor_builder_highTokenLifetime_throws() {
- Map optionsMap = new HashMap();
+ Map optionsMap = new HashMap<>();
optionsMap.put("token_lifetime_seconds", 43201);
- try {
- IdentityPoolCredentials.newBuilder()
- .setHttpTransportFactory(transportFactory)
- .setAudience(
- "//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .setTokenInfoUrl("https://tokeninfo.com")
- .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
- .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP))
- .setScopes(Arrays.asList("scope1", "scope2"))
- .setQuotaProjectId("projectId")
- .setClientId("clientId")
- .setClientSecret("clientSecret")
- .setWorkforcePoolUserProject("workforcePoolUserProject")
- .setUniverseDomain("universeDomain")
- .setServiceAccountImpersonationOptions(optionsMap)
- .build();
- } catch (IllegalArgumentException e) {
- assertEquals(
- "The \"token_lifetime_seconds\" field must be between 600 and 43200 seconds.",
- e.getMessage());
- }
+ IdentityPoolCredentials.Builder builder =
+ IdentityPoolCredentials.newBuilder()
+ .setHttpTransportFactory(transportFactory)
+ .setAudience(
+ "//iam.googleapis.com/locations/global/workforcePools/pool/providers/provider")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL)
+ .setTokenInfoUrl("https://tokeninfo.com")
+ .setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
+ .setCredentialSource(new TestCredentialSource(FILE_CREDENTIAL_SOURCE_MAP))
+ .setScopes(Arrays.asList("scope1", "scope2"))
+ .setQuotaProjectId("projectId")
+ .setClientId("clientId")
+ .setClientSecret("clientSecret")
+ .setWorkforcePoolUserProject("workforcePoolUserProject")
+ .setUniverseDomain("universeDomain");
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> builder.setServiceAccountImpersonationOptions(optionsMap));
+ assertEquals(
+ "The \"token_lifetime_seconds\" field must be between 600 and 43200 seconds.",
+ e.getMessage());
}
@Test
@@ -1006,17 +1004,18 @@ void exchangeExternalCredentialForAccessToken_withServiceAccountImpersonation()
transportFactory.transport.getServiceAccountAccessToken(), returnedToken.getTokenValue());
// Validate that default lifetime was set correctly on the request.
- GenericJson query =
- OAuth2Utils.JSON_FACTORY
- .createJsonParser(transportFactory.transport.getLastRequest().getContentAsString())
- .parseAndClose(GenericJson.class);
+ try (JsonParser jsonParser =
+ OAuth2Utils.JSON_FACTORY.createJsonParser(
+ transportFactory.transport.getLastRequest().getContentAsString())) {
+ GenericJson query = jsonParser.parseAndClose(GenericJson.class);
- assertEquals("3600s", query.get("lifetime"));
+ assertEquals("3600s", query.get("lifetime"));
- // Validate metrics header is set correctly on the sts request.
- Map> headers =
- transportFactory.transport.getRequests().get(1).getHeaders();
- validateMetricsHeader(headers, "url", true, false);
+ // Validate metrics header is set correctly on the sts request.
+ Map> headers =
+ transportFactory.transport.getRequests().get(1).getHeaders();
+ validateMetricsHeader(headers, "url", true, false);
+ }
}
@Test
@@ -1030,7 +1029,7 @@ void exchangeExternalCredentialForAccessToken_withServiceAccountImpersonationOpt
transportFactory.transport.getStsUrl(),
transportFactory.transport.getMetadataUrl(),
transportFactory.transport.getServiceAccountImpersonationUrl(),
- buildServiceAccountImpersonationOptions(2800)),
+ buildServiceAccountImpersonationOptions()),
transportFactory);
StsTokenExchangeRequest stsTokenExchangeRequest =
@@ -1043,16 +1042,16 @@ void exchangeExternalCredentialForAccessToken_withServiceAccountImpersonationOpt
transportFactory.transport.getServiceAccountAccessToken(), returnedToken.getTokenValue());
// Validate that lifetime was set correctly on the request.
- GenericJson query =
- OAuth2Utils.JSON_FACTORY
- .createJsonParser(transportFactory.transport.getLastRequest().getContentAsString())
- .parseAndClose(GenericJson.class);
-
- // Validate metrics header is set correctly on the sts request.
- Map> headers =
- transportFactory.transport.getRequests().get(1).getHeaders();
- validateMetricsHeader(headers, "url", true, true);
- assertEquals("2800s", query.get("lifetime"));
+ try (JsonParser jsonParser =
+ OAuth2Utils.JSON_FACTORY.createJsonParser(
+ transportFactory.transport.getLastRequest().getContentAsString())) {
+ GenericJson query = jsonParser.parseAndClose(GenericJson.class);
+ // Validate metrics header is set correctly on the sts request.
+ Map> headers =
+ transportFactory.transport.getRequests().get(1).getHeaders();
+ validateMetricsHeader(headers, "url", true, true);
+ assertEquals("2800s", query.get("lifetime"));
+ }
}
@Test
@@ -1069,19 +1068,18 @@ void exchangeExternalCredentialForAccessToken_throws() throws IOException {
StsTokenExchangeRequest stsTokenExchangeRequest =
StsTokenExchangeRequest.newBuilder("credential", "subjectTokenType").build();
- try {
- credential.exchangeExternalCredentialForAccessToken(stsTokenExchangeRequest);
- fail("Exception should be thrown.");
- } catch (OAuthException e) {
- assertEquals(errorCode, e.getErrorCode());
- assertEquals(errorDescription, e.getErrorDescription());
- assertEquals(errorUri, e.getErrorUri());
- }
+ OAuthException e =
+ assertThrows(
+ OAuthException.class,
+ (org.junit.jupiter.api.function.Executable)
+ () -> credential.exchangeExternalCredentialForAccessToken(stsTokenExchangeRequest));
+ assertEquals(errorCode, e.getErrorCode());
+ assertEquals(errorDescription, e.getErrorDescription());
+ assertEquals(errorUri, e.getErrorUri());
}
@Test
- void exchangeExternalCredentialForAccessToken_invalidImpersonatedCredentialsThrows()
- throws IOException {
+ void exchangeExternalCredentialForAccessToken_invalidImpersonatedCredentialsThrows() {
GenericJson json = buildJsonIdentityPoolCredential();
json.put("service_account_impersonation_url", "https://iamcredentials.googleapis.com");
ExternalAccountCredentials credential =
@@ -1090,14 +1088,13 @@ void exchangeExternalCredentialForAccessToken_invalidImpersonatedCredentialsThro
StsTokenExchangeRequest stsTokenExchangeRequest =
StsTokenExchangeRequest.newBuilder("credential", "subjectTokenType").build();
- try {
- credential.exchangeExternalCredentialForAccessToken(stsTokenExchangeRequest);
- fail("Exception should be thrown.");
- } catch (IllegalArgumentException e) {
- assertEquals(
- "Unable to determine target principal from service account impersonation URL.",
- e.getMessage());
- }
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> credential.exchangeExternalCredentialForAccessToken(stsTokenExchangeRequest));
+ assertEquals(
+ "Unable to determine target principal from service account impersonation URL.",
+ e.getMessage());
}
@Test
@@ -1147,7 +1144,7 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(
testCredentials.getServiceAccountImpersonationOptions().getLifetime(),
deserializedCredentials.getServiceAccountImpersonationOptions().getLifetime());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
assertEquals(
MockExternalAccountCredentialsTransportFactory.class,
deserializedCredentials.toBuilder().getHttpTransportFactory().getClass());
@@ -1189,12 +1186,11 @@ void validateTokenUrl_invalidUrls() {
"https://us- -1.sts.googleapis.com");
for (String url : invalidUrls) {
- try {
- ExternalAccountCredentials.validateTokenUrl(url);
- fail("Should have failed since an invalid URL was passed.");
- } catch (IllegalArgumentException e) {
- assertEquals("The provided token URL is invalid.", e.getMessage());
- }
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> ExternalAccountCredentials.validateTokenUrl(url));
+ assertEquals("The provided token URL is invalid.", e.getMessage());
}
}
@@ -1235,12 +1231,12 @@ void validateServiceAccountImpersonationUrls_invalidUrls() {
"https://us- -1.iamcredentials.googleapis.com");
for (String url : invalidUrls) {
- try {
- ExternalAccountCredentials.validateServiceAccountImpersonationInfoUrl(url);
- fail("Should have failed since an invalid URL was passed.");
- } catch (IllegalArgumentException e) {
- assertEquals("The provided service account impersonation URL is invalid.", e.getMessage());
- }
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ (org.junit.jupiter.api.function.Executable)
+ () -> ExternalAccountCredentials.validateServiceAccountImpersonationInfoUrl(url));
+ assertEquals("The provided service account impersonation URL is invalid.", e.getMessage());
}
}
@@ -1318,10 +1314,9 @@ private GenericJson buildJsonPluggableAuthWorkforceCredential() {
return json;
}
- static Map buildServiceAccountImpersonationOptions(Integer lifetime) {
+ static Map buildServiceAccountImpersonationOptions() {
Map map = new HashMap();
- map.put("token_lifetime_seconds", lifetime);
-
+ map.put("token_lifetime_seconds", 2800);
return map;
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GdchCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GdchCredentialsTest.java
index b555149167f1..ace74dd67e63 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GdchCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GdchCredentialsTest.java
@@ -32,18 +32,21 @@
package com.google.auth.oauth2;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.json.GenericJson;
+import com.google.api.client.json.Json;
import com.google.api.client.json.JsonFactory;
+import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.json.webtoken.JsonWebSignature;
import com.google.api.client.json.webtoken.JsonWebToken;
import com.google.api.client.testing.http.FixedClock;
+import com.google.api.client.testing.http.MockLowLevelHttpResponse;
import com.google.api.client.util.Clock;
import com.google.auth.TestUtils;
import com.google.auth.oauth2.GoogleCredentials.GoogleCredentialsInfo;
@@ -52,27 +55,35 @@
import java.io.InputStream;
import java.net.URI;
import java.nio.file.Files;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PrivateKey;
+import java.security.Signature;
+import java.security.spec.ECGenParameterSpec;
+import java.util.Base64;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Test;
/** Test case for {@link GdchCredentials}. */
class GdchCredentialsTest extends BaseSerializationTest {
- private static final String FORMAT_VERSION = GdchCredentials.SUPPORTED_FORMAT_VERSION;
+ private static final String FORMAT_VERSION = GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION;
private static final String PRIVATE_KEY_ID = "d84a4fefcf50791d4a90f2d7af17469d6282df9d";
static final String PRIVATE_KEY_PKCS8 =
"-----BEGIN PRIVATE KEY-----\n"
- + "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALX0PQoe1igW12i"
- + "kv1bN/r9lN749y2ijmbc/mFHPyS3hNTyOCjDvBbXYbDhQJzWVUikh4mvGBA07qTj79Xc3yBDfKP2IeyYQIFe0t0"
- + "zkd7R9Zdn98Y2rIQC47aAbDfubtkU1U72t4zL11kHvoa0/RuFZjncvlr42X7be7lYh4p3NAgMBAAECgYASk5wDw"
- + "4Az2ZkmeuN6Fk/y9H+Lcb2pskJIXjrL533vrDWGOC48LrsThMQPv8cxBky8HFSEklPpkfTF95tpD43iVwJRB/Gr"
- + "CtGTw65IfJ4/tI09h6zGc4yqvIo1cHX/LQ+SxKLGyir/dQM925rGt/VojxY5ryJR7GLbCzxPnJm/oQJBANwOCO6"
- + "D2hy1LQYJhXh7O+RLtA/tSnT1xyMQsGT+uUCMiKS2bSKx2wxo9k7h3OegNJIu1q6nZ6AbxDK8H3+d0dUCQQDTrP"
- + "SXagBxzp8PecbaCHjzNRSQE2in81qYnrAFNB4o3DpHyMMY6s5ALLeHKscEWnqP8Ur6X4PvzZecCWU9BKAZAkAut"
- + "LPknAuxSCsUOvUfS1i87ex77Ot+w6POp34pEX+UWb+u5iFn2cQacDTHLV1LtE80L8jVLSbrbrlH43H0DjU5AkEA"
- + "gidhycxS86dxpEljnOMCw8CKoUBd5I880IUahEiUltk7OLJYS/Ts1wbn3kPOVX3wyJs8WBDtBkFrDHW2ezth2QJ"
- + "ADj3e1YhMVdjJW5jqwlD/VNddGjgzyunmiZg0uOXsHXbytYmsA545S8KRQFaJKFXYYFo2kOjqOiC1T2cAzMDjCQ"
- + "==\n-----END PRIVATE KEY-----\n";
+ + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgyITXsUvRm1C3lnyz\n"
+ + "OaMY7TNXZois4NH0bkMwqTAnVbqhRANCAASk5+U9skHVTo+sEVd2/yKY7A2eYn8K\n"
+ + "Cygd3bQalfWs533aTu93XwVx0YNN310aFquv3/VIiFofm1JEBAhUiG8e\n"
+ + "-----END PRIVATE KEY-----";
+
+ // Generated using OpenSSL:
+ // openssl ecparam -name prime256v1 -genkey -noout -out ec-sec1.pem
+ static final String PRIVATE_KEY_SEC1 =
+ "-----BEGIN EC PRIVATE KEY-----\n"
+ + "MHcCAQEEIK+G0KyJyJPDK/tyYsF0RyFW+X1GMsWbrlWn8TbLAI0doAoGCCqGSM49\n"
+ + "AwEHoUQDQgAEmGMJNcYyb9IfS4ngfvSf+c0sxOdcRfPNnZajry4bLgs++2VpQn8e\n"
+ + "l27zuFvF8jrM2/XyG5y9heE8YSjfLMy0Rw==\n"
+ + "-----END EC PRIVATE KEY-----";
private static final String PROJECT_ID = "project-id";
private static final String SERVICE_IDENTITY_NAME = "service-identity-name";
private static final String ACCESS_TOKEN = "1/MkSJoj1xsli0AccessToken_NKPY2";
@@ -81,7 +92,7 @@ class GdchCredentialsTest extends BaseSerializationTest {
private static final String CA_CERT_FILE_NAME = "cert.pem";
private static final String CA_CERT_PATH =
GdchCredentialsTest.class.getClassLoader().getResource(CA_CERT_FILE_NAME).getPath();
- private static final URI API_AUDIENCE = URI.create("https://gdch-api-audience");
+ private static final String API_AUDIENCE = "https://gdch-api-audience";
private static final URI CALL_URI = URI.create("http://googleapis.com/testapi/v1/foo");
@Test
@@ -100,6 +111,23 @@ void fromJSON_getProjectId() throws IOException {
assertEquals(PROJECT_ID, credentials.getProjectId());
}
+ @Test
+ void fromJSON_sec1Key() throws IOException {
+ GenericJson json =
+ writeGdchServiceAccountJson(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_SEC1,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
+
+ assertNotNull(credentials);
+ assertEquals(PROJECT_ID, credentials.getProjectId());
+ }
+
@Test
void fromJSON_getServiceIdentityName() throws IOException {
GenericJson json =
@@ -149,7 +177,7 @@ void fromJSON_getTokenServerUri() throws IOException {
}
@Test
- void fromJSON_nullFormatVersion() throws IOException {
+ void fromJSON_nullFormatVersion() {
GenericJson json =
writeGdchServiceAccountJson(
null,
@@ -160,22 +188,18 @@ void fromJSON_nullFormatVersion() throws IOException {
CA_CERT_PATH,
TOKEN_SERVER_URI);
- try {
- GdchCredentials credentials = GdchCredentials.fromJson(json);
- fail("Should not be able to create GDCH credential without exception.");
- } catch (IOException ex) {
- assertTrue(
- ex.getMessage()
- .contains(
- String.format(
- "Error reading GDCH service account credential from JSON, "
- + "%s is misconfigured.",
- "format_version")));
- }
+ IOException ex = assertThrows(IOException.class, () -> GdchCredentials.fromJson(json));
+ assertTrue(
+ ex.getMessage()
+ .contains(
+ String.format(
+ "Error reading GDCH service account credential from JSON, "
+ + "%s is misconfigured.",
+ "format_version")));
}
@Test
- void fromJSON_nullProjectId() throws IOException {
+ void fromJSON_nullProjectId() {
GenericJson json =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -186,22 +210,18 @@ void fromJSON_nullProjectId() throws IOException {
CA_CERT_PATH,
TOKEN_SERVER_URI);
- try {
- GdchCredentials credentials = GdchCredentials.fromJson(json);
- fail("Should not be able to create GDCH credential without exception.");
- } catch (IOException ex) {
- assertTrue(
- ex.getMessage()
- .contains(
- String.format(
- "Error reading GDCH service account credential from JSON, "
- + "%s is misconfigured.",
- "project")));
- }
+ IOException ex = assertThrows(IOException.class, () -> GdchCredentials.fromJson(json));
+ assertTrue(
+ ex.getMessage()
+ .contains(
+ String.format(
+ "Error reading GDCH service account credential from JSON, "
+ + "%s is misconfigured.",
+ "project")));
}
@Test
- void fromJSON_nullPrivateKeyId() throws IOException {
+ void fromJSON_nullPrivateKeyId() {
GenericJson json =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -212,22 +232,18 @@ void fromJSON_nullPrivateKeyId() throws IOException {
CA_CERT_PATH,
TOKEN_SERVER_URI);
- try {
- GdchCredentials credentials = GdchCredentials.fromJson(json);
- fail("Should not be able to create GDCH credential without exception.");
- } catch (IOException ex) {
- assertTrue(
- ex.getMessage()
- .contains(
- String.format(
- "Error reading GDCH service account credential from JSON, "
- + "%s is misconfigured.",
- "private_key_id")));
- }
+ IOException ex = assertThrows(IOException.class, () -> GdchCredentials.fromJson(json));
+ assertTrue(
+ ex.getMessage()
+ .contains(
+ String.format(
+ "Error reading GDCH service account credential from JSON, "
+ + "%s is misconfigured.",
+ "private_key_id")));
}
@Test
- void fromJSON_nullPrivateKey() throws IOException {
+ void fromJSON_nullPrivateKey() {
GenericJson json =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -238,22 +254,18 @@ void fromJSON_nullPrivateKey() throws IOException {
CA_CERT_PATH,
TOKEN_SERVER_URI);
- try {
- GdchCredentials credentials = GdchCredentials.fromJson(json);
- fail("Should not be able to create GDCH credential without exception.");
- } catch (IOException ex) {
- assertTrue(
- ex.getMessage()
- .contains(
- String.format(
- "Error reading GDCH service account credential from JSON, "
- + "%s is misconfigured.",
- "private_key")));
- }
+ IOException ex = assertThrows(IOException.class, () -> GdchCredentials.fromJson(json));
+ assertTrue(
+ ex.getMessage()
+ .contains(
+ String.format(
+ "Error reading GDCH service account credential from JSON, "
+ + "%s is misconfigured.",
+ "private_key")));
}
@Test
- void fromJSON_nullServiceIdentityName() throws IOException {
+ void fromJSON_nullServiceIdentityName() {
GenericJson json =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -264,18 +276,14 @@ void fromJSON_nullServiceIdentityName() throws IOException {
CA_CERT_PATH,
TOKEN_SERVER_URI);
- try {
- GdchCredentials credentials = GdchCredentials.fromJson(json);
- fail("Should not be able to create GDCH credential without exception.");
- } catch (IOException ex) {
- assertTrue(
- ex.getMessage()
- .contains(
- String.format(
- "Error reading GDCH service account credential from JSON, "
- + "%s is misconfigured.",
- "name")));
- }
+ IOException ex = assertThrows(IOException.class, () -> GdchCredentials.fromJson(json));
+ assertTrue(
+ ex.getMessage()
+ .contains(
+ String.format(
+ "Error reading GDCH service account credential from JSON, "
+ + "%s is misconfigured.",
+ "name")));
}
@Test
@@ -294,7 +302,7 @@ void fromJSON_nullCaCertPath() throws IOException {
}
@Test
- void fromJSON_nullTokenServerUri() throws IOException {
+ void fromJSON_nullTokenServerUri() {
GenericJson json =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -305,22 +313,18 @@ void fromJSON_nullTokenServerUri() throws IOException {
CA_CERT_PATH,
null);
- try {
- GdchCredentials credentials = GdchCredentials.fromJson(json);
- fail("Should not be able to create GDCH credential without exception.");
- } catch (IOException ex) {
- assertTrue(
- ex.getMessage()
- .contains(
- String.format(
- "Error reading GDCH service account credential from JSON, "
- + "%s is misconfigured.",
- "token_uri")));
- }
+ IOException ex = assertThrows(IOException.class, () -> GdchCredentials.fromJson(json));
+ assertTrue(
+ ex.getMessage()
+ .contains(
+ String.format(
+ "Error reading GDCH service account credential from JSON, "
+ + "%s is misconfigured.",
+ "token_uri")));
}
@Test
- void fromJSON_invalidFormatVersion() throws IOException {
+ void fromJSON_invalidFormatVersion() {
GenericJson json =
writeGdchServiceAccountJson(
"100",
@@ -331,18 +335,14 @@ void fromJSON_invalidFormatVersion() throws IOException {
CA_CERT_PATH,
TOKEN_SERVER_URI);
- try {
- GdchCredentials credentials = GdchCredentials.fromJson(json);
- fail("Should not be able to create GDCH credential without exception.");
- } catch (IOException ex) {
- assertTrue(
- ex.getMessage()
- .contains(String.format("Only format version %s is supported", FORMAT_VERSION)));
- }
+ IOException ex = assertThrows(IOException.class, () -> GdchCredentials.fromJson(json));
+ assertTrue(
+ ex.getMessage()
+ .contains(String.format("Only format version %s is supported", FORMAT_VERSION)));
}
@Test
- void fromJSON_invalidCaCertPath() throws IOException {
+ void fromJSON_invalidCaCertPath() {
GenericJson json =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -353,12 +353,8 @@ void fromJSON_invalidCaCertPath() throws IOException {
"/path/to/missing/file",
TOKEN_SERVER_URI);
- try {
- GdchCredentials credentials = GdchCredentials.fromJson(json);
- fail("Should not be able to create GDCH credential without exception.");
- } catch (IOException ex) {
- assertTrue(ex.getMessage().contains("Error reading certificate file from CA cert path"));
- }
+ IOException ex = assertThrows(IOException.class, () -> GdchCredentials.fromJson(json));
+ assertTrue(ex.getMessage().contains("Error reading certificate file from CA cert path"));
}
@Test
@@ -414,6 +410,73 @@ void fromJSON_hasAccessToken() throws IOException {
TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN);
}
+ @Test
+ void fromStream_correct() throws IOException {
+ InputStream stream =
+ writeGdchServiceAccountStream(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_PKCS8,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ GdchCredentials credentials = GdchCredentials.fromStream(stream);
+
+ assertEquals(PROJECT_ID, credentials.getProjectId());
+ assertEquals(SERVICE_IDENTITY_NAME, credentials.getServiceIdentityName());
+ }
+
+ @Test
+ void fromStream_invalidType() throws IOException {
+ GenericJson json =
+ writeGdchServiceAccountJson(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_PKCS8,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ json.put("type", "invalid_type");
+ InputStream stream = TestUtils.jsonToInputStream(json);
+
+ IOException ex = assertThrows(IOException.class, () -> GdchCredentials.fromStream(stream));
+ assertTrue(ex.getMessage().contains("not recognized"));
+ }
+
+ @Test
+ void fromStream_withTransportFactory() throws IOException {
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ InputStream stream =
+ writeGdchServiceAccountStream(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_PKCS8,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ GdchCredentials credentials = GdchCredentials.fromStream(stream, transportFactory);
+
+ assertEquals(transportFactory, credentials.getTransportFactory());
+ }
+
+ @Test
+ void fromPem_correct() throws IOException {
+ GdchCredentials.Builder builder =
+ GdchCredentials.newBuilder()
+ .setProjectId(PROJECT_ID)
+ .setPrivateKeyId(PRIVATE_KEY_ID)
+ .setServiceIdentityName(SERVICE_IDENTITY_NAME)
+ .setTokenServerUri(TOKEN_SERVER_URI)
+ .setHttpTransportFactory(new MockTokenServerTransportFactory());
+
+ GdchCredentials credentials = GdchCredentials.fromPem(PRIVATE_KEY_PKCS8, builder);
+ assertNotNull(credentials.getPrivateKey());
+ assertEquals(PROJECT_ID, credentials.getProjectId());
+ }
+
@Test
void createWithGdchAudience_correct() throws IOException {
GenericJson json =
@@ -439,7 +502,7 @@ void createWithGdchAudience_correct() throws IOException {
assertEquals(SERVICE_IDENTITY_NAME, gdchWithAudience.getServiceIdentityName());
assertEquals(TOKEN_SERVER_URI, gdchWithAudience.getTokenServerUri());
assertEquals(CA_CERT_PATH, credentials.getCaCertPath());
- assertEquals(API_AUDIENCE, gdchWithAudience.getApiAudience());
+ assertEquals(API_AUDIENCE, gdchWithAudience.getGdchAudience());
}
@Test
@@ -455,12 +518,55 @@ void createWithGdchAudience_nullApiAudience() throws IOException {
TOKEN_SERVER_URI);
GdchCredentials credentials = GdchCredentials.fromJson(json);
- try {
- GdchCredentials gdchWithAudience = credentials.createWithGdchAudience(null);
- fail("Should not be able to create GDCH credential without exception.");
- } catch (NullPointerException ex) {
- assertTrue(ex.getMessage().contains("Audience are not configured for GDCH service account"));
- }
+ IllegalArgumentException ex =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> credentials.createWithGdchAudience((String) null));
+ assertTrue(
+ ex.getMessage().contains("Audience cannot be null or empty for GDCH service account"));
+ }
+
+ @Test
+ void createWithGdchAudience_emptyApiAudience() throws IOException {
+ GenericJson json =
+ writeGdchServiceAccountJson(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_PKCS8,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
+
+ IllegalArgumentException ex =
+ assertThrows(IllegalArgumentException.class, () -> credentials.createWithGdchAudience(""));
+ assertTrue(
+ ex.getMessage().contains("Audience cannot be null or empty for GDCH service account"));
+ }
+
+ @Test
+ void getGdchAudience_vs_getApiAudience() throws IOException {
+ GenericJson json =
+ writeGdchServiceAccountJson(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_PKCS8,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
+
+ String validUri = "https://valid-audience.com";
+ GdchCredentials validCredentials = credentials.createWithGdchAudience(validUri);
+ assertEquals(validUri, validCredentials.getGdchAudience());
+ assertEquals(URI.create(validUri), validCredentials.getApiAudience());
+
+ String invalidUri = "invalid uri ^";
+ GdchCredentials invalidCredentials = credentials.createWithGdchAudience(invalidUri);
+ assertEquals(invalidUri, invalidCredentials.getGdchAudience());
+ assertNull(invalidCredentials.getApiAudience());
}
@Test
@@ -477,7 +583,7 @@ void createAssertion_correct() throws IOException {
GdchCredentials credentials = GdchCredentials.fromJson(json);
JsonFactory jsonFactory = OAuth2Utils.JSON_FACTORY;
long currentTimeMillis = Clock.SYSTEM.currentTimeMillis();
- String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis, API_AUDIENCE);
+ String assertion = credentials.createAssertion(jsonFactory, currentTimeMillis);
JsonWebSignature signature = JsonWebSignature.parse(jsonFactory, assertion);
JsonWebToken.Payload payload = signature.getPayload();
@@ -548,30 +654,17 @@ void refreshAccessToken_nullApiAudience() throws IOException {
transportFactory.transport.addGdchServiceAccount(
GdchCredentials.getIssuerSubjectValue(PROJECT_ID, SERVICE_IDENTITY_NAME), tokenString);
transportFactory.transport.setTokenServerUri(TOKEN_SERVER_URI);
- try {
- AccessToken accessToken = credentials.refreshAccessToken();
- fail("Should not be able to refresh access token without exception.");
- } catch (NullPointerException ex) {
- assertTrue(
- ex.getMessage()
- .contains(
- "Audience are not configured for GDCH service account. Specify the "
- + "audience by calling createWithGDCHAudience"));
- }
+ NullPointerException ex =
+ assertThrows(NullPointerException.class, () -> credentials.refreshAccessToken());
+ assertTrue(
+ ex.getMessage()
+ .contains(
+ "Audience cannot be null or empty for GDCH service account credentials. "
+ + "Specify the audience by calling createWithGdchAudience"));
}
@Test
- void getIssuerSubjectValue_correct() throws IOException {
- GenericJson json =
- writeGdchServiceAccountJson(
- FORMAT_VERSION,
- PROJECT_ID,
- PRIVATE_KEY_ID,
- PRIVATE_KEY_PKCS8,
- SERVICE_IDENTITY_NAME,
- CA_CERT_PATH,
- TOKEN_SERVER_URI);
- GdchCredentials credentials = GdchCredentials.fromJson(json);
+ void getIssuerSubjectValue_correct() {
Object expectedIssSubValue =
String.format("system:serviceaccount:%s:%s", PROJECT_ID, SERVICE_IDENTITY_NAME);
assertEquals(
@@ -590,7 +683,7 @@ void equals_same() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials credentials = GdchCredentials.fromJson(json);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
GenericJson otherJson =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -600,14 +693,14 @@ void equals_same() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials otherCredentials = GdchCredentials.fromJson(otherJson);
- assertTrue(credentials.equals(otherCredentials));
- assertTrue(otherCredentials.equals(credentials));
+ GdchCredentials otherCredentials = GdchCredentials.fromJson(otherJson);
+ assertEquals(credentials, otherCredentials);
+ assertEquals(otherCredentials, credentials);
- credentials = ((GdchCredentials) credentials).createWithGdchAudience(API_AUDIENCE);
- otherCredentials = ((GdchCredentials) otherCredentials).createWithGdchAudience(API_AUDIENCE);
- assertTrue(credentials.equals(otherCredentials));
- assertTrue(otherCredentials.equals(credentials));
+ credentials = credentials.createWithGdchAudience(API_AUDIENCE);
+ otherCredentials = otherCredentials.createWithGdchAudience(API_AUDIENCE);
+ assertEquals(credentials, otherCredentials);
+ assertEquals(otherCredentials, credentials);
}
@Test
@@ -621,7 +714,7 @@ void equals_false_projectId() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials credentials = GdchCredentials.fromJson(json);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
GenericJson otherJson =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -631,14 +724,14 @@ void equals_false_projectId() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials otherCredentials = GdchCredentials.fromJson(otherJson);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ GdchCredentials otherCredentials = GdchCredentials.fromJson(otherJson);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
- credentials = ((GdchCredentials) credentials).createWithGdchAudience(API_AUDIENCE);
- otherCredentials = ((GdchCredentials) otherCredentials).createWithGdchAudience(API_AUDIENCE);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ credentials = credentials.createWithGdchAudience(API_AUDIENCE);
+ otherCredentials = otherCredentials.createWithGdchAudience(API_AUDIENCE);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -652,7 +745,7 @@ void equals_false_keyId() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials credentials = GdchCredentials.fromJson(json);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
GenericJson otherJson =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -662,14 +755,14 @@ void equals_false_keyId() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials otherCredentials = GdchCredentials.fromJson(otherJson);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ GdchCredentials otherCredentials = GdchCredentials.fromJson(otherJson);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
- credentials = ((GdchCredentials) credentials).createWithGdchAudience(API_AUDIENCE);
- otherCredentials = ((GdchCredentials) otherCredentials).createWithGdchAudience(API_AUDIENCE);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ credentials = credentials.createWithGdchAudience(API_AUDIENCE);
+ otherCredentials = otherCredentials.createWithGdchAudience(API_AUDIENCE);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -683,7 +776,7 @@ void equals_false_serviceIdentityName() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials credentials = GdchCredentials.fromJson(json);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
GenericJson otherJson =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -693,20 +786,22 @@ void equals_false_serviceIdentityName() throws IOException {
"otherServiceIdentityName",
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials otherCredentials = GdchCredentials.fromJson(otherJson);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ GdchCredentials otherCredentials = GdchCredentials.fromJson(otherJson);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
- credentials = ((GdchCredentials) credentials).createWithGdchAudience(API_AUDIENCE);
- otherCredentials = ((GdchCredentials) otherCredentials).createWithGdchAudience(API_AUDIENCE);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ credentials = credentials.createWithGdchAudience(API_AUDIENCE);
+ otherCredentials = otherCredentials.createWithGdchAudience(API_AUDIENCE);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
void equals_false_caCertPath() throws IOException {
File tmpDirectory = Files.createTempDirectory("tmpDirectory").toFile();
+ tmpDirectory.deleteOnExit();
File testCaCertFile = File.createTempFile("testCert", ".pem", tmpDirectory);
+ testCaCertFile.deleteOnExit();
GenericJson json =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -716,7 +811,7 @@ void equals_false_caCertPath() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials credentials = GdchCredentials.fromJson(json);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
GenericJson otherJson =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -726,16 +821,14 @@ void equals_false_caCertPath() throws IOException {
SERVICE_IDENTITY_NAME,
testCaCertFile.getPath(),
TOKEN_SERVER_URI);
- OAuth2Credentials otherCredentials = GdchCredentials.fromJson(otherJson);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
-
- credentials = ((GdchCredentials) credentials).createWithGdchAudience(API_AUDIENCE);
- otherCredentials = ((GdchCredentials) otherCredentials).createWithGdchAudience(API_AUDIENCE);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ GdchCredentials otherCredentials = GdchCredentials.fromJson(otherJson);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
- testCaCertFile.delete();
+ credentials = credentials.createWithGdchAudience(API_AUDIENCE);
+ otherCredentials = otherCredentials.createWithGdchAudience(API_AUDIENCE);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -749,7 +842,7 @@ void equals_false_tokenServer() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials credentials = GdchCredentials.fromJson(json);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
GenericJson otherJson =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -759,19 +852,19 @@ void equals_false_tokenServer() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
URI.create("https://foo1.com/bar"));
- OAuth2Credentials otherCredentials = GdchCredentials.fromJson(otherJson);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ GdchCredentials otherCredentials = GdchCredentials.fromJson(otherJson);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
- credentials = ((GdchCredentials) credentials).createWithGdchAudience(API_AUDIENCE);
- otherCredentials = ((GdchCredentials) otherCredentials).createWithGdchAudience(API_AUDIENCE);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ credentials = credentials.createWithGdchAudience(API_AUDIENCE);
+ otherCredentials = otherCredentials.createWithGdchAudience(API_AUDIENCE);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
void equals_false_apiAudience() throws IOException {
- URI otherApiAudience = URI.create("https://foo1.com/bar");
+ String otherApiAudience = URI.create("https://foo1.com/bar").toString();
GenericJson json =
writeGdchServiceAccountJson(
@@ -782,7 +875,7 @@ void equals_false_apiAudience() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials credentials = GdchCredentials.fromJson(json);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
GenericJson otherJson =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -792,13 +885,12 @@ void equals_false_apiAudience() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials otherCredentials = GdchCredentials.fromJson(otherJson);
+ GdchCredentials otherCredentials = GdchCredentials.fromJson(otherJson);
- credentials = ((GdchCredentials) credentials).createWithGdchAudience(API_AUDIENCE);
- otherCredentials =
- ((GdchCredentials) otherCredentials).createWithGdchAudience(otherApiAudience);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ credentials = credentials.createWithGdchAudience(API_AUDIENCE);
+ otherCredentials = otherCredentials.createWithGdchAudience(otherApiAudience);
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -812,8 +904,8 @@ void toString_containsFields() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials credentials = GdchCredentials.fromJson(json);
- credentials = ((GdchCredentials) credentials).createWithGdchAudience(API_AUDIENCE);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
+ credentials = credentials.createWithGdchAudience(API_AUDIENCE);
String expectedToString =
String.format(
"GdchCredentials{projectId=%s, privateKeyId=%s, serviceIdentityName=%s, "
@@ -839,7 +931,7 @@ void hashCode_equals() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials credentials = GdchCredentials.fromJson(json);
+ GdchCredentials credentials = GdchCredentials.fromJson(json);
GenericJson otherJson =
writeGdchServiceAccountJson(
FORMAT_VERSION,
@@ -849,11 +941,11 @@ void hashCode_equals() throws IOException {
SERVICE_IDENTITY_NAME,
CA_CERT_PATH,
TOKEN_SERVER_URI);
- OAuth2Credentials otherCredentials = GdchCredentials.fromJson(otherJson);
+ GdchCredentials otherCredentials = GdchCredentials.fromJson(otherJson);
assertEquals(credentials.hashCode(), otherCredentials.hashCode());
- credentials = ((GdchCredentials) credentials).createWithGdchAudience(API_AUDIENCE);
- otherCredentials = ((GdchCredentials) otherCredentials).createWithGdchAudience(API_AUDIENCE);
+ credentials = credentials.createWithGdchAudience(API_AUDIENCE);
+ otherCredentials = otherCredentials.createWithGdchAudience(API_AUDIENCE);
assertEquals(credentials.hashCode(), otherCredentials.hashCode());
}
@@ -876,12 +968,264 @@ void serialize_correct() throws IOException, ClassNotFoundException {
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
assertEquals(
MockTokenServerTransportFactory.class,
deserializedCredentials.toBuilder().getHttpTransportFactory().getClass());
}
+ @Test
+ void refreshAccessToken_invalidResponse_missingAccessToken() throws IOException {
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ GenericJson json =
+ writeGdchServiceAccountJson(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_PKCS8,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ GdchCredentials credentials = GdchCredentials.fromJson(json, transportFactory);
+ GdchCredentials gdchWithAudience = credentials.createWithGdchAudience(API_AUDIENCE);
+
+ transportFactory.transport.addGdchServiceAccount(
+ GdchCredentials.getIssuerSubjectValue(PROJECT_ID, SERVICE_IDENTITY_NAME), null);
+ transportFactory.transport.setTokenServerUri(TOKEN_SERVER_URI);
+
+ IOException ex = assertThrows(IOException.class, () -> gdchWithAudience.refreshAccessToken());
+ assertEquals(
+ "Error parsing token refresh response. Expected value access_token not found.",
+ ex.getMessage());
+ }
+
+ @Test
+ void refreshAccessToken_invalidResponse_wrongTypeAccessToken() throws IOException {
+ refreshAccessToken_invalidResponse(
+ "{\"access_token\": 123, \"expires_in\": 3600}",
+ "Error parsing token refresh response. Expected string value access_token of wrong type.");
+ }
+
+ @Test
+ void refreshAccessToken_invalidResponse_missingExpiresIn() throws IOException {
+ refreshAccessToken_invalidResponse(
+ "{\"access_token\": \"token\"}",
+ "Error parsing token refresh response. Expected value expires_in not found.");
+ }
+
+ @Test
+ void refreshAccessToken_invalidResponse_wrongTypeExpiresIn() throws IOException {
+ refreshAccessToken_invalidResponse(
+ "{\"access_token\": \"token\", \"expires_in\": \"3600\"}",
+ "Error parsing token refresh response. Expected integer value expires_in of wrong type.");
+ }
+
+ private void refreshAccessToken_invalidResponse(
+ String responseContent, String expectedErrorMessage) throws IOException {
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ GenericJson json =
+ writeGdchServiceAccountJson(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_PKCS8,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ GdchCredentials credentials = GdchCredentials.fromJson(json, transportFactory);
+ GdchCredentials gdchWithAudience = credentials.createWithGdchAudience(API_AUDIENCE);
+
+ transportFactory.transport.addResponseSequence(
+ new MockLowLevelHttpResponse().setContentType(Json.MEDIA_TYPE).setContent(responseContent));
+
+ IOException ex = assertThrows(IOException.class, () -> gdchWithAudience.refreshAccessToken());
+ assertEquals(expectedErrorMessage, ex.getMessage());
+ }
+
+ @Test
+ void refreshAccessToken_serverError() throws IOException {
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ GenericJson json =
+ writeGdchServiceAccountJson(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_PKCS8,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ GdchCredentials credentials = GdchCredentials.fromJson(json, transportFactory);
+ GdchCredentials gdchWithAudience = credentials.createWithGdchAudience(API_AUDIENCE);
+
+ transportFactory.transport.addResponseSequence(
+ new MockLowLevelHttpResponse().setStatusCode(400).setReasonPhrase("Bad Request"));
+
+ GoogleAuthException ex =
+ assertThrows(GoogleAuthException.class, () -> gdchWithAudience.refreshAccessToken());
+ assertTrue(ex.getMessage().contains("Error getting access token for GDCH service account"));
+ assertTrue(ex.getMessage().contains("400 Bad Request"));
+ }
+
+ @Test
+ void refreshAccessToken_ioException() throws IOException {
+ MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
+ GenericJson json =
+ writeGdchServiceAccountJson(
+ FORMAT_VERSION,
+ PROJECT_ID,
+ PRIVATE_KEY_ID,
+ PRIVATE_KEY_PKCS8,
+ SERVICE_IDENTITY_NAME,
+ CA_CERT_PATH,
+ TOKEN_SERVER_URI);
+ GdchCredentials credentials = GdchCredentials.fromJson(json, transportFactory);
+ GdchCredentials gdchWithAudience = credentials.createWithGdchAudience(API_AUDIENCE);
+
+ transportFactory.transport.addResponseErrorSequence(new IOException("Connection reset"));
+
+ GoogleAuthException ex =
+ assertThrows(GoogleAuthException.class, () -> gdchWithAudience.refreshAccessToken());
+ assertTrue(ex.getMessage().contains("Error getting access token for GDCH service account"));
+ assertTrue(ex.getMessage().contains("Connection reset"));
+ }
+
+ @Test
+ void transcodeDerToConcat_withGeneratedSignature() throws Exception {
+ // Generate a new key pair and a signature.
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
+ keyGen.initialize(new ECGenParameterSpec("secp256r1"));
+ KeyPair keyPair = keyGen.generateKeyPair();
+ Signature signer = Signature.getInstance("SHA256withECDSA");
+ signer.initSign(keyPair.getPrivate());
+ signer.update(new byte[] {1, 2, 3, 4});
+ byte[] derSignature = signer.sign();
+
+ // Transcode the signature and check length.
+ byte[] jwsSignature = GdchCredentials.transcodeDerToConcat(derSignature, 64);
+ assertEquals(64, jwsSignature.length);
+ }
+
+ @Test
+ void transcodeDerToConcat_invalidDerFormat() {
+ byte[] invalidDer = new byte[] {0x31, 0x00}; // Not a SEQUENCE
+ GoogleAuthException e =
+ assertThrows(
+ GoogleAuthException.class, () -> GdchCredentials.transcodeDerToConcat(invalidDer, 64));
+ assertEquals("Invalid DER signature format.", e.getMessage());
+ }
+
+ @Test
+ void transcodeDerToConcat_invalidLength() {
+ // SEQUENCE length doesn't match actual length
+ byte[] invalidDer = new byte[] {0x30, 0x05, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02};
+ GoogleAuthException e =
+ assertThrows(
+ GoogleAuthException.class, () -> GdchCredentials.transcodeDerToConcat(invalidDer, 64));
+ assertEquals("Invalid DER signature length.", e.getMessage());
+ }
+
+ @Test
+ void transcodeDerToConcat_invalidRInteger() {
+ // Uses BIT STRING (0x03) instead of INTEGER (0x02) for R
+ byte[] invalidDer = new byte[] {0x30, 0x06, 0x03, 0x01, 0x01, 0x02, 0x01, 0x02};
+ GoogleAuthException e =
+ assertThrows(
+ GoogleAuthException.class, () -> GdchCredentials.transcodeDerToConcat(invalidDer, 64));
+ assertEquals("Expected INTEGER for R.", e.getMessage());
+ }
+
+ @Test
+ void transcodeDerToConcat_invalidSInteger() {
+ // Uses BIT STRING (0x03) instead of INTEGER (0x02) for S
+ byte[] invalidDer = new byte[] {0x30, 0x06, 0x02, 0x01, 0x01, 0x03, 0x01, 0x01};
+ GoogleAuthException e =
+ assertThrows(
+ GoogleAuthException.class, () -> GdchCredentials.transcodeDerToConcat(invalidDer, 64));
+ assertEquals("Expected INTEGER for S.", e.getMessage());
+ }
+
+ @Test
+ void signUsingEsSha256_producesVerifiableSignature() throws Exception {
+ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
+ keyGen.initialize(new ECGenParameterSpec("secp256r1"));
+ KeyPair keyPair = keyGen.generateKeyPair();
+
+ JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
+
+ JsonWebSignature.Header header = new JsonWebSignature.Header();
+ header.setAlgorithm("ES256");
+ header.setType("JWT");
+ header.setKeyId("test-key-id");
+
+ JsonWebToken.Payload payload = new JsonWebToken.Payload();
+ payload.setIssuer("test-issuer");
+ payload.setAudience("test-audience");
+
+ String signedJws =
+ GdchCredentials.signUsingEsSha256(keyPair.getPrivate(), jsonFactory, header, payload);
+
+ // Verify the signature.
+ JsonWebSignature jws = JsonWebSignature.parse(jsonFactory, signedJws);
+ assertTrue(jws.verifySignature(keyPair.getPublic()));
+ }
+
+ @Test
+ void signUsingEsSha256_validStructure() throws Exception {
+ PrivateKey privateKey =
+ OAuth2Utils.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8, OAuth2Utils.Pkcs8Algorithm.EC);
+ JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
+
+ JsonWebSignature.Header header = new JsonWebSignature.Header();
+ header.setAlgorithm("ES256");
+ header.setType("JWT");
+ header.setKeyId(PRIVATE_KEY_ID);
+
+ JsonWebToken.Payload payload = new JsonWebToken.Payload();
+ payload.setIssuer("test-issuer");
+ payload.setAudience("test-audience");
+ payload.setSubject("test-subject");
+ payload.setIssuedAtTimeSeconds(1000L);
+ payload.setExpirationTimeSeconds(2000L);
+
+ String signedJws = GdchCredentials.signUsingEsSha256(privateKey, jsonFactory, header, payload);
+
+ // Verify JWS structure
+ String[] parts = signedJws.split("\\.");
+ assertEquals(3, parts.length);
+
+ // Verify header
+ JsonWebSignature.Header decodedHeader =
+ jsonFactory.fromInputStream(
+ new java.io.ByteArrayInputStream(Base64.getUrlDecoder().decode(parts[0])),
+ JsonWebSignature.Header.class);
+ assertEquals("ES256", decodedHeader.getAlgorithm());
+ assertEquals("JWT", decodedHeader.getType());
+ assertEquals(PRIVATE_KEY_ID, decodedHeader.getKeyId());
+
+ // Verify payload
+ JsonWebToken.Payload decodedPayload =
+ jsonFactory.fromInputStream(
+ new java.io.ByteArrayInputStream(Base64.getUrlDecoder().decode(parts[1])),
+ JsonWebToken.Payload.class);
+ assertEquals("test-issuer", decodedPayload.getIssuer());
+ assertEquals("test-audience", decodedPayload.getAudience());
+ assertEquals("test-subject", decodedPayload.getSubject());
+
+ // Verify signature format (64 bytes for ES256)
+ byte[] signatureBytes = Base64.getUrlDecoder().decode(parts[2]);
+ assertEquals(64, signatureBytes.length);
+ }
+
+ @Test
+ void builder_setGdchAudience_nullString() {
+ GdchCredentials.Builder builder = GdchCredentials.newBuilder();
+ IllegalArgumentException ex =
+ assertThrows(IllegalArgumentException.class, () -> builder.setGdchAudience((String) null));
+ assertTrue(
+ ex.getMessage()
+ .contains("Audience cannot be null or empty for GDCH service account credentials."));
+ }
+
static GenericJson writeGdchServiceAccountJson(
String formatVersion,
String project,
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleAuthUtilsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleAuthUtilsTest.java
index 7c883df0fe73..de7077ef6277 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleAuthUtilsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleAuthUtilsTest.java
@@ -47,8 +47,9 @@ void getWellKnownCredentialsPath_correct() {
// the base folder will be an empty string using.
File homeDir = new File("");
File configDir = new File(homeDir, ".config");
- File cloudConfigDir = new File(configDir, provider.CLOUDSDK_CONFIG_DIRECTORY);
- File wellKnownFile = new File(cloudConfigDir, provider.WELL_KNOWN_CREDENTIALS_FILE);
+ File cloudConfigDir = new File(configDir, DefaultCredentialsProvider.CLOUDSDK_CONFIG_DIRECTORY);
+ File wellKnownFile =
+ new File(cloudConfigDir, DefaultCredentialsProvider.WELL_KNOWN_CREDENTIALS_FILE);
String obtainedPath = GoogleAuthUtils.getWellKnownCredentialsPath(provider);
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java
index 503c87d54207..74aa9fae9ccd 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/GoogleCredentialsTest.java
@@ -33,12 +33,12 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.http.HttpStatusCodes;
import com.google.api.client.json.GenericJson;
@@ -71,7 +71,7 @@ class GoogleCredentialsTest extends BaseSerializationTest {
private static final String SA_PRIVATE_KEY_ID = "d84a4fefcf50791d4a90f2d7af17469d6282df9d";
private static final String SA_PRIVATE_KEY_PKCS8 =
ServiceAccountCredentialsTest.PRIVATE_KEY_PKCS8;
- private static final String GDCH_SA_FORMAT_VERSION = GdchCredentials.SUPPORTED_FORMAT_VERSION;
+
private static final String GDCH_SA_PROJECT_ID = "gdch-service-account-project-id";
private static final String GDCH_SA_PRIVATE_KEY_ID = "d84a4fefcf50791d4a90f2d7af17469d6282df9d";
private static final String GDCH_SA_PRIVATE_KEY_PKC8 = GdchCredentialsTest.PRIVATE_KEY_PKCS8;
@@ -82,7 +82,7 @@ class GoogleCredentialsTest extends BaseSerializationTest {
private static final String GDCH_SA_CA_CERT_FILE_NAME = "cert.pem";
private static final String GDCH_SA_CA_CERT_PATH =
GdchCredentialsTest.class.getClassLoader().getResource(GDCH_SA_CA_CERT_FILE_NAME).getPath();
- private static final URI GDCH_API_AUDIENCE = URI.create("https://gdch-api-audience");
+ private static final String GDCH_API_AUDIENCE = "https://gdch-api-audience";
private static final String USER_CLIENT_SECRET = "jakuaL9YyieakhECKL2SwZcu";
private static final String USER_CLIENT_ID = "ya29.1.AADtN_UtlxN3PuGAxrN2XQnZTVRvDyVWnYq4I6dws";
private static final String REFRESH_TOKEN = "1/Tl6awhpFjkMkSJoj1xsli0H2eL5YsMgU_NKPY2TyGWY";
@@ -100,13 +100,8 @@ class GoogleCredentialsTest extends BaseSerializationTest {
private static final String TPC_UNIVERSE = "foo.bar";
@Test
- void getApplicationDefault_nullTransport_throws() throws IOException {
- try {
- GoogleCredentials.getApplicationDefault(null);
- fail();
- } catch (NullPointerException expected) {
- // Expected
- }
+ void getApplicationDefault_nullTransport_throws() {
+ assertThrows(NullPointerException.class, () -> GoogleCredentials.getApplicationDefault(null));
}
@Test
@@ -114,29 +109,23 @@ void fromStream_unknownType_throws() throws IOException {
MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
GenericJson json = new GenericJson();
json.put("type", "unsupported_credential");
- InputStream stream = TestUtils.jsonToInputStream(json);
- try {
- GoogleCredentials.fromStream(stream, transportFactory);
- fail("Should throw if type is unknown.");
- } catch (IOException expected) {
+ try (InputStream stream = TestUtils.jsonToInputStream(json)) {
+ IOException exception =
+ assertThrows(
+ IOException.class, () -> GoogleCredentials.fromStream(stream, transportFactory));
String expectedError =
"Error reading credentials from stream, 'type' value "
+ "'unsupported_credential' not recognized. Valid values are 'authorized_user', "
+ "'service_account', 'gdch_service_account', 'external_account', "
+ "'external_account_authorized_user', 'impersonated_service_account'.";
- assertTrue(expected.getMessage().contains(expectedError));
+ assertTrue(exception.getMessage().contains(expectedError));
}
}
@Test
- void fromStream_nullTransport_throws() throws IOException {
+ void fromStream_nullTransport_throws() {
InputStream stream = new ByteArrayInputStream("foo".getBytes());
- try {
- GoogleCredentials.fromStream(stream, null);
- fail("Should throw if HttpTransportFactory is null");
- } catch (NullPointerException expected) {
- // Expected
- }
+ assertThrows(NullPointerException.class, () -> GoogleCredentials.fromStream(stream, null));
}
@Test
@@ -146,19 +135,17 @@ void fromStream_noType_throws() throws IOException {
ServiceAccountCredentialsTest.writeServiceAccountJson(
"project_id", QUOTA_PROJECT, "universe");
json.remove("type");
- InputStream stream = TestUtils.jsonToInputStream(json);
- try {
- GoogleCredentials.fromStream(stream, transportFactory);
- fail("Should throw if type is unknown.");
- } catch (IOException expected) {
+ try (InputStream stream = TestUtils.jsonToInputStream(json)) {
+ IOException exception =
+ assertThrows(
+ IOException.class, () -> GoogleCredentials.fromStream(stream, transportFactory));
String expectedError = "Error reading credentials from stream, 'type' field not specified.";
- assertEquals(expectedError, expected.getMessage());
+ assertEquals(expectedError, exception.getMessage());
}
}
@Test
void fromStream_nullStream_throws() {
- MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
assertThrows(NullPointerException.class, () -> GoogleCredentials.parseJsonInputStream(null));
}
@@ -175,7 +162,7 @@ void fromStream_serviceAccount_noUniverse_providesToken() throws IOException {
assertNotNull(credentials);
assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain());
- assertEquals(false, credentials.isExplicitUniverseDomain());
+ assertFalse(credentials.isExplicitUniverseDomain());
credentials = credentials.createScoped(SCOPES);
Map> metadata = credentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, ACCESS_TOKEN);
@@ -198,46 +185,62 @@ void fromStream_serviceAccount_Universe_noToken() throws IOException {
assertNotNull(credentials);
assertEquals(TPC_UNIVERSE, credentials.getUniverseDomain());
- assertEquals(true, credentials.isExplicitUniverseDomain());
+ assertTrue(credentials.isExplicitUniverseDomain());
credentials = credentials.createScoped(SCOPES);
- Map> metadata = credentials.getRequestMetadata(CALL_URI);
+ credentials.getRequestMetadata(CALL_URI);
assertNotNull(((ServiceAccountCredentials) credentials).getSelfSignedJwtCredentialsWithScope());
}
@Test
void fromStream_serviceAccountNoClientId_throws() throws IOException {
- InputStream serviceAccountStream =
+ try (InputStream serviceAccountStream =
ServiceAccountCredentialsTest.writeServiceAccountStream(
- null, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID);
-
- testFromStreamException(serviceAccountStream, "client_id");
+ null, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () -> GoogleCredentials.fromStream(serviceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("client_id"));
+ }
}
@Test
void fromStream_serviceAccountNoClientEmail_throws() throws IOException {
- InputStream serviceAccountStream =
+ try (InputStream serviceAccountStream =
ServiceAccountCredentialsTest.writeServiceAccountStream(
- SA_CLIENT_ID, null, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID);
-
- testFromStreamException(serviceAccountStream, "client_email");
+ SA_CLIENT_ID, null, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () -> GoogleCredentials.fromStream(serviceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("client_email"));
+ }
}
@Test
void fromStream_serviceAccountNoPrivateKey_throws() throws IOException {
- InputStream serviceAccountStream =
+ try (InputStream serviceAccountStream =
ServiceAccountCredentialsTest.writeServiceAccountStream(
- SA_CLIENT_ID, SA_CLIENT_EMAIL, null, SA_PRIVATE_KEY_ID);
-
- testFromStreamException(serviceAccountStream, "private_key");
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, null, SA_PRIVATE_KEY_ID)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () -> GoogleCredentials.fromStream(serviceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("private_key"));
+ }
}
@Test
void fromStream_serviceAccountNoPrivateKeyId_throws() throws IOException {
- InputStream serviceAccountStream =
+ try (InputStream serviceAccountStream =
ServiceAccountCredentialsTest.writeServiceAccountStream(
- SA_CLIENT_ID, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, null);
-
- testFromStreamException(serviceAccountStream, "private_key_id");
+ SA_CLIENT_ID, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, null)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () -> GoogleCredentials.fromStream(serviceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("private_key_id"));
+ }
}
@Test
@@ -245,7 +248,7 @@ void fromStream_gdchServiceAccount_correct() throws IOException {
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
- GDCH_SA_FORMAT_VERSION,
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION,
GDCH_SA_PROJECT_ID,
GDCH_SA_PRIVATE_KEY_ID,
GDCH_SA_PRIVATE_KEY_PKC8,
@@ -256,8 +259,8 @@ void fromStream_gdchServiceAccount_correct() throws IOException {
GoogleCredentials.fromStream(gdchServiceAccountStream, transportFactory);
assertNotNull(credentials);
- assertTrue(credentials instanceof GdchCredentials);
- assertEquals(GDCH_SA_PROJECT_ID, ((GdchCredentials) credentials).getProjectId());
+ assertInstanceOf(GdchCredentials.class, credentials);
+ assertEquals(GDCH_SA_PROJECT_ID, credentials.getProjectId());
assertEquals(
GDCH_SA_SERVICE_IDENTITY_NAME, ((GdchCredentials) credentials).getServiceIdentityName());
assertEquals(GDCH_SA_TOKEN_SERVER_URI, ((GdchCredentials) credentials).getTokenServerUri());
@@ -267,8 +270,8 @@ void fromStream_gdchServiceAccount_correct() throws IOException {
credentials = ((GdchCredentials) credentials).createWithGdchAudience(GDCH_API_AUDIENCE);
assertNotNull(credentials);
- assertTrue(credentials instanceof GdchCredentials);
- assertEquals(GDCH_SA_PROJECT_ID, ((GdchCredentials) credentials).getProjectId());
+ assertTrue(true);
+ assertEquals(GDCH_SA_PROJECT_ID, credentials.getProjectId());
assertEquals(
GDCH_SA_SERVICE_IDENTITY_NAME, ((GdchCredentials) credentials).getServiceIdentityName());
assertEquals(GDCH_SA_TOKEN_SERVER_URI, ((GdchCredentials) credentials).getTokenServerUri());
@@ -278,7 +281,7 @@ void fromStream_gdchServiceAccount_correct() throws IOException {
@Test
void fromStream_gdchServiceAccountNoFormatVersion_throws() throws IOException {
- InputStream gdchServiceAccountStream =
+ try (InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
null,
GDCH_SA_PROJECT_ID,
@@ -286,89 +289,119 @@ void fromStream_gdchServiceAccountNoFormatVersion_throws() throws IOException {
GDCH_SA_PRIVATE_KEY_PKC8,
GDCH_SA_SERVICE_IDENTITY_NAME,
GDCH_SA_CA_CERT_PATH,
- GDCH_SA_TOKEN_SERVER_URI);
-
- testFromStreamException(gdchServiceAccountStream, "format_version");
+ GDCH_SA_TOKEN_SERVER_URI)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ GoogleCredentials.fromStream(gdchServiceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("format_version"));
+ }
}
@Test
void fromStream_gdchServiceAccountNoProjectId_throws() throws IOException {
- InputStream gdchServiceAccountStream =
+ try (InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
- GDCH_SA_FORMAT_VERSION,
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION,
null,
GDCH_SA_PRIVATE_KEY_ID,
GDCH_SA_PRIVATE_KEY_PKC8,
GDCH_SA_SERVICE_IDENTITY_NAME,
GDCH_SA_CA_CERT_PATH,
- GDCH_SA_TOKEN_SERVER_URI);
-
- testFromStreamException(gdchServiceAccountStream, "project");
+ GDCH_SA_TOKEN_SERVER_URI)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ GoogleCredentials.fromStream(gdchServiceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("project"));
+ }
}
@Test
void fromStream_gdchServiceAccountNoPrivateKeyId_throws() throws IOException {
- InputStream gdchServiceAccountStream =
+ try (InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
- GDCH_SA_FORMAT_VERSION,
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION,
GDCH_SA_PROJECT_ID,
null,
GDCH_SA_PRIVATE_KEY_PKC8,
GDCH_SA_SERVICE_IDENTITY_NAME,
GDCH_SA_CA_CERT_PATH,
- GDCH_SA_TOKEN_SERVER_URI);
-
- testFromStreamException(gdchServiceAccountStream, "private_key_id");
+ GDCH_SA_TOKEN_SERVER_URI)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ GoogleCredentials.fromStream(gdchServiceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("private_key_id"));
+ }
}
@Test
void fromStream_gdchServiceAccountNoPrivateKey_throws() throws IOException {
- InputStream gdchServiceAccountStream =
+ try (InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
- GDCH_SA_FORMAT_VERSION,
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION,
GDCH_SA_PROJECT_ID,
GDCH_SA_PRIVATE_KEY_ID,
null,
GDCH_SA_SERVICE_IDENTITY_NAME,
GDCH_SA_CA_CERT_PATH,
- GDCH_SA_TOKEN_SERVER_URI);
-
- testFromStreamException(gdchServiceAccountStream, "private_key");
+ GDCH_SA_TOKEN_SERVER_URI)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ GoogleCredentials.fromStream(gdchServiceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("private_key"));
+ }
}
@Test
void fromStream_gdchServiceAccountNoServiceIdentityName_throws() throws IOException {
- InputStream gdchServiceAccountStream =
+ try (InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
- GDCH_SA_FORMAT_VERSION,
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION,
GDCH_SA_PROJECT_ID,
GDCH_SA_PRIVATE_KEY_ID,
GDCH_SA_PRIVATE_KEY_PKC8,
null,
GDCH_SA_CA_CERT_PATH,
- GDCH_SA_TOKEN_SERVER_URI);
-
- testFromStreamException(gdchServiceAccountStream, "name");
+ GDCH_SA_TOKEN_SERVER_URI)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ GoogleCredentials.fromStream(gdchServiceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("name"));
+ }
}
@Test
void fromStream_gdchServiceAccountNoTokenServerUri_throws() throws IOException {
- InputStream gdchServiceAccountStream =
+ try (InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
- GDCH_SA_FORMAT_VERSION,
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION,
GDCH_SA_PROJECT_ID,
GDCH_SA_PRIVATE_KEY_ID,
GDCH_SA_PRIVATE_KEY_PKC8,
GDCH_SA_SERVICE_IDENTITY_NAME,
GDCH_SA_CA_CERT_PATH,
- null);
-
- testFromStreamException(gdchServiceAccountStream, "token_uri");
+ null)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ GoogleCredentials.fromStream(gdchServiceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("token_uri"));
+ }
}
@Test
void fromStream_gdchServiceAccountInvalidFormatVersion_throws() throws IOException {
- InputStream gdchServiceAccountStream =
+ try (InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
"100",
GDCH_SA_PROJECT_ID,
@@ -376,28 +409,41 @@ void fromStream_gdchServiceAccountInvalidFormatVersion_throws() throws IOExcepti
GDCH_SA_PRIVATE_KEY_PKC8,
GDCH_SA_SERVICE_IDENTITY_NAME,
GDCH_SA_CA_CERT_PATH,
- GDCH_SA_TOKEN_SERVER_URI);
-
- testFromStreamException(
- gdchServiceAccountStream,
- String.format("Only format version %s is supported", GDCH_SA_FORMAT_VERSION));
+ GDCH_SA_TOKEN_SERVER_URI)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ GoogleCredentials.fromStream(gdchServiceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(
+ exception
+ .getMessage()
+ .contains(
+ String.format(
+ "Only format version %s is supported",
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION)));
+ }
}
@Test
void fromStream_gdchServiceAccountInvalidCaCertPath_throws() throws IOException {
- InputStream gdchServiceAccountStream =
+ try (InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
- GDCH_SA_FORMAT_VERSION,
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION,
GDCH_SA_PROJECT_ID,
GDCH_SA_PRIVATE_KEY_ID,
GDCH_SA_PRIVATE_KEY_PKC8,
GDCH_SA_SERVICE_IDENTITY_NAME,
"/path/to/missing/file",
- GDCH_SA_TOKEN_SERVER_URI);
-
- testFromStreamException(
- gdchServiceAccountStream,
- String.format("Error reading certificate file from CA cert path"));
+ GDCH_SA_TOKEN_SERVER_URI)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ GoogleCredentials.fromStream(gdchServiceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(
+ exception.getMessage().contains("Error reading certificate file from CA cert path"));
+ }
}
@Test
@@ -430,27 +476,40 @@ void fromStream_userCredentials_defaultUniverse() throws IOException {
@Test
void fromStream_userCredentials_NoClientId_throws() throws IOException {
- InputStream userStream =
- UserCredentialsTest.writeUserStream(null, USER_CLIENT_SECRET, REFRESH_TOKEN, QUOTA_PROJECT);
-
- testFromStreamException(userStream, "client_id");
+ try (InputStream userStream =
+ UserCredentialsTest.writeUserStream(
+ null, USER_CLIENT_SECRET, REFRESH_TOKEN, QUOTA_PROJECT)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () -> GoogleCredentials.fromStream(userStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("client_id"));
+ }
}
@Test
void fromStream_userCredentials_NoClientSecret_throws() throws IOException {
- InputStream userStream =
- UserCredentialsTest.writeUserStream(USER_CLIENT_ID, null, REFRESH_TOKEN, QUOTA_PROJECT);
-
- testFromStreamException(userStream, "client_secret");
+ try (InputStream userStream =
+ UserCredentialsTest.writeUserStream(USER_CLIENT_ID, null, REFRESH_TOKEN, QUOTA_PROJECT)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () -> GoogleCredentials.fromStream(userStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("client_secret"));
+ }
}
@Test
void fromStream_userCredentials_NoRefreshToken_throws() throws IOException {
- InputStream userStream =
+ try (InputStream userStream =
UserCredentialsTest.writeUserStream(
- USER_CLIENT_ID, USER_CLIENT_SECRET, null, QUOTA_PROJECT);
-
- testFromStreamException(userStream, "refresh_token");
+ USER_CLIENT_ID, USER_CLIENT_SECRET, null, QUOTA_PROJECT)) {
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () -> GoogleCredentials.fromStream(userStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("refresh_token"));
+ }
}
@Test
@@ -723,7 +782,7 @@ void create_withoutUniverse() throws IOException {
GoogleCredentials credentials = GoogleCredentials.create(token);
assertEquals(GOOGLE_DEFAULT_UNIVERSE, credentials.getUniverseDomain());
- assertEquals(false, credentials.isExplicitUniverseDomain());
+ assertFalse(credentials.isExplicitUniverseDomain());
}
@Test
@@ -732,7 +791,7 @@ void create_withUniverse() throws IOException {
GoogleCredentials credentials = GoogleCredentials.create("some-universe", token);
assertEquals("some-universe", credentials.getUniverseDomain());
- assertEquals(true, credentials.isExplicitUniverseDomain());
+ assertTrue(credentials.isExplicitUniverseDomain());
}
@Test
@@ -748,7 +807,7 @@ void buildWithQuotaProject() {
assertEquals("", withEmptyQuota.getQuotaProjectId());
GoogleCredentials sameCredentials = googleCredentials.createWithQuotaProject(null);
- assertEquals(null, sameCredentials.getQuotaProjectId());
+ assertNull(sameCredentials.getQuotaProjectId());
}
@Test
@@ -758,17 +817,17 @@ void buildWithUniverseDomain() throws IOException {
GoogleCredentials updated = original.toBuilder().setUniverseDomain("universe2").build();
assertEquals("universe1", original.getUniverseDomain());
- assertEquals(true, original.isExplicitUniverseDomain());
+ assertTrue(original.isExplicitUniverseDomain());
assertEquals("universe2", updated.getUniverseDomain());
- assertEquals(true, updated.isExplicitUniverseDomain());
+ assertTrue(updated.isExplicitUniverseDomain());
GoogleCredentials withEmpty = original.toBuilder().setUniverseDomain("").build();
assertEquals(GOOGLE_DEFAULT_UNIVERSE, withEmpty.getUniverseDomain());
- assertEquals(false, withEmpty.isExplicitUniverseDomain());
+ assertFalse(withEmpty.isExplicitUniverseDomain());
GoogleCredentials withNull = original.toBuilder().setUniverseDomain(null).build();
assertEquals(GOOGLE_DEFAULT_UNIVERSE, withNull.getUniverseDomain());
- assertEquals(false, withNull.isExplicitUniverseDomain());
+ assertFalse(withNull.isExplicitUniverseDomain());
}
@Test
@@ -778,22 +837,22 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(testCredentials, deserializedCredentials);
assertEquals(testCredentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(testCredentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
}
@Test
- void toString_containsFields() throws IOException {
+ void toString_containsFields() {
String expectedToString =
String.format(
"GoogleCredentials{quotaProjectId=%s, universeDomain=%s, isExplicitUniverseDomain=%s}",
- "some-project", "googleapis.com", false, "[some scope]");
+ "some-project", "googleapis.com", false);
GoogleCredentials credentials =
GoogleCredentials.newBuilder().setQuotaProjectId("some-project").build();
assertEquals(expectedToString, credentials.toString());
}
@Test
- void hashCode_equals() throws IOException {
+ void hashCode_equals() {
GoogleCredentials credentials =
GoogleCredentials.newBuilder().setUniverseDomain("some-domain").build();
GoogleCredentials otherCredentials =
@@ -802,24 +861,13 @@ void hashCode_equals() throws IOException {
}
@Test
- void equals_true() throws IOException {
+ void equals_true() {
GoogleCredentials credentials =
GoogleCredentials.newBuilder().setUniverseDomain("some-domain").build();
GoogleCredentials otherCredentials =
GoogleCredentials.newBuilder().setUniverseDomain("some-domain").build();
- assertTrue(credentials.equals(otherCredentials));
- assertTrue(otherCredentials.equals(credentials));
- }
-
- private static void testFromStreamException(InputStream stream, String expectedMessageContent) {
- try {
- GoogleCredentials.fromStream(stream, DUMMY_TRANSPORT_FACTORY);
- fail(
- String.format(
- "Should throw exception with message containing '%s'", expectedMessageContent));
- } catch (IOException expected) {
- assertTrue(expected.getMessage().contains(expectedMessageContent));
- }
+ assertEquals(credentials, otherCredentials);
+ assertEquals(otherCredentials, credentials);
}
@Test
@@ -854,7 +902,7 @@ void getCredentialInfo_userCredentials() throws IOException {
void getCredentialInfo_gdchCredentials() throws IOException {
InputStream gdchServiceAccountStream =
GdchCredentialsTest.writeGdchServiceAccountStream(
- GDCH_SA_FORMAT_VERSION,
+ GdchCredentials.SUPPORTED_JSON_FORMAT_VERSION,
GDCH_SA_PROJECT_ID,
GDCH_SA_PRIVATE_KEY_ID,
GDCH_SA_PRIVATE_KEY_PKC8,
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ITDownscopingTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ITDownscopingTest.java
index 2a04d771030d..5422760c4396 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ITDownscopingTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ITDownscopingTest.java
@@ -32,8 +32,8 @@
package com.google.auth.oauth2;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
@@ -122,12 +122,11 @@ public AccessToken refreshAccessToken() throws IOException {
// Attempt to retrieve the object that the downscoped token does not have access to. This should
// fail.
- try {
- retrieveObjectFromGcs(credentials, GCS_OBJECT_NAME_WITHOUT_PERMISSION);
- fail("Call to GCS should have failed.");
- } catch (HttpResponseException e) {
- assertEquals(403, e.getStatusCode());
- }
+ HttpResponseException e =
+ assertThrows(
+ HttpResponseException.class,
+ () -> retrieveObjectFromGcs(credentials, GCS_OBJECT_NAME_WITHOUT_PERMISSION));
+ assertEquals(403, e.getStatusCode());
}
private void retrieveObjectFromGcs(Credentials credentials, String objectName)
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ITWorkloadIdentityFederationTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ITWorkloadIdentityFederationTest.java
index d1574a06a2fc..0f1cdd3092f6 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ITWorkloadIdentityFederationTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ITWorkloadIdentityFederationTest.java
@@ -312,13 +312,13 @@ private GenericJson buildIdentityPoolCredentialConfig() throws IOException {
private GenericJson buildPluggableCredentialConfig() throws IOException {
String idToken = generateGoogleIdToken(OIDC_AUDIENCE);
- Instant expiration_time = Instant.now().plusSeconds(60 * 60);
+ Instant expirationTime = Instant.now().plusSeconds(60 * 60);
GenericJson executableJson = new GenericJson();
executableJson.setFactory(OAuth2Utils.JSON_FACTORY);
executableJson.put("success", true);
executableJson.put("version", 1);
- executableJson.put("expiration_time", expiration_time.toEpochMilli());
+ executableJson.put("expirationTime", expirationTime.toEpochMilli());
executableJson.put("token_type", "urn:ietf:params:oauth:token-type:jwt");
executableJson.put("id_token", idToken);
@@ -403,8 +403,8 @@ private void callGcs(GoogleCredentials credentials) throws IOException {
}
/**
- * Generates a Google ID token using the iamcredentials generateIdToken API.
- * https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials#sa-credentials-oidc
+ * Generates a Google ID token using the iamcredentials generateIdToken API. ...
*/
private String generateGoogleIdToken(String audience) throws IOException {
GoogleCredentials googleCredentials =
@@ -451,10 +451,10 @@ private String getXmlValueByTagName(String rawXml, String tagName) {
return null;
}
- private class ITAwsSecurityCredentialsProvider implements AwsSecurityCredentialsSupplier {
+ private static class ITAwsSecurityCredentialsProvider implements AwsSecurityCredentialsSupplier {
- private String region;
- private AwsSecurityCredentials credentials;
+ private final String region;
+ private final AwsSecurityCredentials credentials;
ITAwsSecurityCredentialsProvider(String region, AwsSecurityCredentials credentials) {
this.region = region;
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/IdTokenTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/IdTokenTest.java
index 52fa2c00885e..6ab42fa49e2f 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/IdTokenTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/IdTokenTest.java
@@ -32,8 +32,7 @@
package com.google.auth.oauth2;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import java.io.IOException;
import java.util.Date;
@@ -61,16 +60,16 @@ void constructor() throws IOException {
void equals_true() throws IOException {
IdToken accessToken = IdToken.create(TOKEN_1);
IdToken otherAccessToken = IdToken.create(TOKEN_1);
- assertTrue(accessToken.equals(otherAccessToken));
- assertTrue(otherAccessToken.equals(accessToken));
+ assertEquals(accessToken, otherAccessToken);
+ assertEquals(otherAccessToken, accessToken);
}
@Test
void equals_false_token() throws IOException {
IdToken accessToken = IdToken.create(TOKEN_1);
IdToken otherAccessToken = IdToken.create(TOKEN_2);
- assertFalse(accessToken.equals(otherAccessToken));
- assertFalse(otherAccessToken.equals(accessToken));
+ assertNotEquals(accessToken, otherAccessToken);
+ assertNotEquals(otherAccessToken, accessToken);
}
@Test
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/IdentityPoolCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/IdentityPoolCredentialsTest.java
index 6997c79b0ef2..674d523e5090 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/IdentityPoolCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/IdentityPoolCredentialsTest.java
@@ -34,14 +34,12 @@
import static com.google.auth.Credentials.GOOGLE_DEFAULT_UNIVERSE;
import static com.google.auth.oauth2.MockExternalAccountCredentialsTransport.SERVICE_ACCOUNT_IMPERSONATION_URL;
import static com.google.auth.oauth2.OAuth2Utils.JSON_FACTORY;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.GenericJson;
@@ -78,7 +76,7 @@ class IdentityPoolCredentialsTest extends BaseSerializationTest {
(ExternalAccountSupplierContext context) -> "testSubjectToken";
@Test
- void createdScoped_clonedCredentialWithAddedScopes() throws IOException {
+ void createdScoped_clonedCredentialWithAddedScopes() {
IdentityPoolCredentials credentials =
IdentityPoolCredentials.newBuilder(createBaseFileSourcedCredentials())
.setServiceAccountImpersonationUrl(SERVICE_ACCOUNT_IMPERSONATION_URL)
@@ -188,12 +186,11 @@ void retrieveSubjectToken_fileSourcedWithNullFormat_throws() throws IOException
credentialSourceMap.put("file", file.getAbsolutePath());
credentialSourceMap.put("format", formatMap);
- try {
- new IdentityPoolCredentialSource(credentialSourceMap);
- fail("Exception should be thrown due to null format.");
- } catch (IllegalArgumentException e) {
- assertEquals("Invalid credential source format type: null.", e.getMessage());
- }
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new IdentityPoolCredentialSource(credentialSourceMap));
+ assertEquals("Invalid credential source format type: null.", e.getMessage());
}
@Test
@@ -209,14 +206,10 @@ void retrieveSubjectToken_noFile_throws() {
.setCredentialSource(credentialSource)
.build();
- try {
- credentials.retrieveSubjectToken();
- fail("Exception should be thrown.");
- } catch (IOException e) {
- assertEquals(
- String.format("Invalid credential location. The file at %s does not exist.", path),
- e.getMessage());
- }
+ IOException e = assertThrows(IOException.class, credentials::retrieveSubjectToken);
+ assertEquals(
+ String.format("Invalid credential location. The file at %s does not exist.", path),
+ e.getMessage());
}
@Test
@@ -276,15 +269,11 @@ void retrieveSubjectToken_urlSourcedCredential_throws() {
buildUrlBasedCredentialSource(transportFactory.transport.getMetadataUrl()))
.build();
- try {
- credential.retrieveSubjectToken();
- fail("Exception should be thrown.");
- } catch (IOException e) {
- assertEquals(
- String.format(
- "Error getting subject token from metadata server: %s", response.getMessage()),
- e.getMessage());
- }
+ IOException e = assertThrows(IOException.class, credential::retrieveSubjectToken);
+ assertEquals(
+ String.format(
+ "Error getting subject token from metadata server: %s", response.getMessage()),
+ e.getMessage());
}
@Test
@@ -303,7 +292,7 @@ void retrieveSubjectToken_provider() throws IOException {
}
@Test
- void retrieveSubjectToken_providerThrowsError() throws IOException {
+ void retrieveSubjectToken_providerThrowsError() {
IOException testException = new IOException("test");
IdentityPoolSubjectTokenSupplier errorProvider =
@@ -316,12 +305,8 @@ void retrieveSubjectToken_providerThrowsError() throws IOException {
.setSubjectTokenSupplier(errorProvider)
.build();
- try {
- String subjectToken = credentials.retrieveSubjectToken();
- fail("retrieveSubjectToken should fail.");
- } catch (IOException e) {
- assertEquals("test", e.getMessage());
- }
+ IOException e = assertThrows(IOException.class, credentials::retrieveSubjectToken);
+ assertEquals("test", e.getMessage());
}
@Test
@@ -458,7 +443,7 @@ void refreshAccessToken_withServiceAccountImpersonationOptions() throws IOExcept
.setCredentialSource(
buildUrlBasedCredentialSource(transportFactory.transport.getMetadataUrl()))
.setServiceAccountImpersonationOptions(
- ExternalAccountCredentialsTest.buildServiceAccountImpersonationOptions(2800))
+ ExternalAccountCredentialsTest.buildServiceAccountImpersonationOptions())
.build();
AccessToken accessToken = credential.refreshAccessToken();
@@ -590,7 +575,7 @@ void refreshAccessToken_workforceWithServiceAccountImpersonationOptions() throws
buildUrlBasedCredentialSource(transportFactory.transport.getMetadataUrl()))
.setWorkforcePoolUserProject("userProject")
.setServiceAccountImpersonationOptions(
- ExternalAccountCredentialsTest.buildServiceAccountImpersonationOptions(2800))
+ ExternalAccountCredentialsTest.buildServiceAccountImpersonationOptions())
.build();
AccessToken accessToken = credential.refreshAccessToken();
@@ -646,7 +631,7 @@ void identityPoolCredentialSource_validFormats() {
credentialSourceMapWithUrlJsonTextSource);
for (Map source : sources) {
// Should not throw.
- new IdentityPoolCredentialSource(source);
+ assertDoesNotThrow(() -> new IdentityPoolCredentialSource(source));
}
}
@@ -689,20 +674,20 @@ void identityPoolCredentialSource_caseInsensitive() {
credentialSourceMapWithUrlJsonTextSource);
for (Map source : sources) {
// Should not throw.
- new IdentityPoolCredentialSource(source);
+ assertDoesNotThrow(() -> new IdentityPoolCredentialSource(source));
}
}
@Test
void identityPoolCredentialSource_invalidSourceType() {
- try {
- new IdentityPoolCredentialSource(new HashMap<>());
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- "Missing credential source file location, URL, or certificate. At least one must be specified.",
- exception.getMessage());
- }
+ HashMap credentialSourceMap = new HashMap<>();
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new IdentityPoolCredentialSource(credentialSourceMap));
+ assertEquals(
+ "Missing credential source file location, URL, or certificate. At least one must be specified.",
+ e.getMessage());
}
@Test
@@ -714,12 +699,11 @@ void identityPoolCredentialSource_invalidFormatType() {
format.put("type", "unsupportedType");
credentialSourceMap.put("format", format);
- try {
- new IdentityPoolCredentialSource(credentialSourceMap);
- fail("Exception should be thrown.");
- } catch (IllegalArgumentException e) {
- assertEquals("Invalid credential source format type: unsupportedType.", e.getMessage());
- }
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new IdentityPoolCredentialSource(credentialSourceMap));
+ assertEquals("Invalid credential source format type: unsupportedType.", e.getMessage());
}
@Test
@@ -731,12 +715,11 @@ void identityPoolCredentialSource_nullFormatType() {
format.put("type", null);
credentialSourceMap.put("format", format);
- try {
- new IdentityPoolCredentialSource(credentialSourceMap);
- fail("Exception should be thrown.");
- } catch (IllegalArgumentException e) {
- assertEquals("Invalid credential source format type: null.", e.getMessage());
- }
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new IdentityPoolCredentialSource(credentialSourceMap));
+ assertEquals("Invalid credential source format type: null.", e.getMessage());
}
@Test
@@ -748,18 +731,17 @@ void identityPoolCredentialSource_subjectTokenFieldNameUnset() {
format.put("type", "json");
credentialSourceMap.put("format", format);
- try {
- new IdentityPoolCredentialSource(credentialSourceMap);
- fail("Exception should be thrown.");
- } catch (IllegalArgumentException e) {
- assertEquals(
- "When specifying a JSON credential type, the subject_token_field_name must be set.",
- e.getMessage());
- }
+ IllegalArgumentException e =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new IdentityPoolCredentialSource(credentialSourceMap));
+ assertEquals(
+ "When specifying a JSON credential type, the subject_token_field_name must be set.",
+ e.getMessage());
}
@Test
- void builder_allFields() throws IOException {
+ void builder_allFields() {
List scopes = Arrays.asList("scope1", "scope2");
IdentityPoolCredentialSource credentialSource = createFileCredentialSource();
@@ -831,23 +813,20 @@ void builder_invalidWorkforceAudiences_throws() {
"//iam.googleapis.com/locations/global/workforce/providers");
for (String audience : invalidAudiences) {
- try {
- IdentityPoolCredentials.newBuilder()
- .setWorkforcePoolUserProject("workforcePoolUserProject")
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setAudience(audience)
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .setTokenInfoUrl("tokenInfoUrl")
- .setCredentialSource(createFileCredentialSource())
- .setQuotaProjectId("quotaProjectId")
- .build();
- fail("Exception should be thrown.");
- } catch (IllegalArgumentException e) {
- assertEquals(
- "The workforce_pool_user_project parameter should only be provided for a Workforce Pool configuration.",
- e.getMessage());
- }
+ IdentityPoolCredentials.Builder builder =
+ IdentityPoolCredentials.newBuilder()
+ .setWorkforcePoolUserProject("workforcePoolUserProject")
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setAudience(audience)
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL)
+ .setTokenInfoUrl("tokenInfoUrl")
+ .setCredentialSource(createFileCredentialSource())
+ .setQuotaProjectId("quotaProjectId");
+ IllegalArgumentException e = assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals(
+ "The workforce_pool_user_project parameter should only be provided for a Workforce Pool configuration.",
+ e.getMessage());
}
}
@@ -872,44 +851,37 @@ void builder_emptyWorkforceUserProjectWithWorkforceAudience() {
@Test
void builder_supplierAndCredSourceThrows() {
- try {
- IdentityPoolCredentials credentials =
- IdentityPoolCredentials.newBuilder()
- .setSubjectTokenSupplier(testProvider)
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setAudience("audience")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .setCredentialSource(createFileCredentialSource())
- .build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- "IdentityPoolCredentials cannot have both a subjectTokenSupplier and a credentialSource.",
- exception.getMessage());
- }
+ IdentityPoolCredentials.Builder builder =
+ IdentityPoolCredentials.newBuilder()
+ .setSubjectTokenSupplier(testProvider)
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setAudience("audience")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL)
+ .setCredentialSource(createFileCredentialSource());
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals(
+ "IdentityPoolCredentials cannot have both a subjectTokenSupplier and a credentialSource.",
+ exception.getMessage());
}
@Test
- void builder_noSupplierOrCredSourceThrows() throws IOException {
-
- try {
- IdentityPoolCredentials credentials =
- IdentityPoolCredentials.newBuilder()
- .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
- .setAudience("audience")
- .setSubjectTokenType("subjectTokenType")
- .setTokenUrl(STS_URL)
- .build();
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- "A subjectTokenSupplier or a credentialSource must be provided.", exception.getMessage());
- }
+ void builder_noSupplierOrCredSourceThrows() {
+ IdentityPoolCredentials.Builder builder =
+ IdentityPoolCredentials.newBuilder()
+ .setHttpTransportFactory(OAuth2Utils.HTTP_TRANSPORT_FACTORY)
+ .setAudience("audience")
+ .setSubjectTokenType("subjectTokenType")
+ .setTokenUrl(STS_URL);
+ IllegalArgumentException exception =
+ assertThrows(IllegalArgumentException.class, builder::build);
+ assertEquals(
+ "A subjectTokenSupplier or a credentialSource must be provided.", exception.getMessage());
}
@Test
- void builder_missingUniverseDomain_defaults() throws IOException {
+ void builder_missingUniverseDomain_defaults() {
List scopes = Arrays.asList("scope1", "scope2");
IdentityPoolCredentialSource credentialSource = createFileCredentialSource();
@@ -944,7 +916,7 @@ void builder_missingUniverseDomain_defaults() throws IOException {
}
@Test
- void newBuilder_allFields() throws IOException {
+ void newBuilder_allFields() {
List scopes = Arrays.asList("scope1", "scope2");
IdentityPoolCredentials credentials =
@@ -986,7 +958,7 @@ void newBuilder_allFields() throws IOException {
}
@Test
- void newBuilder_noUniverseDomain_defaults() throws IOException {
+ void newBuilder_noUniverseDomain_defaults() {
List scopes = Arrays.asList("scope1", "scope2");
IdentityPoolCredentials credentials =
@@ -1045,14 +1017,42 @@ void serialize() throws IOException, ClassNotFoundException {
}
@Test
- void build_withCertificateSourceAndCustomX509Provider_success()
- throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
- // Create an empty KeyStore and a spy on a custom X509Provider.
- KeyStore keyStore = KeyStore.getInstance("JKS");
- keyStore.load(null, null);
- TestX509Provider x509Provider =
- spy(new TestX509Provider(keyStore, "/path/to/certificate.json"));
+ void build_withCertificateSource_succeeds() throws Exception {
+ // Set up credential source for certificate type.
+ Map certificateMap = new HashMap<>();
+ certificateMap.put("use_default_certificate_config", false);
+ certificateMap.put("certificate_config_location", "testresources/mtls/certificate_config.json");
+ Map credentialSourceMap = new HashMap<>();
+ credentialSourceMap.put("certificate", certificateMap);
+ IdentityPoolCredentialSource credentialSource =
+ new IdentityPoolCredentialSource(credentialSourceMap);
+ MockExternalAccountCredentialsTransportFactory mockTransportFactory =
+ new MockExternalAccountCredentialsTransportFactory();
+ // Build credentials.
+ IdentityPoolCredentials credentials =
+ IdentityPoolCredentials.newBuilder()
+ .setHttpTransportFactory(mockTransportFactory)
+ .setAudience("test-audience")
+ .setSubjectTokenType("test-token-type")
+ .setCredentialSource(credentialSource)
+ .build();
+
+ // Verify successful creation and correct internal setup.
+ assertNotNull(credentials, "Credentials should be successfully created");
+ assertTrue(
+ credentials.getIdentityPoolSubjectTokenSupplier()
+ instanceof CertificateIdentityPoolSubjectTokenSupplier,
+ "Subject token supplier should be for certificates");
+ assertEquals(
+ IdentityPoolCredentials.CERTIFICATE_METRICS_HEADER_VALUE,
+ credentials.getCredentialSourceType(),
+ "Metrics header should indicate certificate source");
+ }
+
+ @Test
+ void build_withDefaultCertificateConfig_success()
+ throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
// Set up credential source for certificate type.
Map certificateMap = new HashMap<>();
certificateMap.put("use_default_certificate_config", true);
@@ -1063,11 +1063,18 @@ void build_withCertificateSourceAndCustomX509Provider_success()
MockExternalAccountCredentialsTransportFactory mockTransportFactory =
new MockExternalAccountCredentialsTransportFactory();
- // Build credentials with the custom provider.
+ // Use the pre-existing test configuration file to bypass well-known path resolution.
+ EnvironmentProvider mockEnvProvider =
+ name ->
+ "GOOGLE_API_CERTIFICATE_CONFIG".equals(name)
+ ? new File("testresources/mtls/certificate_config.json").getAbsolutePath()
+ : null;
+
+ // Build credentials using the default provider (no setX509Provider).
IdentityPoolCredentials credentials =
IdentityPoolCredentials.newBuilder()
- .setX509Provider(x509Provider)
.setHttpTransportFactory(mockTransportFactory)
+ .setEnvironmentProvider(mockEnvProvider)
.setAudience("test-audience")
.setSubjectTokenType("test-token-type")
.setCredentialSource(credentialSource)
@@ -1083,10 +1090,6 @@ void build_withCertificateSourceAndCustomX509Provider_success()
IdentityPoolCredentials.CERTIFICATE_METRICS_HEADER_VALUE,
credentials.getCredentialSourceType(),
"Metrics header should indicate certificate source");
-
- // Verify the custom provider methods were called during build.
- verify(x509Provider).getKeyStore();
- verify(x509Provider).getCertificatePath();
}
@Test
@@ -1148,15 +1151,17 @@ void build_withCustomProvider_throwsOnGetKeyStore()
@Test
void build_withCustomProvider_throwsOnGetCertificatePath()
throws IOException, KeyStoreException, CertificateException, NoSuchAlgorithmException {
- // Simulate a scenario where the X509Provider cannot access or read the certificate
- // configuration file needed to determine the certificate path, resulting in an IOException.
+ // Simulate a scenario where path resolution fails during build with a custom
+ // provider.
+ // We achieve this by passing a non-existent configuration path which causes
+ // MtlsUtils to throw
+ // IOException.
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(null, null);
TestX509Provider x509Provider = new TestX509Provider(keyStore, "/path/to/certificate.json");
- x509Provider.setShouldThrowOnGetCertificatePath(true); // Configure to throw
Map certificateMap = new HashMap<>();
- certificateMap.put("certificate_config_location", "/path/to/certificate.json");
+ certificateMap.put("certificate_config_location", "/non/existent/path.json");
// Expect RuntimeException because the constructor wraps the IOException.
RuntimeException exception =
@@ -1164,10 +1169,9 @@ void build_withCustomProvider_throwsOnGetCertificatePath()
RuntimeException.class,
() -> createCredentialsWithCertificate(x509Provider, certificateMap));
- // Verify the cause is the expected IOException from the mock.
+ // Verify the cause is the expected IOException (or subclass) from MtlsUtils.
assertNotNull(exception.getCause());
assertTrue(exception.getCause() instanceof IOException);
- assertEquals("Simulated IOException on certificate path", exception.getCause().getMessage());
// Verify the wrapper exception message
assertEquals(
@@ -1276,7 +1280,6 @@ private static class TestX509Provider extends X509Provider {
private final KeyStore keyStore;
private final String certificatePath;
private boolean shouldThrowOnGetKeyStore = false;
- private boolean shouldThrowOnGetCertificatePath = false;
TestX509Provider(KeyStore keyStore, String certificatePath) {
super();
@@ -1292,20 +1295,8 @@ public KeyStore getKeyStore() throws IOException {
return keyStore;
}
- @Override
- public String getCertificatePath() throws IOException {
- if (shouldThrowOnGetCertificatePath) {
- throw new IOException("Simulated IOException on certificate path");
- }
- return certificatePath;
- }
-
void setShouldThrowOnGetKeyStore(boolean shouldThrow) {
this.shouldThrowOnGetKeyStore = shouldThrow;
}
-
- void setShouldThrowOnGetCertificatePath(boolean shouldThrow) {
- this.shouldThrowOnGetCertificatePath = shouldThrow;
- }
}
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java
index 0a70c1ec7839..044aa0ce6755 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ImpersonatedCredentialsTest.java
@@ -34,12 +34,12 @@
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -48,6 +48,7 @@
import com.google.api.client.json.GenericJson;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.JsonGenerator;
+import com.google.api.client.json.JsonParser;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.json.webtoken.JsonWebToken.Payload;
import com.google.api.client.testing.http.MockLowLevelHttpRequest;
@@ -123,10 +124,6 @@ class ImpersonatedCredentialsTest extends BaseSerializationTest {
private static final JsonFactory JSON_FACTORY = GsonFactory.getDefaultInstance();
private static final String TEST_UNIVERSE_DOMAIN = "test.xyz";
- private static final String OLD_IMPERSONATION_URL =
- "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/"
- + IMPERSONATED_CLIENT_EMAIL
- + ":generateAccessToken";
public static final String DEFAULT_IMPERSONATION_URL =
String.format(
IamUtils.IAM_ACCESS_TOKEN_ENDPOINT_FORMAT,
@@ -194,8 +191,7 @@ void fromJson_userAsSource_WithQuotaProjectId() throws IOException {
assertEquals(DELEGATES, credentials.getDelegates());
assertEquals(IMMUTABLE_SCOPES_LIST, credentials.getScopes());
assertEquals(3600, credentials.getLifetime());
- GoogleCredentials sourceCredentials = credentials.getSourceCredentials();
- assertTrue(sourceCredentials instanceof UserCredentials);
+ assertInstanceOf(UserCredentials.class, credentials.getSourceCredentials());
}
@Test()
@@ -217,8 +213,7 @@ void fromJson_userAsSource_WithoutQuotaProjectId() throws IOException {
assertEquals(DELEGATES, credentials.getDelegates());
assertEquals(IMMUTABLE_SCOPES_LIST, credentials.getScopes());
assertEquals(3600, credentials.getLifetime());
- GoogleCredentials sourceCredentials = credentials.getSourceCredentials();
- assertTrue(sourceCredentials instanceof UserCredentials);
+ assertInstanceOf(UserCredentials.class, credentials.getSourceCredentials());
}
@Test()
@@ -241,8 +236,7 @@ void fromJson_userAsSource_MissingDelegatesField() throws IOException {
assertEquals(new ArrayList(), credentials.getDelegates());
assertEquals(IMMUTABLE_SCOPES_LIST, credentials.getScopes());
assertEquals(3600, credentials.getLifetime());
- GoogleCredentials sourceCredentials = credentials.getSourceCredentials();
- assertTrue(sourceCredentials instanceof UserCredentials);
+ assertInstanceOf(UserCredentials.class, credentials.getSourceCredentials());
}
@Test()
@@ -258,19 +252,17 @@ void fromJson_ServiceAccountAsSource() throws IOException {
assertEquals(DELEGATES, credentials.getDelegates());
assertEquals(IMMUTABLE_SCOPES_LIST, credentials.getScopes());
assertEquals(3600, credentials.getLifetime());
- GoogleCredentials sourceCredentials = credentials.getSourceCredentials();
- assertTrue(sourceCredentials instanceof ServiceAccountCredentials);
+ assertInstanceOf(ServiceAccountCredentials.class, credentials.getSourceCredentials());
}
@Test()
- void fromJson_InvalidFormat() throws IOException {
+ void fromJson_InvalidFormat() {
GenericJson json = buildInvalidCredentialsJson();
- try {
- ImpersonatedCredentials.fromJson(json, mockTransportFactory);
- fail("An exception should be thrown.");
- } catch (CredentialFormatException e) {
- assertEquals("An invalid input stream was provided.", e.getMessage());
- }
+ CredentialFormatException e =
+ assertThrows(
+ CredentialFormatException.class,
+ () -> ImpersonatedCredentials.fromJson(json, mockTransportFactory));
+ assertEquals("An invalid input stream was provided.", e.getMessage());
}
@Test()
@@ -280,7 +272,7 @@ void createScopedRequired_True() {
sourceCredentials,
IMPERSONATED_CLIENT_EMAIL,
null,
- new ArrayList(),
+ new ArrayList<>(),
VALID_LIFETIME,
mockTransportFactory);
assertTrue(targetCredentials.createScopedRequired());
@@ -311,15 +303,15 @@ void createScoped() {
mockTransportFactory,
QUOTA_PROJECT_ID);
- ImpersonatedCredentials scoped_credentials =
+ ImpersonatedCredentials scopedCredentials =
(ImpersonatedCredentials) targetCredentials.createScoped(IMMUTABLE_SCOPES_LIST);
- assertEquals(targetCredentials.getAccount(), scoped_credentials.getAccount());
- assertEquals(targetCredentials.getDelegates(), scoped_credentials.getDelegates());
- assertEquals(targetCredentials.getLifetime(), scoped_credentials.getLifetime());
+ assertEquals(targetCredentials.getAccount(), scopedCredentials.getAccount());
+ assertEquals(targetCredentials.getDelegates(), scopedCredentials.getDelegates());
+ assertEquals(targetCredentials.getLifetime(), scopedCredentials.getLifetime());
assertEquals(
- targetCredentials.getSourceCredentials(), scoped_credentials.getSourceCredentials());
- assertEquals(targetCredentials.getQuotaProjectId(), scoped_credentials.getQuotaProjectId());
- assertEquals(Arrays.asList("scope1", "scope2"), scoped_credentials.getScopes());
+ targetCredentials.getSourceCredentials(), scopedCredentials.getSourceCredentials());
+ assertEquals(targetCredentials.getQuotaProjectId(), scopedCredentials.getQuotaProjectId());
+ assertEquals(Arrays.asList("scope1", "scope2"), scopedCredentials.getScopes());
}
@Test
@@ -341,10 +333,10 @@ void createScoped_existingAccessTokenInvalidated() throws IOException {
targetCredentials.refresh();
assertEquals(ACCESS_TOKEN, targetCredentials.getAccessToken().getTokenValue());
- ImpersonatedCredentials scoped_credentials =
+ ImpersonatedCredentials scopedCredentials =
(ImpersonatedCredentials) targetCredentials.createScoped(IMMUTABLE_SCOPES_LIST);
- assertNull(scoped_credentials.getAccessToken());
+ assertNull(scopedCredentials.getAccessToken());
}
@Test
@@ -359,15 +351,15 @@ void createScopedWithImmutableScopes() {
mockTransportFactory,
QUOTA_PROJECT_ID);
- ImpersonatedCredentials scoped_credentials =
+ ImpersonatedCredentials scopedCredentials =
(ImpersonatedCredentials) targetCredentials.createScoped(IMMUTABLE_SCOPES_SET);
- assertEquals(targetCredentials.getAccount(), scoped_credentials.getAccount());
- assertEquals(targetCredentials.getDelegates(), scoped_credentials.getDelegates());
- assertEquals(targetCredentials.getLifetime(), scoped_credentials.getLifetime());
+ assertEquals(targetCredentials.getAccount(), scopedCredentials.getAccount());
+ assertEquals(targetCredentials.getDelegates(), scopedCredentials.getDelegates());
+ assertEquals(targetCredentials.getLifetime(), scopedCredentials.getLifetime());
assertEquals(
- targetCredentials.getSourceCredentials(), scoped_credentials.getSourceCredentials());
- assertEquals(targetCredentials.getQuotaProjectId(), scoped_credentials.getQuotaProjectId());
- assertEquals(Arrays.asList("scope1", "scope2"), scoped_credentials.getScopes());
+ targetCredentials.getSourceCredentials(), scopedCredentials.getSourceCredentials());
+ assertEquals(targetCredentials.getQuotaProjectId(), scopedCredentials.getQuotaProjectId());
+ assertEquals(Arrays.asList("scope1", "scope2"), scopedCredentials.getScopes());
}
@Test
@@ -383,10 +375,10 @@ void createScopedWithIamEndpointOverride() {
QUOTA_PROJECT_ID,
IMPERSONATION_OVERRIDE_URL);
- ImpersonatedCredentials scoped_credentials =
+ ImpersonatedCredentials scopedCredentials =
(ImpersonatedCredentials) targetCredentials.createScoped(IMMUTABLE_SCOPES_SET);
assertEquals(
- targetCredentials.getIamEndpointOverride(), scoped_credentials.getIamEndpointOverride());
+ targetCredentials.getIamEndpointOverride(), scopedCredentials.getIamEndpointOverride());
}
@Test
@@ -409,13 +401,9 @@ void refreshAccessToken_unauthorized() throws IOException {
VALID_LIFETIME,
mockTransportFactory);
- try {
- targetCredentials.refreshAccessToken().getTokenValue();
- fail(String.format("Should throw exception with message containing '%s'", expectedMessage));
- } catch (IOException expected) {
- assertEquals("Error requesting access token", expected.getMessage());
- assertTrue(expected.getCause().getMessage().contains(expectedMessage));
- }
+ IOException expected = assertThrows(IOException.class, targetCredentials::refreshAccessToken);
+ assertEquals("Error requesting access token", expected.getMessage());
+ assertTrue(expected.getCause().getMessage().contains(expectedMessage));
}
@Test()
@@ -439,13 +427,9 @@ void refreshAccessToken_malformedTarget() throws IOException {
VALID_LIFETIME,
mockTransportFactory);
- try {
- targetCredentials.refreshAccessToken().getTokenValue();
- fail(String.format("Should throw exception with message containing '%s'", expectedMessage));
- } catch (IOException expected) {
- assertEquals("Error requesting access token", expected.getMessage());
- assertTrue(expected.getCause().getMessage().contains(expectedMessage));
- }
+ IOException expected = assertThrows(IOException.class, targetCredentials::refreshAccessToken);
+ assertEquals("Error requesting access token", expected.getMessage());
+ assertTrue(expected.getCause().getMessage().contains(expectedMessage));
}
@Test()
@@ -457,28 +441,22 @@ void credential_with_zero_lifetime() throws IllegalStateException {
}
@Test()
- void credential_with_invalid_lifetime() throws IOException, IllegalStateException {
-
- try {
- ImpersonatedCredentials targetCredentials =
- ImpersonatedCredentials.create(
- sourceCredentials,
- IMPERSONATED_CLIENT_EMAIL,
- null,
- IMMUTABLE_SCOPES_LIST,
- INVALID_LIFETIME);
- targetCredentials.refreshAccessToken().getTokenValue();
- fail(
- String.format(
- "Should throw exception with message containing '%s'",
- "lifetime must be less than or equal to 43200"));
- } catch (IllegalStateException expected) {
- assertTrue(expected.getMessage().contains("lifetime must be less than or equal to 43200"));
- }
+ void credential_with_invalid_lifetime() throws IllegalStateException {
+ IllegalStateException expected =
+ assertThrows(
+ IllegalStateException.class,
+ () ->
+ ImpersonatedCredentials.create(
+ sourceCredentials,
+ IMPERSONATED_CLIENT_EMAIL,
+ null,
+ IMMUTABLE_SCOPES_LIST,
+ INVALID_LIFETIME));
+ assertTrue(expected.getMessage().contains("lifetime must be less than or equal to 43200"));
}
@Test()
- void credential_with_invalid_scope() throws IOException, IllegalStateException {
+ void credential_with_invalid_scope() throws IllegalStateException {
assertThrows(
NullPointerException.class,
() ->
@@ -667,12 +645,8 @@ void refreshAccessToken_invalidDate() throws IllegalStateException {
VALID_LIFETIME,
mockTransportFactory);
- try {
- targetCredentials.refreshAccessToken().getTokenValue();
- fail(String.format("Should throw exception with message containing '%s'", expectedMessage));
- } catch (IOException expected) {
- assertTrue(expected.getMessage().contains(expectedMessage));
- }
+ IOException expected = assertThrows(IOException.class, targetCredentials::refreshAccessToken);
+ assertTrue(expected.getMessage().contains(expectedMessage));
}
@Test
@@ -738,13 +712,13 @@ void sign_requestIncludesDelegates() throws IOException {
assertArrayEquals(expectedSignature, targetCredentials.sign(expectedSignature));
MockLowLevelHttpRequest request = mockTransportFactory.getTransport().getRequest();
- GenericJson body =
- JSON_FACTORY
- .createJsonParser(request.getContentAsString())
- .parseAndClose(GenericJson.class);
- List delegates = new ArrayList<>();
- delegates.add("delegate@example.com");
- assertEquals(delegates, body.get("delegates"));
+
+ try (JsonParser jsonParser = JSON_FACTORY.createJsonParser(request.getContentAsString())) {
+ GenericJson body = jsonParser.parseAndClose(GenericJson.class);
+ List delegates = new ArrayList<>();
+ delegates.add("delegate@example.com");
+ assertEquals(delegates, body.get("delegates"));
+ }
}
@Test
@@ -752,7 +726,7 @@ void sign_usesSourceCredentials() {
Calendar c = Calendar.getInstance();
c.add(Calendar.DATE, 1);
Date expiry = c.getTime();
- GoogleCredentials sourceCredentials =
+ GoogleCredentials sourceCred =
new GoogleCredentials.Builder()
.setAccessToken(new AccessToken("source-token", expiry))
.build();
@@ -763,7 +737,7 @@ void sign_usesSourceCredentials() {
mockTransportFactory.getTransport().addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_OK, "");
ImpersonatedCredentials targetCredentials =
ImpersonatedCredentials.create(
- sourceCredentials,
+ sourceCred,
IMPERSONATED_CLIENT_EMAIL,
ImmutableList.of("delegate@example.com"),
IMMUTABLE_SCOPES_LIST,
@@ -803,15 +777,11 @@ void sign_accessDenied_throws() {
.getTransport()
.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_FORBIDDEN, "Sign Error");
- try {
- byte[] bytes = {0xD, 0xE, 0xA, 0xD};
- targetCredentials.sign(bytes);
- fail("Signing should have failed");
- } catch (SigningException e) {
- assertEquals("Failed to sign the provided bytes", e.getMessage());
- assertNotNull(e.getCause());
- assertTrue(e.getCause().getMessage().contains("403"));
- }
+ SigningException e =
+ assertThrows(SigningException.class, () -> targetCredentials.sign(expectedSignature));
+ assertEquals("Failed to sign the provided bytes", e.getMessage());
+ assertNotNull(e.getCause());
+ assertTrue(e.getCause().getMessage().contains("403"));
}
@Test
@@ -836,15 +806,11 @@ void sign_serverError_throws() {
.getTransport()
.addStatusCodeAndMessage(HttpStatusCodes.STATUS_CODE_NOT_FOUND, "Sign Error");
- try {
- byte[] bytes = {0xD, 0xE, 0xA, 0xD};
- targetCredentials.sign(bytes);
- fail("Signing should have failed");
- } catch (SigningException e) {
- assertEquals("Failed to sign the provided bytes", e.getMessage());
- assertNotNull(e.getCause());
- assertTrue(e.getCause().getMessage().contains("404"));
- }
+ SigningException e =
+ assertThrows(SigningException.class, () -> targetCredentials.sign(expectedSignature));
+ assertEquals("Failed to sign the provided bytes", e.getMessage());
+ assertNotNull(e.getCause());
+ assertTrue(e.getCause().getMessage().contains("404"));
}
@Test
@@ -1039,12 +1005,8 @@ void idToken_withServerError() {
.setIdTokenProvider(targetCredentials)
.setTargetAudience(targetAudience)
.build();
- try {
- tokenCredential.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (IOException e) {
- assertTrue(e.getMessage().contains("Error code 500 trying to getIDToken"));
- }
+ IOException e = assertThrows(IOException.class, tokenCredential::refresh);
+ assertTrue(e.getMessage().contains("Error code 500 trying to getIDToken"));
}
@Test
@@ -1073,12 +1035,8 @@ void idToken_withOtherError() {
.setIdTokenProvider(targetCredentials)
.setTargetAudience(targetAudience)
.build();
- try {
- tokenCredential.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (IOException e) {
- assertTrue(e.getMessage().contains("Unexpected Error code 301 trying to getIDToken"));
- }
+ IOException e = assertThrows(IOException.class, tokenCredential::refresh);
+ assertTrue(e.getMessage().contains("Unexpected Error code 301 trying to getIDToken"));
}
@Test
@@ -1115,22 +1073,20 @@ void universeDomain_getFromSourceCredentials() throws IOException {
}
@Test
- void universeDomain_whenExplicit_notAllowedIfNotMatchToSourceUD() throws IOException {
+ void universeDomain_whenExplicit_notAllowedIfNotMatchToSourceUD() {
GoogleCredentials sourceCredentialsNonGDU =
sourceCredentials.toBuilder().setUniverseDomain("source.domain.xyz").build();
+ GoogleCredentials.Builder builder =
+ ImpersonatedCredentials.newBuilder()
+ .setSourceCredentials(sourceCredentialsNonGDU)
+ .setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL)
+ .setDelegates(null)
+ .setScopes(IMMUTABLE_SCOPES_LIST)
+ .setLifetime(VALID_LIFETIME)
+ .setHttpTransportFactory(mockTransportFactory)
+ .setUniverseDomain("explicit.domain.com");
IllegalStateException illegalStateException =
- assertThrows(
- IllegalStateException.class,
- () ->
- ImpersonatedCredentials.newBuilder()
- .setSourceCredentials(sourceCredentialsNonGDU)
- .setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL)
- .setDelegates(null)
- .setScopes(IMMUTABLE_SCOPES_LIST)
- .setLifetime(VALID_LIFETIME)
- .setHttpTransportFactory(mockTransportFactory)
- .setUniverseDomain("explicit.domain.com")
- .build());
+ assertThrows(IllegalStateException.class, builder::build);
assertEquals(
"Universe domain source.domain.xyz in source credentials"
+ " does not match explicit.domain.com universe domain set for impersonated credentials.",
@@ -1195,7 +1151,7 @@ void scopes_userConfiguredAndFromJson() throws IOException {
}
@Test
- void hashCode_equals() throws IOException {
+ void hashCode_equals() {
mockTransportFactory.getTransport().setTargetPrincipal(IMPERSONATED_CLIENT_EMAIL);
mockTransportFactory.getTransport().setAccessToken(ACCESS_TOKEN);
mockTransportFactory.getTransport().setExpireTime(getDefaultExpireTime());
@@ -1240,7 +1196,7 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(targetCredentials, deserializedCredentials);
assertEquals(targetCredentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(targetCredentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
}
/**
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/JwtCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/JwtCredentialsTest.java
index 95a4e3f4d81a..dc93eede2141 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/JwtCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/JwtCredentialsTest.java
@@ -35,7 +35,7 @@
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
-import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
@@ -95,51 +95,38 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.getClock(), Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.getClock());
}
@Test
void builder_requiresPrivateKey() {
- try {
- JwtClaims claims =
- JwtClaims.newBuilder()
- .setAudience("some-audience")
- .setIssuer("some-issuer")
- .setSubject("some-subject")
- .build();
- JwtCredentials.newBuilder().setJwtClaims(claims).setPrivateKeyId(PRIVATE_KEY_ID).build();
- fail("Should throw exception");
- } catch (NullPointerException ex) {
- // expected
- }
+ JwtClaims claims =
+ JwtClaims.newBuilder()
+ .setAudience("some-audience")
+ .setIssuer("some-issuer")
+ .setSubject("some-subject")
+ .build();
+ JwtCredentials.Builder builder =
+ JwtCredentials.newBuilder().setJwtClaims(claims).setPrivateKeyId(PRIVATE_KEY_ID);
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void builder_requiresClaims() {
- try {
- JwtCredentials.newBuilder()
- .setPrivateKeyId(PRIVATE_KEY_ID)
- .setPrivateKey(getPrivateKey())
- .build();
- fail("Should throw exception");
- } catch (NullPointerException ex) {
- // expected
- }
+ JwtCredentials.Builder builder =
+ JwtCredentials.newBuilder().setPrivateKeyId(PRIVATE_KEY_ID).setPrivateKey(getPrivateKey());
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void builder_requiresCompleteClaims() {
- try {
- JwtClaims claims = JwtClaims.newBuilder().build();
- JwtCredentials.newBuilder()
- .setJwtClaims(claims)
- .setPrivateKeyId(PRIVATE_KEY_ID)
- .setPrivateKey(getPrivateKey())
- .build();
- fail("Should throw exception");
- } catch (IllegalStateException ex) {
- // expected
- }
+ JwtClaims claims = JwtClaims.newBuilder().build();
+ JwtCredentials.Builder builder =
+ JwtCredentials.newBuilder()
+ .setJwtClaims(claims)
+ .setPrivateKeyId(PRIVATE_KEY_ID)
+ .setPrivateKey(getPrivateKey());
+ assertThrows(IllegalStateException.class, builder::build);
}
@Test
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockExternalAccountCredentialsTransport.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockExternalAccountCredentialsTransport.java
index fc9f8ba3e80b..7719b08d2e7b 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockExternalAccountCredentialsTransport.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockExternalAccountCredentialsTransport.java
@@ -84,11 +84,11 @@ public class MockExternalAccountCredentialsTransport extends MockHttpTransport {
static final String IAM_ENDPOINT = "https://iamcredentials.googleapis.com";
- private Queue responseSequence = new ArrayDeque<>();
- private Queue responseErrorSequence = new ArrayDeque<>();
- private Queue refreshTokenSequence = new ArrayDeque<>();
- private Queue> scopeSequence = new ArrayDeque<>();
- private List requests = new ArrayList<>();
+ private final Queue responseSequence = new ArrayDeque<>();
+ private final Queue responseErrorSequence = new ArrayDeque<>();
+ private final Queue refreshTokenSequence = new ArrayDeque<>();
+ private final Queue> scopeSequence = new ArrayDeque<>();
+ private final List requests = new ArrayList<>();
private String expireTime;
private String metadataServerContentType;
private String stsContent;
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockIAMCredentialsServiceTransportFactory.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockIAMCredentialsServiceTransportFactory.java
index a1df56b4b21a..c21a42f376cd 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockIAMCredentialsServiceTransportFactory.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockIAMCredentialsServiceTransportFactory.java
@@ -35,7 +35,7 @@
import com.google.auth.http.HttpTransportFactory;
public class MockIAMCredentialsServiceTransportFactory implements HttpTransportFactory {
- private MockIAMCredentialsServiceTransport transport;
+ private final MockIAMCredentialsServiceTransport transport;
MockIAMCredentialsServiceTransportFactory() {
this(Credentials.GOOGLE_DEFAULT_UNIVERSE);
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java
index 725a124fcd15..1b218b73ef45 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java
@@ -44,8 +44,7 @@
import com.google.common.io.BaseEncoding;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
-import java.net.MalformedURLException;
-import java.net.URL;
+import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.List;
@@ -168,10 +167,9 @@ public LowLevelHttpResponse execute() throws IOException {
GenericJson signContents = new GenericJson();
signContents.setFactory(OAuth2Utils.JSON_FACTORY);
signContents.put("signedBlob", BaseEncoding.base64().encode(signature));
-
- String signature = signContents.toPrettyString();
-
- return new MockLowLevelHttpResponse().setContentType(Json.MEDIA_TYPE).setContent(signature);
+ return new MockLowLevelHttpResponse()
+ .setContentType(Json.MEDIA_TYPE)
+ .setContent(signContents.toPrettyString());
}
};
}
@@ -228,7 +226,7 @@ public LowLevelHttpResponse execute() throws IOException {
}
private MockLowLevelHttpRequest getMockRequestForIdentityDocument(String url)
- throws MalformedURLException, UnsupportedEncodingException {
+ throws UnsupportedEncodingException {
if (statusCode != null && statusCode != HttpStatusCodes.STATUS_CODE_OK) {
return new MockLowLevelHttpRequest(url) {
@Override
@@ -254,7 +252,7 @@ public LowLevelHttpResponse execute() {
// https://cloud.google.com/compute/docs/instances/verifying-instance-identity#token_format
Map queryPairs = new HashMap();
- String query = (new URL(url)).getQuery();
+ String query = (URI.create(url)).getQuery();
String[] pairs = query.split("&");
for (String pair : pairs) {
int idx = pair.indexOf("=");
@@ -263,33 +261,29 @@ public LowLevelHttpResponse execute() {
URLDecoder.decode(pair.substring(idx + 1), "UTF-8"));
}
- if (queryPairs.containsKey("format")) {
- if (((String) queryPairs.get("format")).equals("full")) {
-
- // return licenses only if format=full is set
- if (queryPairs.containsKey("licenses")) {
- // The metadata server defaults to false and matches "on", "off" and ::absl::SimpleAtob.
- // See https://abseil.io/docs/cpp/guides/strings#numericConversion for more information.
- if (BOOL_PARAMETER_VALUE.matcher((String) queryPairs.get("licenses")).matches()) {
- return new MockLowLevelHttpRequest(url) {
- @Override
- public LowLevelHttpResponse execute() throws IOException {
- return new MockLowLevelHttpResponse()
- .setContent(ComputeEngineCredentialsTest.FULL_ID_TOKEN_WITH_LICENSES);
- }
- };
- }
- }
- // otherwise return full format
+ if (queryPairs.containsKey("format") && queryPairs.get("format").equals("full")) {
+ // return licenses only if format=full is set
+ if (queryPairs.containsKey("licenses")
+ && BOOL_PARAMETER_VALUE.matcher(queryPairs.get("licenses")).matches()) {
return new MockLowLevelHttpRequest(url) {
@Override
public LowLevelHttpResponse execute() throws IOException {
return new MockLowLevelHttpResponse()
- .setContent(ComputeEngineCredentialsTest.FULL_ID_TOKEN);
+ .setContent(ComputeEngineCredentialsTest.FULL_ID_TOKEN_WITH_LICENSES);
}
};
}
+
+ // otherwise return full format
+ return new MockLowLevelHttpRequest(url) {
+ @Override
+ public LowLevelHttpResponse execute() throws IOException {
+ return new MockLowLevelHttpResponse()
+ .setContent(ComputeEngineCredentialsTest.FULL_ID_TOKEN);
+ }
+ };
}
+
// Return default format if nothing is set
return new MockLowLevelHttpRequest(url) {
@Override
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockTokenCheckingTransport.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockTokenCheckingTransport.java
index 3ef4df2fe942..11af02041343 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockTokenCheckingTransport.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockTokenCheckingTransport.java
@@ -44,8 +44,8 @@ public class MockTokenCheckingTransport extends HttpTransport {
public static final String SUCCESS_CONTENT = "{\"key\":\"value\"}";
- private MockTokenServerTransport tokenServer;
- private String refreshToken;
+ private final MockTokenServerTransport tokenServer;
+ private final String refreshToken;
public MockTokenCheckingTransport(MockTokenServerTransport tokenServer, String refreshToken) {
this.tokenServer = tokenServer;
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java
index a61c185b5704..5a6cd2e5d1a8 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/MockTokenServerTransport.java
@@ -75,7 +75,6 @@ public class MockTokenServerTransport extends MockHttpTransport {
private final Queue> responseSequence = new ArrayDeque<>();
private int expiresInSeconds = 3600;
private MockLowLevelHttpRequest request;
- private ClientAuthenticationType clientAuthenticationType;
private PKCEProvider pkceProvider;
public MockTokenServerTransport() {}
@@ -88,9 +87,7 @@ public void setTokenServerUri(URI tokenServerUri) {
this.tokenServerUri = tokenServerUri;
}
- public void setClientAuthType(ClientAuthenticationType type) {
- this.clientAuthenticationType = type;
- }
+ public void setClientAuthType(ClientAuthenticationType type) {}
public void setPkceProvider(PKCEProvider pkceProvider) {
this.pkceProvider = pkceProvider;
@@ -141,9 +138,9 @@ public void setError(IOException error) {
this.error = error;
}
- public void addResponseErrorSequence(IOException... errors) {
- for (IOException error : errors) {
- responseSequence.add(Futures.immediateFailedFuture(error));
+ public void addResponseErrorSequence(IOException... ioExceptions) {
+ for (IOException ioException : ioExceptions) {
+ responseSequence.add(Futures.immediateFailedFuture(ioException));
}
}
@@ -173,7 +170,6 @@ public LowLevelHttpRequest buildRequest(String method, String url) throws IOExce
}
int questionMarkPos = url.indexOf('?');
final String urlWithoutQuery = (questionMarkPos > 0) ? url.substring(0, questionMarkPos) : url;
- final String query = (questionMarkPos > 0) ? url.substring(questionMarkPos + 1) : "";
if (!responseSequence.isEmpty()) {
request =
@@ -213,7 +209,7 @@ public LowLevelHttpResponse execute() throws IOException {
}
String content = this.getContentAsString();
- Map query = TestUtils.parseQuery(content);
+ Map query = parseRequestContent(content);
String accessToken = null;
String refreshToken = null;
String grantedScopesString = null;
@@ -255,16 +251,18 @@ public LowLevelHttpResponse execute() throws IOException {
} else if (query.containsKey("grant_type")) {
String grantType = query.get("grant_type");
String assertion = query.get("assertion");
+ if (assertion == null) {
+ assertion = query.get("subject_token");
+ }
JsonWebSignature signature = JsonWebSignature.parse(JSON_FACTORY, assertion);
if (OAuth2Utils.GRANT_TYPE_JWT_BEARER.equals(grantType)) {
String foundEmail = signature.getPayload().getIssuer();
- if (!serviceAccounts.containsKey(foundEmail)) {}
accessToken = serviceAccounts.get(foundEmail);
String foundTargetAudience =
(String) signature.getPayload().get("target_audience");
String foundScopes = (String) signature.getPayload().get("scope");
- if ((foundScopes == null || foundScopes.length() == 0)
- && (foundTargetAudience == null || foundTargetAudience.length() == 0)) {
+ if ((foundScopes == null || foundScopes.isEmpty())
+ && (foundTargetAudience == null || foundTargetAudience.isEmpty())) {
throw new IOException("Either target_audience or scopes must be specified.");
}
@@ -284,7 +282,10 @@ public LowLevelHttpResponse execute() throws IOException {
"GDCH Service Account Service Identity Name not found as issuer.");
}
accessToken = gdchServiceAccounts.get(foundServiceIdentityName);
- String foundApiAudience = (String) signature.getPayload().get("api_audience");
+ String foundApiAudience = query.get("audience");
+ if (foundApiAudience == null || foundApiAudience.isEmpty()) {
+ foundApiAudience = (String) signature.getPayload().get("api_audience");
+ }
if ((foundApiAudience == null || foundApiAudience.length() == 0)) {
throw new IOException("Api_audience must be specified.");
}
@@ -326,7 +327,7 @@ public LowLevelHttpResponse execute() throws IOException {
new MockLowLevelHttpRequest(url) {
@Override
public LowLevelHttpResponse execute() throws IOException {
- Map parameters = TestUtils.parseQuery(this.getContentAsString());
+ Map parameters = parseRequestContent(this.getContentAsString());
String token = parameters.get("token");
if (token == null) {
throw new IOException("Token to revoke not found.");
@@ -358,7 +359,7 @@ public LowLevelHttpResponse execute() throws IOException {
}
String content = this.getContentAsString();
- Map query = TestUtils.parseQuery(content);
+ Map query = parseRequestContent(content);
// Validate required fields.
if (!query.containsKey("code")
@@ -414,6 +415,13 @@ public LowLevelHttpResponse execute() throws IOException {
return super.buildRequest(method, url);
}
+ private Map parseRequestContent(String content) throws IOException {
+ if (content != null && content.trim().startsWith("{")) {
+ return TestUtils.parseJson(content);
+ }
+ return TestUtils.parseQuery(content);
+ }
+
private void validateAdditionalParameters(Map query) {
if (additionalParameters.containsKey(query.get("code"))) {
Map additionalParametersMap = additionalParameters.get(query.get("code"));
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsTest.java
index a54765abcbbb..c726006180ca 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsTest.java
@@ -32,14 +32,15 @@
package com.google.auth.oauth2;
import static java.util.concurrent.TimeUnit.HOURS;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.util.Clock;
import com.google.auth.TestClock;
@@ -100,7 +101,7 @@ void tearDown() {
void constructor_storesAccessToken() {
OAuth2Credentials credentials =
OAuth2Credentials.newBuilder().setAccessToken(new AccessToken(ACCESS_TOKEN, null)).build();
- assertEquals(credentials.getAccessToken().getTokenValue(), ACCESS_TOKEN);
+ assertEquals(ACCESS_TOKEN, credentials.getAccessToken().getTokenValue());
}
@Test
@@ -169,7 +170,7 @@ public AccessToken refreshAccessToken() throws IOException {
assertEquals(lastMetadata, callback.awaitResult());
waitForRefreshTaskCompletion(credentials);
assertEquals(1, refreshCount.get());
- lastMetadata = credentials.getRequestMetadata();
+ credentials.getRequestMetadata();
refreshCount.set(0);
// Fast forward to expired
@@ -181,7 +182,7 @@ public AccessToken refreshAccessToken() throws IOException {
TestUtils.assertContainsBearerToken(callback.awaitResult(), newToken.getTokenValue());
assertEquals(1, refreshCount.get());
waitForRefreshTaskCompletion(credentials);
- lastMetadata = credentials.getRequestMetadata();
+ credentials.getRequestMetadata();
}
@Test
@@ -192,7 +193,7 @@ void getAuthenticationType_returnsOAuth2() {
.setClientSecret(CLIENT_SECRET)
.setRefreshToken(REFRESH_TOKEN)
.build();
- assertEquals(credentials.getAuthenticationType(), "OAuth2");
+ assertEquals("OAuth2", credentials.getAuthenticationType());
}
@Test
@@ -214,7 +215,7 @@ void hasRequestMetadataOnly_returnsTrue() {
.setClientSecret(CLIENT_SECRET)
.setRefreshToken(REFRESH_TOKEN)
.build();
- assertTrue(credentials.hasRequestMetadata());
+ assertTrue(credentials.hasRequestMetadataOnly());
}
@Test
@@ -331,13 +332,9 @@ void getRequestMetadata_blocking_cachesExpiringToken() throws IOException {
clock.addToCurrentTime(60 * 60 * 1000);
assertEquals(0, transportFactory.transport.buildRequestCount);
- try {
- credentials.getRequestMetadata(CALL_URI);
- fail("Should throw");
- } catch (IOException e) {
- assertSame(error, e.getCause());
- assertEquals(1, transportFactory.transport.buildRequestCount--);
- }
+ IOException e = assertThrows(IOException.class, () -> credentials.getRequestMetadata(CALL_URI));
+ assertSame(error, e.getCause());
+ assertEquals(1, transportFactory.transport.buildRequestCount--);
// Reset the error and try again
transportFactory.transport.setError(null);
@@ -347,7 +344,7 @@ void getRequestMetadata_blocking_cachesExpiringToken() throws IOException {
}
@Test
- void getRequestMetadata_async() throws IOException {
+ void getRequestMetadata_async() {
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
@@ -668,12 +665,12 @@ public Map> call() throws Exception {
// Get the error that getRequestMetadata(uri) created
Throwable actualBlockingError =
- assertThrows(ExecutionException.class, () -> blockingCall.get()).getCause();
+ assertThrows(ExecutionException.class, blockingCall::get).getCause();
assertEquals(error, actualBlockingError);
RuntimeException actualAsyncError =
- assertThrows(RuntimeException.class, () -> callback1.awaitResult());
+ assertThrows(RuntimeException.class, callback1::awaitResult);
assertEquals(error, actualAsyncError);
}
@@ -692,12 +689,9 @@ public AccessToken refreshAccessToken() {
expectedStacktrace = expectedStacktrace.subList(1, expectedStacktrace.size());
AtomicReference actualError = new AtomicReference<>();
- try {
- creds.getRequestMetadata(CALL_URI);
- fail("Should not be able to use credential without exception.");
- } catch (Exception refreshError) {
- actualError.set(refreshError);
- }
+ Exception refreshError =
+ assertThrows(RuntimeException.class, () -> creds.getRequestMetadata(CALL_URI));
+ actualError.set(refreshError);
List actualStacktrace = Arrays.asList(actualError.get().getStackTrace());
actualStacktrace =
@@ -789,37 +783,37 @@ void refreshIfExpired_refreshesToken() throws IOException {
}
@Test
- void refresh_temporaryToken_throws() throws IOException {
+ void refresh_temporaryToken_throws() {
OAuth2Credentials credentials =
OAuth2Credentials.newBuilder().setAccessToken(new AccessToken(ACCESS_TOKEN, null)).build();
- assertThrows(IllegalStateException.class, () -> credentials.refresh());
+ assertThrows(IllegalStateException.class, credentials::refresh);
}
@Test
- void equals_true() throws IOException {
+ void equals_true() {
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
OAuth2Credentials credentials =
OAuth2Credentials.newBuilder().setAccessToken(new AccessToken(accessToken1, null)).build();
OAuth2Credentials otherCredentials =
OAuth2Credentials.newBuilder().setAccessToken(new AccessToken(accessToken1, null)).build();
- assertTrue(credentials.equals(otherCredentials));
- assertTrue(otherCredentials.equals(credentials));
+ assertEquals(credentials, otherCredentials);
+ assertEquals(otherCredentials, credentials);
}
@Test
- void equals_false_accessToken() throws IOException {
+ void equals_false_accessToken() {
final String accessToken1 = "1/MkSJoj1xsli0AccessToken_NKPY2";
final String accessToken2 = "2/MkSJoj1xsli0AccessToken_NKPY2";
OAuth2Credentials credentials =
OAuth2Credentials.newBuilder().setAccessToken(new AccessToken(accessToken1, null)).build();
OAuth2Credentials otherCredentials =
OAuth2Credentials.newBuilder().setAccessToken(new AccessToken(accessToken2, null)).build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
- void toString_containsFields() throws IOException {
+ void toString_containsFields() {
AccessToken accessToken = new AccessToken("1/MkSJoj1xsli0AccessToken_NKPY2", null);
OAuth2Credentials credentials =
OAuth2Credentials.newBuilder().setAccessToken(accessToken).build();
@@ -829,12 +823,12 @@ void toString_containsFields() throws IOException {
ImmutableMap.of(
AuthHttpConstants.AUTHORIZATION,
ImmutableList.of(OAuth2Utils.BEARER_PREFIX + accessToken.getTokenValue())),
- accessToken.toString());
+ accessToken);
assertEquals(expectedToString, credentials.toString());
}
@Test
- void hashCode_equals() throws IOException {
+ void hashCode_equals() {
final String accessToken = "1/MkSJoj1xsli0AccessToken_NKPY2";
OAuth2Credentials credentials =
OAuth2Credentials.newBuilder().setAccessToken(new AccessToken(accessToken, null)).build();
@@ -852,7 +846,7 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
}
@Test
@@ -862,65 +856,16 @@ void updateTokenValueBeforeWake() throws IOException, InterruptedException {
AccessToken refreshedToken = new AccessToken("2/MkSJoj1xsli0AccessToken_NKPY2", null);
refreshedTokenFuture.set(refreshedToken);
- final ListenableFutureTask task =
- ListenableFutureTask.create(
- new Callable() {
- @Override
- public OAuthValue call() throws Exception {
- return OAuthValue.create(refreshedToken, new HashMap<>());
- }
- });
-
- OAuth2Credentials creds =
- new OAuth2Credentials() {
- @Override
- public AccessToken refreshAccessToken() {
- synchronized (this) {
- // Wake up the main thread. This is done now because the child thread (t) is known to
- // have the refresh task. Now we want the main thread to wake up and create a future
- // in order to wait for the refresh to complete.
- this.notify();
- }
- RefreshTaskListener listener =
- new RefreshTaskListener(task) {
- @Override
- public void run() {
- try {
- // Sleep before setting accessToken to new accessToken. Refresh should not
- // complete before this, and the accessToken is `null` until it is.
- Thread.sleep(300);
- super.run();
- } catch (Exception e) {
- fail("Unexpected error. Exception: " + e);
- }
- }
- };
-
- this.refreshTask = new RefreshTask(task, listener);
-
- try {
- // Sleep for 100 milliseconds to give parent thread time to create a refresh future.
- Thread.sleep(100);
- return refreshedTokenFuture.get();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
- };
+ OAuth2Credentials creds = getOAuth2Credentials(refreshedToken, refreshedTokenFuture);
Thread t =
new Thread(
- new Runnable() {
- @Override
- public void run() {
- try {
- creds.refresh();
- assertNotNull(creds.getAccessToken());
- } catch (Exception e) {
- fail("Unexpected error. Exception: " + e);
- }
- }
- });
+ () ->
+ assertDoesNotThrow(
+ () -> {
+ creds.refresh();
+ assertNotNull(creds.getAccessToken());
+ }));
t.start();
synchronized (creds) {
@@ -941,6 +886,47 @@ public void run() {
t.join();
}
+ private OAuth2Credentials getOAuth2Credentials(
+ AccessToken refreshedToken, SettableFuture refreshedTokenFuture) {
+ final ListenableFutureTask task =
+ ListenableFutureTask.create(() -> OAuthValue.create(refreshedToken, new HashMap<>()));
+
+ return new OAuth2Credentials() {
+ @Override
+ public AccessToken refreshAccessToken() {
+ synchronized (this) {
+ // Wake up the main thread. This is done now because the child thread (t) is known to
+ // have the refresh task. Now we want the main thread to wake up and create a future
+ // in order to wait for the refresh to complete.
+ this.notify();
+ }
+ RefreshTaskListener listener =
+ new RefreshTaskListener(task) {
+ @Override
+ public void run() {
+ assertDoesNotThrow(
+ () -> {
+ // Sleep before setting accessToken to new accessToken. Refresh should not
+ // complete before this, and the accessToken is `null` until it is.
+ Thread.sleep(300);
+ super.run();
+ });
+ }
+ };
+
+ this.refreshTask = new RefreshTask(task, listener);
+
+ try {
+ // Sleep for 100 milliseconds to give parent thread time to create a refresh future.
+ Thread.sleep(100);
+ return refreshedTokenFuture.get();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ };
+ }
+
private void waitForRefreshTaskCompletion(OAuth2Credentials credentials)
throws TimeoutException, InterruptedException {
for (int i = 0; i < 100; i++) {
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsWithRefreshTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsWithRefreshTest.java
index 2c285c5491a8..a6b437eabc3b 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsWithRefreshTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/OAuth2CredentialsWithRefreshTest.java
@@ -33,8 +33,9 @@
import static com.google.auth.oauth2.OAuth2Credentials.DEFAULT_EXPIRATION_MARGIN;
import static com.google.auth.oauth2.OAuth2Credentials.DEFAULT_REFRESH_MARGIN;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import com.google.auth.TestUtils;
import java.io.IOException;
@@ -150,37 +151,24 @@ public AccessToken refreshAccessToken() {
@Test
void builder_noAccessToken() {
- OAuth2CredentialsWithRefresh.newBuilder()
- .setRefreshHandler(
- new OAuth2CredentialsWithRefresh.OAuth2RefreshHandler() {
- @Override
- public AccessToken refreshAccessToken() {
- return null;
- }
- })
- .build();
+ OAuth2CredentialsWithRefresh.Builder builder =
+ OAuth2CredentialsWithRefresh.newBuilder().setRefreshHandler(() -> null);
+ assertDoesNotThrow(builder::build);
}
@Test
void builder_noRefreshHandler_throws() {
- try {
- OAuth2CredentialsWithRefresh.newBuilder().setAccessToken(ACCESS_TOKEN).build();
- fail("Should fail as a refresh handler must be provided.");
- } catch (NullPointerException e) {
- // Expected.
- }
+ OAuth2CredentialsWithRefresh.Builder builder =
+ OAuth2CredentialsWithRefresh.newBuilder().setAccessToken(ACCESS_TOKEN);
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void builder_noExpirationTimeInAccessToken_throws() {
- try {
- OAuth2CredentialsWithRefresh.newBuilder()
- .setAccessToken(new AccessToken("accessToken", null))
- .build();
- fail("Should fail as a refresh handler must be provided.");
- } catch (IllegalArgumentException e) {
- // Expected.
- }
+ OAuth2CredentialsWithRefresh.Builder builder =
+ OAuth2CredentialsWithRefresh.newBuilder()
+ .setAccessToken(new AccessToken("accessToken", null));
+ assertThrows(IllegalArgumentException.class, builder::build);
}
@Test
@@ -189,13 +177,7 @@ void refreshAccessToken_delegateToRefreshHandler() throws IOException {
OAuth2CredentialsWithRefresh credentials =
OAuth2CredentialsWithRefresh.newBuilder()
.setAccessToken(ACCESS_TOKEN)
- .setRefreshHandler(
- new OAuth2CredentialsWithRefresh.OAuth2RefreshHandler() {
- @Override
- public AccessToken refreshAccessToken() {
- return refreshedToken;
- }
- })
+ .setRefreshHandler(() -> refreshedToken)
.build();
AccessToken accessToken = credentials.refreshAccessToken();
@@ -210,13 +192,7 @@ void getRequestMetadata() throws IOException {
OAuth2CredentialsWithRefresh credentials =
OAuth2CredentialsWithRefresh.newBuilder()
.setAccessToken(ACCESS_TOKEN)
- .setRefreshHandler(
- new OAuth2CredentialsWithRefresh.OAuth2RefreshHandler() {
- @Override
- public AccessToken refreshAccessToken() {
- return refreshedToken;
- }
- })
+ .setRefreshHandler(() -> refreshedToken)
.build();
Map> metadata = credentials.getRequestMetadata(uri);
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthCredentialsTest.java
index 9832c78215c0..094b21f9dbb2 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthCredentialsTest.java
@@ -36,7 +36,6 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.GenericJson;
@@ -94,7 +93,7 @@ void retrieveSubjectToken_shouldDelegateToHandler() throws IOException {
.setExecutableHandler(options -> "pluggableAuthToken")
.build();
String subjectToken = credential.retrieveSubjectToken();
- assertEquals(subjectToken, "pluggableAuthToken");
+ assertEquals("pluggableAuthToken", subjectToken);
}
@Test
@@ -119,24 +118,24 @@ void retrieveSubjectToken_shouldPassAllOptionsToHandler() throws IOException {
String subjectToken = credential.retrieveSubjectToken();
- assertEquals(subjectToken, "pluggableAuthToken");
+ assertEquals("pluggableAuthToken", subjectToken);
// Validate that the correct options were passed to the executable handler.
ExecutableOptions options = providedOptions[0];
- assertEquals(options.getExecutableCommand(), command);
+ assertEquals(command, options.getExecutableCommand());
assertEquals(options.getExecutableTimeoutMs(), Integer.parseInt(timeout));
- assertEquals(options.getOutputFilePath(), outputFile);
+ assertEquals(outputFile, options.getOutputFilePath());
Map envMap = options.getEnvironmentMap();
- assertEquals(envMap.size(), 5);
+ assertEquals(5, envMap.size());
assertEquals(envMap.get("GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE"), credential.getAudience());
assertEquals(
envMap.get("GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE"), credential.getSubjectTokenType());
- assertEquals(envMap.get("GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE"), "0");
+ assertEquals("0", envMap.get("GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE"));
assertEquals(
envMap.get("GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL"),
credential.getServiceAccountEmail());
- assertEquals(envMap.get("GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE"), outputFile);
+ assertEquals(outputFile, envMap.get("GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE"));
}
@Test
@@ -159,20 +158,20 @@ void retrieveSubjectToken_shouldPassMinimalOptionsToHandler() throws IOException
String subjectToken = credential.retrieveSubjectToken();
- assertEquals(subjectToken, "pluggableAuthToken");
+ assertEquals("pluggableAuthToken", subjectToken);
// Validate that the correct options were passed to the executable handler.
ExecutableOptions options = providedOptions[0];
- assertEquals(options.getExecutableCommand(), command);
- assertEquals(options.getExecutableTimeoutMs(), DEFAULT_EXECUTABLE_TIMEOUT_MS);
+ assertEquals(command, options.getExecutableCommand());
+ assertEquals(DEFAULT_EXECUTABLE_TIMEOUT_MS, options.getExecutableTimeoutMs());
assertNull(options.getOutputFilePath());
Map envMap = options.getEnvironmentMap();
- assertEquals(envMap.size(), 3);
+ assertEquals(3, envMap.size());
assertEquals(envMap.get("GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE"), credential.getAudience());
assertEquals(
envMap.get("GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE"), credential.getSubjectTokenType());
- assertEquals(envMap.get("GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE"), "0");
+ assertEquals("0", envMap.get("GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE"));
assertNull(envMap.get("GOOGLE_EXTERNAL_ACCOUNT_IMPERSONATED_EMAIL"));
assertNull(envMap.get("GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE"));
}
@@ -198,7 +197,7 @@ void refreshAccessToken_withoutServiceAccountImpersonation() throws IOException
// Validate that the correct subject token was passed to STS.
Map query =
TestUtils.parseQuery(transportFactory.transport.getRequests().get(0).getContentAsString());
- assertEquals(query.get("subject_token"), "pluggableAuthToken");
+ assertEquals("pluggableAuthToken", query.get("subject_token"));
// Validate metrics header is set correctly on the sts request.
Map> headers =
@@ -239,7 +238,7 @@ void refreshAccessToken_withServiceAccountImpersonation() throws IOException {
// Validate that the correct subject token was passed to STS.
Map query =
TestUtils.parseQuery(transportFactory.transport.getRequests().get(0).getContentAsString());
- assertEquals(query.get("subject_token"), "pluggableAuthToken");
+ assertEquals("pluggableAuthToken", query.get("subject_token"));
// Validate metrics header is set correctly on the sts request.
Map> headers =
@@ -265,7 +264,7 @@ void refreshAccessToken_withServiceAccountImpersonationOptions() throws IOExcept
.setServiceAccountImpersonationUrl(
transportFactory.transport.getServiceAccountImpersonationUrl())
.setServiceAccountImpersonationOptions(
- ExternalAccountCredentialsTest.buildServiceAccountImpersonationOptions(2800))
+ ExternalAccountCredentialsTest.buildServiceAccountImpersonationOptions())
.setHttpTransportFactory(transportFactory)
.build();
@@ -304,9 +303,9 @@ void pluggableAuthCredentialSource_allFields() {
PluggableAuthCredentialSource credentialSource = new PluggableAuthCredentialSource(source);
- assertEquals(credentialSource.getCommand(), "/path/to/executable");
- assertEquals(credentialSource.getTimeoutMs(), 10000);
- assertEquals(credentialSource.getOutputFilePath(), "/path/to/output/file");
+ assertEquals("/path/to/executable", credentialSource.getCommand());
+ assertEquals(10000, credentialSource.getTimeoutMs());
+ assertEquals("/path/to/output/file", credentialSource.getOutputFilePath());
}
@Test
@@ -317,8 +316,8 @@ void pluggableAuthCredentialSource_noTimeoutProvided_setToDefault() {
executable.put("command", "command");
PluggableAuthCredentialSource credentialSource = new PluggableAuthCredentialSource(source);
- assertEquals(credentialSource.getCommand(), "command");
- assertEquals(credentialSource.getTimeoutMs(), DEFAULT_EXECUTABLE_TIMEOUT_MS);
+ assertEquals("command", credentialSource.getCommand());
+ assertEquals(DEFAULT_EXECUTABLE_TIMEOUT_MS, credentialSource.getTimeoutMs());
assertNull(credentialSource.getOutputFilePath());
}
@@ -335,16 +334,14 @@ void pluggableAuthCredentialSource_timeoutProvidedOutOfRange_throws() {
for (int value : possibleOutOfRangeValues) {
executable.put("timeout_millis", value);
- try {
- new PluggableAuthCredentialSource(source);
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- String.format(
- "The executable timeout must be between %s and %s milliseconds.",
- MINIMUM_EXECUTABLE_TIMEOUT_MS, MAXIMUM_EXECUTABLE_TIMEOUT_MS),
- exception.getMessage());
- }
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class, () -> new PluggableAuthCredentialSource(source));
+ assertEquals(
+ String.format(
+ "The executable timeout must be between %s and %s milliseconds.",
+ MINIMUM_EXECUTABLE_TIMEOUT_MS, MAXIMUM_EXECUTABLE_TIMEOUT_MS),
+ exception.getMessage());
}
}
@@ -362,21 +359,21 @@ void pluggableAuthCredentialSource_validTimeoutProvided() {
executable.put("timeout_millis", value);
PluggableAuthCredentialSource credentialSource = new PluggableAuthCredentialSource(source);
- assertEquals(credentialSource.getCommand(), "command");
- assertEquals(credentialSource.getTimeoutMs(), 10000);
+ assertEquals("command", credentialSource.getCommand());
+ assertEquals(10000, credentialSource.getTimeoutMs());
assertNull(credentialSource.getOutputFilePath());
}
}
@Test
void pluggableAuthCredentialSource_missingExecutableField_throws() {
- try {
- new PluggableAuthCredentialSource(new HashMap<>());
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- "Invalid credential source for PluggableAuth credentials.", exception.getMessage());
- }
+ HashMap credentialSourceMap = new HashMap<>();
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class,
+ () -> new PluggableAuthCredentialSource(credentialSourceMap));
+ assertEquals(
+ "Invalid credential source for PluggableAuth credentials.", exception.getMessage());
}
@Test
@@ -385,18 +382,16 @@ void pluggableAuthCredentialSource_missingExecutableCommandField_throws() {
Map executable = new HashMap<>();
source.put("executable", executable);
- try {
- new PluggableAuthCredentialSource(source);
- fail("Should not be able to continue without exception.");
- } catch (IllegalArgumentException exception) {
- assertEquals(
- "The PluggableAuthCredentialSource is missing the required 'command' field.",
- exception.getMessage());
- }
+ IllegalArgumentException exception =
+ assertThrows(
+ IllegalArgumentException.class, () -> new PluggableAuthCredentialSource(source));
+ assertEquals(
+ "The PluggableAuthCredentialSource is missing the required 'command' field.",
+ exception.getMessage());
}
@Test
- void builder_allFields() throws IOException {
+ void builder_allFields() {
List scopes = Arrays.asList("scope1", "scope2");
PluggableAuthCredentialSource source = buildCredentialSource();
@@ -436,7 +431,7 @@ void builder_allFields() throws IOException {
}
@Test
- void builder_missingUniverseDomain_defaults() throws IOException {
+ void builder_missingUniverseDomain_defaults() {
List scopes = Arrays.asList("scope1", "scope2");
PluggableAuthCredentialSource source = buildCredentialSource();
@@ -475,7 +470,7 @@ void builder_missingUniverseDomain_defaults() throws IOException {
}
@Test
- void newBuilder_allFields() throws IOException {
+ void newBuilder_allFields() {
List scopes = Arrays.asList("scope1", "scope2");
PluggableAuthCredentialSource source = buildCredentialSource();
@@ -517,7 +512,7 @@ void newBuilder_allFields() throws IOException {
}
@Test
- void newBuilder_noUniverseDomain_defaults() throws IOException {
+ void newBuilder_noUniverseDomain_defaults() {
List scopes = Arrays.asList("scope1", "scope2");
PluggableAuthCredentialSource source = buildCredentialSource();
@@ -558,7 +553,7 @@ void newBuilder_noUniverseDomain_defaults() throws IOException {
}
@Test
- void createdScoped_clonedCredentialWithAddedScopes() throws IOException {
+ void createdScoped_clonedCredentialWithAddedScopes() {
PluggableAuthCredentials credentials =
PluggableAuthCredentials.newBuilder(CREDENTIAL)
.setExecutableHandler(options -> "pluggableAuthToken")
@@ -591,7 +586,7 @@ void createdScoped_clonedCredentialWithAddedScopes() throws IOException {
}
@Test
- void serialize() throws IOException, ClassNotFoundException {
+ void serialize() {
PluggableAuthCredentials testCredentials =
PluggableAuthCredentials.newBuilder(CREDENTIAL)
.setExecutableHandler(options -> "pluggableAuthToken")
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthExceptionTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthExceptionTest.java
index f924d4137724..534ad9f33a2b 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthExceptionTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthExceptionTest.java
@@ -39,8 +39,6 @@
/** Tests for {@link PluggableAuthException}. */
class PluggableAuthExceptionTest {
- private static final String MESSAGE_FORMAT = "Error code %s: %s";
-
@Test
void constructor() {
PluggableAuthException e = new PluggableAuthException("errorCode", "errorDescription");
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthHandlerTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthHandlerTest.java
index c31266d27360..1566c7eed418 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthHandlerTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/PluggableAuthHandlerTest.java
@@ -33,8 +33,8 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
@@ -189,7 +189,7 @@ void retrieveTokenFromExecutable_samlResponse() throws IOException, InterruptedE
}
@Test
- void retrieveTokenFromExecutable_errorResponse_throws() throws InterruptedException, IOException {
+ void retrieveTokenFromExecutable_errorResponse_throws() throws InterruptedException {
TestEnvironmentProvider environmentProvider = new TestEnvironmentProvider();
environmentProvider.setEnv("GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES", "1");
@@ -211,13 +211,12 @@ void retrieveTokenFromExecutable_errorResponse_throws() throws InterruptedExcept
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider, processBuilder);
// Call retrieveTokenFromExecutable().
- try {
- handler.retrieveTokenFromExecutable(DEFAULT_OPTIONS);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException e) {
- assertEquals("401", e.getErrorCode());
- assertEquals("Caller not authorized.", e.getErrorDescription());
- }
+ PluggableAuthException e =
+ assertThrows(
+ PluggableAuthException.class,
+ () -> handler.retrieveTokenFromExecutable(DEFAULT_OPTIONS));
+ assertEquals("401", e.getErrorCode());
+ assertEquals("Caller not authorized.", e.getErrorDescription());
}
@Test
@@ -281,7 +280,7 @@ void retrieveTokenFromExecutable_successResponseWithoutExpirationTimeField()
@Test
void
retrieveTokenFromExecutable_successResponseWithoutExpirationTimeFieldWithOutputFileSpecified_throws()
- throws InterruptedException, IOException {
+ throws InterruptedException {
TestEnvironmentProvider environmentProvider = new TestEnvironmentProvider();
environmentProvider.setEnv("GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES", "1");
@@ -333,19 +332,14 @@ public String getOutputFilePath() {
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider, processBuilder);
- // Call retrieveTokenFromExecutable() should throw an exception as the STDOUT response
- // is missing
- // the `expiration_time` field and an output file was specified in the configuration.
- try {
- handler.retrieveTokenFromExecutable(options);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException exception) {
- assertEquals(
- "Error code INVALID_EXECUTABLE_RESPONSE: The executable response must contain the "
- + "`expiration_time` field for successful responses when an output_file has been specified in the"
- + " configuration.",
- exception.getMessage());
- }
+ PluggableAuthException exception =
+ assertThrows(
+ PluggableAuthException.class, () -> handler.retrieveTokenFromExecutable(options));
+ assertEquals(
+ "Error code INVALID_EXECUTABLE_RESPONSE: The executable response must contain the "
+ + "`expiration_time` field for successful responses when an output_file has been specified in the"
+ + " configuration.",
+ exception.getMessage());
verify(mockProcess, times(i + 1)).destroy();
verify(mockProcess, times(i + 1))
@@ -410,16 +404,14 @@ public String getOutputFilePath() {
// Call retrieveTokenFromExecutable() which should throw an exception as the output file
// response is missing
// the `expiration_time` field.
- try {
- handler.retrieveTokenFromExecutable(options);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException exception) {
- assertEquals(
- "Error code INVALID_EXECUTABLE_RESPONSE: The executable response must contain the "
- + "`expiration_time` field for successful responses when an output_file has been specified in the"
- + " configuration.",
- exception.getMessage());
- }
+ PluggableAuthException exception =
+ assertThrows(
+ PluggableAuthException.class, () -> handler.retrieveTokenFromExecutable(options));
+ assertEquals(
+ "Error code INVALID_EXECUTABLE_RESPONSE: The executable response must contain the "
+ + "`expiration_time` field for successful responses when an output_file has been specified in the"
+ + " configuration.",
+ exception.getMessage());
// Validate executable not invoked.
verify(mockProcess, times(0)).destroyForcibly();
@@ -485,8 +477,7 @@ public String getOutputFilePath() {
}
@Test
- void retrieveTokenFromExecutable_withInvalidOutputFile_throws()
- throws IOException, InterruptedException {
+ void retrieveTokenFromExecutable_withInvalidOutputFile_throws() throws IOException {
TestEnvironmentProvider environmentProvider = new TestEnvironmentProvider();
environmentProvider.setEnv("GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES", "1");
@@ -530,12 +521,10 @@ public String getOutputFilePath() {
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider, processBuilder);
// Call retrieveTokenFromExecutable().
- try {
- handler.retrieveTokenFromExecutable(options);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException e) {
- assertEquals("INVALID_OUTPUT_FILE", e.getErrorCode());
- }
+ PluggableAuthException e =
+ assertThrows(
+ PluggableAuthException.class, () -> handler.retrieveTokenFromExecutable(options));
+ assertEquals("INVALID_OUTPUT_FILE", e.getErrorCode());
}
@Test
@@ -629,18 +618,16 @@ void retrieveTokenFromExecutable_expiredResponse_throws()
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider, processBuilder);
// Call retrieveTokenFromExecutable().
- try {
- handler.retrieveTokenFromExecutable(DEFAULT_OPTIONS);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException e) {
- assertEquals("INVALID_RESPONSE", e.getErrorCode());
- assertEquals("The executable response is expired.", e.getErrorDescription());
- }
+ PluggableAuthException e =
+ assertThrows(
+ PluggableAuthException.class,
+ () -> handler.retrieveTokenFromExecutable(DEFAULT_OPTIONS));
+ assertEquals("INVALID_RESPONSE", e.getErrorCode());
+ assertEquals("The executable response is expired.", e.getErrorDescription());
}
@Test
- void retrieveTokenFromExecutable_invalidVersion_throws()
- throws InterruptedException, IOException {
+ void retrieveTokenFromExecutable_invalidVersion_throws() throws InterruptedException {
TestEnvironmentProvider environmentProvider = new TestEnvironmentProvider();
environmentProvider.setEnv("GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES", "1");
@@ -663,22 +650,20 @@ void retrieveTokenFromExecutable_invalidVersion_throws()
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider, processBuilder);
// Call retrieveTokenFromExecutable().
- try {
- handler.retrieveTokenFromExecutable(DEFAULT_OPTIONS);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException e) {
- assertEquals("UNSUPPORTED_VERSION", e.getErrorCode());
- assertEquals(
- "The version of the executable response is not supported. "
- + String.format(
- "The maximum version currently supported is %s.",
- EXECUTABLE_SUPPORTED_MAX_VERSION),
- e.getErrorDescription());
- }
+ PluggableAuthException e =
+ assertThrows(
+ PluggableAuthException.class,
+ () -> handler.retrieveTokenFromExecutable(DEFAULT_OPTIONS));
+ assertEquals("UNSUPPORTED_VERSION", e.getErrorCode());
+ assertEquals(
+ "The version of the executable response is not supported. "
+ + String.format(
+ "The maximum version currently supported is %s.", EXECUTABLE_SUPPORTED_MAX_VERSION),
+ e.getErrorDescription());
}
@Test
- void retrieveTokenFromExecutable_allowExecutablesDisabled_throws() throws IOException {
+ void retrieveTokenFromExecutable_allowExecutablesDisabled_throws() {
// In order to use Pluggable Auth, GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES must be set to 1.
// If set to 0, a runtime exception should be thrown.
TestEnvironmentProvider environmentProvider = new TestEnvironmentProvider();
@@ -686,16 +671,15 @@ void retrieveTokenFromExecutable_allowExecutablesDisabled_throws() throws IOExce
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider);
- try {
- handler.retrieveTokenFromExecutable(DEFAULT_OPTIONS);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException e) {
- assertEquals("PLUGGABLE_AUTH_DISABLED", e.getErrorCode());
- assertEquals(
- "Pluggable Auth executables need to be explicitly allowed to run by "
- + "setting the GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES environment variable to 1.",
- e.getErrorDescription());
- }
+ PluggableAuthException e =
+ assertThrows(
+ PluggableAuthException.class,
+ () -> handler.retrieveTokenFromExecutable(DEFAULT_OPTIONS));
+ assertEquals("PLUGGABLE_AUTH_DISABLED", e.getErrorCode());
+ assertEquals(
+ "Pluggable Auth executables need to be explicitly allowed to run by "
+ + "setting the GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES environment variable to 1.",
+ e.getErrorDescription());
}
@Test
@@ -853,7 +837,7 @@ void getExecutableResponse_errorResponse() throws IOException, InterruptedExcept
}
@Test
- void getExecutableResponse_timeoutExceeded_throws() throws InterruptedException, IOException {
+ void getExecutableResponse_timeoutExceeded_throws() throws InterruptedException {
TestEnvironmentProvider environmentProvider = new TestEnvironmentProvider();
environmentProvider.setEnv("GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES", "1");
@@ -867,14 +851,12 @@ void getExecutableResponse_timeoutExceeded_throws() throws InterruptedException,
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider, processBuilder);
// Call getExecutableResponse().
- try {
- handler.getExecutableResponse(DEFAULT_OPTIONS);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException e) {
- assertEquals("TIMEOUT_EXCEEDED", e.getErrorCode());
- assertEquals(
- "The executable failed to finish within the timeout specified.", e.getErrorDescription());
- }
+ PluggableAuthException e =
+ assertThrows(
+ PluggableAuthException.class, () -> handler.getExecutableResponse(DEFAULT_OPTIONS));
+ assertEquals("TIMEOUT_EXCEEDED", e.getErrorCode());
+ assertEquals(
+ "The executable failed to finish within the timeout specified.", e.getErrorDescription());
verify(mockProcess, times(1))
.waitFor(
@@ -883,7 +865,7 @@ void getExecutableResponse_timeoutExceeded_throws() throws InterruptedException,
}
@Test
- void getExecutableResponse_nonZeroExitCode_throws() throws InterruptedException, IOException {
+ void getExecutableResponse_nonZeroExitCode_throws() throws InterruptedException {
TestEnvironmentProvider environmentProvider = new TestEnvironmentProvider();
environmentProvider.setEnv("GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES", "1");
@@ -899,15 +881,13 @@ void getExecutableResponse_nonZeroExitCode_throws() throws InterruptedException,
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider, processBuilder);
// Call getExecutableResponse().
- try {
- handler.getExecutableResponse(DEFAULT_OPTIONS);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException e) {
- assertEquals("EXIT_CODE", e.getErrorCode());
- assertEquals(
- String.format("The executable failed with exit code %s.", EXIT_CODE_FAIL),
- e.getErrorDescription());
- }
+ PluggableAuthException e =
+ assertThrows(
+ PluggableAuthException.class, () -> handler.getExecutableResponse(DEFAULT_OPTIONS));
+ assertEquals("EXIT_CODE", e.getErrorCode());
+ assertEquals(
+ String.format("The executable failed with exit code %s.", EXIT_CODE_FAIL),
+ e.getErrorDescription());
verify(mockProcess, times(1))
.waitFor(
@@ -916,7 +896,7 @@ void getExecutableResponse_nonZeroExitCode_throws() throws InterruptedException,
}
@Test
- void getExecutableResponse_processInterrupted_throws() throws InterruptedException, IOException {
+ void getExecutableResponse_processInterrupted_throws() throws InterruptedException {
TestEnvironmentProvider environmentProvider = new TestEnvironmentProvider();
environmentProvider.setEnv("GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES", "1");
@@ -931,15 +911,13 @@ void getExecutableResponse_processInterrupted_throws() throws InterruptedExcepti
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider, processBuilder);
// Call getExecutableResponse().
- try {
- handler.getExecutableResponse(DEFAULT_OPTIONS);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException e) {
- assertEquals("INTERRUPTED", e.getErrorCode());
- assertEquals(
- String.format("The execution was interrupted: %s.", new InterruptedException()),
- e.getErrorDescription());
- }
+ PluggableAuthException e =
+ assertThrows(
+ PluggableAuthException.class, () -> handler.getExecutableResponse(DEFAULT_OPTIONS));
+ assertEquals("INTERRUPTED", e.getErrorCode());
+ assertEquals(
+ String.format("The execution was interrupted: %s.", new InterruptedException()),
+ e.getErrorDescription());
verify(mockProcess, times(1))
.waitFor(
@@ -948,7 +926,7 @@ void getExecutableResponse_processInterrupted_throws() throws InterruptedExcepti
}
@Test
- void getExecutableResponse_invalidResponse_throws() throws InterruptedException, IOException {
+ void getExecutableResponse_invalidResponse_throws() throws InterruptedException {
TestEnvironmentProvider environmentProvider = new TestEnvironmentProvider();
environmentProvider.setEnv("GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES", "1");
@@ -969,15 +947,13 @@ void getExecutableResponse_invalidResponse_throws() throws InterruptedException,
PluggableAuthHandler handler = new PluggableAuthHandler(environmentProvider, processBuilder);
// Call getExecutableResponse().
- try {
- handler.getExecutableResponse(DEFAULT_OPTIONS);
- fail("Should not be able to continue without exception.");
- } catch (PluggableAuthException e) {
- assertEquals("INVALID_RESPONSE", e.getErrorCode());
- assertEquals(
- String.format("The executable returned an invalid response: %s.", badResponse),
- e.getErrorDescription());
- }
+ PluggableAuthException e =
+ assertThrows(
+ PluggableAuthException.class, () -> handler.getExecutableResponse(DEFAULT_OPTIONS));
+ assertEquals("INVALID_RESPONSE", e.getErrorCode());
+ assertEquals(
+ String.format("The executable returned an invalid response: %s.", badResponse),
+ e.getErrorDescription());
verify(mockProcess, times(1))
.waitFor(
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/SecureSessionAgentConfigTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/SecureSessionAgentConfigTest.java
index b9249517c640..3dc07f494c6d 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/SecureSessionAgentConfigTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/SecureSessionAgentConfigTest.java
@@ -35,7 +35,7 @@
import org.junit.jupiter.api.Test;
-/** Test cases for {@linkSecureSessionAgentConfig}. */
+/** Test cases for {@link SecureSessionAgentConfig}. */
class SecureSessionAgentConfigTest {
private static final String S2A_PLAINTEXT_ADDRESS = "plaintext";
private static final String S2A_MTLS_ADDRESS = "mtls";
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java
index 2c516a9b2b4a..ed26a0af3c6f 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountCredentialsTest.java
@@ -32,6 +32,7 @@
package com.google.auth.oauth2;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
@@ -139,17 +140,14 @@ private static ServiceAccountCredentials.Builder createDefaultBuilderWithScopes(
private static ServiceAccountCredentials.Builder createDefaultBuilderWithKey(
PrivateKey privateKey) {
- ServiceAccountCredentials.Builder builder =
- ServiceAccountCredentials.newBuilder()
- .setClientId(CLIENT_ID)
- .setClientEmail(CLIENT_EMAIL)
- .setPrivateKey(privateKey)
- .setPrivateKeyId(PRIVATE_KEY_ID)
- .setProjectId(PROJECT_ID)
- .setQuotaProjectId(QUOTA_PROJECT)
- .setHttpTransportFactory(new MockHttpTransportFactory());
-
- return builder;
+ return ServiceAccountCredentials.newBuilder()
+ .setClientId(CLIENT_ID)
+ .setClientEmail(CLIENT_EMAIL)
+ .setPrivateKey(privateKey)
+ .setPrivateKeyId(PRIVATE_KEY_ID)
+ .setProjectId(PROJECT_ID)
+ .setQuotaProjectId(QUOTA_PROJECT)
+ .setHttpTransportFactory(new MockHttpTransportFactory());
}
static ServiceAccountCredentials.Builder createDefaultBuilder() throws IOException {
@@ -172,16 +170,11 @@ void setLifetime() throws IOException {
}
@Test
- void setLifetime_invalid_lifetime() throws IOException, IllegalStateException {
- try {
- createDefaultBuilder().setLifetime(INVALID_LIFETIME).build();
- fail(
- String.format(
- "Should throw exception with message containing '%s'",
- "lifetime must be less than or equal to 43200"));
- } catch (IllegalStateException expected) {
- assertTrue(expected.getMessage().contains("lifetime must be less than or equal to 43200"));
- }
+ void setLifetime_invalid_lifetime() throws IllegalStateException, IOException {
+ ServiceAccountCredentials.Builder builder =
+ createDefaultBuilder().setLifetime(INVALID_LIFETIME);
+ IllegalStateException exception = assertThrows(IllegalStateException.class, builder::build);
+ assertTrue(exception.getMessage().contains("lifetime must be less than or equal to 43200"));
}
@Test
@@ -300,7 +293,6 @@ void createAssertion_custom_lifetime() throws IOException {
@Test
void createAssertionForIdToken_correct() throws IOException {
- PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(PRIVATE_KEY_PKCS8);
ServiceAccountCredentials credentials =
createDefaultBuilder()
.setPrivateKeyId(PRIVATE_KEY_ID)
@@ -369,14 +361,11 @@ void createdScoped_withAud_noUniverse_jwtWithScopesDisabled_accessToken() throws
GoogleCredentials credentials = createDefaultBuilderWithToken(ACCESS_TOKEN).build();
// No aud, no scopes gives an exception.
- try {
- credentials.getRequestMetadata(null);
- fail("Should not be able to get token without scopes");
- } catch (IOException e) {
- assertTrue(
- e.getMessage().contains("Scopes and uri are not configured for service account"),
- "expected to fail with exception");
- }
+ IOException exception =
+ assertThrows(IOException.class, () -> credentials.getRequestMetadata(null));
+ assertTrue(
+ exception.getMessage().contains("Scopes and uri are not configured for service account"),
+ "expected to fail with exception");
GoogleCredentials scopedCredentials = credentials.createScoped(SCOPES);
assertEquals(false, credentials.isExplicitUniverseDomain());
@@ -389,15 +378,10 @@ void createdScoped_withAud_noUniverse_jwtWithScopesDisabled_accessToken() throws
void createdScoped_withUniverse_selfSignedJwt() throws IOException {
ServiceAccountCredentials credentials =
createDefaultBuilder().setUniverseDomain("foo.bar").build();
-
- try {
- credentials.getRequestMetadata(null);
- fail("Should not be able to get token without scopes");
- } catch (IOException e) {
- assertTrue(
- e.getMessage().contains("Scopes and uri are not configured for service account"),
- "expected to fail with exception");
- }
+ IOException exception =
+ assertThrows(IOException.class, () -> credentials.getRequestMetadata(null));
+ assertTrue(
+ exception.getMessage().contains("Scopes and uri are not configured for service account"));
GoogleCredentials scopedCredentials = credentials.createScoped("dummy.scope");
Map> metadata = scopedCredentials.getRequestMetadata(null);
@@ -429,14 +413,10 @@ void createdScoped_withUniverse_selfSignedJwt() throws IOException {
void noScopes_withUniverse_selfSignedJwt() throws IOException {
GoogleCredentials credentials = createDefaultBuilder().setUniverseDomain("foo.bar").build();
- try {
- credentials.getRequestMetadata(null);
- fail("Should not be able to get token without scopes");
- } catch (IOException e) {
- assertTrue(
- e.getMessage().contains("Scopes and uri are not configured for service account"),
- "expected to fail with exception");
- }
+ IOException exception =
+ assertThrows(IOException.class, () -> credentials.getRequestMetadata(null));
+ assertTrue(
+ exception.getMessage().contains("Scopes and uri are not configured for service account"));
Map> metadata = credentials.getRequestMetadata(CALL_URI);
assertNull(((ServiceAccountCredentials) credentials).getSelfSignedJwtCredentialsWithScope());
@@ -588,8 +568,8 @@ void fromJson_hasQuotaProjectId() throws IOException {
assertTrue(metadata.containsKey(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY));
assertEquals(
- metadata.get(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY),
- Collections.singletonList(QUOTA_PROJECT));
+ Collections.singletonList(QUOTA_PROJECT),
+ metadata.get(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY));
}
@Test
@@ -602,15 +582,15 @@ void getRequestMetadata_hasAccessToken() throws IOException {
@Test
void getRequestMetadata_customTokenServer_hasAccessToken() throws IOException {
- final URI TOKEN_SERVER = URI.create("https://foo.com/bar");
+ final URI tokenServerUri = URI.create("https://foo.com/bar");
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
transportFactory.transport.addServiceAccount(CLIENT_EMAIL, ACCESS_TOKEN);
- transportFactory.transport.setTokenServerUri(TOKEN_SERVER);
+ transportFactory.transport.setTokenServerUri(tokenServerUri);
OAuth2Credentials credentials =
createDefaultBuilder()
.setScopes(SCOPES)
.setHttpTransportFactory(transportFactory)
- .setTokenServerUri(TOKEN_SERVER)
+ .setTokenServerUri(tokenServerUri)
.build();
Map> metadata = credentials.getRequestMetadata(CALL_URI);
@@ -672,7 +652,6 @@ void refreshAccessToken_IOException_Retry() throws IOException {
MockTokenServerTransport transport = transportFactory.transport;
ServiceAccountCredentials credentials =
createDefaultBuilder().setScopes(SCOPES).setHttpTransportFactory(transportFactory).build();
- ;
transport.addServiceAccount(CLIENT_EMAIL, accessToken1);
TestUtils.assertContainsBearerToken(credentials.getRequestMetadata(CALL_URI), accessToken1);
@@ -743,15 +722,11 @@ void refreshAccessToken_defaultRetriesDisabled() throws IOException {
MockLowLevelHttpResponse response429 = new MockLowLevelHttpResponse().setStatusCode(429);
transport.addServiceAccount(CLIENT_EMAIL, accessToken2);
- try {
- transport.addResponseSequence(response408, response429);
- credentials.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (GoogleAuthException ex) {
- assertTrue(ex.getMessage().contains("Error getting access token for service account: 408"));
- assertTrue(ex.isRetryable());
- assertEquals(0, ex.getRetryCount());
- }
+ transport.addResponseSequence(response408, response429);
+ GoogleAuthException ex = assertThrows(GoogleAuthException.class, credentials::refresh);
+ assertTrue(ex.getMessage().contains("Error getting access token for service account: 408"));
+ assertTrue(ex.isRetryable());
+ assertEquals(0, ex.getRetryCount());
}
@Test
@@ -770,21 +745,17 @@ void refreshAccessToken_maxRetries_maxDelay() throws IOException {
MockLowLevelHttpResponse response503 = new MockLowLevelHttpResponse().setStatusCode(503);
Instant start = Instant.now();
- try {
- transport.addResponseSequence(response408, response429, response500, response503);
- credentials.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (GoogleAuthException ex) {
- Instant finish = Instant.now();
- long timeElapsed = Duration.between(start, finish).toMillis();
-
- // we expect max retry time of 7 sec +/- jitter
- assertTrue(timeElapsed > 5500 && timeElapsed < 10000);
- assertTrue(ex.getMessage().contains("Error getting access token for service account: 503"));
- assertTrue(ex.isRetryable());
- assertEquals(3, ex.getRetryCount());
- assertTrue(ex.getCause() instanceof HttpResponseException);
- }
+ transport.addResponseSequence(response408, response429, response500, response503);
+ GoogleAuthException ex = assertThrows(GoogleAuthException.class, credentials::refresh);
+ Instant finish = Instant.now();
+ long timeElapsed = Duration.between(start, finish).toMillis();
+
+ // we expect max retry time of 7 sec +/- jitter
+ assertTrue(timeElapsed > 5500 && timeElapsed < 10000);
+ assertTrue(ex.getMessage().contains("Error getting access token for service account: 503"));
+ assertTrue(ex.isRetryable());
+ assertEquals(3, ex.getRetryCount());
+ assertTrue(ex.getCause() instanceof HttpResponseException);
}
@Test
@@ -801,24 +772,19 @@ void refreshAccessToken_RequestFailure_retried() throws IOException {
MockLowLevelHttpResponse response503 = new MockLowLevelHttpResponse().setStatusCode(503);
Instant start = Instant.now();
- try {
- transport.addResponseSequence(response503);
- transport.addResponseErrorSequence(error, error, error);
- credentials.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (GoogleAuthException ex) {
- Instant finish = Instant.now();
- long timeElapsed = Duration.between(start, finish).toMillis();
-
- // we expect max retry time of 7 sec +/- jitter
- assertTrue(timeElapsed > 5500 && timeElapsed < 10000);
- assertTrue(
- ex.getMessage()
- .contains("Error getting access token for service account: Invalid grant"));
- assertTrue(ex.isRetryable());
- assertEquals(3, ex.getRetryCount());
- assertTrue(ex.getCause() instanceof IOException);
- }
+ transport.addResponseSequence(response503);
+ transport.addResponseErrorSequence(error, error, error);
+ GoogleAuthException ex = assertThrows(GoogleAuthException.class, credentials::refresh);
+ Instant finish = Instant.now();
+ long timeElapsed = Duration.between(start, finish).toMillis();
+
+ // we expect max retry time of 7 sec +/- jitter
+ assertTrue(timeElapsed > 5500 && timeElapsed < 10000);
+ assertTrue(
+ ex.getMessage().contains("Error getting access token for service account: Invalid grant"));
+ assertTrue(ex.isRetryable());
+ assertEquals(3, ex.getRetryCount());
+ assertTrue(ex.getCause() instanceof IOException);
}
@Test
@@ -839,15 +805,11 @@ void refreshAccessToken_4xx_5xx_NonRetryableFails() throws IOException {
}
MockLowLevelHttpResponse mockResponse = new MockLowLevelHttpResponse().setStatusCode(status);
- try {
- transport.addResponseSequence(mockResponse);
- transport.addServiceAccount(CLIENT_EMAIL, accessToken2);
- credentials.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (GoogleAuthException ex) {
- assertFalse(ex.isRetryable());
- assertEquals(0, ex.getRetryCount());
- }
+ transport.addResponseSequence(mockResponse);
+ transport.addServiceAccount(CLIENT_EMAIL, accessToken2);
+ GoogleAuthException ex = assertThrows(GoogleAuthException.class, credentials::refresh);
+ assertFalse(ex.isRetryable());
+ assertEquals(0, ex.getRetryCount());
}
}
@@ -1071,8 +1033,8 @@ void equals_true() throws IOException {
SCOPES,
transportFactory,
tokenServer);
- assertTrue(credentials.equals(otherCredentials));
- assertTrue(otherCredentials.equals(credentials));
+ assertEquals(credentials, otherCredentials);
+ assertEquals(otherCredentials, credentials);
}
@Test
@@ -1097,8 +1059,8 @@ void equals_false_clientId() throws IOException {
SCOPES,
serverTransportFactory,
tokenServer1);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -1123,8 +1085,8 @@ void equals_false_email() throws IOException {
SCOPES,
serverTransportFactory,
tokenServer1);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -1152,8 +1114,8 @@ void equals_false_super() throws IOException {
.toBuilder()
.setUniverseDomain("universe.com")
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -1178,8 +1140,8 @@ void equals_false_keyId() throws IOException {
SCOPES,
serverTransportFactory,
tokenServer1);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -1204,8 +1166,8 @@ void equals_false_scopes() throws IOException {
ImmutableSet.of(),
serverTransportFactory,
tokenServer1);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -1231,8 +1193,8 @@ void equals_false_transportFactory() throws IOException {
SCOPES,
httpTransportFactory,
tokenServer1);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -1258,8 +1220,8 @@ void equals_false_tokenServer() throws IOException {
SCOPES,
serverTransportFactory,
tokenServer2);
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -1373,38 +1335,30 @@ void serialize() throws IOException, ClassNotFoundException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try (ObjectOutputStream output = new ObjectOutputStream(bytes)) {
output.writeObject(credentials);
- String s = output.toString();
}
ServiceAccountCredentials deserializedCredentials = serializeAndDeserialize(credentials);
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
assertEquals(
MockTokenServerTransportFactory.class,
deserializedCredentials.toBuilder().getHttpTransportFactory().getClass());
}
@Test
- void fromStream_nullTransport_throws() throws IOException {
+ void fromStream_nullTransport_throws() {
InputStream stream = new ByteArrayInputStream("foo".getBytes());
- try {
- ServiceAccountCredentials.fromStream(stream, null);
- fail("Should throw if HttpTransportFactory is null");
- } catch (NullPointerException expected) {
- // Expected
- }
+ assertThrows(
+ NullPointerException.class, () -> ServiceAccountCredentials.fromStream(stream, null));
}
@Test
- void fromStream_nullStream_throws() throws IOException {
+ void fromStream_nullStream_throws() {
MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
- try {
- ServiceAccountCredentials.fromStream(null, transportFactory);
- fail("Should throw if InputStream is null");
- } catch (NullPointerException expected) {
- // Expected
- }
+ assertThrows(
+ NullPointerException.class,
+ () -> ServiceAccountCredentials.fromStream(null, transportFactory));
}
@Test
@@ -1428,7 +1382,13 @@ void fromStream_noClientId_throws() throws IOException {
InputStream serviceAccountStream =
writeServiceAccountStream(null, CLIENT_EMAIL, PRIVATE_KEY_PKCS8, PRIVATE_KEY_ID);
- testFromStreamException(serviceAccountStream, "client_id");
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ ServiceAccountCredentials.fromStream(
+ serviceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("client_id"));
}
@Test
@@ -1436,7 +1396,13 @@ void fromStream_noClientEmail_throws() throws IOException {
InputStream serviceAccountStream =
writeServiceAccountStream(CLIENT_ID, null, PRIVATE_KEY_PKCS8, PRIVATE_KEY_ID);
- testFromStreamException(serviceAccountStream, "client_email");
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ ServiceAccountCredentials.fromStream(
+ serviceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("client_email"));
}
@Test
@@ -1456,12 +1422,8 @@ void getIdTokenWithAudience_badEmailError_issClaimTraced() throws IOException {
String expectedErrorMessage = String.format("iss: %s", CLIENT_EMAIL);
- try {
- tokenCredential.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (IOException expected) {
- assertTrue(expected.getMessage().contains(expectedErrorMessage));
- }
+ IOException exception = assertThrows(IOException.class, tokenCredential::refresh);
+ assertTrue(exception.getMessage().contains(expectedErrorMessage));
}
@Test
@@ -1469,7 +1431,13 @@ void fromStream_noPrivateKey_throws() throws IOException {
InputStream serviceAccountStream =
writeServiceAccountStream(CLIENT_ID, CLIENT_EMAIL, null, PRIVATE_KEY_ID);
- testFromStreamException(serviceAccountStream, "private_key");
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ ServiceAccountCredentials.fromStream(
+ serviceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("private_key"));
}
@Test
@@ -1477,7 +1445,13 @@ void fromStream_noPrivateKeyId_throws() throws IOException {
InputStream serviceAccountStream =
writeServiceAccountStream(CLIENT_ID, CLIENT_EMAIL, PRIVATE_KEY_PKCS8, null);
- testFromStreamException(serviceAccountStream, "private_key_id");
+ IOException exception =
+ assertThrows(
+ IOException.class,
+ () ->
+ ServiceAccountCredentials.fromStream(
+ serviceAccountStream, DUMMY_TRANSPORT_FACTORY));
+ assertTrue(exception.getMessage().contains("private_key_id"));
}
@Test
@@ -1586,7 +1560,7 @@ public void onSuccess(Map> metadata) {
@Override
public void onFailure(Throwable exception) {
- fail("Should not throw a failure.");
+ // Test framework should fail if this is called and success.set(true) is not reached.
}
});
@@ -1626,7 +1600,7 @@ public void onSuccess(Map> metadata) {
@Override
public void onFailure(Throwable exception) {
- fail("Should not throw a failure.");
+ // Test framework should fail if this is called and success.set(true) is not reached.
}
});
@@ -1683,12 +1657,7 @@ void refreshAccessToken_withDomainDelegation_selfSignedJWT_disabled() throws IOE
Map> metadata = credentials.getRequestMetadata(CALL_URI);
TestUtils.assertContainsBearerToken(metadata, accessToken1);
- try {
- verifyJwtAccess(metadata, "dummy.scope");
- fail("jwt access should fail with ServiceAccountUser");
- } catch (Exception ex) {
- // expected
- }
+ assertThrows(IllegalArgumentException.class, () -> verifyJwtAccess(metadata, "dummy.scope"));
transport.addServiceAccount(CLIENT_EMAIL, accessToken2);
credentials.refresh();
@@ -1755,11 +1724,7 @@ void getRequestMetadataWithCallback_selfSignedJWT() throws IOException {
new RequestMetadataCallback() {
@Override
public void onSuccess(Map> metadata) {
- try {
- verifyJwtAccess(metadata, "dummy.scope");
- } catch (IOException e) {
- fail("Should not throw a failure");
- }
+ assertDoesNotThrow(() -> verifyJwtAccess(metadata, "dummy.scope"));
success.set(true);
}
@@ -1888,15 +1853,4 @@ static InputStream writeServiceAccountStream(
clientId, clientEmail, privateKeyPkcs8, privateKeyId, null, null, universeDomain);
return TestUtils.jsonToInputStream(json);
}
-
- private static void testFromStreamException(InputStream stream, String expectedMessageContent) {
- try {
- ServiceAccountCredentials.fromStream(stream, DUMMY_TRANSPORT_FACTORY);
- fail(
- String.format(
- "Should throw exception with message containing '%s'", expectedMessageContent));
- } catch (IOException expected) {
- assertTrue(expected.getMessage().contains(expectedMessageContent));
- }
- }
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java
index 8d696663132b..d961f7b1b685 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/ServiceAccountJwtAccessCredentialsTest.java
@@ -33,12 +33,14 @@
import static com.google.auth.Credentials.GOOGLE_DEFAULT_UNIVERSE;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertSame;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;
@@ -117,50 +119,44 @@ void constructor_allParameters_constructs() throws IOException {
@Test
void constructor_noClientId_constructs() throws IOException {
PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
- ServiceAccountJwtAccessCredentials.newBuilder()
- .setClientEmail(SA_CLIENT_EMAIL)
- .setPrivateKey(privateKey)
- .setPrivateKeyId(SA_PRIVATE_KEY_ID)
- .build();
+ ServiceAccountJwtAccessCredentials.Builder builder =
+ ServiceAccountJwtAccessCredentials.newBuilder()
+ .setClientEmail(SA_CLIENT_EMAIL)
+ .setPrivateKey(privateKey)
+ .setPrivateKeyId(SA_PRIVATE_KEY_ID);
+ assertDoesNotThrow(builder::build);
}
@Test
void constructor_noPrivateKeyId_constructs() throws IOException {
PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
- ServiceAccountJwtAccessCredentials.newBuilder()
- .setClientId(SA_CLIENT_ID)
- .setClientEmail(SA_CLIENT_EMAIL)
- .setPrivateKey(privateKey)
- .build();
+ ServiceAccountJwtAccessCredentials.Builder builder =
+ ServiceAccountJwtAccessCredentials.newBuilder()
+ .setClientId(SA_CLIENT_ID)
+ .setClientEmail(SA_CLIENT_EMAIL)
+ .setPrivateKey(privateKey);
+ assertDoesNotThrow(builder::build);
}
@Test
void constructor_noEmail_throws() throws IOException {
PrivateKey privateKey = OAuth2Utils.privateKeyFromPkcs8(SA_PRIVATE_KEY_PKCS8);
- try {
- ServiceAccountJwtAccessCredentials.newBuilder()
- .setClientId(SA_CLIENT_ID)
- .setPrivateKey(privateKey)
- .setPrivateKeyId(SA_PRIVATE_KEY_ID)
- .build();
- fail("exception expected");
- } catch (NullPointerException e) {
- // Expected
- }
+ ServiceAccountJwtAccessCredentials.Builder builder =
+ ServiceAccountJwtAccessCredentials.newBuilder()
+ .setClientId(SA_CLIENT_ID)
+ .setPrivateKey(privateKey)
+ .setPrivateKeyId(SA_PRIVATE_KEY_ID);
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void constructor_noPrivateKey_throws() {
- try {
- ServiceAccountJwtAccessCredentials.newBuilder()
- .setClientId(SA_CLIENT_ID)
- .setClientEmail(SA_CLIENT_EMAIL)
- .setPrivateKeyId(SA_PRIVATE_KEY_ID)
- .build();
- fail("exception expected");
- } catch (NullPointerException e) {
- // Expected
- }
+ ServiceAccountJwtAccessCredentials.Builder builder =
+ ServiceAccountJwtAccessCredentials.newBuilder()
+ .setClientId(SA_CLIENT_ID)
+ .setClientEmail(SA_CLIENT_EMAIL)
+ .setPrivateKeyId(SA_PRIVATE_KEY_ID);
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
@@ -168,7 +164,7 @@ void getAuthenticationType_returnsJwtAccess() throws IOException {
Credentials credentials =
ServiceAccountJwtAccessCredentials.fromPkcs8(
SA_CLIENT_ID, SA_CLIENT_EMAIL, SA_PRIVATE_KEY_PKCS8, SA_PRIVATE_KEY_ID);
- assertEquals(credentials.getAuthenticationType(), "JWTAccess");
+ assertEquals("JWTAccess", credentials.getAuthenticationType());
}
@Test
@@ -200,7 +196,7 @@ void getRequestMetadata_blocking_hasJwtAccess() throws IOException {
Map> metadata = credentials.getRequestMetadata(CALL_URI);
- verifyJwtAccess(metadata, SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID);
+ verifyJwtAccess(metadata, CALL_URI);
}
@Test
@@ -217,7 +213,7 @@ void getRequestMetadata_blocking_defaultURI_hasJwtAccess() throws IOException {
Map> metadata = credentials.getRequestMetadata();
- verifyJwtAccess(metadata, SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID);
+ verifyJwtAccess(metadata, CALL_URI);
}
@Test
@@ -231,12 +227,7 @@ void getRequestMetadata_blocking_noURI_throws() throws IOException {
.setPrivateKeyId(SA_PRIVATE_KEY_ID)
.build();
- try {
- credentials.getRequestMetadata();
- fail("exception expected");
- } catch (IOException e) {
- // Expected
- }
+ assertThrows(IOException.class, credentials::getRequestMetadata);
}
@Test
@@ -305,7 +296,7 @@ void getRequestMetadata_async_hasJwtAccess() throws IOException {
credentials.getRequestMetadata(CALL_URI, executor, callback);
assertEquals(0, executor.numTasks());
assertNotNull(callback.metadata);
- verifyJwtAccess(callback.metadata, SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID);
+ verifyJwtAccess(callback.metadata, CALL_URI);
}
@Test
@@ -325,7 +316,7 @@ void getRequestMetadata_async_defaultURI_hasJwtAccess() throws IOException {
credentials.getRequestMetadata(null, executor, callback);
assertEquals(0, executor.numTasks());
assertNotNull(callback.metadata);
- verifyJwtAccess(callback.metadata, SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID);
+ verifyJwtAccess(callback.metadata, CALL_URI);
}
@Test
@@ -418,8 +409,8 @@ void getRequestMetadata_contains_quotaProjectId() throws IOException {
Map> metadata = credentials.getRequestMetadata(CALL_URI);
assertTrue(metadata.containsKey(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY));
assertEquals(
- metadata.get(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY),
- Collections.singletonList(QUOTA_PROJECT));
+ Collections.singletonList(QUOTA_PROJECT),
+ metadata.get(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY));
}
@Test
@@ -473,8 +464,8 @@ void equals_true() throws IOException {
.setPrivateKeyId(SA_PRIVATE_KEY_ID)
.setDefaultAudience(CALL_URI)
.build();
- assertTrue(credentials.equals(otherCredentials));
- assertTrue(otherCredentials.equals(credentials));
+ assertEquals(credentials, otherCredentials);
+ assertEquals(otherCredentials, credentials);
}
@Test
@@ -496,8 +487,8 @@ void equals_false_clientId() throws IOException {
.setPrivateKeyId(SA_PRIVATE_KEY_ID)
.setDefaultAudience(CALL_URI)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -519,8 +510,8 @@ void equals_false_email() throws IOException {
.setPrivateKeyId(SA_PRIVATE_KEY_ID)
.setDefaultAudience(CALL_URI)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -542,8 +533,8 @@ void equals_false_keyId() throws IOException {
.setPrivateKeyId("otherKeyId")
.setDefaultAudience(CALL_URI)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -566,8 +557,8 @@ void equals_false_callUri() throws IOException {
.setPrivateKeyId(SA_PRIVATE_KEY_ID)
.setDefaultAudience(otherCallUri)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
@@ -625,23 +616,19 @@ void serialize() throws IOException, ClassNotFoundException {
.build();
ServiceAccountJwtAccessCredentials deserializedCredentials =
serializeAndDeserialize(credentials);
- verifyJwtAccess(
- deserializedCredentials.getRequestMetadata(), SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID);
+ verifyJwtAccess(deserializedCredentials.getRequestMetadata(), CALL_URI);
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
}
@Test
- void fromStream_nullStream_throws() throws IOException {
+ void fromStream_nullStream_throws() {
MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
- try {
- ServiceAccountCredentials.fromStream(null, transportFactory);
- fail("Should throw if InputStream is null");
- } catch (NullPointerException expected) {
- // Expected
- }
+ assertThrows(
+ NullPointerException.class,
+ () -> ServiceAccountCredentials.fromStream(null, transportFactory));
}
@Test
@@ -654,7 +641,7 @@ void fromStream_hasJwtAccess() throws IOException {
assertNotNull(credentials);
Map> metadata = credentials.getRequestMetadata(CALL_URI);
- verifyJwtAccess(metadata, SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID);
+ verifyJwtAccess(metadata, CALL_URI);
}
@Test
@@ -668,7 +655,7 @@ void fromStream_defaultURI_hasJwtAccess() throws IOException {
assertNotNull(credentials);
Map> metadata = credentials.getRequestMetadata(null);
- verifyJwtAccess(metadata, SA_CLIENT_EMAIL, CALL_URI, SA_PRIVATE_KEY_ID);
+ verifyJwtAccess(metadata, CALL_URI);
}
@Test
@@ -722,7 +709,7 @@ void jwtWithClaims_overrideAudience() throws IOException {
Map> metadata = withAudience.getRequestMetadata(CALL_URI);
- verifyJwtAccess(metadata, SA_CLIENT_EMAIL, URI.create("new-audience"), SA_PRIVATE_KEY_ID);
+ verifyJwtAccess(metadata, URI.create("new-audience"));
}
@Test
@@ -735,12 +722,8 @@ void jwtWithClaims_noAudience() throws IOException {
.setPrivateKey(privateKey)
.setPrivateKeyId(SA_PRIVATE_KEY_ID)
.build();
- try {
- credentials.jwtWithClaims(JwtClaims.newBuilder().build());
- fail("Expected to throw exception for missing audience");
- } catch (IllegalStateException ex) {
- // expected exception
- }
+ JwtClaims claims = JwtClaims.newBuilder().build();
+ assertThrows(IllegalStateException.class, () -> credentials.jwtWithClaims(claims));
}
@Test
@@ -757,7 +740,7 @@ void jwtWithClaims_defaultAudience() throws IOException {
Credentials withAudience = credentials.jwtWithClaims(JwtClaims.newBuilder().build());
Map> metadata = withAudience.getRequestMetadata(CALL_URI);
- verifyJwtAccess(metadata, SA_CLIENT_EMAIL, URI.create("default-audience"), SA_PRIVATE_KEY_ID);
+ verifyJwtAccess(metadata, URI.create("default-audience"));
}
@Test
@@ -832,15 +815,7 @@ public void onFailure(Throwable exception) {
@Test
void fromJSON_noUniverseDomain() throws IOException {
- GenericJson json =
- writeServiceAccountJson(
- SA_CLIENT_ID,
- SA_CLIENT_EMAIL,
- SA_PRIVATE_KEY_PKCS8,
- "test-project-id",
- SA_PRIVATE_KEY_ID,
- QUOTA_PROJECT,
- null);
+ GenericJson json = writeServiceAccountJson(null);
ServiceAccountJwtAccessCredentials credentials =
ServiceAccountJwtAccessCredentials.fromJson(json, URI.create("default-aud"));
assertEquals(SA_CLIENT_ID, credentials.getClientId());
@@ -853,15 +828,7 @@ void fromJSON_noUniverseDomain() throws IOException {
@Test
void fromJSON_UniverseDomainSet() throws IOException {
- GenericJson json =
- writeServiceAccountJson(
- SA_CLIENT_ID,
- SA_CLIENT_EMAIL,
- SA_PRIVATE_KEY_PKCS8,
- "test-project-id",
- SA_PRIVATE_KEY_ID,
- QUOTA_PROJECT,
- "example.com");
+ GenericJson json = writeServiceAccountJson("example.com");
ServiceAccountJwtAccessCredentials credentials =
ServiceAccountJwtAccessCredentials.fromJson(json, URI.create("default-aud"));
assertEquals(SA_CLIENT_ID, credentials.getClientId());
@@ -933,11 +900,7 @@ void builder_customUniverseDomain() throws IOException {
assertEquals("example.com", credentials.getUniverseDomain());
}
- private void verifyJwtAccess(
- Map> metadata,
- String expectedEmail,
- URI expectedAudience,
- String expectedKeyId)
+ private void verifyJwtAccess(Map> metadata, URI expectedAudience)
throws IOException {
assertNotNull(metadata);
List authorizations = metadata.get(AuthHttpConstants.AUTHORIZATION);
@@ -951,50 +914,32 @@ private void verifyJwtAccess(
}
assertNotNull(assertion, "Bearer assertion not found");
JsonWebSignature signature = JsonWebSignature.parse(JSON_FACTORY, assertion);
- assertEquals(expectedEmail, signature.getPayload().getIssuer());
- assertEquals(expectedEmail, signature.getPayload().getSubject());
+ assertEquals(
+ ServiceAccountJwtAccessCredentialsTest.SA_CLIENT_EMAIL, signature.getPayload().getIssuer());
+ assertEquals(
+ ServiceAccountJwtAccessCredentialsTest.SA_CLIENT_EMAIL,
+ signature.getPayload().getSubject());
assertEquals(expectedAudience.toString(), signature.getPayload().getAudience());
- assertEquals(expectedKeyId, signature.getHeader().getKeyId());
+ assertEquals(
+ ServiceAccountJwtAccessCredentialsTest.SA_PRIVATE_KEY_ID, signature.getHeader().getKeyId());
}
private static void testFromStreamException(InputStream stream, String expectedMessageContent) {
- try {
- ServiceAccountJwtAccessCredentials.fromStream(stream, CALL_URI);
- fail(
- String.format(
- "Should throw exception with message containing '%s'", expectedMessageContent));
- } catch (IOException expected) {
- assertTrue(expected.getMessage().contains(expectedMessageContent));
- }
+ IOException expected =
+ assertThrows(
+ IOException.class,
+ () -> ServiceAccountJwtAccessCredentials.fromStream(stream, CALL_URI));
+ assertTrue(expected.getMessage().contains(expectedMessageContent));
}
- private GenericJson writeServiceAccountJson(
- String clientId,
- String clientEmail,
- String privateKeyPkcs8,
- String privateKeyId,
- String projectId,
- String quotaProjectId,
- String universeDomain) {
+ private GenericJson writeServiceAccountJson(String universeDomain) {
GenericJson json = new GenericJson();
- if (clientId != null) {
- json.put("client_id", clientId);
- }
- if (clientEmail != null) {
- json.put("client_email", clientEmail);
- }
- if (privateKeyPkcs8 != null) {
- json.put("private_key", privateKeyPkcs8);
- }
- if (privateKeyId != null) {
- json.put("private_key_id", privateKeyId);
- }
- if (projectId != null) {
- json.put("project_id", projectId);
- }
- if (quotaProjectId != null) {
- json.put("quota_project_id", quotaProjectId);
- }
+ json.put("client_id", ServiceAccountJwtAccessCredentialsTest.SA_CLIENT_ID);
+ json.put("client_email", ServiceAccountJwtAccessCredentialsTest.SA_CLIENT_EMAIL);
+ json.put("private_key", ServiceAccountJwtAccessCredentialsTest.SA_PRIVATE_KEY_PKCS8);
+ json.put("private_key_id", "test-project-id");
+ json.put("project_id", ServiceAccountJwtAccessCredentialsTest.SA_PRIVATE_KEY_ID);
+ json.put("quota_project_id", ServiceAccountJwtAccessCredentialsTest.QUOTA_PROJECT);
if (universeDomain != null) {
json.put("universe_domain", universeDomain);
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/StsRequestHandlerTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/StsRequestHandlerTest.java
index 6607403a4d7a..a0e2090d2cc9 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/StsRequestHandlerTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/StsRequestHandlerTest.java
@@ -176,7 +176,7 @@ void exchangeToken_throwsException() throws IOException {
TestUtils.buildHttpResponseException(
"invalidRequest", /* errorDescription= */ null, /* errorUri= */ null));
- OAuthException e = assertThrows(OAuthException.class, () -> requestHandler.exchangeToken());
+ OAuthException e = assertThrows(OAuthException.class, requestHandler::exchangeToken);
assertEquals("invalidRequest", e.getErrorCode());
assertNull(e.getErrorDescription());
@@ -196,7 +196,7 @@ void exchangeToken_withOptionalParams_throwsException() throws IOException {
transport.addResponseErrorSequence(
TestUtils.buildHttpResponseException("invalidRequest", "errorDescription", "errorUri"));
- OAuthException e = assertThrows(OAuthException.class, () -> requestHandler.exchangeToken());
+ OAuthException e = assertThrows(OAuthException.class, requestHandler::exchangeToken);
assertEquals("invalidRequest", e.getErrorCode());
assertEquals("errorDescription", e.getErrorDescription());
@@ -216,8 +216,7 @@ void exchangeToken_ioException() {
IOException e = new IOException();
transport.addResponseErrorSequence(e);
- IOException thrownException =
- assertThrows(IOException.class, () -> requestHandler.exchangeToken());
+ IOException thrownException = assertThrows(IOException.class, requestHandler::exchangeToken);
assertEquals(e, thrownException);
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TestEnvironmentProvider.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TestEnvironmentProvider.java
index 9e6de11089fe..b7921b3a426c 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TestEnvironmentProvider.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TestEnvironmentProvider.java
@@ -1,9 +1,39 @@
+/*
+ * Copyright 2021, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
package com.google.auth.oauth2;
import java.util.HashMap;
import java.util.Map;
-final class TestEnvironmentProvider implements EnvironmentProvider {
+public final class TestEnvironmentProvider implements EnvironmentProvider {
private final Map environmentVariables = new HashMap<>();
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TestPropertyProvider.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TestPropertyProvider.java
new file mode 100644
index 000000000000..e84d6ba5c8e0
--- /dev/null
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TestPropertyProvider.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.google.auth.oauth2;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class TestPropertyProvider implements PropertyProvider {
+ private final Map properties = new HashMap<>();
+
+ public TestPropertyProvider() {}
+
+ public void setProperty(String property, String value) {
+ properties.put(property, value);
+ }
+
+ @Override
+ public String getProperty(String property, String def) {
+ if (properties.containsKey(property)) {
+ return properties.get(property);
+ }
+ return def;
+ }
+}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TokenVerifierTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TokenVerifierTest.java
index 6872214f05d7..81847ffd24f8 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TokenVerifierTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/TokenVerifierTest.java
@@ -32,8 +32,8 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.LowLevelHttpRequest;
@@ -84,12 +84,9 @@ public long currentTimeMillis() {
void verifyExpiredToken() {
for (String token : ALL_TOKENS) {
TokenVerifier tokenVerifier = TokenVerifier.newBuilder().build();
- try {
- tokenVerifier.verify(token);
- fail("Should have thrown a VerificationException");
- } catch (TokenVerifier.VerificationException e) {
- assertTrue(e.getMessage().contains("expired"));
- }
+ VerificationException e =
+ assertThrows(VerificationException.class, () -> tokenVerifier.verify(token));
+ assertTrue(e.getMessage().contains("expired"));
}
}
@@ -98,12 +95,9 @@ void verifyExpectedAudience() {
TokenVerifier tokenVerifier =
TokenVerifier.newBuilder().setAudience("expected audience").build();
for (String token : ALL_TOKENS) {
- try {
- tokenVerifier.verify(token);
- fail("Should have thrown a VerificationException");
- } catch (TokenVerifier.VerificationException e) {
- assertTrue(e.getMessage().contains("audience does not match"));
- }
+ VerificationException e =
+ assertThrows(VerificationException.class, () -> tokenVerifier.verify(token));
+ assertTrue(e.getMessage().contains("audience does not match"));
}
}
@@ -111,12 +105,9 @@ void verifyExpectedAudience() {
void verifyExpectedIssuer() {
TokenVerifier tokenVerifier = TokenVerifier.newBuilder().setIssuer("expected issuer").build();
for (String token : ALL_TOKENS) {
- try {
- tokenVerifier.verify(token);
- fail("Should have thrown a VerificationException");
- } catch (TokenVerifier.VerificationException e) {
- assertTrue(e.getMessage().contains("issuer does not match"));
- }
+ VerificationException e =
+ assertThrows(VerificationException.class, () -> tokenVerifier.verify(token));
+ assertTrue(e.getMessage().contains("issuer does not match"));
}
}
@@ -151,13 +142,10 @@ public LowLevelHttpResponse execute() throws IOException {
.setHttpTransportFactory(httpTransportFactory)
.build();
- try {
- tokenVerifier.verify(ES256_TOKEN);
- fail("Should not be able to continue without exception.");
- } catch (TokenVerifier.VerificationException exception) {
- assertTrue(
- exception.getMessage().contains("Error fetching PublicKey from certificate location"));
- }
+ VerificationException exception =
+ assertThrows(VerificationException.class, () -> tokenVerifier.verify(ES256_TOKEN));
+ assertTrue(
+ exception.getMessage().contains("Error fetching PublicKey from certificate location"));
}
@Test
@@ -189,12 +177,9 @@ public LowLevelHttpResponse execute() throws IOException {
.setClock(FIXED_CLOCK)
.setHttpTransportFactory(httpTransportFactory)
.build();
- try {
- tokenVerifier.verify(ES256_TOKEN);
- fail("Should have failed verification");
- } catch (TokenVerifier.VerificationException e) {
- assertTrue(e.getMessage().contains("Error fetching PublicKey"));
- }
+ VerificationException e =
+ assertThrows(VerificationException.class, () -> tokenVerifier.verify(ES256_TOKEN));
+ assertTrue(e.getMessage().contains("Error fetching PublicKey"));
}
@Test
@@ -230,19 +215,12 @@ void verifyPublicKeyStoreIntermittentError() throws VerificationException, IOExc
.setHttpTransportFactory(transportFactory)
.build();
- try {
- tokenVerifier.verify(ES256_TOKEN);
- fail("Should not be able to continue without exception.");
- } catch (TokenVerifier.VerificationException exception) {
- assertTrue(exception.getMessage().contains("Error fetching PublicKey"));
- }
+ VerificationException exception =
+ assertThrows(VerificationException.class, () -> tokenVerifier.verify(ES256_TOKEN));
+ assertTrue(exception.getMessage().contains("Error fetching PublicKey"));
- try {
- tokenVerifier.verify(ES256_TOKEN);
- fail("Should not be able to continue without exception.");
- } catch (TokenVerifier.VerificationException exception) {
- assertTrue(exception.getCause().getMessage().contains("No valid public key"));
- }
+ exception = assertThrows(VerificationException.class, () -> tokenVerifier.verify(ES256_TOKEN));
+ assertTrue(exception.getCause().getMessage().contains("No valid public key"));
assertNotNull(tokenVerifier.verify(ES256_TOKEN));
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java
index 050a9d199079..bcde55b0045a 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserAuthorizerTest.java
@@ -40,7 +40,6 @@
import static org.junit.jupiter.api.Assertions.assertSame;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.auth.TestUtils;
import com.google.auth.http.HttpTransportFactory;
@@ -66,7 +65,7 @@ class UserAuthorizerTest {
private static final List GRANTED_SCOPES = Arrays.asList("scope1", "scope2");
private static final String GRANTED_SCOPES_STRING = String.join(" ", GRANTED_SCOPES);
private static final String DUMMY_SCOPE = "dummy_scope";
- private static final List DUMMY_SCOPES = Arrays.asList(DUMMY_SCOPE);
+ private static final List DUMMY_SCOPES = Collections.singletonList(DUMMY_SCOPE);
private static final Long EXPIRATION_TIME = 504000300L;
private static final AccessToken ACCESS_TOKEN =
AccessToken.newBuilder()
@@ -147,20 +146,15 @@ void constructorWithClientAuthenticationTypeNone() {
@Test
void constructorCommon_nullClientId_throws() {
- assertThrows(
- NullPointerException.class,
- () ->
- UserAuthorizer.newBuilder()
- .setScopes(DUMMY_SCOPES)
- .setCallbackUri(CALLBACK_URI)
- .build());
+ UserAuthorizer.Builder builder =
+ UserAuthorizer.newBuilder().setScopes(DUMMY_SCOPES).setCallbackUri(CALLBACK_URI);
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
void constructorCommon_nullScopes_throws() {
- assertThrows(
- NullPointerException.class,
- () -> UserAuthorizer.newBuilder().setClientId(CLIENT_ID).build());
+ UserAuthorizer.Builder builder = UserAuthorizer.newBuilder().setClientId(CLIENT_ID);
+ assertThrows(NullPointerException.class, builder::build);
}
@Test
@@ -181,30 +175,30 @@ void getCallbackUri_relativeToBase() {
@Test
void getAuthorizationUrl() throws IOException {
- final String CUSTOM_STATE = "custom_state";
- final String PROTOCOL = "https";
- final String HOST = "accounts.test.com";
- final String PATH = "/o/o/oauth2/auth";
- final URI AUTH_URI = URI.create(PROTOCOL + "://" + HOST + PATH);
+ final String customState = "custom_state";
+ final String protocol = "https";
+ final String host = "accounts.test.com";
+ final String path = "/o/o/oauth2/auth";
+ final URI authUri = URI.create(protocol + "://" + host + path);
final String EXPECTED_CALLBACK = "http://example.com" + CALLBACK_URI.toString();
UserAuthorizer authorizer =
UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(DUMMY_SCOPES)
.setCallbackUri(CALLBACK_URI)
- .setUserAuthUri(AUTH_URI)
+ .setUserAuthUri(authUri)
.setPKCEProvider(pkce)
.build();
- URL authorizationUrl = authorizer.getAuthorizationUrl(USER_ID, CUSTOM_STATE, BASE_URI);
+ URL authorizationUrl = authorizer.getAuthorizationUrl(USER_ID, customState, BASE_URI);
- assertEquals(PROTOCOL, authorizationUrl.getProtocol());
+ assertEquals(protocol, authorizationUrl.getProtocol());
assertEquals(-1, authorizationUrl.getPort());
- assertEquals(PATH, authorizationUrl.getPath());
- assertEquals(HOST, authorizationUrl.getHost());
+ assertEquals(path, authorizationUrl.getPath());
+ assertEquals(host, authorizationUrl.getHost());
String query = authorizationUrl.getQuery();
Map parameters = TestUtils.parseQuery(query);
- assertEquals(CUSTOM_STATE, parameters.get("state"));
+ assertEquals(customState, parameters.get("state"));
assertEquals(USER_ID, parameters.get("login_hint"));
assertEquals(EXPECTED_CALLBACK, parameters.get("redirect_uri"));
assertEquals(CLIENT_ID_VALUE, parameters.get("client_id"));
@@ -217,18 +211,17 @@ void getAuthorizationUrl() throws IOException {
@Test
void getAuthorizationUrl_additionalParameters() throws IOException {
- final String CUSTOM_STATE = "custom_state";
- final String PROTOCOL = "https";
- final String HOST = "accounts.test.com";
- final String PATH = "/o/o/oauth2/auth";
- final URI AUTH_URI = URI.create(PROTOCOL + "://" + HOST + PATH);
- final String EXPECTED_CALLBACK = "http://example.com" + CALLBACK_URI.toString();
+ final String customState = "custom_state";
+ final String protocol = "https";
+ final String host = "accounts.test.com";
+ final String path = "/o/o/oauth2/auth";
+ final URI authUri = URI.create(protocol + "://" + host + path);
UserAuthorizer authorizer =
UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
.setScopes(DUMMY_SCOPES)
.setCallbackUri(CALLBACK_URI)
- .setUserAuthUri(AUTH_URI)
+ .setUserAuthUri(authUri)
.build();
Map additionalParameters = new HashMap();
additionalParameters.put("param1", "value1");
@@ -236,7 +229,7 @@ void getAuthorizationUrl_additionalParameters() throws IOException {
// Verify that the authorization URL doesn't include the additional parameters if they are not
// passed in.
- URL authorizationUrl = authorizer.getAuthorizationUrl(USER_ID, CUSTOM_STATE, BASE_URI);
+ URL authorizationUrl = authorizer.getAuthorizationUrl(USER_ID, customState, BASE_URI);
String query = authorizationUrl.getQuery();
Map parameters = TestUtils.parseQuery(query);
assertFalse(parameters.containsKey("param1"));
@@ -244,7 +237,7 @@ void getAuthorizationUrl_additionalParameters() throws IOException {
// Verify that the authorization URL includes the additional parameters if they are passed in.
authorizationUrl =
- authorizer.getAuthorizationUrl(USER_ID, CUSTOM_STATE, BASE_URI, additionalParameters);
+ authorizer.getAuthorizationUrl(USER_ID, customState, BASE_URI, additionalParameters);
query = authorizationUrl.getQuery();
parameters = TestUtils.parseQuery(query);
assertEquals("value1", parameters.get("param1"));
@@ -252,7 +245,7 @@ void getAuthorizationUrl_additionalParameters() throws IOException {
// Verify that the authorization URL doesn't include the additional parameters passed in the
// previous call to the authorizer
- authorizationUrl = authorizer.getAuthorizationUrl(USER_ID, CUSTOM_STATE, BASE_URI);
+ authorizationUrl = authorizer.getAuthorizationUrl(USER_ID, customState, BASE_URI);
query = authorizationUrl.getQuery();
parameters = TestUtils.parseQuery(query);
assertFalse(parameters.containsKey("param1"));
@@ -392,7 +385,7 @@ void testGetTokenResponseFromAuthCodeExchange_missingAuthCode_throws() {
}
@Test
- void testGetTokenResponseFromAuthCodeExchange_missingAccessToken_throws() throws IOException {
+ void testGetTokenResponseFromAuthCodeExchange_missingAccessToken_throws() {
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
transportFactory.transport.addClient(CLIENT_ID_VALUE, CLIENT_SECRET);
// Missing access token.
@@ -452,7 +445,7 @@ void getCredentials_storedCredentials_returnsStored() throws IOException {
}
@Test
- void getCredentials_nullUserId_throws() throws IOException {
+ void getCredentials_nullUserId_throws() {
TokenStore tokenStore = new MemoryTokensStorage();
UserAuthorizer authorizer =
UserAuthorizer.newBuilder()
@@ -643,7 +636,7 @@ void getCredentialsFromCode_additionalParameters() throws IOException {
}
@Test
- void getCredentialsFromCode_nullCode_throws() throws IOException {
+ void getCredentialsFromCode_nullCode_throws() {
UserAuthorizer authorizer =
UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
@@ -695,7 +688,7 @@ void getAndStoreCredentialsFromCode_getAndStoresCredentials() throws IOException
}
@Test
- void getAndStoreCredentialsFromCode_nullCode_throws() throws IOException {
+ void getAndStoreCredentialsFromCode_nullCode_throws() {
UserAuthorizer authorizer =
UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
@@ -709,7 +702,7 @@ void getAndStoreCredentialsFromCode_nullCode_throws() throws IOException {
}
@Test
- void getAndStoreCredentialsFromCode_nullUserId_throws() throws IOException {
+ void getAndStoreCredentialsFromCode_nullUserId_throws() {
UserAuthorizer authorizer =
UserAuthorizer.newBuilder()
.setClientId(CLIENT_ID)
@@ -756,19 +749,14 @@ void revokeAuthorization_revokesAndClears() throws IOException {
authorizer.revokeAuthorization(USER_ID);
- try {
- credentials1.refresh();
- fail("Credentials should not refresh after revoke.");
- } catch (IOException expected) {
- // Expected
- }
+ assertThrows(IOException.class, credentials1::refresh);
UserCredentials credentials2 = authorizer.getCredentials(USER_ID);
assertNull(credentials2);
}
@Test
void nullCodeVerifierPKCEProvider() {
- PKCEProvider pkce =
+ PKCEProvider pkceProvider =
new PKCEProvider() {
@Override
public String getCodeVerifier() {
@@ -786,20 +774,17 @@ public String getCodeChallenge() {
}
};
- assertThrows(
- IllegalArgumentException.class,
- () ->
- UserAuthorizer.newBuilder()
- .setClientId(CLIENT_ID)
- .setScopes(DUMMY_SCOPES)
- .setTokenStore(new MemoryTokensStorage())
- .setPKCEProvider(pkce)
- .build());
+ UserAuthorizer.Builder builder =
+ UserAuthorizer.newBuilder()
+ .setClientId(CLIENT_ID)
+ .setScopes(DUMMY_SCOPES)
+ .setTokenStore(new MemoryTokensStorage());
+ assertThrows(IllegalArgumentException.class, () -> builder.setPKCEProvider(pkceProvider));
}
@Test
void nullCodeChallengePKCEProvider() {
- PKCEProvider pkce =
+ PKCEProvider pkceProvider =
new PKCEProvider() {
@Override
public String getCodeVerifier() {
@@ -817,20 +802,17 @@ public String getCodeChallenge() {
}
};
- assertThrows(
- IllegalArgumentException.class,
- () ->
- UserAuthorizer.newBuilder()
- .setClientId(CLIENT_ID)
- .setScopes(DUMMY_SCOPES)
- .setTokenStore(new MemoryTokensStorage())
- .setPKCEProvider(pkce)
- .build());
+ UserAuthorizer.Builder builder =
+ UserAuthorizer.newBuilder()
+ .setClientId(CLIENT_ID)
+ .setScopes(DUMMY_SCOPES)
+ .setTokenStore(new MemoryTokensStorage());
+ assertThrows(IllegalArgumentException.class, () -> builder.setPKCEProvider(pkceProvider));
}
@Test
void nullCodeChallengeMethodPKCEProvider() {
- PKCEProvider pkce =
+ PKCEProvider pkceProvider =
new PKCEProvider() {
@Override
public String getCodeVerifier() {
@@ -848,15 +830,12 @@ public String getCodeChallenge() {
}
};
- assertThrows(
- IllegalArgumentException.class,
- () ->
- UserAuthorizer.newBuilder()
- .setClientId(CLIENT_ID)
- .setScopes(DUMMY_SCOPES)
- .setTokenStore(new MemoryTokensStorage())
- .setPKCEProvider(pkce)
- .build());
+ UserAuthorizer.Builder builder =
+ UserAuthorizer.newBuilder()
+ .setClientId(CLIENT_ID)
+ .setScopes(DUMMY_SCOPES)
+ .setTokenStore(new MemoryTokensStorage());
+ assertThrows(IllegalArgumentException.class, () -> builder.setPKCEProvider(pkceProvider));
}
@Test
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java
index e5a6c658a320..aaabf4aeefec 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/UserCredentialsTest.java
@@ -31,6 +31,7 @@
package com.google.auth.oauth2;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotEquals;
@@ -85,13 +86,9 @@ class UserCredentialsTest extends BaseSerializationTest {
@Test
void constructor_accessAndRefreshTokenNull_throws() {
- assertThrows(
- IllegalStateException.class,
- () ->
- UserCredentials.newBuilder()
- .setClientId(CLIENT_ID)
- .setClientSecret(CLIENT_SECRET)
- .build());
+ UserCredentials.Builder builder =
+ UserCredentials.newBuilder().setClientId(CLIENT_ID).setClientSecret(CLIENT_SECRET);
+ assertThrows(IllegalStateException.class, builder::build);
}
@Test
@@ -180,8 +177,8 @@ void fromJson_hasQuotaProjectId() throws IOException {
Map> metadata = credentials.getRequestMetadata(CALL_URI);
assertTrue(metadata.containsKey(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY));
assertEquals(
- metadata.get(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY),
- Collections.singletonList(QUOTA_PROJECT));
+ Collections.singletonList(QUOTA_PROJECT),
+ metadata.get(GoogleCredentials.QUOTA_PROJECT_ID_HEADER_KEY));
}
@Test
@@ -203,7 +200,7 @@ void getRequestMetadata_initialToken_hasAccessToken() throws IOException {
}
@Test
- void getRequestMetadata_initialTokenRefreshed_throws() throws IOException {
+ void getRequestMetadata_initialTokenRefreshed_throws() {
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
@@ -215,12 +212,7 @@ void getRequestMetadata_initialTokenRefreshed_throws() throws IOException {
.setHttpTransportFactory(transportFactory)
.build();
- try {
- userCredentials.refresh();
- fail("Should not be able to refresh without refresh token.");
- } catch (IllegalStateException expected) {
- // Expected
- }
+ assertThrows(IllegalStateException.class, userCredentials::refresh);
}
@Test
@@ -243,18 +235,18 @@ void getRequestMetadata_fromRefreshToken_hasAccessToken() throws IOException {
@Test
void getRequestMetadata_customTokenServer_hasAccessToken() throws IOException {
- final URI TOKEN_SERVER = URI.create("https://foo.com/bar");
+ final URI tokenServerUri = URI.create("https://foo.com/bar");
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
transportFactory.transport.addClient(CLIENT_ID, CLIENT_SECRET);
transportFactory.transport.addRefreshToken(REFRESH_TOKEN, ACCESS_TOKEN);
- transportFactory.transport.setTokenServerUri(TOKEN_SERVER);
+ transportFactory.transport.setTokenServerUri(tokenServerUri);
UserCredentials userCredentials =
UserCredentials.newBuilder()
.setClientId(CLIENT_ID)
.setClientSecret(CLIENT_SECRET)
.setRefreshToken(REFRESH_TOKEN)
.setHttpTransportFactory(transportFactory)
- .setTokenServerUri(TOKEN_SERVER)
+ .setTokenServerUri(tokenServerUri)
.build();
Map> metadata = userCredentials.getRequestMetadata(CALL_URI);
@@ -263,7 +255,7 @@ void getRequestMetadata_customTokenServer_hasAccessToken() throws IOException {
}
@Test
- void equals_true() throws IOException {
+ void equals_true() {
final URI tokenServer = URI.create("https://foo.com/bar");
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
@@ -287,12 +279,12 @@ void equals_true() throws IOException {
.setTokenServerUri(tokenServer)
.setQuotaProjectId(QUOTA_PROJECT)
.build();
- assertTrue(credentials.equals(otherCredentials));
- assertTrue(otherCredentials.equals(credentials));
+ assertEquals(credentials, otherCredentials);
+ assertEquals(otherCredentials, credentials);
}
@Test
- void equals_false_clientId() throws IOException {
+ void equals_false_clientId() {
final URI tokenServer1 = URI.create("https://foo1.com/bar");
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
@@ -314,12 +306,12 @@ void equals_false_clientId() throws IOException {
.setHttpTransportFactory(httpTransportFactory)
.setTokenServerUri(tokenServer1)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
- void equals_false_clientSecret() throws IOException {
+ void equals_false_clientSecret() {
final URI tokenServer1 = URI.create("https://foo1.com/bar");
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
@@ -341,12 +333,12 @@ void equals_false_clientSecret() throws IOException {
.setHttpTransportFactory(httpTransportFactory)
.setTokenServerUri(tokenServer1)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
- void equals_false_refreshToken() throws IOException {
+ void equals_false_refreshToken() {
final URI tokenServer1 = URI.create("https://foo1.com/bar");
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
@@ -368,12 +360,12 @@ void equals_false_refreshToken() throws IOException {
.setHttpTransportFactory(httpTransportFactory)
.setTokenServerUri(tokenServer1)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
- void equals_false_accessToken() throws IOException {
+ void equals_false_accessToken() {
final URI tokenServer1 = URI.create("https://foo1.com/bar");
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
AccessToken otherAccessToken = new AccessToken("otherAccessToken", null);
@@ -396,13 +388,13 @@ void equals_false_accessToken() throws IOException {
.setHttpTransportFactory(httpTransportFactory)
.setTokenServerUri(tokenServer1)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
assertNotEquals(credentials.hashCode(), otherAccessToken.hashCode());
}
@Test
- void equals_false_transportFactory() throws IOException {
+ void equals_false_transportFactory() {
final URI tokenServer1 = URI.create("https://foo1.com/bar");
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
MockHttpTransportFactory httpTransportFactory = new MockHttpTransportFactory();
@@ -425,12 +417,12 @@ void equals_false_transportFactory() throws IOException {
.setHttpTransportFactory(serverTransportFactory)
.setTokenServerUri(tokenServer1)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
- void equals_false_tokenServer() throws IOException {
+ void equals_false_tokenServer() {
final URI tokenServer1 = URI.create("https://foo1.com/bar");
final URI tokenServer2 = URI.create("https://foo2.com/bar");
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
@@ -453,12 +445,12 @@ void equals_false_tokenServer() throws IOException {
.setHttpTransportFactory(httpTransportFactory)
.setTokenServerUri(tokenServer2)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
- void equals_false_quotaProjectId() throws IOException {
+ void equals_false_quotaProjectId() {
final String quotaProject1 = "sample-id-1";
final String quotaProject2 = "sample-id-2";
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
@@ -481,12 +473,12 @@ void equals_false_quotaProjectId() throws IOException {
.setHttpTransportFactory(httpTransportFactory)
.setQuotaProjectId(quotaProject2)
.build();
- assertFalse(credentials.equals(otherCredentials));
- assertFalse(otherCredentials.equals(credentials));
+ assertNotEquals(credentials, otherCredentials);
+ assertNotEquals(otherCredentials, credentials);
}
@Test
- void toString_containsFields() throws IOException {
+ void toString_containsFields() {
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
final URI tokenServer = URI.create("https://foo.com/bar");
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
@@ -518,7 +510,7 @@ void toString_containsFields() throws IOException {
}
@Test
- void hashCode_equals() throws IOException {
+ void hashCode_equals() {
final URI tokenServer = URI.create("https://foo.com/bar");
MockTokenServerTransportFactory transportFactory = new MockTokenServerTransportFactory();
AccessToken accessToken = new AccessToken(ACCESS_TOKEN, null);
@@ -563,29 +555,20 @@ void serialize() throws IOException, ClassNotFoundException {
assertEquals(credentials, deserializedCredentials);
assertEquals(credentials.hashCode(), deserializedCredentials.hashCode());
assertEquals(credentials.toString(), deserializedCredentials.toString());
- assertSame(deserializedCredentials.clock, Clock.SYSTEM);
+ assertSame(Clock.SYSTEM, deserializedCredentials.clock);
}
@Test
- void fromStream_nullTransport_throws() throws IOException {
+ void fromStream_nullTransport_throws() {
InputStream stream = new ByteArrayInputStream("foo".getBytes());
- try {
- UserCredentials.fromStream(stream, null);
- fail("Should throw if HttpTransportFactory is null");
- } catch (NullPointerException expected) {
- // Expected
- }
+ assertThrows(NullPointerException.class, () -> UserCredentials.fromStream(stream, null));
}
@Test
- void fromStream_nullStream_throws() throws IOException {
+ void fromStream_nullStream_throws() {
MockHttpTransportFactory transportFactory = new MockHttpTransportFactory();
- try {
- UserCredentials.fromStream(null, transportFactory);
- fail("Should throw if InputStream is null");
- } catch (NullPointerException expected) {
- // Expected
- }
+ assertThrows(
+ NullPointerException.class, () -> UserCredentials.fromStream(null, transportFactory));
}
@Test
@@ -607,25 +590,31 @@ void fromStream_user_providesToken() throws IOException {
void fromStream_userNoClientId_throws() throws IOException {
InputStream userStream = writeUserStream(null, CLIENT_SECRET, REFRESH_TOKEN, QUOTA_PROJECT);
- testFromStreamException(userStream, "client_id");
+ IOException exception =
+ assertThrows(IOException.class, () -> UserCredentials.fromStream(userStream));
+ assertTrue(exception.getMessage().contains("client_id"));
}
@Test
void fromStream_userNoClientSecret_throws() throws IOException {
InputStream userStream = writeUserStream(CLIENT_ID, null, REFRESH_TOKEN, QUOTA_PROJECT);
- testFromStreamException(userStream, "client_secret");
+ IOException exception =
+ assertThrows(IOException.class, () -> UserCredentials.fromStream(userStream));
+ assertTrue(exception.getMessage().contains("client_secret"));
}
@Test
void fromStream_userNoRefreshToken_throws() throws IOException {
InputStream userStream = writeUserStream(CLIENT_ID, CLIENT_SECRET, null, QUOTA_PROJECT);
- testFromStreamException(userStream, "refresh_token");
+ IOException exception =
+ assertThrows(IOException.class, () -> UserCredentials.fromStream(userStream));
+ assertTrue(exception.getMessage().contains("refresh_token"));
}
@Test
- void saveUserCredentials_saved_throws() throws IOException {
+ void saveUserCredentials_saved_doesNotThrow() throws IOException {
UserCredentials userCredentials =
UserCredentials.newBuilder()
.setClientId(CLIENT_ID)
@@ -636,11 +625,11 @@ void saveUserCredentials_saved_throws() throws IOException {
file.deleteOnExit();
String filePath = file.getAbsolutePath();
- userCredentials.save(filePath);
+ assertDoesNotThrow(() -> userCredentials.save(filePath));
}
@Test
- void saveAndRestoreUserCredential_saveAndRestored_throws() throws IOException {
+ void saveAndRestoreUserCredential_saveAndRestored_doesNotThrow() throws IOException {
UserCredentials userCredentials =
UserCredentials.newBuilder()
.setClientId(CLIENT_ID)
@@ -653,15 +642,14 @@ void saveAndRestoreUserCredential_saveAndRestored_throws() throws IOException {
String filePath = file.getAbsolutePath();
- userCredentials.save(filePath);
-
- FileInputStream inputStream = new FileInputStream(new File(filePath));
-
- UserCredentials restoredCredentials = UserCredentials.fromStream(inputStream);
+ assertDoesNotThrow(() -> userCredentials.save(filePath));
- assertEquals(userCredentials.getClientId(), restoredCredentials.getClientId());
- assertEquals(userCredentials.getClientSecret(), restoredCredentials.getClientSecret());
- assertEquals(userCredentials.getRefreshToken(), restoredCredentials.getRefreshToken());
+ try (FileInputStream inputStream = new FileInputStream(filePath)) {
+ UserCredentials restoredCredentials = UserCredentials.fromStream(inputStream);
+ assertEquals(userCredentials.getClientId(), restoredCredentials.getClientId());
+ assertEquals(userCredentials.getClientSecret(), restoredCredentials.getClientSecret());
+ assertEquals(userCredentials.getRefreshToken(), restoredCredentials.getRefreshToken());
+ }
}
@Test
@@ -791,15 +779,11 @@ void IdTokenCredentials_NoRetry_RetryableStatus_throws() throws IOException {
UserCredentials credentials = UserCredentials.fromStream(userStream, transportFactory);
- try {
- transportFactory.transport.addResponseSequence(response408, response429);
- credentials.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (GoogleAuthException ex) {
- assertTrue(ex.getMessage().contains("com.google.api.client.http.HttpResponseException: 408"));
- assertTrue(ex.isRetryable());
- assertEquals(0, ex.getRetryCount());
- }
+ transportFactory.transport.addResponseSequence(response408, response429);
+ GoogleAuthException ex = assertThrows(GoogleAuthException.class, credentials::refresh);
+ assertTrue(ex.getMessage().contains("com.google.api.client.http.HttpResponseException: 408"));
+ assertTrue(ex.isRetryable());
+ assertEquals(0, ex.getRetryCount());
IdTokenCredentials tokenCredential =
IdTokenCredentials.newBuilder().setIdTokenProvider(credentials).build();
@@ -808,14 +792,11 @@ void IdTokenCredentials_NoRetry_RetryableStatus_throws() throws IOException {
assertNull(tokenCredential.getIdToken());
// trigger the refresh like it would happen during a request build
- try {
- tokenCredential.getRequestMetadata(CALL_URI);
- fail("Should not be able to use credential without exception.");
- } catch (GoogleAuthException ex) {
- assertTrue(ex.getMessage().contains("com.google.api.client.http.HttpResponseException: 429"));
- assertTrue(ex.isRetryable());
- assertEquals(0, ex.getRetryCount());
- }
+ GoogleAuthException ex2 =
+ assertThrows(GoogleAuthException.class, () -> tokenCredential.getRequestMetadata(CALL_URI));
+ assertTrue(ex2.getMessage().contains("com.google.api.client.http.HttpResponseException: 429"));
+ assertTrue(ex2.isRetryable());
+ assertEquals(0, ex2.getRetryCount());
}
@Test
@@ -850,14 +831,10 @@ void refreshAccessToken_4xx_5xx_NonRetryableFails() throws IOException {
}
MockLowLevelHttpResponse mockResponse = new MockLowLevelHttpResponse().setStatusCode(status);
- try {
- transportFactory.transport.addResponseSequence(mockResponse);
- credentials.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (GoogleAuthException ex) {
- assertFalse(ex.isRetryable());
- assertEquals(0, ex.getRetryCount());
- }
+ transportFactory.transport.addResponseSequence(mockResponse);
+ GoogleAuthException ex = assertThrows(GoogleAuthException.class, credentials::refresh);
+ assertFalse(ex.isRetryable());
+ assertEquals(0, ex.getRetryCount());
}
}
@@ -880,12 +857,8 @@ void IdTokenCredentials_NoUserEmailScope_throws() throws IOException {
+ " login'. The latter form would not work for Cloud Run, but would still generate an"
+ " id token.";
- try {
- tokenCredential.refresh();
- fail("Should not be able to use credential without exception.");
- } catch (IOException expected) {
- assertTrue(expected.getMessage().equals(expectedMessageContent));
- }
+ IOException exception = assertThrows(IOException.class, tokenCredential::refresh);
+ assertEquals(exception.getMessage(), expectedMessageContent);
}
@Test
@@ -940,15 +913,4 @@ static InputStream writeUserStream(
GenericJson json = writeUserJson(clientId, clientSecret, refreshToken, quotaProjectId, null);
return TestUtils.jsonToInputStream(json);
}
-
- private static void testFromStreamException(InputStream stream, String expectedMessageContent) {
- try {
- UserCredentials.fromStream(stream);
- fail(
- String.format(
- "Should throw exception with message containing '%s'", expectedMessageContent));
- } catch (IOException expected) {
- assertTrue(expected.getMessage().contains(expectedMessageContent));
- }
- }
}
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/functional/FTQuotaProjectId.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/functional/FTQuotaProjectId.java
index 034507e07bde..842781219edb 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/functional/FTQuotaProjectId.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/functional/FTQuotaProjectId.java
@@ -39,7 +39,7 @@
import java.io.IOException;
import org.junit.jupiter.api.Test;
-public final class FTQuotaProjectId {
+final class FTQuotaProjectId {
@Test
void validate_quota_from_environment_used() throws IOException {
diff --git a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/functional/FTServiceAccountCredentialsTest.java b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/functional/FTServiceAccountCredentialsTest.java
index ca0ec4fc134f..82ba939611f5 100644
--- a/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/functional/FTServiceAccountCredentialsTest.java
+++ b/google-auth-library-java/oauth2_http/javatests/com/google/auth/oauth2/functional/FTServiceAccountCredentialsTest.java
@@ -34,8 +34,8 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.junit.jupiter.api.Assertions.fail;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpRequest;
@@ -50,7 +50,6 @@
import com.google.auth.oauth2.IdTokenCredentials;
import com.google.auth.oauth2.IdTokenProvider;
import com.google.auth.oauth2.OAuth2Utils;
-import java.io.FileNotFoundException;
import java.io.IOException;
import org.junit.jupiter.api.Test;
@@ -135,36 +134,35 @@ void ScopeSetNoAudienceOnePlatformTest() throws Exception {
}
@Test
- void WrongScopeComputeTest() throws Exception {
+ void WrongScopeComputeTest() {
executeRequestWrongScope(computeUrl);
}
@Test
- void WrongScopeStorageTest() throws Exception {
+ void WrongScopeStorageTest() {
executeRequestWrongScope(storageUrl);
}
@Test
- void WrongScopeBigQueryTest() throws Exception {
+ void WrongScopeBigQueryTest() {
executeRequestWrongScope(bigQueryUrl);
}
@Test
- void WrongScopeOnePlatformTest() throws Exception {
+ void WrongScopeOnePlatformTest() {
executeRequestWrongScope(cloudTasksUrl);
}
- private void executeRequestWrongScope(String serviceUri)
- throws FileNotFoundException, IOException {
+ private void executeRequestWrongScope(String serviceUri) {
String expectedMessage = "403 Forbidden";
- try {
- executeRequestWithCredentialsWithScope(
- serviceUri, "https://www.googleapis.com/auth/adexchange.buyer");
- fail("Should throw exception: " + expectedMessage);
- } catch (IOException expected) {
- assertTrue(expected.getMessage().contains(expectedMessage));
- }
+ IOException expected =
+ assertThrows(
+ IOException.class,
+ () ->
+ executeRequestWithCredentialsWithScope(
+ serviceUri, "https://www.googleapis.com/auth/adexchange.buyer"));
+ assertTrue(expected.getMessage().contains(expectedMessage));
}
private HttpResponse executeRequestWithCredentialsWithoutScope(String serviceUrl)
diff --git a/google-auth-library-java/oauth2_http/pom.xml b/google-auth-library-java/oauth2_http/pom.xml
index e49953262b53..30311fc42007 100644
--- a/google-auth-library-java/oauth2_http/pom.xml
+++ b/google-auth-library-java/oauth2_http/pom.xml
@@ -7,7 +7,7 @@
com.google.auth
google-auth-library-parent
- 1.45.0
+ 1.46.0
../pom.xml
diff --git a/google-auth-library-java/oauth2_http/testresources/mtls/certificate_config.json b/google-auth-library-java/oauth2_http/testresources/mtls/certificate_config.json
new file mode 100644
index 000000000000..8a7592faf295
--- /dev/null
+++ b/google-auth-library-java/oauth2_http/testresources/mtls/certificate_config.json
@@ -0,0 +1,8 @@
+{
+ "cert_configs": {
+ "workload": {
+ "cert_path": "testresources/mtls/test_cert.pem",
+ "key_path": "testresources/mtls/test_key.pem"
+ }
+ }
+}
diff --git a/google-auth-library-java/oauth2_http/testresources/mtls/test_cert.pem b/google-auth-library-java/oauth2_http/testresources/mtls/test_cert.pem
new file mode 100644
index 000000000000..17fcf0227c80
--- /dev/null
+++ b/google-auth-library-java/oauth2_http/testresources/mtls/test_cert.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICGzCCAYSgAwIBAgIIWrt6xtmHPs4wDQYJKoZIhvcNAQEFBQAwMzExMC8GA1UE
+AxMoMTAwOTEyMDcyNjg3OC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbTAeFw0x
+MjEyMDExNjEwNDRaFw0yMjExMjkxNjEwNDRaMDMxMTAvBgNVBAMTKDEwMDkxMjA3
+MjY4NzguYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20wgZ8wDQYJKoZIhvcNAQEB
+BQADgY0AMIGJAoGBAL1SdY8jTUVU7O4/XrZLYTw0ON1lV6MQRGajFDFCqD2Fd9tQ
+GLW8Iftx9wfXe1zuaehJSgLcyCxazfyJoN3RiONBihBqWY6d3lQKqkgsRTNZkdFJ
+Wdzl/6CxhK9sojh2p0r3tydtv9iwq5fuuWIvtODtT98EgphhncQAqkKoF3zVAgMB
+AAGjODA2MAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQM
+MAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBBQUAA4GBAD8XQEqzGePa9VrvtEGpf+R4
+fkxKbcYAzqYq202nKu0kfjhIYkYSBj6gi348YaxE64yu60TVl42l5HThmswUheW4
+uQIaq36JvwvsDP5Zoj5BgiNSnDAFQp+jJFBRUA5vooJKgKgMDf/r/DCOsbO6VJF1
+kWwa9n19NFiV0z3m6isj
+-----END CERTIFICATE-----
diff --git a/google-auth-library-java/oauth2_http/testresources/mtls/test_key.pem b/google-auth-library-java/oauth2_http/testresources/mtls/test_key.pem
new file mode 100644
index 000000000000..c6a91c3ce623
--- /dev/null
+++ b/google-auth-library-java/oauth2_http/testresources/mtls/test_key.pem
@@ -0,0 +1,16 @@
+-----BEGIN PRIVATE KEY-----
+MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAL1SdY8jTUVU7O4/
+XrZLYTw0ON1lV6MQRGajFDFCqD2Fd9tQGLW8Iftx9wfXe1zuaehJSgLcyCxazfyJ
+oN3RiONBihBqWY6d3lQKqkgsRTNZkdFJWdzl/6CxhK9sojh2p0r3tydtv9iwq5fu
+uWIvtODtT98EgphhncQAqkKoF3zVAgMBAAECgYB51B9cXe4yiGTzJ4pOKpHGySAy
+sC1F/IjXt2eeD3PuKv4m/hL4l7kScpLx0+NJuQ4j8U2UK/kQOdrGANapB1ZbMZAK
+/q0xmIUzdNIDiGSoTXGN2mEfdsEpQ/Xiv0lyhYBBPC/K4sYIpHccnhSRQUZlWLLY
+lE5cFNKC9b7226mNvQJBAPt0hfCNIN0kUYOA9jdLtx7CE4ySGMPf5KPBuzPd8ty1
+fxaFm9PB7B76VZQYmHcWy8rT5XjoLJHrmGW1ZvP+iDsCQQDAvnKoarPOGb5iJfkq
+RrA4flf1TOlf+1+uqIOJ94959jkkJeb0gv/TshDnm6/bWn+1kJylQaKygCizwPwB
+Z84vAkA0Duur4YvsPJijoQ9YY1SGCagCcjyuUKwFOxaGpmyhRPIKt56LOJqpzyno
+fy8ReKa4VyYq4eZYT249oFCwMwIBAkAROPNF2UL3x5UbcAkznd1hLujtIlI4IV4L
+XUNjsJtBap7we/KHJq11XRPlniO4lf2TW7iji5neGVWJulTKS1xBAkAerktk4Hsw
+ErUaUG1s/d+Sgc8e/KMeBElV+NxGhcWEeZtfHMn/6VOlbzY82JyvC9OKC80A5CAE
+VUV6b25kqrcu
+-----END PRIVATE KEY-----
diff --git a/google-auth-library-java/pom.xml b/google-auth-library-java/pom.xml
index 461655dd4e55..0020399949aa 100644
--- a/google-auth-library-java/pom.xml
+++ b/google-auth-library-java/pom.xml
@@ -5,7 +5,7 @@
4.0.0
com.google.auth
google-auth-library-parent
- 1.45.0
+ 1.46.0
pom
Google Auth Library for Java
Client libraries providing authentication and
diff --git a/google-cloud-jar-parent/pom.xml b/google-cloud-jar-parent/pom.xml
index cc2417588618..7ea2f4738280 100644
--- a/google-cloud-jar-parent/pom.xml
+++ b/google-cloud-jar-parent/pom.xml
@@ -5,7 +5,7 @@
4.0.0
google-cloud-jar-parent
com.google.cloud
- 1.84.0
+ 1.85.0
pom
Google Cloud JAR Parent
@@ -15,7 +15,7 @@
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../google-cloud-pom-parent/pom.xml
@@ -27,7 +27,7 @@
com.google.cloud
google-cloud-shared-dependencies
- 3.60.0
+ 3.61.0
pom
import
@@ -46,7 +46,7 @@
com.google.cloud
google-cloud-storage
- 2.66.0
+ 2.67.0
com.google.apis
diff --git a/google-cloud-pom-parent/pom.xml b/google-cloud-pom-parent/pom.xml
index 5c6149b5c8b1..e0f039d054c1 100644
--- a/google-cloud-pom-parent/pom.xml
+++ b/google-cloud-pom-parent/pom.xml
@@ -5,7 +5,7 @@
4.0.0
google-cloud-pom-parent
com.google.cloud
- 1.84.0
+ 1.85.0
pom
Google Cloud POM Parent
https://github.com/googleapis/google-cloud-java
@@ -15,7 +15,7 @@
com.google.cloud
sdk-platform-java-config
- 3.60.0
+ 3.61.0
../sdk-platform-java/sdk-platform-java-config
diff --git a/java-accessapproval/.OwlBot-hermetic.yaml b/java-accessapproval/.OwlBot-hermetic.yaml
index e48afc86d349..4736283994aa 100644
--- a/java-accessapproval/.OwlBot-hermetic.yaml
+++ b/java-accessapproval/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-accessapproval/samples/snippets/generated"
deep-preserve-regex:
-- "/java-accessapproval/google-cloud-accessapproval/src/test/java/com/google/cloud/accessapproval/v1/it"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-cloud-accessapproval/src/test/java/com/google/cloud/accessapproval/v1/it"
deep-copy-regex:
- source: "/google/cloud/accessapproval/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-accessapproval/README.md b/java-accessapproval/README.md
index 097ee8d1a1d5..0ad0f90b5729 100644
--- a/java-accessapproval/README.md
+++ b/java-accessapproval/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-accessapproval
- 2.89.0
+ 2.91.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-accessapproval:2.89.0'
+implementation 'com.google.cloud:google-cloud-accessapproval:2.91.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-accessapproval" % "2.89.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-accessapproval" % "2.91.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-accessapproval/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-accessapproval.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-accessapproval/2.89.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-accessapproval/2.91.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-accessapproval/google-cloud-accessapproval-bom/pom.xml b/java-accessapproval/google-cloud-accessapproval-bom/pom.xml
index 88397d21b229..1b7b58c96f63 100644
--- a/java-accessapproval/google-cloud-accessapproval-bom/pom.xml
+++ b/java-accessapproval/google-cloud-accessapproval-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-accessapproval-bom
- 2.91.0
+ 2.92.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -23,17 +23,17 @@
com.google.cloud
google-cloud-accessapproval
- 2.91.0
+ 2.92.0
com.google.api.grpc
grpc-google-cloud-accessapproval-v1
- 2.91.0
+ 2.92.0
com.google.api.grpc
proto-google-cloud-accessapproval-v1
- 2.91.0
+ 2.92.0
diff --git a/java-accessapproval/google-cloud-accessapproval/pom.xml b/java-accessapproval/google-cloud-accessapproval/pom.xml
index 629c6a62549f..6c699750cf39 100644
--- a/java-accessapproval/google-cloud-accessapproval/pom.xml
+++ b/java-accessapproval/google-cloud-accessapproval/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-accessapproval
- 2.91.0
+ 2.92.0
jar
Google Cloud Access Approval
Java idiomatic client for Google Cloud accessapproval
com.google.cloud
google-cloud-accessapproval-parent
- 2.91.0
+ 2.92.0
google-cloud-accessapproval
diff --git a/java-accessapproval/google-cloud-accessapproval/src/main/java/com/google/cloud/accessapproval/v1/stub/Version.java b/java-accessapproval/google-cloud-accessapproval/src/main/java/com/google/cloud/accessapproval/v1/stub/Version.java
index 5828b64f314f..207ec18e6be2 100644
--- a/java-accessapproval/google-cloud-accessapproval/src/main/java/com/google/cloud/accessapproval/v1/stub/Version.java
+++ b/java-accessapproval/google-cloud-accessapproval/src/main/java/com/google/cloud/accessapproval/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-accessapproval:current}
- static final String VERSION = "2.91.0";
+ static final String VERSION = "2.92.0";
// {x-version-update-end}
}
diff --git a/java-accessapproval/grpc-google-cloud-accessapproval-v1/pom.xml b/java-accessapproval/grpc-google-cloud-accessapproval-v1/pom.xml
index 708dbfe130e8..4b604498f10a 100644
--- a/java-accessapproval/grpc-google-cloud-accessapproval-v1/pom.xml
+++ b/java-accessapproval/grpc-google-cloud-accessapproval-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-accessapproval-v1
- 2.91.0
+ 2.92.0
grpc-google-cloud-accessapproval-v1
GRPC library for grpc-google-cloud-accessapproval-v1
com.google.cloud
google-cloud-accessapproval-parent
- 2.91.0
+ 2.92.0
diff --git a/java-accessapproval/pom.xml b/java-accessapproval/pom.xml
index 328973181227..78903c4369ea 100644
--- a/java-accessapproval/pom.xml
+++ b/java-accessapproval/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-accessapproval-parent
pom
- 2.91.0
+ 2.92.0
Google Cloud Access Approval Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,17 +29,17 @@
com.google.api.grpc
proto-google-cloud-accessapproval-v1
- 2.91.0
+ 2.92.0
com.google.api.grpc
grpc-google-cloud-accessapproval-v1
- 2.91.0
+ 2.92.0
com.google.cloud
google-cloud-accessapproval
- 2.91.0
+ 2.92.0
diff --git a/java-accessapproval/proto-google-cloud-accessapproval-v1/pom.xml b/java-accessapproval/proto-google-cloud-accessapproval-v1/pom.xml
index 9b3f46724633..5c98bf142f33 100644
--- a/java-accessapproval/proto-google-cloud-accessapproval-v1/pom.xml
+++ b/java-accessapproval/proto-google-cloud-accessapproval-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-accessapproval-v1
- 2.91.0
+ 2.92.0
proto-google-cloud-accessapproval-v1beta1
PROTO library for proto-google-cloud-accessapproval-v1
com.google.cloud
google-cloud-accessapproval-parent
- 2.91.0
+ 2.92.0
diff --git a/java-accesscontextmanager/.OwlBot-hermetic.yaml b/java-accesscontextmanager/.OwlBot-hermetic.yaml
index 3a4cdc7f8dd6..d06ba37a7aec 100644
--- a/java-accesscontextmanager/.OwlBot-hermetic.yaml
+++ b/java-accesscontextmanager/.OwlBot-hermetic.yaml
@@ -18,7 +18,8 @@ deep-remove-regex:
- "/java-accesscontextmanager/samples/snippets/generated"
deep-preserve-regex:
-- "/java-accesscontextmanager/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/identity/accesscontextmanager/(v\\d)/.*-java/proto-google-.*/src"
diff --git a/java-accesscontextmanager/README.md b/java-accesscontextmanager/README.md
index deff21cbab1a..373e7a206c59 100644
--- a/java-accesscontextmanager/README.md
+++ b/java-accesscontextmanager/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-identity-accesscontextmanager
- 1.89.0
+ 1.91.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-identity-accesscontextmanager:1.89.0'
+implementation 'com.google.cloud:google-identity-accesscontextmanager:1.91.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-identity-accesscontextmanager" % "1.89.0"
+libraryDependencies += "com.google.cloud" % "google-identity-accesscontextmanager" % "1.91.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-identity-accesscontextmanager/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-identity-accesscontextmanager.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-identity-accesscontextmanager/1.89.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-identity-accesscontextmanager/1.91.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-accesscontextmanager/google-identity-accesscontextmanager-bom/pom.xml b/java-accesscontextmanager/google-identity-accesscontextmanager-bom/pom.xml
index 53869480e835..d5b9428060f2 100644
--- a/java-accesscontextmanager/google-identity-accesscontextmanager-bom/pom.xml
+++ b/java-accesscontextmanager/google-identity-accesscontextmanager-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-identity-accesscontextmanager-bom
- 1.91.0
+ 1.92.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,22 +27,22 @@
com.google.cloud
google-identity-accesscontextmanager
- 1.91.0
+ 1.92.0
com.google.api.grpc
grpc-google-identity-accesscontextmanager-v1
- 1.91.0
+ 1.92.0
com.google.api.grpc
proto-google-identity-accesscontextmanager-v1
- 1.91.0
+ 1.92.0
com.google.api.grpc
proto-google-identity-accesscontextmanager-type
- 1.91.0
+ 1.92.0
diff --git a/java-accesscontextmanager/google-identity-accesscontextmanager/pom.xml b/java-accesscontextmanager/google-identity-accesscontextmanager/pom.xml
index 2b0243712361..120edd3c74d6 100644
--- a/java-accesscontextmanager/google-identity-accesscontextmanager/pom.xml
+++ b/java-accesscontextmanager/google-identity-accesscontextmanager/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-identity-accesscontextmanager
- 1.91.0
+ 1.92.0
jar
Google Identity Access Context Manager
Identity Access Context Manager n/a
com.google.cloud
google-identity-accesscontextmanager-parent
- 1.91.0
+ 1.92.0
google-identity-accesscontextmanager
diff --git a/java-accesscontextmanager/google-identity-accesscontextmanager/src/main/java/com/google/identity/accesscontextmanager/v1/stub/Version.java b/java-accesscontextmanager/google-identity-accesscontextmanager/src/main/java/com/google/identity/accesscontextmanager/v1/stub/Version.java
index 764b34d99cdd..68f86b432abf 100644
--- a/java-accesscontextmanager/google-identity-accesscontextmanager/src/main/java/com/google/identity/accesscontextmanager/v1/stub/Version.java
+++ b/java-accesscontextmanager/google-identity-accesscontextmanager/src/main/java/com/google/identity/accesscontextmanager/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-identity-accesscontextmanager:current}
- static final String VERSION = "1.91.0";
+ static final String VERSION = "1.92.0";
// {x-version-update-end}
}
diff --git a/java-accesscontextmanager/grpc-google-identity-accesscontextmanager-v1/pom.xml b/java-accesscontextmanager/grpc-google-identity-accesscontextmanager-v1/pom.xml
index e35884e19051..7646567fc972 100644
--- a/java-accesscontextmanager/grpc-google-identity-accesscontextmanager-v1/pom.xml
+++ b/java-accesscontextmanager/grpc-google-identity-accesscontextmanager-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-identity-accesscontextmanager-v1
- 1.91.0
+ 1.92.0
grpc-google-identity-accesscontextmanager-v1
GRPC library for google-identity-accesscontextmanager
com.google.cloud
google-identity-accesscontextmanager-parent
- 1.91.0
+ 1.92.0
diff --git a/java-accesscontextmanager/pom.xml b/java-accesscontextmanager/pom.xml
index a8904ad9bbe0..a8f992ccafcd 100644
--- a/java-accesscontextmanager/pom.xml
+++ b/java-accesscontextmanager/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-identity-accesscontextmanager-parent
pom
- 1.91.0
+ 1.92.0
Google Identity Access Context Manager Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -30,22 +30,22 @@
com.google.api.grpc
proto-google-identity-accesscontextmanager-type
- 1.91.0
+ 1.92.0
com.google.api.grpc
proto-google-identity-accesscontextmanager-v1
- 1.91.0
+ 1.92.0
com.google.api.grpc
grpc-google-identity-accesscontextmanager-v1
- 1.91.0
+ 1.92.0
com.google.cloud
google-identity-accesscontextmanager
- 1.91.0
+ 1.92.0
diff --git a/java-accesscontextmanager/proto-google-identity-accesscontextmanager-type/pom.xml b/java-accesscontextmanager/proto-google-identity-accesscontextmanager-type/pom.xml
index 1d942650e743..a71fe0f3137e 100644
--- a/java-accesscontextmanager/proto-google-identity-accesscontextmanager-type/pom.xml
+++ b/java-accesscontextmanager/proto-google-identity-accesscontextmanager-type/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-identity-accesscontextmanager-type
- 1.91.0
+ 1.92.0
proto-google-identity-accesscontextmanager-type
PROTO library for proto-google-identity-accesscontextmanager-type
com.google.cloud
google-identity-accesscontextmanager-parent
- 1.91.0
+ 1.92.0
diff --git a/java-accesscontextmanager/proto-google-identity-accesscontextmanager-v1/pom.xml b/java-accesscontextmanager/proto-google-identity-accesscontextmanager-v1/pom.xml
index 2943aaf8a32a..e2b18be340e3 100644
--- a/java-accesscontextmanager/proto-google-identity-accesscontextmanager-v1/pom.xml
+++ b/java-accesscontextmanager/proto-google-identity-accesscontextmanager-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-identity-accesscontextmanager-v1
- 1.91.0
+ 1.92.0
proto-google-identity-accesscontextmanager-v1
PROTO library for proto-google-identity-accesscontextmanager-v1
com.google.cloud
google-identity-accesscontextmanager-parent
- 1.91.0
+ 1.92.0
@@ -37,7 +37,7 @@
com.google.api.grpc
proto-google-identity-accesscontextmanager-type
- 1.91.0
+ 1.92.0
diff --git a/java-admanager/.OwlBot-hermetic.yaml b/java-admanager/.OwlBot-hermetic.yaml
index bbf57d3062d3..ceb5433db71d 100644
--- a/java-admanager/.OwlBot-hermetic.yaml
+++ b/java-admanager/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-admanager/samples/snippets/generated"
deep-preserve-regex:
-- "/java-admanager/ad-manager-.*/src/test/java/com/google/.*/v.*/it/IT.*Test.java"
+- "/.*ad-manager.*/src/main/java/.*/stub/Version.java"
+- "/.*ad-manager.*/src/test/java/com/google/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/ads/admanager/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-admanager/README.md b/java-admanager/README.md
index 0637cfc4217d..eb1ab1472043 100644
--- a/java-admanager/README.md
+++ b/java-admanager/README.md
@@ -22,20 +22,20 @@ If you are using Maven, add this to your pom.xml file:
com.google.api-ads
ad-manager
- 0.47.0
+ 0.49.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.api-ads:ad-manager:0.47.0'
+implementation 'com.google.api-ads:ad-manager:0.49.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.api-ads" % "ad-manager" % "0.47.0"
+libraryDependencies += "com.google.api-ads" % "ad-manager" % "0.49.0"
```
## Authentication
@@ -158,7 +158,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/ad-manager/latest/overview
[stability-image]: https://img.shields.io/badge/stability-preview-yellow
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.api-ads/ad-manager.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.api-ads/ad-manager/0.47.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.api-ads/ad-manager/0.49.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-admanager/ad-manager-bom/pom.xml b/java-admanager/ad-manager-bom/pom.xml
index 6149abf55885..31e73b809970 100644
--- a/java-admanager/ad-manager-bom/pom.xml
+++ b/java-admanager/ad-manager-bom/pom.xml
@@ -3,12 +3,12 @@
4.0.0
com.google.api-ads
ad-manager-bom
- 0.49.0
+ 0.50.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -26,12 +26,12 @@
com.google.api-ads
ad-manager
- 0.49.0
+ 0.50.0
com.google.api-ads.api.grpc
proto-ad-manager-v1
- 0.49.0
+ 0.50.0
diff --git a/java-admanager/ad-manager/pom.xml b/java-admanager/ad-manager/pom.xml
index a8e8f8a5e1b9..5a5479e1d72a 100644
--- a/java-admanager/ad-manager/pom.xml
+++ b/java-admanager/ad-manager/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.api-ads
ad-manager
- 0.49.0
+ 0.50.0
jar
Google Google Ad Manager API
Google Ad Manager API The Ad Manager API enables an app to integrate with Google Ad Manager. You can read Ad Manager data and run reports using the API.
com.google.api-ads
ad-manager-parent
- 0.49.0
+ 0.50.0
ad-manager
diff --git a/java-admanager/ad-manager/src/main/java/com/google/ads/admanager/v1/stub/Version.java b/java-admanager/ad-manager/src/main/java/com/google/ads/admanager/v1/stub/Version.java
index 1be9d3667545..ee1c2d97e1c2 100644
--- a/java-admanager/ad-manager/src/main/java/com/google/ads/admanager/v1/stub/Version.java
+++ b/java-admanager/ad-manager/src/main/java/com/google/ads/admanager/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:ad-manager:current}
- static final String VERSION = "0.49.0";
+ static final String VERSION = "0.50.0";
// {x-version-update-end}
}
diff --git a/java-admanager/pom.xml b/java-admanager/pom.xml
index 26d1c21b91ea..cbcbf0235d9d 100644
--- a/java-admanager/pom.xml
+++ b/java-admanager/pom.xml
@@ -4,7 +4,7 @@
com.google.api-ads
ad-manager-parent
pom
- 0.49.0
+ 0.50.0
Google Google Ad Manager API Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,12 +29,12 @@
com.google.api-ads
ad-manager
- 0.49.0
+ 0.50.0
com.google.api-ads.api.grpc
proto-ad-manager-v1
- 0.49.0
+ 0.50.0
diff --git a/java-admanager/proto-ad-manager-v1/pom.xml b/java-admanager/proto-ad-manager-v1/pom.xml
index 18f8f9225914..3ecbe452cd27 100644
--- a/java-admanager/proto-ad-manager-v1/pom.xml
+++ b/java-admanager/proto-ad-manager-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api-ads.api.grpc
proto-ad-manager-v1
- 0.49.0
+ 0.50.0
proto-ad-manager-v1
Proto library for ad-manager
com.google.api-ads
ad-manager-parent
- 0.49.0
+ 0.50.0
diff --git a/java-advisorynotifications/.OwlBot-hermetic.yaml b/java-advisorynotifications/.OwlBot-hermetic.yaml
index ac2508b427bc..5feb99e20c19 100644
--- a/java-advisorynotifications/.OwlBot-hermetic.yaml
+++ b/java-advisorynotifications/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-advisorynotifications/samples/snippets/generated"
deep-preserve-regex:
-- "/java-advisorynotifications/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/cloud/advisorynotifications/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-advisorynotifications/README.md b/java-advisorynotifications/README.md
index e9f719781c9b..2616ee1f27d0 100644
--- a/java-advisorynotifications/README.md
+++ b/java-advisorynotifications/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-advisorynotifications
- 0.77.0
+ 0.79.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-advisorynotifications:0.77.0'
+implementation 'com.google.cloud:google-cloud-advisorynotifications:0.79.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-advisorynotifications" % "0.77.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-advisorynotifications" % "0.79.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-advisorynotifications/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-advisorynotifications.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-advisorynotifications/0.77.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-advisorynotifications/0.79.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-advisorynotifications/google-cloud-advisorynotifications-bom/pom.xml b/java-advisorynotifications/google-cloud-advisorynotifications-bom/pom.xml
index a36710e5851c..5666d6512308 100644
--- a/java-advisorynotifications/google-cloud-advisorynotifications-bom/pom.xml
+++ b/java-advisorynotifications/google-cloud-advisorynotifications-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-advisorynotifications-bom
- 0.79.0
+ 0.80.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,17 +27,17 @@
com.google.cloud
google-cloud-advisorynotifications
- 0.79.0
+ 0.80.0
com.google.api.grpc
grpc-google-cloud-advisorynotifications-v1
- 0.79.0
+ 0.80.0
com.google.api.grpc
proto-google-cloud-advisorynotifications-v1
- 0.79.0
+ 0.80.0
diff --git a/java-advisorynotifications/google-cloud-advisorynotifications/pom.xml b/java-advisorynotifications/google-cloud-advisorynotifications/pom.xml
index 515d4bd991b6..221375a3b9ff 100644
--- a/java-advisorynotifications/google-cloud-advisorynotifications/pom.xml
+++ b/java-advisorynotifications/google-cloud-advisorynotifications/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-advisorynotifications
- 0.79.0
+ 0.80.0
jar
Google Advisory Notifications API
Advisory Notifications API An API for accessing Advisory Notifications in Google Cloud.
com.google.cloud
google-cloud-advisorynotifications-parent
- 0.79.0
+ 0.80.0
google-cloud-advisorynotifications
diff --git a/java-advisorynotifications/google-cloud-advisorynotifications/src/main/java/com/google/cloud/advisorynotifications/v1/stub/Version.java b/java-advisorynotifications/google-cloud-advisorynotifications/src/main/java/com/google/cloud/advisorynotifications/v1/stub/Version.java
index f625a653e959..3fffa1621d11 100644
--- a/java-advisorynotifications/google-cloud-advisorynotifications/src/main/java/com/google/cloud/advisorynotifications/v1/stub/Version.java
+++ b/java-advisorynotifications/google-cloud-advisorynotifications/src/main/java/com/google/cloud/advisorynotifications/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-advisorynotifications:current}
- static final String VERSION = "0.79.0";
+ static final String VERSION = "0.80.0";
// {x-version-update-end}
}
diff --git a/java-advisorynotifications/grpc-google-cloud-advisorynotifications-v1/pom.xml b/java-advisorynotifications/grpc-google-cloud-advisorynotifications-v1/pom.xml
index cff3713bf84e..117289b70d96 100644
--- a/java-advisorynotifications/grpc-google-cloud-advisorynotifications-v1/pom.xml
+++ b/java-advisorynotifications/grpc-google-cloud-advisorynotifications-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-advisorynotifications-v1
- 0.79.0
+ 0.80.0
grpc-google-cloud-advisorynotifications-v1
GRPC library for google-cloud-advisorynotifications
com.google.cloud
google-cloud-advisorynotifications-parent
- 0.79.0
+ 0.80.0
diff --git a/java-advisorynotifications/pom.xml b/java-advisorynotifications/pom.xml
index e58bc580e91f..ee1734dab8f1 100644
--- a/java-advisorynotifications/pom.xml
+++ b/java-advisorynotifications/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-advisorynotifications-parent
pom
- 0.79.0
+ 0.80.0
Google Advisory Notifications API Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,17 +29,17 @@
com.google.cloud
google-cloud-advisorynotifications
- 0.79.0
+ 0.80.0
com.google.api.grpc
grpc-google-cloud-advisorynotifications-v1
- 0.79.0
+ 0.80.0
com.google.api.grpc
proto-google-cloud-advisorynotifications-v1
- 0.79.0
+ 0.80.0
diff --git a/java-advisorynotifications/proto-google-cloud-advisorynotifications-v1/pom.xml b/java-advisorynotifications/proto-google-cloud-advisorynotifications-v1/pom.xml
index 5d8ae10d86bd..ccd7bea8d7a2 100644
--- a/java-advisorynotifications/proto-google-cloud-advisorynotifications-v1/pom.xml
+++ b/java-advisorynotifications/proto-google-cloud-advisorynotifications-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-advisorynotifications-v1
- 0.79.0
+ 0.80.0
proto-google-cloud-advisorynotifications-v1
Proto library for google-cloud-advisorynotifications
com.google.cloud
google-cloud-advisorynotifications-parent
- 0.79.0
+ 0.80.0
diff --git a/java-aiplatform/.OwlBot-hermetic.yaml b/java-aiplatform/.OwlBot-hermetic.yaml
index bb7869c9a33c..27f0b13f5309 100644
--- a/java-aiplatform/.OwlBot-hermetic.yaml
+++ b/java-aiplatform/.OwlBot-hermetic.yaml
@@ -20,6 +20,9 @@ deep-remove-regex:
- "/java-aiplatform/samples/snippets/generated"
- "/java-aiplatform/google-.*/src/main/java/com/google/cloud/aiplatform/v1beta1"
+deep-preserve-regex:
+ - "/.*google-.*/src/main/java/.*/stub/Version.java"
+
deep-copy-regex:
- source: "/google/cloud/aiplatform/(v.*)/.*-java/proto-google-.*/src"
dest: "/owl-bot-staging/java-aiplatform/$1/proto-google-cloud-aiplatform-$1/src"
diff --git a/java-aiplatform/README.md b/java-aiplatform/README.md
index 2ecd1ae76a82..9da0d2e678f4 100644
--- a/java-aiplatform/README.md
+++ b/java-aiplatform/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-aiplatform
- 3.89.0
+ 3.91.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-aiplatform:3.89.0'
+implementation 'com.google.cloud:google-cloud-aiplatform:3.91.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-aiplatform" % "3.89.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-aiplatform" % "3.91.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-aiplatform/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-aiplatform.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-aiplatform/3.89.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-aiplatform/3.91.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-aiplatform/google-cloud-aiplatform-bom/pom.xml b/java-aiplatform/google-cloud-aiplatform-bom/pom.xml
index 0366c18e2567..53089ab57e64 100644
--- a/java-aiplatform/google-cloud-aiplatform-bom/pom.xml
+++ b/java-aiplatform/google-cloud-aiplatform-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-aiplatform-bom
- 3.91.0
+ 3.92.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,27 +27,27 @@
com.google.cloud
google-cloud-aiplatform
- 3.91.0
+ 3.92.0
com.google.api.grpc
grpc-google-cloud-aiplatform-v1
- 3.91.0
+ 3.92.0
com.google.api.grpc
grpc-google-cloud-aiplatform-v1beta1
- 0.107.0
+ 0.108.0
com.google.api.grpc
proto-google-cloud-aiplatform-v1
- 3.91.0
+ 3.92.0
com.google.api.grpc
proto-google-cloud-aiplatform-v1beta1
- 0.107.0
+ 0.108.0
diff --git a/java-aiplatform/google-cloud-aiplatform/pom.xml b/java-aiplatform/google-cloud-aiplatform/pom.xml
index dcfec118325b..06b8680e5685 100644
--- a/java-aiplatform/google-cloud-aiplatform/pom.xml
+++ b/java-aiplatform/google-cloud-aiplatform/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-aiplatform
- 3.91.0
+ 3.92.0
jar
Google Cloud Vertex AI
Java client for Google Cloud Vertex AI services.
com.google.cloud
google-cloud-aiplatform-parent
- 3.91.0
+ 3.92.0
google-cloud-aiplatform
diff --git a/java-aiplatform/google-cloud-aiplatform/src/main/java/com/google/cloud/aiplatform/v1/stub/Version.java b/java-aiplatform/google-cloud-aiplatform/src/main/java/com/google/cloud/aiplatform/v1/stub/Version.java
index 87fb722d7d86..c8c43ab8b03f 100644
--- a/java-aiplatform/google-cloud-aiplatform/src/main/java/com/google/cloud/aiplatform/v1/stub/Version.java
+++ b/java-aiplatform/google-cloud-aiplatform/src/main/java/com/google/cloud/aiplatform/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-aiplatform:current}
- static final String VERSION = "3.91.0";
+ static final String VERSION = "3.92.0";
// {x-version-update-end}
}
diff --git a/java-aiplatform/google-cloud-aiplatform/src/main/java/com/google/cloud/aiplatform/v1beta1/stub/Version.java b/java-aiplatform/google-cloud-aiplatform/src/main/java/com/google/cloud/aiplatform/v1beta1/stub/Version.java
index 5fb0c2ff9c55..66784e842651 100644
--- a/java-aiplatform/google-cloud-aiplatform/src/main/java/com/google/cloud/aiplatform/v1beta1/stub/Version.java
+++ b/java-aiplatform/google-cloud-aiplatform/src/main/java/com/google/cloud/aiplatform/v1beta1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-aiplatform:current}
- static final String VERSION = "3.91.0";
+ static final String VERSION = "3.92.0";
// {x-version-update-end}
}
diff --git a/java-aiplatform/grpc-google-cloud-aiplatform-v1/pom.xml b/java-aiplatform/grpc-google-cloud-aiplatform-v1/pom.xml
index 4c069d4c5fb9..9f2a00bd78c3 100644
--- a/java-aiplatform/grpc-google-cloud-aiplatform-v1/pom.xml
+++ b/java-aiplatform/grpc-google-cloud-aiplatform-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-aiplatform-v1
- 3.91.0
+ 3.92.0
grpc-google-cloud-aiplatform-v1
GRPC library for google-cloud-aiplatform
com.google.cloud
google-cloud-aiplatform-parent
- 3.91.0
+ 3.92.0
diff --git a/java-aiplatform/grpc-google-cloud-aiplatform-v1beta1/pom.xml b/java-aiplatform/grpc-google-cloud-aiplatform-v1beta1/pom.xml
index 03094011bd70..1de53d7c1ce4 100644
--- a/java-aiplatform/grpc-google-cloud-aiplatform-v1beta1/pom.xml
+++ b/java-aiplatform/grpc-google-cloud-aiplatform-v1beta1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-aiplatform-v1beta1
- 0.107.0
+ 0.108.0
grpc-google-cloud-aiplatform-v1beta1
GRPC library for google-cloud-aiplatform
com.google.cloud
google-cloud-aiplatform-parent
- 3.91.0
+ 3.92.0
diff --git a/java-aiplatform/pom.xml b/java-aiplatform/pom.xml
index ef2ac9284c48..e9d96fef69bc 100644
--- a/java-aiplatform/pom.xml
+++ b/java-aiplatform/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-aiplatform-parent
pom
- 3.91.0
+ 3.92.0
Google Cloud Vertex AI Parent
Java client for Google Cloud Vertex AI services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,27 +29,27 @@
com.google.cloud
google-cloud-aiplatform
- 3.91.0
+ 3.92.0
com.google.api.grpc
proto-google-cloud-aiplatform-v1
- 3.91.0
+ 3.92.0
com.google.api.grpc
proto-google-cloud-aiplatform-v1beta1
- 0.107.0
+ 0.108.0
com.google.api.grpc
grpc-google-cloud-aiplatform-v1
- 3.91.0
+ 3.92.0
com.google.api.grpc
grpc-google-cloud-aiplatform-v1beta1
- 0.107.0
+ 0.108.0
diff --git a/java-aiplatform/proto-google-cloud-aiplatform-v1/pom.xml b/java-aiplatform/proto-google-cloud-aiplatform-v1/pom.xml
index 30b31c0305e1..2fb68d8037b6 100644
--- a/java-aiplatform/proto-google-cloud-aiplatform-v1/pom.xml
+++ b/java-aiplatform/proto-google-cloud-aiplatform-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-aiplatform-v1
- 3.91.0
+ 3.92.0
proto-google-cloud-aiplatform-v1
Proto library for google-cloud-aiplatform
com.google.cloud
google-cloud-aiplatform-parent
- 3.91.0
+ 3.92.0
diff --git a/java-aiplatform/proto-google-cloud-aiplatform-v1beta1/pom.xml b/java-aiplatform/proto-google-cloud-aiplatform-v1beta1/pom.xml
index ed1ac5ee388c..048ad4b2add6 100644
--- a/java-aiplatform/proto-google-cloud-aiplatform-v1beta1/pom.xml
+++ b/java-aiplatform/proto-google-cloud-aiplatform-v1beta1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-aiplatform-v1beta1
- 0.107.0
+ 0.108.0
proto-google-cloud-aiplatform-v1beta1
Proto library for google-cloud-aiplatform
com.google.cloud
google-cloud-aiplatform-parent
- 3.91.0
+ 3.92.0
diff --git a/java-alloydb-connectors/.OwlBot-hermetic.yaml b/java-alloydb-connectors/.OwlBot-hermetic.yaml
index 2ad69b20a09a..93a134a913f0 100644
--- a/java-alloydb-connectors/.OwlBot-hermetic.yaml
+++ b/java-alloydb-connectors/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-alloydb-connectors/samples/snippets/generated"
deep-preserve-regex:
-- "/java-alloydb-connectors/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/cloud/alloydb/connectors/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-alloydb-connectors/README.md b/java-alloydb-connectors/README.md
index 70685f0384e7..90bf340ad429 100644
--- a/java-alloydb-connectors/README.md
+++ b/java-alloydb-connectors/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-alloydb-connectors
- 0.66.0
+ 0.68.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-alloydb-connectors:0.66.0'
+implementation 'com.google.cloud:google-cloud-alloydb-connectors:0.68.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-alloydb-connectors" % "0.66.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-alloydb-connectors" % "0.68.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-alloydb-connectors/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-alloydb-connectors.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-alloydb-connectors/0.66.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-alloydb-connectors/0.68.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-alloydb-connectors/google-cloud-alloydb-connectors-bom/pom.xml b/java-alloydb-connectors/google-cloud-alloydb-connectors-bom/pom.xml
index 9e253dab3079..48b94f33e928 100644
--- a/java-alloydb-connectors/google-cloud-alloydb-connectors-bom/pom.xml
+++ b/java-alloydb-connectors/google-cloud-alloydb-connectors-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-alloydb-connectors-bom
- 0.68.0
+ 0.69.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,22 +27,22 @@
com.google.cloud
google-cloud-alloydb-connectors
- 0.68.0
+ 0.69.0
com.google.api.grpc
proto-google-cloud-alloydb-connectors-v1alpha
- 0.68.0
+ 0.69.0
com.google.api.grpc
proto-google-cloud-alloydb-connectors-v1beta
- 0.68.0
+ 0.69.0
com.google.api.grpc
proto-google-cloud-alloydb-connectors-v1
- 0.68.0
+ 0.69.0
diff --git a/java-alloydb-connectors/google-cloud-alloydb-connectors/pom.xml b/java-alloydb-connectors/google-cloud-alloydb-connectors/pom.xml
index 2c076225e312..bff3acf63972 100644
--- a/java-alloydb-connectors/google-cloud-alloydb-connectors/pom.xml
+++ b/java-alloydb-connectors/google-cloud-alloydb-connectors/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-alloydb-connectors
- 0.68.0
+ 0.69.0
jar
Google AlloyDB connectors
AlloyDB connectors AlloyDB is a fully-managed, PostgreSQL-compatible database for demanding transactional workloads. It provides enterprise-grade performance and availability while maintaining 100% compatibility with open-source PostgreSQL.
com.google.cloud
google-cloud-alloydb-connectors-parent
- 0.68.0
+ 0.69.0
google-cloud-alloydb-connectors
diff --git a/java-alloydb-connectors/pom.xml b/java-alloydb-connectors/pom.xml
index 4d3bdaf15cf0..1b8bd1212ccb 100644
--- a/java-alloydb-connectors/pom.xml
+++ b/java-alloydb-connectors/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-alloydb-connectors-parent
pom
- 0.68.0
+ 0.69.0
Google AlloyDB connectors Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,22 +29,22 @@
com.google.cloud
google-cloud-alloydb-connectors
- 0.68.0
+ 0.69.0
com.google.api.grpc
proto-google-cloud-alloydb-connectors-v1
- 0.68.0
+ 0.69.0
com.google.api.grpc
proto-google-cloud-alloydb-connectors-v1beta
- 0.68.0
+ 0.69.0
com.google.api.grpc
proto-google-cloud-alloydb-connectors-v1alpha
- 0.68.0
+ 0.69.0
diff --git a/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1/pom.xml b/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1/pom.xml
index be249df12370..687776110f30 100644
--- a/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1/pom.xml
+++ b/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-alloydb-connectors-v1
- 0.68.0
+ 0.69.0
proto-google-cloud-alloydb-connectors-v1
Proto library for google-cloud-alloydb-connectors
com.google.cloud
google-cloud-alloydb-connectors-parent
- 0.68.0
+ 0.69.0
diff --git a/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1alpha/pom.xml b/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1alpha/pom.xml
index 0bf67db2cb04..8b8b1a199f39 100644
--- a/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1alpha/pom.xml
+++ b/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1alpha/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-alloydb-connectors-v1alpha
- 0.68.0
+ 0.69.0
proto-google-cloud-alloydb-connectors-v1alpha
Proto library for google-cloud-alloydb-connectors
com.google.cloud
google-cloud-alloydb-connectors-parent
- 0.68.0
+ 0.69.0
diff --git a/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1beta/pom.xml b/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1beta/pom.xml
index 59180f80cc7e..7e7467a74f8d 100644
--- a/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1beta/pom.xml
+++ b/java-alloydb-connectors/proto-google-cloud-alloydb-connectors-v1beta/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-alloydb-connectors-v1beta
- 0.68.0
+ 0.69.0
proto-google-cloud-alloydb-connectors-v1beta
Proto library for google-cloud-alloydb-connectors
com.google.cloud
google-cloud-alloydb-connectors-parent
- 0.68.0
+ 0.69.0
diff --git a/java-alloydb/.OwlBot-hermetic.yaml b/java-alloydb/.OwlBot-hermetic.yaml
index 0d85032ca1f3..6f0899e44b64 100644
--- a/java-alloydb/.OwlBot-hermetic.yaml
+++ b/java-alloydb/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-alloydb/samples/snippets/generated"
deep-preserve-regex:
-- "/java-alloydb/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/cloud/alloydb/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-alloydb/README.md b/java-alloydb/README.md
index ccb918c7528b..d1ea58dae68a 100644
--- a/java-alloydb/README.md
+++ b/java-alloydb/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-alloydb
- 0.77.0
+ 0.79.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-alloydb:0.77.0'
+implementation 'com.google.cloud:google-cloud-alloydb:0.79.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-alloydb" % "0.77.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-alloydb" % "0.79.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-alloydb/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-alloydb.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-alloydb/0.77.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-alloydb/0.79.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-alloydb/google-cloud-alloydb-bom/pom.xml b/java-alloydb/google-cloud-alloydb-bom/pom.xml
index 8bc3b2096faa..8743977d425e 100644
--- a/java-alloydb/google-cloud-alloydb-bom/pom.xml
+++ b/java-alloydb/google-cloud-alloydb-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-alloydb-bom
- 0.79.0
+ 0.80.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,37 +27,37 @@
com.google.cloud
google-cloud-alloydb
- 0.79.0
+ 0.80.0
com.google.api.grpc
grpc-google-cloud-alloydb-v1beta
- 0.79.0
+ 0.80.0
com.google.api.grpc
grpc-google-cloud-alloydb-v1
- 0.79.0
+ 0.80.0
com.google.api.grpc
grpc-google-cloud-alloydb-v1alpha
- 0.79.0
+ 0.80.0
com.google.api.grpc
proto-google-cloud-alloydb-v1
- 0.79.0
+ 0.80.0
com.google.api.grpc
proto-google-cloud-alloydb-v1beta
- 0.79.0
+ 0.80.0
com.google.api.grpc
proto-google-cloud-alloydb-v1alpha
- 0.79.0
+ 0.80.0
diff --git a/java-alloydb/google-cloud-alloydb/pom.xml b/java-alloydb/google-cloud-alloydb/pom.xml
index 3ec286851bf4..28012fd70021 100644
--- a/java-alloydb/google-cloud-alloydb/pom.xml
+++ b/java-alloydb/google-cloud-alloydb/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-alloydb
- 0.79.0
+ 0.80.0
jar
Google AlloyDB
AlloyDB AlloyDB is a fully managed, PostgreSQL-compatible database service with industry-leading performance, availability, and scale.
com.google.cloud
google-cloud-alloydb-parent
- 0.79.0
+ 0.80.0
google-cloud-alloydb
diff --git a/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1/stub/Version.java b/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1/stub/Version.java
index 0b6fcc927902..2b1bedac133b 100644
--- a/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1/stub/Version.java
+++ b/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-alloydb:current}
- static final String VERSION = "0.79.0";
+ static final String VERSION = "0.80.0";
// {x-version-update-end}
}
diff --git a/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1alpha/stub/Version.java b/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1alpha/stub/Version.java
index 4af267e30b67..e94e50627423 100644
--- a/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1alpha/stub/Version.java
+++ b/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1alpha/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-alloydb:current}
- static final String VERSION = "0.79.0";
+ static final String VERSION = "0.80.0";
// {x-version-update-end}
}
diff --git a/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1beta/stub/Version.java b/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1beta/stub/Version.java
index fd9fadc429df..7d13508642a0 100644
--- a/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1beta/stub/Version.java
+++ b/java-alloydb/google-cloud-alloydb/src/main/java/com/google/cloud/alloydb/v1beta/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-alloydb:current}
- static final String VERSION = "0.79.0";
+ static final String VERSION = "0.80.0";
// {x-version-update-end}
}
diff --git a/java-alloydb/grpc-google-cloud-alloydb-v1/pom.xml b/java-alloydb/grpc-google-cloud-alloydb-v1/pom.xml
index 03b4e55b35a3..d202496f4e1e 100644
--- a/java-alloydb/grpc-google-cloud-alloydb-v1/pom.xml
+++ b/java-alloydb/grpc-google-cloud-alloydb-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-alloydb-v1
- 0.79.0
+ 0.80.0
grpc-google-cloud-alloydb-v1
GRPC library for google-cloud-alloydb
com.google.cloud
google-cloud-alloydb-parent
- 0.79.0
+ 0.80.0
diff --git a/java-alloydb/grpc-google-cloud-alloydb-v1alpha/pom.xml b/java-alloydb/grpc-google-cloud-alloydb-v1alpha/pom.xml
index 1779ac05218c..3f9a55f63773 100644
--- a/java-alloydb/grpc-google-cloud-alloydb-v1alpha/pom.xml
+++ b/java-alloydb/grpc-google-cloud-alloydb-v1alpha/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-alloydb-v1alpha
- 0.79.0
+ 0.80.0
grpc-google-cloud-alloydb-v1alpha
GRPC library for google-cloud-alloydb
com.google.cloud
google-cloud-alloydb-parent
- 0.79.0
+ 0.80.0
diff --git a/java-alloydb/grpc-google-cloud-alloydb-v1beta/pom.xml b/java-alloydb/grpc-google-cloud-alloydb-v1beta/pom.xml
index f3e63b22cb47..a1a42d140f84 100644
--- a/java-alloydb/grpc-google-cloud-alloydb-v1beta/pom.xml
+++ b/java-alloydb/grpc-google-cloud-alloydb-v1beta/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-alloydb-v1beta
- 0.79.0
+ 0.80.0
grpc-google-cloud-alloydb-v1beta
GRPC library for google-cloud-alloydb
com.google.cloud
google-cloud-alloydb-parent
- 0.79.0
+ 0.80.0
diff --git a/java-alloydb/pom.xml b/java-alloydb/pom.xml
index d75f1ec034ed..6a182667e097 100644
--- a/java-alloydb/pom.xml
+++ b/java-alloydb/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-alloydb-parent
pom
- 0.79.0
+ 0.80.0
Google AlloyDB Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,37 +29,37 @@
com.google.cloud
google-cloud-alloydb
- 0.79.0
+ 0.80.0
com.google.api.grpc
grpc-google-cloud-alloydb-v1beta
- 0.79.0
+ 0.80.0
com.google.api.grpc
grpc-google-cloud-alloydb-v1
- 0.79.0
+ 0.80.0
com.google.api.grpc
grpc-google-cloud-alloydb-v1alpha
- 0.79.0
+ 0.80.0
com.google.api.grpc
proto-google-cloud-alloydb-v1
- 0.79.0
+ 0.80.0
com.google.api.grpc
proto-google-cloud-alloydb-v1beta
- 0.79.0
+ 0.80.0
com.google.api.grpc
proto-google-cloud-alloydb-v1alpha
- 0.79.0
+ 0.80.0
diff --git a/java-alloydb/proto-google-cloud-alloydb-v1/pom.xml b/java-alloydb/proto-google-cloud-alloydb-v1/pom.xml
index bcf6957d27b9..df6f59ccaa34 100644
--- a/java-alloydb/proto-google-cloud-alloydb-v1/pom.xml
+++ b/java-alloydb/proto-google-cloud-alloydb-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-alloydb-v1
- 0.79.0
+ 0.80.0
proto-google-cloud-alloydb-v1
Proto library for google-cloud-alloydb
com.google.cloud
google-cloud-alloydb-parent
- 0.79.0
+ 0.80.0
diff --git a/java-alloydb/proto-google-cloud-alloydb-v1alpha/pom.xml b/java-alloydb/proto-google-cloud-alloydb-v1alpha/pom.xml
index 6b958b82692e..c3ffc7bc75cc 100644
--- a/java-alloydb/proto-google-cloud-alloydb-v1alpha/pom.xml
+++ b/java-alloydb/proto-google-cloud-alloydb-v1alpha/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-alloydb-v1alpha
- 0.79.0
+ 0.80.0
proto-google-cloud-alloydb-v1alpha
Proto library for google-cloud-alloydb
com.google.cloud
google-cloud-alloydb-parent
- 0.79.0
+ 0.80.0
diff --git a/java-alloydb/proto-google-cloud-alloydb-v1beta/pom.xml b/java-alloydb/proto-google-cloud-alloydb-v1beta/pom.xml
index 171ac0f7b75f..075eb715d31f 100644
--- a/java-alloydb/proto-google-cloud-alloydb-v1beta/pom.xml
+++ b/java-alloydb/proto-google-cloud-alloydb-v1beta/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-alloydb-v1beta
- 0.79.0
+ 0.80.0
proto-google-cloud-alloydb-v1beta
Proto library for google-cloud-alloydb
com.google.cloud
google-cloud-alloydb-parent
- 0.79.0
+ 0.80.0
diff --git a/java-analytics-admin/.OwlBot-hermetic.yaml b/java-analytics-admin/.OwlBot-hermetic.yaml
index dddd519ff75e..5f3586f3a66c 100644
--- a/java-analytics-admin/.OwlBot-hermetic.yaml
+++ b/java-analytics-admin/.OwlBot-hermetic.yaml
@@ -19,6 +19,9 @@ deep-remove-regex:
- "/java-analytics-admin/google-.*/src"
- "/java-analytics-admin/samples/snippets/generated"
+deep-preserve-regex:
+ - "/.*google-.*/src/main/java/.*/stub/Version.java"
+
deep-copy-regex:
- source: "/google/analytics/admin/(v.*)/.*-java/proto-google-.*/src"
dest: "/owl-bot-staging/java-analytics-admin/$1/proto-google-analytics-admin-$1/src"
diff --git a/java-analytics-admin/README.md b/java-analytics-admin/README.md
index 668354c68f1d..6e8a02bab9b6 100644
--- a/java-analytics-admin/README.md
+++ b/java-analytics-admin/README.md
@@ -45,20 +45,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.analytics
google-analytics-admin
- 0.98.0
+ 0.100.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.analytics:google-analytics-admin:0.98.0'
+implementation 'com.google.analytics:google-analytics-admin:0.100.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.analytics" % "google-analytics-admin" % "0.98.0"
+libraryDependencies += "com.google.analytics" % "google-analytics-admin" % "0.100.0"
```
## Authentication
@@ -181,7 +181,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-analytics-admin/latest/overview
[stability-image]: https://img.shields.io/badge/stability-preview-yellow
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.analytics/google-analytics-admin.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.analytics/google-analytics-admin/0.98.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.analytics/google-analytics-admin/0.100.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-analytics-admin/google-analytics-admin-bom/pom.xml b/java-analytics-admin/google-analytics-admin-bom/pom.xml
index 7461c5539fe9..6f4ed857ec9f 100644
--- a/java-analytics-admin/google-analytics-admin-bom/pom.xml
+++ b/java-analytics-admin/google-analytics-admin-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.analytics
google-analytics-admin-bom
- 0.100.0
+ 0.101.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,27 +27,27 @@
com.google.analytics
google-analytics-admin
- 0.100.0
+ 0.101.0
com.google.api.grpc
grpc-google-analytics-admin-v1alpha
- 0.100.0
+ 0.101.0
com.google.api.grpc
grpc-google-analytics-admin-v1beta
- 0.100.0
+ 0.101.0
com.google.api.grpc
proto-google-analytics-admin-v1alpha
- 0.100.0
+ 0.101.0
com.google.api.grpc
proto-google-analytics-admin-v1beta
- 0.100.0
+ 0.101.0
diff --git a/java-analytics-admin/google-analytics-admin/pom.xml b/java-analytics-admin/google-analytics-admin/pom.xml
index 27decbf32e8a..44c6c119efb2 100644
--- a/java-analytics-admin/google-analytics-admin/pom.xml
+++ b/java-analytics-admin/google-analytics-admin/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.analytics
google-analytics-admin
- 0.100.0
+ 0.101.0
jar
Google Analytics Admin
allows you to manage Google Analytics accounts and properties.
com.google.analytics
google-analytics-admin-parent
- 0.100.0
+ 0.101.0
google-analytics-admin
diff --git a/java-analytics-admin/google-analytics-admin/src/main/java/com/google/analytics/admin/v1alpha/stub/Version.java b/java-analytics-admin/google-analytics-admin/src/main/java/com/google/analytics/admin/v1alpha/stub/Version.java
index 1462044426ea..5e97ebae34d5 100644
--- a/java-analytics-admin/google-analytics-admin/src/main/java/com/google/analytics/admin/v1alpha/stub/Version.java
+++ b/java-analytics-admin/google-analytics-admin/src/main/java/com/google/analytics/admin/v1alpha/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-analytics-admin:current}
- static final String VERSION = "0.100.0";
+ static final String VERSION = "0.101.0";
// {x-version-update-end}
}
diff --git a/java-analytics-admin/google-analytics-admin/src/main/java/com/google/analytics/admin/v1beta/stub/Version.java b/java-analytics-admin/google-analytics-admin/src/main/java/com/google/analytics/admin/v1beta/stub/Version.java
index 4bff079458f0..c71afd60bd93 100644
--- a/java-analytics-admin/google-analytics-admin/src/main/java/com/google/analytics/admin/v1beta/stub/Version.java
+++ b/java-analytics-admin/google-analytics-admin/src/main/java/com/google/analytics/admin/v1beta/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-analytics-admin:current}
- static final String VERSION = "0.100.0";
+ static final String VERSION = "0.101.0";
// {x-version-update-end}
}
diff --git a/java-analytics-admin/grpc-google-analytics-admin-v1alpha/pom.xml b/java-analytics-admin/grpc-google-analytics-admin-v1alpha/pom.xml
index 87b8fa3e4e8e..0a2e4d28be30 100644
--- a/java-analytics-admin/grpc-google-analytics-admin-v1alpha/pom.xml
+++ b/java-analytics-admin/grpc-google-analytics-admin-v1alpha/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-analytics-admin-v1alpha
- 0.100.0
+ 0.101.0
grpc-google-analytics-admin-v1alpha
GRPC library for grpc-google-analytics-admin-v1alpha
com.google.analytics
google-analytics-admin-parent
- 0.100.0
+ 0.101.0
diff --git a/java-analytics-admin/grpc-google-analytics-admin-v1beta/pom.xml b/java-analytics-admin/grpc-google-analytics-admin-v1beta/pom.xml
index ab9c61a1e347..b7eda6d03c45 100644
--- a/java-analytics-admin/grpc-google-analytics-admin-v1beta/pom.xml
+++ b/java-analytics-admin/grpc-google-analytics-admin-v1beta/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-analytics-admin-v1beta
- 0.100.0
+ 0.101.0
grpc-google-analytics-admin-v1beta
GRPC library for google-analytics-admin
com.google.analytics
google-analytics-admin-parent
- 0.100.0
+ 0.101.0
diff --git a/java-analytics-admin/pom.xml b/java-analytics-admin/pom.xml
index a43c8476a382..c59746103845 100644
--- a/java-analytics-admin/pom.xml
+++ b/java-analytics-admin/pom.xml
@@ -4,7 +4,7 @@
com.google.analytics
google-analytics-admin-parent
pom
- 0.100.0
+ 0.101.0
Google Analytics Admin Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,27 +29,27 @@
com.google.analytics
google-analytics-admin
- 0.100.0
+ 0.101.0
com.google.api.grpc
proto-google-analytics-admin-v1beta
- 0.100.0
+ 0.101.0
com.google.api.grpc
grpc-google-analytics-admin-v1beta
- 0.100.0
+ 0.101.0
com.google.api.grpc
proto-google-analytics-admin-v1alpha
- 0.100.0
+ 0.101.0
com.google.api.grpc
grpc-google-analytics-admin-v1alpha
- 0.100.0
+ 0.101.0
diff --git a/java-analytics-admin/proto-google-analytics-admin-v1alpha/pom.xml b/java-analytics-admin/proto-google-analytics-admin-v1alpha/pom.xml
index 469fcf262f54..0d2cb61ce3d2 100644
--- a/java-analytics-admin/proto-google-analytics-admin-v1alpha/pom.xml
+++ b/java-analytics-admin/proto-google-analytics-admin-v1alpha/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-analytics-admin-v1alpha
- 0.100.0
+ 0.101.0
proto-google-analytics-admin-v1alpha
PROTO library for proto-google-analytics-admin-v1alpha
com.google.analytics
google-analytics-admin-parent
- 0.100.0
+ 0.101.0
diff --git a/java-analytics-admin/proto-google-analytics-admin-v1beta/pom.xml b/java-analytics-admin/proto-google-analytics-admin-v1beta/pom.xml
index 8e30352aace0..83a7d5a97f6f 100644
--- a/java-analytics-admin/proto-google-analytics-admin-v1beta/pom.xml
+++ b/java-analytics-admin/proto-google-analytics-admin-v1beta/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-analytics-admin-v1beta
- 0.100.0
+ 0.101.0
proto-google-analytics-admin-v1beta
Proto library for google-analytics-admin
com.google.analytics
google-analytics-admin-parent
- 0.100.0
+ 0.101.0
diff --git a/java-analytics-data/.OwlBot-hermetic.yaml b/java-analytics-data/.OwlBot-hermetic.yaml
index 9a32eb669f2b..01c77325e63d 100644
--- a/java-analytics-data/.OwlBot-hermetic.yaml
+++ b/java-analytics-data/.OwlBot-hermetic.yaml
@@ -19,6 +19,9 @@ deep-remove-regex:
- "/java-analytics-data/google-.*/src"
- "/java-analytics-data/samples/snippets/generated"
+deep-preserve-regex:
+ - "/.*google-.*/src/main/java/.*/stub/Version.java"
+
deep-copy-regex:
- source: "/google/analytics/data/(v.*)/.*-java/proto-google-.*/src"
dest: "/owl-bot-staging/java-analytics-data/$1/proto-google-analytics-data-$1/src"
diff --git a/java-analytics-data/README.md b/java-analytics-data/README.md
index 25cef4a8ded6..54b22f7c7845 100644
--- a/java-analytics-data/README.md
+++ b/java-analytics-data/README.md
@@ -45,20 +45,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.analytics
google-analytics-data
- 0.99.0
+ 0.101.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.analytics:google-analytics-data:0.99.0'
+implementation 'com.google.analytics:google-analytics-data:0.101.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.analytics" % "google-analytics-data" % "0.99.0"
+libraryDependencies += "com.google.analytics" % "google-analytics-data" % "0.101.0"
```
## Authentication
@@ -181,7 +181,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-analytics-data/latest/overview
[stability-image]: https://img.shields.io/badge/stability-preview-yellow
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.analytics/google-analytics-data.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.analytics/google-analytics-data/0.99.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.analytics/google-analytics-data/0.101.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-analytics-data/google-analytics-data-bom/pom.xml b/java-analytics-data/google-analytics-data-bom/pom.xml
index 4c14ff166c2b..d1e19d83cc7b 100644
--- a/java-analytics-data/google-analytics-data-bom/pom.xml
+++ b/java-analytics-data/google-analytics-data-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.analytics
google-analytics-data-bom
- 0.101.0
+ 0.102.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,27 +27,27 @@
com.google.analytics
google-analytics-data
- 0.101.0
+ 0.102.0
com.google.api.grpc
grpc-google-analytics-data-v1beta
- 0.101.0
+ 0.102.0
com.google.api.grpc
grpc-google-analytics-data-v1alpha
- 0.101.0
+ 0.102.0
com.google.api.grpc
proto-google-analytics-data-v1beta
- 0.101.0
+ 0.102.0
com.google.api.grpc
proto-google-analytics-data-v1alpha
- 0.101.0
+ 0.102.0
diff --git a/java-analytics-data/google-analytics-data/pom.xml b/java-analytics-data/google-analytics-data/pom.xml
index 95244e684866..90ec56e85939 100644
--- a/java-analytics-data/google-analytics-data/pom.xml
+++ b/java-analytics-data/google-analytics-data/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.analytics
google-analytics-data
- 0.101.0
+ 0.102.0
jar
Google Analytics Data
provides programmatic methods to access report data in Google Analytics App+Web properties.
com.google.analytics
google-analytics-data-parent
- 0.101.0
+ 0.102.0
google-analytics-data
diff --git a/java-analytics-data/google-analytics-data/src/main/java/com/google/analytics/data/v1alpha/stub/Version.java b/java-analytics-data/google-analytics-data/src/main/java/com/google/analytics/data/v1alpha/stub/Version.java
index 7d0f30b9f65d..de5fc05e236e 100644
--- a/java-analytics-data/google-analytics-data/src/main/java/com/google/analytics/data/v1alpha/stub/Version.java
+++ b/java-analytics-data/google-analytics-data/src/main/java/com/google/analytics/data/v1alpha/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-analytics-data:current}
- static final String VERSION = "0.101.0";
+ static final String VERSION = "0.102.0";
// {x-version-update-end}
}
diff --git a/java-analytics-data/google-analytics-data/src/main/java/com/google/analytics/data/v1beta/stub/Version.java b/java-analytics-data/google-analytics-data/src/main/java/com/google/analytics/data/v1beta/stub/Version.java
index a73edf3ebda3..9377ea78985e 100644
--- a/java-analytics-data/google-analytics-data/src/main/java/com/google/analytics/data/v1beta/stub/Version.java
+++ b/java-analytics-data/google-analytics-data/src/main/java/com/google/analytics/data/v1beta/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-analytics-data:current}
- static final String VERSION = "0.101.0";
+ static final String VERSION = "0.102.0";
// {x-version-update-end}
}
diff --git a/java-analytics-data/grpc-google-analytics-data-v1alpha/pom.xml b/java-analytics-data/grpc-google-analytics-data-v1alpha/pom.xml
index 4a981f6cc21b..99a13a4a06df 100644
--- a/java-analytics-data/grpc-google-analytics-data-v1alpha/pom.xml
+++ b/java-analytics-data/grpc-google-analytics-data-v1alpha/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-analytics-data-v1alpha
- 0.101.0
+ 0.102.0
grpc-google-analytics-data-v1alpha
GRPC library for google-analytics-data
com.google.analytics
google-analytics-data-parent
- 0.101.0
+ 0.102.0
diff --git a/java-analytics-data/grpc-google-analytics-data-v1beta/pom.xml b/java-analytics-data/grpc-google-analytics-data-v1beta/pom.xml
index aba5d71f2a4d..c99df7606c8b 100644
--- a/java-analytics-data/grpc-google-analytics-data-v1beta/pom.xml
+++ b/java-analytics-data/grpc-google-analytics-data-v1beta/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-analytics-data-v1beta
- 0.101.0
+ 0.102.0
grpc-google-analytics-data-v1beta
GRPC library for grpc-google-analytics-data-v1beta
com.google.analytics
google-analytics-data-parent
- 0.101.0
+ 0.102.0
diff --git a/java-analytics-data/pom.xml b/java-analytics-data/pom.xml
index c8095b76e499..350aad9131a5 100644
--- a/java-analytics-data/pom.xml
+++ b/java-analytics-data/pom.xml
@@ -4,7 +4,7 @@
com.google.analytics
google-analytics-data-parent
pom
- 0.101.0
+ 0.102.0
Google Analytics Data Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,27 +29,27 @@
com.google.analytics
google-analytics-data
- 0.101.0
+ 0.102.0
com.google.api.grpc
proto-google-analytics-data-v1alpha
- 0.101.0
+ 0.102.0
com.google.api.grpc
grpc-google-analytics-data-v1alpha
- 0.101.0
+ 0.102.0
com.google.api.grpc
proto-google-analytics-data-v1beta
- 0.101.0
+ 0.102.0
com.google.api.grpc
grpc-google-analytics-data-v1beta
- 0.101.0
+ 0.102.0
diff --git a/java-analytics-data/proto-google-analytics-data-v1alpha/pom.xml b/java-analytics-data/proto-google-analytics-data-v1alpha/pom.xml
index b396fb1b5730..99d674e1a189 100644
--- a/java-analytics-data/proto-google-analytics-data-v1alpha/pom.xml
+++ b/java-analytics-data/proto-google-analytics-data-v1alpha/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-analytics-data-v1alpha
- 0.101.0
+ 0.102.0
proto-google-analytics-data-v1alpha
Proto library for google-analytics-data
com.google.analytics
google-analytics-data-parent
- 0.101.0
+ 0.102.0
diff --git a/java-analytics-data/proto-google-analytics-data-v1beta/pom.xml b/java-analytics-data/proto-google-analytics-data-v1beta/pom.xml
index 2c56ac66fdaf..2895b78545f4 100644
--- a/java-analytics-data/proto-google-analytics-data-v1beta/pom.xml
+++ b/java-analytics-data/proto-google-analytics-data-v1beta/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-analytics-data-v1beta
- 0.101.0
+ 0.102.0
proto-google-analytics-data-v1beta
PROTO library for proto-google-analytics-data-v1beta
com.google.analytics
google-analytics-data-parent
- 0.101.0
+ 0.102.0
diff --git a/java-analyticshub/.OwlBot-hermetic.yaml b/java-analyticshub/.OwlBot-hermetic.yaml
index 16bd7686a712..52b3e48efc60 100644
--- a/java-analyticshub/.OwlBot-hermetic.yaml
+++ b/java-analyticshub/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-analyticshub/samples/snippets/generated"
deep-preserve-regex:
-- "/java-analyticshub/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/cloud/bigquery/analyticshub/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-analyticshub/README.md b/java-analyticshub/README.md
index 1a6fa3be9f21..db6d49ac6e17 100644
--- a/java-analyticshub/README.md
+++ b/java-analyticshub/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-analyticshub
- 0.85.0
+ 0.87.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-analyticshub:0.85.0'
+implementation 'com.google.cloud:google-cloud-analyticshub:0.87.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-analyticshub" % "0.85.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-analyticshub" % "0.87.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-analyticshub/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-analyticshub.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-analyticshub/0.85.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-analyticshub/0.87.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-analyticshub/google-cloud-analyticshub-bom/pom.xml b/java-analyticshub/google-cloud-analyticshub-bom/pom.xml
index 7fe1fc0e8ada..1660d870026a 100644
--- a/java-analyticshub/google-cloud-analyticshub-bom/pom.xml
+++ b/java-analyticshub/google-cloud-analyticshub-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-analyticshub-bom
- 0.87.0
+ 0.88.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,17 +27,17 @@
com.google.cloud
google-cloud-analyticshub
- 0.87.0
+ 0.88.0
com.google.api.grpc
grpc-google-cloud-analyticshub-v1
- 0.87.0
+ 0.88.0
com.google.api.grpc
proto-google-cloud-analyticshub-v1
- 0.87.0
+ 0.88.0
diff --git a/java-analyticshub/google-cloud-analyticshub/pom.xml b/java-analyticshub/google-cloud-analyticshub/pom.xml
index 456b26744a78..995edc76615d 100644
--- a/java-analyticshub/google-cloud-analyticshub/pom.xml
+++ b/java-analyticshub/google-cloud-analyticshub/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-analyticshub
- 0.87.0
+ 0.88.0
jar
Google Analytics Hub API
Analytics Hub API TBD
com.google.cloud
google-cloud-analyticshub-parent
- 0.87.0
+ 0.88.0
google-cloud-analyticshub
diff --git a/java-analyticshub/google-cloud-analyticshub/src/main/java/com/google/cloud/bigquery/analyticshub/v1/stub/Version.java b/java-analyticshub/google-cloud-analyticshub/src/main/java/com/google/cloud/bigquery/analyticshub/v1/stub/Version.java
index 926c4343c907..a9014c961907 100644
--- a/java-analyticshub/google-cloud-analyticshub/src/main/java/com/google/cloud/bigquery/analyticshub/v1/stub/Version.java
+++ b/java-analyticshub/google-cloud-analyticshub/src/main/java/com/google/cloud/bigquery/analyticshub/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-analyticshub:current}
- static final String VERSION = "0.87.0";
+ static final String VERSION = "0.88.0";
// {x-version-update-end}
}
diff --git a/java-analyticshub/grpc-google-cloud-analyticshub-v1/pom.xml b/java-analyticshub/grpc-google-cloud-analyticshub-v1/pom.xml
index 28d6fa5fdd3f..6f7a95b470c8 100644
--- a/java-analyticshub/grpc-google-cloud-analyticshub-v1/pom.xml
+++ b/java-analyticshub/grpc-google-cloud-analyticshub-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-analyticshub-v1
- 0.87.0
+ 0.88.0
grpc-google-cloud-analyticshub-v1
GRPC library for google-cloud-analyticshub
com.google.cloud
google-cloud-analyticshub-parent
- 0.87.0
+ 0.88.0
diff --git a/java-analyticshub/pom.xml b/java-analyticshub/pom.xml
index fefdba92a5f3..b0fae30b5f78 100644
--- a/java-analyticshub/pom.xml
+++ b/java-analyticshub/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-analyticshub-parent
pom
- 0.87.0
+ 0.88.0
Google Analytics Hub API Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,17 +29,17 @@
com.google.cloud
google-cloud-analyticshub
- 0.87.0
+ 0.88.0
com.google.api.grpc
grpc-google-cloud-analyticshub-v1
- 0.87.0
+ 0.88.0
com.google.api.grpc
proto-google-cloud-analyticshub-v1
- 0.87.0
+ 0.88.0
diff --git a/java-analyticshub/proto-google-cloud-analyticshub-v1/pom.xml b/java-analyticshub/proto-google-cloud-analyticshub-v1/pom.xml
index b23e6debbf42..7505511c0544 100644
--- a/java-analyticshub/proto-google-cloud-analyticshub-v1/pom.xml
+++ b/java-analyticshub/proto-google-cloud-analyticshub-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-analyticshub-v1
- 0.87.0
+ 0.88.0
proto-google-cloud-analyticshub-v1
Proto library for google-cloud-analyticshub
com.google.cloud
google-cloud-analyticshub-parent
- 0.87.0
+ 0.88.0
diff --git a/java-api-gateway/.OwlBot-hermetic.yaml b/java-api-gateway/.OwlBot-hermetic.yaml
index d533c156c462..410f47678877 100644
--- a/java-api-gateway/.OwlBot-hermetic.yaml
+++ b/java-api-gateway/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-api-gateway/google-.*/src"
deep-preserve-regex:
-- "/java-api-gateway/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/cloud/apigateway/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-api-gateway/README.md b/java-api-gateway/README.md
index 7e235898dd35..ff73e1501031 100644
--- a/java-api-gateway/README.md
+++ b/java-api-gateway/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-api-gateway
- 2.88.0
+ 2.90.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-api-gateway:2.88.0'
+implementation 'com.google.cloud:google-cloud-api-gateway:2.90.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-api-gateway" % "2.88.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-api-gateway" % "2.90.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-api-gateway/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-api-gateway.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-api-gateway/2.88.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-api-gateway/2.90.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-api-gateway/google-cloud-api-gateway-bom/pom.xml b/java-api-gateway/google-cloud-api-gateway-bom/pom.xml
index cf18a6e89518..6dcf5fb8bd2f 100644
--- a/java-api-gateway/google-cloud-api-gateway-bom/pom.xml
+++ b/java-api-gateway/google-cloud-api-gateway-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-api-gateway-bom
- 2.90.0
+ 2.91.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,17 +27,17 @@
com.google.cloud
google-cloud-api-gateway
- 2.90.0
+ 2.91.0
com.google.api.grpc
grpc-google-cloud-api-gateway-v1
- 2.90.0
+ 2.91.0
com.google.api.grpc
proto-google-cloud-api-gateway-v1
- 2.90.0
+ 2.91.0
diff --git a/java-api-gateway/google-cloud-api-gateway/pom.xml b/java-api-gateway/google-cloud-api-gateway/pom.xml
index 477d4ee513d5..1d88e6bc9f50 100644
--- a/java-api-gateway/google-cloud-api-gateway/pom.xml
+++ b/java-api-gateway/google-cloud-api-gateway/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-api-gateway
- 2.90.0
+ 2.91.0
jar
Google API Gateway
API Gateway enables you to provide secure access to your backend services through a well-defined REST API that is consistent across all of your services, regardless of the service implementation. Clients consume your REST APIS to implement standalone apps for a mobile device or tablet, through apps running in a browser, or through any other type of app that can make a request to an HTTP endpoint.
com.google.cloud
google-cloud-api-gateway-parent
- 2.90.0
+ 2.91.0
google-cloud-api-gateway
diff --git a/java-api-gateway/google-cloud-api-gateway/src/main/java/com/google/cloud/apigateway/v1/stub/Version.java b/java-api-gateway/google-cloud-api-gateway/src/main/java/com/google/cloud/apigateway/v1/stub/Version.java
index dd25f0d17241..0b011a454d75 100644
--- a/java-api-gateway/google-cloud-api-gateway/src/main/java/com/google/cloud/apigateway/v1/stub/Version.java
+++ b/java-api-gateway/google-cloud-api-gateway/src/main/java/com/google/cloud/apigateway/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-api-gateway:current}
- static final String VERSION = "2.90.0";
+ static final String VERSION = "2.91.0";
// {x-version-update-end}
}
diff --git a/java-api-gateway/grpc-google-cloud-api-gateway-v1/pom.xml b/java-api-gateway/grpc-google-cloud-api-gateway-v1/pom.xml
index a2e7ba789a72..eba9c7924d64 100644
--- a/java-api-gateway/grpc-google-cloud-api-gateway-v1/pom.xml
+++ b/java-api-gateway/grpc-google-cloud-api-gateway-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-api-gateway-v1
- 2.90.0
+ 2.91.0
grpc-google-cloud-api-gateway-v1
GRPC library for google-cloud-api-gateway
com.google.cloud
google-cloud-api-gateway-parent
- 2.90.0
+ 2.91.0
diff --git a/java-api-gateway/pom.xml b/java-api-gateway/pom.xml
index 71eb41f063bf..d1a4878a7937 100644
--- a/java-api-gateway/pom.xml
+++ b/java-api-gateway/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-api-gateway-parent
pom
- 2.90.0
+ 2.91.0
Google API Gateway Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,17 +29,17 @@
com.google.cloud
google-cloud-api-gateway
- 2.90.0
+ 2.91.0
com.google.api.grpc
grpc-google-cloud-api-gateway-v1
- 2.90.0
+ 2.91.0
com.google.api.grpc
proto-google-cloud-api-gateway-v1
- 2.90.0
+ 2.91.0
diff --git a/java-api-gateway/proto-google-cloud-api-gateway-v1/pom.xml b/java-api-gateway/proto-google-cloud-api-gateway-v1/pom.xml
index fff3c86733f3..70d7bb2afb82 100644
--- a/java-api-gateway/proto-google-cloud-api-gateway-v1/pom.xml
+++ b/java-api-gateway/proto-google-cloud-api-gateway-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-api-gateway-v1
- 2.90.0
+ 2.91.0
proto-google-cloud-api-gateway-v1
Proto library for google-cloud-api-gateway
com.google.cloud
google-cloud-api-gateway-parent
- 2.90.0
+ 2.91.0
diff --git a/java-apigee-connect/.OwlBot-hermetic.yaml b/java-apigee-connect/.OwlBot-hermetic.yaml
index a76b224b883b..c5d378822b26 100644
--- a/java-apigee-connect/.OwlBot-hermetic.yaml
+++ b/java-apigee-connect/.OwlBot-hermetic.yaml
@@ -19,6 +19,9 @@ deep-remove-regex:
- "/java-apigee-connect/proto-google-.*/src"
- "/java-apigee-connect/google-.*/src"
+deep-preserve-regex:
+ - "/.*google-.*/src/main/java/.*/stub/Version.java"
+
deep-copy-regex:
- source: "/google/cloud/apigeeconnect/(v.*)/.*-java/proto-google-.*/src"
dest: "/owl-bot-staging/java-apigee-connect/$1/proto-google-cloud-apigee-connect-$1/src"
diff --git a/java-apigee-connect/README.md b/java-apigee-connect/README.md
index a55b33b756f3..611d8bfd9b48 100644
--- a/java-apigee-connect/README.md
+++ b/java-apigee-connect/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-apigee-connect
- 2.88.0
+ 2.90.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-apigee-connect:2.88.0'
+implementation 'com.google.cloud:google-cloud-apigee-connect:2.90.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-apigee-connect" % "2.88.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-apigee-connect" % "2.90.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-apigee-connect/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-apigee-connect.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apigee-connect/2.88.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apigee-connect/2.90.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-apigee-connect/google-cloud-apigee-connect-bom/pom.xml b/java-apigee-connect/google-cloud-apigee-connect-bom/pom.xml
index ac1d6a33ec79..2254077535a8 100644
--- a/java-apigee-connect/google-cloud-apigee-connect-bom/pom.xml
+++ b/java-apigee-connect/google-cloud-apigee-connect-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-apigee-connect-bom
- 2.90.0
+ 2.91.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,17 +27,17 @@
com.google.cloud
google-cloud-apigee-connect
- 2.90.0
+ 2.91.0
com.google.api.grpc
grpc-google-cloud-apigee-connect-v1
- 2.90.0
+ 2.91.0
com.google.api.grpc
proto-google-cloud-apigee-connect-v1
- 2.90.0
+ 2.91.0
diff --git a/java-apigee-connect/google-cloud-apigee-connect/pom.xml b/java-apigee-connect/google-cloud-apigee-connect/pom.xml
index 787a91aa7026..740687a9ed35 100644
--- a/java-apigee-connect/google-cloud-apigee-connect/pom.xml
+++ b/java-apigee-connect/google-cloud-apigee-connect/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-apigee-connect
- 2.90.0
+ 2.91.0
jar
Google Apigee Connect
Apigee Connect allows the Apigee hybrid management plane to connect securely to the MART service in the runtime plane without requiring you to expose the MART endpoint on the internet.
com.google.cloud
google-cloud-apigee-connect-parent
- 2.90.0
+ 2.91.0
google-cloud-apigee-connect
diff --git a/java-apigee-connect/google-cloud-apigee-connect/src/main/java/com/google/cloud/apigeeconnect/v1/stub/Version.java b/java-apigee-connect/google-cloud-apigee-connect/src/main/java/com/google/cloud/apigeeconnect/v1/stub/Version.java
index 30b1bf584b09..7e935fce3a06 100644
--- a/java-apigee-connect/google-cloud-apigee-connect/src/main/java/com/google/cloud/apigeeconnect/v1/stub/Version.java
+++ b/java-apigee-connect/google-cloud-apigee-connect/src/main/java/com/google/cloud/apigeeconnect/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-apigee-connect:current}
- static final String VERSION = "2.90.0";
+ static final String VERSION = "2.91.0";
// {x-version-update-end}
}
diff --git a/java-apigee-connect/grpc-google-cloud-apigee-connect-v1/pom.xml b/java-apigee-connect/grpc-google-cloud-apigee-connect-v1/pom.xml
index 5474185d0093..38606646b313 100644
--- a/java-apigee-connect/grpc-google-cloud-apigee-connect-v1/pom.xml
+++ b/java-apigee-connect/grpc-google-cloud-apigee-connect-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-apigee-connect-v1
- 2.90.0
+ 2.91.0
grpc-google-cloud-apigee-connect-v1
GRPC library for google-cloud-apigee-connect
com.google.cloud
google-cloud-apigee-connect-parent
- 2.90.0
+ 2.91.0
diff --git a/java-apigee-connect/pom.xml b/java-apigee-connect/pom.xml
index 78b92f783645..45117b70df7a 100644
--- a/java-apigee-connect/pom.xml
+++ b/java-apigee-connect/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-apigee-connect-parent
pom
- 2.90.0
+ 2.91.0
Google Apigee Connect Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,17 +29,17 @@
com.google.cloud
google-cloud-apigee-connect
- 2.90.0
+ 2.91.0
com.google.api.grpc
grpc-google-cloud-apigee-connect-v1
- 2.90.0
+ 2.91.0
com.google.api.grpc
proto-google-cloud-apigee-connect-v1
- 2.90.0
+ 2.91.0
diff --git a/java-apigee-connect/proto-google-cloud-apigee-connect-v1/pom.xml b/java-apigee-connect/proto-google-cloud-apigee-connect-v1/pom.xml
index 742936b8dd46..53cf6cdde1e6 100644
--- a/java-apigee-connect/proto-google-cloud-apigee-connect-v1/pom.xml
+++ b/java-apigee-connect/proto-google-cloud-apigee-connect-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-apigee-connect-v1
- 2.90.0
+ 2.91.0
proto-google-cloud-apigee-connect-v1
Proto library for google-cloud-apigee-connect
com.google.cloud
google-cloud-apigee-connect-parent
- 2.90.0
+ 2.91.0
diff --git a/java-apigee-registry/.OwlBot-hermetic.yaml b/java-apigee-registry/.OwlBot-hermetic.yaml
index 930a6b531f95..1444f0ccaf15 100644
--- a/java-apigee-registry/.OwlBot-hermetic.yaml
+++ b/java-apigee-registry/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-apigee-registry/samples/snippets/generated"
deep-preserve-regex:
-- "/java-apigee-registry/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/cloud/apigeeregistry/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-apigee-registry/README.md b/java-apigee-registry/README.md
index 3b381bb29bc0..7347afdf251e 100644
--- a/java-apigee-registry/README.md
+++ b/java-apigee-registry/README.md
@@ -45,20 +45,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-apigee-registry
- 0.88.0
+ 0.90.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-apigee-registry:0.88.0'
+implementation 'com.google.cloud:google-cloud-apigee-registry:0.90.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-apigee-registry" % "0.88.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-apigee-registry" % "0.90.0"
```
## Authentication
@@ -181,7 +181,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-apigee-registry/latest/overview
[stability-image]: https://img.shields.io/badge/stability-preview-yellow
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-apigee-registry.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apigee-registry/0.88.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apigee-registry/0.90.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-apigee-registry/google-cloud-apigee-registry-bom/pom.xml b/java-apigee-registry/google-cloud-apigee-registry-bom/pom.xml
index ba43c89a87ca..84c0ba2e6a02 100644
--- a/java-apigee-registry/google-cloud-apigee-registry-bom/pom.xml
+++ b/java-apigee-registry/google-cloud-apigee-registry-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-apigee-registry-bom
- 0.90.0
+ 0.91.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,17 +27,17 @@
com.google.cloud
google-cloud-apigee-registry
- 0.90.0
+ 0.91.0
com.google.api.grpc
grpc-google-cloud-apigee-registry-v1
- 0.90.0
+ 0.91.0
com.google.api.grpc
proto-google-cloud-apigee-registry-v1
- 0.90.0
+ 0.91.0
diff --git a/java-apigee-registry/google-cloud-apigee-registry/pom.xml b/java-apigee-registry/google-cloud-apigee-registry/pom.xml
index 196f3bcbc343..320371b9bf31 100644
--- a/java-apigee-registry/google-cloud-apigee-registry/pom.xml
+++ b/java-apigee-registry/google-cloud-apigee-registry/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-apigee-registry
- 0.90.0
+ 0.91.0
jar
Google Registry API
Registry API allows teams to upload and share machine-readable descriptions of APIs that are in use and in development.
com.google.cloud
google-cloud-apigee-registry-parent
- 0.90.0
+ 0.91.0
google-cloud-apigee-registry
diff --git a/java-apigee-registry/google-cloud-apigee-registry/src/main/java/com/google/cloud/apigeeregistry/v1/stub/Version.java b/java-apigee-registry/google-cloud-apigee-registry/src/main/java/com/google/cloud/apigeeregistry/v1/stub/Version.java
index 8a8e43488b73..a3bb234e5148 100644
--- a/java-apigee-registry/google-cloud-apigee-registry/src/main/java/com/google/cloud/apigeeregistry/v1/stub/Version.java
+++ b/java-apigee-registry/google-cloud-apigee-registry/src/main/java/com/google/cloud/apigeeregistry/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-apigee-registry:current}
- static final String VERSION = "0.90.0";
+ static final String VERSION = "0.91.0";
// {x-version-update-end}
}
diff --git a/java-apigee-registry/grpc-google-cloud-apigee-registry-v1/pom.xml b/java-apigee-registry/grpc-google-cloud-apigee-registry-v1/pom.xml
index 014e40a3eba5..1be6d177636d 100644
--- a/java-apigee-registry/grpc-google-cloud-apigee-registry-v1/pom.xml
+++ b/java-apigee-registry/grpc-google-cloud-apigee-registry-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-apigee-registry-v1
- 0.90.0
+ 0.91.0
grpc-google-cloud-apigee-registry-v1
GRPC library for google-cloud-apigee-registry
com.google.cloud
google-cloud-apigee-registry-parent
- 0.90.0
+ 0.91.0
diff --git a/java-apigee-registry/pom.xml b/java-apigee-registry/pom.xml
index 23bdec9585cb..8184e5ce19e6 100644
--- a/java-apigee-registry/pom.xml
+++ b/java-apigee-registry/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-apigee-registry-parent
pom
- 0.90.0
+ 0.91.0
Google Registry API Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,17 +29,17 @@
com.google.cloud
google-cloud-apigee-registry
- 0.90.0
+ 0.91.0
com.google.api.grpc
grpc-google-cloud-apigee-registry-v1
- 0.90.0
+ 0.91.0
com.google.api.grpc
proto-google-cloud-apigee-registry-v1
- 0.90.0
+ 0.91.0
diff --git a/java-apigee-registry/proto-google-cloud-apigee-registry-v1/pom.xml b/java-apigee-registry/proto-google-cloud-apigee-registry-v1/pom.xml
index 11a1f8737457..cb5a9bac89cc 100644
--- a/java-apigee-registry/proto-google-cloud-apigee-registry-v1/pom.xml
+++ b/java-apigee-registry/proto-google-cloud-apigee-registry-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-apigee-registry-v1
- 0.90.0
+ 0.91.0
proto-google-cloud-apigee-registry-v1
Proto library for google-cloud-apigee-registry
com.google.cloud
google-cloud-apigee-registry-parent
- 0.90.0
+ 0.91.0
diff --git a/java-apihub/.OwlBot-hermetic.yaml b/java-apihub/.OwlBot-hermetic.yaml
index 6f67c7f6724a..86d34b927e2f 100644
--- a/java-apihub/.OwlBot-hermetic.yaml
+++ b/java-apihub/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-apihub/samples/snippets/generated"
deep-preserve-regex:
-- "/java-apihub/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/cloud/apihub/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-apihub/README.md b/java-apihub/README.md
index 9af3d352a037..ed80109ce1a5 100644
--- a/java-apihub/README.md
+++ b/java-apihub/README.md
@@ -45,20 +45,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-apihub
- 0.41.0
+ 0.43.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-apihub:0.41.0'
+implementation 'com.google.cloud:google-cloud-apihub:0.43.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-apihub" % "0.41.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-apihub" % "0.43.0"
```
## Authentication
@@ -181,7 +181,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-apihub/latest/overview
[stability-image]: https://img.shields.io/badge/stability-preview-yellow
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-apihub.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apihub/0.41.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apihub/0.43.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-apihub/google-cloud-apihub-bom/pom.xml b/java-apihub/google-cloud-apihub-bom/pom.xml
index cefbec2e074e..02fab7ca9cb6 100644
--- a/java-apihub/google-cloud-apihub-bom/pom.xml
+++ b/java-apihub/google-cloud-apihub-bom/pom.xml
@@ -3,12 +3,12 @@
4.0.0
com.google.cloud
google-cloud-apihub-bom
- 0.43.0
+ 0.44.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -26,12 +26,12 @@
com.google.cloud
google-cloud-apihub
- 0.43.0
+ 0.44.0
com.google.api.grpc
proto-google-cloud-apihub-v1
- 0.43.0
+ 0.44.0
diff --git a/java-apihub/google-cloud-apihub/pom.xml b/java-apihub/google-cloud-apihub/pom.xml
index 0870f1ce9651..1befcc626694 100644
--- a/java-apihub/google-cloud-apihub/pom.xml
+++ b/java-apihub/google-cloud-apihub/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-apihub
- 0.43.0
+ 0.44.0
jar
Google API hub API
API hub API API hub lets you consolidate and organize information about all of the APIs of interest to your organization. API hub lets you capture critical information about APIs that allows developers to discover and evaluate them easily and leverage the work of other teams wherever possible. API platform teams can use API hub to have visibility into and manage their portfolio of APIs.
com.google.cloud
google-cloud-apihub-parent
- 0.43.0
+ 0.44.0
google-cloud-apihub
diff --git a/java-apihub/google-cloud-apihub/src/main/java/com/google/cloud/apihub/v1/stub/Version.java b/java-apihub/google-cloud-apihub/src/main/java/com/google/cloud/apihub/v1/stub/Version.java
index be0230169cae..6cbc0e3d072d 100644
--- a/java-apihub/google-cloud-apihub/src/main/java/com/google/cloud/apihub/v1/stub/Version.java
+++ b/java-apihub/google-cloud-apihub/src/main/java/com/google/cloud/apihub/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-apihub:current}
- static final String VERSION = "0.43.0";
+ static final String VERSION = "0.44.0";
// {x-version-update-end}
}
diff --git a/java-apihub/pom.xml b/java-apihub/pom.xml
index e17e2aad7615..564bb20bf06d 100644
--- a/java-apihub/pom.xml
+++ b/java-apihub/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-apihub-parent
pom
- 0.43.0
+ 0.44.0
Google API hub API Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,12 +29,12 @@
com.google.cloud
google-cloud-apihub
- 0.43.0
+ 0.44.0
com.google.api.grpc
proto-google-cloud-apihub-v1
- 0.43.0
+ 0.44.0
diff --git a/java-apihub/proto-google-cloud-apihub-v1/pom.xml b/java-apihub/proto-google-cloud-apihub-v1/pom.xml
index 01a6d1dcb0c0..9457521e15d6 100644
--- a/java-apihub/proto-google-cloud-apihub-v1/pom.xml
+++ b/java-apihub/proto-google-cloud-apihub-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-apihub-v1
- 0.43.0
+ 0.44.0
proto-google-cloud-apihub-v1
Proto library for google-cloud-apihub
com.google.cloud
google-cloud-apihub-parent
- 0.43.0
+ 0.44.0
diff --git a/java-apikeys/.OwlBot-hermetic.yaml b/java-apikeys/.OwlBot-hermetic.yaml
index 7cba2ebe02e9..a20286624096 100644
--- a/java-apikeys/.OwlBot-hermetic.yaml
+++ b/java-apikeys/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-apikeys/samples/snippets/generated"
deep-preserve-regex:
-- "/java-apikeys/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/api/apikeys/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-apikeys/README.md b/java-apikeys/README.md
index 9d1e5d50819a..3b57ec90e5c0 100644
--- a/java-apikeys/README.md
+++ b/java-apikeys/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-apikeys
- 0.86.0
+ 0.88.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-apikeys:0.86.0'
+implementation 'com.google.cloud:google-cloud-apikeys:0.88.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-apikeys" % "0.86.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-apikeys" % "0.88.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-apikeys/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-apikeys.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apikeys/0.86.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apikeys/0.88.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-apikeys/google-cloud-apikeys-bom/pom.xml b/java-apikeys/google-cloud-apikeys-bom/pom.xml
index 7435743970d9..8eec0af4b90a 100644
--- a/java-apikeys/google-cloud-apikeys-bom/pom.xml
+++ b/java-apikeys/google-cloud-apikeys-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-apikeys-bom
- 0.88.0
+ 0.89.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,17 +27,17 @@
com.google.cloud
google-cloud-apikeys
- 0.88.0
+ 0.89.0
com.google.api.grpc
grpc-google-cloud-apikeys-v2
- 0.88.0
+ 0.89.0
com.google.api.grpc
proto-google-cloud-apikeys-v2
- 0.88.0
+ 0.89.0
diff --git a/java-apikeys/google-cloud-apikeys/pom.xml b/java-apikeys/google-cloud-apikeys/pom.xml
index 25cee5e89a83..900bfa58fee9 100644
--- a/java-apikeys/google-cloud-apikeys/pom.xml
+++ b/java-apikeys/google-cloud-apikeys/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-apikeys
- 0.88.0
+ 0.89.0
jar
Google API Keys API
API Keys API API Keys lets you create and manage your API keys for your projects.
com.google.cloud
google-cloud-apikeys-parent
- 0.88.0
+ 0.89.0
google-cloud-apikeys
diff --git a/java-apikeys/google-cloud-apikeys/src/main/java/com/google/api/apikeys/v2/stub/Version.java b/java-apikeys/google-cloud-apikeys/src/main/java/com/google/api/apikeys/v2/stub/Version.java
index 8cbd3b5c4d21..6a7a83cf124f 100644
--- a/java-apikeys/google-cloud-apikeys/src/main/java/com/google/api/apikeys/v2/stub/Version.java
+++ b/java-apikeys/google-cloud-apikeys/src/main/java/com/google/api/apikeys/v2/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-apikeys:current}
- static final String VERSION = "0.88.0";
+ static final String VERSION = "0.89.0";
// {x-version-update-end}
}
diff --git a/java-apikeys/grpc-google-cloud-apikeys-v2/pom.xml b/java-apikeys/grpc-google-cloud-apikeys-v2/pom.xml
index 3130e919b15a..dd76cdafa108 100644
--- a/java-apikeys/grpc-google-cloud-apikeys-v2/pom.xml
+++ b/java-apikeys/grpc-google-cloud-apikeys-v2/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-apikeys-v2
- 0.88.0
+ 0.89.0
grpc-google-cloud-apikeys-v2
GRPC library for google-cloud-apikeys
com.google.cloud
google-cloud-apikeys-parent
- 0.88.0
+ 0.89.0
diff --git a/java-apikeys/pom.xml b/java-apikeys/pom.xml
index 42b78e4129c4..92f68a2f7efe 100644
--- a/java-apikeys/pom.xml
+++ b/java-apikeys/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-apikeys-parent
pom
- 0.88.0
+ 0.89.0
Google API Keys API Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,17 +29,17 @@
com.google.cloud
google-cloud-apikeys
- 0.88.0
+ 0.89.0
com.google.api.grpc
grpc-google-cloud-apikeys-v2
- 0.88.0
+ 0.89.0
com.google.api.grpc
proto-google-cloud-apikeys-v2
- 0.88.0
+ 0.89.0
diff --git a/java-apikeys/proto-google-cloud-apikeys-v2/pom.xml b/java-apikeys/proto-google-cloud-apikeys-v2/pom.xml
index dfbbc46b5ef1..65523560b180 100644
--- a/java-apikeys/proto-google-cloud-apikeys-v2/pom.xml
+++ b/java-apikeys/proto-google-cloud-apikeys-v2/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-apikeys-v2
- 0.88.0
+ 0.89.0
proto-google-cloud-apikeys-v2
Proto library for google-cloud-apikeys
com.google.cloud
google-cloud-apikeys-parent
- 0.88.0
+ 0.89.0
diff --git a/java-appengine-admin/.OwlBot-hermetic.yaml b/java-appengine-admin/.OwlBot-hermetic.yaml
index f23fb5845c0b..7bf30a296880 100644
--- a/java-appengine-admin/.OwlBot-hermetic.yaml
+++ b/java-appengine-admin/.OwlBot-hermetic.yaml
@@ -19,6 +19,9 @@ deep-remove-regex:
- "/java-appengine-admin/google-.*/src"
- "/java-appengine-admin/samples/snippets/generated"
+deep-preserve-regex:
+ - "/.*google-.*/src/main/java/.*/stub/Version.java"
+
deep-copy-regex:
- source: "/google/appengine/(v.*)/.*-java/proto-google-.*/src"
dest: "/owl-bot-staging/java-appengine-admin/$1/proto-google-cloud-appengine-admin-$1/src"
diff --git a/java-appengine-admin/README.md b/java-appengine-admin/README.md
index e3e84cf6c54a..4a46602eb961 100644
--- a/java-appengine-admin/README.md
+++ b/java-appengine-admin/README.md
@@ -42,20 +42,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-appengine-admin
- 2.88.0
+ 2.90.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-appengine-admin:2.88.0'
+implementation 'com.google.cloud:google-cloud-appengine-admin:2.90.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-appengine-admin" % "2.88.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-appengine-admin" % "2.90.0"
```
## Authentication
@@ -175,7 +175,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-appengine-admin/latest/overview
[stability-image]: https://img.shields.io/badge/stability-stable-green
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-appengine-admin.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-appengine-admin/2.88.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-appengine-admin/2.90.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-appengine-admin/google-cloud-appengine-admin-bom/pom.xml b/java-appengine-admin/google-cloud-appengine-admin-bom/pom.xml
index bfce13d9cf6c..bff67d71068b 100644
--- a/java-appengine-admin/google-cloud-appengine-admin-bom/pom.xml
+++ b/java-appengine-admin/google-cloud-appengine-admin-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-appengine-admin-bom
- 2.90.0
+ 2.91.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,17 +27,17 @@
com.google.cloud
google-cloud-appengine-admin
- 2.90.0
+ 2.91.0
com.google.api.grpc
grpc-google-cloud-appengine-admin-v1
- 2.90.0
+ 2.91.0
com.google.api.grpc
proto-google-cloud-appengine-admin-v1
- 2.90.0
+ 2.91.0
diff --git a/java-appengine-admin/google-cloud-appengine-admin/pom.xml b/java-appengine-admin/google-cloud-appengine-admin/pom.xml
index 2daf113d942e..efe6023792d4 100644
--- a/java-appengine-admin/google-cloud-appengine-admin/pom.xml
+++ b/java-appengine-admin/google-cloud-appengine-admin/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-appengine-admin
- 2.90.0
+ 2.91.0
jar
Google App Engine Admin API
App Engine Admin API you to manage your App Engine applications.
com.google.cloud
google-cloud-appengine-admin-parent
- 2.90.0
+ 2.91.0
google-cloud-appengine-admin
diff --git a/java-appengine-admin/google-cloud-appengine-admin/src/main/java/com/google/appengine/v1/stub/Version.java b/java-appengine-admin/google-cloud-appengine-admin/src/main/java/com/google/appengine/v1/stub/Version.java
index 51fb223d58a7..16387d615fc8 100644
--- a/java-appengine-admin/google-cloud-appengine-admin/src/main/java/com/google/appengine/v1/stub/Version.java
+++ b/java-appengine-admin/google-cloud-appengine-admin/src/main/java/com/google/appengine/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-appengine-admin:current}
- static final String VERSION = "2.90.0";
+ static final String VERSION = "2.91.0";
// {x-version-update-end}
}
diff --git a/java-appengine-admin/grpc-google-cloud-appengine-admin-v1/pom.xml b/java-appengine-admin/grpc-google-cloud-appengine-admin-v1/pom.xml
index fc3e8b11ff26..00c708937112 100644
--- a/java-appengine-admin/grpc-google-cloud-appengine-admin-v1/pom.xml
+++ b/java-appengine-admin/grpc-google-cloud-appengine-admin-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-appengine-admin-v1
- 2.90.0
+ 2.91.0
grpc-google-cloud-appengine-admin-v1
GRPC library for google-cloud-appengine-admin
com.google.cloud
google-cloud-appengine-admin-parent
- 2.90.0
+ 2.91.0
diff --git a/java-appengine-admin/pom.xml b/java-appengine-admin/pom.xml
index 711aac37c910..59e7b17bfdb2 100644
--- a/java-appengine-admin/pom.xml
+++ b/java-appengine-admin/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-appengine-admin-parent
pom
- 2.90.0
+ 2.91.0
Google App Engine Admin API Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,17 +29,17 @@
com.google.cloud
google-cloud-appengine-admin
- 2.90.0
+ 2.91.0
com.google.api.grpc
grpc-google-cloud-appengine-admin-v1
- 2.90.0
+ 2.91.0
com.google.api.grpc
proto-google-cloud-appengine-admin-v1
- 2.90.0
+ 2.91.0
diff --git a/java-appengine-admin/proto-google-cloud-appengine-admin-v1/pom.xml b/java-appengine-admin/proto-google-cloud-appengine-admin-v1/pom.xml
index 08572524183a..c7297af712df 100644
--- a/java-appengine-admin/proto-google-cloud-appengine-admin-v1/pom.xml
+++ b/java-appengine-admin/proto-google-cloud-appengine-admin-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-appengine-admin-v1
- 2.90.0
+ 2.91.0
proto-google-cloud-appengine-admin-v1
Proto library for google-cloud-appengine-admin
com.google.cloud
google-cloud-appengine-admin-parent
- 2.90.0
+ 2.91.0
diff --git a/java-apphub/.OwlBot-hermetic.yaml b/java-apphub/.OwlBot-hermetic.yaml
index cd07e1fbffb6..4ec45152b5f3 100644
--- a/java-apphub/.OwlBot-hermetic.yaml
+++ b/java-apphub/.OwlBot-hermetic.yaml
@@ -20,7 +20,8 @@ deep-remove-regex:
- "/java-apphub/samples/snippets/generated"
deep-preserve-regex:
-- "/java-apphub/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+- "/.*google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
deep-copy-regex:
- source: "/google/cloud/apphub/(v.*)/.*-java/proto-google-.*/src"
diff --git a/java-apphub/README.md b/java-apphub/README.md
index ce8d7c331231..a07644102c14 100644
--- a/java-apphub/README.md
+++ b/java-apphub/README.md
@@ -45,20 +45,20 @@ If you are using Maven without the BOM, add this to your dependencies:
com.google.cloud
google-cloud-apphub
- 0.52.0
+ 0.54.0
```
If you are using Gradle without BOM, add this to your dependencies:
```Groovy
-implementation 'com.google.cloud:google-cloud-apphub:0.52.0'
+implementation 'com.google.cloud:google-cloud-apphub:0.54.0'
```
If you are using SBT, add this to your dependencies:
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-apphub" % "0.52.0"
+libraryDependencies += "com.google.cloud" % "google-cloud-apphub" % "0.54.0"
```
## Authentication
@@ -181,7 +181,7 @@ Java is a registered trademark of Oracle and/or its affiliates.
[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-apphub/latest/overview
[stability-image]: https://img.shields.io/badge/stability-preview-yellow
[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-apphub.svg
-[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apphub/0.52.0
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-apphub/0.54.0
[authentication]: https://github.com/googleapis/google-cloud-java#authentication
[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
diff --git a/java-apphub/google-cloud-apphub-bom/pom.xml b/java-apphub/google-cloud-apphub-bom/pom.xml
index 302195caabe0..dd12bcdd26c0 100644
--- a/java-apphub/google-cloud-apphub-bom/pom.xml
+++ b/java-apphub/google-cloud-apphub-bom/pom.xml
@@ -3,13 +3,13 @@
4.0.0
com.google.cloud
google-cloud-apphub-bom
- 0.54.0
+ 0.55.0
pom
com.google.cloud
google-cloud-pom-parent
- 1.84.0
+ 1.85.0
../../google-cloud-pom-parent/pom.xml
@@ -27,17 +27,17 @@
com.google.cloud
google-cloud-apphub
- 0.54.0
+ 0.55.0
com.google.api.grpc
grpc-google-cloud-apphub-v1
- 0.54.0
+ 0.55.0
com.google.api.grpc
proto-google-cloud-apphub-v1
- 0.54.0
+ 0.55.0
diff --git a/java-apphub/google-cloud-apphub/pom.xml b/java-apphub/google-cloud-apphub/pom.xml
index 6d08ba6131c4..952f87cabfee 100644
--- a/java-apphub/google-cloud-apphub/pom.xml
+++ b/java-apphub/google-cloud-apphub/pom.xml
@@ -3,14 +3,14 @@
4.0.0
com.google.cloud
google-cloud-apphub
- 0.54.0
+ 0.55.0
jar
Google App Hub API
App Hub API App Hub simplifies the process of building, running, and managing applications on Google Cloud.
com.google.cloud
google-cloud-apphub-parent
- 0.54.0
+ 0.55.0
google-cloud-apphub
diff --git a/java-apphub/google-cloud-apphub/src/main/java/com/google/cloud/apphub/v1/stub/Version.java b/java-apphub/google-cloud-apphub/src/main/java/com/google/cloud/apphub/v1/stub/Version.java
index 71ae0d362604..2950a777fc3b 100644
--- a/java-apphub/google-cloud-apphub/src/main/java/com/google/cloud/apphub/v1/stub/Version.java
+++ b/java-apphub/google-cloud-apphub/src/main/java/com/google/cloud/apphub/v1/stub/Version.java
@@ -21,7 +21,7 @@
@InternalApi("For internal use only")
final class Version {
// {x-version-update-start:google-cloud-apphub:current}
- static final String VERSION = "0.54.0";
+ static final String VERSION = "0.55.0";
// {x-version-update-end}
}
diff --git a/java-apphub/grpc-google-cloud-apphub-v1/pom.xml b/java-apphub/grpc-google-cloud-apphub-v1/pom.xml
index ac783208d528..453a671d8f1f 100644
--- a/java-apphub/grpc-google-cloud-apphub-v1/pom.xml
+++ b/java-apphub/grpc-google-cloud-apphub-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
grpc-google-cloud-apphub-v1
- 0.54.0
+ 0.55.0
grpc-google-cloud-apphub-v1
GRPC library for google-cloud-apphub
com.google.cloud
google-cloud-apphub-parent
- 0.54.0
+ 0.55.0
diff --git a/java-apphub/pom.xml b/java-apphub/pom.xml
index cad56c30c40b..5be622b6ee58 100644
--- a/java-apphub/pom.xml
+++ b/java-apphub/pom.xml
@@ -4,7 +4,7 @@
com.google.cloud
google-cloud-apphub-parent
pom
- 0.54.0
+ 0.55.0
Google App Hub API Parent
Java idiomatic client for Google Cloud Platform services.
@@ -13,7 +13,7 @@
com.google.cloud
google-cloud-jar-parent
- 1.84.0
+ 1.85.0
../google-cloud-jar-parent/pom.xml
@@ -29,17 +29,17 @@
com.google.cloud
google-cloud-apphub
- 0.54.0
+ 0.55.0
com.google.api.grpc
grpc-google-cloud-apphub-v1
- 0.54.0
+ 0.55.0
com.google.api.grpc
proto-google-cloud-apphub-v1
- 0.54.0
+ 0.55.0
diff --git a/java-apphub/proto-google-cloud-apphub-v1/pom.xml b/java-apphub/proto-google-cloud-apphub-v1/pom.xml
index ad8bb4d60a5c..95842e3ec6e1 100644
--- a/java-apphub/proto-google-cloud-apphub-v1/pom.xml
+++ b/java-apphub/proto-google-cloud-apphub-v1/pom.xml
@@ -4,13 +4,13 @@
4.0.0
com.google.api.grpc
proto-google-cloud-apphub-v1
- 0.54.0
+ 0.55.0
proto-google-cloud-apphub-v1
Proto library for google-cloud-apphub
com.google.cloud
google-cloud-apphub-parent
- 0.54.0
+ 0.55.0
diff --git a/java-appoptimize/.OwlBot-hermetic.yaml b/java-appoptimize/.OwlBot-hermetic.yaml
new file mode 100644
index 000000000000..8c33a053fe62
--- /dev/null
+++ b/java-appoptimize/.OwlBot-hermetic.yaml
@@ -0,0 +1,36 @@
+# Copyright 2024 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+deep-remove-regex:
+- "/java-appoptimize/grpc-google-.*/src"
+- "/java-appoptimize/proto-google-.*/src"
+- "/java-appoptimize/google-.*/src"
+- "/java-appoptimize/samples/snippets/generated"
+
+deep-preserve-regex:
+- "/java-appoptimize/google-.*/src/test/java/com/google/cloud/.*/v.*/it/IT.*Test.java"
+- "/.*google-.*/src/main/java/.*/stub/Version.java"
+
+deep-copy-regex:
+- source: "/google/cloud/appoptimize/(v.*)/.*-java/proto-google-.*/src"
+ dest: "/owl-bot-staging/java-appoptimize/$1/proto-google-cloud-appoptimize-$1/src"
+- source: "/google/cloud/appoptimize/(v.*)/.*-java/grpc-google-.*/src"
+ dest: "/owl-bot-staging/java-appoptimize/$1/grpc-google-cloud-appoptimize-$1/src"
+- source: "/google/cloud/appoptimize/(v.*)/.*-java/gapic-google-.*/src"
+ dest: "/owl-bot-staging/java-appoptimize/$1/google-cloud-appoptimize/src"
+- source: "/google/cloud/appoptimize/(v.*)/.*-java/samples/snippets/generated"
+ dest: "/owl-bot-staging/java-appoptimize/$1/samples/snippets/generated"
+
+api-name: appoptimize
\ No newline at end of file
diff --git a/java-appoptimize/.repo-metadata.json b/java-appoptimize/.repo-metadata.json
new file mode 100644
index 000000000000..ab1b1e92abd3
--- /dev/null
+++ b/java-appoptimize/.repo-metadata.json
@@ -0,0 +1,16 @@
+{
+ "api_shortname": "appoptimize",
+ "name_pretty": "App Optimize API",
+ "product_documentation": "https://docs.cloud.google.com/app-optimize/overview",
+ "api_description": "The App Optimize API provides developers and platform teams with tools to monitor, analyze, and improve the performance and cost-efficiency of their cloud applications.",
+ "client_documentation": "https://cloud.google.com/java/docs/reference/google-cloud-appoptimize/latest/overview",
+ "release_level": "preview",
+ "transport": "both",
+ "language": "java",
+ "repo": "googleapis/google-cloud-java",
+ "repo_short": "java-appoptimize",
+ "distribution_name": "com.google.cloud:google-cloud-appoptimize",
+ "api_id": "appoptimize.googleapis.com",
+ "library_type": "GAPIC_AUTO",
+ "requires_billing": true
+}
\ No newline at end of file
diff --git a/java-appoptimize/README.md b/java-appoptimize/README.md
new file mode 100644
index 000000000000..2c9ce0d61010
--- /dev/null
+++ b/java-appoptimize/README.md
@@ -0,0 +1,205 @@
+# Google App Optimize API Client for Java
+
+Java idiomatic client for [App Optimize API][product-docs].
+
+[![Maven][maven-version-image]][maven-version-link]
+![Stability][stability-image]
+
+- [Product Documentation][product-docs]
+- [Client Library Documentation][javadocs]
+
+> Note: This client is a work-in-progress, and may occasionally
+> make backwards-incompatible changes.
+
+
+## Quickstart
+
+
+If you are using Maven with [BOM][libraries-bom], add this to your pom.xml file:
+
+```xml
+
+
+
+ com.google.cloud
+ libraries-bom
+ 26.79.0
+ pom
+ import
+
+
+
+
+
+
+ com.google.cloud
+ google-cloud-appoptimize
+
+
+```
+
+If you are using Maven without the BOM, add this to your dependencies:
+
+
+```xml
+
+ com.google.cloud
+ google-cloud-appoptimize
+ 0.0.0
+
+```
+
+If you are using Gradle without BOM, add this to your dependencies:
+
+```Groovy
+implementation 'com.google.cloud:google-cloud-appoptimize:0.0.0'
+```
+
+If you are using SBT, add this to your dependencies:
+
+```Scala
+libraryDependencies += "com.google.cloud" % "google-cloud-appoptimize" % "0.0.0"
+```
+
+## Authentication
+
+See the [Authentication][authentication] section in the base directory's README.
+
+## Authorization
+
+The client application making API calls must be granted [authorization scopes][auth-scopes] required for the desired App Optimize API APIs, and the authenticated principal must have the [IAM role(s)][predefined-iam-roles] required to access GCP resources using the App Optimize API API calls.
+
+## Getting Started
+
+### Prerequisites
+
+You will need a [Google Cloud Platform Console][developer-console] project with the App Optimize API [API enabled][enable-api].
+You will need to [enable billing][enable-billing] to use Google App Optimize API.
+[Follow these instructions][create-project] to get your project set up. You will also need to set up the local development environment by
+[installing the Google Cloud Command Line Interface][cloud-cli] and running the following commands in command line:
+`gcloud auth login` and `gcloud config set project [YOUR PROJECT ID]`.
+
+### Installation and setup
+
+You'll need to obtain the `google-cloud-appoptimize` library. See the [Quickstart](#quickstart) section
+to add `google-cloud-appoptimize` as a dependency in your code.
+
+## About App Optimize API
+
+
+[App Optimize API][product-docs] The App Optimize API provides developers and platform teams with tools to monitor, analyze, and improve the performance and cost-efficiency of their cloud applications.
+
+See the [App Optimize API client library docs][javadocs] to learn how to
+use this App Optimize API Client Library.
+
+
+
+
+
+
+## Troubleshooting
+
+To get help, follow the instructions in the [shared Troubleshooting document][troubleshooting].
+
+## Transport
+
+App Optimize API uses both gRPC and HTTP/JSON for the transport layer.
+
+## Supported Java Versions
+
+Java 8 or above is required for using this client.
+
+Google's Java client libraries,
+[Google Cloud Client Libraries][cloudlibs]
+and
+[Google Cloud API Libraries][apilibs],
+follow the
+[Oracle Java SE support roadmap][oracle]
+(see the Oracle Java SE Product Releases section).
+
+### For new development
+
+In general, new feature development occurs with support for the lowest Java
+LTS version covered by Oracle's Premier Support (which typically lasts 5 years
+from initial General Availability). If the minimum required JVM for a given
+library is changed, it is accompanied by a [semver][semver] major release.
+
+Java 11 and (in September 2021) Java 17 are the best choices for new
+development.
+
+### Keeping production systems current
+
+Google tests its client libraries with all current LTS versions covered by
+Oracle's Extended Support (which typically lasts 8 years from initial
+General Availability).
+
+#### Legacy support
+
+Google's client libraries support legacy versions of Java runtimes with long
+term stable libraries that don't receive feature updates on a best efforts basis
+as it may not be possible to backport all patches.
+
+Google provides updates on a best efforts basis to apps that continue to use
+Java 7, though apps might need to upgrade to current versions of the library
+that supports their JVM.
+
+#### Where to find specific information
+
+The latest versions and the supported Java versions are identified on
+the individual GitHub repository `github.com/GoogleAPIs/java-SERVICENAME`
+and on [google-cloud-java][g-c-j].
+
+## Versioning
+
+
+This library follows [Semantic Versioning](http://semver.org/).
+
+
+It is currently in major version zero (``0.y.z``), which means that anything may change at any time
+and the public API should not be considered stable.
+
+
+## Contributing
+
+
+Contributions to this library are always welcome and highly encouraged.
+
+See [CONTRIBUTING][contributing] for more information how to get started.
+
+Please note that this project is released with a Contributor Code of Conduct. By participating in
+this project you agree to abide by its terms. See [Code of Conduct][code-of-conduct] for more
+information.
+
+
+## License
+
+Apache 2.0 - See [LICENSE][license] for more information.
+
+Java is a registered trademark of Oracle and/or its affiliates.
+
+[product-docs]: https://docs.cloud.google.com/app-optimize/overview
+[javadocs]: https://cloud.google.com/java/docs/reference/google-cloud-appoptimize/latest/overview
+[stability-image]: https://img.shields.io/badge/stability-preview-yellow
+[maven-version-image]: https://img.shields.io/maven-central/v/com.google.cloud/google-cloud-appoptimize.svg
+[maven-version-link]: https://central.sonatype.com/artifact/com.google.cloud/google-cloud-appoptimize/0.0.0
+[authentication]: https://github.com/googleapis/google-cloud-java#authentication
+[auth-scopes]: https://developers.google.com/identity/protocols/oauth2/scopes
+[predefined-iam-roles]: https://cloud.google.com/iam/docs/understanding-roles#predefined_roles
+[iam-policy]: https://cloud.google.com/iam/docs/overview#cloud-iam-policy
+[developer-console]: https://console.developers.google.com/
+[create-project]: https://cloud.google.com/resource-manager/docs/creating-managing-projects
+[cloud-cli]: https://cloud.google.com/cli
+[troubleshooting]: https://github.com/googleapis/google-cloud-java/blob/main/TROUBLESHOOTING.md
+[contributing]: https://github.com/googleapis/google-cloud-java/blob/main/CONTRIBUTING.md
+[code-of-conduct]: https://github.com/googleapis/google-cloud-java/blob/main/CODE_OF_CONDUCT.md#contributor-code-of-conduct
+[license]: https://github.com/googleapis/google-cloud-java/blob/main/LICENSE
+[enable-billing]: https://cloud.google.com/apis/docs/getting-started#enabling_billing
+[enable-api]: https://console.cloud.google.com/flows/enableapi?apiid=appoptimize.googleapis.com
+[libraries-bom]: https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/The-Google-Cloud-Platform-Libraries-BOM
+[shell_img]: https://gstatic.com/cloudssh/images/open-btn.png
+
+[semver]: https://semver.org/
+[cloudlibs]: https://cloud.google.com/apis/docs/client-libraries-explained
+[apilibs]: https://cloud.google.com/apis/docs/client-libraries-explained#google_api_client_libraries
+[oracle]: https://www.oracle.com/java/technologies/java-se-support-roadmap.html
+[g-c-j]: http://github.com/googleapis/google-cloud-java
diff --git a/java-appoptimize/google-cloud-appoptimize-bom/pom.xml b/java-appoptimize/google-cloud-appoptimize-bom/pom.xml
new file mode 100644
index 000000000000..58908ffb96e0
--- /dev/null
+++ b/java-appoptimize/google-cloud-appoptimize-bom/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+ com.google.cloud
+ google-cloud-appoptimize-bom
+ 0.1.0
+ pom
+
+ com.google.cloud
+ google-cloud-pom-parent
+ 1.85.0
+ ../../google-cloud-pom-parent/pom.xml
+
+
+ Google App Optimize API BOM
+
+ BOM for App Optimize API
+
+
+
+ true
+
+
+
+
+
+ com.google.cloud
+ google-cloud-appoptimize
+ 0.1.0
+
+
+ com.google.api.grpc
+ grpc-google-cloud-appoptimize-v1beta
+ 0.1.0
+
+
+ com.google.api.grpc
+ proto-google-cloud-appoptimize-v1beta
+ 0.1.0
+
+
+
+
diff --git a/java-appoptimize/google-cloud-appoptimize/pom.xml b/java-appoptimize/google-cloud-appoptimize/pom.xml
new file mode 100644
index 000000000000..95aa221cfcfd
--- /dev/null
+++ b/java-appoptimize/google-cloud-appoptimize/pom.xml
@@ -0,0 +1,115 @@
+
+
+ 4.0.0
+ com.google.cloud
+ google-cloud-appoptimize
+ 0.1.0
+ jar
+ Google App Optimize API
+ App Optimize API The App Optimize API provides developers and platform teams with tools to monitor, analyze, and improve the performance and cost-efficiency of their cloud applications.
+
+ com.google.cloud
+ google-cloud-appoptimize-parent
+ 0.1.0
+
+
+ google-cloud-appoptimize
+
+
+
+ io.grpc
+ grpc-api
+
+
+ io.grpc
+ grpc-stub
+
+
+ io.grpc
+ grpc-protobuf
+
+
+ com.google.api
+ api-common
+
+
+ com.google.protobuf
+ protobuf-java
+
+
+ com.google.api.grpc
+ proto-google-common-protos
+
+
+
+ com.google.api.grpc
+ proto-google-cloud-appoptimize-v1beta
+
+
+ com.google.guava
+ guava
+
+
+ com.google.api
+ gax
+
+
+ com.google.api
+ gax-grpc
+
+
+ com.google.api
+ gax-httpjson
+
+
+ com.google.api.grpc
+ proto-google-iam-v1
+
+
+ org.threeten
+ threetenbp
+
+
+
+
+ com.google.api.grpc
+ grpc-google-common-protos
+ test
+
+
+ com.google.api.grpc
+ grpc-google-iam-v1
+ test
+
+
+ junit
+ junit
+ test
+
+
+
+ com.google.api.grpc
+ grpc-google-cloud-appoptimize-v1beta
+ test
+
+
+
+ com.google.api
+ gax
+ testlib
+ test
+
+
+ com.google.api
+ gax-grpc
+ testlib
+ test
+
+
+ com.google.api
+ gax-httpjson
+ testlib
+ test
+
+
+
diff --git a/java-appoptimize/google-cloud-appoptimize/src/main/java/com/google/cloud/appoptimize/v1beta/AppOptimizeClient.java b/java-appoptimize/google-cloud-appoptimize/src/main/java/com/google/cloud/appoptimize/v1beta/AppOptimizeClient.java
new file mode 100644
index 000000000000..e0be5f8de406
--- /dev/null
+++ b/java-appoptimize/google-cloud-appoptimize/src/main/java/com/google/cloud/appoptimize/v1beta/AppOptimizeClient.java
@@ -0,0 +1,1515 @@
+/*
+ * Copyright 2026 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.cloud.appoptimize.v1beta;
+
+import com.google.api.core.ApiFuture;
+import com.google.api.core.ApiFutures;
+import com.google.api.core.BetaApi;
+import com.google.api.gax.core.BackgroundResource;
+import com.google.api.gax.httpjson.longrunning.OperationsClient;
+import com.google.api.gax.longrunning.OperationFuture;
+import com.google.api.gax.paging.AbstractFixedSizeCollection;
+import com.google.api.gax.paging.AbstractPage;
+import com.google.api.gax.paging.AbstractPagedListResponse;
+import com.google.api.gax.rpc.OperationCallable;
+import com.google.api.gax.rpc.PageContext;
+import com.google.api.gax.rpc.UnaryCallable;
+import com.google.cloud.appoptimize.v1beta.stub.AppOptimizeStub;
+import com.google.cloud.appoptimize.v1beta.stub.AppOptimizeStubSettings;
+import com.google.cloud.location.GetLocationRequest;
+import com.google.cloud.location.ListLocationsRequest;
+import com.google.cloud.location.ListLocationsResponse;
+import com.google.cloud.location.Location;
+import com.google.common.util.concurrent.MoreExecutors;
+import com.google.longrunning.Operation;
+import com.google.protobuf.Empty;
+import com.google.protobuf.ListValue;
+import java.io.IOException;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import javax.annotation.Generated;
+
+// AUTO-GENERATED DOCUMENTATION AND CLASS.
+/**
+ * Service Description: Service for managing and querying optimization reports.
+ *
+ * This class provides the ability to make remote calls to the backing service through method
+ * calls that map to API methods. Sample code to get started:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ReportName name = ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]");
+ * Report response = appOptimizeClient.getReport(name);
+ * }
+ * }
+ *
+ * Note: close() needs to be called on the AppOptimizeClient object to clean up resources such as
+ * threads. In the example above, try-with-resources is used, which automatically calls close().
+ *
+ *
+ * Methods
+ *
+ * | Method |
+ * Description |
+ * Method Variants |
+ *
+ *
+ * CreateReport |
+ * Creates a new report.
+ * This initiates a long-running operation that, upon completion, results in a report resource. Once the report is created, its results can be read via `ReadReport`. |
+ *
+ * Request object method variants only take one parameter, a request object, which must be constructed before the call.
+ *
+ * Methods that return long-running operations have "Async" method variants that return `OperationFuture`, which is used to track polling of the service.
+ *
+ * createReportAsync(LocationName parent, Report report, String reportId)
+ * createReportAsync(String parent, Report report, String reportId)
+ *
+ * Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.
+ *
+ * |
+ *
+ *
+ * GetReport |
+ * Retrieves the details of a report configuration. |
+ *
+ * Request object method variants only take one parameter, a request object, which must be constructed before the call.
+ *
+ * "Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.
+ *
+ * Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.
+ *
+ * getReportCallable()
+ *
+ * |
+ *
+ *
+ * ListReports |
+ * Lists reports within a given project. |
+ *
+ * Request object method variants only take one parameter, a request object, which must be constructed before the call.
+ *
+ * "Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.
+ *
+ * Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.
+ *
+ * |
+ *
+ *
+ * DeleteReport |
+ * Deletes the specified report. |
+ *
+ * Request object method variants only take one parameter, a request object, which must be constructed before the call.
+ *
+ * "Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.
+ *
+ * Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.
+ *
+ * |
+ *
+ *
+ * ReadReport |
+ * Reads data within a specified report. |
+ *
+ * Request object method variants only take one parameter, a request object, which must be constructed before the call.
+ *
+ * "Flattened" method variants have converted the fields of the request object into function parameters to enable multiple ways to call the same method.
+ *
+ * Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.
+ *
+ * |
+ *
+ *
+ * ListLocations |
+ * Lists information about the supported locations for this service.
+ * This method lists locations based on the resource scope provided inthe [ListLocationsRequest.name] field:
+ * * **Global locations**: If `name` is empty, the method lists thepublic locations available to all projects. * **Project-specificlocations**: If `name` follows the format`projects/{project}`, the method lists locations visible to thatspecific project. This includes public, private, or otherproject-specific locations enabled for the project.
+ * For gRPC and client library implementations, the resource name ispassed as the `name` field. For direct service calls, the resourcename isincorporated into the request path based on the specific serviceimplementation and version. |
+ *
+ * Request object method variants only take one parameter, a request object, which must be constructed before the call.
+ *
+ * Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.
+ *
+ * |
+ *
+ *
+ * GetLocation |
+ * Gets information about a location. |
+ *
+ * Request object method variants only take one parameter, a request object, which must be constructed before the call.
+ *
+ * Callable method variants take no parameters and return an immutable API callable object, which can be used to initiate calls to the service.
+ *
+ * |
+ *
+ *
+ *
+ * See the individual methods for example code.
+ *
+ *
Many parameters require resource names to be formatted in a particular way. To assist with
+ * these names, this class includes a format method for each type of name, and additionally a parse
+ * method to extract the individual identifiers contained within names that are returned.
+ *
+ *
This class can be customized by passing in a custom instance of AppOptimizeSettings to
+ * create(). For example:
+ *
+ *
To customize credentials:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * AppOptimizeSettings appOptimizeSettings =
+ * AppOptimizeSettings.newBuilder()
+ * .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials))
+ * .build();
+ * AppOptimizeClient appOptimizeClient = AppOptimizeClient.create(appOptimizeSettings);
+ * }
+ *
+ * To customize the endpoint:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * AppOptimizeSettings appOptimizeSettings =
+ * AppOptimizeSettings.newBuilder().setEndpoint(myEndpoint).build();
+ * AppOptimizeClient appOptimizeClient = AppOptimizeClient.create(appOptimizeSettings);
+ * }
+ *
+ * To use REST (HTTP1.1/JSON) transport (instead of gRPC) for sending and receiving requests over
+ * the wire:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * AppOptimizeSettings appOptimizeSettings = AppOptimizeSettings.newHttpJsonBuilder().build();
+ * AppOptimizeClient appOptimizeClient = AppOptimizeClient.create(appOptimizeSettings);
+ * }
+ *
+ * Please refer to the GitHub repository's samples for more quickstart code snippets.
+ */
+@BetaApi
+@Generated("by gapic-generator-java")
+public class AppOptimizeClient implements BackgroundResource {
+ private final AppOptimizeSettings settings;
+ private final AppOptimizeStub stub;
+ private final OperationsClient httpJsonOperationsClient;
+ private final com.google.longrunning.OperationsClient operationsClient;
+
+ /** Constructs an instance of AppOptimizeClient with default settings. */
+ public static final AppOptimizeClient create() throws IOException {
+ return create(AppOptimizeSettings.newBuilder().build());
+ }
+
+ /**
+ * Constructs an instance of AppOptimizeClient, using the given settings. The channels are created
+ * based on the settings passed in, or defaults for any settings that are not set.
+ */
+ public static final AppOptimizeClient create(AppOptimizeSettings settings) throws IOException {
+ return new AppOptimizeClient(settings);
+ }
+
+ /**
+ * Constructs an instance of AppOptimizeClient, using the given stub for making calls. This is for
+ * advanced usage - prefer using create(AppOptimizeSettings).
+ */
+ public static final AppOptimizeClient create(AppOptimizeStub stub) {
+ return new AppOptimizeClient(stub);
+ }
+
+ /**
+ * Constructs an instance of AppOptimizeClient, using the given settings. This is protected so
+ * that it is easy to make a subclass, but otherwise, the static factory methods should be
+ * preferred.
+ */
+ protected AppOptimizeClient(AppOptimizeSettings settings) throws IOException {
+ this.settings = settings;
+ this.stub = ((AppOptimizeStubSettings) settings.getStubSettings()).createStub();
+ this.operationsClient =
+ com.google.longrunning.OperationsClient.create(this.stub.getOperationsStub());
+ this.httpJsonOperationsClient = OperationsClient.create(this.stub.getHttpJsonOperationsStub());
+ }
+
+ protected AppOptimizeClient(AppOptimizeStub stub) {
+ this.settings = null;
+ this.stub = stub;
+ this.operationsClient =
+ com.google.longrunning.OperationsClient.create(this.stub.getOperationsStub());
+ this.httpJsonOperationsClient = OperationsClient.create(this.stub.getHttpJsonOperationsStub());
+ }
+
+ public final AppOptimizeSettings getSettings() {
+ return settings;
+ }
+
+ public AppOptimizeStub getStub() {
+ return stub;
+ }
+
+ /**
+ * Returns the OperationsClient that can be used to query the status of a long-running operation
+ * returned by another API method call.
+ */
+ public final com.google.longrunning.OperationsClient getOperationsClient() {
+ return operationsClient;
+ }
+
+ /**
+ * Returns the OperationsClient that can be used to query the status of a long-running operation
+ * returned by another API method call.
+ */
+ @BetaApi
+ public final OperationsClient getHttpJsonOperationsClient() {
+ return httpJsonOperationsClient;
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Creates a new report.
+ *
+ *
This initiates a long-running operation that, upon completion, results in a report resource.
+ * Once the report is created, its results can be read via `ReadReport`.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * LocationName parent = LocationName.of("[PROJECT]", "[LOCATION]");
+ * Report report = Report.newBuilder().build();
+ * String reportId = "reportId-427040401";
+ * Report response = appOptimizeClient.createReportAsync(parent, report, reportId).get();
+ * }
+ * }
+ *
+ * @param parent Required. The parent Google Cloud project that will own the report.
+ * This value does not define the scope of the report data. See `Report.scope` for setting
+ * the data scope.
+ *
Format: `projects/{project}/locations/{location}`.
+ * @param report Required. The report resource to create.
+ * @param reportId Required. The ID to use for this report. This ID must be unique within the
+ * parent project and should comply with RFC 1034 restrictions (letters, numbers, and hyphen,
+ * with the first character a letter, the last a letter or a number, and a 63 character
+ * maximum).
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final OperationFuture createReportAsync(
+ LocationName parent, Report report, String reportId) {
+ CreateReportRequest request =
+ CreateReportRequest.newBuilder()
+ .setParent(parent == null ? null : parent.toString())
+ .setReport(report)
+ .setReportId(reportId)
+ .build();
+ return createReportAsync(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Creates a new report.
+ *
+ * This initiates a long-running operation that, upon completion, results in a report resource.
+ * Once the report is created, its results can be read via `ReadReport`.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * String parent = LocationName.of("[PROJECT]", "[LOCATION]").toString();
+ * Report report = Report.newBuilder().build();
+ * String reportId = "reportId-427040401";
+ * Report response = appOptimizeClient.createReportAsync(parent, report, reportId).get();
+ * }
+ * }
+ *
+ * @param parent Required. The parent Google Cloud project that will own the report.
+ * This value does not define the scope of the report data. See `Report.scope` for setting
+ * the data scope.
+ *
Format: `projects/{project}/locations/{location}`.
+ * @param report Required. The report resource to create.
+ * @param reportId Required. The ID to use for this report. This ID must be unique within the
+ * parent project and should comply with RFC 1034 restrictions (letters, numbers, and hyphen,
+ * with the first character a letter, the last a letter or a number, and a 63 character
+ * maximum).
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final OperationFuture createReportAsync(
+ String parent, Report report, String reportId) {
+ CreateReportRequest request =
+ CreateReportRequest.newBuilder()
+ .setParent(parent)
+ .setReport(report)
+ .setReportId(reportId)
+ .build();
+ return createReportAsync(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Creates a new report.
+ *
+ * This initiates a long-running operation that, upon completion, results in a report resource.
+ * Once the report is created, its results can be read via `ReadReport`.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * CreateReportRequest request =
+ * CreateReportRequest.newBuilder()
+ * .setParent(LocationName.of("[PROJECT]", "[LOCATION]").toString())
+ * .setReportId("reportId-427040401")
+ * .setReport(Report.newBuilder().build())
+ * .build();
+ * Report response = appOptimizeClient.createReportAsync(request).get();
+ * }
+ * }
+ *
+ * @param request The request object containing all of the parameters for the API call.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final OperationFuture createReportAsync(
+ CreateReportRequest request) {
+ return createReportOperationCallable().futureCall(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Creates a new report.
+ *
+ * This initiates a long-running operation that, upon completion, results in a report resource.
+ * Once the report is created, its results can be read via `ReadReport`.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * CreateReportRequest request =
+ * CreateReportRequest.newBuilder()
+ * .setParent(LocationName.of("[PROJECT]", "[LOCATION]").toString())
+ * .setReportId("reportId-427040401")
+ * .setReport(Report.newBuilder().build())
+ * .build();
+ * OperationFuture future =
+ * appOptimizeClient.createReportOperationCallable().futureCall(request);
+ * // Do something.
+ * Report response = future.get();
+ * }
+ * }
+ */
+ public final OperationCallable
+ createReportOperationCallable() {
+ return stub.createReportOperationCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Creates a new report.
+ *
+ * This initiates a long-running operation that, upon completion, results in a report resource.
+ * Once the report is created, its results can be read via `ReadReport`.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * CreateReportRequest request =
+ * CreateReportRequest.newBuilder()
+ * .setParent(LocationName.of("[PROJECT]", "[LOCATION]").toString())
+ * .setReportId("reportId-427040401")
+ * .setReport(Report.newBuilder().build())
+ * .build();
+ * ApiFuture future = appOptimizeClient.createReportCallable().futureCall(request);
+ * // Do something.
+ * Operation response = future.get();
+ * }
+ * }
+ */
+ public final UnaryCallable createReportCallable() {
+ return stub.createReportCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Retrieves the details of a report configuration.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ReportName name = ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]");
+ * Report response = appOptimizeClient.getReport(name);
+ * }
+ * }
+ *
+ * @param name Required. The name of the report to retrieve.
+ * Format: `projects/{project}/locations/{location}/reports/{report_id}`.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final Report getReport(ReportName name) {
+ GetReportRequest request =
+ GetReportRequest.newBuilder().setName(name == null ? null : name.toString()).build();
+ return getReport(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Retrieves the details of a report configuration.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * String name = ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString();
+ * Report response = appOptimizeClient.getReport(name);
+ * }
+ * }
+ *
+ * @param name Required. The name of the report to retrieve.
+ * Format: `projects/{project}/locations/{location}/reports/{report_id}`.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final Report getReport(String name) {
+ GetReportRequest request = GetReportRequest.newBuilder().setName(name).build();
+ return getReport(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Retrieves the details of a report configuration.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * GetReportRequest request =
+ * GetReportRequest.newBuilder()
+ * .setName(ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString())
+ * .build();
+ * Report response = appOptimizeClient.getReport(request);
+ * }
+ * }
+ *
+ * @param request The request object containing all of the parameters for the API call.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final Report getReport(GetReportRequest request) {
+ return getReportCallable().call(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Retrieves the details of a report configuration.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * GetReportRequest request =
+ * GetReportRequest.newBuilder()
+ * .setName(ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString())
+ * .build();
+ * ApiFuture future = appOptimizeClient.getReportCallable().futureCall(request);
+ * // Do something.
+ * Report response = future.get();
+ * }
+ * }
+ */
+ public final UnaryCallable getReportCallable() {
+ return stub.getReportCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Lists reports within a given project.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * LocationName parent = LocationName.of("[PROJECT]", "[LOCATION]");
+ * for (Report element : appOptimizeClient.listReports(parent).iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ *
+ * @param parent Required. The parent project whose reports are to be listed.
+ * Format: `projects/{project}/locations/{location}`.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final ListReportsPagedResponse listReports(LocationName parent) {
+ ListReportsRequest request =
+ ListReportsRequest.newBuilder()
+ .setParent(parent == null ? null : parent.toString())
+ .build();
+ return listReports(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Lists reports within a given project.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * String parent = LocationName.of("[PROJECT]", "[LOCATION]").toString();
+ * for (Report element : appOptimizeClient.listReports(parent).iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ *
+ * @param parent Required. The parent project whose reports are to be listed.
+ * Format: `projects/{project}/locations/{location}`.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final ListReportsPagedResponse listReports(String parent) {
+ ListReportsRequest request = ListReportsRequest.newBuilder().setParent(parent).build();
+ return listReports(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Lists reports within a given project.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ListReportsRequest request =
+ * ListReportsRequest.newBuilder()
+ * .setParent(LocationName.of("[PROJECT]", "[LOCATION]").toString())
+ * .setPageSize(883849137)
+ * .setPageToken("pageToken873572522")
+ * .build();
+ * for (Report element : appOptimizeClient.listReports(request).iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ *
+ * @param request The request object containing all of the parameters for the API call.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final ListReportsPagedResponse listReports(ListReportsRequest request) {
+ return listReportsPagedCallable().call(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Lists reports within a given project.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ListReportsRequest request =
+ * ListReportsRequest.newBuilder()
+ * .setParent(LocationName.of("[PROJECT]", "[LOCATION]").toString())
+ * .setPageSize(883849137)
+ * .setPageToken("pageToken873572522")
+ * .build();
+ * ApiFuture future = appOptimizeClient.listReportsPagedCallable().futureCall(request);
+ * // Do something.
+ * for (Report element : future.get().iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ */
+ public final UnaryCallable
+ listReportsPagedCallable() {
+ return stub.listReportsPagedCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Lists reports within a given project.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ListReportsRequest request =
+ * ListReportsRequest.newBuilder()
+ * .setParent(LocationName.of("[PROJECT]", "[LOCATION]").toString())
+ * .setPageSize(883849137)
+ * .setPageToken("pageToken873572522")
+ * .build();
+ * while (true) {
+ * ListReportsResponse response = appOptimizeClient.listReportsCallable().call(request);
+ * for (Report element : response.getReportsList()) {
+ * // doThingsWith(element);
+ * }
+ * String nextPageToken = response.getNextPageToken();
+ * if (!Strings.isNullOrEmpty(nextPageToken)) {
+ * request = request.toBuilder().setPageToken(nextPageToken).build();
+ * } else {
+ * break;
+ * }
+ * }
+ * }
+ * }
+ */
+ public final UnaryCallable listReportsCallable() {
+ return stub.listReportsCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Deletes the specified report.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ReportName name = ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]");
+ * appOptimizeClient.deleteReport(name);
+ * }
+ * }
+ *
+ * @param name Required. The name of the report to delete.
+ * Format: `projects/{project}/locations/{location}/reports/{report_id}`.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final void deleteReport(ReportName name) {
+ DeleteReportRequest request =
+ DeleteReportRequest.newBuilder().setName(name == null ? null : name.toString()).build();
+ deleteReport(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Deletes the specified report.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * String name = ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString();
+ * appOptimizeClient.deleteReport(name);
+ * }
+ * }
+ *
+ * @param name Required. The name of the report to delete.
+ * Format: `projects/{project}/locations/{location}/reports/{report_id}`.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final void deleteReport(String name) {
+ DeleteReportRequest request = DeleteReportRequest.newBuilder().setName(name).build();
+ deleteReport(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Deletes the specified report.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * DeleteReportRequest request =
+ * DeleteReportRequest.newBuilder()
+ * .setName(ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString())
+ * .setAllowMissing(true)
+ * .build();
+ * appOptimizeClient.deleteReport(request);
+ * }
+ * }
+ *
+ * @param request The request object containing all of the parameters for the API call.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final void deleteReport(DeleteReportRequest request) {
+ deleteReportCallable().call(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Deletes the specified report.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * DeleteReportRequest request =
+ * DeleteReportRequest.newBuilder()
+ * .setName(ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString())
+ * .setAllowMissing(true)
+ * .build();
+ * ApiFuture future = appOptimizeClient.deleteReportCallable().futureCall(request);
+ * // Do something.
+ * future.get();
+ * }
+ * }
+ */
+ public final UnaryCallable deleteReportCallable() {
+ return stub.deleteReportCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Reads data within a specified report.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ReportName name = ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]");
+ * for (ListValue element : appOptimizeClient.readReport(name).iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ *
+ * @param name Required. The resource name of the report to query.
+ * Format: `projects/{project}/locations/{location}/reports/{report_id}`.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final ReadReportPagedResponse readReport(ReportName name) {
+ ReadReportRequest request =
+ ReadReportRequest.newBuilder().setName(name == null ? null : name.toString()).build();
+ return readReport(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Reads data within a specified report.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * String name = ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString();
+ * for (ListValue element : appOptimizeClient.readReport(name).iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ *
+ * @param name Required. The resource name of the report to query.
+ * Format: `projects/{project}/locations/{location}/reports/{report_id}`.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final ReadReportPagedResponse readReport(String name) {
+ ReadReportRequest request = ReadReportRequest.newBuilder().setName(name).build();
+ return readReport(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Reads data within a specified report.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ReadReportRequest request =
+ * ReadReportRequest.newBuilder()
+ * .setName(ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString())
+ * .setPageSize(883849137)
+ * .setPageToken("pageToken873572522")
+ * .build();
+ * for (ListValue element : appOptimizeClient.readReport(request).iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ *
+ * @param request The request object containing all of the parameters for the API call.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final ReadReportPagedResponse readReport(ReadReportRequest request) {
+ return readReportPagedCallable().call(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Reads data within a specified report.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ReadReportRequest request =
+ * ReadReportRequest.newBuilder()
+ * .setName(ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString())
+ * .setPageSize(883849137)
+ * .setPageToken("pageToken873572522")
+ * .build();
+ * ApiFuture future = appOptimizeClient.readReportPagedCallable().futureCall(request);
+ * // Do something.
+ * for (ListValue element : future.get().iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ */
+ public final UnaryCallable readReportPagedCallable() {
+ return stub.readReportPagedCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Reads data within a specified report.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ReadReportRequest request =
+ * ReadReportRequest.newBuilder()
+ * .setName(ReportName.of("[PROJECT]", "[LOCATION]", "[REPORT]").toString())
+ * .setPageSize(883849137)
+ * .setPageToken("pageToken873572522")
+ * .build();
+ * while (true) {
+ * ReadReportResponse response = appOptimizeClient.readReportCallable().call(request);
+ * for (ListValue element : response.getRowsList()) {
+ * // doThingsWith(element);
+ * }
+ * String nextPageToken = response.getNextPageToken();
+ * if (!Strings.isNullOrEmpty(nextPageToken)) {
+ * request = request.toBuilder().setPageToken(nextPageToken).build();
+ * } else {
+ * break;
+ * }
+ * }
+ * }
+ * }
+ */
+ public final UnaryCallable readReportCallable() {
+ return stub.readReportCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Lists information about the supported locations for this service.
+ *
+ * This method lists locations based on the resource scope provided inthe
+ * [ListLocationsRequest.name] field:
+ *
+ *
* **Global locations**: If `name` is empty, the method lists thepublic
+ * locations available to all projects. * **Project-specificlocations**: If
+ * `name` follows the format`projects/{project}`, the method lists locations visible to
+ * thatspecific project. This includes public, private, or otherproject-specific locations enabled
+ * for the project.
+ *
+ *
For gRPC and client library implementations, the resource name ispassed as the `name` field.
+ * For direct service calls, the resourcename isincorporated into the request path based on the
+ * specific serviceimplementation and version.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ListLocationsRequest request =
+ * ListLocationsRequest.newBuilder()
+ * .setName("name3373707")
+ * .setFilter("filter-1274492040")
+ * .setPageSize(883849137)
+ * .setPageToken("pageToken873572522")
+ * .build();
+ * for (Location element : appOptimizeClient.listLocations(request).iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ *
+ * @param request The request object containing all of the parameters for the API call.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final ListLocationsPagedResponse listLocations(ListLocationsRequest request) {
+ return listLocationsPagedCallable().call(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Lists information about the supported locations for this service.
+ *
+ * This method lists locations based on the resource scope provided inthe
+ * [ListLocationsRequest.name] field:
+ *
+ *
* **Global locations**: If `name` is empty, the method lists thepublic
+ * locations available to all projects. * **Project-specificlocations**: If
+ * `name` follows the format`projects/{project}`, the method lists locations visible to
+ * thatspecific project. This includes public, private, or otherproject-specific locations enabled
+ * for the project.
+ *
+ *
For gRPC and client library implementations, the resource name ispassed as the `name` field.
+ * For direct service calls, the resourcename isincorporated into the request path based on the
+ * specific serviceimplementation and version.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ListLocationsRequest request =
+ * ListLocationsRequest.newBuilder()
+ * .setName("name3373707")
+ * .setFilter("filter-1274492040")
+ * .setPageSize(883849137)
+ * .setPageToken("pageToken873572522")
+ * .build();
+ * ApiFuture future =
+ * appOptimizeClient.listLocationsPagedCallable().futureCall(request);
+ * // Do something.
+ * for (Location element : future.get().iterateAll()) {
+ * // doThingsWith(element);
+ * }
+ * }
+ * }
+ */
+ public final UnaryCallable
+ listLocationsPagedCallable() {
+ return stub.listLocationsPagedCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Lists information about the supported locations for this service.
+ *
+ * This method lists locations based on the resource scope provided inthe
+ * [ListLocationsRequest.name] field:
+ *
+ *
* **Global locations**: If `name` is empty, the method lists thepublic
+ * locations available to all projects. * **Project-specificlocations**: If
+ * `name` follows the format`projects/{project}`, the method lists locations visible to
+ * thatspecific project. This includes public, private, or otherproject-specific locations enabled
+ * for the project.
+ *
+ *
For gRPC and client library implementations, the resource name ispassed as the `name` field.
+ * For direct service calls, the resourcename isincorporated into the request path based on the
+ * specific serviceimplementation and version.
+ *
+ *
Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * ListLocationsRequest request =
+ * ListLocationsRequest.newBuilder()
+ * .setName("name3373707")
+ * .setFilter("filter-1274492040")
+ * .setPageSize(883849137)
+ * .setPageToken("pageToken873572522")
+ * .build();
+ * while (true) {
+ * ListLocationsResponse response = appOptimizeClient.listLocationsCallable().call(request);
+ * for (Location element : response.getLocationsList()) {
+ * // doThingsWith(element);
+ * }
+ * String nextPageToken = response.getNextPageToken();
+ * if (!Strings.isNullOrEmpty(nextPageToken)) {
+ * request = request.toBuilder().setPageToken(nextPageToken).build();
+ * } else {
+ * break;
+ * }
+ * }
+ * }
+ * }
+ */
+ public final UnaryCallable listLocationsCallable() {
+ return stub.listLocationsCallable();
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Gets information about a location.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * GetLocationRequest request = GetLocationRequest.newBuilder().setName("name3373707").build();
+ * Location response = appOptimizeClient.getLocation(request);
+ * }
+ * }
+ *
+ * @param request The request object containing all of the parameters for the API call.
+ * @throws com.google.api.gax.rpc.ApiException if the remote call fails
+ */
+ public final Location getLocation(GetLocationRequest request) {
+ return getLocationCallable().call(request);
+ }
+
+ // AUTO-GENERATED DOCUMENTATION AND METHOD.
+ /**
+ * Gets information about a location.
+ *
+ * Sample code:
+ *
+ *
{@code
+ * // This snippet has been automatically generated and should be regarded as a code template only.
+ * // It will require modifications to work:
+ * // - It may require correct/in-range values for request initialization.
+ * // - It may require specifying regional endpoints when creating the service client as shown in
+ * // https://cloud.google.com/java/docs/setup#configure_endpoints_for_the_client_library
+ * try (AppOptimizeClient appOptimizeClient = AppOptimizeClient.create()) {
+ * GetLocationRequest request = GetLocationRequest.newBuilder().setName("name3373707").build();
+ * ApiFuture future = appOptimizeClient.getLocationCallable().futureCall(request);
+ * // Do something.
+ * Location response = future.get();
+ * }
+ * }
+ */
+ public final UnaryCallable getLocationCallable() {
+ return stub.getLocationCallable();
+ }
+
+ @Override
+ public final void close() {
+ stub.close();
+ }
+
+ @Override
+ public void shutdown() {
+ stub.shutdown();
+ }
+
+ @Override
+ public boolean isShutdown() {
+ return stub.isShutdown();
+ }
+
+ @Override
+ public boolean isTerminated() {
+ return stub.isTerminated();
+ }
+
+ @Override
+ public void shutdownNow() {
+ stub.shutdownNow();
+ }
+
+ @Override
+ public boolean awaitTermination(long duration, TimeUnit unit) throws InterruptedException {
+ return stub.awaitTermination(duration, unit);
+ }
+
+ public static class ListReportsPagedResponse
+ extends AbstractPagedListResponse<
+ ListReportsRequest,
+ ListReportsResponse,
+ Report,
+ ListReportsPage,
+ ListReportsFixedSizeCollection> {
+
+ public static ApiFuture createAsync(
+ PageContext context,
+ ApiFuture futureResponse) {
+ ApiFuture futurePage =
+ ListReportsPage.createEmptyPage().createPageAsync(context, futureResponse);
+ return ApiFutures.transform(
+ futurePage, input -> new ListReportsPagedResponse(input), MoreExecutors.directExecutor());
+ }
+
+ private ListReportsPagedResponse(ListReportsPage page) {
+ super(page, ListReportsFixedSizeCollection.createEmptyCollection());
+ }
+ }
+
+ public static class ListReportsPage
+ extends AbstractPage {
+
+ private ListReportsPage(
+ PageContext context,
+ ListReportsResponse response) {
+ super(context, response);
+ }
+
+ private static ListReportsPage createEmptyPage() {
+ return new ListReportsPage(null, null);
+ }
+
+ @Override
+ protected ListReportsPage createPage(
+ PageContext context,
+ ListReportsResponse response) {
+ return new ListReportsPage(context, response);
+ }
+
+ @Override
+ public ApiFuture createPageAsync(
+ PageContext context,
+ ApiFuture futureResponse) {
+ return super.createPageAsync(context, futureResponse);
+ }
+ }
+
+ public static class ListReportsFixedSizeCollection
+ extends AbstractFixedSizeCollection<
+ ListReportsRequest,
+ ListReportsResponse,
+ Report,
+ ListReportsPage,
+ ListReportsFixedSizeCollection> {
+
+ private ListReportsFixedSizeCollection(List pages, int collectionSize) {
+ super(pages, collectionSize);
+ }
+
+ private static ListReportsFixedSizeCollection createEmptyCollection() {
+ return new ListReportsFixedSizeCollection(null, 0);
+ }
+
+ @Override
+ protected ListReportsFixedSizeCollection createCollection(
+ List pages, int collectionSize) {
+ return new ListReportsFixedSizeCollection(pages, collectionSize);
+ }
+ }
+
+ public static class ReadReportPagedResponse
+ extends AbstractPagedListResponse<
+ ReadReportRequest,
+ ReadReportResponse,
+ ListValue,
+ ReadReportPage,
+ ReadReportFixedSizeCollection> {
+
+ public static ApiFuture createAsync(
+ PageContext context,
+ ApiFuture futureResponse) {
+ ApiFuture futurePage =
+ ReadReportPage.createEmptyPage().createPageAsync(context, futureResponse);
+ return ApiFutures.transform(
+ futurePage, input -> new ReadReportPagedResponse(input), MoreExecutors.directExecutor());
+ }
+
+ private ReadReportPagedResponse(ReadReportPage page) {
+ super(page, ReadReportFixedSizeCollection.createEmptyCollection());
+ }
+ }
+
+ public static class ReadReportPage
+ extends AbstractPage {
+
+ private ReadReportPage(
+ PageContext context,
+ ReadReportResponse response) {
+ super(context, response);
+ }
+
+ private static ReadReportPage createEmptyPage() {
+ return new ReadReportPage(null, null);
+ }
+
+ @Override
+ protected ReadReportPage createPage(
+ PageContext context,
+ ReadReportResponse response) {
+ return new ReadReportPage(context, response);
+ }
+
+ @Override
+ public ApiFuture createPageAsync(
+ PageContext context,
+ ApiFuture futureResponse) {
+ return super.createPageAsync(context, futureResponse);
+ }
+ }
+
+ public static class ReadReportFixedSizeCollection
+ extends AbstractFixedSizeCollection<
+ ReadReportRequest,
+ ReadReportResponse,
+ ListValue,
+ ReadReportPage,
+ ReadReportFixedSizeCollection> {
+
+ private ReadReportFixedSizeCollection(List pages, int collectionSize) {
+ super(pages, collectionSize);
+ }
+
+ private static ReadReportFixedSizeCollection createEmptyCollection() {
+ return new ReadReportFixedSizeCollection(null, 0);
+ }
+
+ @Override
+ protected ReadReportFixedSizeCollection createCollection(
+ List pages, int collectionSize) {
+ return new ReadReportFixedSizeCollection(pages, collectionSize);
+ }
+ }
+
+ public static class ListLocationsPagedResponse
+ extends AbstractPagedListResponse<
+ ListLocationsRequest,
+ ListLocationsResponse,
+ Location,
+ ListLocationsPage,
+ ListLocationsFixedSizeCollection> {
+
+ public static ApiFuture createAsync(
+ PageContext context,
+ ApiFuture futureResponse) {
+ ApiFuture futurePage =
+ ListLocationsPage.createEmptyPage().createPageAsync(context, futureResponse);
+ return ApiFutures.transform(
+ futurePage,
+ input -> new ListLocationsPagedResponse(input),
+ MoreExecutors.directExecutor());
+ }
+
+ private ListLocationsPagedResponse(ListLocationsPage page) {
+ super(page, ListLocationsFixedSizeCollection.createEmptyCollection());
+ }
+ }
+
+ public static class ListLocationsPage
+ extends AbstractPage<
+ ListLocationsRequest, ListLocationsResponse, Location, ListLocationsPage> {
+
+ private ListLocationsPage(
+ PageContext context,
+ ListLocationsResponse response) {
+ super(context, response);
+ }
+
+ private static ListLocationsPage createEmptyPage() {
+ return new ListLocationsPage(null, null);
+ }
+
+ @Override
+ protected ListLocationsPage createPage(
+ PageContext context,
+ ListLocationsResponse response) {
+ return new ListLocationsPage(context, response);
+ }
+
+ @Override
+ public ApiFuture createPageAsync(
+ PageContext