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 a35f38ff74cdb5b72eb0b4ea5ef0a3ff27c9e305 Author: Raffaele Marcello <marcelloraffa...@gmail.com> AuthorDate: Tue Mar 16 12:49:48 2021 +0100 CAMEL-15963 Create a Google Cloud Functions component --- .../catalog/docs/google-functions-component.adoc | 3 + .../camel-google/camel-google-functions/pom.xml | 5 +- .../GoogleCloudFunctionsClientFactory.java | 56 ++++++ .../functions/GoogleCloudFunctionsComponent.java | 1 - .../functions/GoogleCloudFunctionsEndpoint.java | 26 +-- .../functions/GoogleCloudFunctionsProducer.java | 202 +++++++-------------- .../ROOT/pages/google-functions-component.adoc | 3 + parent/pom.xml | 2 + 8 files changed, 132 insertions(+), 166 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-functions-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-functions-component.adoc index cad2ef2..7e230c6 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-functions-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/google-functions-component.adoc @@ -205,6 +205,9 @@ This operation will get the `CloudFunction` object for the project `myProject`, -------------------------------------------------------------------------------- //call function from("direct:start") +.process(exchange -> { + exchange.getIn().setBody("just a message"); +}) .to("google-functions://myCamelFunction?serviceAccountKey=/home/user/Downloads/my-key.json&project=myProject&location=us-central1&operation=callFunction") .log("body:${body}") .to("mock:result"); diff --git a/components/camel-google/camel-google-functions/pom.xml b/components/camel-google/camel-google-functions/pom.xml index fd865b2..b8402d5 100644 --- a/components/camel-google/camel-google-functions/pom.xml +++ b/components/camel-google/camel-google-functions/pom.xml @@ -34,7 +34,6 @@ <properties> <firstVersion>3.9.0</firstVersion> - <google-cloud-functions-version>1.0.8</google-cloud-functions-version> </properties> <dependencyManagement> @@ -48,7 +47,7 @@ <dependency> <groupId>com.google.cloud</groupId> <artifactId>google-cloud-functions-bom</artifactId> - <version>${google-cloud-functions-version}</version> + <version>${google-cloud-functions-bom-version}</version> <type>pom</type> <scope>import</scope> </dependency> @@ -79,7 +78,7 @@ <groupId>com.google.api</groupId> <artifactId>gax-grpc</artifactId> <classifier>testlib</classifier> - <version>1.62.0</version> + <version>${google-cloud-functions-gax-grpc-version}</version> <scope>test</scope> </dependency> diff --git a/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsClientFactory.java b/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsClientFactory.java new file mode 100644 index 0000000..354c543 --- /dev/null +++ b/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsClientFactory.java @@ -0,0 +1,56 @@ +/* + * 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.functions; + +import java.io.FileInputStream; + +import com.google.api.gax.core.FixedCredentialsProvider; +import com.google.auth.Credentials; +import com.google.auth.oauth2.ServiceAccountCredentials; +import com.google.cloud.functions.v1.CloudFunctionsServiceClient; +import com.google.cloud.functions.v1.CloudFunctionsServiceSettings; +import com.google.common.base.Strings; +import org.apache.camel.CamelContext; + +public final class GoogleCloudFunctionsClientFactory { + /** + * Prevent instantiation. + */ + private GoogleCloudFunctionsClientFactory() { + } + + public static CloudFunctionsServiceClient create( + CamelContext context, + GoogleCloudFunctionsConfiguration configuration) + throws Exception { + CloudFunctionsServiceClient cloudFunctionsClient = null; + if (!Strings.isNullOrEmpty(configuration.getServiceAccountKey())) { + Credentials myCredentials = ServiceAccountCredentials + .fromStream(new FileInputStream(configuration.getServiceAccountKey())); + CloudFunctionsServiceSettings settings = CloudFunctionsServiceSettings.newBuilder() + .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials)).build(); + cloudFunctionsClient = CloudFunctionsServiceClient.create(settings); + } else { + // it needs to define the environment variable GOOGLE_APPLICATION_CREDENTIALS + // with the service account file + // more info at https://cloud.google.com/docs/authentication/production + CloudFunctionsServiceSettings settings = CloudFunctionsServiceSettings.newBuilder().build(); + cloudFunctionsClient = CloudFunctionsServiceClient.create(settings); + } + return cloudFunctionsClient; + } +} diff --git a/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsComponent.java b/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsComponent.java index 5dcdedc..abafbd6 100644 --- a/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsComponent.java +++ b/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsComponent.java @@ -31,7 +31,6 @@ public class GoogleCloudFunctionsComponent extends DefaultComponent { private GoogleCloudFunctionsConfiguration configuration = new GoogleCloudFunctionsConfiguration(); public GoogleCloudFunctionsComponent() { - super(null); } public GoogleCloudFunctionsComponent(CamelContext context) { diff --git a/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsEndpoint.java b/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsEndpoint.java index d3016bd..895aa0d 100644 --- a/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsEndpoint.java +++ b/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsEndpoint.java @@ -16,14 +16,7 @@ */ package org.apache.camel.component.google.functions; -import java.io.FileInputStream; - -import com.google.api.client.util.Strings; -import com.google.api.gax.core.FixedCredentialsProvider; -import com.google.auth.Credentials; -import com.google.auth.oauth2.ServiceAccountCredentials; import com.google.cloud.functions.v1.CloudFunctionsServiceClient; -import com.google.cloud.functions.v1.CloudFunctionsServiceSettings; import org.apache.camel.Category; import org.apache.camel.Consumer; import org.apache.camel.Processor; @@ -81,28 +74,15 @@ public class GoogleCloudFunctionsEndpoint extends DefaultEndpoint { if (configuration.getClient() != null) { cloudFunctionsClient = configuration.getClient(); } else { - if (!Strings.isNullOrEmpty(configuration.getServiceAccountKey())) { - Credentials myCredentials = ServiceAccountCredentials - .fromStream(new FileInputStream(configuration.getServiceAccountKey())); - CloudFunctionsServiceSettings settings = CloudFunctionsServiceSettings.newBuilder() - .setCredentialsProvider(FixedCredentialsProvider.create(myCredentials)).build(); - cloudFunctionsClient = CloudFunctionsServiceClient.create(settings); - } else { - //it needs to define the environment variable GOOGLE_APPLICATION_CREDENTIALS with the service account file - //more info at https://cloud.google.com/docs/authentication/production - CloudFunctionsServiceSettings settings = CloudFunctionsServiceSettings.newBuilder().build(); - cloudFunctionsClient = CloudFunctionsServiceClient.create(settings); - } + cloudFunctionsClient = GoogleCloudFunctionsClientFactory.create(this.getCamelContext(), configuration); } } @Override protected void doStop() throws Exception { super.doStop(); - if (configuration.getClient() == null) { - if (cloudFunctionsClient != null) { - cloudFunctionsClient.close(); - } + if (configuration.getClient() == null && cloudFunctionsClient != null) { + cloudFunctionsClient.close(); } } diff --git a/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsProducer.java b/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsProducer.java index 2cd854c..35ac521 100644 --- a/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsProducer.java +++ b/components/camel-google/camel-google-functions/src/main/java/org/apache/camel/component/google/functions/GoogleCloudFunctionsProducer.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.concurrent.ExecutionException; import com.google.api.client.util.Lists; -import com.google.api.gax.rpc.ApiException; import com.google.cloud.functions.v1.CallFunctionRequest; import com.google.cloud.functions.v1.CallFunctionResponse; import com.google.cloud.functions.v1.CloudFunction; @@ -92,220 +91,145 @@ public class GoogleCloudFunctionsProducer extends DefaultProducer { } private void listFunctions(CloudFunctionsServiceClient client, Exchange exchange) throws InvalidPayloadException { + List<CloudFunction> response = null; if (getConfiguration().isPojoRequest()) { - Object payload = exchange.getIn().getMandatoryBody(); - if (payload instanceof ListFunctionsRequest) { - ListFunctionsPagedResponse pagedListResponse; - try { - pagedListResponse = client.listFunctions((ListFunctionsRequest) payload); - List<CloudFunction> response = Lists.newArrayList(pagedListResponse.iterateAll()); - Message message = getMessageForResponse(exchange); - message.setBody(response); - } catch (ApiException ae) { - LOG.trace("listFunctions command returned the error code {}", ae.getStatusCode()); - throw ae; - } - } + ListFunctionsRequest request = exchange.getIn().getMandatoryBody(ListFunctionsRequest.class); + ListFunctionsPagedResponse pagedListResponse = client.listFunctions(request); + response = Lists.newArrayList(pagedListResponse.iterateAll()); } else { - ListFunctionsRequest request = ListFunctionsRequest.newBuilder() - .setParent(LocationName.of(getConfiguration().getProject(), getConfiguration().getLocation()) - .toString()) - .setPageSize(883849137) // TODO check it - .setPageToken("pageToken873572522").build(); + ListFunctionsRequest request = ListFunctionsRequest + .newBuilder().setParent(LocationName + .of(getConfiguration().getProject(), getConfiguration().getLocation()).toString()) + .setPageSize(Integer.MAX_VALUE).build(); ListFunctionsPagedResponse pagedListResponse = client.listFunctions(request); - List<CloudFunction> response = Lists.newArrayList(pagedListResponse.iterateAll()); - Message message = getMessageForResponse(exchange); - message.setBody(response); + response = Lists.newArrayList(pagedListResponse.iterateAll()); } + Message message = getMessageForResponse(exchange); + message.setBody(response); } private void getFunction(CloudFunctionsServiceClient client, Exchange exchange) throws InvalidPayloadException { + CloudFunction response = null; if (getConfiguration().isPojoRequest()) { - Object payload = exchange.getIn().getMandatoryBody(); - if (payload instanceof CloudFunctionName) { - CloudFunction response; - try { - response = client.getFunction((CloudFunctionName) payload); - } catch (ApiException ae) { - LOG.trace("getFunction command returned the error code {}", ae.getStatusCode()); - throw ae; - } - Message message = getMessageForResponse(exchange); - message.setBody(response); - } + CloudFunctionName request = exchange.getIn().getMandatoryBody(CloudFunctionName.class); + response = client.getFunction(request); } else { CloudFunctionName cfName = CloudFunctionName.of(getConfiguration().getProject(), getConfiguration().getLocation(), getConfiguration().getFunctionName()); - CloudFunction response = client.getFunction(cfName); - Message message = getMessageForResponse(exchange); - message.setBody(response); + response = client.getFunction(cfName); } + Message message = getMessageForResponse(exchange); + message.setBody(response); } private void callFunction(CloudFunctionsServiceClient client, Exchange exchange) throws InvalidPayloadException { + CallFunctionResponse response = null; if (getConfiguration().isPojoRequest()) { - Object payload = exchange.getIn().getMandatoryBody(); - if (payload instanceof CallFunctionRequest) { - CallFunctionResponse response; - try { - response = client.callFunction((CallFunctionRequest) payload); - Message message = getMessageForResponse(exchange); - message.setHeader(GoogleCloudFunctionsConstants.RESPONSE_OBJECT, response); - message.setBody(response.getResult()); - } catch (ApiException ae) { - LOG.trace("callFunction command returned the error code {}", ae.getStatusCode()); - throw ae; - } - } + CallFunctionRequest request = exchange.getIn().getMandatoryBody(CallFunctionRequest.class); + response = client.callFunction(request); } else { String data = exchange.getIn().getBody(String.class); CloudFunctionName cfName = CloudFunctionName.of(getConfiguration().getProject(), getConfiguration().getLocation(), getConfiguration().getFunctionName()); CallFunctionRequest request = CallFunctionRequest.newBuilder().setName(cfName.toString()).setData(data) .build(); - CallFunctionResponse response = client.callFunction(request); - Message message = getMessageForResponse(exchange); - message.setHeader(GoogleCloudFunctionsConstants.RESPONSE_OBJECT, response); - message.setBody(response.getResult()); + response = client.callFunction(request); } + Message message = getMessageForResponse(exchange); + message.setHeader(GoogleCloudFunctionsConstants.RESPONSE_OBJECT, response); + message.setBody(response.getResult()); } private void generateDownloadUrl(CloudFunctionsServiceClient client, Exchange exchange) throws InvalidPayloadException { + GenerateDownloadUrlResponse response = null; if (getConfiguration().isPojoRequest()) { - Object payload = exchange.getIn().getMandatoryBody(); - if (payload instanceof GenerateDownloadUrlRequest) { - try { - GenerateDownloadUrlResponse response = client - .generateDownloadUrl((GenerateDownloadUrlRequest) payload); - Message message = getMessageForResponse(exchange); - message.setHeader(GoogleCloudFunctionsConstants.RESPONSE_OBJECT, response); - message.setBody(response.getDownloadUrl()); - } catch (ApiException ae) { - LOG.trace("generateDownloadUrl command returned the error code {}", ae.getStatusCode()); - throw ae; - } - } + GenerateDownloadUrlRequest request = exchange.getIn().getMandatoryBody(GenerateDownloadUrlRequest.class); + response = client.generateDownloadUrl(request); } else { CloudFunctionName cfName = CloudFunctionName.of(getConfiguration().getProject(), getConfiguration().getLocation(), getConfiguration().getFunctionName()); GenerateDownloadUrlRequest request = GenerateDownloadUrlRequest.newBuilder().setName(cfName.toString()) .build(); - GenerateDownloadUrlResponse response = client.generateDownloadUrl(request); - Message message = getMessageForResponse(exchange); - message.setHeader(GoogleCloudFunctionsConstants.RESPONSE_OBJECT, response); - message.setBody(response.getDownloadUrl()); + response = client.generateDownloadUrl(request); } + Message message = getMessageForResponse(exchange); + message.setHeader(GoogleCloudFunctionsConstants.RESPONSE_OBJECT, response); + message.setBody(response.getDownloadUrl()); } private void generateUploadUrl(CloudFunctionsServiceClient client, Exchange exchange) throws InvalidPayloadException { + GenerateUploadUrlResponse response = null; if (getConfiguration().isPojoRequest()) { - Object payload = exchange.getIn().getMandatoryBody(); - if (payload instanceof GenerateUploadUrlRequest) { - try { - GenerateUploadUrlResponse response = client.generateUploadUrl((GenerateUploadUrlRequest) payload); - Message message = getMessageForResponse(exchange); - message.setHeader(GoogleCloudFunctionsConstants.RESPONSE_OBJECT, response); - message.setBody(response.getUploadUrl()); - } catch (ApiException ae) { - LOG.trace("generateUploadUrl command returned the error code {}", ae.getStatusCode()); - throw ae; - } - } + GenerateUploadUrlRequest request = exchange.getIn().getMandatoryBody(GenerateUploadUrlRequest.class); + response = client.generateUploadUrl(request); } else { LocationName locationName = LocationName.of(getConfiguration().getProject(), getConfiguration().getLocation()); GenerateUploadUrlRequest request = GenerateUploadUrlRequest.newBuilder().setParent(locationName.toString()) .build(); - GenerateUploadUrlResponse response = client.generateUploadUrl(request); - Message message = getMessageForResponse(exchange); - message.setHeader(GoogleCloudFunctionsConstants.RESPONSE_OBJECT, response); - message.setBody(response.getUploadUrl()); + response = client.generateUploadUrl(request); } + Message message = getMessageForResponse(exchange); + message.setHeader(GoogleCloudFunctionsConstants.RESPONSE_OBJECT, response); + message.setBody(response.getUploadUrl()); } private void createFunction(CloudFunctionsServiceClient client, Exchange exchange) throws InvalidPayloadException, InterruptedException, ExecutionException { + CloudFunction response = null; if (getConfiguration().isPojoRequest()) { - Object payload = exchange.getIn().getMandatoryBody(); - if (payload instanceof CreateFunctionRequest) { - try { - CloudFunction response = client.createFunctionAsync((CreateFunctionRequest) payload).get(); - Message message = getMessageForResponse(exchange); - message.setBody(response); - } catch (ApiException ae) { - LOG.trace("createFunction command returned the error code {}", ae.getStatusCode()); - throw ae; - } - } + CreateFunctionRequest request = exchange.getIn().getMandatoryBody(CreateFunctionRequest.class); + response = client.createFunctionAsync(request).get(); } else { final String project = getConfiguration().getProject(); final String location = getConfiguration().getLocation(); final String functionName = getConfiguration().getFunctionName(); - final String entryPoint = exchange.getIn().getHeader(GoogleCloudFunctionsConstants.ENTRY_POINT, String.class); + final String entryPoint = exchange.getIn().getHeader(GoogleCloudFunctionsConstants.ENTRY_POINT, + String.class); final String runtime = exchange.getIn().getHeader(GoogleCloudFunctionsConstants.RUNTIME, String.class); - final String sourceArchiveUrl - = exchange.getIn().getHeader(GoogleCloudFunctionsConstants.SOURCE_ARCHIVE_URL, String.class); - + final String sourceArchiveUrl = exchange.getIn().getHeader(GoogleCloudFunctionsConstants.SOURCE_ARCHIVE_URL, + String.class); CloudFunction function = CloudFunction.newBuilder() - .setName(CloudFunctionName.of(project, location, functionName).toString()) - .setEntryPoint(entryPoint) - .setRuntime(runtime) - .setHttpsTrigger(HttpsTrigger.getDefaultInstance()) - .setSourceArchiveUrl(sourceArchiveUrl) - .build(); + .setName(CloudFunctionName.of(project, location, functionName).toString()).setEntryPoint(entryPoint) + .setRuntime(runtime).setHttpsTrigger(HttpsTrigger.getDefaultInstance()) + .setSourceArchiveUrl(sourceArchiveUrl).build(); CreateFunctionRequest request = CreateFunctionRequest.newBuilder() - .setLocation(LocationName.of(project, location).toString()) - .setFunction(function).build(); - - CloudFunction response = client.createFunctionAsync(request).get(); - Message message = getMessageForResponse(exchange); - message.setBody(response); + .setLocation(LocationName.of(project, location).toString()).setFunction(function).build(); + response = client.createFunctionAsync(request).get(); } + Message message = getMessageForResponse(exchange); + message.setBody(response); } private void updateFunction(CloudFunctionsServiceClient client, Exchange exchange) throws InvalidPayloadException, InterruptedException, ExecutionException { + CloudFunction response = null; if (getConfiguration().isPojoRequest()) { - Object payload = exchange.getIn().getMandatoryBody(); - if (payload instanceof UpdateFunctionRequest) { - try { - CloudFunction response = client.updateFunctionAsync((UpdateFunctionRequest) payload).get(); - Message message = getMessageForResponse(exchange); - message.setBody(response); - } catch (ApiException ae) { - LOG.trace("updateFunction command returned the error code {}", ae.getStatusCode()); - throw ae; - } - } + UpdateFunctionRequest request = exchange.getIn().getMandatoryBody(UpdateFunctionRequest.class); + response = client.updateFunctionAsync(request).get(); } else { throw new IllegalArgumentException("updateFunction is supported only in pojo mode"); } + Message message = getMessageForResponse(exchange); + message.setBody(response); } private void deleteFunction(CloudFunctionsServiceClient client, Exchange exchange) throws InvalidPayloadException, InterruptedException, ExecutionException { + Empty response = null; if (getConfiguration().isPojoRequest()) { - Object payload = exchange.getIn().getMandatoryBody(); - if (payload instanceof DeleteFunctionRequest) { - try { - Empty response = client.deleteFunctionAsync((DeleteFunctionRequest) payload).get(); - Message message = getMessageForResponse(exchange); - message.setBody(response); - } catch (ApiException ae) { - LOG.trace("deleteFunction command returned the error code {}", ae.getStatusCode()); - throw ae; - } - } + DeleteFunctionRequest request = exchange.getIn().getMandatoryBody(DeleteFunctionRequest.class); + response = client.deleteFunctionAsync(request).get(); } else { CloudFunctionName cfName = CloudFunctionName.of(getConfiguration().getProject(), getConfiguration().getLocation(), getConfiguration().getFunctionName()); DeleteFunctionRequest request = DeleteFunctionRequest.newBuilder().setName(cfName.toString()).build(); - Empty response = client.deleteFunctionAsync(request).get(); - Message message = getMessageForResponse(exchange); - message.setBody(response); + response = client.deleteFunctionAsync(request).get(); } + Message message = getMessageForResponse(exchange); + message.setBody(response); } private GoogleCloudFunctionsOperations determineOperation(Exchange exchange) { diff --git a/docs/components/modules/ROOT/pages/google-functions-component.adoc b/docs/components/modules/ROOT/pages/google-functions-component.adoc index 709d2c5..3c9fd5e 100644 --- a/docs/components/modules/ROOT/pages/google-functions-component.adoc +++ b/docs/components/modules/ROOT/pages/google-functions-component.adoc @@ -207,6 +207,9 @@ This operation will get the `CloudFunction` object for the project `myProject`, -------------------------------------------------------------------------------- //call function from("direct:start") +.process(exchange -> { + exchange.getIn().setBody("just a message"); +}) .to("google-functions://myCamelFunction?serviceAccountKey=/home/user/Downloads/my-key.json&project=myProject&location=us-central1&operation=callFunction") .log("body:${body}") .to("mock:result"); diff --git a/parent/pom.xml b/parent/pom.xml index b70a795..54d40c0 100644 --- a/parent/pom.xml +++ b/parent/pom.xml @@ -214,6 +214,8 @@ <google-api-services-sheets-version>v4-rev551-1.22.0</google-api-services-sheets-version> <google-api-services-mail-version>v1-rev81-1.22.0</google-api-services-mail-version> <google-cloud-bom-version>16.3.0</google-cloud-bom-version> + <google-cloud-functions-bom-version>1.0.8</google-cloud-functions-bom-version> + <google-cloud-functions-gax-grpc-version>1.62.0</google-cloud-functions-gax-grpc-version> <google-cloud-guava-version>30.0-jre</google-cloud-guava-version> <google-mail-guava-version>17.0</google-mail-guava-version> <graaljs-version>21.0.0.2</graaljs-version>