You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ac...@apache.org on 2021/03/03 15:35:22 UTC

[camel] 01/02: CAMEL-16273 - Camel-google-* cloud components: Make the serviceAccountKey explicitly configurable - Camel-google-pubsub

This is an automated email from the ASF dual-hosted git repository.

acosentino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 715f4106c1e002004ba97f1e3f69ac9d5b95c83e
Author: Andrea Cosentino <an...@gmail.com>
AuthorDate: Wed Mar 3 15:38:14 2021 +0100

    CAMEL-16273 - Camel-google-* cloud components: Make the serviceAccountKey explicitly configurable - Camel-google-pubsub
---
 .../catalog/docs/google-pubsub-component.adoc      |  3 +-
 .../pubsub/GooglePubsubEndpointConfigurer.java     |  6 +++
 .../pubsub/GooglePubsubEndpointUriFactory.java     |  3 +-
 .../component/google/pubsub/google-pubsub.json     |  1 +
 .../src/main/docs/google-pubsub-component.adoc     |  3 +-
 .../google/pubsub/GooglePubsubComponent.java       | 54 +++++++++++++++++-----
 .../google/pubsub/GooglePubsubConsumer.java        |  7 +--
 .../google/pubsub/GooglePubsubEndpoint.java        | 13 ++++++
 .../google/pubsub/GooglePubsubProducer.java        |  2 +-
 .../dsl/GooglePubsubEndpointBuilderFactory.java    | 54 ++++++++++++++++++++++
 .../ROOT/pages/google-pubsub-component.adoc        |  3 +-
 11 files changed, 130 insertions(+), 19 deletions(-)

diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-pubsub-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-pubsub-component.adoc
index a7c67af..83d4535 100644
--- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-pubsub-component.adoc
+++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-pubsub-component.adoc
@@ -81,7 +81,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (12 parameters):
+=== Query Parameters (13 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -91,6 +91,7 @@ with the following path and query parameters:
 | *concurrentConsumers* (common) | The number of parallel streams consuming from the subscription | 1 | Integer
 | *loggerId* (common) | Logger ID to use when a match to the parent route required |  | String
 | *maxMessagesPerPoll* (common) | The max number of messages to receive from the server in a single API call | 1 | Integer
+| *serviceAccountKey* (common) | The Service account key that can be used as credentials for the Storage client. It can be loaded by default from classpath, but you can prefix with classpath:, file:, or http: to load the resource from different systems. |  | String
 | *synchronousPull* (common) | Synchronously pull batches of messages | false | boolean
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
diff --git a/components/camel-google-pubsub/src/generated/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpointConfigurer.java b/components/camel-google-pubsub/src/generated/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpointConfigurer.java
index 8b8737b..b794579 100644
--- a/components/camel-google-pubsub/src/generated/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpointConfigurer.java
+++ b/components/camel-google-pubsub/src/generated/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpointConfigurer.java
@@ -42,6 +42,8 @@ public class GooglePubsubEndpointConfigurer extends PropertyConfigurerSupport im
         case "pubsubendpoint":
         case "pubsubEndpoint": target.setPubsubEndpoint(property(camelContext, java.lang.String.class, value)); return true;
         case "serializer": target.setSerializer(property(camelContext, org.apache.camel.component.google.pubsub.serializer.GooglePubsubSerializer.class, value)); return true;
+        case "serviceaccountkey":
+        case "serviceAccountKey": target.setServiceAccountKey(property(camelContext, java.lang.String.class, value)); return true;
         case "synchronouspull":
         case "synchronousPull": target.setSynchronousPull(property(camelContext, boolean.class, value)); return true;
         default: return false;
@@ -77,6 +79,8 @@ public class GooglePubsubEndpointConfigurer extends PropertyConfigurerSupport im
         case "pubsubendpoint":
         case "pubsubEndpoint": return java.lang.String.class;
         case "serializer": return org.apache.camel.component.google.pubsub.serializer.GooglePubsubSerializer.class;
+        case "serviceaccountkey":
+        case "serviceAccountKey": return java.lang.String.class;
         case "synchronouspull":
         case "synchronousPull": return boolean.class;
         default: return null;
@@ -108,6 +112,8 @@ public class GooglePubsubEndpointConfigurer extends PropertyConfigurerSupport im
         case "pubsubendpoint":
         case "pubsubEndpoint": return target.getPubsubEndpoint();
         case "serializer": return target.getSerializer();
+        case "serviceaccountkey":
+        case "serviceAccountKey": return target.getServiceAccountKey();
         case "synchronouspull":
         case "synchronousPull": return target.isSynchronousPull();
         default: return null;
diff --git a/components/camel-google-pubsub/src/generated/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpointUriFactory.java b/components/camel-google-pubsub/src/generated/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpointUriFactory.java
index a54d3b7..dcee6c6 100644
--- a/components/camel-google-pubsub/src/generated/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpointUriFactory.java
+++ b/components/camel-google-pubsub/src/generated/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpointUriFactory.java
@@ -20,7 +20,8 @@ public class GooglePubsubEndpointUriFactory extends org.apache.camel.support.com
     private static final Set<String> PROPERTY_NAMES;
     private static final Set<String> SECRET_PROPERTY_NAMES;
     static {
-        Set<String> props = new HashSet<>(14);
+        Set<String> props = new HashSet<>(15);
+        props.add("serviceAccountKey");
         props.add("exchangePattern");
         props.add("serializer");
         props.add("synchronousPull");
diff --git a/components/camel-google-pubsub/src/generated/resources/org/apache/camel/component/google/pubsub/google-pubsub.json b/components/camel-google-pubsub/src/generated/resources/org/apache/camel/component/google/pubsub/google-pubsub.json
index 71a44e4..d17dacf 100644
--- a/components/camel-google-pubsub/src/generated/resources/org/apache/camel/component/google/pubsub/google-pubsub.json
+++ b/components/camel-google-pubsub/src/generated/resources/org/apache/camel/component/google/pubsub/google-pubsub.json
@@ -37,6 +37,7 @@
     "concurrentConsumers": { "kind": "parameter", "displayName": "Concurrent Consumers", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1", "description": "The number of parallel streams consuming from the subscription" },
     "loggerId": { "kind": "parameter", "displayName": "Logger Id", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Logger ID to use when a match to the parent route required" },
     "maxMessagesPerPoll": { "kind": "parameter", "displayName": "Max Messages Per Poll", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "1", "description": "The max number of messages to receive from the server in a single API call" },
+    "serviceAccountKey": { "kind": "parameter", "displayName": "Service Account Key", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "The Service account key that can be used as credentials for the Storage client. It can be loaded by default from classpath, but you can prefix with classpath:, file:, or http: to load the resource from different systems." },
     "synchronousPull": { "kind": "parameter", "displayName": "Synchronous Pull", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Synchronously pull batches of messages" },
     "bridgeErrorHandler": { "kind": "parameter", "displayName": "Bridge Error Handler", "group": "consumer", "label": "consumer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a m [...]
     "exceptionHandler": { "kind": "parameter", "displayName": "Exception Handler", "group": "consumer (advanced)", "label": "consumer,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.ExceptionHandler", "optionalPrefix": "consumer.", "deprecated": false, "autowired": false, "secret": false, "description": "To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the con [...]
diff --git a/components/camel-google-pubsub/src/main/docs/google-pubsub-component.adoc b/components/camel-google-pubsub/src/main/docs/google-pubsub-component.adoc
index a7c67af..83d4535 100644
--- a/components/camel-google-pubsub/src/main/docs/google-pubsub-component.adoc
+++ b/components/camel-google-pubsub/src/main/docs/google-pubsub-component.adoc
@@ -81,7 +81,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (12 parameters):
+=== Query Parameters (13 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -91,6 +91,7 @@ with the following path and query parameters:
 | *concurrentConsumers* (common) | The number of parallel streams consuming from the subscription | 1 | Integer
 | *loggerId* (common) | Logger ID to use when a match to the parent route required |  | String
 | *maxMessagesPerPoll* (common) | The max number of messages to receive from the server in a single API call | 1 | Integer
+| *serviceAccountKey* (common) | The Service account key that can be used as credentials for the Storage client. It can be loaded by default from classpath, but you can prefix with classpath:, file:, or http: to load the resource from different systems. |  | String
 | *synchronousPull* (common) | Synchronously pull batches of messages | false | boolean
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler
diff --git a/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubComponent.java b/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubComponent.java
index a727380..dbc2aca 100644
--- a/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubComponent.java
+++ b/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubComponent.java
@@ -17,15 +17,18 @@
 package org.apache.camel.component.google.pubsub;
 
 import java.io.IOException;
+import java.io.InputStream;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 
 import com.google.api.gax.core.CredentialsProvider;
+import com.google.api.gax.core.FixedCredentialsProvider;
 import com.google.api.gax.core.NoCredentialsProvider;
 import com.google.api.gax.grpc.GrpcTransportChannel;
 import com.google.api.gax.rpc.FixedTransportChannelProvider;
 import com.google.api.gax.rpc.TransportChannelProvider;
+import com.google.auth.oauth2.ServiceAccountCredentials;
 import com.google.cloud.pubsub.v1.MessageReceiver;
 import com.google.cloud.pubsub.v1.Publisher;
 import com.google.cloud.pubsub.v1.Subscriber;
@@ -40,6 +43,8 @@ import org.apache.camel.Endpoint;
 import org.apache.camel.spi.Metadata;
 import org.apache.camel.spi.annotations.Component;
 import org.apache.camel.support.DefaultComponent;
+import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StringHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -119,19 +124,29 @@ public class GooglePubsubComponent extends DefaultComponent {
         super.doShutdown();
     }
 
-    public Publisher getPublisher(String topicName, GooglePubsubEndpoint googlePubsubEndpoint) throws ExecutionException {
-        return cachedPublishers.get(topicName, () -> buildPublisher(topicName, googlePubsubEndpoint));
+    public Publisher getPublisher(String topicName, GooglePubsubEndpoint googlePubsubEndpoint, String serviceAccountKey)
+            throws ExecutionException {
+        return cachedPublishers.get(topicName, () -> buildPublisher(topicName, googlePubsubEndpoint, serviceAccountKey));
     }
 
-    private Publisher buildPublisher(String topicName, GooglePubsubEndpoint googlePubsubEndpoint) throws IOException {
+    private Publisher buildPublisher(String topicName, GooglePubsubEndpoint googlePubsubEndpoint, String serviceAccountKey)
+            throws IOException {
         Publisher.Builder builder = Publisher.newBuilder(topicName);
         if (StringHelper.trimToNull(endpoint) != null) {
             ManagedChannel channel = ManagedChannelBuilder.forTarget(endpoint).usePlaintext().build();
             TransportChannelProvider channelProvider
                     = FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
-            CredentialsProvider credentialsProvider = NoCredentialsProvider.create();
-            builder.setChannelProvider(channelProvider).setCredentialsProvider(credentialsProvider);
+            builder.setChannelProvider(channelProvider);
         }
+        CredentialsProvider credentialsProvider;
+        if (ObjectHelper.isEmpty(serviceAccountKey)) {
+            credentialsProvider = NoCredentialsProvider.create();
+        } else {
+            InputStream serviceAccountFile
+                    = ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext(), serviceAccountKey);
+            credentialsProvider = FixedCredentialsProvider.create(ServiceAccountCredentials.fromStream(serviceAccountFile));
+        }
+        builder.setCredentialsProvider(credentialsProvider);
         if (StringHelper.trimToNull(googlePubsubEndpoint.getPubsubEndpoint()) != null) {
             builder.setEndpoint(googlePubsubEndpoint.getPubsubEndpoint());
         }
@@ -145,19 +160,28 @@ public class GooglePubsubComponent extends DefaultComponent {
         return builder.build();
     }
 
-    public Subscriber getSubscriber(String subscriptionName, MessageReceiver messageReceiver) {
+    public Subscriber getSubscriber(String subscriptionName, MessageReceiver messageReceiver, String serviceAccountKey)
+            throws IOException {
         Subscriber.Builder builder = Subscriber.newBuilder(subscriptionName, messageReceiver);
         if (StringHelper.trimToNull(endpoint) != null) {
             ManagedChannel channel = ManagedChannelBuilder.forTarget(endpoint).usePlaintext().build();
             TransportChannelProvider channelProvider
                     = FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
-            CredentialsProvider credentialsProvider = NoCredentialsProvider.create();
-            builder.setChannelProvider(channelProvider).setCredentialsProvider(credentialsProvider);
+            builder.setChannelProvider(channelProvider);
+        }
+        CredentialsProvider credentialsProvider;
+        if (ObjectHelper.isEmpty(serviceAccountKey)) {
+            credentialsProvider = NoCredentialsProvider.create();
+        } else {
+            InputStream serviceAccountFile
+                    = ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext(), serviceAccountKey);
+            credentialsProvider = FixedCredentialsProvider.create(ServiceAccountCredentials.fromStream(serviceAccountFile));
         }
+        builder.setCredentialsProvider(credentialsProvider);
         return builder.build();
     }
 
-    public SubscriberStub getSubscriberStub() throws IOException {
+    public SubscriberStub getSubscriberStub(String serviceAccountKey) throws IOException {
         SubscriberStubSettings.Builder builder = SubscriberStubSettings.newBuilder().setTransportChannelProvider(
                 SubscriberStubSettings.defaultGrpcTransportProviderBuilder().build());
 
@@ -165,9 +189,17 @@ public class GooglePubsubComponent extends DefaultComponent {
             ManagedChannel channel = ManagedChannelBuilder.forTarget(endpoint).usePlaintext().build();
             TransportChannelProvider channelProvider
                     = FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
-            CredentialsProvider credentialsProvider = NoCredentialsProvider.create();
-            builder.setTransportChannelProvider(channelProvider).setCredentialsProvider(credentialsProvider);
+            builder.setTransportChannelProvider(channelProvider);
+        }
+        CredentialsProvider credentialsProvider;
+        if (ObjectHelper.isEmpty(serviceAccountKey)) {
+            credentialsProvider = NoCredentialsProvider.create();
+        } else {
+            InputStream serviceAccountFile
+                    = ResourceHelper.resolveMandatoryResourceAsInputStream(getCamelContext(), serviceAccountKey);
+            credentialsProvider = FixedCredentialsProvider.create(ServiceAccountCredentials.fromStream(serviceAccountFile));
         }
+        builder.setCredentialsProvider(credentialsProvider);
         return builder.build().createStub();
     }
 
diff --git a/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubConsumer.java b/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubConsumer.java
index 8adc5e1..a08b892 100644
--- a/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubConsumer.java
+++ b/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubConsumer.java
@@ -121,11 +121,12 @@ public class GooglePubsubConsumer extends DefaultConsumer {
             }
         }
 
-        private void asynchronousPull(String subscriptionName) {
+        private void asynchronousPull(String subscriptionName) throws IOException {
             while (isRunAllowed() && !isSuspendingOrSuspended()) {
                 MessageReceiver messageReceiver = new CamelMessageReceiver(GooglePubsubConsumer.this, endpoint, processor);
 
-                Subscriber subscriber = endpoint.getComponent().getSubscriber(subscriptionName, messageReceiver);
+                Subscriber subscriber = endpoint.getComponent().getSubscriber(subscriptionName, messageReceiver,
+                        endpoint.getServiceAccountKey());
                 try {
                     subscribers.add(subscriber);
                     subscriber.startAsync().awaitRunning();
@@ -141,7 +142,7 @@ public class GooglePubsubConsumer extends DefaultConsumer {
 
         private void synchronousPull(String subscriptionName) {
             while (isRunAllowed() && !isSuspendingOrSuspended()) {
-                try (SubscriberStub subscriber = endpoint.getComponent().getSubscriberStub()) {
+                try (SubscriberStub subscriber = endpoint.getComponent().getSubscriberStub(endpoint.getServiceAccountKey())) {
 
                     PullRequest pullRequest = PullRequest.newBuilder()
                             .setMaxMessages(endpoint.getMaxMessagesPerPoll())
diff --git a/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpoint.java b/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpoint.java
index 94ca30f..b36df5e 100644
--- a/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpoint.java
+++ b/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubEndpoint.java
@@ -54,6 +54,11 @@ public class GooglePubsubEndpoint extends DefaultEndpoint {
     @Metadata(required = true)
     private String destinationName;
 
+    @UriParam(label = "common",
+              description = "The Service account key that can be used as credentials for the Storage client. It can be loaded by default from "
+                            + " classpath, but you can prefix with classpath:, file:, or http: to load the resource from different systems.")
+    private String serviceAccountKey;
+
     @UriParam(name = "loggerId", description = "Logger ID to use when a match to the parent route required")
     private String loggerId;
 
@@ -160,6 +165,14 @@ public class GooglePubsubEndpoint extends DefaultEndpoint {
         this.loggerId = loggerId;
     }
 
+    public String getServiceAccountKey() {
+        return serviceAccountKey;
+    }
+
+    public void setServiceAccountKey(String serviceAccountKey) {
+        this.serviceAccountKey = serviceAccountKey;
+    }
+
     public String getDestinationName() {
         return destinationName;
     }
diff --git a/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubProducer.java b/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubProducer.java
index 233fbb0..604062a 100644
--- a/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubProducer.java
+++ b/components/camel-google-pubsub/src/main/java/org/apache/camel/component/google/pubsub/GooglePubsubProducer.java
@@ -84,7 +84,7 @@ public class GooglePubsubProducer extends DefaultProducer {
         GooglePubsubEndpoint endpoint = (GooglePubsubEndpoint) getEndpoint();
         String topicName = String.format("projects/%s/topics/%s", endpoint.getProjectId(), endpoint.getDestinationName());
 
-        Publisher publisher = endpoint.getComponent().getPublisher(topicName, endpoint);
+        Publisher publisher = endpoint.getComponent().getPublisher(topicName, endpoint, endpoint.getServiceAccountKey());
 
         Object body = exchange.getIn().getBody();
         ByteString byteString;
diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/GooglePubsubEndpointBuilderFactory.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/GooglePubsubEndpointBuilderFactory.java
index 2d3aebe..a3a7fac 100644
--- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/GooglePubsubEndpointBuilderFactory.java
+++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/GooglePubsubEndpointBuilderFactory.java
@@ -158,6 +158,24 @@ public interface GooglePubsubEndpointBuilderFactory {
             return this;
         }
         /**
+         * The Service account key that can be used as credentials for the
+         * Storage client. It can be loaded by default from classpath, but you
+         * can prefix with classpath:, file:, or http: to load the resource from
+         * different systems.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: common
+         * 
+         * @param serviceAccountKey the value to set
+         * @return the dsl builder
+         */
+        default GooglePubsubEndpointConsumerBuilder serviceAccountKey(
+                String serviceAccountKey) {
+            doSetProperty("serviceAccountKey", serviceAccountKey);
+            return this;
+        }
+        /**
          * Synchronously pull batches of messages.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
@@ -444,6 +462,24 @@ public interface GooglePubsubEndpointBuilderFactory {
             return this;
         }
         /**
+         * The Service account key that can be used as credentials for the
+         * Storage client. It can be loaded by default from classpath, but you
+         * can prefix with classpath:, file:, or http: to load the resource from
+         * different systems.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: common
+         * 
+         * @param serviceAccountKey the value to set
+         * @return the dsl builder
+         */
+        default GooglePubsubEndpointProducerBuilder serviceAccountKey(
+                String serviceAccountKey) {
+            doSetProperty("serviceAccountKey", serviceAccountKey);
+            return this;
+        }
+        /**
          * Synchronously pull batches of messages.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
@@ -749,6 +785,24 @@ public interface GooglePubsubEndpointBuilderFactory {
             return this;
         }
         /**
+         * The Service account key that can be used as credentials for the
+         * Storage client. It can be loaded by default from classpath, but you
+         * can prefix with classpath:, file:, or http: to load the resource from
+         * different systems.
+         * 
+         * The option is a: &lt;code&gt;java.lang.String&lt;/code&gt; type.
+         * 
+         * Group: common
+         * 
+         * @param serviceAccountKey the value to set
+         * @return the dsl builder
+         */
+        default GooglePubsubEndpointBuilder serviceAccountKey(
+                String serviceAccountKey) {
+            doSetProperty("serviceAccountKey", serviceAccountKey);
+            return this;
+        }
+        /**
          * Synchronously pull batches of messages.
          * 
          * The option is a: &lt;code&gt;boolean&lt;/code&gt; type.
diff --git a/docs/components/modules/ROOT/pages/google-pubsub-component.adoc b/docs/components/modules/ROOT/pages/google-pubsub-component.adoc
index c2d3476..ad8f5f3 100644
--- a/docs/components/modules/ROOT/pages/google-pubsub-component.adoc
+++ b/docs/components/modules/ROOT/pages/google-pubsub-component.adoc
@@ -83,7 +83,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (12 parameters):
+=== Query Parameters (13 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -93,6 +93,7 @@ with the following path and query parameters:
 | *concurrentConsumers* (common) | The number of parallel streams consuming from the subscription | 1 | Integer
 | *loggerId* (common) | Logger ID to use when a match to the parent route required |  | String
 | *maxMessagesPerPoll* (common) | The max number of messages to receive from the server in a single API call | 1 | Integer
+| *serviceAccountKey* (common) | The Service account key that can be used as credentials for the Storage client. It can be loaded by default from classpath, but you can prefix with classpath:, file:, or http: to load the resource from different systems. |  | String
 | *synchronousPull* (common) | Synchronously pull batches of messages | false | boolean
 | *bridgeErrorHandler* (consumer) | Allows for bridging the consumer to the Camel routing Error Handler, which mean any exceptions occurred while the consumer is trying to pickup incoming messages, or the likes, will now be processed as a message and handled by the routing Error Handler. By default the consumer will use the org.apache.camel.spi.ExceptionHandler to deal with exceptions, that will be logged at WARN or ERROR level and ignored. | false | boolean
 | *exceptionHandler* (consumer) | To let the consumer use a custom ExceptionHandler. Notice if the option bridgeErrorHandler is enabled then this option is not in use. By default the consumer will deal with exceptions, that will be logged at WARN or ERROR level and ignored. |  | ExceptionHandler