This is an automated email from the ASF dual-hosted git repository. acosentino pushed a commit to branch 23034 in repository https://gitbox.apache.org/repos/asf/camel.git
commit d8f26f136dd574de990c5c9a671dc7e2d71da31c Author: Andrea Cosentino <[email protected]> AuthorDate: Fri Feb 20 10:16:53 2026 +0100 CAMEL-23034 - Generalize Google services authentication with common module 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":
