This is an automated email from the ASF dual-hosted git repository.
acosentino pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new fbd9c5d904f1 CAMEL-23034 - Generalize Google services authentication
with common module (#21547)
fbd9c5d904f1 is described below
commit fbd9c5d904f1c2c1372ffccb3f994702a581896b
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Feb 20 11:11:22 2026 +0100
CAMEL-23034 - Generalize Google services authentication with common module
(#21547)
Signed-off-by: Andrea Cosentino <[email protected]>
---
bom/camel-bom/pom.xml | 5 +
catalog/camel-allcomponents/pom.xml | 5 +
.../pom.xml | 59 +++--
.../services/org/apache/camel/other.properties | 7 +
.../src/generated/resources/google-common.json | 15 ++
.../google/common/GoogleCommonConfiguration.java | 94 ++++++++
.../google/common/GoogleCredentialsHelper.java | 264 +++++++++++++++++++++
.../camel-google/camel-google-sheets/pom.xml | 4 +
.../sheets/BatchGoogleSheetsClientFactory.java | 62 ++---
.../google/sheets/GoogleSheetsConfiguration.java | 10 +-
.../camel-google/camel-google-storage/pom.xml | 4 +
.../storage/GoogleCloudStorageConfiguration.java | 4 +-
.../GoogleCloudStorageConnectionFactory.java | 15 +-
components/camel-google/pom.xml | 1 +
coverage/pom.xml | 5 +
.../others/examples/json/google-common.json | 1 +
parent/pom.xml | 5 +
.../camel/maven/packaging/PrepareCatalogMojo.java | 1 +
18 files changed, 485 insertions(+), 76 deletions(-)
diff --git a/bom/camel-bom/pom.xml b/bom/camel-bom/pom.xml
index 65ddf1d20781..0fdae66dc14f 100644
--- a/bom/camel-bom/pom.xml
+++ b/bom/camel-bom/pom.xml
@@ -932,6 +932,11 @@
<artifactId>camel-google-calendar</artifactId>
<version>4.19.0-SNAPSHOT</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-google-common</artifactId>
+ <version>4.19.0-SNAPSHOT</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-google-drive</artifactId>
diff --git a/catalog/camel-allcomponents/pom.xml
b/catalog/camel-allcomponents/pom.xml
index bf7e786f80e0..1f7ed5f164f9 100644
--- a/catalog/camel-allcomponents/pom.xml
+++ b/catalog/camel-allcomponents/pom.xml
@@ -797,6 +797,11 @@
<artifactId>camel-google-calendar</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-google-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-google-drive</artifactId>
diff --git a/components/camel-google/camel-google-storage/pom.xml
b/components/camel-google/camel-google-common/pom.xml
similarity index 51%
copy from components/camel-google/camel-google-storage/pom.xml
copy to components/camel-google/camel-google-common/pom.xml
index 35a7f57dd982..f7eab363c5c8 100644
--- a/components/camel-google/camel-google-storage/pom.xml
+++ b/components/camel-google/camel-google-common/pom.xml
@@ -27,13 +27,14 @@
<version>4.19.0-SNAPSHOT</version>
</parent>
- <artifactId>camel-google-storage</artifactId>
+ <artifactId>camel-google-common</artifactId>
<packaging>jar</packaging>
- <name>Camel :: Google :: Storage</name>
- <description>For storing and accessing data on Google Cloud
Platform</description>
+ <name>Camel :: Google :: Common</name>
+ <description>Camel Google Common utilities for credential
initialization</description>
<properties>
- <camel.surefire.forkTimeout>300</camel.surefire.forkTimeout>
+ <firstVersion>4.19.0</firstVersion>
+ <label>cloud,google</label>
</properties>
<dependencies>
@@ -42,33 +43,53 @@
<artifactId>camel-support</artifactId>
</dependency>
<dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-health</artifactId>
+ <groupId>com.google.auth</groupId>
+ <artifactId>google-auth-library-oauth2-http</artifactId>
+ <version>${google-auth-library-oauth2-http-version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
- <groupId>com.google.cloud</groupId>
- <artifactId>google-cloud-storage</artifactId>
- <version>${google-cloud-storage-version}</version>
+ <groupId>com.google.api-client</groupId>
+ <artifactId>google-api-client</artifactId>
+ <version>${google-api-client-version}</version>
<exclusions>
<exclusion>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
</exclusion>
+ <exclusion>
+ <groupId>com.google.oauth-client</groupId>
+ <artifactId>google-oauth-client</artifactId>
+ </exclusion>
</exclusions>
</dependency>
-
- <!-- for testing -->
<dependency>
- <groupId>org.apache.camel</groupId>
- <artifactId>camel-test-junit5</artifactId>
- <scope>test</scope>
+ <groupId>com.google.oauth-client</groupId>
+ <artifactId>google-oauth-client</artifactId>
+ <version>${google-oauth-client-version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
<dependency>
- <groupId>com.google.cloud</groupId>
- <artifactId>google-cloud-core</artifactId>
- <version>${google-cloud-core-version}</version>
- <scope>test</scope>
- <classifier>tests</classifier>
+ <groupId>com.google.http-client</groupId>
+ <artifactId>google-http-client-jackson2</artifactId>
+ <version>${google-cloud-http-client-version}</version>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.code.findbugs</groupId>
+ <artifactId>jsr305</artifactId>
+ </exclusion>
+ </exclusions>
</dependency>
</dependencies>
+
</project>
diff --git
a/components/camel-google/camel-google-common/src/generated/resources/META-INF/services/org/apache/camel/other.properties
b/components/camel-google/camel-google-common/src/generated/resources/META-INF/services/org/apache/camel/other.properties
new file mode 100644
index 000000000000..4b534cec9013
--- /dev/null
+++
b/components/camel-google/camel-google-common/src/generated/resources/META-INF/services/org/apache/camel/other.properties
@@ -0,0 +1,7 @@
+# Generated by camel build tools - do NOT edit this file!
+name=google-common
+groupId=org.apache.camel
+artifactId=camel-google-common
+version=4.19.0-SNAPSHOT
+projectName=Camel :: Google :: Common
+projectDescription=Camel Google Common utilities for credential initialization
diff --git
a/components/camel-google/camel-google-common/src/generated/resources/google-common.json
b/components/camel-google/camel-google-common/src/generated/resources/google-common.json
new file mode 100644
index 000000000000..64da3caea719
--- /dev/null
+++
b/components/camel-google/camel-google-common/src/generated/resources/google-common.json
@@ -0,0 +1,15 @@
+{
+ "other": {
+ "kind": "other",
+ "name": "google-common",
+ "title": "Google Common",
+ "description": "Camel Google Common utilities for credential
initialization",
+ "deprecated": false,
+ "firstVersion": "4.19.0",
+ "label": "cloud,google",
+ "supportLevel": "Preview",
+ "groupId": "org.apache.camel",
+ "artifactId": "camel-google-common",
+ "version": "4.19.0-SNAPSHOT"
+ }
+}
diff --git
a/components/camel-google/camel-google-common/src/main/java/org/apache/camel/component/google/common/GoogleCommonConfiguration.java
b/components/camel-google/camel-google-common/src/main/java/org/apache/camel/component/google/common/GoogleCommonConfiguration.java
new file mode 100644
index 000000000000..d36e10ac558b
--- /dev/null
+++
b/components/camel-google/camel-google-common/src/main/java/org/apache/camel/component/google/common/GoogleCommonConfiguration.java
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.camel.component.google.common;
+
+import java.util.Collection;
+
+/**
+ * Common configuration interface for all Google components.
+ * <p>
+ * Each Google component's Configuration class should implement this interface
to enable use of the common
+ * {@link GoogleCredentialsHelper} for credential creation.
+ * </p>
+ */
+public interface GoogleCommonConfiguration {
+
+ // ==================== Service Account Credentials ====================
+
+ /**
+ * Service account key file (JSON) for authenticating with Google
services. Can be loaded from classpath, file
+ * system, or http(s) URL. Prefixes: classpath:, file:, http:, https:
+ */
+ String getServiceAccountKey();
+
+ // ==================== OAuth 2.0 Credentials (for legacy API client)
====================
+
+ /**
+ * OAuth 2.0 Client ID for the Google application.
+ */
+ default String getClientId() {
+ return null;
+ }
+
+ /**
+ * OAuth 2.0 Client Secret for the Google application.
+ */
+ default String getClientSecret() {
+ return null;
+ }
+
+ /**
+ * OAuth 2.0 access token. This typically expires after an hour so
refreshToken is recommended for long term usage.
+ */
+ default String getAccessToken() {
+ return null;
+ }
+
+ /**
+ * OAuth 2.0 refresh token. Using this, the component can obtain a new
accessToken whenever the current one expires.
+ */
+ default String getRefreshToken() {
+ return null;
+ }
+
+ // ==================== Domain-wide Delegation ====================
+
+ /**
+ * User email to impersonate for domain-wide delegation with service
account.
+ */
+ default String getDelegate() {
+ return null;
+ }
+
+ // ==================== Scopes ====================
+
+ /**
+ * Returns the OAuth scopes as a collection. Used when creating
credentials.
+ */
+ default Collection<String> getScopesAsList() {
+ return null;
+ }
+
+ // ==================== Authentication Toggle ====================
+
+ /**
+ * Whether to authenticate with Google services. Set to false when using
emulators (e.g., PubSub emulator).
+ */
+ default boolean isAuthenticate() {
+ return true;
+ }
+}
diff --git
a/components/camel-google/camel-google-common/src/main/java/org/apache/camel/component/google/common/GoogleCredentialsHelper.java
b/components/camel-google/camel-google-common/src/main/java/org/apache/camel/component/google/common/GoogleCredentialsHelper.java
new file mode 100644
index 000000000000..f0d06e31aff1
--- /dev/null
+++
b/components/camel-google/camel-google-common/src/main/java/org/apache/camel/component/google/common/GoogleCredentialsHelper.java
@@ -0,0 +1,264 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+package org.apache.camel.component.google.common;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Collection;
+
+import com.google.api.client.auth.oauth2.Credential;
+import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
+import com.google.api.client.http.HttpTransport;
+import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.client.json.JsonFactory;
+import com.google.api.client.json.jackson2.JacksonFactory;
+import com.google.auth.Credentials;
+import com.google.auth.oauth2.GoogleCredentials;
+import com.google.auth.oauth2.ServiceAccountCredentials;
+import org.apache.camel.CamelContext;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.util.ObjectHelper;
+
+/**
+ * Utility class providing centralized credential resolution for Google
services.
+ * <p>
+ * This class handles the common patterns for obtaining Google credentials:
+ * <ul>
+ * <li>Service Account JSON key file (for GCP native clients)</li>
+ * <li>OAuth 2.0 credentials with client ID/secret (for legacy Google API
clients)</li>
+ * <li>Application Default Credentials (ADC) as fallback</li>
+ * </ul>
+ */
+public final class GoogleCredentialsHelper {
+
+ private static final HttpTransport DEFAULT_HTTP_TRANSPORT = new
NetHttpTransport();
+ private static final JsonFactory DEFAULT_JSON_FACTORY = new
JacksonFactory();
+
+ private GoogleCredentialsHelper() {
+ // Utility class - prevent instantiation
+ }
+
+ // ==================== GCP Native Clients (google-cloud-* libraries)
====================
+
+ /**
+ * Gets credentials for GCP native clients (Storage, Firestore, BigQuery,
etc.).
+ * <p>
+ * Resolution order:
+ * <ol>
+ * <li>Service Account key file if provided</li>
+ * <li>Application Default Credentials (ADC) as fallback</li>
+ * </ol>
+ *
+ * @param context the Camel context for resource resolution
+ * @param config the component configuration
+ * @param scopes OAuth scopes to apply (optional, used for service
account)
+ * @return Google credentials for use with GCP native clients
+ * @throws IOException if credentials cannot be loaded
+ */
+ public static Credentials getCredentials(
+ CamelContext context,
+ GoogleCommonConfiguration config,
+ Collection<String> scopes)
+ throws IOException {
+
+ if (!config.isAuthenticate()) {
+ return null;
+ }
+
+ String serviceAccountKey = config.getServiceAccountKey();
+ if (ObjectHelper.isNotEmpty(serviceAccountKey)) {
+ return loadServiceAccountCredentials(context, serviceAccountKey,
scopes, config.getDelegate());
+ }
+
+ // Fall back to Application Default Credentials
+ GoogleCredentials credentials =
GoogleCredentials.getApplicationDefault();
+ if (scopes != null && !scopes.isEmpty()) {
+ credentials = credentials.createScoped(scopes);
+ }
+ return credentials;
+ }
+
+ /**
+ * Gets credentials for GCP native clients using configuration's scopes.
+ *
+ * @param context the Camel context for resource resolution
+ * @param config the component configuration
+ * @return Google credentials for use with GCP native clients
+ * @throws IOException if credentials cannot be loaded
+ */
+ public static Credentials getCredentials(
+ CamelContext context,
+ GoogleCommonConfiguration config)
+ throws IOException {
+ return getCredentials(context, config, config.getScopesAsList());
+ }
+
+ // ==================== Legacy Google API Clients (google-api-client
library) ====================
+
+ /**
+ * Gets OAuth credential for legacy Google API clients (Sheets, Calendar,
Drive, Mail, etc.).
+ * <p>
+ * Resolution order:
+ * <ol>
+ * <li>OAuth 2.0 credentials if clientId and clientSecret are provided</li>
+ * <li>Service Account key file if provided</li>
+ * </ol>
+ *
+ * @param context the Camel context for resource resolution
+ * @param config the component configuration
+ * @param scopes OAuth scopes to apply
+ * @param httpTransport HTTP transport to use (pass null for default)
+ * @param jsonFactory JSON factory to use (pass null for default)
+ * @return Google credential for use with legacy API
clients
+ * @throws IOException if credentials cannot be loaded
+ * @throws RuntimeException if neither OAuth nor service account
credentials are configured
+ */
+ public static Credential getOAuthCredential(
+ CamelContext context,
+ GoogleCommonConfiguration config,
+ Collection<String> scopes,
+ HttpTransport httpTransport,
+ JsonFactory jsonFactory)
+ throws IOException {
+
+ HttpTransport transport = httpTransport != null ? httpTransport :
DEFAULT_HTTP_TRANSPORT;
+ JsonFactory factory = jsonFactory != null ? jsonFactory :
DEFAULT_JSON_FACTORY;
+
+ // Check for OAuth 2.0 credentials first
+ if (hasOAuthCredentials(config)) {
+ return createOAuthCredential(config, scopes, transport, factory);
+ }
+
+ // Check for Service Account credentials
+ String serviceAccountKey = config.getServiceAccountKey();
+ if (ObjectHelper.isNotEmpty(serviceAccountKey)) {
+ return loadServiceAccountAsLegacyCredential(
+ context, serviceAccountKey, scopes, config.getDelegate(),
transport, factory);
+ }
+
+ throw new IllegalArgumentException(
+ "Either OAuth credentials (clientId + clientSecret) or
serviceAccountKey must be provided");
+ }
+
+ /**
+ * Gets OAuth credential for legacy Google API clients using default
transport and factory.
+ *
+ * @param context the Camel context for resource resolution
+ * @param config the component configuration
+ * @param scopes OAuth scopes to apply
+ * @return Google credential for use with legacy API clients
+ * @throws IOException if credentials cannot be loaded
+ */
+ public static Credential getOAuthCredential(
+ CamelContext context,
+ GoogleCommonConfiguration config,
+ Collection<String> scopes)
+ throws IOException {
+ return getOAuthCredential(context, config, scopes, null, null);
+ }
+
+ // ==================== Private Helper Methods ====================
+
+ /**
+ * Checks if OAuth 2.0 credentials are configured.
+ */
+ private static boolean hasOAuthCredentials(GoogleCommonConfiguration
config) {
+ return ObjectHelper.isNotEmpty(config.getClientId())
+ && ObjectHelper.isNotEmpty(config.getClientSecret());
+ }
+
+ /**
+ * Creates OAuth 2.0 credential from client ID, secret, and tokens.
+ */
+ private static Credential createOAuthCredential(
+ GoogleCommonConfiguration config,
+ Collection<String> scopes,
+ HttpTransport transport,
+ JsonFactory jsonFactory) {
+
+ Credential credential = new GoogleCredential.Builder()
+ .setJsonFactory(jsonFactory)
+ .setTransport(transport)
+ .setClientSecrets(config.getClientId(),
config.getClientSecret())
+ .setServiceAccountScopes(scopes)
+ .build();
+
+ if (ObjectHelper.isNotEmpty(config.getRefreshToken())) {
+ credential.setRefreshToken(config.getRefreshToken());
+ }
+
+ if (ObjectHelper.isNotEmpty(config.getAccessToken())) {
+ credential.setAccessToken(config.getAccessToken());
+ }
+
+ return credential;
+ }
+
+ /**
+ * Loads service account credentials from JSON key file for GCP native
clients.
+ */
+ private static Credentials loadServiceAccountCredentials(
+ CamelContext context,
+ String serviceAccountKey,
+ Collection<String> scopes,
+ String delegate)
+ throws IOException {
+
+ try (InputStream is =
ResourceHelper.resolveMandatoryResourceAsInputStream(context,
serviceAccountKey)) {
+ ServiceAccountCredentials credentials =
ServiceAccountCredentials.fromStream(is);
+
+ if (scopes != null && !scopes.isEmpty()) {
+ credentials = (ServiceAccountCredentials)
credentials.createScoped(scopes);
+ }
+
+ if (ObjectHelper.isNotEmpty(delegate)) {
+ credentials = (ServiceAccountCredentials)
credentials.createDelegated(delegate);
+ }
+
+ return credentials;
+ }
+ }
+
+ /**
+ * Loads service account credentials as legacy GoogleCredential for older
API clients.
+ */
+ private static Credential loadServiceAccountAsLegacyCredential(
+ CamelContext context,
+ String serviceAccountKey,
+ Collection<String> scopes,
+ String delegate,
+ HttpTransport transport,
+ JsonFactory jsonFactory)
+ throws IOException {
+
+ try (InputStream is =
ResourceHelper.resolveMandatoryResourceAsInputStream(context,
serviceAccountKey)) {
+ GoogleCredential credential = GoogleCredential
+ .fromStream(is, transport, jsonFactory);
+
+ if (scopes != null && !scopes.isEmpty()) {
+ credential = credential.createScoped(scopes);
+ }
+
+ if (ObjectHelper.isNotEmpty(delegate)) {
+ credential = credential.createDelegated(delegate);
+ }
+
+ credential.refreshToken();
+ return credential;
+ }
+ }
+}
diff --git a/components/camel-google/camel-google-sheets/pom.xml
b/components/camel-google/camel-google-sheets/pom.xml
index 9429cd792b27..bade44021164 100644
--- a/components/camel-google/camel-google-sheets/pom.xml
+++ b/components/camel-google/camel-google-sheets/pom.xml
@@ -43,6 +43,10 @@
</properties>
<dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-google-common</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-support</artifactId>
diff --git
a/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/BatchGoogleSheetsClientFactory.java
b/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/BatchGoogleSheetsClientFactory.java
index 8030ae0fb287..777f2a228202 100644
---
a/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/BatchGoogleSheetsClientFactory.java
+++
b/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/BatchGoogleSheetsClientFactory.java
@@ -16,11 +16,9 @@
*/
package org.apache.camel.component.google.sheets;
-import java.io.IOException;
import java.util.Collection;
import com.google.api.client.auth.oauth2.Credential;
-import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
@@ -28,8 +26,7 @@ import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.sheets.v4.Sheets;
import org.apache.camel.CamelContext;
import org.apache.camel.RuntimeCamelException;
-import org.apache.camel.support.ResourceHelper;
-import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.component.google.common.GoogleCredentialsHelper;
public class BatchGoogleSheetsClientFactory implements
GoogleSheetsClientFactory {
@@ -62,7 +59,15 @@ public class BatchGoogleSheetsClientFactory implements
GoogleSheetsClientFactory
}
try {
- Credential credential = authorize(clientId, clientSecret, scopes,
refreshToken, accessToken);
+ // Create a temporary configuration to use GoogleCredentialsHelper
+ GoogleSheetsConfiguration tempConfig = new
GoogleSheetsConfiguration();
+ tempConfig.setClientId(clientId);
+ tempConfig.setClientSecret(clientSecret);
+ tempConfig.setRefreshToken(refreshToken);
+ tempConfig.setAccessToken(accessToken);
+
+ Credential credential
+ = GoogleCredentialsHelper.getOAuthCredential(null,
tempConfig, scopes, transport, jsonFactory);
Sheets.Builder clientBuilder = new Sheets.Builder(transport,
jsonFactory, credential)
.setApplicationName(applicationName);
@@ -82,28 +87,6 @@ public class BatchGoogleSheetsClientFactory implements
GoogleSheetsClientFactory
clientBuilder.setRootUrl(Sheets.DEFAULT_ROOT_URL);
}
- // Authorizes the installed application to access user's protected data.
- private Credential authorize(
- String clientId, String clientSecret, Collection<String> scopes,
String refreshToken, String accessToken) {
- // authorize
- Credential credential = new GoogleCredential.Builder()
- .setJsonFactory(jsonFactory)
- .setTransport(transport)
- .setClientSecrets(clientId, clientSecret)
- .setServiceAccountScopes(scopes)
- .build();
-
- if (ObjectHelper.isNotEmpty(refreshToken)) {
- credential.setRefreshToken(refreshToken);
- }
-
- if (ObjectHelper.isNotEmpty(accessToken)) {
- credential.setAccessToken(accessToken);
- }
-
- return credential;
- }
-
@Override
public Sheets makeClient(
CamelContext camelContext, String serviceAccountKey,
Collection<String> scopes, String applicationName,
@@ -112,27 +95,16 @@ public class BatchGoogleSheetsClientFactory implements
GoogleSheetsClientFactory
throw new IllegalArgumentException("serviceAccountKey is required
to create Google Sheets client.");
}
try {
- Credential credential = authorizeServiceAccount(camelContext,
serviceAccountKey, delegate, scopes);
+ // Create a temporary configuration to use GoogleCredentialsHelper
+ GoogleSheetsConfiguration tempConfig = new
GoogleSheetsConfiguration();
+ tempConfig.setServiceAccountKey(serviceAccountKey);
+ tempConfig.setDelegate(delegate);
+
+ Credential credential
+ = GoogleCredentialsHelper.getOAuthCredential(camelContext,
tempConfig, scopes, transport, jsonFactory);
return new Sheets.Builder(transport, jsonFactory,
credential).setApplicationName(applicationName).build();
} catch (Exception e) {
throw new RuntimeCamelException("Could not create Google Sheets
client.", e);
}
}
-
- private Credential authorizeServiceAccount(
- CamelContext camelContext, String serviceAccountKey, String
delegate, Collection<String> scopes) {
- // authorize
- try {
- GoogleCredential cred = GoogleCredential
-
.fromStream(ResourceHelper.resolveMandatoryResourceAsInputStream(camelContext,
serviceAccountKey),
- transport,
- jsonFactory)
- .createScoped(scopes != null && !scopes.isEmpty() ? scopes
: null)
- .createDelegated(delegate);
- cred.refreshToken();
- return cred;
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- }
}
diff --git
a/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/GoogleSheetsConfiguration.java
b/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/GoogleSheetsConfiguration.java
index eb2db1f9be1a..99fc3de93fb3 100644
---
a/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/GoogleSheetsConfiguration.java
+++
b/components/camel-google/camel-google-sheets/src/main/java/org/apache/camel/component/google/sheets/GoogleSheetsConfiguration.java
@@ -19,6 +19,7 @@ package org.apache.camel.component.google.sheets;
import java.util.Collection;
import java.util.List;
+import org.apache.camel.component.google.common.GoogleCommonConfiguration;
import org.apache.camel.component.google.sheets.internal.GoogleSheetsApiName;
import org.apache.camel.spi.Configurer;
import org.apache.camel.spi.Metadata;
@@ -32,7 +33,7 @@ import
org.apache.camel.support.component.AbstractApiConfiguration;
*/
@UriParams
@Configurer(extended = true)
-public class GoogleSheetsConfiguration extends AbstractApiConfiguration {
+public class GoogleSheetsConfiguration extends AbstractApiConfiguration
implements GoogleCommonConfiguration {
@UriPath
@Metadata(required = true)
@@ -80,6 +81,7 @@ public class GoogleSheetsConfiguration extends
AbstractApiConfiguration {
this.methodName = methodName;
}
+ @Override
public String getClientId() {
return clientId;
}
@@ -91,6 +93,7 @@ public class GoogleSheetsConfiguration extends
AbstractApiConfiguration {
this.clientId = clientId;
}
+ @Override
public String getClientSecret() {
return clientSecret;
}
@@ -102,6 +105,7 @@ public class GoogleSheetsConfiguration extends
AbstractApiConfiguration {
this.clientSecret = clientSecret;
}
+ @Override
public String getAccessToken() {
return accessToken;
}
@@ -113,6 +117,7 @@ public class GoogleSheetsConfiguration extends
AbstractApiConfiguration {
this.accessToken = accessToken;
}
+ @Override
public String getRefreshToken() {
return refreshToken;
}
@@ -140,6 +145,7 @@ public class GoogleSheetsConfiguration extends
AbstractApiConfiguration {
return scopes;
}
+ @Override
public Collection<String> getScopesAsList() {
if (scopes != null) {
return List.of(scopes.split(","));
@@ -159,6 +165,7 @@ public class GoogleSheetsConfiguration extends
AbstractApiConfiguration {
this.scopes = scopes;
}
+ @Override
public String getServiceAccountKey() {
return serviceAccountKey;
}
@@ -172,6 +179,7 @@ public class GoogleSheetsConfiguration extends
AbstractApiConfiguration {
this.serviceAccountKey = serviceAccountKey;
}
+ @Override
public String getDelegate() {
return delegate;
}
diff --git a/components/camel-google/camel-google-storage/pom.xml
b/components/camel-google/camel-google-storage/pom.xml
index 35a7f57dd982..52be90a96b78 100644
--- a/components/camel-google/camel-google-storage/pom.xml
+++ b/components/camel-google/camel-google-storage/pom.xml
@@ -37,6 +37,10 @@
</properties>
<dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-google-common</artifactId>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-support</artifactId>
diff --git
a/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageConfiguration.java
b/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageConfiguration.java
index 3447e3d535b2..d367a1c260b6 100644
---
a/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageConfiguration.java
+++
b/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageConfiguration.java
@@ -19,13 +19,14 @@ package org.apache.camel.component.google.storage;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageClass;
import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.component.google.common.GoogleCommonConfiguration;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriParams;
import org.apache.camel.spi.UriPath;
@UriParams
-public class GoogleCloudStorageConfiguration implements Cloneable {
+public class GoogleCloudStorageConfiguration implements Cloneable,
GoogleCommonConfiguration {
@UriPath(label = "common", description = "Bucket name or ARN")
@Metadata(required = true)
@@ -94,6 +95,7 @@ public class GoogleCloudStorageConfiguration implements
Cloneable {
this.bucketName = bucketName;
}
+ @Override
public String getServiceAccountKey() {
return serviceAccountKey;
}
diff --git
a/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageConnectionFactory.java
b/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageConnectionFactory.java
index b26829ad5863..255dc31c4038 100644
---
a/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageConnectionFactory.java
+++
b/components/camel-google/camel-google-storage/src/main/java/org/apache/camel/component/google/storage/GoogleCloudStorageConnectionFactory.java
@@ -16,14 +16,11 @@
*/
package org.apache.camel.component.google.storage;
-import java.io.InputStream;
-
-import com.google.api.client.util.Strings;
-import com.google.auth.oauth2.ServiceAccountCredentials;
+import com.google.auth.Credentials;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
import org.apache.camel.CamelContext;
-import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.component.google.common.GoogleCredentialsHelper;
public final class GoogleCloudStorageConnectionFactory {
@@ -34,12 +31,10 @@ public final class GoogleCloudStorageConnectionFactory {
}
public static Storage create(CamelContext context,
GoogleCloudStorageConfiguration configuration) throws Exception {
- if (!Strings.isNullOrEmpty(configuration.getServiceAccountKey())) {
- InputStream resolveMandatoryResourceAsInputStream
- =
ResourceHelper.resolveMandatoryResourceAsInputStream(context,
configuration.getServiceAccountKey());
+ Credentials credentials =
GoogleCredentialsHelper.getCredentials(context, configuration);
+ if (credentials != null) {
return StorageOptions.newBuilder()
- .setCredentials(
-
ServiceAccountCredentials.fromStream(resolveMandatoryResourceAsInputStream))
+ .setCredentials(credentials)
.build().getService();
} else {
return StorageOptions.getDefaultInstance().getService();
diff --git a/components/camel-google/pom.xml b/components/camel-google/pom.xml
index 2c8f4aed82dd..e3a06bf48f3c 100644
--- a/components/camel-google/pom.xml
+++ b/components/camel-google/pom.xml
@@ -33,6 +33,7 @@
<description>Camel AWS parent</description>
<modules>
+ <module>camel-google-common</module>
<module>camel-google-bigquery</module>
<module>camel-google-calendar</module>
<module>camel-google-drive</module>
diff --git a/coverage/pom.xml b/coverage/pom.xml
index f10f3694e522..3d7774b4ce4e 100644
--- a/coverage/pom.xml
+++ b/coverage/pom.xml
@@ -952,6 +952,11 @@
<artifactId>camel-google-bigquery</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-google-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-google-calendar</artifactId>
diff --git a/docs/components/modules/others/examples/json/google-common.json
b/docs/components/modules/others/examples/json/google-common.json
new file mode 120000
index 000000000000..70db88c13f20
--- /dev/null
+++ b/docs/components/modules/others/examples/json/google-common.json
@@ -0,0 +1 @@
+../../../../../../components/camel-google/camel-google-common/src/generated/resources/google-common.json
\ No newline at end of file
diff --git a/parent/pom.xml b/parent/pom.xml
index 2123c943000a..f841fa70d097 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -1479,6 +1479,11 @@
<artifactId>camel-google-calendar</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-google-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-google-drive</artifactId>
diff --git
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
index d80e467c58b3..5bf533453e72 100644
---
a/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
+++
b/tooling/maven/camel-package-maven-plugin/src/main/java/org/apache/camel/maven/packaging/PrepareCatalogMojo.java
@@ -932,6 +932,7 @@ public class PrepareCatalogMojo extends AbstractMojo {
case "camel-debezium-common":
case "camel-fhir":
case "camel-google":
+ case "camel-google-common":
case "camel-http-base":
case "camel-http-common":
case "camel-huawei":