This is an automated email from the ASF dual-hosted git repository.
jamesnetherton pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-quarkus.git
The following commit(s) were added to refs/heads/main by this push:
new 3270856203 Fixes #6690, #6933 - google-secret-manager extend coverage
and native support
3270856203 is described below
commit 3270856203cb38bd26b422b04251711850b2e0ec
Author: Jiri Ondrusek <[email protected]>
AuthorDate: Thu Jan 23 15:35:24 2025 +0100
Fixes #6690, #6933 - google-secret-manager extend coverage and native
support
---
.../examples/components/google-secret-manager.yml | 6 +-
.../extensions/google-secret-manager.adoc | 14 +-
extensions-jvm/pom.xml | 1 -
.../google-secret-manager/deployment/pom.xml | 4 +
.../deployment/GoogleSecretManagerProcessor.java | 14 --
.../google-secret-manager/pom.xml | 2 +-
.../google-secret-manager/runtime/pom.xml | 24 +++
.../manager/graalvm/GaxGrpcSubstitutions.java | 149 +++++++++++++++++++
.../main/resources/META-INF/quarkus-extension.yaml | 3 +-
extensions/pom.xml | 1 +
integration-tests-jvm/pom.xml | 1 -
.../support/google/GoogleCloudTestResource.java | 5 +-
.../google-secret-manager/README.adoc | 4 +-
.../google-secret-manager/pom.xml | 37 +++++
.../manager/it/GoogleSecretManagerResource.java | 32 ++--
.../manager/it/GoogleSecretManagerRoutes.java | 2 +-
...kus.test.support.google.GoogleTestEnvCustomizer | 1 +
.../src/main/resources/application.properties | 18 ++-
.../secret/manager/it/GooglePubSubCustomizer.java | 165 +++++++++++++++++++++
.../secret/manager/it/GoogleSecretManagerIT.java | 24 ++-
.../secret/manager/it/GoogleSecretManagerTest.java | 92 ++++++++++--
.../it/GoogleSecretManagerTestResource.java | 100 +++++++++----
integration-tests/pom.xml | 1 +
tooling/scripts/test-categories.yaml | 1 +
24 files changed, 603 insertions(+), 98 deletions(-)
diff --git a/docs/modules/ROOT/examples/components/google-secret-manager.yml
b/docs/modules/ROOT/examples/components/google-secret-manager.yml
index 6ed43c7200..105aef213e 100644
--- a/docs/modules/ROOT/examples/components/google-secret-manager.yml
+++ b/docs/modules/ROOT/examples/components/google-secret-manager.yml
@@ -2,11 +2,11 @@
# This file was generated by
camel-quarkus-maven-plugin:update-extension-doc-page
cqArtifactId: camel-quarkus-google-secret-manager
cqArtifactIdBase: google-secret-manager
-cqNativeSupported: false
-cqStatus: Preview
+cqNativeSupported: true
+cqStatus: Stable
cqDeprecated: false
cqJvmSince: 2.8.0
-cqNativeSince: n/a
+cqNativeSince: 3.19.0
cqCamelPartName: google-secret-manager
cqCamelPartTitle: Google Secret Manager
cqCamelPartDescription: Manage Google Secret Manager Secrets
diff --git
a/docs/modules/ROOT/pages/reference/extensions/google-secret-manager.adoc
b/docs/modules/ROOT/pages/reference/extensions/google-secret-manager.adoc
index 7dc7ed4675..22a126a888 100644
--- a/docs/modules/ROOT/pages/reference/extensions/google-secret-manager.adoc
+++ b/docs/modules/ROOT/pages/reference/extensions/google-secret-manager.adoc
@@ -4,17 +4,17 @@
= Google Secret Manager
:linkattrs:
:cq-artifact-id: camel-quarkus-google-secret-manager
-:cq-native-supported: false
-:cq-status: Preview
-:cq-status-deprecation: Preview
+:cq-native-supported: true
+:cq-status: Stable
+:cq-status-deprecation: Stable
:cq-description: Manage Google Secret Manager Secrets
:cq-deprecated: false
:cq-jvm-since: 2.8.0
-:cq-native-since: n/a
+:cq-native-since: 3.19.0
ifeval::[{doc-show-badges} == true]
[.badges]
-[.badge-key]##JVM since##[.badge-supported]##2.8.0##
[.badge-key]##Native##[.badge-unsupported]##unsupported##
+[.badge-key]##JVM since##[.badge-supported]##2.8.0## [.badge-key]##Native
since##[.badge-supported]##3.19.0##
endif::[]
Manage Google Secret Manager Secrets
@@ -29,6 +29,10 @@ Please refer to the above link for usage and configuration
details.
[id="extensions-google-secret-manager-maven-coordinates"]
== Maven coordinates
+https://{link-quarkus-code-generator}/?extension-search=camel-quarkus-google-secret-manager[Create
a new project with this extension on {link-quarkus-code-generator},
window="_blank"]
+
+Or add the coordinates to your existing project:
+
[source,xml]
----
<dependency>
diff --git a/extensions-jvm/pom.xml b/extensions-jvm/pom.xml
index 3dba978298..76d2efd09a 100644
--- a/extensions-jvm/pom.xml
+++ b/extensions-jvm/pom.xml
@@ -62,7 +62,6 @@
<module>fastjson</module>
<module>flink</module>
<module>google-functions</module>
- <module>google-secret-manager</module>
<module>guava-eventbus</module>
<module>huaweicloud-smn</module>
<module>iec60870</module>
diff --git a/extensions-jvm/google-secret-manager/deployment/pom.xml
b/extensions/google-secret-manager/deployment/pom.xml
similarity index 94%
rename from extensions-jvm/google-secret-manager/deployment/pom.xml
rename to extensions/google-secret-manager/deployment/pom.xml
index 1c6a87c070..0d36b5cdad 100644
--- a/extensions-jvm/google-secret-manager/deployment/pom.xml
+++ b/extensions/google-secret-manager/deployment/pom.xml
@@ -38,6 +38,10 @@
<groupId>org.apache.camel.quarkus</groupId>
<artifactId>camel-quarkus-google-secret-manager</artifactId>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-grpc-common-deployment</artifactId>
+ </dependency>
</dependencies>
<build>
diff --git
a/extensions-jvm/google-secret-manager/deployment/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/deployment/GoogleSecretManagerProcessor.java
b/extensions/google-secret-manager/deployment/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/deployment/GoogleSecretManagerProcessor.java
similarity index 68%
rename from
extensions-jvm/google-secret-manager/deployment/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/deployment/GoogleSecretManagerProcessor.java
rename to
extensions/google-secret-manager/deployment/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/deployment/GoogleSecretManagerProcessor.java
index 8925730946..6cbd9bd4f4 100644
---
a/extensions-jvm/google-secret-manager/deployment/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/deployment/GoogleSecretManagerProcessor.java
+++
b/extensions/google-secret-manager/deployment/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/deployment/GoogleSecretManagerProcessor.java
@@ -17,11 +17,7 @@
package org.apache.camel.quarkus.component.google.secret.manager.deployment;
import io.quarkus.deployment.annotations.BuildStep;
-import io.quarkus.deployment.annotations.ExecutionTime;
-import io.quarkus.deployment.annotations.Record;
import io.quarkus.deployment.builditem.FeatureBuildItem;
-import io.quarkus.deployment.pkg.steps.NativeOrNativeSourcesBuild;
-import org.apache.camel.quarkus.core.JvmOnlyRecorder;
import org.jboss.logging.Logger;
class GoogleSecretManagerProcessor {
@@ -33,14 +29,4 @@ class GoogleSecretManagerProcessor {
FeatureBuildItem feature() {
return new FeatureBuildItem(FEATURE);
}
-
- /**
- * Remove this once this extension starts supporting the native mode.
- */
- @BuildStep(onlyIf = NativeOrNativeSourcesBuild.class)
- @Record(value = ExecutionTime.RUNTIME_INIT)
- void warnJvmInNative(JvmOnlyRecorder recorder) {
- JvmOnlyRecorder.warnJvmInNative(LOG, FEATURE); // warn at build time
- recorder.warnJvmInNative(FEATURE); // warn at runtime
- }
}
diff --git a/extensions-jvm/google-secret-manager/pom.xml
b/extensions/google-secret-manager/pom.xml
similarity index 96%
rename from extensions-jvm/google-secret-manager/pom.xml
rename to extensions/google-secret-manager/pom.xml
index f133c62abc..ab9adf03d7 100644
--- a/extensions-jvm/google-secret-manager/pom.xml
+++ b/extensions/google-secret-manager/pom.xml
@@ -21,7 +21,7 @@
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.apache.camel.quarkus</groupId>
- <artifactId>camel-quarkus-extensions-jvm</artifactId>
+ <artifactId>camel-quarkus-extensions</artifactId>
<version>3.19.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
diff --git a/extensions-jvm/google-secret-manager/runtime/pom.xml
b/extensions/google-secret-manager/runtime/pom.xml
similarity index 84%
rename from extensions-jvm/google-secret-manager/runtime/pom.xml
rename to extensions/google-secret-manager/runtime/pom.xml
index e3eb4d9807..5732963479 100644
--- a/extensions-jvm/google-secret-manager/runtime/pom.xml
+++ b/extensions/google-secret-manager/runtime/pom.xml
@@ -32,6 +32,7 @@
<properties>
<camel.quarkus.jvmSince>2.8.0</camel.quarkus.jvmSince>
+ <camel.quarkus.nativeSince>3.19.0</camel.quarkus.nativeSince>
</properties>
<dependencies>
@@ -92,6 +93,29 @@
</exclusion>
</exclusions>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-grpc-common</artifactId>
+ <exclusions>
+ <exclusion>
+ <groupId>com.google.guava</groupId>
+ <artifactId>listenablefuture</artifactId>
+ </exclusion>
+ </exclusions>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.logmanager</groupId>
+ <artifactId>log4j2-jboss-logmanager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.jboss.logmanager</groupId>
+ <artifactId>log4j-jboss-logmanager</artifactId>
+ </dependency>
+ <dependency>
+ <groupId>org.graalvm.sdk</groupId>
+ <artifactId>nativeimage</artifactId>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
<build>
diff --git
a/extensions/google-secret-manager/runtime/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/graalvm/GaxGrpcSubstitutions.java
b/extensions/google-secret-manager/runtime/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/graalvm/GaxGrpcSubstitutions.java
new file mode 100644
index 0000000000..39165d8b16
--- /dev/null
+++
b/extensions/google-secret-manager/runtime/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/graalvm/GaxGrpcSubstitutions.java
@@ -0,0 +1,149 @@
+/*
+ * 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.quarkus.component.google.secret.manager.graalvm;
+
+import java.io.IOException;
+import java.security.GeneralSecurityException;
+import java.time.Duration;
+import java.util.concurrent.Executor;
+import java.util.concurrent.TimeUnit;
+
+import com.google.api.core.ApiFunction;
+import com.google.api.gax.grpc.ChannelPrimer;
+import com.google.api.gax.grpc.GrpcHeaderInterceptor;
+import com.google.api.gax.grpc.GrpcInterceptorProvider;
+import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
+import com.google.api.gax.rpc.HeaderProvider;
+import com.oracle.svm.core.annotate.Alias;
+import com.oracle.svm.core.annotate.Substitute;
+import com.oracle.svm.core.annotate.TargetClass;
+import io.grpc.*;
+
+@TargetClass(InstantiatingGrpcChannelProvider.class)
+final class InstantiatingGrpcChannelProviderSubstitutions {
+ @Alias
+ private Executor executor;
+ @Alias
+ private HeaderProvider headerProvider;
+ @Alias
+ private GrpcInterceptorProvider interceptorProvider;
+ @Alias
+ private String endpoint;
+ @Alias
+ private Integer maxInboundMessageSize;
+ @Alias
+ private Integer maxInboundMetadataSize;
+ @Alias
+ private Duration keepAliveTime;
+ @Alias
+ private Duration keepAliveTimeout;
+ @Alias
+ private Boolean keepAliveWithoutCalls;
+ @Alias
+ private ChannelPrimer channelPrimer;
+ @Alias
+ private ApiFunction<ManagedChannelBuilder, ManagedChannelBuilder>
channelConfigurator;
+
+ @Substitute
+ private ManagedChannel createSingleChannel() throws IOException {
+ GrpcHeaderInterceptor headerInterceptor = new
GrpcHeaderInterceptor(headerProvider.getHeaders());
+ ClientInterceptor metadataHandlerInterceptor = new
GrpcMetadataHandlerInterceptorTarget();
+
+ int colon = endpoint.lastIndexOf(':');
+ if (colon < 0) {
+ throw new IllegalStateException("invalid endpoint - should have
been validated: " + endpoint);
+ }
+ int port = Integer.parseInt(endpoint.substring(colon + 1));
+ String serviceAddress = endpoint.substring(0, colon);
+
+ ManagedChannelBuilder<?> builder;
+ ChannelCredentials channelCredentials;
+ try {
+ channelCredentials = createMtlsChannelCredentials();
+ } catch (GeneralSecurityException e) {
+ throw new IOException(e);
+ }
+
+ if (channelCredentials != null) {
+ builder = Grpc.newChannelBuilder(endpoint, channelCredentials);
+ } else {
+ builder = ManagedChannelBuilder.forAddress(serviceAddress, port);
+ }
+
+ builder.disableServiceConfigLookUp();
+
+ builder = builder.intercept(new GrpcChannelUUIDInterceptorTarget())
+ .intercept(headerInterceptor)
+ .intercept(metadataHandlerInterceptor)
+ .userAgent(headerInterceptor.getUserAgentHeader())
+ .executor(executor);
+
+ if (maxInboundMetadataSize != null) {
+ builder.maxInboundMetadataSize(maxInboundMetadataSize);
+ }
+ if (maxInboundMessageSize != null) {
+ builder.maxInboundMessageSize(maxInboundMessageSize);
+ }
+ if (keepAliveTime != null) {
+ builder.keepAliveTime(keepAliveTime.toMillis(),
TimeUnit.MILLISECONDS);
+ }
+ if (keepAliveTimeout != null) {
+ builder.keepAliveTimeout(keepAliveTimeout.toMillis(),
TimeUnit.MILLISECONDS);
+ }
+ if (keepAliveWithoutCalls != null) {
+ builder.keepAliveWithoutCalls(keepAliveWithoutCalls);
+ }
+ if (interceptorProvider != null) {
+ builder.intercept(interceptorProvider.getInterceptors());
+ }
+ if (channelConfigurator != null) {
+ builder = channelConfigurator.apply(builder);
+ }
+
+ ManagedChannel managedChannel = builder.build();
+ if (channelPrimer != null) {
+ channelPrimer.primeChannel(managedChannel);
+ }
+ return managedChannel;
+ }
+
+ @Alias
+ ChannelCredentials createMtlsChannelCredentials() throws IOException,
GeneralSecurityException {
+ throw new UnsupportedOperationException();
+ }
+}
+
+@TargetClass(className =
"com.google.api.gax.grpc.GrpcMetadataHandlerInterceptor")
+final class GrpcMetadataHandlerInterceptorTarget implements ClientInterceptor {
+
+ @Alias()
+ @Override
+ public <ReqT, RespT> ClientCall<ReqT, RespT>
interceptCall(MethodDescriptor<ReqT, RespT> method,
+ final CallOptions callOptions, Channel next) {
+ throw new UnsupportedOperationException();
+ }
+}
+
+@TargetClass(className = "com.google.api.gax.grpc.GrpcChannelUUIDInterceptor")
+final class GrpcChannelUUIDInterceptorTarget implements ClientInterceptor {
+ @Alias
+ @Override
+ public <ReqT, RespT> ClientCall<ReqT, RespT>
interceptCall(MethodDescriptor<ReqT, RespT> methodDescriptor,
+ CallOptions callOptions, Channel channel) {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git
a/extensions-jvm/google-secret-manager/runtime/src/main/resources/META-INF/quarkus-extension.yaml
b/extensions/google-secret-manager/runtime/src/main/resources/META-INF/quarkus-extension.yaml
similarity index 97%
rename from
extensions-jvm/google-secret-manager/runtime/src/main/resources/META-INF/quarkus-extension.yaml
rename to
extensions/google-secret-manager/runtime/src/main/resources/META-INF/quarkus-extension.yaml
index 780163d74c..b08871c75d 100644
---
a/extensions-jvm/google-secret-manager/runtime/src/main/resources/META-INF/quarkus-extension.yaml
+++
b/extensions/google-secret-manager/runtime/src/main/resources/META-INF/quarkus-extension.yaml
@@ -26,9 +26,8 @@ description: "Manage Google Secret Manager Secrets"
metadata:
icon-url:
"https://raw.githubusercontent.com/apache/camel-website/main/antora-ui-camel/src/img/logo-d.svg"
sponsor: "Apache Software Foundation"
- unlisted: true
guide:
"https://camel.apache.org/camel-quarkus/latest/reference/extensions/google-secret-manager.html"
categories:
- "integration"
status:
- - "preview"
+ - "stable"
diff --git a/extensions/pom.xml b/extensions/pom.xml
index 9368ae6f8e..263e200e8b 100644
--- a/extensions/pom.xml
+++ b/extensions/pom.xml
@@ -118,6 +118,7 @@
<module>google-drive</module>
<module>google-mail</module>
<module>google-pubsub</module>
+ <module>google-secret-manager</module>
<module>google-sheets</module>
<module>google-storage</module>
<module>graphql</module>
diff --git a/integration-tests-jvm/pom.xml b/integration-tests-jvm/pom.xml
index 13ce4680e4..b77c5ab692 100644
--- a/integration-tests-jvm/pom.xml
+++ b/integration-tests-jvm/pom.xml
@@ -61,7 +61,6 @@
<module>fastjson</module>
<module>flink</module>
<module>google-functions</module>
- <module>google-secret-manager</module>
<module>guava-eventbus</module>
<module>huaweicloud-smn</module>
<module>iec60870</module>
diff --git
a/integration-tests-support/google/src/main/java/org/apache/camel/quarkus/test/support/google/GoogleCloudTestResource.java
b/integration-tests-support/google/src/main/java/org/apache/camel/quarkus/test/support/google/GoogleCloudTestResource.java
index 7356077baa..53fe8186ec 100644
---
a/integration-tests-support/google/src/main/java/org/apache/camel/quarkus/test/support/google/GoogleCloudTestResource.java
+++
b/integration-tests-support/google/src/main/java/org/apache/camel/quarkus/test/support/google/GoogleCloudTestResource.java
@@ -39,6 +39,8 @@ public class GoogleCloudTestResource implements
QuarkusTestResourceLifecycleMana
private final GoogleCloudContext envContext = new GoogleCloudContext();
+ protected List<GoogleTestEnvCustomizer> customizers;
+
/**
* Method usable by dependant modules.
*
@@ -70,7 +72,7 @@ public class GoogleCloudTestResource implements
QuarkusTestResourceLifecycleMana
envContext.setUsingMockBackend(usingMockBackend);
ServiceLoader<GoogleTestEnvCustomizer> loader =
ServiceLoader.load(GoogleTestEnvCustomizer.class);
- List<GoogleTestEnvCustomizer> customizers = new ArrayList<>();
+ customizers = new ArrayList<>();
for (GoogleTestEnvCustomizer customizer : loader) {
LOGGER.info("Loaded GoogleTestEnvCustomizer " +
customizer.getClass().getName());
customizers.add(customizer);
@@ -113,6 +115,7 @@ public class GoogleCloudTestResource implements
QuarkusTestResourceLifecycleMana
}
}
+ @Override
public void stop() {
if (envContext != null) {
envContext.close();
diff --git a/integration-tests-jvm/google-secret-manager/README.adoc
b/integration-tests/google-secret-manager/README.adoc
similarity index 67%
rename from integration-tests-jvm/google-secret-manager/README.adoc
rename to integration-tests/google-secret-manager/README.adoc
index c29df4e79d..30bef24f6b 100644
--- a/integration-tests-jvm/google-secret-manager/README.adoc
+++ b/integration-tests/google-secret-manager/README.adoc
@@ -7,8 +7,8 @@ Below are the environment variables that have to be configured:
[source,shell]
----
-export GOOGLE_SERVICE_ACCOUNT_KEY=<path-to-google-credentials-json-file>
-export GOOGLE_PROJECT=<name-of-your-project>
+export GOOGLE_APPLICATION_CREDENTIALS=<path-to-google-credentials-json-file>
+export GOOGLE_PROJECT_ID=<name-of-your-project>
----
If any of the required variables is not defined, the tests are automatically
skipped.
\ No newline at end of file
diff --git a/integration-tests-jvm/google-secret-manager/pom.xml
b/integration-tests/google-secret-manager/pom.xml
similarity index 79%
rename from integration-tests-jvm/google-secret-manager/pom.xml
rename to integration-tests/google-secret-manager/pom.xml
index 78c40b18ad..5cd42cdceb 100644
--- a/integration-tests-jvm/google-secret-manager/pom.xml
+++ b/integration-tests/google-secret-manager/pom.xml
@@ -73,6 +73,11 @@
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>io.quarkus</groupId>
+ <artifactId>quarkus-junit5-internal</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
@@ -83,6 +88,11 @@
<artifactId>camel-quarkus-integration-test-support</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel.quarkus</groupId>
+
<artifactId>camel-quarkus-integration-tests-support-google</artifactId>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.awaitility</groupId>
<artifactId>awaitility</artifactId>
@@ -91,6 +101,33 @@
</dependencies>
<profiles>
+ <profile>
+ <id>native</id>
+ <activation>
+ <property>
+ <name>native</name>
+ </property>
+ </activation>
+ <properties>
+ <quarkus.native.enabled>true</quarkus.native.enabled>
+ </properties>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-failsafe-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>integration-test</goal>
+ <goal>verify</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
<profile>
<id>virtualDependencies</id>
<activation>
diff --git
a/integration-tests-jvm/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerResource.java
b/integration-tests/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerResource.java
similarity index 80%
rename from
integration-tests-jvm/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerResource.java
rename to
integration-tests/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerResource.java
index cbec79846a..43fad98f03 100644
---
a/integration-tests-jvm/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerResource.java
+++
b/integration-tests/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerResource.java
@@ -46,10 +46,10 @@ public class GoogleSecretManagerResource {
private static final Logger LOG =
Logger.getLogger(GoogleSecretManagerResource.class);
- @ConfigProperty(name =
"cq.google-secrets-manager.path-to-service-account-key")
+ @ConfigProperty(name = "camel.vault.gcp.serviceAccountKey")
String accountKey;
- @ConfigProperty(name = "cq.google-secrets-manager.project-name")
+ @ConfigProperty(name = "camel.vault.gcp.projectId")
String projectName;
@Inject
@@ -82,16 +82,28 @@ public class GoogleSecretManagerResource {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
- public Response operation(@PathParam("operation") String operation,
@QueryParam("body") String body,
+ public Response operation(@PathParam("operation") String operation,
+ @QueryParam("body") String body,
+ @QueryParam("accountKey") String accountKey,
+ @QueryParam("useEnv") boolean useEnv,
Map<String, Object> headers) {
- Exchange ex =
producerTemplate.send(String.format("google-secret-manager://%s" +
- "?serviceAccountKey=file:%s" +
- "&operation=%s", projectName, accountKey, operation),
- e -> {
- e.getIn().setHeaders(headers == null ?
Collections.emptyMap() : headers);
- e.getIn().setBody(body == null ? "" : body);
- });
+ String url = useEnv ? String.format("google-secret-manager://%s" +
+ "?operation=%s", projectName, operation) : String.format(
+ "google-secret-manager://%s" +
+ "?serviceAccountKey=%s" +
+ "&operation=%s",
+ projectName, accountKey, operation);
+ Exchange ex;
+ try {
+ ex = producerTemplate.send(url,
+ e -> {
+ e.getIn().setHeaders(headers == null ?
Collections.emptyMap() : headers);
+ e.getIn().setBody(body == null ? "" : body);
+ });
+ } catch (Exception e) {
+ return Response.ok(e.getMessage()).build();
+ }
Object result = null;
switch (GoogleSecretManagerOperations.valueOf(operation)) {
diff --git
a/integration-tests-jvm/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerRoutes.java
b/integration-tests/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerRoutes.java
similarity index 93%
copy from
integration-tests-jvm/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerRoutes.java
copy to
integration-tests/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerRoutes.java
index 15074d1863..ca292463e7 100644
---
a/integration-tests-jvm/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerRoutes.java
+++
b/integration-tests/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerRoutes.java
@@ -30,7 +30,7 @@ public class GoogleSecretManagerRoutes extends RouteBuilder {
@Override
public void configure() throws Exception {
from("direct:loadGcpPassword")
- .setBody(new
SimpleExpression("{{gcp:%s@1}}".formatted(gcpSecretId)));
+ .setBody(new
SimpleExpression("{{gcp:%s}}".formatted(gcpSecretId)));
}
}
diff --git
a/integration-tests/google-secret-manager/src/main/resources/META-INF/services/org.apache.camel.quarkus.test.support.google.GoogleTestEnvCustomizer
b/integration-tests/google-secret-manager/src/main/resources/META-INF/services/org.apache.camel.quarkus.test.support.google.GoogleTestEnvCustomizer
new file mode 100644
index 0000000000..be21b79dcc
--- /dev/null
+++
b/integration-tests/google-secret-manager/src/main/resources/META-INF/services/org.apache.camel.quarkus.test.support.google.GoogleTestEnvCustomizer
@@ -0,0 +1 @@
+org.apache.camel.quarkus.component.google.secret.manager.it.GooglePubSubCustomizer
\ No newline at end of file
diff --git
a/integration-tests-jvm/google-secret-manager/src/main/resources/application.properties
b/integration-tests/google-secret-manager/src/main/resources/application.properties
similarity index 65%
rename from
integration-tests-jvm/google-secret-manager/src/main/resources/application.properties
rename to
integration-tests/google-secret-manager/src/main/resources/application.properties
index a563d11879..daae6d266d 100644
---
a/integration-tests-jvm/google-secret-manager/src/main/resources/application.properties
+++
b/integration-tests/google-secret-manager/src/main/resources/application.properties
@@ -14,7 +14,17 @@
## See the License for the specific language governing permissions and
## limitations under the License.
## ---------------------------------------------------------------------------
-cq.google-secrets-manager.path-to-service-account-key=${GOOGLE_SERVICE_ACCOUNT_KEY}
-cq.google-secrets-manager.project-name=${GOOGLE_PROJECT_NAME}
-camel.vault.gcp.serviceAccountKey=file:${GOOGLE_SERVICE_ACCOUNT_KEY}
-camel.vault.gcp.projectId=${GOOGLE_PROJECT_NAME}
+camel.vault.gcp.serviceAccountKey=file:${GOOGLE_APPLICATION_CREDENTIALS}
+camel.vault.gcp.projectId=${GOOGLE_PROJECT_ID}
+
+#enable secret refresh
+camel.vault.gcp.refreshEnabled=true
+camel.vault.gcp.refreshPeriod=1000
+camel.vault.gcp.secrets=CQ-GCPTestSecret*
+#topic for receiving the secret changes
+camel.vault.gcp.subscriptionName=${google-pubsub.refresh-subscription-name}
+camel.main.context-reload-enabled = true
+
+#test works only with the real backend
+camel.quarkus.start-mock-backend=false
+
diff --git
a/integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GooglePubSubCustomizer.java
b/integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GooglePubSubCustomizer.java
new file mode 100644
index 0000000000..84190ad4b5
--- /dev/null
+++
b/integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GooglePubSubCustomizer.java
@@ -0,0 +1,165 @@
+/*
+ * 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.quarkus.component.google.secret.manager.it;
+
+import java.io.IOException;
+import java.util.Locale;
+import java.util.concurrent.TimeUnit;
+
+import com.google.api.gax.core.CredentialsProvider;
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.api.gax.grpc.GrpcTransportChannel;
+import com.google.api.gax.rpc.FixedTransportChannelProvider;
+import com.google.cloud.pubsub.v1.*;
+import com.google.pubsub.v1.*;
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import org.apache.camel.quarkus.test.support.google.GoogleCloudContext;
+import org.apache.camel.quarkus.test.support.google.GoogleCloudTestResource;
+import org.apache.camel.quarkus.test.support.google.GoogleTestEnvCustomizer;
+import org.apache.commons.lang3.RandomStringUtils;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.PubSubEmulatorContainer;
+import org.testcontainers.utility.DockerImageName;
+
+public class GooglePubSubCustomizer implements GoogleTestEnvCustomizer {
+
+ private static final String TEST_PROJECT_ID = "test-project";
+
+ private PubSubEmulatorContainer container;
+
+ @Override
+ public GenericContainer createContainer() {
+ DockerImageName imageName =
DockerImageName.parse(GoogleCloudTestResource.GOOGLE_EMULATOR_IMAGE);
+ container = new PubSubEmulatorContainer(imageName);
+ return container;
+ }
+
+ @Override
+ public void customize(GoogleCloudContext envContext) {
+ try {
+ SubscriptionAdminClient subscriptionClient =
createSubscriptionAdminClient(envContext);
+ TopicAdminClient topicClient = createTopicAdminClient(envContext);
+
+ String projectId =
envContext.getProperties().getOrDefault(GoogleCloudTestResource.PARAM_PROJECT_ID,
+ TEST_PROJECT_ID);
+
+ envContext.property("project.id", projectId);
+ if (container != null) {
+ envContext.property("cq-test-authenticate", "false");
+ envContext.property("cq-test-endpoint",
container.getEmulatorEndpoint());
+ }
+
+ final String refreshTopicName = "camel-quarkus-refresh-topic-"
+ +
RandomStringUtils.randomAlphanumeric(49).toLowerCase(Locale.ROOT);
+ envContext.property("google-pubsub.refresh-topic-name",
refreshTopicName);
+
+ final String refreshSubscriptionName =
"camel-quarkus-refresh-subscription-"
+ +
RandomStringUtils.randomAlphanumeric(49).toLowerCase(Locale.ROOT);
+ envContext.property("google-pubsub.refresh-subscription-name",
refreshSubscriptionName);
+
+ Topic topic = createTopic(topicClient, refreshTopicName,
projectId);
+ Subscription subscription = createSubscription(subscriptionClient,
topic, refreshSubscriptionName, projectId);
+
+ envContext.closeable(() -> {
+ subscriptionClient.deleteSubscription(subscription.getName());
+ topicClient.deleteTopic(topic.getName());
+
+ topicClient.shutdown();
+ subscriptionClient.shutdown();
+
+ topicClient.awaitTermination(5, TimeUnit.SECONDS);
+ subscriptionClient.awaitTermination(5, TimeUnit.SECONDS);
+ });
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private Topic createTopic(TopicAdminClient topicClient, String topicName,
String projectId) {
+ Topic topic = Topic.newBuilder().setName(TopicName.of(projectId,
topicName).toString()).build();
+ return topicClient.createTopic(topic);
+ }
+
+ private Subscription createSubscription(SubscriptionAdminClient
subscriptionClient, Topic topic, String subscriptionName,
+ String projectId) {
+ return createSubscription(subscriptionClient, topic, subscriptionName,
projectId, false);
+ }
+
+ private Subscription createSubscription(SubscriptionAdminClient
subscriptionClient, Topic topic, String subscriptionName,
+ String projectId,
+ boolean enableOrdering) {
+ ProjectSubscriptionName projectSubscriptionName =
ProjectSubscriptionName.of(projectId, subscriptionName);
+ Subscription.Builder subscriptionBuilder = Subscription.newBuilder()
+ .setName(projectSubscriptionName.toString())
+ .setTopic(topic.getName())
+ .setAckDeadlineSeconds(10);
+
+ if (enableOrdering) {
+ subscriptionBuilder =
subscriptionBuilder.setEnableMessageOrdering(true);
+ }
+
+ return
subscriptionClient.createSubscription(subscriptionBuilder.build());
+ }
+
+ private FixedTransportChannelProvider
createChannelProvider(GoogleCloudContext context) {
+ ManagedChannel channel = ManagedChannelBuilder
+ .forTarget(String.format("%s:%s", container.getHost(),
container.getFirstMappedPort()))
+ .usePlaintext()
+ .build();
+
+ return
FixedTransportChannelProvider.create(GrpcTransportChannel.create(channel));
+ }
+
+ private TopicAdminClient createTopicAdminClient(GoogleCloudContext
context) throws IOException {
+ if (!context.isUsingMockBackend()) {
+ return TopicAdminClient.create();
+ }
+ FixedTransportChannelProvider channelProvider =
createChannelProvider(context);
+ CredentialsProvider credentialsProvider =
NoCredentialsProvider.create();
+
+ try {
+ return TopicAdminClient.create(
+ TopicAdminSettings.newBuilder()
+ .setTransportChannelProvider(channelProvider)
+ .setCredentialsProvider(credentialsProvider)
+ .build());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private SubscriptionAdminClient
createSubscriptionAdminClient(GoogleCloudContext context) throws IOException {
+ if (!context.isUsingMockBackend()) {
+ return SubscriptionAdminClient.create();
+ }
+ FixedTransportChannelProvider channelProvider =
createChannelProvider(context);
+ CredentialsProvider credentialsProvider =
NoCredentialsProvider.create();
+
+ try {
+ return SubscriptionAdminClient.create(
+ SubscriptionAdminSettings.newBuilder()
+ .setTransportChannelProvider(channelProvider)
+ .setCredentialsProvider(credentialsProvider)
+ .build());
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+}
diff --git
a/integration-tests-jvm/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerRoutes.java
b/integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerIT.java
similarity index 61%
rename from
integration-tests-jvm/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerRoutes.java
rename to
integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerIT.java
index 15074d1863..927c960d30 100644
---
a/integration-tests-jvm/google-secret-manager/src/main/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerRoutes.java
+++
b/integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerIT.java
@@ -16,21 +16,15 @@
*/
package org.apache.camel.quarkus.component.google.secret.manager.it;
-import jakarta.enterprise.context.ApplicationScoped;
-import org.apache.camel.builder.RouteBuilder;
-import org.apache.camel.model.language.SimpleExpression;
-import org.eclipse.microprofile.config.inject.ConfigProperty;
+import io.quarkus.test.junit.QuarkusIntegrationTest;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariables;
-@ApplicationScoped
-public class GoogleSecretManagerRoutes extends RouteBuilder {
+@QuarkusIntegrationTest
+@EnabledIfEnvironmentVariables({
+ @EnabledIfEnvironmentVariable(named =
"GOOGLE_APPLICATION_CREDENTIALS", matches = ".+"),
+ @EnabledIfEnvironmentVariable(named = "GOOGLE_PROJECT_ID", matches =
".+")
+})
+class GoogleSecretManagerIT extends GoogleSecretManagerTest {
- @ConfigProperty(name = "gcpSecretId")
- String gcpSecretId;
-
- @Override
- public void configure() throws Exception {
- from("direct:loadGcpPassword")
- .setBody(new
SimpleExpression("{{gcp:%s@1}}".formatted(gcpSecretId)));
-
- }
}
diff --git
a/integration-tests-jvm/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTest.java
b/integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTest.java
similarity index 57%
rename from
integration-tests-jvm/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTest.java
rename to
integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTest.java
index 7bdceb27c5..9c5a3a7c45 100644
---
a/integration-tests-jvm/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTest.java
+++
b/integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTest.java
@@ -20,21 +20,25 @@ import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
+import java.util.logging.LogManager;
import io.quarkus.logging.Log;
+import io.quarkus.test.InMemoryLogHandler;
import io.quarkus.test.common.QuarkusTestResource;
import io.quarkus.test.junit.QuarkusTest;
import io.restassured.RestAssured;
import io.restassured.http.ContentType;
import
org.apache.camel.component.google.secret.manager.GoogleSecretManagerConstants;
import
org.apache.camel.component.google.secret.manager.GoogleSecretManagerOperations;
-import org.apache.camel.quarkus.test.mock.backend.MockBackendUtils;
+import org.apache.camel.quarkus.test.support.google.GoogleCloudTestResource;
import org.awaitility.Awaitility;
import org.eclipse.microprofile.config.ConfigProvider;
import org.hamcrest.CoreMatchers;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariables;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
@@ -42,20 +46,30 @@ import static org.hamcrest.Matchers.not;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
- * Todo use MockBackendUtils
+ * There is no mock support for google secret-manager, therefore tests work
only with real credentials.
+ * <p/>
+ * Basic operations are covered by test `secretCreateListDelete`. Test is
parametrized.
+ * True/false in the parameter forces to yse environment property or not.
+ * <p/>
+ * Second test `loadGcpSecretAndRefreshTest` covers use of gcp secret manager
properties.
+ * The refresh of the secret is simulated by sending of pubsub message.
+ * For that purpose the second testResource is used. (which creates topic and
subscription)
*/
@QuarkusTest
@QuarkusTestResource(GoogleSecretManagerTestResource.class)
+@QuarkusTestResource(GoogleCloudTestResource.class)
@EnabledIfEnvironmentVariables({
- @EnabledIfEnvironmentVariable(named = "GOOGLE_SERVICE_ACCOUNT_KEY",
matches = ".+"),
- @EnabledIfEnvironmentVariable(named = "GOOGLE_PROJECT_NAME", matches =
".+")
+ @EnabledIfEnvironmentVariable(named =
"GOOGLE_APPLICATION_CREDENTIALS", matches = ".+"),
+ @EnabledIfEnvironmentVariable(named = "GOOGLE_PROJECT_ID", matches =
".+")
})
class GoogleSecretManagerTest {
- @Test
- void secretCreateListDelete() {
+ @ParameterizedTest
+ @ValueSource(booleans = { true, false })
+ void secretCreateListDelete(boolean useEnvProperties) {
final String secretToCreate = "firstSecret!";
- final String secretId = "CQTestSecret" + System.currentTimeMillis();
+ final String secretId = "CQTestSecret-" + useEnvProperties + "-" +
System.currentTimeMillis();
+ String accountKey =
ConfigProvider.getConfig().getValue("camel.vault.gcp.serviceAccountKey",
String.class);
String createdName;
boolean deleted = false;
@@ -69,11 +83,26 @@ class GoogleSecretManagerTest {
String name = createdName.substring(0,
createdName.indexOf("/version"));
String version =
createdName.substring(createdName.lastIndexOf("/") + 1);
+ if (!useEnvProperties) {
+ //validate that with the wrong accessKey, the request fails
+ RestAssured.given()
+ .contentType(ContentType.JSON)
+ .body(Map.of(GoogleSecretManagerConstants.SECRET_ID,
secretId, GoogleSecretManagerConstants.VERSION_ID,
+ version))
+ .queryParam("accountKey", "file:wrongPath")
+ .post("/google-secret-manager/operation/" +
GoogleSecretManagerOperations.getSecretVersion)
+ .then()
+ .statusCode(200)
+ .body(containsString("java.io.FileNotFoundException:
wrongPath does not exist"));
+ }
+
//get secret
RestAssured.given()
.contentType(ContentType.JSON)
.body(Map.of(GoogleSecretManagerConstants.SECRET_ID,
secretId, GoogleSecretManagerConstants.VERSION_ID,
version))
+ .queryParam("useEnv", useEnvProperties)
+ .queryParam("accountKey", accountKey)
.post("/google-secret-manager/operation/" +
GoogleSecretManagerOperations.getSecretVersion)
.then()
.statusCode(200)
@@ -82,6 +111,8 @@ class GoogleSecretManagerTest {
// list secrets
RestAssured.given()
.contentType(ContentType.JSON)
+ .queryParam("useEnv", useEnvProperties)
+ .queryParam("accountKey", accountKey)
.post("/google-secret-manager/operation/" +
GoogleSecretManagerOperations.listSecrets)
.then()
.statusCode(200)
@@ -93,6 +124,8 @@ class GoogleSecretManagerTest {
//verify that the secret is gone
RestAssured.given()
.contentType(ContentType.JSON)
+ .queryParam("useEnv", useEnvProperties)
+ .queryParam("accountKey", accountKey)
.post("/google-secret-manager/operation/" +
GoogleSecretManagerOperations.listSecrets)
.then()
.statusCode(200)
@@ -101,10 +134,10 @@ class GoogleSecretManagerTest {
deleted = true;
} finally {
- if (!deleted && !MockBackendUtils.startMockBackend(false)) {
- String file =
ConfigProvider.getConfig().getValue("cq.google-secrets-manager.path-to-service-account-key",
+ if (!deleted) {
+ String file =
ConfigProvider.getConfig().getValue("camel.vault.gcp.serviceAccountKey",
String.class);
- String projectName =
ConfigProvider.getConfig().getValue("cq.google-secrets-manager.project-name",
+ String projectName =
ConfigProvider.getConfig().getValue("camel.vault.gcp.projectId",
String.class);
GoogleSecretManagerTestResource.deleteSecret(secretId, file,
projectName);
}
@@ -112,14 +145,49 @@ class GoogleSecretManagerTest {
}
@Test
- void loadGcpSecretTest() {
+ void loadGcpSecretAndRefreshTest() throws Exception {
+ InMemoryLogHandler inMemoryLogHandler = new InMemoryLogHandler(
+ record -> record.getMessage().contains("Reloading
CamelContext"));
+
LogManager.getLogManager().getLogger("").addHandler(inMemoryLogHandler);
+
String expectedSecret =
ConfigProvider.getConfig().getValue("gcpSecretValue", String.class);
+ String secretId = ConfigProvider.getConfig().getValue("gcpSecretId",
String.class);
+ String projectId = ConfigProvider.getConfig().getValue("cqProjectId",
String.class);
+ String accountKey =
ConfigProvider.getConfig().getValue("gcpAccessFile", String.class);
+ //verify default secret value
RestAssured
.get("/google-secret-manager/getGcpSecret/")
.then()
.statusCode(200)
.body(is(expectedSecret));
+
+ //change secret
+ GoogleSecretManagerTestResource.updateSecret(secretId, "new_changeit",
accountKey, projectId);
+
+ //wait a moment and verify that the secret returned by the route is
not changed
+ Thread.sleep(20000);
+
+ RestAssured
+ .get("/google-secret-manager/getGcpSecret/")
+ .then()
+ .statusCode(200)
+ .body(is(expectedSecret));
+
+ //simulate that secret change is detected and proper message to a
subscription is sent
+ GoogleSecretManagerTestResource.sendMsg("mocked message forcing
refresh",
+ Map.of("eventType", "SECRET_UPDATE", "secretId", secretId));
+
+ //wait till the refresh is executed, route should return the new secret
+ Awaitility.await()
+ .atMost(30, TimeUnit.SECONDS)
+ .pollDelay(1, TimeUnit.SECONDS)
+ .pollInterval(1, TimeUnit.SECONDS)
+ .untilAsserted(() -> RestAssured
+ .get("/google-secret-manager/getGcpSecret/")
+ .then()
+ .statusCode(200)
+ .body(is("new_changeit")));
}
protected String createSecret(String secretName, String secretValue) {
@@ -132,6 +200,7 @@ class GoogleSecretManagerTest {
.contentType(ContentType.JSON)
.body(Collections.singletonMap(GoogleSecretManagerConstants.SECRET_ID,
secretName))
.queryParam("body", secretValue)
+ .queryParam("useEnv", true)
.post("/google-secret-manager/operation/" +
GoogleSecretManagerOperations.createSecret)
.then()
.statusCode(200)
@@ -150,6 +219,7 @@ class GoogleSecretManagerTest {
RestAssured.given()
.contentType(ContentType.JSON)
.body(Collections.singletonMap(GoogleSecretManagerConstants.SECRET_ID,
secretId))
+ .queryParam("useEnv", true)
.post("/google-secret-manager/operation/" +
GoogleSecretManagerOperations.deleteSecret)
.then()
.statusCode(200)
diff --git
a/integration-tests-jvm/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTestResource.java
b/integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTestResource.java
similarity index 59%
rename from
integration-tests-jvm/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTestResource.java
rename to
integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTestResource.java
index 4e13c1fd7d..d842408f05 100644
---
a/integration-tests-jvm/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTestResource.java
+++
b/integration-tests/google-secret-manager/src/test/java/org/apache/camel/quarkus/component/google/secret/manager/it/GoogleSecretManagerTestResource.java
@@ -18,11 +18,13 @@ package
org.apache.camel.quarkus.component.google.secret.manager.it;
import java.io.FileInputStream;
import java.io.IOException;
+import java.util.HashMap;
import java.util.Map;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.auth.Credentials;
import com.google.auth.oauth2.ServiceAccountCredentials;
+import com.google.cloud.pubsub.v1.Publisher;
import com.google.cloud.secretmanager.v1.ProjectName;
import com.google.cloud.secretmanager.v1.Replication;
import com.google.cloud.secretmanager.v1.Secret;
@@ -31,8 +33,10 @@ import
com.google.cloud.secretmanager.v1.SecretManagerServiceSettings;
import com.google.cloud.secretmanager.v1.SecretName;
import com.google.cloud.secretmanager.v1.SecretPayload;
import com.google.protobuf.ByteString;
+import com.google.pubsub.v1.PubsubMessage;
+import com.google.pubsub.v1.TopicName;
import io.quarkus.test.common.QuarkusTestResourceLifecycleManager;
-import org.apache.camel.quarkus.test.mock.backend.MockBackendUtils;
+import org.eclipse.microprofile.config.ConfigProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -43,36 +47,31 @@ public class GoogleSecretManagerTestResource implements
QuarkusTestResourceLifec
private String gcpSecretId;
private String accessFile;
private String projectName;
- private boolean realBackendIsUsed = false;
@Override
public Map<String, String> start() {
+ Map<String, String> retVal = new HashMap<>();
gcpSecretId = "CQ-GCPTestSecret" + System.currentTimeMillis();
String gcpSecretValue = "GCP secret value";
- accessFile = System.getenv("GOOGLE_SERVICE_ACCOUNT_KEY");
- projectName = System.getenv("GOOGLE_PROJECT_NAME");
-
- final boolean startMockBackend =
MockBackendUtils.startMockBackend(false);
- final boolean realCredentialsProvided = accessFile != null &&
!accessFile.isEmpty() && projectName != null
- && !projectName.isEmpty();
- final boolean usingMockBackend = startMockBackend &&
!realCredentialsProvided;
-
- if (usingMockBackend) {
- //try wiremock
- throw new RuntimeException("Mocked test backend is not implemented
yet");
- } else {
- if (!startMockBackend && !realCredentialsProvided) {
- throw new IllegalStateException(
- "Set GOOGLE_PROJECT and GOOGLE_SERVICE_ACCOUNT_KEY env
vars if you set CAMEL_QUARKUS_START_MOCK_BACKEND=false");
- }
- MockBackendUtils.logRealBackendUsed();
- realBackendIsUsed = true;
- //create secret for gcp
- createSecret(gcpSecretId, gcpSecretValue, accessFile, projectName);
+ accessFile = System.getenv("GOOGLE_APPLICATION_CREDENTIALS");
+ projectName = System.getenv("GOOGLE_PROJECT_ID");
+
+ if (accessFile == null || accessFile.isEmpty() || projectName == null
|| projectName.isEmpty()) {
+ throw new IllegalStateException(
+ "Set GOOGLE_PROJECT_ID and GOOGLE_APPLICATION_CREDENTIALS
env vars if you set CAMEL_QUARKUS_START_MOCK_BACKEND=false");
}
- return Map.of("gcpSecretId", gcpSecretId, "gcpSecretValue",
gcpSecretValue);
+
+ //create secret for gcp
+ createSecret(gcpSecretId, gcpSecretValue, accessFile, projectName);
+
+ retVal.put("gcpSecretId", gcpSecretId);
+ retVal.put("gcpSecretValue", gcpSecretValue);
+ retVal.put("gcpAccessFile", accessFile);
+ retVal.put("cqProjectId", projectName);
+
+ return retVal;
}
static void createSecret(String secretId, String secretValue, String
accessFile, String project) {
@@ -129,11 +128,58 @@ public class GoogleSecretManagerTestResource implements
QuarkusTestResourceLifec
}
}
- @Override
- public void stop() {
+ static void updateSecret(String secretId, String newSecretValue, String
accessFile, String project) {
+ SecretManagerServiceClient client = null;
+ try (FileInputStream fis = new FileInputStream(accessFile)) {
+
+ Credentials myCredentials =
ServiceAccountCredentials.fromStream(fis);
+ SecretManagerServiceSettings settings =
SecretManagerServiceSettings.newBuilder()
+
.setCredentialsProvider(FixedCredentialsProvider.create(myCredentials)).build();
+ client = SecretManagerServiceClient.create(settings);
+
+ Secret oldSecret = client.getSecret(SecretName.of(project,
secretId));
- if (realBackendIsUsed) {
- deleteSecret(gcpSecretId, accessFile, projectName);
+ SecretPayload payload = SecretPayload.newBuilder()
+ .setData(ByteString.copyFromUtf8(newSecretValue)).build();
+
+ client.addSecretVersion(oldSecret.getName(), payload);
+
+ } catch (IOException e) {
+ LOG.error("Unsuccessful update of secret (%s) for gcp.
".formatted(secretId));
+ throw new RuntimeException(e);
+ } finally {
+ if (client != null) {
+ client.close();
+ }
}
}
+
+ private static Publisher createPublisher(String projectId, String topicId)
throws IOException {
+ TopicName topicName = TopicName.of(projectId, topicId);
+
+ return Publisher.newBuilder(topicName).build();
+ }
+
+ static void sendMsg(String msg, Map<String, String> attributes) {
+ try {
+ Publisher publisher = createPublisher(
+
ConfigProvider.getConfig().getValue("camel.vault.gcp.projectId", String.class),
+
ConfigProvider.getConfig().getValue("google-pubsub.refresh-topic-name",
String.class));
+
+ PubsubMessage message = PubsubMessage.newBuilder()
+ .setData(com.google.protobuf.ByteString.copyFromUtf8(msg))
+ .putAllAttributes(attributes)
+ .build();
+
+ publisher.publish(message).get();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ }
+
+ @Override
+ public void stop() {
+ deleteSecret(gcpSecretId, accessFile, projectName);
+ }
}
diff --git a/integration-tests/pom.xml b/integration-tests/pom.xml
index 1d08f66102..111bc22dcf 100644
--- a/integration-tests/pom.xml
+++ b/integration-tests/pom.xml
@@ -101,6 +101,7 @@
<module>google</module>
<module>google-bigquery</module>
<module>google-pubsub</module>
+ <module>google-secret-manager</module>
<module>google-storage</module>
<module>graphql</module>
<module>grok</module>
diff --git a/tooling/scripts/test-categories.yaml
b/tooling/scripts/test-categories.yaml
index e280e67051..a4eedcb333 100644
--- a/tooling/scripts/test-categories.yaml
+++ b/tooling/scripts/test-categories.yaml
@@ -175,6 +175,7 @@ group-10:
- consul
- digitalocean
- fop
+ - google-secret-manager
- groovy
- joor
- mail