This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/main by this push:
new eb036c7c23c5 CAMEL-26622: camel-google-storage - run the integration
tests on Floci GCP (#29818)
eb036c7c23c5 is described below
commit eb036c7c23c51627bcae9e557d4ba08ef3f373cc
Author: Andrea Cosentino <[email protected]>
AuthorDate: Fri Nov 13 15:54:43 2026 +0100
CAMEL-26622: camel-google-storage - run the integration tests on Floci GCP
(#29818)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
.../apache/camel/catalog/test-infra/metadata.json | 11 +++
.../camel-google/camel-google-storage/pom.xml | 12 +++
.../google/storage/integration/ComplexIT.java | 97 +++++++++++++------
test-infra/camel-test-infra-all/pom.xml | 11 +++
.../src/generated/resources/META-INF/metadata.json | 11 +++
test-infra/camel-test-infra-google-common/pom.xml | 40 ++++++++
.../test/infra/google/common/GoogleProperties.java | 29 ++++++
.../google/common/services/FlociGcpContainer.java | 50 ++++++++++
.../src/main/resources/META-INF/MANIFEST.MF | 0
.../google/common/services/container.properties | 19 ++++
test-infra/camel-test-infra-google-storage/pom.xml | 40 ++++++++
.../storage/common/GoogleStorageProperties.java | 27 ++++++
.../services/GoogleStorageInfraService.java | 37 ++++++++
.../GoogleStorageLocalContainerInfraService.java | 103 +++++++++++++++++++++
.../services/GoogleStorageRemoteInfraService.java | 57 ++++++++++++
.../storage/services/GoogleStorageService.java | 27 ++++++
.../services/GoogleStorageServiceFactory.java | 83 +++++++++++++++++
.../src/main/resources/META-INF/MANIFEST.MF | 0
test-infra/pom.xml | 2 +
19 files changed, 626 insertions(+), 30 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
index 51503f728729..f53dfdae7abb 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/test-infra/metadata.json
@@ -174,6 +174,17 @@
"version" : "4.24.0-SNAPSHOT",
"serviceVersion" : "1.24.0",
"uiSupported" : false
+}, {
+ "service" :
"org.apache.camel.test.infra.google.storage.services.GoogleStorageInfraService",
+ "description" : "Local Google Cloud Storage service with Floci GCP",
+ "implementation" :
"org.apache.camel.test.infra.google.storage.services.GoogleStorageLocalContainerInfraService",
+ "alias" : [ "google" ],
+ "aliasImplementation" : [ "storage" ],
+ "groupId" : "org.apache.camel",
+ "artifactId" : "camel-test-infra-google-storage",
+ "version" : "4.24.0-SNAPSHOT",
+ "serviceVersion" : "0.12.0",
+ "uiSupported" : false
}, {
"service" :
"org.apache.camel.test.infra.rabbitmq.services.RabbitMQInfraService",
"description" : "RabbitMQ is an open source message and streaming broker",
diff --git a/components/camel-google/camel-google-storage/pom.xml
b/components/camel-google/camel-google-storage/pom.xml
index 5d6a835e0764..3042da2df562 100644
--- a/components/camel-google/camel-google-storage/pom.xml
+++ b/components/camel-google/camel-google-storage/pom.xml
@@ -34,6 +34,10 @@
<properties>
<camel.surefire.forkTimeout>300</camel.surefire.forkTimeout>
+
+ <!-- Floci GCP is not available for these -->
+ <skipITs.ppc64le>true</skipITs.ppc64le>
+ <skipITs.s390x>true</skipITs.s390x>
</properties>
<dependencies>
@@ -74,6 +78,14 @@
<scope>test</scope>
<classifier>tests</classifier>
</dependency>
+
+ <!-- test infra -->
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-infra-google-storage</artifactId>
+ <version>${project.version}</version>
+ <scope>test</scope>
+ </dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
diff --git
a/components/camel-google/camel-google-storage/src/test/java/org/apache/camel/component/google/storage/integration/ComplexIT.java
b/components/camel-google/camel-google-storage/src/test/java/org/apache/camel/component/google/storage/integration/ComplexIT.java
index 7c4d2df67ff8..d5a34f9e6bb5 100644
---
a/components/camel-google/camel-google-storage/src/test/java/org/apache/camel/component/google/storage/integration/ComplexIT.java
+++
b/components/camel-google/camel-google-storage/src/test/java/org/apache/camel/component/google/storage/integration/ComplexIT.java
@@ -17,24 +17,37 @@
package org.apache.camel.component.google.storage.integration;
import java.io.ByteArrayInputStream;
+import java.net.URI;
+import java.security.KeyPairGenerator;
import java.util.List;
+import java.util.concurrent.TimeUnit;
+import com.google.auth.oauth2.ServiceAccountCredentials;
import com.google.cloud.storage.Blob;
+import com.google.cloud.storage.Storage;
+import com.google.cloud.storage.StorageOptions;
import org.apache.camel.EndpointInject;
-import org.apache.camel.ProducerTemplate;
+import org.apache.camel.Exchange;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.google.storage.GoogleCloudStorageConstants;
import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.Registry;
+import
org.apache.camel.test.infra.google.storage.services.GoogleStorageLocalContainerInfraService;
+import
org.apache.camel.test.infra.google.storage.services.GoogleStorageService;
+import
org.apache.camel.test.infra.google.storage.services.GoogleStorageServiceFactory;
import org.apache.camel.test.junit6.CamelTestSupport;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable;
+import org.junit.jupiter.api.extension.RegisterExtension;
-@EnabledIfEnvironmentVariable(named = "GOOGLE_APPLICATION_CREDENTIALS",
matches = ".*",
- disabledReason = "Application credentials were
not provided")
-public class ComplexIT extends CamelTestSupport {
+/**
+ * Runs against the Cloud Storage service of Floci GCP, or with {@code
-Dgoogle.instance.type=remote} against the one of
+ * the project of the application default credentials, such as the key of the
{@code GOOGLE_APPLICATION_CREDENTIALS}
+ * environment variable.
+ */
+class ComplexIT extends CamelTestSupport {
- @EndpointInject
- private ProducerTemplate template;
+ @RegisterExtension
+ static GoogleStorageService service =
GoogleStorageServiceFactory.createService();
@EndpointInject("mock:bucket1")
private MockEndpoint mockBucket1;
@@ -45,14 +58,40 @@ public class ComplexIT extends CamelTestSupport {
@EndpointInject("mock:processed")
private MockEndpoint mockProcessed;
+ @Override
+ protected void bindToRegistry(Registry registry) throws Exception {
+ if (service instanceof GoogleStorageLocalContainerInfraService) {
+ // the endpoints take the client of the registry; against Google
Cloud, they build their own
+ registry.bind("storageClient", createLocalStorageClient());
+ }
+ }
+
+ // Floci GCP gives an access token to a service account of any key, at the
token address of the key: unlike no
+ // credentials, the ones of a key made for the test can sign the download
links
+ private static Storage createLocalStorageClient() throws Exception {
+ KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");
+ generator.initialize(2048);
+ ServiceAccountCredentials credentials =
ServiceAccountCredentials.newBuilder()
+ .setClientEmail("camel@" + service.projectId() +
".iam.gserviceaccount.com")
+ .setPrivateKeyId("camel")
+ .setPrivateKey(generator.generateKeyPair().getPrivate())
+ .setProjectId(service.projectId())
+ .setTokenServerUri(URI.create(service.endpoint() + "/token"))
+ .build();
+ return StorageOptions.newBuilder()
+ .setHost(service.endpoint())
+ .setProjectId(service.projectId())
+ .setCredentials(credentials)
+ .build()
+ .getService();
+ }
+
@Override
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
@Override
public void configure() {
final int numberOfObjects = 3;
- //final String serviceAccountKeyFile = "somefile.json";
- final String serviceAccountKeyFile =
System.getenv("GOOGLE_APPLICATION_CREDENTIALS");
final String bucket1 = "camel_test_bucket1";
final String bucket2 = "camel_test_bucket2";
final String bucket3 = "camel_test_processed_bucket";
@@ -60,20 +99,19 @@ public class ComplexIT extends CamelTestSupport {
//upload 3 file into bucket1
byte[] payload = "Camel rocks!".getBytes();
- ByteArrayInputStream bais = new ByteArrayInputStream(payload);
- from("timer:timer1?repeatCount=" + numberOfObjects)
+ from("timer:timer1?includeMetadata=true&repeatCount=" +
numberOfObjects)
.process(exchange -> {
- String filename = "file_" + ((int) (Math.random()
* 10000)) + ".txt";
+ String filename = "file_" +
exchange.getProperty(Exchange.TIMER_COUNTER) + ".txt";
exchange.getIn().setHeader(GoogleCloudStorageConstants.OBJECT_NAME, filename);
- exchange.getIn().setBody(bais);
+ exchange.getIn().setBody(new
ByteArrayInputStream(payload));
})
- .to("google-storage://" + bucket1 +
"?serviceAccountKey=file:" + serviceAccountKeyFile)
+ .to("google-storage://" + bucket1)
.log("upload file
object:${header.CamelGoogleCloudStorageObjectName}, body:${body}")
.to("mock:bucket1");
//poll from bucket1, moving processed into bucket_processed
and deleting original
- from("google-storage://" + bucket1 +
"?serviceAccountKey=file:" + serviceAccountKeyFile
- + "&moveAfterRead=true"
+ from("google-storage://" + bucket1
+ + "?moveAfterRead=true"
+ "&destinationBucket=" + bucket3
+ "&autoCreateBucket=true"
+ "&deleteAfterRead=true"
@@ -84,26 +122,26 @@ public class ComplexIT extends CamelTestSupport {
//upload these files to bucket2
from("direct:processed")
- .to("google-storage://" + bucket2 +
"?serviceAccountKey=file:" + serviceAccountKeyFile)
+ .to("google-storage://" + bucket2)
.log("uploaded file
object:${header.CamelGoogleCloudStorageObjectName}, body:${body}")
.process(exchange -> {
exchange.getIn().setHeader(GoogleCloudStorageConstants.DOWNLOAD_LINK_EXPIRATION_TIME,
86400000L); //1 day
})
- .to("google-storage://" + bucket2 +
"?serviceAccountKey=file:" + serviceAccountKeyFile
- + "&operation=createDownloadLink")
+ .to("google-storage://" + bucket2
+ + "?operation=createDownloadLink")
.log("URL for
${header.CamelGoogleCloudStorageBucketName}/${header.CamelGoogleCloudStorageObjectName}
=${body}")
.to("mock:bucket2");
//list all buckets
from("timer:timer1?repeatCount=1&fixedRate=true&period=10000")
- .to("google-storage://" + bucket2 +
"?serviceAccountKey=file:" + serviceAccountKeyFile
- + "&operation=listBuckets")
+ .to("google-storage://" + bucket2
+ + "?operation=listBuckets")
.log("list buckets:${body}");
//list all object of the bucket2 and send result to
direct:moreinfo and direct:copy
from("timer:timer1?repeatCount=1&fixedRate=true&period=10000")
- .to("google-storage://" + bucket2 +
"?serviceAccountKey=file:" + serviceAccountKeyFile
- + "&operation=listObjects")
+ .to("google-storage://" + bucket2
+ + "?operation=listObjects")
.log("list " + bucket2 + " objects body:${body}")
.split(bodyAs(List.class))
.log("splitted: ${body}")
@@ -115,8 +153,8 @@ public class ComplexIT extends CamelTestSupport {
String fileName = blob.getName();
exchange.getIn().setHeader(GoogleCloudStorageConstants.OBJECT_NAME, fileName);
})
- .to("google-storage://" + bucket2 +
"?serviceAccountKey=file:" + serviceAccountKeyFile
- + "&operation=getObject")
+ .to("google-storage://" + bucket2
+ + "?operation=getObject")
.log("get object
bucket:${header.CamelGoogleCloudStorageBucketName}
object:${header.CamelGoogleCloudStorageObjectName}, body:${body}");
//copy object
@@ -129,8 +167,8 @@ public class ComplexIT extends CamelTestSupport {
exchange.getIn().setHeader(GoogleCloudStorageConstants.DESTINATION_BUCKET_NAME,
bucket4);
exchange.getIn().setHeader(GoogleCloudStorageConstants.DESTINATION_OBJECT_NAME,
copyFileName);
})
- .to("google-storage://" + bucket2 +
"?serviceAccountKey=file:" + serviceAccountKeyFile
- + "&operation=copyObject")
+ .to("google-storage://" + bucket2
+ + "?operation=copyObject")
.log("${body}");
}
@@ -138,13 +176,12 @@ public class ComplexIT extends CamelTestSupport {
}
@Test
- public void sendIn() throws Exception {
+ void sendIn() throws Exception {
mockBucket1.expectedMessageCount(3);
mockBucket2.expectedMessageCount(3);
mockProcessed.expectedMessageCount(3);
- Thread.sleep(10000);
- MockEndpoint.assertIsSatisfied(context);
+ MockEndpoint.assertIsSatisfied(context, 30, TimeUnit.SECONDS);
}
}
diff --git a/test-infra/camel-test-infra-all/pom.xml
b/test-infra/camel-test-infra-all/pom.xml
index bea09ffe17a5..dfac989b11c5 100644
--- a/test-infra/camel-test-infra-all/pom.xml
+++ b/test-infra/camel-test-infra-all/pom.xml
@@ -141,6 +141,11 @@
<artifactId>camel-test-infra-google-pubsub</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-infra-google-storage</artifactId>
+ <version>${project.version}</version>
+ </dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-infra-infinispan</artifactId>
@@ -514,6 +519,12 @@
<artifactId>camel-test-infra-google-pubsub</artifactId>
</dependency>
</fileSet>
+ <fileSet>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+
<artifactId>camel-test-infra-google-storage</artifactId>
+ </dependency>
+ </fileSet>
<fileSet>
<dependency>
<groupId>org.apache.camel</groupId>
diff --git
a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
index 51503f728729..f53dfdae7abb 100644
---
a/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
+++
b/test-infra/camel-test-infra-all/src/generated/resources/META-INF/metadata.json
@@ -174,6 +174,17 @@
"version" : "4.24.0-SNAPSHOT",
"serviceVersion" : "1.24.0",
"uiSupported" : false
+}, {
+ "service" :
"org.apache.camel.test.infra.google.storage.services.GoogleStorageInfraService",
+ "description" : "Local Google Cloud Storage service with Floci GCP",
+ "implementation" :
"org.apache.camel.test.infra.google.storage.services.GoogleStorageLocalContainerInfraService",
+ "alias" : [ "google" ],
+ "aliasImplementation" : [ "storage" ],
+ "groupId" : "org.apache.camel",
+ "artifactId" : "camel-test-infra-google-storage",
+ "version" : "4.24.0-SNAPSHOT",
+ "serviceVersion" : "0.12.0",
+ "uiSupported" : false
}, {
"service" :
"org.apache.camel.test.infra.rabbitmq.services.RabbitMQInfraService",
"description" : "RabbitMQ is an open source message and streaming broker",
diff --git a/test-infra/camel-test-infra-google-common/pom.xml
b/test-infra/camel-test-infra-google-common/pom.xml
new file mode 100644
index 000000000000..8ca74ade6088
--- /dev/null
+++ b/test-infra/camel-test-infra-google-common/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>camel-test-infra-parent</artifactId>
+ <groupId>org.apache.camel</groupId>
+ <relativePath>../camel-test-infra-parent/pom.xml</relativePath>
+ <version>4.24.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>Camel :: Test Infra :: Google Common</name>
+ <artifactId>camel-test-infra-google-common</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-infra-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git
a/test-infra/camel-test-infra-google-common/src/main/java/org/apache/camel/test/infra/google/common/GoogleProperties.java
b/test-infra/camel-test-infra-google-common/src/main/java/org/apache/camel/test/infra/google/common/GoogleProperties.java
new file mode 100644
index 000000000000..3a21641a8ec5
--- /dev/null
+++
b/test-infra/camel-test-infra-google-common/src/main/java/org/apache/camel/test/infra/google/common/GoogleProperties.java
@@ -0,0 +1,29 @@
+/*
+ * 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.test.infra.google.common;
+
+public final class GoogleProperties {
+ /**
+ * The image of Floci GCP, which runs the local Google Cloud services
+ */
+ public static final String GOOGLE_CONTAINER = "google.container";
+
+ private GoogleProperties() {
+
+ }
+}
diff --git
a/test-infra/camel-test-infra-google-common/src/main/java/org/apache/camel/test/infra/google/common/services/FlociGcpContainer.java
b/test-infra/camel-test-infra-google-common/src/main/java/org/apache/camel/test/infra/google/common/services/FlociGcpContainer.java
new file mode 100644
index 000000000000..37926550c39b
--- /dev/null
+++
b/test-infra/camel-test-infra-google-common/src/main/java/org/apache/camel/test/infra/google/common/services/FlociGcpContainer.java
@@ -0,0 +1,50 @@
+/*
+ * 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.test.infra.google.common.services;
+
+import java.time.Duration;
+
+import org.apache.camel.test.infra.common.services.ContainerEnvironmentUtil;
+import org.testcontainers.containers.GenericContainer;
+import org.testcontainers.containers.wait.strategy.Wait;
+
+/**
+ * A container running Floci GCP (https://github.com/floci-io/floci-gcp), a
local Google Cloud emulator. It serves the
+ * gRPC and the REST APIs of the Google Cloud services on one port, and
accepts any project id.
+ */
+public class FlociGcpContainer extends GenericContainer<FlociGcpContainer> {
+ public static final int SERVICE_PORT = 4588;
+
+ public FlociGcpContainer(String imageName, boolean fixedPort) {
+ super(imageName);
+
+ ContainerEnvironmentUtil.configurePort(this, fixedPort, SERVICE_PORT);
+
+ waitingFor(Wait.forHttp("/health")
+ .forPort(SERVICE_PORT)
+ .forStatusCode(200)
+ .withStartupTimeout(Duration.ofSeconds(120)));
+ }
+
+ /**
+ * The address of the emulator, for example {@code http://localhost:32768}
+ */
+ public String serviceAddress() {
+ return String.format("http://%s:%d", getHost(),
getMappedPort(SERVICE_PORT));
+ }
+}
diff --git
a/test-infra/camel-test-infra-google-common/src/main/resources/META-INF/MANIFEST.MF
b/test-infra/camel-test-infra-google-common/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git
a/test-infra/camel-test-infra-google-common/src/main/resources/org/apache/camel/test/infra/google/common/services/container.properties
b/test-infra/camel-test-infra-google-common/src/main/resources/org/apache/camel/test/infra/google/common/services/container.properties
new file mode 100644
index 000000000000..b39172195ef1
--- /dev/null
+++
b/test-infra/camel-test-infra-google-common/src/main/resources/org/apache/camel/test/infra/google/common/services/container.properties
@@ -0,0 +1,19 @@
+## ---------------------------------------------------------------------------
+## 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.
+## ---------------------------------------------------------------------------
+# Floci GCP: the local Google Cloud services
+google.container=mirror.gcr.io/floci/floci-gcp:0.12.0
+google.container.version.exclude=latest,nightly,compat
diff --git a/test-infra/camel-test-infra-google-storage/pom.xml
b/test-infra/camel-test-infra-google-storage/pom.xml
new file mode 100644
index 000000000000..23e7bd15258f
--- /dev/null
+++ b/test-infra/camel-test-infra-google-storage/pom.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>camel-test-infra-parent</artifactId>
+ <groupId>org.apache.camel</groupId>
+ <relativePath>../camel-test-infra-parent/pom.xml</relativePath>
+ <version>4.24.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <name>Camel :: Test Infra :: Google Cloud Storage</name>
+ <artifactId>camel-test-infra-google-storage</artifactId>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-test-infra-google-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git
a/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/common/GoogleStorageProperties.java
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/common/GoogleStorageProperties.java
new file mode 100644
index 000000000000..4c515fdad65b
--- /dev/null
+++
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/common/GoogleStorageProperties.java
@@ -0,0 +1,27 @@
+/*
+ * 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.test.infra.google.storage.common;
+
+public final class GoogleStorageProperties {
+ public static final String PROJECT_ID = "google.storage.project.id";
+ public static final String ENDPOINT = "google.storage.endpoint";
+
+ private GoogleStorageProperties() {
+
+ }
+}
diff --git
a/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageInfraService.java
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageInfraService.java
new file mode 100644
index 000000000000..3691ef94ded6
--- /dev/null
+++
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageInfraService.java
@@ -0,0 +1,37 @@
+/*
+ * 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.test.infra.google.storage.services;
+
+import org.apache.camel.test.infra.common.services.InfrastructureService;
+
+/**
+ * A Cloud Storage service: the one of Floci GCP, or the one of a real Google
Cloud project.
+ */
+public interface GoogleStorageInfraService extends InfrastructureService {
+
+ /**
+ * The id of the project
+ */
+ String projectId();
+
+ /**
+ * The address of the Cloud Storage API, for example {@code
http://localhost:32768} for Floci GCP or
+ * {@code https://storage.googleapis.com} for Google Cloud
+ */
+ String endpoint();
+}
diff --git
a/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageLocalContainerInfraService.java
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageLocalContainerInfraService.java
new file mode 100644
index 000000000000..69a638ffe1bb
--- /dev/null
+++
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageLocalContainerInfraService.java
@@ -0,0 +1,103 @@
+/*
+ * 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.test.infra.google.storage.services;
+
+import org.apache.camel.spi.annotations.InfraService;
+import org.apache.camel.test.infra.common.LocalPropertyResolver;
+import org.apache.camel.test.infra.common.services.ContainerEnvironmentUtil;
+import org.apache.camel.test.infra.common.services.ContainerService;
+import org.apache.camel.test.infra.google.common.GoogleProperties;
+import org.apache.camel.test.infra.google.common.services.FlociGcpContainer;
+import
org.apache.camel.test.infra.google.storage.common.GoogleStorageProperties;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A local Cloud Storage service on Floci GCP. Floci GCP accepts any
credentials, and gives an access token to a service
+ * account of any key at {@code <endpoint>/token}.
+ */
+@InfraService(service = GoogleStorageInfraService.class,
+ description = "Local Google Cloud Storage service with Floci
GCP",
+ serviceAlias = "google", serviceImplementationAlias = "storage")
+public class GoogleStorageLocalContainerInfraService
+ implements GoogleStorageInfraService,
ContainerService<FlociGcpContainer> {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(GoogleStorageLocalContainerInfraService.class);
+ private static final String DEFAULT_PROJECT_ID = "test-project";
+
+ private final FlociGcpContainer container;
+
+ public GoogleStorageLocalContainerInfraService() {
+ this(LocalPropertyResolver.getProperty(FlociGcpContainer.class,
GoogleProperties.GOOGLE_CONTAINER));
+ }
+
+ public GoogleStorageLocalContainerInfraService(String imageName) {
+ container = initContainer(imageName);
+ String name = ContainerEnvironmentUtil.containerName(this.getClass());
+ if (name != null) {
+ container.withCreateContainerCmdModifier(cmd ->
cmd.withName(name));
+ }
+ }
+
+ public GoogleStorageLocalContainerInfraService(FlociGcpContainer
container) {
+ this.container = container;
+ }
+
+ protected FlociGcpContainer initContainer(String imageName) {
+ return new FlociGcpContainer(imageName,
ContainerEnvironmentUtil.isFixedPort(this.getClass()));
+ }
+
+ @Override
+ public void registerProperties() {
+ System.setProperty(GoogleStorageProperties.PROJECT_ID, projectId());
+ System.setProperty(GoogleStorageProperties.ENDPOINT, endpoint());
+ }
+
+ @Override
+ public void initialize() {
+ container.start();
+
+ LOG.info("Floci GCP running at address {}",
container.serviceAddress());
+
+ registerProperties();
+ }
+
+ @Override
+ public void shutdown() {
+ container.stop();
+ }
+
+ @Override
+ public FlociGcpContainer getContainer() {
+ return container;
+ }
+
+ /**
+ * The id of the project, {@code test-project} unless the {@code
google.storage.project.id} system property gives
+ * another one: Floci GCP accepts any
+ */
+ @Override
+ public String projectId() {
+ return System.getProperty(GoogleStorageProperties.PROJECT_ID,
DEFAULT_PROJECT_ID);
+ }
+
+ @Override
+ public String endpoint() {
+ return container.serviceAddress();
+ }
+}
diff --git
a/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageRemoteInfraService.java
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageRemoteInfraService.java
new file mode 100644
index 000000000000..14fbf99c8a31
--- /dev/null
+++
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageRemoteInfraService.java
@@ -0,0 +1,57 @@
+/*
+ * 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.test.infra.google.storage.services;
+
+import
org.apache.camel.test.infra.google.storage.common.GoogleStorageProperties;
+
+/**
+ * The Cloud Storage service of a real Google Cloud project, which the clients
reach with the application default
+ * credentials, such as the key of the {@code GOOGLE_APPLICATION_CREDENTIALS}
environment variable.
+ */
+public class GoogleStorageRemoteInfraService implements
GoogleStorageInfraService {
+ private static final String DEFAULT_ENDPOINT =
"https://storage.googleapis.com";
+
+ @Override
+ public void registerProperties() {
+ // NO-OP
+ }
+
+ @Override
+ public void initialize() {
+ registerProperties();
+ }
+
+ @Override
+ public void shutdown() {
+ // NO-OP
+ }
+
+ /**
+ * The id of the project of the {@code google.storage.project.id} system
property, if any: the clients otherwise
+ * take the one of the application default credentials
+ */
+ @Override
+ public String projectId() {
+ return System.getProperty(GoogleStorageProperties.PROJECT_ID);
+ }
+
+ @Override
+ public String endpoint() {
+ return System.getProperty(GoogleStorageProperties.ENDPOINT,
DEFAULT_ENDPOINT);
+ }
+}
diff --git
a/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageService.java
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageService.java
new file mode 100644
index 000000000000..c330661c8f59
--- /dev/null
+++
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageService.java
@@ -0,0 +1,27 @@
+/*
+ * 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.test.infra.google.storage.services;
+
+import org.apache.camel.test.infra.common.services.ContainerTestService;
+import org.apache.camel.test.infra.common.services.TestService;
+
+/**
+ * Test infra service for Google Cloud Storage
+ */
+public interface GoogleStorageService extends GoogleStorageInfraService,
TestService, ContainerTestService {
+}
diff --git
a/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageServiceFactory.java
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageServiceFactory.java
new file mode 100644
index 000000000000..0ab5dd4661b0
--- /dev/null
+++
b/test-infra/camel-test-infra-google-storage/src/main/java/org/apache/camel/test/infra/google/storage/services/GoogleStorageServiceFactory.java
@@ -0,0 +1,83 @@
+/*
+ * 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.test.infra.google.storage.services;
+
+import org.apache.camel.test.infra.common.services.SimpleTestServiceBuilder;
+import org.apache.camel.test.infra.common.services.SingletonService;
+
+/**
+ * Creates the Cloud Storage service of Floci GCP, or with {@code
-Dgoogle.instance.type=remote} the one of a real
+ * Google Cloud project.
+ */
+public final class GoogleStorageServiceFactory {
+
+ private static class SingletonGoogleStorageService extends
SingletonService<GoogleStorageService>
+ implements GoogleStorageService {
+ public SingletonGoogleStorageService(GoogleStorageService service,
String name) {
+ super(service, name);
+ }
+
+ @Override
+ public String projectId() {
+ return getService().projectId();
+ }
+
+ @Override
+ public String endpoint() {
+ return getService().endpoint();
+ }
+ }
+
+ private GoogleStorageServiceFactory() {
+
+ }
+
+ public static SimpleTestServiceBuilder<GoogleStorageService> builder() {
+ return new SimpleTestServiceBuilder<>("google");
+ }
+
+ public static GoogleStorageService createService() {
+ return builder()
+ .addLocalMapping(GoogleStorageLocalContainerService::new)
+ .addRemoteMapping(GoogleStorageRemoteService::new)
+ .build();
+ }
+
+ public static GoogleStorageService createSingletonService() {
+ return SingletonServiceHolder.INSTANCE;
+ }
+
+ private static class SingletonServiceHolder {
+ static final GoogleStorageService INSTANCE;
+ static {
+ SimpleTestServiceBuilder<GoogleStorageService> instance =
builder();
+ // a name of its own: the singleton of another Google service of
the same JVM must not stand for this one
+ instance.addLocalMapping(
+ () -> new SingletonGoogleStorageService(new
GoogleStorageLocalContainerService(), "google-storage"))
+ .addRemoteMapping(GoogleStorageRemoteService::new);
+ INSTANCE = instance.build();
+ }
+ }
+
+ static class GoogleStorageLocalContainerService extends
GoogleStorageLocalContainerInfraService
+ implements GoogleStorageService {
+ }
+
+ static class GoogleStorageRemoteService extends
GoogleStorageRemoteInfraService implements GoogleStorageService {
+ }
+}
diff --git
a/test-infra/camel-test-infra-google-storage/src/main/resources/META-INF/MANIFEST.MF
b/test-infra/camel-test-infra-google-storage/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 000000000000..e69de29bb2d1
diff --git a/test-infra/pom.xml b/test-infra/pom.xml
index e8da1e527977..020f4d5b8562 100644
--- a/test-infra/pom.xml
+++ b/test-infra/pom.xml
@@ -67,7 +67,9 @@
<module>camel-test-infra-arangodb</module>
<module>camel-test-infra-apicurio-registry</module>
<module>camel-test-infra-consul</module>
+ <module>camel-test-infra-google-common</module>
<module>camel-test-infra-google-pubsub</module>
+ <module>camel-test-infra-google-storage</module>
<module>camel-test-infra-infinispan</module>
<module>camel-test-infra-microprofile-lra</module>
<module>camel-test-infra-minio</module>